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 {
41 template <
typename ColorBase>
42 struct size :
public mp11::mp_size<typename ColorBase::layout_t::color_space_t> {};
76 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
164 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>
191 ->
typename color_element_reference_type<ColorBase,Color>::type
198 template <
typename ColorBase,
typename Color>
200 ->
typename color_element_const_reference_type<ColorBase,Color>::type
224 template <
typename ColorBase>
229 template <
typename ColorBase>
234 template <
typename ColorBase>
242 struct element_recursion
245 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
246 #pragma GCC diagnostic push
247 #pragma GCC diagnostic ignored "-Wconversion"
248 #pragma GCC diagnostic ignored "-Wfloat-equal"
251 template <
typename P1,
typename P2>
252 static bool static_equal(
const P1& p1,
const P2& p2)
254 return element_recursion<N-1>::static_equal(p1,p2) &&
258 template <
typename P1,
typename P2>
259 static void static_copy(
const P1& p1, P2& p2)
261 element_recursion<N-1>::static_copy(p1,p2);
265 template <
typename P,
typename T2>
266 static void static_fill(P& p, T2 v)
268 element_recursion<N-1>::static_fill(p,v);
272 template <
typename Dst,
typename Op>
273 static void static_generate(Dst& dst, Op op)
275 element_recursion<N-1>::static_generate(dst,op);
279 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
280 #pragma GCC diagnostic pop
284 template <
typename P1,
typename Op>
285 static Op static_for_each(P1& p1, Op op) {
286 Op op2(element_recursion<N-1>::static_for_each(p1,op));
287 op2(semantic_at_c<N-1>(p1));
290 template <
typename P1,
typename Op>
291 static Op static_for_each(
const P1& p1, Op op) {
292 Op op2(element_recursion<N-1>::static_for_each(p1,op));
293 op2(semantic_at_c<N-1>(p1));
297 template <
typename P1,
typename P2,
typename Op>
298 static Op static_for_each(P1& p1, P2& p2, Op op) {
299 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
300 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
303 template <
typename P1,
typename P2,
typename Op>
304 static Op static_for_each(P1& p1,
const P2& p2, Op op) {
305 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
306 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
309 template <
typename P1,
typename P2,
typename Op>
310 static Op static_for_each(
const P1& p1, P2& p2, Op op) {
311 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
312 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
315 template <
typename P1,
typename P2,
typename Op>
316 static Op static_for_each(
const P1& p1,
const P2& p2, Op op) {
317 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
318 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
322 template <
typename P1,
typename P2,
typename P3,
typename Op>
323 static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
324 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
325 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
328 template <
typename P1,
typename P2,
typename P3,
typename Op>
329 static Op static_for_each(P1& p1, P2& p2,
const P3& p3, Op op) {
330 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
331 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
334 template <
typename P1,
typename P2,
typename P3,
typename Op>
335 static Op static_for_each(P1& p1,
const P2& p2, P3& p3, Op op) {
336 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
337 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
340 template <
typename P1,
typename P2,
typename P3,
typename Op>
341 static Op static_for_each(P1& p1,
const P2& p2,
const P3& p3, Op op) {
342 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
343 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
346 template <
typename P1,
typename P2,
typename P3,
typename Op>
347 static Op static_for_each(
const P1& p1, P2& p2, P3& p3, Op op) {
348 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
349 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
352 template <
typename P1,
typename P2,
typename P3,
typename Op>
353 static Op static_for_each(
const P1& p1, P2& p2,
const P3& p3, Op op) {
354 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
355 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
358 template <
typename P1,
typename P2,
typename P3,
typename Op>
359 static Op static_for_each(
const P1& p1,
const P2& p2, P3& p3, Op op) {
360 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
361 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
364 template <
typename P1,
typename P2,
typename P3,
typename Op>
365 static Op static_for_each(
const P1& p1,
const P2& p2,
const P3& p3, Op op) {
366 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
367 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
371 template <
typename P1,
typename Dst,
typename Op>
372 static Op static_transform(P1& src, Dst& dst, Op op) {
373 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
377 template <
typename P1,
typename Dst,
typename Op>
378 static Op static_transform(
const P1& src, Dst& dst, Op op) {
379 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
384 template <
typename P1,
typename P2,
typename Dst,
typename Op>
385 static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
386 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
390 template <
typename P1,
typename P2,
typename Dst,
typename Op>
391 static Op static_transform(P1& src1,
const P2& src2, Dst& dst, Op op) {
392 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
396 template <
typename P1,
typename P2,
typename Dst,
typename Op>
397 static Op static_transform(
const P1& src1, P2& src2, Dst& dst, Op op) {
398 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
402 template <
typename P1,
typename P2,
typename Dst,
typename Op>
403 static Op static_transform(
const P1& src1,
const P2& src2, Dst& dst, Op op) {
404 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
411 template<>
struct element_recursion<0> {
413 template <
typename P1,
typename P2>
414 static bool static_equal(
const P1&,
const P2&) {
return true; }
416 template <
typename P1,
typename P2>
417 static void static_copy(
const P1&,
const P2&) {}
419 template <
typename P,
typename T2>
420 static void static_fill(
const P&, T2) {}
422 template <
typename Dst,
typename Op>
423 static void static_generate(
const Dst&,Op){}
425 template <
typename P1,
typename Op>
426 static Op static_for_each(
const P1&,Op op){
return op;}
428 template <
typename P1,
typename P2,
typename Op>
429 static Op static_for_each(
const P1&,
const P2&,Op op){
return op;}
431 template <
typename P1,
typename P2,
typename P3,
typename Op>
432 static Op static_for_each(
const P1&,
const P2&,
const P3&,Op op){
return op;}
434 template <
typename P1,
typename Dst,
typename Op>
435 static Op static_transform(
const P1&,
const Dst&,Op op){
return op;}
437 template <
typename P1,
typename P2,
typename Dst,
typename Op>
438 static Op static_transform(
const P1&,
const P2&,
const Dst&,Op op){
return op;}
442 template <
typename Q>
443 inline auto mutable_min(Q
const& x, Q
const& y) -> Q
const& {
return x<y ? x : y; }
445 template <
typename Q>
446 inline auto mutable_min(Q& x, Q& y) -> Q& {
return x<y ? x : y; }
448 template <
typename Q>
449 inline auto mutable_max(Q
const& x, Q
const& y) -> Q
const& {
return x<y ? y : x; }
451 template <
typename Q>
452 inline auto mutable_max(Q& x, Q& y) -> Q& {
return x<y ? y : x; }
459 template <
typename P>
460 static auto max_(P
const& p) ->
typename element_const_reference_type<P>::type
462 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
465 template <
typename P>
466 static auto max_(P& p) ->
typename element_reference_type<P>::type
468 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
471 template <
typename P>
472 static auto min_(P
const& p) ->
typename element_const_reference_type<P>::type
474 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
477 template <
typename P>
478 static auto min_(P& p) ->
typename element_reference_type<P>::type
480 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
486 struct min_max_recur<1>
488 template <
typename P>
489 static auto max_(P
const& p) ->
typename element_const_reference_type<P>::type {
return semantic_at_c<0>(p); }
491 template <
typename P>
492 static auto max_(P& p) ->
typename element_reference_type<P>::type {
return semantic_at_c<0>(p); }
494 template <
typename P>
495 static auto min_(P
const& p) ->
typename element_const_reference_type<P>::type {
return semantic_at_c<0>(p); }
497 template <
typename P>
498 static auto min_(P& p) ->
typename element_reference_type<P>::type {
return semantic_at_c<0>(p); }
515 template <
typename P>
517 auto static_max(P
const& p) ->
typename element_const_reference_type<P>::type {
return detail::min_max_recur<size<P>::value>::max_(p); }
519 template <
typename P>
521 auto static_max(P& p) ->
typename element_reference_type<P>::type {
return detail::min_max_recur<size<P>::value>::max_(p); }
523 template <
typename P>
525 auto static_min(P
const& p) ->
typename element_const_reference_type<P>::type {
return detail::min_max_recur<size<P>::value>::min_(p); }
527 template <
typename P>
529 auto static_min(P& p) ->
typename element_reference_type<P>::type {
return detail::min_max_recur<size<P>::value>::min_(p); }
547 template <
typename P1,
typename P2>
549 bool static_equal(P1
const& p1,
const P2& p2) {
return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
568 template <
typename Src,
typename Dst>
570 void static_copy(
const Src& src, Dst& dst)
572 detail::element_recursion<size<Dst>::value>::static_copy(src, dst);
589 template <
typename P,
typename V>
591 void static_fill(P& p,
const V& v)
593 detail::element_recursion<size<P>::value>::static_fill(p,v);
617 template <
typename P1,
typename Op>
619 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
649 template <
typename Src,
typename Dst,
typename Op>
651 Op static_transform(Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
652 template <
typename Src,
typename Dst,
typename Op>
654 Op static_transform(
const Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
656 template <
typename P2,
typename P3,
typename Dst,
typename Op>
658 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
659 template <
typename P2,
typename P3,
typename Dst,
typename Op>
661 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); }
662 template <
typename P2,
typename P3,
typename Dst,
typename Op>
664 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); }
665 template <
typename P2,
typename P3,
typename Dst,
typename Op>
667 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); }
696 template <
typename P1,
typename Op>
698 Op static_for_each( P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
699 template <
typename P1,
typename Op>
701 Op static_for_each(
const P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
703 template <
typename P1,
typename P2,
typename Op>
705 Op static_for_each(P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
706 template <
typename P1,
typename P2,
typename Op>
708 Op static_for_each(P1& p1,
const P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
709 template <
typename P1,
typename P2,
typename Op>
711 Op static_for_each(
const P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
712 template <
typename P1,
typename P2,
typename Op>
714 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); }
716 template <
typename P1,
typename P2,
typename P3,
typename Op>
718 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); }
719 template <
typename P1,
typename P2,
typename P3,
typename Op>
721 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); }
722 template <
typename P1,
typename P2,
typename P3,
typename Op>
724 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); }
725 template <
typename P1,
typename P2,
typename P3,
typename Op>
727 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); }
728 template <
typename P1,
typename P2,
typename P3,
typename Op>
730 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); }
731 template <
typename P1,
typename P2,
typename P3,
typename Op>
733 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); }
734 template <
typename P1,
typename P2,
typename P3,
typename Op>
736 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); }
737 template <
typename P1,
typename P2,
typename P3,
typename Op>
739 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); }
auto get_color(const ColorBase &cb, Color=Color()) -> typename color_element_const_reference_type< ColorBase, Color >::type
Constant accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:199
auto semantic_at_c(ColorBase &p) -> typename std::enable_if< !std::is_const< ColorBase >::value, typename kth_semantic_element_reference_type< ColorBase, K >::type >::type
A mutable accessor to the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:119
defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
Definition: algorithm.hpp:36
Specifies the return type of the constant element accessor by color name, get_color(color_base,...
Definition: color_base_algorithm.hpp:185
Specifies the return type of the mutable element accessor by color name, get_color(color_base,...
Definition: color_base_algorithm.hpp:180
Specifies the type of the element associated with a given color tag.
Definition: color_base_algorithm.hpp:175
A predicate metafunction determining whether a given color base contains a given color.
Definition: color_base_algorithm.hpp:167
Returns the index corresponding to the first occurrance of a given given type in.
Definition: utilities.hpp:251
Specifies the return type of the constant element accessor at_c of a homogeneous color base.
Definition: color_base_algorithm.hpp:235
Specifies the return type of the mutable element accessor at_c of a homogeneous color base.
Definition: color_base_algorithm.hpp:230
Specifies the element type of a homogeneous color base.
Definition: color_base_algorithm.hpp:225
Specifies the return type of the constant semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:105
Specifies the return type of the mutable semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:91
Specifies the type of the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:78
Returns an integral constant type specifying the number of elements in a color base.
Definition: color_base_algorithm.hpp:42