]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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; | |
79 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; } | |
80 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; } | |
81 | ||
82 | homogeneous_color_base() {} | |
83 | homogeneous_color_base(Element v) : _v0(v) {} | |
84 | ||
85 | // grayscale pixel values are convertible to channel type | |
86 | operator Element () const { return _v0; } | |
87 | ||
88 | 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; | |
100 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; } | |
101 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; } | |
102 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; } | |
103 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; } | |
104 | ||
105 | homogeneous_color_base() {} | |
106 | explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {} | |
107 | homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {} | |
108 | ||
109 | 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 | |
114 | 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 | |
119 | template <typename P> homogeneous_color_base(P* p,bool) : | |
120 | _v0(&semantic_at_c<0>(*p)), | |
121 | _v1(&semantic_at_c<1>(*p)) {} | |
122 | 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 | |
127 | 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[] | |
132 | 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; | |
146 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; } | |
147 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; } | |
148 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; } | |
149 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; } | |
150 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; } | |
151 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; } | |
152 | ||
153 | homogeneous_color_base() {} | |
154 | explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {} | |
155 | homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {} | |
156 | ||
157 | 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 | |
163 | 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 | |
169 | 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)) {} | |
173 | 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 | |
179 | 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[] | |
185 | 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; | |
202 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; } | |
203 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; } | |
204 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; } | |
205 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; } | |
206 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; } | |
207 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; } | |
208 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; } | |
209 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; } | |
210 | homogeneous_color_base() {} | |
211 | explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {} | |
212 | homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {} | |
213 | ||
214 | 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 | |
221 | 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 | |
228 | 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 | ||
234 | 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 | |
241 | 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[] | |
248 | 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; | |
266 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; } | |
267 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; } | |
268 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; } | |
269 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; } | |
270 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; } | |
271 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; } | |
272 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; } | |
273 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; } | |
274 | typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) { return _v4; } | |
275 | typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; } | |
276 | homogeneous_color_base() {} | |
277 | explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {} | |
278 | homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {} | |
279 | ||
280 | 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 | |
288 | 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 | |
296 | 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 | ||
303 | 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 | |
311 | 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[] | |
319 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 { | |
396 | 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 | |
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 |