1 /*
2     Copyright 2005-2007 Adobe Systems Incorporated
3 
4     Use, modification and distribution are subject to the Boost Software License,
5     Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6     http://www.boost.org/LICENSE_1_0.txt).
7 
8     See http://stlab.adobe.com/gil for most recent version including documentation.
9 */
10 
11 /*************************************************************************************************/
12 
13 #ifndef GIL_COLOR_BASE_HPP
14 #define GIL_COLOR_BASE_HPP
15 
16 ////////////////////////////////////////////////////////////////////////////////////////
17 /// \file
18 /// \brief pixel class and related utilities
19 /// \author Lubomir Bourdev and Hailin Jin \n
20 ///         Adobe Systems Incorporated
21 /// \date   2005-2007 \n Last updated on May 6, 2007
22 ///
23 ////////////////////////////////////////////////////////////////////////////////////////
24 
25 #include <cassert>
26 #include <boost/mpl/range_c.hpp>
27 #include <boost/mpl/size.hpp>
28 #include <boost/mpl/vector_c.hpp>
29 #include <boost/type_traits.hpp>
30 #include <boost/utility/enable_if.hpp>
31 
32 #include "gil_config.hpp"
33 #include "utilities.hpp"
34 #include "gil_concept.hpp"
35 
36 namespace boost { namespace gil {
37 
38 // Forward-declare
39 template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
40 
41 // Forward-declare semantic_at_c
42 template <int K, typename ColorBase>
43 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
44 template <int K, typename ColorBase>
45 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
46 
47 // Forward declare element_reference_type
48 template <typename ColorBase> struct element_reference_type;
49 template <typename ColorBase> struct element_const_reference_type;
50 template <typename ColorBase, int K> struct kth_element_type;
51 template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
52 template <typename ColorBase, int K> struct kth_element_reference_type;
53 template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
54 template <typename ColorBase, int K> struct kth_element_const_reference_type;
55 template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
56 
57 namespace detail {
58 
59 template <typename DstLayout, typename SrcLayout, int K>
60 struct mapping_transform
61     : public mpl::at<typename SrcLayout::channel_mapping_t,
62                      typename detail::type_to_index<typename DstLayout::channel_mapping_t,mpl::integral_c<int,K> >::type
63                            >::type {};
64 
65 /// \defgroup ColorBaseModelHomogeneous detail::homogeneous_color_base
66 /// \ingroup ColorBaseModel
67 /// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
68 /// If the element type models Regular, this class models HomogeneousColorBaseValueConcept.
69 
70 
71 /// \brief A homogeneous color base holding one color element. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
72 /// \ingroup ColorBaseModelHomogeneous
73 template <typename Element, typename Layout>
74 struct homogeneous_color_base<Element,Layout,1> {
75 private:
76     Element _v0;
77 public:
78     typedef Layout layout_t;
atboost::gil::detail::homogeneous_color_base79     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
atboost::gil::detail::homogeneous_color_base80     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
81 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base82     homogeneous_color_base() {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base83     homogeneous_color_base(Element v) : _v0(v) {}
84 
85     // grayscale pixel values are convertible to channel type
operator Elementboost::gil::detail::homogeneous_color_base86     operator Element () const { return _v0; }
87 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base88     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(at_c<0>(c)) {}
89 };
90 
91 
92 /// \brief A homogeneous color base holding two color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
93 /// \ingroup ColorBaseModelHomogeneous
94 template <typename Element, typename Layout>
95 struct homogeneous_color_base<Element,Layout,2> {
96 private:
97     Element _v0, _v1;
98 public:
99     typedef Layout layout_t;
atboost::gil::detail::homogeneous_color_base100     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
atboost::gil::detail::homogeneous_color_base101     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
atboost::gil::detail::homogeneous_color_base102     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
atboost::gil::detail::homogeneous_color_base103     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
104 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base105     homogeneous_color_base() {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base106     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base107     homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {}
108 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base109     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) :
110         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
111         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
112 
113     // Support for l-value reference proxy copy construction
homogeneous_color_baseboost::gil::detail::homogeneous_color_base114     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,2>& c) :
115         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
116         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
117 
118     // Support for planar_pixel_iterator construction and dereferencing
homogeneous_color_baseboost::gil::detail::homogeneous_color_base119     template <typename P> homogeneous_color_base(P* p,bool) :
120         _v0(&semantic_at_c<0>(*p)),
121         _v1(&semantic_at_c<1>(*p)) {}
derefboost::gil::detail::homogeneous_color_base122     template <typename Ref> Ref deref() const {
123         return Ref(*semantic_at_c<0>(*this),
124                    *semantic_at_c<1>(*this)); }
125 
126     // Support for planar_pixel_reference offset constructor
homogeneous_color_baseboost::gil::detail::homogeneous_color_base127     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
128         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
129           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
130 
131     // Support for planar_pixel_reference operator[]
at_c_dynamicboost::gil::detail::homogeneous_color_base132     Element at_c_dynamic(std::size_t i) const {
133         if (i==0) return _v0;
134         return _v1;
135     }
136 };
137 
138 /// \brief A homogeneous color base holding three color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
139 /// \ingroup ColorBaseModelHomogeneous
140 template <typename Element, typename Layout>
141 struct homogeneous_color_base<Element,Layout,3> {
142 private:
143     Element _v0, _v1, _v2;
144 public:
145     typedef Layout layout_t;
atboost::gil::detail::homogeneous_color_base146     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
atboost::gil::detail::homogeneous_color_base147     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
atboost::gil::detail::homogeneous_color_base148     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
atboost::gil::detail::homogeneous_color_base149     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
atboost::gil::detail::homogeneous_color_base150     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
atboost::gil::detail::homogeneous_color_base151     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
152 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base153     homogeneous_color_base() {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base154     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base155     homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {}
156 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base157     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) :
158         _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
159         _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
160         _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
161 
162     // Support for l-value reference proxy copy construction
homogeneous_color_baseboost::gil::detail::homogeneous_color_base163     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,3>& c) :
164         _v0(gil::at_c<mapping_transform<Layout,L2,0>::value>(c)),
165         _v1(gil::at_c<mapping_transform<Layout,L2,1>::value>(c)),
166         _v2(gil::at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
167 
168     // Support for planar_pixel_iterator construction and dereferencing
homogeneous_color_baseboost::gil::detail::homogeneous_color_base169     template <typename P> homogeneous_color_base(P* p,bool) :
170         _v0(&semantic_at_c<0>(*p)),
171         _v1(&semantic_at_c<1>(*p)),
172         _v2(&semantic_at_c<2>(*p)) {}
derefboost::gil::detail::homogeneous_color_base173     template <typename Ref> Ref deref() const {
174         return Ref(*semantic_at_c<0>(*this),
175                    *semantic_at_c<1>(*this),
176                    *semantic_at_c<2>(*this)); }
177 
178     // Support for planar_pixel_reference offset constructor
homogeneous_color_baseboost::gil::detail::homogeneous_color_base179     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
180         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
181           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
182           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
183 
184     // Support for planar_pixel_reference operator[]
at_c_dynamicboost::gil::detail::homogeneous_color_base185     Element at_c_dynamic(std::size_t i) const {
186         switch (i) {
187             case 0: return _v0;
188             case 1: return _v1;
189         }
190         return _v2;
191     }
192 };
193 
194 /// \brief A homogeneous color base holding four color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
195 /// \ingroup ColorBaseModelHomogeneous
196 template <typename Element, typename Layout>
197 struct homogeneous_color_base<Element,Layout,4> {
198 private:
199     Element _v0, _v1, _v2, _v3;
200 public:
201     typedef Layout layout_t;
atboost::gil::detail::homogeneous_color_base202     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
atboost::gil::detail::homogeneous_color_base203     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
atboost::gil::detail::homogeneous_color_base204     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
atboost::gil::detail::homogeneous_color_base205     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
atboost::gil::detail::homogeneous_color_base206     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
atboost::gil::detail::homogeneous_color_base207     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
atboost::gil::detail::homogeneous_color_base208     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<3>)       { return _v3; }
atboost::gil::detail::homogeneous_color_base209     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
homogeneous_color_baseboost::gil::detail::homogeneous_color_base210     homogeneous_color_base() {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base211     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base212     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {}
213 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base214     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,4>& c) :
215         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
216         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
217         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
218         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
219 
220     // Support for l-value reference proxy copy construction
homogeneous_color_baseboost::gil::detail::homogeneous_color_base221     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,4>& c) :
222         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
223         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
224         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
225         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
226 
227     // Support for planar_pixel_iterator construction and dereferencing
homogeneous_color_baseboost::gil::detail::homogeneous_color_base228     template <typename P> homogeneous_color_base(P* p,bool) :
229         _v0(&semantic_at_c<0>(*p)),
230         _v1(&semantic_at_c<1>(*p)),
231         _v2(&semantic_at_c<2>(*p)),
232         _v3(&semantic_at_c<3>(*p)) {}
233 
derefboost::gil::detail::homogeneous_color_base234     template <typename Ref> Ref deref() const {
235         return Ref(*semantic_at_c<0>(*this),
236                    *semantic_at_c<1>(*this),
237                    *semantic_at_c<2>(*this),
238                    *semantic_at_c<3>(*this)); }
239 
240     // Support for planar_pixel_reference offset constructor
homogeneous_color_baseboost::gil::detail::homogeneous_color_base241     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
242         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
243           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
244           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
245           _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
246 
247     // Support for planar_pixel_reference operator[]
at_c_dynamicboost::gil::detail::homogeneous_color_base248     Element at_c_dynamic(std::size_t i) const {
249         switch (i) {
250             case 0: return _v0;
251             case 1: return _v1;
252             case 2: return _v2;
253         }
254         return _v3;
255     }
256 };
257 
258 /// \brief A homogeneous color base holding five color elements. Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
259 /// \ingroup ColorBaseModelHomogeneous
260 template <typename Element, typename Layout>
261 struct homogeneous_color_base<Element,Layout,5> {
262 private:
263     Element _v0, _v1, _v2, _v3, _v4;
264 public:
265     typedef Layout layout_t;
atboost::gil::detail::homogeneous_color_base266     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<0>)       { return _v0; }
atboost::gil::detail::homogeneous_color_base267     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
atboost::gil::detail::homogeneous_color_base268     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<1>)       { return _v1; }
atboost::gil::detail::homogeneous_color_base269     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
atboost::gil::detail::homogeneous_color_base270     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<2>)       { return _v2; }
atboost::gil::detail::homogeneous_color_base271     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
atboost::gil::detail::homogeneous_color_base272     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<3>)       { return _v3; }
atboost::gil::detail::homogeneous_color_base273     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
atboost::gil::detail::homogeneous_color_base274     typename element_reference_type<homogeneous_color_base>::type       at(mpl::int_<4>)       { return _v4; }
atboost::gil::detail::homogeneous_color_base275     typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; }
homogeneous_color_baseboost::gil::detail::homogeneous_color_base276     homogeneous_color_base() {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base277     explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {}
homogeneous_color_baseboost::gil::detail::homogeneous_color_base278     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {}
279 
homogeneous_color_baseboost::gil::detail::homogeneous_color_base280     template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,5>& c) :
281         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
282         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
283         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
284         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
285         _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
286 
287     // Support for l-value reference proxy copy construction
homogeneous_color_baseboost::gil::detail::homogeneous_color_base288     template <typename E2, typename L2> homogeneous_color_base(      homogeneous_color_base<E2,L2,5>& c) :
289         _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
290         _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
291         _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
292         _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
293         _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
294 
295     // Support for planar_pixel_iterator construction and dereferencing
homogeneous_color_baseboost::gil::detail::homogeneous_color_base296     template <typename P> homogeneous_color_base(P* p,bool) :
297         _v0(&semantic_at_c<0>(*p)),
298         _v1(&semantic_at_c<1>(*p)),
299         _v2(&semantic_at_c<2>(*p)),
300         _v3(&semantic_at_c<3>(*p)),
301         _v4(&semantic_at_c<4>(*p)) {}
302 
derefboost::gil::detail::homogeneous_color_base303     template <typename Ref> Ref deref() const {
304         return Ref(*semantic_at_c<0>(*this),
305                    *semantic_at_c<1>(*this),
306                    *semantic_at_c<2>(*this),
307                    *semantic_at_c<3>(*this),
308                    *semantic_at_c<4>(*this)); }
309 
310     // Support for planar_pixel_reference offset constructor
homogeneous_color_baseboost::gil::detail::homogeneous_color_base311     template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
312         : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
313           _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
314           _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
315           _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
316           _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
317 
318     // Support for planar_pixel_reference operator[]
at_c_dynamicboost::gil::detail::homogeneous_color_base319     Element at_c_dynamic(std::size_t i) const {
320         switch (i) {
321             case 0: return _v0;
322             case 1: return _v1;
323             case 2: return _v2;
324             case 3: return _v3;
325         }
326         return _v4;
327     }
328 };
329 
330 // The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe
331 // -- there is no guarantee that the compiler won't add any padding between adjacent channels.
332 // Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs.
333 // This is because the color base structs must model the interleaved organization in memory. In other words, the client may
334 // have existing RGB image in the form "RGBRGBRGB..." and we must be able to represent it with an array of RGB color bases (i.e. RGB pixels)
335 // with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem.
336 // We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size
337 // of this channel is padded to 4 bytes, so an RGB pixel of it will be 4x3=12 bytes. The code below will still work properly.
338 // However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types.
339 
340 template <typename Element, typename Layout, int K>
341 typename element_reference_type<homogeneous_color_base<Element,Layout,K> >::type
dynamic_at_c(homogeneous_color_base<Element,Layout,K> & cb,std::size_t i)342 dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
343     assert(i<K);
344     return (gil_reinterpret_cast<Element*>(&cb))[i];
345 }
346 
347 template <typename Element, typename Layout, int K>
348 typename element_const_reference_type<homogeneous_color_base<Element,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<Element,Layout,K> & cb,std::size_t i)349 dynamic_at_c(const homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
350     assert(i<K);
351     return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
352 }
353 
354 template <typename Element, typename Layout, int K>
355 typename element_reference_type<homogeneous_color_base<Element&,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<Element &,Layout,K> & cb,std::size_t i)356 dynamic_at_c(const homogeneous_color_base<Element&,Layout,K>& cb, std::size_t i) {
357     assert(i<K);
358     return cb.at_c_dynamic(i);
359 }
360 
361 template <typename Element, typename Layout, int K>
362 typename element_const_reference_type<homogeneous_color_base<const Element&,Layout,K> >::type
dynamic_at_c(const homogeneous_color_base<const Element &,Layout,K> & cb,std::size_t i)363 dynamic_at_c(const homogeneous_color_base<const Element&,Layout,K>& cb, std::size_t i) {
364     assert(i<K);
365     return cb.at_c_dynamic(i);
366 }
367 
368 
369 } // namespace detail
370 
371 template <typename Element, typename Layout, int K1, int K>
372 struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
373     typedef Element type;
374 };
375 
376 template <typename Element, typename Layout, int K1, int K>
377 struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
378 
379 template <typename Element, typename Layout, int K1, int K>
380 struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
381 
382 /// \brief Provides mutable access to the K-th element, in physical order
383 /// \ingroup ColorBaseModelHomogeneous
384 template <int K, typename E, typename L, int N> inline
385 typename add_reference<E>::type
at_c(detail::homogeneous_color_base<E,L,N> & p)386 at_c(      detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
387 
388 /// \brief Provides constant access to the K-th element, in physical order
389 /// \ingroup ColorBaseModelHomogeneous
390 template <int K, typename E, typename L, int N> inline
391 typename add_reference<typename add_const<E>::type>::type
at_c(const detail::homogeneous_color_base<E,L,N> & p)392 at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
393 
394 namespace detail {
395     struct swap_fn {
operator ()boost::gil::detail::swap_fn396         template <typename T> void operator()(T& x, T& y) const {
397             using std::swap;
398             swap(x,y);
399         }
400     };
401 }
402 template <typename E, typename L, int N> inline
swap(detail::homogeneous_color_base<E,L,N> & x,detail::homogeneous_color_base<E,L,N> & y)403 void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) {
404     static_for_each(x,y,detail::swap_fn());
405 }
406 
407 
408 } }  // namespace boost::gil
409 
410 #endif
411