Boost GIL


color_base_algorithm.hpp
1//
2// Copyright 2005-2007 Adobe Systems Incorporated
3// Copyright 2019 Mateusz Loskot <mateusz at loskot dot net>
4//
5// Distributed under the Boost Software License, Version 1.0
6// See accompanying file LICENSE_1_0.txt or copy at
7// http://www.boost.org/LICENSE_1_0.txt
8//
9#ifndef BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
10#define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
11
12#include <boost/gil/concepts.hpp>
13#include <boost/gil/utilities.hpp>
14#include <boost/gil/detail/mp11.hpp>
15
16#include <boost/config.hpp>
17
18#include <algorithm>
19#include <type_traits>
20
21namespace boost { namespace gil {
22
26
41template <typename ColorBase>
42struct size : public mp11::mp_size<typename ColorBase::layout_t::color_space_t> {};
43
47
76template <typename ColorBase, int K>
78{
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");
82
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;
85};
86
89template <typename ColorBase, int K>
91{
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");
95
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); }
99};
100
103template <typename ColorBase, int K>
105{
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");
109
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); }
113};
114
117template <int K, typename ColorBase>
118inline
119auto semantic_at_c(ColorBase& p)
120 -> typename std::enable_if
121 <
122 !std::is_const<ColorBase>::value,
123 typename kth_semantic_element_reference_type<ColorBase, K>::type
124 >::type
125{
127}
128
131template <int K, typename ColorBase>
132inline
133auto semantic_at_c(ColorBase const& p)
134 -> typename kth_semantic_element_const_reference_type<ColorBase, K>::type
135{
137}
138
142
164template <typename ColorBase, typename Color>
166 : mp11::mp_contains<typename ColorBase::layout_t::color_space_t, Color>
167{};
168
169template <typename ColorBase, typename Color>
170struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
171
174template <typename ColorBase, typename Color>
175struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
176
179template <typename ColorBase, typename Color>
180struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
181
184template <typename ColorBase, typename Color>
185struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
186
189template <typename ColorBase, typename Color>
190auto get_color(ColorBase& cb, Color=Color())
191 -> typename color_element_reference_type<ColorBase,Color>::type
192{
194}
195
198template <typename ColorBase, typename Color>
199auto get_color(const ColorBase& cb, Color=Color())
200 -> typename color_element_const_reference_type<ColorBase,Color>::type
201{
203}
204
210
224template <typename ColorBase>
225struct element_type : public kth_element_type<ColorBase, 0> {};
226
229template <typename ColorBase>
230struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
231
234template <typename ColorBase>
235struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
236
237
238namespace detail {
239
240// compile-time recursion for per-element operations on color bases
241template <int N>
242struct element_recursion
243{
244
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"
249#endif
250
251 template <typename P1,typename P2>
252 static bool static_equal(const P1& p1, const P2& p2)
253 {
254 return element_recursion<N-1>::static_equal(p1,p2) &&
255 semantic_at_c<N-1>(p1)==semantic_at_c<N-1>(p2);
256 }
257
258 template <typename P1,typename P2>
259 static void static_copy(const P1& p1, P2& p2)
260 {
261 element_recursion<N-1>::static_copy(p1,p2);
262 semantic_at_c<N-1>(p2)=semantic_at_c<N-1>(p1);
263 }
264
265 template <typename P,typename T2>
266 static void static_fill(P& p, T2 v)
267 {
268 element_recursion<N-1>::static_fill(p,v);
269 semantic_at_c<N-1>(p)=v;
270 }
271
272 template <typename Dst,typename Op>
273 static void static_generate(Dst& dst, Op op)
274 {
275 element_recursion<N-1>::static_generate(dst,op);
276 semantic_at_c<N-1>(dst)=op();
277 }
278
279#if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
280#pragma GCC diagnostic pop
281#endif
282
283 //static_for_each with one source
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));
288 return op2;
289 }
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));
294 return op2;
295 }
296 //static_for_each with two sources
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));
301 return op2;
302 }
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));
307 return op2;
308 }
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));
313 return op2;
314 }
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));
319 return op2;
320 }
321 //static_for_each with three sources
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));
326 return op2;
327 }
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));
332 return op2;
333 }
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));
338 return op2;
339 }
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));
344 return op2;
345 }
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));
350 return op2;
351 }
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));
356 return op2;
357 }
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));
362 return op2;
363 }
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));
368 return op2;
369 }
370 //static_transform with one source
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));
374 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
375 return op2;
376 }
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));
380 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
381 return op2;
382 }
383 //static_transform with two sources
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));
387 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
388 return op2;
389 }
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));
393 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
394 return op2;
395 }
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));
399 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
400 return op2;
401 }
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));
405 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
406 return op2;
407 }
408};
409
410// Termination condition of the compile-time recursion for element operations on a color base
411template<> struct element_recursion<0> {
412 //static_equal
413 template <typename P1,typename P2>
414 static bool static_equal(const P1&, const P2&) { return true; }
415 //static_copy
416 template <typename P1,typename P2>
417 static void static_copy(const P1&, const P2&) {}
418 //static_fill
419 template <typename P, typename T2>
420 static void static_fill(const P&, T2) {}
421 //static_generate
422 template <typename Dst,typename Op>
423 static void static_generate(const Dst&,Op){}
424 //static_for_each with one source
425 template <typename P1,typename Op>
426 static Op static_for_each(const P1&,Op op){return op;}
427 //static_for_each with two sources
428 template <typename P1,typename P2,typename Op>
429 static Op static_for_each(const P1&,const P2&,Op op){return op;}
430 //static_for_each with three sources
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;}
433 //static_transform with one source
434 template <typename P1,typename Dst,typename Op>
435 static Op static_transform(const P1&,const Dst&,Op op){return op;}
436 //static_transform with two sources
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;}
439};
440
441// std::min and std::max don't have the mutable overloads...
442template <typename Q>
443inline auto mutable_min(Q const& x, Q const& y) -> Q const& { return x<y ? x : y; }
444
445template <typename Q>
446inline auto mutable_min(Q& x, Q& y) -> Q& { return x<y ? x : y; }
447
448template <typename Q>
449inline auto mutable_max(Q const& x, Q const& y) -> Q const& { return x<y ? y : x; }
450
451template <typename Q>
452inline auto mutable_max(Q& x, Q& y) -> Q& { return x<y ? y : x; }
453
454
455// compile-time recursion for min/max element
456template <int N>
457struct min_max_recur
458{
459 template <typename P>
460 static auto max_(P const& p) -> typename element_const_reference_type<P>::type
461 {
462 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
463 }
464
465 template <typename P>
466 static auto max_(P& p) -> typename element_reference_type<P>::type
467 {
468 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
469 }
470
471 template <typename P>
472 static auto min_(P const& p) -> typename element_const_reference_type<P>::type
473 {
474 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
475 }
476
477 template <typename P>
478 static auto min_(P& p) -> typename element_reference_type<P>::type
479 {
480 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
481 }
482};
483
484// termination condition of the compile-time recursion for min/max element
485template <>
486struct min_max_recur<1>
487{
488 template <typename P>
489 static auto max_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
490
491 template <typename P>
492 static auto max_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
493
494 template <typename P>
495 static auto min_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
496
497 template <typename P>
498 static auto min_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
499};
500} // namespace detail
501
514
515template <typename P>
516BOOST_FORCEINLINE
517auto static_max(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
518
519template <typename P>
520BOOST_FORCEINLINE
521auto static_max(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
522
523template <typename P>
524BOOST_FORCEINLINE
525auto static_min(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
526
527template <typename P>
528BOOST_FORCEINLINE
529auto static_min(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
531
546
547template <typename P1,typename P2>
548BOOST_FORCEINLINE
549bool static_equal(P1 const& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
550
552
567
568template <typename Src,typename Dst>
569BOOST_FORCEINLINE
570void static_copy(const Src& src, Dst& dst)
571{
572 detail::element_recursion<size<Dst>::value>::static_copy(src, dst);
573}
574
576
588
589template <typename P,typename V>
590BOOST_FORCEINLINE
591void static_fill(P& p, const V& v)
592{
593 detail::element_recursion<size<P>::value>::static_fill(p,v);
594}
595
597
616
617template <typename P1,typename Op>
618BOOST_FORCEINLINE
619void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
621
647
648//static_transform with one source
649template <typename Src,typename Dst,typename Op>
650BOOST_FORCEINLINE
651Op static_transform(Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
652template <typename Src,typename Dst,typename Op>
653BOOST_FORCEINLINE
654Op static_transform(const Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
655//static_transform with two sources
656template <typename P2,typename P3,typename Dst,typename Op>
657BOOST_FORCEINLINE
658Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
659template <typename P2,typename P3,typename Dst,typename Op>
660BOOST_FORCEINLINE
661Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
662template <typename P2,typename P3,typename Dst,typename Op>
663BOOST_FORCEINLINE
664Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
665template <typename P2,typename P3,typename Dst,typename Op>
666BOOST_FORCEINLINE
667Op 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); }
669
694
695//static_for_each with one source
696template <typename P1,typename Op>
697BOOST_FORCEINLINE
698Op static_for_each( P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
699template <typename P1,typename Op>
700BOOST_FORCEINLINE
701Op static_for_each(const P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
702//static_for_each with two sources
703template <typename P1,typename P2,typename Op>
704BOOST_FORCEINLINE
705Op static_for_each(P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
706template <typename P1,typename P2,typename Op>
707BOOST_FORCEINLINE
708Op static_for_each(P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
709template <typename P1,typename P2,typename Op>
710BOOST_FORCEINLINE
711Op static_for_each(const P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
712template <typename P1,typename P2,typename Op>
713BOOST_FORCEINLINE
714Op static_for_each(const P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
715//static_for_each with three sources
716template <typename P1,typename P2,typename P3,typename Op>
717BOOST_FORCEINLINE
718Op 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); }
719template <typename P1,typename P2,typename P3,typename Op>
720BOOST_FORCEINLINE
721Op 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); }
722template <typename P1,typename P2,typename P3,typename Op>
723BOOST_FORCEINLINE
724Op 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); }
725template <typename P1,typename P2,typename P3,typename Op>
726BOOST_FORCEINLINE
727Op 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); }
728template <typename P1,typename P2,typename P3,typename Op>
729BOOST_FORCEINLINE
730Op 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); }
731template <typename P1,typename P2,typename P3,typename Op>
732BOOST_FORCEINLINE
733Op 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); }
734template <typename P1,typename P2,typename P3,typename Op>
735BOOST_FORCEINLINE
736Op 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); }
737template <typename P1,typename P2,typename P3,typename Op>
738BOOST_FORCEINLINE
739Op 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); }
741
742}} // namespace boost::gil
743
744#endif
auto get_color(ColorBase &cb, Color=Color()) -> typename color_element_reference_type< ColorBase, Color >::type
Mutable accessor to the element associated with a given color name.
Definition: color_base_algorithm.hpp:190
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