File indexing completed on 2024-11-15 09:12:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
0010 #define BOOST_GIL_COLOR_BASE_ALGORITHM_HPP
0011
0012 #include <boost/gil/concepts.hpp>
0013 #include <boost/gil/utilities.hpp>
0014 #include <boost/gil/detail/mp11.hpp>
0015
0016 #include <boost/config.hpp>
0017
0018 #include <algorithm>
0019 #include <type_traits>
0020
0021 namespace boost { namespace gil {
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 template <typename ColorBase>
0042 struct size : public mp11::mp_size<typename ColorBase::layout_t::color_space_t> {};
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 template <typename ColorBase, int K>
0077 struct kth_semantic_element_type
0078 {
0079 using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0080 static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0081 "K index should be less than size of channel_mapping_t sequence");
0082
0083 static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0084 using type = typename kth_element_type<ColorBase, semantic_index>::type;
0085 };
0086
0087
0088
0089 template <typename ColorBase, int K>
0090 struct kth_semantic_element_reference_type
0091 {
0092 using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0093 static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0094 "K index should be less than size of channel_mapping_t sequence");
0095
0096 static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0097 using type = typename kth_element_reference_type<ColorBase, semantic_index>::type;
0098 static type get(ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
0099 };
0100
0101
0102
0103 template <typename ColorBase, int K>
0104 struct kth_semantic_element_const_reference_type
0105 {
0106 using channel_mapping_t = typename ColorBase::layout_t::channel_mapping_t;
0107 static_assert(K < mp11::mp_size<channel_mapping_t>::value,
0108 "K index should be less than size of channel_mapping_t sequence");
0109
0110 static constexpr int semantic_index = mp11::mp_at_c<channel_mapping_t, K>::type::value;
0111 using type = typename kth_element_const_reference_type<ColorBase,semantic_index>::type;
0112 static type get(const ColorBase& cb) { return gil::at_c<semantic_index>(cb); }
0113 };
0114
0115
0116
0117 template <int K, typename ColorBase>
0118 inline
0119 auto semantic_at_c(ColorBase& p)
0120 -> typename std::enable_if
0121 <
0122 !std::is_const<ColorBase>::value,
0123 typename kth_semantic_element_reference_type<ColorBase, K>::type
0124 >::type
0125 {
0126 return kth_semantic_element_reference_type<ColorBase, K>::get(p);
0127 }
0128
0129
0130
0131 template <int K, typename ColorBase>
0132 inline
0133 auto semantic_at_c(ColorBase const& p)
0134 -> typename kth_semantic_element_const_reference_type<ColorBase, K>::type
0135 {
0136 return kth_semantic_element_const_reference_type<ColorBase, K>::get(p);
0137 }
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 template <typename ColorBase, typename Color>
0165 struct contains_color
0166 : mp11::mp_contains<typename ColorBase::layout_t::color_space_t, Color>
0167 {};
0168
0169 template <typename ColorBase, typename Color>
0170 struct color_index_type : public detail::type_to_index<typename ColorBase::layout_t::color_space_t,Color> {};
0171
0172
0173
0174 template <typename ColorBase, typename Color>
0175 struct color_element_type : public kth_semantic_element_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0176
0177
0178
0179 template <typename ColorBase, typename Color>
0180 struct color_element_reference_type : public kth_semantic_element_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0181
0182
0183
0184 template <typename ColorBase, typename Color>
0185 struct color_element_const_reference_type : public kth_semantic_element_const_reference_type<ColorBase,color_index_type<ColorBase,Color>::value> {};
0186
0187
0188
0189 template <typename ColorBase, typename Color>
0190 auto get_color(ColorBase& cb, Color=Color())
0191 -> typename color_element_reference_type<ColorBase,Color>::type
0192 {
0193 return color_element_reference_type<ColorBase,Color>::get(cb);
0194 }
0195
0196
0197
0198 template <typename ColorBase, typename Color>
0199 auto get_color(const ColorBase& cb, Color=Color())
0200 -> typename color_element_const_reference_type<ColorBase,Color>::type
0201 {
0202 return color_element_const_reference_type<ColorBase,Color>::get(cb);
0203 }
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 template <typename ColorBase>
0225 struct element_type : public kth_element_type<ColorBase, 0> {};
0226
0227
0228
0229 template <typename ColorBase>
0230 struct element_reference_type : public kth_element_reference_type<ColorBase, 0> {};
0231
0232
0233
0234 template <typename ColorBase>
0235 struct element_const_reference_type : public kth_element_const_reference_type<ColorBase, 0> {};
0236
0237
0238 namespace detail {
0239
0240
0241 template <int N>
0242 struct element_recursion
0243 {
0244
0245 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0246 #pragma GCC diagnostic push
0247 #pragma GCC diagnostic ignored "-Wconversion"
0248 #pragma GCC diagnostic ignored "-Wfloat-equal"
0249 #endif
0250
0251 template <typename P1,typename P2>
0252 static bool static_equal(const P1& p1, const P2& p2)
0253 {
0254 return element_recursion<N-1>::static_equal(p1,p2) &&
0255 semantic_at_c<N-1>(p1)==semantic_at_c<N-1>(p2);
0256 }
0257
0258 template <typename P1,typename P2>
0259 static void static_copy(const P1& p1, P2& p2)
0260 {
0261 element_recursion<N-1>::static_copy(p1,p2);
0262 semantic_at_c<N-1>(p2)=semantic_at_c<N-1>(p1);
0263 }
0264
0265 template <typename P,typename T2>
0266 static void static_fill(P& p, T2 v)
0267 {
0268 element_recursion<N-1>::static_fill(p,v);
0269 semantic_at_c<N-1>(p)=v;
0270 }
0271
0272 template <typename Dst,typename Op>
0273 static void static_generate(Dst& dst, Op op)
0274 {
0275 element_recursion<N-1>::static_generate(dst,op);
0276 semantic_at_c<N-1>(dst)=op();
0277 }
0278
0279 #if defined(BOOST_GCC) && (BOOST_GCC >= 40900)
0280 #pragma GCC diagnostic pop
0281 #endif
0282
0283
0284 template <typename P1,typename Op>
0285 static Op static_for_each(P1& p1, Op op) {
0286 Op op2(element_recursion<N-1>::static_for_each(p1,op));
0287 op2(semantic_at_c<N-1>(p1));
0288 return op2;
0289 }
0290 template <typename P1,typename Op>
0291 static Op static_for_each(const P1& p1, Op op) {
0292 Op op2(element_recursion<N-1>::static_for_each(p1,op));
0293 op2(semantic_at_c<N-1>(p1));
0294 return op2;
0295 }
0296
0297 template <typename P1,typename P2,typename Op>
0298 static Op static_for_each(P1& p1, P2& p2, Op op) {
0299 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0300 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0301 return op2;
0302 }
0303 template <typename P1,typename P2,typename Op>
0304 static Op static_for_each(P1& p1, const P2& p2, Op op) {
0305 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0306 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0307 return op2;
0308 }
0309 template <typename P1,typename P2,typename Op>
0310 static Op static_for_each(const P1& p1, P2& p2, Op op) {
0311 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0312 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0313 return op2;
0314 }
0315 template <typename P1,typename P2,typename Op>
0316 static Op static_for_each(const P1& p1, const P2& p2, Op op) {
0317 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op));
0318 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2));
0319 return op2;
0320 }
0321
0322 template <typename P1,typename P2,typename P3,typename Op>
0323 static Op static_for_each(P1& p1, P2& p2, P3& p3, Op op) {
0324 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0325 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0326 return op2;
0327 }
0328 template <typename P1,typename P2,typename P3,typename Op>
0329 static Op static_for_each(P1& p1, P2& p2, const P3& p3, Op op) {
0330 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0331 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0332 return op2;
0333 }
0334 template <typename P1,typename P2,typename P3,typename Op>
0335 static Op static_for_each(P1& p1, const P2& p2, P3& p3, Op op) {
0336 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0337 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0338 return op2;
0339 }
0340 template <typename P1,typename P2,typename P3,typename Op>
0341 static Op static_for_each(P1& p1, const P2& p2, const P3& p3, Op op) {
0342 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0343 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0344 return op2;
0345 }
0346 template <typename P1,typename P2,typename P3,typename Op>
0347 static Op static_for_each(const P1& p1, P2& p2, P3& p3, Op op) {
0348 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0349 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0350 return op2;
0351 }
0352 template <typename P1,typename P2,typename P3,typename Op>
0353 static Op static_for_each(const P1& p1, P2& p2, const P3& p3, Op op) {
0354 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0355 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0356 return op2;
0357 }
0358 template <typename P1,typename P2,typename P3,typename Op>
0359 static Op static_for_each(const P1& p1, const P2& p2, P3& p3, Op op) {
0360 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0361 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0362 return op2;
0363 }
0364 template <typename P1,typename P2,typename P3,typename Op>
0365 static Op static_for_each(const P1& p1, const P2& p2, const P3& p3, Op op) {
0366 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op));
0367 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2), semantic_at_c<N-1>(p3));
0368 return op2;
0369 }
0370
0371 template <typename P1,typename Dst,typename Op>
0372 static Op static_transform(P1& src, Dst& dst, Op op) {
0373 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
0374 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
0375 return op2;
0376 }
0377 template <typename P1,typename Dst,typename Op>
0378 static Op static_transform(const P1& src, Dst& dst, Op op) {
0379 Op op2(element_recursion<N-1>::static_transform(src,dst,op));
0380 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src));
0381 return op2;
0382 }
0383
0384 template <typename P1,typename P2,typename Dst,typename Op>
0385 static Op static_transform(P1& src1, P2& src2, Dst& dst, Op op) {
0386 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0387 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0388 return op2;
0389 }
0390 template <typename P1,typename P2,typename Dst,typename Op>
0391 static Op static_transform(P1& src1, const P2& src2, Dst& dst, Op op) {
0392 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0393 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0394 return op2;
0395 }
0396 template <typename P1,typename P2,typename Dst,typename Op>
0397 static Op static_transform(const P1& src1, P2& src2, Dst& dst, Op op) {
0398 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0399 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0400 return op2;
0401 }
0402 template <typename P1,typename P2,typename Dst,typename Op>
0403 static Op static_transform(const P1& src1, const P2& src2, Dst& dst, Op op) {
0404 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op));
0405 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src1), semantic_at_c<N-1>(src2));
0406 return op2;
0407 }
0408 };
0409
0410
0411 template<> struct element_recursion<0> {
0412
0413 template <typename P1,typename P2>
0414 static bool static_equal(const P1&, const P2&) { return true; }
0415
0416 template <typename P1,typename P2>
0417 static void static_copy(const P1&, const P2&) {}
0418
0419 template <typename P, typename T2>
0420 static void static_fill(const P&, T2) {}
0421
0422 template <typename Dst,typename Op>
0423 static void static_generate(const Dst&,Op){}
0424
0425 template <typename P1,typename Op>
0426 static Op static_for_each(const P1&,Op op){return op;}
0427
0428 template <typename P1,typename P2,typename Op>
0429 static Op static_for_each(const P1&,const P2&,Op op){return op;}
0430
0431 template <typename P1,typename P2,typename P3,typename Op>
0432 static Op static_for_each(const P1&,const P2&,const P3&,Op op){return op;}
0433
0434 template <typename P1,typename Dst,typename Op>
0435 static Op static_transform(const P1&,const Dst&,Op op){return op;}
0436
0437 template <typename P1,typename P2,typename Dst,typename Op>
0438 static Op static_transform(const P1&,const P2&,const Dst&,Op op){return op;}
0439 };
0440
0441
0442 template <typename Q>
0443 inline auto mutable_min(Q const& x, Q const& y) -> Q const& { return x<y ? x : y; }
0444
0445 template <typename Q>
0446 inline auto mutable_min(Q& x, Q& y) -> Q& { return x<y ? x : y; }
0447
0448 template <typename Q>
0449 inline auto mutable_max(Q const& x, Q const& y) -> Q const& { return x<y ? y : x; }
0450
0451 template <typename Q>
0452 inline auto mutable_max(Q& x, Q& y) -> Q& { return x<y ? y : x; }
0453
0454
0455
0456 template <int N>
0457 struct min_max_recur
0458 {
0459 template <typename P>
0460 static auto max_(P const& p) -> typename element_const_reference_type<P>::type
0461 {
0462 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
0463 }
0464
0465 template <typename P>
0466 static auto max_(P& p) -> typename element_reference_type<P>::type
0467 {
0468 return mutable_max(min_max_recur<N-1>::max_(p),semantic_at_c<N-1>(p));
0469 }
0470
0471 template <typename P>
0472 static auto min_(P const& p) -> typename element_const_reference_type<P>::type
0473 {
0474 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
0475 }
0476
0477 template <typename P>
0478 static auto min_(P& p) -> typename element_reference_type<P>::type
0479 {
0480 return mutable_min(min_max_recur<N-1>::min_(p),semantic_at_c<N-1>(p));
0481 }
0482 };
0483
0484
0485 template <>
0486 struct min_max_recur<1>
0487 {
0488 template <typename P>
0489 static auto max_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
0490
0491 template <typename P>
0492 static auto max_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
0493
0494 template <typename P>
0495 static auto min_(P const& p) -> typename element_const_reference_type<P>::type { return semantic_at_c<0>(p); }
0496
0497 template <typename P>
0498 static auto min_(P& p) -> typename element_reference_type<P>::type { return semantic_at_c<0>(p); }
0499 };
0500 }
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515 template <typename P>
0516 BOOST_FORCEINLINE
0517 auto static_max(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
0518
0519 template <typename P>
0520 BOOST_FORCEINLINE
0521 auto static_max(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::max_(p); }
0522
0523 template <typename P>
0524 BOOST_FORCEINLINE
0525 auto static_min(P const& p) -> typename element_const_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
0526
0527 template <typename P>
0528 BOOST_FORCEINLINE
0529 auto static_min(P& p) -> typename element_reference_type<P>::type { return detail::min_max_recur<size<P>::value>::min_(p); }
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547 template <typename P1,typename P2>
0548 BOOST_FORCEINLINE
0549 bool static_equal(P1 const& p1, const P2& p2) { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); }
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 template <typename Src,typename Dst>
0569 BOOST_FORCEINLINE
0570 void static_copy(const Src& src, Dst& dst)
0571 {
0572 detail::element_recursion<size<Dst>::value>::static_copy(src, dst);
0573 }
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 template <typename P,typename V>
0590 BOOST_FORCEINLINE
0591 void static_fill(P& p, const V& v)
0592 {
0593 detail::element_recursion<size<P>::value>::static_fill(p,v);
0594 }
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617 template <typename P1,typename Op>
0618 BOOST_FORCEINLINE
0619 void static_generate(P1& dst,Op op) { detail::element_recursion<size<P1>::value>::static_generate(dst,op); }
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649 template <typename Src,typename Dst,typename Op>
0650 BOOST_FORCEINLINE
0651 Op static_transform(Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
0652 template <typename Src,typename Dst,typename Op>
0653 BOOST_FORCEINLINE
0654 Op static_transform(const Src& src,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(src,dst,op); }
0655
0656 template <typename P2,typename P3,typename Dst,typename Op>
0657 BOOST_FORCEINLINE
0658 Op static_transform(P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0659 template <typename P2,typename P3,typename Dst,typename Op>
0660 BOOST_FORCEINLINE
0661 Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0662 template <typename P2,typename P3,typename Dst,typename Op>
0663 BOOST_FORCEINLINE
0664 Op static_transform(const P2& p2,P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0665 template <typename P2,typename P3,typename Dst,typename Op>
0666 BOOST_FORCEINLINE
0667 Op static_transform(const P2& p2,const P3& p3,Dst& dst,Op op) { return detail::element_recursion<size<Dst>::value>::static_transform(p2,p3,dst,op); }
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696 template <typename P1,typename Op>
0697 BOOST_FORCEINLINE
0698 Op static_for_each( P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
0699 template <typename P1,typename Op>
0700 BOOST_FORCEINLINE
0701 Op static_for_each(const P1& p1, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); }
0702
0703 template <typename P1,typename P2,typename Op>
0704 BOOST_FORCEINLINE
0705 Op static_for_each(P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0706 template <typename P1,typename P2,typename Op>
0707 BOOST_FORCEINLINE
0708 Op static_for_each(P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0709 template <typename P1,typename P2,typename Op>
0710 BOOST_FORCEINLINE
0711 Op static_for_each(const P1& p1, P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0712 template <typename P1,typename P2,typename Op>
0713 BOOST_FORCEINLINE
0714 Op static_for_each(const P1& p1,const P2& p2, Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); }
0715
0716 template <typename P1,typename P2,typename P3,typename Op>
0717 BOOST_FORCEINLINE
0718 Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0719 template <typename P1,typename P2,typename P3,typename Op>
0720 BOOST_FORCEINLINE
0721 Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0722 template <typename P1,typename P2,typename P3,typename Op>
0723 BOOST_FORCEINLINE
0724 Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0725 template <typename P1,typename P2,typename P3,typename Op>
0726 BOOST_FORCEINLINE
0727 Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0728 template <typename P1,typename P2,typename P3,typename Op>
0729 BOOST_FORCEINLINE
0730 Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0731 template <typename P1,typename P2,typename P3,typename Op>
0732 BOOST_FORCEINLINE
0733 Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0734 template <typename P1,typename P2,typename P3,typename Op>
0735 BOOST_FORCEINLINE
0736 Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0737 template <typename P1,typename P2,typename P3,typename Op>
0738 BOOST_FORCEINLINE
0739 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,p3,op); }
0740
0741
0742 }}
0743
0744 #endif