00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef GIL_COLOR_BASE_HPP
00014 #define GIL_COLOR_BASE_HPP
00015
00024
00025 #include <cassert>
00026 #include <boost/mpl/range_c.hpp>
00027 #include <boost/mpl/size.hpp>
00028 #include <boost/mpl/vector_c.hpp>
00029 #include <boost/type_traits.hpp>
00030 #include <boost/utility/enable_if.hpp>
00031
00032 #include "gil_config.hpp"
00033 #include "utilities.hpp"
00034 #include "gil_concept.hpp"
00035
00036 namespace boost { namespace gil {
00037
00038
00039 template <int K, typename ColorBase>
00040 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
00041 template <int K, typename ColorBase>
00042 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
00043
00044
00045 template <typename ColorBase> struct element_reference_type;
00046 template <typename ColorBase> struct element_const_reference_type;
00047 template <typename ColorBase, int K> struct kth_element_type;
00048 template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
00049 template <typename ColorBase, int K> struct kth_element_reference_type;
00050 template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
00051 template <typename ColorBase, int K> struct kth_element_const_reference_type;
00052 template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
00053
00054 namespace detail {
00055
00056 template <typename DstLayout, typename SrcLayout, int K>
00057 struct mapping_transform
00058 : public mpl::at<typename SrcLayout::channel_mapping_t,
00059 typename detail::type_to_index<typename DstLayout::channel_mapping_t,mpl::integral_c<int,K> >::type
00060 >::type {};
00061
00066
00067
00070 template <typename Element, typename Layout>
00071 struct homogeneous_color_base<Element,Layout,1> {
00072 private:
00073 Element _v0;
00074 public:
00075 typedef Layout layout_t;
00076 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00077 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00078
00079 homogeneous_color_base() {}
00080 homogeneous_color_base(Element v) : _v0(v) {}
00081
00082
00083 operator Element () const { return _v0; }
00084
00085 template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,1>& c) : _v0(at_c<0>(c)) {}
00086 };
00087
00088
00091 template <typename Element, typename Layout>
00092 struct homogeneous_color_base<Element,Layout,2> {
00093 private:
00094 Element _v0, _v1;
00095 public:
00096 typedef Layout layout_t;
00097 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00098 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00099 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00100 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00101
00102 homogeneous_color_base() {}
00103 explicit homogeneous_color_base(Element v) : _v0(v), _v1(v) {}
00104 homogeneous_color_base(Element v0, Element v1) : _v0(v0), _v1(v1) {}
00105
00106 template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,2>& c) :
00107 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00108 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
00109
00110
00111 template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,2>& c) :
00112 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00113 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)) {}
00114
00115
00116 template <typename P> homogeneous_color_base(P* p,bool) :
00117 _v0(&semantic_at_c<0>(*p)),
00118 _v1(&semantic_at_c<1>(*p)) {}
00119 template <typename Ref> Ref deref() const {
00120 return Ref(*semantic_at_c<0>(*this),
00121 *semantic_at_c<1>(*this)); }
00122
00123
00124 template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
00125 : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00126 _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)) {}
00127
00128
00129 Element at_c_dynamic(size_t i) const {
00130 if (i==0) return _v0;
00131 return _v1;
00132 }
00133 };
00134
00137 template <typename Element, typename Layout>
00138 struct homogeneous_color_base<Element,Layout,3> {
00139 private:
00140 Element _v0, _v1, _v2;
00141 public:
00142 typedef Layout layout_t;
00143 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00144 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00145 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00146 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00147 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00148 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00149
00150 homogeneous_color_base() {}
00151 explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v) {}
00152 homogeneous_color_base(Element v0, Element v1, Element v2) : _v0(v0), _v1(v1), _v2(v2) {}
00153
00154 template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,3>& c) :
00155 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00156 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00157 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
00158
00159
00160 template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,3>& c) :
00161 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00162 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00163 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)) {}
00164
00165
00166 template <typename P> homogeneous_color_base(P* p,bool) :
00167 _v0(&semantic_at_c<0>(*p)),
00168 _v1(&semantic_at_c<1>(*p)),
00169 _v2(&semantic_at_c<2>(*p)) {}
00170 template <typename Ref> Ref deref() const {
00171 return Ref(*semantic_at_c<0>(*this),
00172 *semantic_at_c<1>(*this),
00173 *semantic_at_c<2>(*this)); }
00174
00175
00176 template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
00177 : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00178 _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00179 _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)) {}
00180
00181
00182 Element at_c_dynamic(size_t i) const {
00183 switch (i) {
00184 case 0: return _v0;
00185 case 1: return _v1;
00186 }
00187 return _v2;
00188 }
00189 };
00190
00193 template <typename Element, typename Layout>
00194 struct homogeneous_color_base<Element,Layout,4> {
00195 private:
00196 Element _v0, _v1, _v2, _v3;
00197 public:
00198 typedef Layout layout_t;
00199 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00200 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00201 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00202 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00203 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00204 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00205 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
00206 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
00207 homogeneous_color_base() {}
00208 explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v) {}
00209 homogeneous_color_base(Element v0, Element v1, Element v2, Element v3) : _v0(v0), _v1(v1), _v2(v2), _v3(v3) {}
00210
00211 template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,4>& c) :
00212 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00213 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00214 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00215 _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
00216
00217
00218 template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,4>& c) :
00219 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00220 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00221 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00222 _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)) {}
00223
00224
00225 template <typename P> homogeneous_color_base(P* p,bool) :
00226 _v0(&semantic_at_c<0>(*p)),
00227 _v1(&semantic_at_c<1>(*p)),
00228 _v2(&semantic_at_c<2>(*p)),
00229 _v3(&semantic_at_c<3>(*p)) {}
00230
00231 template <typename Ref> Ref deref() const {
00232 return Ref(*semantic_at_c<0>(*this),
00233 *semantic_at_c<1>(*this),
00234 *semantic_at_c<2>(*this),
00235 *semantic_at_c<3>(*this)); }
00236
00237
00238 template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
00239 : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00240 _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00241 _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
00242 _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)) {}
00243
00244
00245 Element at_c_dynamic(size_t i) const {
00246 switch (i) {
00247 case 0: return _v0;
00248 case 1: return _v1;
00249 case 2: return _v2;
00250 }
00251 return _v3;
00252 }
00253 };
00254
00257 template <typename Element, typename Layout>
00258 struct homogeneous_color_base<Element,Layout,5> {
00259 private:
00260 Element _v0, _v1, _v2, _v3, _v4;
00261 public:
00262 typedef Layout layout_t;
00263 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) { return _v0; }
00264 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<0>) const { return _v0; }
00265 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) { return _v1; }
00266 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<1>) const { return _v1; }
00267 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) { return _v2; }
00268 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<2>) const { return _v2; }
00269 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) { return _v3; }
00270 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<3>) const { return _v3; }
00271 typename element_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) { return _v4; }
00272 typename element_const_reference_type<homogeneous_color_base>::type at(mpl::int_<4>) const { return _v4; }
00273 homogeneous_color_base() {}
00274 explicit homogeneous_color_base(Element v) : _v0(v), _v1(v), _v2(v), _v3(v), _v4(v) {}
00275 homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4) : _v0(v0), _v1(v1), _v2(v2), _v3(v3), _v4(v4) {}
00276
00277 template <typename E2, typename L2> homogeneous_color_base(const homogeneous_color_base<E2,L2,5>& c) :
00278 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00279 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00280 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00281 _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
00282 _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
00283
00284
00285 template <typename E2, typename L2> homogeneous_color_base( homogeneous_color_base<E2,L2,5>& c) :
00286 _v0(at_c<mapping_transform<Layout,L2,0>::value>(c)),
00287 _v1(at_c<mapping_transform<Layout,L2,1>::value>(c)),
00288 _v2(at_c<mapping_transform<Layout,L2,2>::value>(c)),
00289 _v3(at_c<mapping_transform<Layout,L2,3>::value>(c)),
00290 _v4(at_c<mapping_transform<Layout,L2,4>::value>(c)) {}
00291
00292
00293 template <typename P> homogeneous_color_base(P* p,bool) :
00294 _v0(&semantic_at_c<0>(*p)),
00295 _v1(&semantic_at_c<1>(*p)),
00296 _v2(&semantic_at_c<2>(*p)),
00297 _v3(&semantic_at_c<3>(*p)),
00298 _v4(&semantic_at_c<4>(*p)) {}
00299
00300 template <typename Ref> Ref deref() const {
00301 return Ref(*semantic_at_c<0>(*this),
00302 *semantic_at_c<1>(*this),
00303 *semantic_at_c<2>(*this),
00304 *semantic_at_c<3>(*this),
00305 *semantic_at_c<4>(*this)); }
00306
00307
00308 template <typename Ptr> homogeneous_color_base(const Ptr& ptr, std::ptrdiff_t diff)
00309 : _v0(*memunit_advanced(semantic_at_c<0>(ptr),diff)),
00310 _v1(*memunit_advanced(semantic_at_c<1>(ptr),diff)),
00311 _v2(*memunit_advanced(semantic_at_c<2>(ptr),diff)),
00312 _v3(*memunit_advanced(semantic_at_c<3>(ptr),diff)),
00313 _v4(*memunit_advanced(semantic_at_c<4>(ptr),diff)) {}
00314
00315
00316 Element at_c_dynamic(size_t i) const {
00317 switch (i) {
00318 case 0: return _v0;
00319 case 1: return _v1;
00320 case 2: return _v2;
00321 case 3: return _v3;
00322 }
00323 return _v4;
00324 }
00325 };
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 template <typename Element, typename Layout, int K>
00338 typename element_reference_type<homogeneous_color_base<Element,Layout,K> >::type
00339 dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
00340 assert(i<K);
00341 return (gil_reinterpret_cast<Element*>(&cb))[i];
00342 }
00343
00344 template <typename Element, typename Layout, int K>
00345 typename element_const_reference_type<homogeneous_color_base<Element,Layout,K> >::type
00346 dynamic_at_c(const homogeneous_color_base<Element,Layout,K>& cb, std::size_t i) {
00347 assert(i<K);
00348 return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
00349 }
00350
00351 template <typename Element, typename Layout, int K>
00352 typename element_reference_type<homogeneous_color_base<Element&,Layout,K> >::type
00353 dynamic_at_c(const homogeneous_color_base<Element&,Layout,K>& cb, std::size_t i) {
00354 assert(i<K);
00355 return cb.at_c_dynamic(i);
00356 }
00357
00358 template <typename Element, typename Layout, int K>
00359 typename element_const_reference_type<homogeneous_color_base<const Element&,Layout,K> >::type
00360 dynamic_at_c(const homogeneous_color_base<const Element&,Layout,K>& cb, std::size_t i) {
00361 assert(i<K);
00362 return cb.at_c_dynamic(i);
00363 }
00364
00365
00366 }
00367
00368 template <typename Element, typename Layout, int K1, int K>
00369 struct kth_element_type<detail::homogeneous_color_base<Element,Layout,K1>, K> {
00370 typedef Element type;
00371 };
00372
00373 template <typename Element, typename Layout, int K1, int K>
00374 struct kth_element_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<Element> {};
00375
00376 template <typename Element, typename Layout, int K1, int K>
00377 struct kth_element_const_reference_type<detail::homogeneous_color_base<Element,Layout,K1>, K> : public add_reference<typename add_const<Element>::type> {};
00378
00381 template <int K, typename E, typename L, int N> inline
00382 typename add_reference<E>::type
00383 at_c( detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
00384
00387 template <int K, typename E, typename L, int N> inline
00388 typename add_reference<typename add_const<E>::type>::type
00389 at_c(const detail::homogeneous_color_base<E,L,N>& p) { return p.at(mpl::int_<K>()); }
00390
00391 namespace detail {
00392 struct swap_fn {
00393 template <typename T> void operator()(T& x, T& y) const {
00394 using std::swap;
00395 swap(x,y);
00396 }
00397 };
00398 }
00399 template <typename E, typename L, int N> inline
00400 void swap(detail::homogeneous_color_base<E,L,N>& x, detail::homogeneous_color_base<E,L,N>& y) {
00401 static_for_each(x,y,detail::swap_fn());
00402 }
00403
00404
00405 } }
00406
00407 #endif