Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:12:39

0001 //
0002 // Copyright 2005-2007 Adobe Systems Incorporated
0003 // Copyright 2019 Mateusz Loskot <mateusz at loskot dot net>
0004 //
0005 // Distributed under the Boost Software License, Version 1.0
0006 // See accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt
0008 //
0009 #ifndef BOOST_GIL_COLOR_BASE_HPP
0010 #define BOOST_GIL_COLOR_BASE_HPP
0011 
0012 #include <boost/gil/utilities.hpp>
0013 #include <boost/gil/concepts.hpp>
0014 #include <boost/gil/detail/mp11.hpp>
0015 
0016 #include <boost/assert.hpp>
0017 #include <boost/config.hpp>
0018 
0019 #include <type_traits>
0020 
0021 namespace boost { namespace gil {
0022 
0023 // Forward-declare
0024 template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
0025 
0026 // Forward-declare semantic_at_c
0027 template <int K, typename ColorBase>
0028 auto semantic_at_c(ColorBase& p)
0029     -> typename std::enable_if
0030     <
0031         !std::is_const<ColorBase>::value,
0032         typename kth_semantic_element_reference_type<ColorBase, K>::type
0033     >::type;
0034 
0035 
0036 template <int K, typename ColorBase>
0037 auto semantic_at_c(const ColorBase& p) -> typename kth_semantic_element_const_reference_type<ColorBase,K>::type;
0038 
0039 // Forward declare element_reference_type
0040 template <typename ColorBase> struct element_reference_type;
0041 template <typename ColorBase> struct element_const_reference_type;
0042 template <typename ColorBase, int K> struct kth_element_type;
0043 template <typename ColorBase, int K> struct kth_element_type<const ColorBase,K> : public kth_element_type<ColorBase,K> {};
0044 template <typename ColorBase, int K> struct kth_element_reference_type;
0045 template <typename ColorBase, int K> struct kth_element_reference_type<const ColorBase,K> : public kth_element_reference_type<ColorBase,K> {};
0046 template <typename ColorBase, int K> struct kth_element_const_reference_type;
0047 template <typename ColorBase, int K> struct kth_element_const_reference_type<const ColorBase,K> : public kth_element_const_reference_type<ColorBase,K> {};
0048 
0049 namespace detail {
0050 
0051 template <typename DstLayout, typename SrcLayout, int K>
0052 struct mapping_transform : mp11::mp_at
0053     <
0054         typename SrcLayout::channel_mapping_t,
0055         typename detail::type_to_index
0056         <
0057             typename DstLayout::channel_mapping_t,
0058             std::integral_constant<int, K>
0059         >
0060     >::type
0061 {};
0062 
0063 /// \defgroup ColorBaseModelHomogeneous detail::homogeneous_color_base
0064 /// \ingroup ColorBaseModel
0065 /// \brief A homogeneous color base holding one color element.
0066 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0067 /// If the element type models Regular, this class models HomogeneousColorBaseValueConcept.
0068 
0069 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0070 #pragma warning(push)
0071 #pragma warning(disable:4512) //assignment operator could not be generated
0072 #endif
0073 
0074 /// \brief A homogeneous color base holding one color element.
0075 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0076 /// \ingroup ColorBaseModelHomogeneous
0077 template <typename Element, typename Layout>
0078 struct homogeneous_color_base<Element, Layout, 1>
0079 {
0080     using layout_t = Layout;
0081 
0082     template
0083     <
0084         typename U = Element,
0085         typename = typename std::enable_if<!std::is_reference<U>::value>::type
0086     >
0087     homogeneous_color_base() : v0_{} {}
0088 
0089     explicit homogeneous_color_base(Element v) : v0_(v) {}
0090 
0091     template <typename E2, typename L2>
0092     homogeneous_color_base(homogeneous_color_base<E2, L2, 1> const& c)
0093         : v0_(gil::at_c<0>(c))
0094     {}
0095 
0096     auto at(std::integral_constant<int, 0>)
0097         -> typename element_reference_type<homogeneous_color_base>::type
0098     { return v0_; }
0099 
0100     auto at(std::integral_constant<int, 0>) const
0101         -> typename element_const_reference_type<homogeneous_color_base>::type
0102     { return v0_; }
0103 
0104     // grayscale pixel values are convertible to channel type
0105     // FIXME: explicit?
0106     operator Element() const { return v0_; }
0107 
0108 private:
0109     Element v0_;
0110 };
0111 
0112 /// \brief A homogeneous color base holding two color elements
0113 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0114 /// \ingroup ColorBaseModelHomogeneous
0115 template <typename Element, typename Layout>
0116 struct homogeneous_color_base<Element, Layout, 2>
0117 {
0118     using layout_t = Layout;
0119 
0120     template
0121     <
0122         typename U = Element,
0123         typename = typename std::enable_if<!std::is_reference<U>::value>::type
0124     >
0125     homogeneous_color_base() : v0_{}, v1_{} {}
0126 
0127     explicit homogeneous_color_base(Element v) : v0_(v), v1_(v) {}
0128 
0129     homogeneous_color_base(Element v0, Element v1) : v0_(v0), v1_(v1) {}
0130 
0131     template <typename E2, typename L2>
0132     homogeneous_color_base(homogeneous_color_base<E2, L2, 2> const& c)
0133         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0134         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0135     {}
0136 
0137     // Support for l-value reference proxy copy construction
0138     template <typename E2, typename L2>
0139     homogeneous_color_base(homogeneous_color_base<E2, L2, 2>& c)
0140         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0141         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0142     {}
0143 
0144     // Support for planar_pixel_iterator construction and dereferencing
0145     template <typename P>
0146     homogeneous_color_base(P* p, bool)
0147         : v0_(&semantic_at_c<0>(*p))
0148         , v1_(&semantic_at_c<1>(*p))
0149     {}
0150 
0151     // Support for planar_pixel_reference offset constructor
0152     template <typename Ptr>
0153     homogeneous_color_base(Ptr const& ptr, std::ptrdiff_t diff)
0154         : v0_(*memunit_advanced(semantic_at_c<0>(ptr), diff))
0155         , v1_(*memunit_advanced(semantic_at_c<1>(ptr), diff))
0156     {}
0157 
0158     template <typename Ref>
0159     Ref deref() const
0160     {
0161         return Ref(*semantic_at_c<0>(*this), *semantic_at_c<1>(*this));
0162     }
0163 
0164     auto at(std::integral_constant<int, 0>)
0165         -> typename element_reference_type<homogeneous_color_base>::type
0166     { return v0_; }
0167 
0168     auto at(std::integral_constant<int, 0>) const
0169         -> typename element_const_reference_type<homogeneous_color_base>::type
0170     { return v0_; }
0171 
0172     auto at(std::integral_constant<int, 1>)
0173         -> typename element_reference_type<homogeneous_color_base>::type
0174     { return v1_; }
0175 
0176     auto at(std::integral_constant<int, 1>) const
0177         -> typename element_const_reference_type<homogeneous_color_base>::type
0178     { return v1_; }
0179 
0180     // Support for planar_pixel_reference operator[]
0181     auto at_c_dynamic(std::size_t i) const -> Element
0182     {
0183         if (i == 0)
0184             return v0_;
0185         else
0186             return v1_;
0187     }
0188 
0189 private:
0190     Element v0_;
0191     Element v1_;
0192 };
0193 
0194 /// \brief A homogeneous color base holding three color elements.
0195 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0196 /// \ingroup ColorBaseModelHomogeneous
0197 template <typename Element, typename Layout>
0198 struct homogeneous_color_base<Element, Layout, 3>
0199 {
0200     using layout_t = Layout;
0201 
0202     template
0203     <
0204         typename U = Element,
0205         typename = typename std::enable_if<!std::is_reference<U>::value>::type
0206     >
0207     homogeneous_color_base() : v0_{}, v1_{}, v2_{} {}
0208 
0209     explicit homogeneous_color_base(Element v) : v0_(v), v1_(v), v2_(v) {}
0210 
0211     homogeneous_color_base(Element v0, Element v1, Element v2)
0212         : v0_(v0), v1_(v1), v2_(v2)
0213     {}
0214 
0215     template <typename E2, typename L2>
0216     homogeneous_color_base(homogeneous_color_base<E2, L2, 3> const& c)
0217         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0218         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0219         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0220     {}
0221 
0222     // Support for l-value reference proxy copy construction
0223     template <typename E2, typename L2>
0224     homogeneous_color_base(homogeneous_color_base<E2, L2, 3>& c)
0225         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0226         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0227         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0228     {}
0229 
0230     // Support for planar_pixel_iterator construction and dereferencing
0231     template <typename P>
0232     homogeneous_color_base(P* p, bool)
0233         : v0_(&semantic_at_c<0>(*p))
0234         , v1_(&semantic_at_c<1>(*p))
0235         , v2_(&semantic_at_c<2>(*p))
0236     {}
0237 
0238     // Support for planar_pixel_reference offset constructor
0239     template <typename Ptr>
0240     homogeneous_color_base(Ptr const& ptr, std::ptrdiff_t diff)
0241         : v0_(*memunit_advanced(semantic_at_c<0>(ptr), diff))
0242         , v1_(*memunit_advanced(semantic_at_c<1>(ptr), diff))
0243         , v2_(*memunit_advanced(semantic_at_c<2>(ptr), diff))
0244     {}
0245 
0246     template <typename Ref>
0247     Ref deref() const
0248     {
0249         return Ref(
0250             *semantic_at_c<0>(*this),
0251             *semantic_at_c<1>(*this),
0252             *semantic_at_c<2>(*this));
0253     }
0254 
0255     auto at(std::integral_constant<int, 0>)
0256         -> typename element_reference_type<homogeneous_color_base>::type
0257     { return v0_; }
0258 
0259     auto at(std::integral_constant<int, 0>) const
0260         -> typename element_const_reference_type<homogeneous_color_base>::type
0261     { return v0_; }
0262 
0263     auto at(std::integral_constant<int, 1>)
0264         -> typename element_reference_type<homogeneous_color_base>::type
0265     { return v1_; }
0266 
0267     auto at(std::integral_constant<int, 1>) const
0268         -> typename element_const_reference_type<homogeneous_color_base>::type
0269     { return v1_; }
0270 
0271     auto at(std::integral_constant<int, 2>)
0272         -> typename element_reference_type<homogeneous_color_base>::type
0273     { return v2_; }
0274 
0275     auto at(std::integral_constant<int, 2>) const
0276         -> typename element_const_reference_type<homogeneous_color_base>::type
0277     { return v2_; }
0278 
0279     // Support for planar_pixel_reference operator[]
0280     auto at_c_dynamic(std::size_t i) const -> Element
0281     {
0282         switch (i)
0283         {
0284         case 0: return v0_;
0285         case 1: return v1_;
0286         }
0287         return v2_;
0288     }
0289 
0290 private:
0291     Element v0_;
0292     Element v1_;
0293     Element v2_;
0294 };
0295 
0296 /// \brief A homogeneous color base holding four color elements.
0297 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0298 /// \ingroup ColorBaseModelHomogeneous
0299 template <typename Element, typename Layout>
0300 struct homogeneous_color_base<Element, Layout, 4>
0301 {
0302     using layout_t = Layout;
0303 
0304     template
0305     <
0306         typename U = Element,
0307         typename = typename std::enable_if<!std::is_reference<U>::value>::type
0308     >
0309     homogeneous_color_base() : v0_{}, v1_{}, v2_{}, v3_{} {}
0310 
0311     explicit homogeneous_color_base(Element v) : v0_(v), v1_(v), v2_(v), v3_(v) {}
0312 
0313     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3)
0314         : v0_(v0), v1_(v1), v2_(v2), v3_(v3)
0315     {}
0316 
0317     template <typename E2, typename L2>
0318     homogeneous_color_base(homogeneous_color_base<E2, L2, 4> const& c)
0319         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0320         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0321         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0322         , v3_(gil::at_c<mapping_transform<Layout, L2, 3>::value>(c))
0323     {}
0324 
0325     // Support for l-value reference proxy copy construction
0326     template <typename E2, typename L2>
0327     homogeneous_color_base(homogeneous_color_base<E2, L2, 4>& c)
0328         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0329         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0330         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0331         , v3_(gil::at_c<mapping_transform<Layout, L2, 3>::value>(c))
0332     {}
0333 
0334     // Support for planar_pixel_iterator construction and dereferencing
0335     template <typename P>
0336     homogeneous_color_base(P * p, bool)
0337         : v0_(&semantic_at_c<0>(*p))
0338         , v1_(&semantic_at_c<1>(*p))
0339         , v2_(&semantic_at_c<2>(*p))
0340         , v3_(&semantic_at_c<3>(*p))
0341     {}
0342 
0343     // Support for planar_pixel_reference offset constructor
0344     template <typename Ptr>
0345     homogeneous_color_base(Ptr const& ptr, std::ptrdiff_t diff)
0346         : v0_(*memunit_advanced(semantic_at_c<0>(ptr), diff))
0347         , v1_(*memunit_advanced(semantic_at_c<1>(ptr), diff))
0348         , v2_(*memunit_advanced(semantic_at_c<2>(ptr), diff))
0349         , v3_(*memunit_advanced(semantic_at_c<3>(ptr), diff))
0350     {}
0351 
0352     template <typename Ref>
0353     Ref deref() const
0354     {
0355         return Ref(
0356             *semantic_at_c<0>(*this),
0357             *semantic_at_c<1>(*this),
0358             *semantic_at_c<2>(*this),
0359             *semantic_at_c<3>(*this));
0360     }
0361 
0362     auto at(std::integral_constant<int, 0>)
0363         -> typename element_reference_type<homogeneous_color_base>::type
0364     { return v0_; }
0365 
0366     auto at(std::integral_constant<int, 0>) const
0367         -> typename element_const_reference_type<homogeneous_color_base>::type
0368     { return v0_; }
0369 
0370     auto at(std::integral_constant<int, 1>)
0371         -> typename element_reference_type<homogeneous_color_base>::type
0372     { return v1_; }
0373 
0374     auto at(std::integral_constant<int, 1>) const
0375         -> typename element_const_reference_type<homogeneous_color_base>::type
0376     { return v1_; }
0377 
0378     auto at(std::integral_constant<int, 2>)
0379         -> typename element_reference_type<homogeneous_color_base>::type
0380     { return v2_; }
0381 
0382     auto at(std::integral_constant<int, 2>) const
0383         -> typename element_const_reference_type<homogeneous_color_base>::type
0384     { return v2_; }
0385 
0386     auto at(std::integral_constant<int, 3>)
0387         -> typename element_reference_type<homogeneous_color_base>::type
0388     { return v3_; }
0389 
0390     auto at(std::integral_constant<int, 3>) const
0391         -> typename element_const_reference_type<homogeneous_color_base>::type
0392     { return v3_; }
0393 
0394     // Support for planar_pixel_reference operator[]
0395     auto at_c_dynamic(std::size_t i) const -> Element
0396     {
0397         switch (i)
0398         {
0399         case 0: return v0_;
0400         case 1: return v1_;
0401         case 2: return v2_;
0402         }
0403         return v3_;
0404     }
0405 
0406 private:
0407     Element v0_;
0408     Element v1_;
0409     Element v2_;
0410     Element v3_;
0411 };
0412 
0413 /// \brief A homogeneous color base holding five color elements.
0414 /// Models HomogeneousColorBaseConcept or HomogeneousColorBaseValueConcept
0415 /// \ingroup ColorBaseModelHomogeneous
0416 template <typename Element, typename Layout>
0417 struct homogeneous_color_base<Element, Layout, 5>
0418 {
0419     using layout_t = Layout;
0420 
0421     template
0422     <
0423         typename U = Element,
0424         typename = typename std::enable_if<!std::is_reference<U>::value>::type
0425     >
0426     homogeneous_color_base()
0427         : v0_{}, v1_{}, v2_{}, v3_{}, v4_{}
0428     {}
0429 
0430     explicit homogeneous_color_base(Element v)
0431         : v0_(v), v1_(v), v2_(v), v3_(v), v4_(v)
0432     {}
0433 
0434     homogeneous_color_base(Element v0, Element v1, Element v2, Element v3, Element v4)
0435         : v0_(v0), v1_(v1), v2_(v2), v3_(v3), v4_(v4)
0436     {}
0437 
0438     template <typename E2, typename L2>
0439     homogeneous_color_base(homogeneous_color_base<E2, L2, 5> const& c)
0440         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0441         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0442         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0443         , v3_(gil::at_c<mapping_transform<Layout, L2, 3>::value>(c))
0444         , v4_(gil::at_c<mapping_transform<Layout, L2, 4>::value>(c))
0445     {}
0446 
0447     // Support for l-value reference proxy copy construction
0448     template <typename E2, typename L2>
0449     homogeneous_color_base(homogeneous_color_base<E2, L2, 5>& c)
0450         : v0_(gil::at_c<mapping_transform<Layout, L2, 0>::value>(c))
0451         , v1_(gil::at_c<mapping_transform<Layout, L2, 1>::value>(c))
0452         , v2_(gil::at_c<mapping_transform<Layout, L2, 2>::value>(c))
0453         , v3_(gil::at_c<mapping_transform<Layout, L2, 3>::value>(c))
0454         , v4_(gil::at_c<mapping_transform<Layout, L2, 4>::value>(c))
0455     {}
0456 
0457     // Support for planar_pixel_iterator construction and dereferencing
0458     template <typename P>
0459     homogeneous_color_base(P* p, bool)
0460         : v0_(&semantic_at_c<0>(*p))
0461         , v1_(&semantic_at_c<1>(*p))
0462         , v2_(&semantic_at_c<2>(*p))
0463         , v3_(&semantic_at_c<3>(*p))
0464         , v4_(&semantic_at_c<4>(*p))
0465     {}
0466 
0467     // Support for planar_pixel_reference offset constructor
0468     template <typename Ptr>
0469     homogeneous_color_base(Ptr const& ptr, std::ptrdiff_t diff)
0470         : v0_(*memunit_advanced(semantic_at_c<0>(ptr), diff))
0471         , v1_(*memunit_advanced(semantic_at_c<1>(ptr), diff))
0472         , v2_(*memunit_advanced(semantic_at_c<2>(ptr), diff))
0473         , v3_(*memunit_advanced(semantic_at_c<3>(ptr), diff))
0474         , v4_(*memunit_advanced(semantic_at_c<4>(ptr), diff))
0475     {}
0476 
0477 
0478     auto at(std::integral_constant<int, 0>)
0479         -> typename element_reference_type<homogeneous_color_base>::type
0480     { return v0_; }
0481 
0482     auto at(std::integral_constant<int, 0>) const
0483         -> typename element_const_reference_type<homogeneous_color_base>::type
0484     { return v0_; }
0485 
0486     auto at(std::integral_constant<int, 1>)
0487         -> typename element_reference_type<homogeneous_color_base>::type
0488     { return v1_; }
0489 
0490     auto at(std::integral_constant<int, 1>) const
0491         -> typename element_const_reference_type<homogeneous_color_base>::type
0492     { return v1_; }
0493 
0494     auto at(std::integral_constant<int, 2>)
0495         -> typename element_reference_type<homogeneous_color_base>::type
0496     { return v2_; }
0497 
0498     auto at(std::integral_constant<int, 2>) const
0499         -> typename element_const_reference_type<homogeneous_color_base>::type
0500     { return v2_; }
0501 
0502     auto at(std::integral_constant<int, 3>)
0503         -> typename element_reference_type<homogeneous_color_base>::type
0504     { return v3_; }
0505 
0506     auto at(std::integral_constant<int, 3>) const
0507         -> typename element_const_reference_type<homogeneous_color_base>::type
0508     { return v3_; }
0509 
0510     auto at(std::integral_constant<int, 4>)
0511         -> typename element_reference_type<homogeneous_color_base>::type
0512     { return v4_; }
0513 
0514     auto at(std::integral_constant<int, 4>) const
0515         -> typename element_const_reference_type<homogeneous_color_base>::type
0516     { return v4_; }
0517 
0518     template <typename Ref>
0519     Ref deref() const
0520     {
0521         return Ref(
0522             *semantic_at_c<0>(*this),
0523             *semantic_at_c<1>(*this),
0524             *semantic_at_c<2>(*this),
0525             *semantic_at_c<3>(*this),
0526             *semantic_at_c<4>(*this));
0527     }
0528 
0529     // Support for planar_pixel_reference operator[]
0530     auto at_c_dynamic(std::size_t i) const -> Element
0531     {
0532         switch (i)
0533         {
0534         case 0: return v0_;
0535         case 1: return v1_;
0536         case 2: return v2_;
0537         case 3: return v3_;
0538         }
0539         return v4_;
0540     }
0541 
0542 private:
0543     Element v0_;
0544     Element v1_;
0545     Element v2_;
0546     Element v3_;
0547     Element v4_;
0548 };
0549 
0550 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0551 #pragma warning(pop)
0552 #endif
0553 
0554 // The following way of casting adjacent channels (the contents of color_base) into an array appears to be unsafe
0555 // -- there is no guarantee that the compiler won't add any padding between adjacent channels.
0556 // Note, however, that GIL _must_ be compiled with compiler settings ensuring there is no padding in the color base structs.
0557 // This is because the color base structs must model the interleaved organization in memory. In other words, the client may
0558 // 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)
0559 // with no padding. We have tested with char/int/float/double channels on gcc and VC and have so far discovered no problem.
0560 // We have even tried using strange channels consisting of short + char (3 bytes). With the default 4-byte alignment on VC, the size
0561 // 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.
0562 // However, the client must nevertheless ensure that proper compiler settings are used for their compiler and their channel types.
0563 
0564 template <typename Element, typename Layout, int K>
0565 auto dynamic_at_c(homogeneous_color_base<Element,Layout,K>& cb, std::size_t i)
0566     -> typename element_reference_type<homogeneous_color_base<Element, Layout, K>>::type
0567 {
0568     BOOST_ASSERT(i < K);
0569     return (gil_reinterpret_cast<Element*>(&cb))[i];
0570 }
0571 
0572 template <typename Element, typename Layout, int K>
0573 auto dynamic_at_c(homogeneous_color_base<Element, Layout, K> const& cb, std::size_t i)
0574     -> typename element_const_reference_type
0575         <
0576             homogeneous_color_base<Element, Layout, K>
0577         >::type
0578 {
0579     BOOST_ASSERT(i < K);
0580     return (gil_reinterpret_cast_c<const Element*>(&cb))[i];
0581 }
0582 
0583 template <typename Element, typename Layout, int K>
0584 auto dynamic_at_c(homogeneous_color_base<Element&, Layout, K> const& cb, std::size_t i)
0585     -> typename element_reference_type
0586         <
0587             homogeneous_color_base<Element&, Layout, K>
0588         >::type
0589 {
0590     BOOST_ASSERT(i < K);
0591     return cb.at_c_dynamic(i);
0592 }
0593 
0594 template <typename Element, typename Layout, int K>
0595 auto dynamic_at_c(
0596     homogeneous_color_base<Element const&, Layout, K>const& cb, std::size_t i)
0597     -> typename element_const_reference_type
0598         <
0599             homogeneous_color_base<Element const&, Layout, K>
0600         >::type
0601 {
0602     BOOST_ASSERT(i < K);
0603     return cb.at_c_dynamic(i);
0604 }
0605 
0606 } // namespace detail
0607 
0608 template <typename Element, typename Layout, int K1, int K>
0609 struct kth_element_type<detail::homogeneous_color_base<Element, Layout, K1>, K>
0610 {
0611     using type = Element;
0612 };
0613 
0614 template <typename Element, typename Layout, int K1, int K>
0615 struct kth_element_reference_type<detail::homogeneous_color_base<Element, Layout, K1>, K>
0616     : std::add_lvalue_reference<Element>
0617 {};
0618 
0619 template <typename Element, typename Layout, int K1, int K>
0620 struct kth_element_const_reference_type
0621     <
0622         detail::homogeneous_color_base<Element, Layout, K1>,
0623         K
0624     >
0625     : std::add_lvalue_reference<typename std::add_const<Element>::type>
0626 {};
0627 
0628 /// \brief Provides mutable access to the K-th element, in physical order
0629 /// \ingroup ColorBaseModelHomogeneous
0630 template <int K, typename E, typename L, int N>
0631 inline
0632 auto at_c(detail::homogeneous_color_base<E, L, N>& p)
0633     -> typename std::add_lvalue_reference<E>::type
0634 {
0635     return p.at(std::integral_constant<int, K>());
0636 }
0637 
0638 /// \brief Provides constant access to the K-th element, in physical order
0639 /// \ingroup ColorBaseModelHomogeneous
0640 template <int K, typename E, typename L, int N>
0641 inline
0642 auto at_c(const detail::homogeneous_color_base<E, L, N>& p)
0643     -> typename std::add_lvalue_reference<typename std::add_const<E>::type>::type
0644 {
0645     return p.at(std::integral_constant<int, K>());
0646 }
0647 
0648 namespace detail
0649 {
0650 
0651 struct swap_fn
0652 {
0653     template <typename T>
0654     void operator()(T& x, T& y) const
0655     {
0656         using std::swap;
0657         swap(x, y);
0658     }
0659 };
0660 
0661 } // namespace detail
0662 
0663 template <typename E, typename L, int N>
0664 inline
0665 void swap(
0666     detail::homogeneous_color_base<E, L, N>& x,
0667     detail::homogeneous_color_base<E, L, N>& y)
0668 {
0669     static_for_each(x, y, detail::swap_fn());
0670 }
0671 
0672 }}  // namespace boost::gil
0673 
0674 #endif