Go to the documentation of this file.
12 #ifndef GIL_REDUCE_HPP
13 #define GIL_REDUCE_HPP
15 #include <boost/mpl/insert_range.hpp>
16 #include <boost/mpl/range_c.hpp>
17 #include <boost/mpl/vector_c.hpp>
18 #include <boost/mpl/back.hpp>
19 #include <boost/mpl/vector.hpp>
20 #include <boost/mpl/long.hpp>
21 #include <boost/mpl/logical.hpp>
22 #include <boost/mpl/transform.hpp>
23 #include <boost/mpl/insert.hpp>
24 #include <boost/mpl/transform.hpp>
26 #include "../../metafunctions.hpp"
27 #include "../../typedefs.hpp"
40 #ifdef GIL_REDUCE_CODE_BLOAT
44 #define GIL_BINARY_REDUCE_LIMIT 226
46 namespace boost { namespace mpl {
57 template < typename SrcTypes, typename DstTypes>
58 struct mapping_vector {};
60 template < typename SrcTypes, typename DstTypes, long K>
61 struct at_c<mapping_vector<SrcTypes,DstTypes>, K> {
62 static const std::size_t value=size<DstTypes>::value - order<DstTypes, typename gil::at_c<SrcTypes,K>::type>::type::value +1;
63 typedef size_t<value> type;
66 template < typename SrcTypes, typename DstTypes>
67 struct size<mapping_vector<SrcTypes,DstTypes> > {
68 typedef typename size<SrcTypes>::type type;
69 static const std::size_t value=type::value;
82 template < typename SFirst, std:: size_t NLeft>
83 struct copy_to_vector_impl {
85 typedef typename deref<SFirst>::type T;
86 typedef typename next<SFirst>::type next;
87 typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;
89 typedef typename push_front<rest, T>::type type;
92 template < typename SFirst>
93 struct copy_to_vector_impl<SFirst,1> {
94 typedef vector<typename deref<SFirst>::type> type;
98 template < typename Src>
99 struct copy_to_vector {
100 typedef typename detail::copy_to_vector_impl<typename begin<Src>::type, size<Src>::value>::type type;
104 struct copy_to_vector<set<> > {
105 typedef vector0<> type;
110 namespace boost { namespace gil {
134 template < typename Types, typename Op>
135 struct unary_reduce_impl {
136 typedef typename mpl::transform<Types, detail::reduce<Op, mpl::_1> >::type reduced_t;
137 typedef typename mpl::copy<reduced_t, mpl::inserter<mpl::set<>, mpl::insert<mpl::_1,mpl::_2> > >::type unique_t;
138 static const bool is_single=mpl::size<unique_t>::value==1;
141 template <typename Types, typename Op, bool IsSingle=unary_reduce_impl<Types,Op>::is_single>
142 struct unary_reduce : public unary_reduce_impl<Types,Op> {
143 typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;
144 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
146 static unsigned short inline map_index(std::size_t index) {
147 typedef typename mpl::mapping_vector<reduced_t, unique_t> indices_t;
148 return gil::at_c<indices_t, unsigned short>(index);
150 template < typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc( const Bits& bits, std::size_t index, Op op) {
151 return apply_operation_basec<unique_t>(bits,map_index(index),op);
154 template < typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
155 return apply_operation_base<unique_t>(bits,map_index(index),op);
159 template < typename Types, typename Op>
160 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op> {
161 typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
162 static unsigned short inline map_index(std::size_t index) { return 0; }
164 template < typename Bits> BOOST_FORCEINLINE static typename Op::result_type applyc( const Bits& bits, std::size_t index, Op op) {
165 return op(*gil_reinterpret_cast_c< const typename mpl::front<unique_t>::type*>(&bits));
168 template < typename Bits> BOOST_FORCEINLINE static typename Op::result_type apply(Bits& bits, std::size_t index, Op op) {
169 return op(*gil_reinterpret_cast< typename mpl::front<unique_t>::type*>(&bits));
188 struct pair_generator {
189 template < typename Vec2> struct apply {
190 typedef std::pair<const typename mpl::at_c<Vec2,0>::type*, const typename mpl::at_c<Vec2,1>::type*> type;
195 template < typename Unary1, typename Unary2, typename Op, bool IsComplex>
196 struct binary_reduce_impl {
198 typedef typename mpl::copy_to_vector<typename Unary1::unique_t>::type vec1_types;
199 typedef typename mpl::copy_to_vector<typename Unary2::unique_t>::type vec2_types;
201 typedef mpl::cross_vector<mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
202 typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;
204 static unsigned short inline map_index(std::size_t index1, std::size_t index2) {
205 unsigned short r1=Unary1::map_index(index1);
206 unsigned short r2=Unary2::map_index(index2);
207 return bin_reduced_t::map_index(r2*mpl::size<vec1_types>::value + r1);
210 typedef typename bin_reduced_t::unique_t unique_t;
212 template < typename Bits1, typename Bits2>
213 static typename Op::result_type inline apply( const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
214 std::pair<const void*,const void*> pr(&bits1, &bits2);
215 return apply_operation_basec<unique_t>(pr, map_index(index1,index2),op);
220 template < typename Unary1, typename Unary2, typename Op>
221 struct binary_reduce_impl<Unary1,Unary2,Op,true> {
222 template < typename Bits1, typename Bits2>
223 static typename Op::result_type inline apply( const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
224 return apply_operation_base<Unary1::unique_t,Unary2::unique_t>(bits1, index1, bits2, index2, op);
230 template < typename Types1, typename Types2, typename Op>
231 struct binary_reduce {
233 typedef unary_reduce<Types1,Op> unary1_t;
234 typedef unary_reduce<Types2,Op> unary2_t;
236 static const std::size_t CROSS_SIZE = mpl::size<typename unary1_t::unique_t>::value *
237 mpl::size<typename unary2_t::unique_t>::value;
239 typedef detail::binary_reduce_impl<unary1_t,unary2_t,Op, (CROSS_SIZE>GIL_BINARY_REDUCE_LIMIT)> impl;
241 template < typename Bits1, typename Bits2>
242 static typename Op::result_type inline apply( const Bits1& bits1, std::size_t index1, const Bits2& bits2, std::size_t index2, Op op) {
243 return impl::apply(bits1,index1,bits2,index2,op);
247 template < typename Types, typename UnaryOp>
248 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation(variant<Types>& arg, UnaryOp op) {
249 return unary_reduce<Types,UnaryOp>::template apply(arg._bits, arg._index ,op);
252 template < typename Types, typename UnaryOp>
253 BOOST_FORCEINLINE typename UnaryOp::result_type apply_operation( const variant<Types>& arg, UnaryOp op) {
254 return unary_reduce<Types,UnaryOp>::template applyc(arg._bits, arg._index ,op);
257 template < typename Types1, typename Types2, typename BinaryOp>
258 BOOST_FORCEINLINE typename BinaryOp::result_type apply_operation( const variant<Types1>& arg1, const variant<Types2>& arg2, BinaryOp op) {
259 return binary_reduce<Types1,Types2,BinaryOp>::template apply(arg1._bits, arg1._index, arg2._bits, arg2._index, op);
262 #undef GIL_BINARY_REDUCE_LIMIT
267 namespace boost { namespace mpl {
287 template < typename VecOfVecs, typename TypeGen>
288 struct cross_vector {};
292 template < typename VecOfVecs, typename TypeGen, std:: size_t K>
293 struct cross_iterator {
294 typedef mpl::random_access_iterator_tag category;
306 template < typename VecOfVecs, typename TypeGen, std:: size_t K>
307 struct deref<cross_iterator<VecOfVecs,TypeGen,K> > {
309 typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
311 typedef typename TypeGen::template apply<DerefTypes>::type type;
316 template < typename VecOfVecs, typename TypeGen, std:: size_t K>
317 struct next<cross_iterator<VecOfVecs,TypeGen,K> > {
318 typedef cross_iterator<VecOfVecs,TypeGen,K+1> type;
323 template < typename VecOfVecs, typename TypeGen, std:: size_t K>
324 struct prior<cross_iterator<VecOfVecs,TypeGen,K> > {
325 typedef cross_iterator<VecOfVecs,TypeGen,K-1> type;
330 template < typename VecOfVecs, typename TypeGen, std:: size_t K, typename Distance>
331 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > {
332 typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type;
338 template < typename VecOfVecs, typename TypeGen, std:: size_t K1, std:: size_t K2>
339 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>, cross_iterator<VecOfVecs,TypeGen,K2> > {
340 typedef size_t<K2-K1> type;
348 template < typename VecOfVecs, typename TypeGen>
349 struct size<cross_vector<VecOfVecs,TypeGen> > {
350 typedef typename fold<VecOfVecs, size_t<1>, times<_1, size<_2> > >::type type;
351 static const std::size_t value=type::value;
356 template < typename VecOfVecs, typename TypeGen>
357 struct empty<cross_vector<VecOfVecs,TypeGen> > {
358 typedef typename empty<VecOfVecs>::type type;
363 template < typename VecOfVecs, typename TypeGen, typename K>
364 struct at<cross_vector<VecOfVecs,TypeGen>, K> {
366 typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
368 typedef typename deref<KthIterator>::type type;
373 template < typename VecOfVecs, typename TypeGen>
374 struct begin<cross_vector<VecOfVecs,TypeGen> > {
375 typedef cross_iterator<VecOfVecs,TypeGen,0> type;
380 template < typename VecOfVecs, typename TypeGen>
381 struct end<cross_vector<VecOfVecs,TypeGen> > {
383 typedef cross_vector<VecOfVecs,TypeGen> this_t;
385 typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
390 template < typename VecOfVecs, typename TypeGen>
391 struct front<cross_vector<VecOfVecs,TypeGen> > {
393 typedef cross_vector<VecOfVecs,TypeGen> this_t;
395 typedef typename deref<typename begin<this_t>::type>::type type;
400 template < typename VecOfVecs, typename TypeGen>
401 struct back<cross_vector<VecOfVecs,TypeGen> > {
403 typedef cross_vector<VecOfVecs,TypeGen> this_t;
404 typedef typename size<this_t>::type size;
405 typedef typename minus<size, size_t<1> >::type last_index;
407 typedef typename at<this_t, last_index>::type type;
412 template < typename VecOfVecs, typename TypeGen, typename OPP>
413 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > {
414 typedef typename lambda<OPP>::type Op;
416 template < typename Elements>
418 typedef typename TypeGen::template apply<Elements>::type orig_t;
419 typedef typename Op::template apply<orig_t>::type type;
422 typedef cross_vector<VecOfVecs, adapter > type;
427 namespace boost { namespace gil {
429 template < typename Types, typename T> struct type_to_index;
430 template < typename V> struct view_is_basic;
445 template < typename Op, typename T>
457 template < typename Op, typename View, bool IsBasic>
458 struct reduce_view_basic {
462 template < typename Op, typename Loc>
463 struct reduce<Op, image_view<Loc> >
464 : public reduce_view_basic<Op,image_view<Loc>,view_is_basic<image_view<Loc> >::value> {};
473 template < typename Op, typename Img, bool IsBasic>
474 struct reduce_image_basic {
478 template < typename Op, typename V, typename Alloc>
479 struct reduce<Op, image<V,Alloc> > : public reduce_image_basic<Op,image<V,Alloc>,image_is_basic<image<V,Alloc> >::value > {};
488 template < typename Op, typename V1, typename V2, bool AreBasic>
489 struct reduce_views_basic {
490 typedef std::pair<const V1*, const V2*> type;
493 template < typename Op, typename L1, typename L2>
494 struct reduce<Op, std::pair<const image_view<L1>*, const image_view<L2>*> >
495 : public reduce_views_basic<Op,image_view<L1>,image_view<L2>,
496 mpl::and_<view_is_basic<image_view<L1> >, view_is_basic<image_view<L2> > >::value >
506 template < typename Cs>
507 struct reduce_color_space {
511 template <> struct reduce_color_space<lab_t> { typedef rgb_t type; };
512 template <> struct reduce_color_space<hsb_t> { typedef rgb_t type; };
513 template <> struct reduce_color_space<cmyk_t> { typedef rgba_t type; };
621 template < typename SrcLayout, typename DstLayout>
622 struct reduce_color_layouts {
623 typedef SrcLayout first_t;
624 typedef DstLayout second_t;
633 struct copy_pixels_fn;
647 template < typename V1, typename V2, bool Compatible>
648 struct reduce_copy_pixop_compat {
649 typedef error_t type;
654 template < typename V1, typename V2>
655 struct reduce_copy_pixop_compat<V1,V2,true> {
656 typedef layout<typename V1::color_space_t, typename V1::channel_mapping_t> layout1;
657 typedef layout<typename V2::color_space_t, typename V2::channel_mapping_t> layout2;
659 typedef typename reduce_color_layouts<layout1,layout2>::first_t L1;
660 typedef typename reduce_color_layouts<layout1,layout2>::second_t L2;
662 typedef typename derived_view_type<V1, use_default, L1, use_default, use_default, use_default, mpl::false_>::type DV1;
663 typedef typename derived_view_type<V2, use_default, L2, use_default, use_default, use_default, mpl::true_ >::type DV2;
665 typedef std::pair<const DV1*, const DV2*> type;
669 template < typename V1, typename V2>
670 struct reduce_views_basic<copy_pixels_fn, V1, V2, true>
671 : public reduce_copy_pixop_compat<V1, V2, mpl::and_<views_are_compatible<V1,V2>, view_is_mutable<V2> >::value > {
680 struct destructor_op;
681 template < typename View> struct reduce_view_basic<destructor_op,View,true> { typedef gray8_view_t type; };
689 struct any_type_get_dimensions;
690 template < typename View> struct reduce_view_basic<any_type_get_dimensions,View,true> { typedef gray8_view_t type; };
691 template < typename Img> struct reduce_image_basic<any_type_get_dimensions,Img,true> { typedef gray8_image_t type; };
699 struct any_type_get_num_channels;
700 template < typename View> struct reduce_view_basic<any_type_get_num_channels,View,true> {
701 typedef typename View::color_space_t::base Cs;
702 typedef typename view_type<bits8,typename reduce_color_space<Cs>::type>::type type;
704 template < typename Img> struct reduce_image_basic<any_type_get_num_channels,Img,true> {
705 typedef typename Img::color_space_t::base Cs;
706 typedef typename image_type<bits8,typename reduce_color_space<Cs>::type>::type type;
715 template < typename Sampler, typename MapFn> struct resample_pixels_fn;
717 template < typename S, typename M, typename V, bool IsBasic>
718 struct reduce_view_basic<resample_pixels_fn<S,M>, V, IsBasic> : public reduce_view_basic<copy_pixels_fn, V, IsBasic> {};
720 template < typename S, typename M, typename V1, typename V2, bool IsBasic>
721 struct reduce_views_basic<resample_pixels_fn<S,M>, V1, V2, IsBasic> : public reduce_views_basic<copy_pixels_fn, V1, V2, IsBasic> {};
731 template < typename CC> class copy_and_convert_pixels_fn;
734 template < typename CC, typename View, bool IsBasic>
735 struct reduce_view_basic<copy_and_convert_pixels_fn<CC>, View, IsBasic>
736 : public derived_view_type<View, use_default, use_default, use_default, use_default, mpl::true_> {
741 template < typename CC, typename V1, typename V2, bool AreBasic>
742 struct reduce_views_basic<copy_and_convert_pixels_fn<CC>, V1, V2, AreBasic> {
743 typedef is_same<typename V1::pixel_t, typename V2::pixel_t> Same;
745 typedef reduce_color_space<typename V1::color_space_t::base> CsR;
746 typedef typename mpl::if_<Same, typename CsR::type, typename V1::color_space_t>::type Cs1;
747 typedef typename mpl::if_<Same, typename CsR::type, typename V2::color_space_t>::type Cs2;
749 typedef typename derived_view_type<V1, use_default, layout<Cs1, typename V1::channel_mapping_t>, use_default, use_default, mpl::false_>::type DV1;
750 typedef typename derived_view_type<V2, use_default, layout<Cs2, typename V2::channel_mapping_t>, use_default, use_default, mpl::true_ >::type DV2;
752 typedef std::pair<const DV1*, const DV2*> type;
786 #endif // GIL_REDUCE_CODE_BLOAT
BOOST_FORCEINLINE UnaryOp::result_type apply_operation(variant< Types > &arg, UnaryOp op) Invokes a generic mutable operation (represented as a unary function object) on a variant... Definition: apply_operation.hpp:35
Constructs for static-to-dynamic integer convesion.
|