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