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/type_traits.hpp>
18 #include <boost/utility/enable_if.hpp>
22 namespace boost {
namespace gil {
42 template <
typename ColorBase>
45 struct size :
public mpl::size<typename ColorBase::layout_t::color_space_t> {};
82 BOOST_STATIC_CONSTANT(
int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
83 typedef typename kth_element_type<ColorBase, semantic_index>::type type;
89 BOOST_STATIC_CONSTANT(
int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
90 typedef typename kth_element_reference_type<ColorBase,semantic_index>::type type;
91 static type
get(ColorBase& cb) {
return gil::at_c<semantic_index>(cb); }
97 BOOST_STATIC_CONSTANT(
int, semantic_index = (mpl::at_c<typename ColorBase::layout_t::channel_mapping_t,K>::type::value));
98 typedef typename kth_element_const_reference_type<ColorBase,semantic_index>::type type;
99 static type
get(
const ColorBase& cb) {
return gil::at_c<semantic_index>(cb); }
104 template <
int K,
typename ColorBase>
inline
105 typename disable_if<is_const<ColorBase>,
typename kth_semantic_element_reference_type<ColorBase,K>::type>::type
112 template <
int K,
typename ColorBase>
inline
113 typename kth_semantic_element_const_reference_type<ColorBase,K>::type
143 template <
typename ColorBase,
typename Color>
146 struct contains_color :
public mpl::contains<typename ColorBase::layout_t::color_space_t,Color> {};
148 template <
typename ColorBase,
typename Color>
149 struct color_index_type :
public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
153 template <
typename ColorBase,
typename Color>
158 template <
typename ColorBase,
typename Color>
163 template <
typename ColorBase,
typename Color>
168 template <
typename ColorBase,
typename Color>
175 template <
typename ColorBase,
typename Color>
176 typename color_element_const_reference_type<ColorBase,Color>::type
get_color(
const ColorBase& cb, Color=Color()) {
197 template <
typename ColorBase>
204 template <
typename ColorBase>
209 template <
typename ColorBase>
210 struct element_const_reference_type :
public kth_element_const_reference_type<ColorBase, 0> {};
217 struct element_recursion
220 #if defined(BOOST_GCC)
221 #pragma GCC diagnostic push
222 #pragma GCC diagnostic ignored "-Wconversion"
223 #pragma GCC diagnostic ignored "-Wfloat-equal"
225 template <
typename P1,
typename P2>
226 static bool static_equal(
const P1& p1,
const P2& p2)
228 return element_recursion<N-1>::static_equal(p1,p2) &&
232 template <
typename P1,
typename P2>
233 static void static_copy(
const P1& p1, P2& p2)
235 element_recursion<N-1>::static_copy(p1,p2);
239 template <
typename P,
typename T2>
240 static void static_fill(P& p, T2 v)
242 element_recursion<N-1>::static_fill(p,v);
246 template <
typename Dst,
typename Op>
247 static void static_generate(Dst& dst, Op op)
249 element_recursion<N-1>::static_generate(dst,op);
252 #if defined(BOOST_GCC)
253 #pragma GCC diagnostic pop
257 template <
typename P1,
typename Op>
258 static Op static_for_each(P1& p1, Op op) {
259 Op op2(element_recursion<N-1>::static_for_each(p1,op));
260 op2(semantic_at_c<N-1>(p1));
263 template <
typename P1,
typename Op>
264 static Op static_for_each(
const P1& p1, Op op) {
265 Op op2(element_recursion<N-1>::static_for_each(p1,op));
266 op2(semantic_at_c<N-1>(p1));
270 template <
typename P1,
typename P2,
typename Op>
271 static Op static_for_each(P1& p1, P2& p2, Op op) {
272 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
273 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
276 template <
typename P1,
typename P2,
typename Op>
277 static Op static_for_each(P1& p1,
const P2& p2, Op op) {
278 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
279 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
282 template <
typename P1,
typename P2,
typename Op>
283 static Op static_for_each(
const P1& p1, P2& p2, Op op) {
284 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
285 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
288 template <
typename P1,
typename P2,
typename Op>
289 static Op static_for_each(
const P1& p1,
const P2& p2, Op op) {
290 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
291 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
295 template <
typename P1,
typename P2,
typename P3,
typename Op>
296 static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
297 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
298 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
301 template <
typename P1,
typename P2,
typename P3,
typename Op>
302 static Op static_for_each(P1& p1, P2& p2,
const P3& p3, Op op) {
303 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
304 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
307 template <
typename P1,
typename P2,
typename P3,
typename Op>
308 static Op static_for_each(P1& p1,
const P2& p2, P3& p3, Op op) {
309 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
310 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
313 template <
typename P1,
typename P2,
typename P3,
typename Op>
314 static Op static_for_each(P1& p1,
const P2& p2,
const P3& p3, Op op) {
315 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
316 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
319 template <
typename P1,
typename P2,
typename P3,
typename Op>
320 static Op static_for_each(
const P1& p1, P2& p2, P3& p3, Op op) {
321 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
322 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
325 template <
typename P1,
typename P2,
typename P3,
typename Op>
326 static Op static_for_each(
const P1& p1, P2& p2,
const P3& p3, Op op) {
327 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
328 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
331 template <
typename P1,
typename P2,
typename P3,
typename Op>
332 static Op static_for_each(
const P1& p1,
const P2& p2, P3& p3, Op op) {
333 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
334 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
337 template <
typename P1,
typename P2,
typename P3,
typename Op>
338 static Op static_for_each(
const P1& p1,
const P2& p2,
const P3& p3, Op op) {
339 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
340 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
344 template <
typename P1,
typename Dst,
typename Op>
345 static Op static_transform(P1& src, Dst& dst, Op op) {
346 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
350 template <
typename P1,
typename Dst,
typename Op>
351 static Op static_transform(
const P1& src, Dst& dst, Op op) {
352 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
357 template <
typename P1,
typename P2,
typename Dst,
typename Op>
358 static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
359 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
363 template <
typename P1,
typename P2,
typename Dst,
typename Op>
364 static Op static_transform(P1& src1,
const P2& src2, Dst& dst, Op op) {
365 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
369 template <
typename P1,
typename P2,
typename Dst,
typename Op>
370 static Op static_transform(
const P1& src1, P2& src2, Dst& dst, Op op) {
371 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
375 template <
typename P1,
typename P2,
typename Dst,
typename Op>
376 static Op static_transform(
const P1& src1,
const P2& src2, Dst& dst, Op op) {
377 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
384 template<>
struct element_recursion<0> {
386 template <
typename P1,
typename P2>
387 static bool static_equal(
const P1&,
const P2&) {
return true; }
389 template <
typename P1,
typename P2>
390 static void static_copy(
const P1&,
const P2&) {}
392 template <
typename P,
typename T2>
393 static void static_fill(
const P&, T2) {}
395 template <
typename Dst,
typename Op>
396 static void static_generate(
const Dst&,Op){}
398 template <
typename P1,
typename Op>
399 static Op static_for_each(
const P1&,Op op){
return op;}
401 template <
typename P1,
typename P2,
typename Op>
402 static Op static_for_each(
const P1&,
const P2&,Op op){
return op;}
404 template <
typename P1,
typename P2,
typename P3,
typename Op>
405 static Op static_for_each(
const P1&,
const P2&,
const P3&,Op op){
return op;}
407 template <
typename P1,
typename Dst,
typename Op>
408 static Op static_transform(
const P1&,
const Dst&,Op op){
return op;}
410 template <
typename P1,
typename P2,
typename Dst,
typename Op>
411 static Op static_transform(
const P1&,
const P2&,
const Dst&,Op op){
return op;}
415 template <
typename Q>
inline const Q& mutable_min(
const Q& x,
const Q& y) {
return x<y ? x : y; }
416 template <
typename Q>
inline Q& mutable_min( Q& x, Q& y) {
return x<y ? x : y; }
417 template <
typename Q>
inline const Q& mutable_max(
const Q& x,
const Q& y) {
return x<y ? y : x; }
418 template <
typename Q>
inline Q& mutable_max( Q& x, Q& y) {
return x<y ? y : x; }
423 struct min_max_recur {
424 template <
typename P>
static typename element_const_reference_type<P>::type max_(
const P& p) {
425 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
427 template <
typename P>
static typename element_reference_type<P>::type max_( P& p) {
428 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
430 template <
typename P>
static typename element_const_reference_type<P>::type min_(
const P& p) {
431 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
433 template <
typename P>
static typename element_reference_type<P>::type min_( P& p) {
434 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
440 struct min_max_recur<1> {
441 template <
typename P>
static typename element_const_reference_type<P>::type max_(
const P& p) {
return semantic_at_c<0>(p); }
442 template <
typename P>
static typename element_reference_type<P>::type max_( P& p) {
return semantic_at_c<0>(p); }
443 template <
typename P>
static typename element_const_reference_type<P>::type min_(
const P& p) {
return semantic_at_c<0>(p); }
444 template <
typename P>
static typename element_reference_type<P>::type min_( P& p) {
return semantic_at_c<0>(p); }
464 template <
typename P>
466 typename element_const_reference_type<P>::type static_max(
const P& p) {
return detail::min_max_recur<size<P>::value>::max_(p); }
468 template <
typename P>
470 typename element_reference_type<P>::type static_max( P& p) {
return detail::min_max_recur<size<P>::value>::max_(p); }
472 template <
typename P>
474 typename element_const_reference_type<P>::type static_min(
const P& p) {
return detail::min_max_recur<size<P>::value>::min_(p); }
476 template <
typename P>
478 typename element_reference_type<P>::type static_min( P& p) {
return detail::min_max_recur<size<P>::value>::min_(p); }
498 template <
typename P1,
typename P2>
500 bool static_equal(
const P1& p1,
const P2& p2) {
return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
521 template <
typename Src,
typename Dst>
523 void static_copy(
const Src& src, Dst& dst) { detail::element_recursion<size<Dst>::value>::static_copy(src,dst); }
540 template <
typename P,
typename V>
542 void static_fill(P& p,
const V& v) { detail::element_recursion<size<P>::value>::static_fill(p,v); }
566 template <
typename P1,
typename Op>
568 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
600 template <
typename Src,
typename Dst,
typename Op>
602 Op static_transform(Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
603 template <
typename Src,
typename Dst,
typename Op>
605 Op static_transform(
const Src& src,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
607 template <
typename P2,
typename P3,
typename Dst,
typename Op>
609 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) {
return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
610 template <
typename P2,
typename P3,
typename Dst,
typename Op>
612 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); }
613 template <
typename P2,
typename P3,
typename Dst,
typename Op>
615 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); }
616 template <
typename P2,
typename P3,
typename Dst,
typename Op>
618 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); }
649 template <
typename P1,
typename Op>
651 Op static_for_each( P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
652 template <
typename P1,
typename Op>
654 Op static_for_each(
const P1& p1, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
656 template <
typename P1,
typename P2,
typename Op>
658 Op static_for_each(P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
659 template <
typename P1,
typename P2,
typename Op>
661 Op static_for_each(P1& p1,
const P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
662 template <
typename P1,
typename P2,
typename Op>
664 Op static_for_each(
const P1& p1, P2& p2, Op op) {
return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
665 template <
typename P1,
typename P2,
typename Op>
667 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); }
669 template <
typename P1,
typename P2,
typename P3,
typename Op>
671 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); }
672 template <
typename P1,
typename P2,
typename P3,
typename Op>
674 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); }
675 template <
typename P1,
typename P2,
typename P3,
typename Op>
677 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); }
678 template <
typename P1,
typename P2,
typename P3,
typename Op>
680 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); }
681 template <
typename P1,
typename P2,
typename P3,
typename Op>
683 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); }
684 template <
typename P1,
typename P2,
typename P3,
typename Op>
686 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); }
687 template <
typename P1,
typename P2,
typename P3,
typename Op>
689 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); }
690 template <
typename P1,
typename P2,
typename P3,
typename Op>
692 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); }
disable_if< is_const< ColorBase >, typename kth_semantic_element_reference_type< ColorBase, K >::type >::type semantic_at_c(ColorBase &p)
A mutable accessor to the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:106
Specifies the return type of the constant element accessor by color name, get_color(color_base, Color());.
Definition: color_base_algorithm.hpp:164
Specifies the element type of a homogeneous color base.
Definition: color_base_algorithm.hpp:200
Specifies the type of the K-th semantic element of a color base.
Definition: color_base_algorithm.hpp:81
Specifies the return type of the mutable semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:88
A predicate metafunction determining whether a given color base contains a given color.
Definition: color_base_algorithm.hpp:146
Specifies the return type of the mutable element accessor at_c of a homogeneous color base...
Definition: color_base.hpp:35
Specifies the type of the element associated with a given color tag.
Definition: color_base_algorithm.hpp:154
Specifies the return type of the mutable element accessor by color name, get_color(color_base, Color());.
Definition: color_base_algorithm.hpp:159
Returns an MPL integral type specifying the number of elements in a color base.
Definition: color_base_algorithm.hpp:45
Specifies the return type of the constant semantic_at_c<K>(color_base);.
Definition: color_base_algorithm.hpp:96
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:176