8 #ifndef BOOST_GIL_COLOR_BASE_ALGORITHM_HPP 9 #define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP 11 #include <boost/gil/concepts.hpp> 12 #include <boost/gil/utilities.hpp> 14 #include <boost/config.hpp> 15 #include <boost/mpl/at.hpp> 16 #include <boost/mpl/contains.hpp> 17 #include <boost/mpl/size.hpp> 18 #include <boost/type_traits.hpp> 21 #include <type_traits> 23 namespace boost {
namespace gil {
43 template <
typename ColorBase>
46 struct size :
public mpl::size<typename ColorBase::layout_t::color_space_t> {};
80 template <
typename ColorBase,
int K>
85 using channel_mapping_t =
typename ColorBase::layout_t::channel_mapping_t;
86 static_assert(K < mpl::size<channel_mapping_t>::value,
87 "K index should be less than size of channel_mapping_t sequence");
89 static constexpr
int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
90 using type =
typename kth_element_type<ColorBase, semantic_index>::type;
95 template <
typename ColorBase,
int K>
98 using channel_mapping_t =
typename ColorBase::layout_t::channel_mapping_t;
99 static_assert(K < mpl::size<channel_mapping_t>::value,
100 "K index should be less than size of channel_mapping_t sequence");
102 static constexpr
int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
103 using type =
typename kth_element_reference_type<ColorBase, semantic_index>::type;
104 static type get(ColorBase& cb) {
return gil::at_c<semantic_index>(cb); }
111 using channel_mapping_t =
typename ColorBase::layout_t::channel_mapping_t;
112 static_assert(K < mpl::size<channel_mapping_t>::value,
113 "K index should be less than size of channel_mapping_t sequence");
115 static constexpr
int semantic_index = mpl::at_c<channel_mapping_t, K>::type::value;
116 using type =
typename kth_element_const_reference_type<ColorBase,semantic_index>::type;
117 static type get(
const ColorBase& cb) {
return gil::at_c<semantic_index>(cb); }
122 template <
int K,
typename ColorBase>
125 ->
typename std::enable_if
127 !std::is_const<ColorBase>::value,
128 typename kth_semantic_element_reference_type<ColorBase, K>::type
136 template <
int K,
typename ColorBase>
inline 137 typename kth_semantic_element_const_reference_type<ColorBase,K>::type
167 template <
typename ColorBase,
typename Color>
170 struct contains_color :
public mpl::contains<typename ColorBase::layout_t::color_space_t,Color> {};
172 template <
typename ColorBase,
typename Color>
173 struct color_index_type :
public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
177 template <
typename ColorBase,
typename Color>
182 template <
typename ColorBase,
typename Color>
187 template <
typename ColorBase,
typename Color>
192 template <
typename ColorBase,
typename Color>
199 template <
typename ColorBase,
typename Color>
200 typename color_element_const_reference_type<ColorBase,Color>::type
get_color(
const ColorBase& cb, Color=Color()) {
221 template <
typename ColorBase>
228 template <
typename ColorBase>
233 template <
typename ColorBase>
234 struct element_const_reference_type :
public kth_element_const_reference_type<ColorBase, 0> {};
241 struct element_recursion
244 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) 245 #pragma GCC diagnostic push 246 #pragma GCC diagnostic ignored "-Wconversion" 247 #pragma GCC diagnostic ignored "-Wfloat-equal" 250 template <
typename P1,
typename P2>
251 static bool static_equal(
const P1& p1,
const P2& p2)
253 return element_recursion<N-1>::static_equal(p1,p2) &&
257 template <
typename P1,
typename P2>
258 static void static_copy(
const P1& p1, P2& p2)
260 element_recursion<N-1>::static_copy(p1,p2);
264 template <
typename P,
typename T2>
265 static void static_fill(P& p, T2 v)
267 element_recursion<N-1>::static_fill(p,v);
271 template <
typename Dst,
typename Op>
272 static void static_generate(Dst& dst, Op op)
274 element_recursion<N-1>::static_generate(dst,op);
278 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) 279 #pragma GCC diagnostic pop 283 template <
typename P1,
typename Op>
284 static Op static_for_each(P1& p1, Op op) {
285 Op op2(element_recursion<N-1>::static_for_each(p1,op));
286 op2(semantic_at_c<N-1>(p1));
289 template <
typename P1,
typename Op>
290 static Op static_for_each(
const P1& p1, Op op) {
291 Op op2(element_recursion<N-1>::static_for_each(p1,op));
292 op2(semantic_at_c<N-1>(p1));
296 template <
typename P1,
typename P2,
typename Op>
297 static Op static_for_each(P1& p1, P2& p2, Op op) {
298 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
299 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
302 template <
typename P1,
typename P2,
typename Op>
303 static Op static_for_each(P1& p1,
const P2& p2, Op op) {
304 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
305 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
308 template <
typename P1,
typename P2,
typename Op>
309 static Op static_for_each(
const P1& p1, P2& p2, Op op) {
310 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
311 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
314 template <
typename P1,
typename P2,
typename Op>
315 static Op static_for_each(
const P1& p1,
const P2& p2, Op op) {
316 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
317 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
321 template <
typename P1,
typename P2,
typename P3,
typename Op>
322 static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
323 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
324 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
327 template <
typename P1,
typename P2,
typename P3,
typename Op>
328 static Op static_for_each(P1& p1, P2& p2,
const P3& p3, Op op) {
329 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
330 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
333 template <
typename P1,
typename P2,
typename P3,
typename Op>
334 static Op static_for_each(P1& p1,
const P2& p2, P3& p3, Op op) {
335 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
336 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
339 template <
typename P1,
typename P2,
typename P3,
typename Op>
340 static Op static_for_each(P1& p1,
const P2& p2,
const P3& p3, Op op) {
341 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
342 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
345 template <
typename P1,
typename P2,
typename P3,
typename Op>
346 static Op static_for_each(
const P1& p1, P2& p2, P3& p3, Op op) {
347 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
348 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
351 template <
typename P1,
typename P2,
typename P3,
typename Op>
352 static Op static_for_each(
const P1& p1, P2& p2,
const P3& p3, Op op) {
353 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
354 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
357 template <
typename P1,
typename P2,
typename P3,
typename Op>
358 static Op static_for_each(
const P1& p1,
const P2& p2, P3& p3, Op op) {
359 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
360 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
363 template <
typename P1,
typename P2,
typename P3,
typename Op>
364 static Op static_for_each(
const P1& p1,
const P2& p2,
const P3& p3, Op op) {
365 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
366 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
370 template <
typename P1,
typename Dst,
typename Op>
371 static Op static_transform(P1& src, Dst& dst, Op op) {
372 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
376 template <
typename P1,
typename Dst,
typename Op>
377 static Op static_transform(
const P1& src, Dst& dst, Op op) {
378 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
383 template <
typename P1,
typename P2,
typename Dst,
typename Op>
384 static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
385 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
389 template <
typename P1,
typename P2,
typename Dst,
typename Op>
390 static Op static_transform(P1& src1,
const P2& src2, Dst& dst, Op op) {
391 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
395 template <
typename P1,
typename P2,
typename Dst,
typename Op>
396 static Op static_transform(
const P1& src1, P2& src2, Dst& dst, Op op) {
397 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
401 template <
typename P1,
typename P2,
typename Dst,
typename Op>
402 static Op static_transform(
const P1& src1,
const P2& src2, Dst& dst, Op op) {
403 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
410 template<>
struct element_recursion<0> {
412 template <
typename P1,
typename P2>
413 static bool static_equal(
const P1&,
const P2&) {
return true; }
415 template <
typename P1,
typename P2>
416 static void static_copy(
const P1&,
const P2&) {}
418 template <
typename P,
typename T2>
419 static void static_fill(
const P&, T2) {}
421 template <
typename Dst,
typename Op>
422 static void static_generate(
const Dst&,Op){}
424 template <
typename P1,
typename Op>
425 static Op static_for_each(
const P1&,Op op){
return op;}
427 template <
typename P1,
typename P2,
typename Op>
428 static Op static_for_each(
const P1&,
const P2&,Op op){
return op;}
430 template <
typename P1,
typename P2,
typename P3,
typename Op>
431 static Op static_for_each(
const P1&,
const P2&,
const P3&,Op op){
return op;}
433 template <
typename P1,
typename Dst,
typename Op>
434 static Op static_transform(
const P1&,
const Dst&,Op op){
return op;}
436 template <
typename P1,
typename P2,
typename Dst,
typename Op>
437 static Op static_transform(
const P1&,
const P2&,
const Dst&,Op op){
return op;}
441 template <
typename Q>
inline const Q& mutable_min(
const Q& x,
const Q& y) {
return x<y ? x : y; }
442 template <
typename Q>
inline Q& mutable_min( Q& x, Q& y) {
return x<y ? x : y; }
443 template <
typename Q>
inline const Q& mutable_max(
const Q& x,
const Q& y) {
return x<y ? y : x; }
444 template <
typename Q>
inline Q& mutable_max( Q& x, Q& y) {
return x<y ? y : x; }
449 struct min_max_recur {
450 template <
typename P>
static typename element_const_reference_type<P>::type max_(
const 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_reference_type<P>::type max_( P& p) {
454 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
456 template <
typename P>
static typename element_const_reference_type<P>::type min_(
const P& p) {
457 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
459 template <
typename P>
static typename element_reference_type<P>::type min_( P& p) {
460 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
466 struct min_max_recur<1> {
467 template <
typename P>
static typename element_const_reference_type<P>::type max_(
const P& p) {
return semantic_at_c<0>(p); }
468 template <
typename P>
static typename element_reference_type<P>::type max_( P& p) {
return semantic_at_c<0>(p); }
469 template <
typename P>
static typename element_const_reference_type<P>::type min_(
const P& p) {
return semantic_at_c<0>(p); }
470 template <
typename P>
static typename element_reference_type<P>::type min_( P& p) {
return semantic_at_c<0>(p); }
487 template <
typename P>
489 typename element_const_reference_type<P>::type static_max(
const P& p) {
return detail::min_max_recur<size<P>::value>::max_(p); }
491 template <
typename P>
493 typename element_reference_type<P>::type static_max( P& p) {
return detail::min_max_recur<size<P>::value>::max_(p); }
495 template <
typename P>
497 typename element_const_reference_type<P>::type static_min(
const P& p) {
return detail::min_max_recur<size<P>::value>::min_(p); }
499 template <
typename P>
501 typename element_reference_type<P>::type static_min( P& p) {
return detail::min_max_recur<size<P>::value>::min_(p); }
519 template <
typename P1,
typename P2>
521 bool static_equal(
const P1& p1,
const P2& p2) {
return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
540 template <
typename Src,
typename Dst>
542 void static_copy(
const Src& src, Dst& dst) { 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) { detail::element_recursion<size<P>::value>::static_fill(p,v); }
582 template <
typename P1,
typename Op>
584 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
614 template <
typename Src,
typename Dst,
typename Op>
616 Op static_transform(Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
617 template <
typename Src,
typename Dst,
typename Op>
619 Op static_transform(
const Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
621 template <
typename P2,
typename P3,
typename Dst,
typename Op>
623 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
624 template <
typename P2,
typename P3,
typename Dst,
typename Op>
626 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); }
627 template <
typename P2,
typename P3,
typename Dst,
typename Op>
629 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); }
630 template <
typename P2,
typename P3,
typename Dst,
typename Op>
632 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); }
661 template <
typename P1,
typename Op>
663 Op static_for_each( P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
664 template <
typename P1,
typename Op>
666 Op static_for_each(
const P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
668 template <
typename P1,
typename P2,
typename Op>
670 Op static_for_each(P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
671 template <
typename P1,
typename P2,
typename Op>
673 Op static_for_each(P1& p1,
const P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
674 template <
typename P1,
typename P2,
typename Op>
676 Op static_for_each(
const P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
677 template <
typename P1,
typename P2,
typename Op>
679 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); }
681 template <
typename P1,
typename P2,
typename P3,
typename Op>
683 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); }
684 template <
typename P1,
typename P2,
typename P3,
typename Op>
686 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); }
687 template <
typename P1,
typename P2,
typename P3,
typename Op>
689 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); }
690 template <
typename P1,
typename P2,
typename P3,
typename Op>
692 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); }
693 template <
typename P1,
typename P2,
typename P3,
typename Op>
695 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); }
696 template <
typename P1,
typename P2,
typename P3,
typename Op>
698 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); }
699 template <
typename P1,
typename P2,
typename P3,
typename Op>
701 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); }
702 template <
typename P1,
typename P2,
typename P3,
typename Op>
704 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:188
Specifies the element type of a homogeneous color base.
Definition: color_base_algorithm.hpp:224
Specifies the type of the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:83
Specifies the return type of the mutable semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:96
A predicate metafunction determining whether a given color base contains a given color.
Definition: color_base_algorithm.hpp:170
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:124
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:178
Specifies the return type of the mutable element accessor by color name, get_color(color_base,...
Definition: color_base_algorithm.hpp:183
Returns an MPL integral type specifying the number of elements in a color base.
Definition: color_base_algorithm.hpp:46
Specifies the return type of the constant semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:109
Returns the index corresponding to the first occurrance of a given given type in.
Definition: utilities.hpp:233
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:200