9 #ifndef BOOST_GIL_COLOR_BASE_ALGORITHM_HPP    10 #define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP    12 #include <boost/gil/concepts.hpp>    13 #include <boost/gil/utilities.hpp>    14 #include <boost/gil/detail/mp11.hpp>    16 #include <boost/config.hpp>    19 #include <type_traits>    21 namespace boost { 
namespace gil {
    39 template <
typename ColorBase>
    42 struct size : 
public mp11::mp_size<typename ColorBase::layout_t::color_space_t> {};
    74 template <
typename ColorBase, 
int K>
    79     using channel_mapping_t = 
typename ColorBase::layout_t::channel_mapping_t;
    80     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
    81         "K index should be less than size of channel_mapping_t sequence");
    83     static constexpr 
int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
    84     using type = 
typename kth_element_type<ColorBase, semantic_index>::type;
    89 template <
typename ColorBase, 
int K>
    92     using channel_mapping_t = 
typename ColorBase::layout_t::channel_mapping_t;
    93     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
    94         "K index should be less than size of channel_mapping_t sequence");
    96     static constexpr 
int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
    97     using type = 
typename kth_element_reference_type<ColorBase, semantic_index>::type;
    98     static type get(ColorBase& cb) { 
return gil::at_c<semantic_index>(cb); }
   103 template <
typename ColorBase, 
int K>
   106     using channel_mapping_t = 
typename ColorBase::layout_t::channel_mapping_t;
   107     static_assert(K < mp11::mp_size<channel_mapping_t>::value,
   108         "K index should be less than size of channel_mapping_t sequence");
   110     static constexpr 
int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
   111     using type = 
typename kth_element_const_reference_type<ColorBase,semantic_index>::type;
   112     static type get(
const ColorBase& cb) { 
return gil::at_c<semantic_index>(cb); }
   117 template <
int K, 
typename ColorBase>
   120     -> 
typename std::enable_if
   122         !std::is_const<ColorBase>::value,
   123         typename kth_semantic_element_reference_type<ColorBase, K>::type
   131 template <
int K, 
typename ColorBase>
   134     -> 
typename kth_semantic_element_const_reference_type<ColorBase, K>::type
   162 template <
typename ColorBase, 
typename Color>
   166     : mp11::mp_contains<typename ColorBase::layout_t::color_space_t, Color>
   169 template <
typename ColorBase, 
typename Color>
   170 struct color_index_type : 
public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
   174 template <
typename ColorBase, 
typename Color>
   179 template <
typename ColorBase, 
typename Color>
   184 template <
typename ColorBase, 
typename Color>
   189 template <
typename ColorBase, 
typename Color>
   190 typename color_element_reference_type<ColorBase,Color>::type 
get_color(ColorBase& cb, Color=Color()) {
   196 template <
typename ColorBase, 
typename Color>
   218 template <
typename ColorBase>
   225 template <
typename ColorBase>
   230 template <
typename ColorBase>
   231 struct element_const_reference_type : 
public kth_element_const_reference_type<ColorBase, 0> {};
   238 struct element_recursion
   241 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)   242 #pragma GCC diagnostic push   243 #pragma GCC diagnostic ignored "-Wconversion"   244 #pragma GCC diagnostic ignored "-Wfloat-equal"   247     template <
typename P1,
typename P2>
   248     static bool static_equal(
const P1& p1, 
const P2& p2)
   250         return element_recursion<N-1>::static_equal(p1,p2) &&
   254     template <
typename P1,
typename P2>
   255     static void static_copy(
const P1& p1, P2& p2)
   257         element_recursion<N-1>::static_copy(p1,p2);
   261     template <
typename P,
typename T2>
   262     static void static_fill(P& p, T2 v)
   264         element_recursion<N-1>::static_fill(p,v);
   268     template <
typename Dst,
typename Op>
   269     static void static_generate(Dst& dst, Op op)
   271         element_recursion<N-1>::static_generate(dst,op);
   275 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)   276 #pragma GCC diagnostic pop   280     template <
typename P1,
typename Op>
   281     static Op static_for_each(P1& p1, Op op) {
   282         Op op2(element_recursion<N-1>::static_for_each(p1,op));
   283         op2(semantic_at_c<N-1>(p1));
   286     template <
typename P1,
typename Op>
   287     static Op static_for_each(
const P1& p1, Op op) {
   288         Op op2(element_recursion<N-1>::static_for_each(p1,op));
   289         op2(semantic_at_c<N-1>(p1));
   293     template <
typename P1,
typename P2,
typename Op>
   294     static Op static_for_each(P1& p1, P2& p2, Op op) {
   295         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
   296         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
   299     template <
typename P1,
typename P2,
typename Op>
   300     static Op static_for_each(P1& p1, 
const P2& p2, Op op) {
   301         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
   302         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
   305     template <
typename P1,
typename P2,
typename Op>
   306     static Op static_for_each(
const P1& p1, P2& p2, Op op) {
   307         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
   308         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
   311     template <
typename P1,
typename P2,
typename Op>
   312     static Op static_for_each(
const P1& p1, 
const P2& p2, Op op) {
   313         Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
   314         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
   318     template <
typename P1,
typename P2,
typename P3,
typename Op>
   319     static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
   320         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   321         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   324     template <
typename P1,
typename P2,
typename P3,
typename Op>
   325     static Op static_for_each(P1& p1, P2& p2, 
const P3& p3, Op op) {
   326         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   327         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   330     template <
typename P1,
typename P2,
typename P3,
typename Op>
   331     static Op static_for_each(P1& p1, 
const P2& p2, P3& p3, Op op) {
   332         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   333         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   336     template <
typename P1,
typename P2,
typename P3,
typename Op>
   337     static Op static_for_each(P1& p1, 
const P2& p2, 
const P3& p3, Op op) {
   338         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   339         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   342     template <
typename P1,
typename P2,
typename P3,
typename Op>
   343     static Op static_for_each(
const P1& p1, P2& p2, P3& p3, Op op) {
   344         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   345         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   348     template <
typename P1,
typename P2,
typename P3,
typename Op>
   349     static Op static_for_each(
const P1& p1, P2& p2, 
const P3& p3, Op op) {
   350         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   351         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   354     template <
typename P1,
typename P2,
typename P3,
typename Op>
   355     static Op static_for_each(
const P1& p1, 
const P2& p2, P3& p3, Op op) {
   356         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   357         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   360     template <
typename P1,
typename P2,
typename P3,
typename Op>
   361     static Op static_for_each(
const P1& p1, 
const P2& p2, 
const P3& p3, Op op) {
   362         Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
   363         op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
   367     template <
typename P1,
typename Dst,
typename Op>
   368     static Op static_transform(P1& src, Dst& dst, Op op) {
   369         Op op2(element_recursion<N-1>::static_transform(src,dst,op));
   373     template <
typename P1,
typename Dst,
typename Op>
   374     static Op static_transform(
const P1& src, Dst& dst, Op op) {
   375         Op op2(element_recursion<N-1>::static_transform(src,dst,op));
   380     template <
typename P1,
typename P2,
typename Dst,
typename Op>
   381     static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
   382         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
   386     template <
typename P1,
typename P2,
typename Dst,
typename Op>
   387     static Op static_transform(P1& src1, 
const P2& src2, Dst& dst, Op op) {
   388         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
   392     template <
typename P1,
typename P2,
typename Dst,
typename Op>
   393     static Op static_transform(
const P1& src1, P2& src2, Dst& dst, Op op) {
   394         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
   398     template <
typename P1,
typename P2,
typename Dst,
typename Op>
   399     static Op static_transform(
const P1& src1, 
const P2& src2, Dst& dst, Op op) {
   400         Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
   407 template<> 
struct element_recursion<0> {
   409     template <
typename P1,
typename P2>
   410     static bool static_equal(
const P1&, 
const P2&) { 
return true; }
   412     template <
typename P1,
typename P2>
   413     static void static_copy(
const P1&, 
const P2&) {}
   415     template <
typename P, 
typename T2>
   416     static void static_fill(
const P&, T2) {}
   418     template <
typename Dst,
typename Op>
   419     static void static_generate(
const Dst&,Op){}
   421     template <
typename P1,
typename Op>
   422     static Op static_for_each(
const P1&,Op op){
return op;}
   424     template <
typename P1,
typename P2,
typename Op>
   425     static Op static_for_each(
const P1&,
const P2&,Op op){
return op;}
   427     template <
typename P1,
typename P2,
typename P3,
typename Op>
   428     static Op static_for_each(
const P1&,
const P2&,
const P3&,Op op){
return op;}
   430     template <
typename P1,
typename Dst,
typename Op>
   431     static Op static_transform(
const P1&,
const Dst&,Op op){
return op;}
   433     template <
typename P1,
typename P2,
typename Dst,
typename Op>
   434     static Op static_transform(
const P1&,
const P2&,
const Dst&,Op op){
return op;}
   438 template <
typename Q> 
inline const Q& mutable_min(
const Q& x, 
const Q& y) { 
return x<y ? x : y; }
   439 template <
typename Q> 
inline       Q& mutable_min(      Q& x,       Q& y) { 
return x<y ? x : y; }
   440 template <
typename Q> 
inline const Q& mutable_max(
const Q& x, 
const Q& y) { 
return x<y ? y : x; }
   441 template <
typename Q> 
inline       Q& mutable_max(      Q& x,       Q& y) { 
return x<y ? y : x; }
   446 struct min_max_recur {
   447     template <
typename P> 
static typename element_const_reference_type<P>::type max_(
const P& p) {
   448         return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
   450     template <
typename P> 
static typename element_reference_type<P>::type       max_(      P& p) {
   451         return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
   453     template <
typename P> 
static typename element_const_reference_type<P>::type min_(
const P& p) {
   454         return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
   456     template <
typename P> 
static typename element_reference_type<P>::type       min_(      P& p) {
   457         return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
   463 struct min_max_recur<1> {
   464     template <
typename P> 
static typename element_const_reference_type<P>::type max_(
const P& p) { 
return semantic_at_c<0>(p); }
   465     template <
typename P> 
static typename element_reference_type<P>::type       max_(      P& p) { 
return semantic_at_c<0>(p); }
   466     template <
typename P> 
static typename element_const_reference_type<P>::type min_(
const P& p) { 
return semantic_at_c<0>(p); }
   467     template <
typename P> 
static typename element_reference_type<P>::type       min_(      P& p) { 
return semantic_at_c<0>(p); }
   484 template <
typename P>
   486 typename element_const_reference_type<P>::type static_max(
const P& p) { 
return detail::min_max_recur<size<P>::value>::max_(p); }
   488 template <
typename P>
   490 typename element_reference_type<P>::type       static_max(      P& p) { 
return detail::min_max_recur<size<P>::value>::max_(p); }
   492 template <
typename P>
   494 typename element_const_reference_type<P>::type static_min(
const P& p) { 
return detail::min_max_recur<size<P>::value>::min_(p); }
   496 template <
typename P>
   498 typename element_reference_type<P>::type       static_min(      P& p) { 
return detail::min_max_recur<size<P>::value>::min_(p); }
   516 template <
typename P1,
typename P2>
   518 bool static_equal(
const P1& p1, 
const P2& p2) { 
return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
   537 template <
typename Src,
typename Dst>
   539 void static_copy(
const Src& src, Dst& dst)
   541     detail::element_recursion<size<Dst>::value>::static_copy(src, dst);
   558 template <
typename P,
typename V>
   560 void static_fill(P& p, 
const V& v)
   562     detail::element_recursion<size<P>::value>::static_fill(p,v);
   586 template <
typename P1,
typename Op>
   588 void static_generate(P1& dst,Op op)                      { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
   618 template <
typename Src,
typename Dst,
typename Op>
   620 Op static_transform(Src& src,Dst& dst,Op op)              { 
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
   621 template <
typename Src,
typename Dst,
typename Op>
   623 Op static_transform(
const Src& src,Dst& dst,Op op)              { 
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
   625 template <
typename P2,
typename P3,
typename Dst,
typename Op>
   627 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { 
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
   628 template <
typename P2,
typename P3,
typename Dst,
typename Op>
   630 Op static_transform(P2& p2,
const P3& p3,Dst& dst,Op op) { 
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
   631 template <
typename P2,
typename P3,
typename Dst,
typename Op>
   633 Op static_transform(
const P2& p2,P3& p3,Dst& dst,Op op) { 
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
   634 template <
typename P2,
typename P3,
typename Dst,
typename Op>
   636 Op static_transform(
const P2& p2,
const P3& p3,Dst& dst,Op op) { 
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
   665 template <
typename P1,
typename Op>
   667 Op static_for_each(      P1& p1, Op op)                          { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
   668 template <
typename P1,
typename Op>
   670 Op static_for_each(
const P1& p1, Op op)                          { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
   672 template <
typename P1,
typename P2,
typename Op>
   674 Op static_for_each(P1& p1,      P2& p2, Op op)             { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
   675 template <
typename P1,
typename P2,
typename Op>
   677 Op static_for_each(P1& p1,
const P2& p2, Op op)             { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
   678 template <
typename P1,
typename P2,
typename Op>
   680 Op static_for_each(
const P1& p1,      P2& p2, Op op)             { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
   681 template <
typename P1,
typename P2,
typename Op>
   683 Op static_for_each(
const P1& p1,
const P2& p2, Op op)             { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
   685 template <
typename P1,
typename P2,
typename P3,
typename Op>
   687 Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   688 template <
typename P1,
typename P2,
typename P3,
typename Op>
   690 Op static_for_each(P1& p1,P2& p2,
const P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   691 template <
typename P1,
typename P2,
typename P3,
typename Op>
   693 Op static_for_each(P1& p1,
const P2& p2,P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   694 template <
typename P1,
typename P2,
typename P3,
typename Op>
   696 Op static_for_each(P1& p1,
const P2& p2,
const P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   697 template <
typename P1,
typename P2,
typename P3,
typename Op>
   699 Op static_for_each(
const P1& p1,P2& p2,P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   700 template <
typename P1,
typename P2,
typename P3,
typename Op>
   702 Op static_for_each(
const P1& p1,P2& p2,
const P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   703 template <
typename P1,
typename P2,
typename P3,
typename Op>
   705 Op static_for_each(
const P1& p1,
const P2& p2,P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
   706 template <
typename P1,
typename P2,
typename P3,
typename Op>
   708 Op static_for_each(
const P1& p1,
const P2& p2,
const P3& p3,Op op) { 
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
 Specifies the return type of the constant element accessor by color name, get_color(color_base,...
Definition: color_base_algorithm.hpp:185
Specifies the element type of a homogeneous color base.
Definition: color_base_algorithm.hpp:221
Specifies the type of the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:77
Specifies the return type of the mutable semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:90
A predicate metafunction determining whether a given color base contains a given color.
Definition: color_base_algorithm.hpp:165
auto semantic_at_c(ColorBase const &p) -> typename kth_semantic_element_const_reference_type< ColorBase, K >::type
A constant accessor to the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:133
Specifies the return type of the mutable element accessor at_c of a homogeneous color base.
Definition: color_base.hpp:40
Specifies the type of the element associated with a given color tag.
Definition: color_base_algorithm.hpp:175
Specifies the return type of the mutable element accessor by color name, get_color(color_base,...
Definition: color_base_algorithm.hpp:180
Returns an integral constant type specifying the number of elements in a color base.
Definition: color_base_algorithm.hpp:42
Specifies the return type of the constant semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:104
Returns the index corresponding to the first occurrance of a given given type in.
Definition: utilities.hpp:249
color_element_const_reference_type< ColorBase, Color >::type get_color(const ColorBase &cb, Color=Color())
Constant accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:197