File indexing completed on 2024-11-15 09:12:39
0001
0002
0003
0004
0005
0006
0007
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
0024 template <typename P> P* memunit_advanced(const P* p, std::ptrdiff_t diff);
0025
0026
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
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
0064
0065
0066
0067
0068
0069 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0070 #pragma warning(push)
0071 #pragma warning(disable:4512)
0072 #endif
0073
0074
0075
0076
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
0105
0106 operator Element() const { return v0_; }
0107
0108 private:
0109 Element v0_;
0110 };
0111
0112
0113
0114
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
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
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
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
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
0195
0196
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
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
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
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
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
0297
0298
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
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
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
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
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
0414
0415
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
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
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
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
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
0555
0556
0557
0558
0559
0560
0561
0562
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 }
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
0629
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
0639
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 }
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 }}
0673
0674 #endif