libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/reduce.hpp
Go to the documentation of this file.
00001 
00011 /*
00012  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00013  *
00014  *  This file is part of Psychosynth.
00015  *   
00016  *  Psychosynth is free software: you can redistribute it and/or modify
00017  *  it under the terms of the GNU General Public License as published by
00018  *  the Free Software Foundation, either version 3 of the License, or
00019  *  (at your option) any later version.
00020  *
00021  *  Psychosynth is distributed in the hope that it will be useful,
00022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *  GNU General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU General Public License
00027  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028  *
00029  */
00030 
00031 /*
00032  *  Copyright 2005-2007 Adobe Systems Incorporated
00033  * 
00034  *  Use, modification and distribution are subject to the Boost
00035  *  Software License, Version 1.0. (See accompanying file
00036  *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
00037  */
00038 
00039 #ifndef PSYNTH_SOUND_REDUCE_HPP
00040 #define PSYNTH_SOUND_REDUCE_HPP
00041 
00042 #include <boost/mpl/insert_range.hpp>
00043 #include <boost/mpl/range_c.hpp>
00044 #include <boost/mpl/vector_c.hpp>
00045 #include <boost/mpl/back.hpp>
00046 #include <boost/mpl/vector.hpp>
00047 #include <boost/mpl/set.hpp>
00048 #include <boost/mpl/long.hpp>
00049 #include <boost/mpl/logical.hpp>
00050 #include <boost/mpl/transform.hpp>
00051 #include <boost/mpl/insert.hpp>
00052 #include <boost/mpl/transform.hpp>
00053 #include <boost/mpl/order.hpp>
00054 
00055 #include <psynth/sound/metafunctions.hpp>
00056 #include <psynth/sound/typedefs.hpp>
00057 #include <psynth/sound/dynamic_at_c.hpp>
00058 
00059 
00060 #ifdef PSYNTH_REDUCE_CODE_BLOAT
00061 
00062 
00063 // Max number of cases in the cross-expension of binary operation for
00064 // it to be reduced as unary
00065 #define PSYNTH_BINARY_REDUCE_LIMIT 226
00066 
00067 namespace boost
00068 {
00069 namespace mpl
00070 {
00071 
00072 namespace detail {
00073 
00074 template <typename VecOfVecs, std::size_t N, std::size_t B_SIZE>
00075 struct _select_subvector {
00076 private:
00077     typedef typename front<VecOfVecs>::type cur_vec;
00078     static const std::size_t cur_base = size<cur_vec>::value;
00079     typedef typename pop_front<VecOfVecs>::type  next_vec_of_vecs; 
00080     typedef typename _select_subvector<next_vec_of_vecs,  N/cur_base, B_SIZE-1>::type
00081     next_subvector;
00082 public:
00083     typedef typename push_front<
00084     next_subvector,
00085     typename at_c<cur_vec, N%cur_base>::type >::type type;
00086 };
00087  
00088 template <typename VecOfVecs, std::size_t N>
00089 struct _select_subvector<VecOfVecs, N, 0> {
00090     typedef vector<>::type type;
00091 };
00092  
00093 template <typename VecOfVecs, std::size_t N>
00094 struct select_subvector_c {
00095     typedef typename _select_subvector<
00096         VecOfVecs, N, size<VecOfVecs>::value>::type type;
00097 };
00098 
00099 } /* namespace detail */
00100 
00130 template <typename VecOfVecs, typename TypeGen>
00131 struct cross_vector {};
00132 
00137 template <typename VecOfVecs, typename TypeGen, std::size_t K>
00138 struct cross_iterator
00139 {
00140     typedef boost::mpl::random_access_iterator_tag category;
00141 };
00142 
00143 /*
00144  *
00145  *      Implementation of the iterator functions of cross vector
00146  *
00147  */
00148 
00159 template <typename VecOfVecs, typename TypeGen, std::size_t K>
00160 struct deref<cross_iterator<VecOfVecs,TypeGen,K> >
00161 {
00162 private:
00163     typedef typename detail::select_subvector_c<VecOfVecs, K>::type DerefTypes;
00164 public:
00165     typedef typename TypeGen::template apply<DerefTypes>::type type;
00166 };
00167 
00172 template <typename VecOfVecs, typename TypeGen, std::size_t K>
00173 struct next<cross_iterator<VecOfVecs,TypeGen,K> > {
00174     typedef cross_iterator<VecOfVecs,TypeGen,K+1> type;
00175 };
00176 
00181 template <typename VecOfVecs, typename TypeGen, std::size_t K>
00182 struct prior<cross_iterator<VecOfVecs,TypeGen,K> > {
00183     typedef cross_iterator<VecOfVecs,TypeGen,K-1> type;
00184 };
00185 
00190 template <typename VecOfVecs, typename TypeGen, std::size_t K, typename Distance>
00191 struct advance<cross_iterator<VecOfVecs,TypeGen,K>, Distance > {
00192     typedef cross_iterator<VecOfVecs,TypeGen,K+Distance::value> type;
00193 };
00194 
00201 template <typename VecOfVecs, typename TypeGen,
00202           std::size_t K1, std::size_t K2>
00203 struct distance<cross_iterator<VecOfVecs,TypeGen,K1>,
00204                 cross_iterator<VecOfVecs,TypeGen,K2> >
00205 {
00206     typedef size_t<K2-K1> type;
00207 };
00208 
00209 
00210 /*
00211  *
00212  *      Implementation of cross vector
00213  *
00214  */
00215 
00221 template <typename VecOfVecs, typename TypeGen>
00222 struct size<cross_vector<VecOfVecs,TypeGen> >
00223 {
00224     typedef typename fold<VecOfVecs, size_t<1>,
00225                           times<_1, size<_2> > >::type type;
00226     static const std::size_t value = type::value;
00227 };
00228 
00233 template <typename VecOfVecs, typename TypeGen>
00234 struct empty<cross_vector<VecOfVecs,TypeGen> > {
00235     typedef typename empty<VecOfVecs>::type type;
00236 };
00237 
00242 template <typename VecOfVecs, typename TypeGen, typename K>
00243 struct at<cross_vector<VecOfVecs,TypeGen>, K>
00244 {
00245 private:
00246     typedef cross_iterator<VecOfVecs,TypeGen,K::value> KthIterator;
00247 public:
00248     typedef typename deref<KthIterator>::type type;
00249 };
00250 
00255 template <typename VecOfVecs, typename TypeGen>
00256 struct begin<cross_vector<VecOfVecs,TypeGen> > {
00257     typedef cross_iterator<VecOfVecs,TypeGen,0> type;
00258 };
00259 
00264 template <typename VecOfVecs, typename TypeGen>
00265 struct end<cross_vector<VecOfVecs,TypeGen> >
00266 {
00267 private:
00268     typedef cross_vector<VecOfVecs,TypeGen> this_t;
00269 public:
00270     typedef cross_iterator<VecOfVecs,TypeGen,size<this_t>::value> type;
00271 };
00272 
00277 template <typename VecOfVecs, typename TypeGen>
00278 struct front<cross_vector<VecOfVecs,TypeGen> >
00279 {
00280 private:
00281     typedef cross_vector<VecOfVecs,TypeGen> this_t;
00282 public:
00283     typedef typename deref<typename begin<this_t>::type>::type type;
00284 };
00285 
00290 template <typename VecOfVecs, typename TypeGen>
00291 struct back<cross_vector<VecOfVecs,TypeGen> > {
00292 private:
00293     typedef cross_vector<VecOfVecs,TypeGen> this_t;
00294     typedef typename size<this_t>::type            size;
00295     typedef typename minus<size, size_t<1> >::type last_index;
00296 public:
00297     typedef typename at<this_t, last_index>::type type;
00298 };
00299 
00304 template <typename VecOfVecs, typename TypeGen, typename OPP>
00305 struct transform<cross_vector<VecOfVecs,TypeGen>, OPP > {
00306     typedef typename lambda<OPP>::type Op;
00307     struct adapter {
00308         template <typename Elements> 
00309         struct apply {
00310             typedef typename TypeGen::template apply<Elements>::type orig_t;
00311             typedef typename Op::template apply<orig_t>::type type;
00312         };
00313     };
00314     typedef cross_vector<VecOfVecs, adapter > type; 
00315 };
00316 
00317 } /* namespace mpl */
00318 } /* namespace boost */
00319 
00320 namespace boost
00321 {
00322 namespace mpl
00323 {
00324 
00335 template <typename SrcTypes, typename DstTypes>
00336 struct mapping_vector {};
00337 
00338 template <typename SrcTypes, typename DstTypes, long K>
00339 struct at_c<mapping_vector<SrcTypes,DstTypes>, K>
00340 {
00341     static const std::size_t value =
00342         size<DstTypes>::value -
00343         mpl::order<DstTypes, typename at_c<SrcTypes,K>::type>::type::value + 1;
00344     typedef size_t<value> type;
00345 };
00346 
00347 template <typename SrcTypes, typename DstTypes>
00348 struct size<mapping_vector<SrcTypes,DstTypes> >
00349 {
00350     typedef typename size<SrcTypes>::type type;
00351     static const std::size_t value = type::value;
00352 };
00353 
00354 
00365 namespace detail
00366 {
00367 
00368 template <typename SFirst, std::size_t NLeft>
00369 struct copy_to_vector_impl
00370 {
00371 private:
00372     typedef typename deref<SFirst>::type T;
00373     typedef typename next<SFirst>::type next;
00374     typedef typename copy_to_vector_impl<next, NLeft-1>::type rest;
00375 public:
00376     typedef typename push_front<rest, T>::type type;
00377 };
00378 
00379 template <typename SFirst> 
00380 struct copy_to_vector_impl<SFirst,1>
00381 {
00382     typedef vector<typename deref<SFirst>::type> type;
00383 };
00384 
00385 } /* namespace detail */
00386 
00387 template <typename Src>
00388 struct copy_to_vector
00389 {
00390     typedef typename detail::copy_to_vector_impl<
00391         typename begin<Src>::type, size<Src>::value>::type type;
00392 };
00393 
00394 template <>
00395 struct copy_to_vector<mpl::set<> >
00396 {
00397     typedef mpl::vector0<> type;
00398 };
00399 
00400 } /* namespace mpl */
00401 } /* namespace boost */
00402 
00403 
00404 namespace psynth
00405 {
00406 namespace sound
00407 {
00408 
00427 template <typename Types, typename Op>
00428 struct unary_reduce_impl
00429 {
00430     typedef typename boost::mpl::transform<
00431         Types, detail::reduce<Op, boost::mpl::_1> >::type reduced_t;
00432     typedef typename boost::mpl::copy<
00433         reduced_t, boost::mpl::inserter<
00434                        boost::mpl::set<>,
00435                        boost::mpl::insert<boost::mpl::_1,
00436                                           boost::mpl::_2> > >::type unique_t;
00437     static const bool is_single = boost::mpl::size<unique_t>::value == 1;
00438 };
00439 
00440 template <typename Types, typename Op,
00441           bool IsSingle = unary_reduce_impl<Types,Op>::is_single>
00442 struct unary_reduce : public unary_reduce_impl<Types,Op>
00443 {
00444     typedef typename unary_reduce_impl<Types,Op>::reduced_t reduced_t;
00445     typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
00446 
00447     static unsigned short inline map_index (std::size_t index)
00448     {
00449         typedef typename boost::mpl::mapping_vector<reduced_t, unique_t> indices_t;
00450         return gil::at_c<indices_t, unsigned short>(index);
00451     }
00452     
00453     template <typename Bits> PSYNTH_FORCEINLINE
00454     static typename Op::result_type applyc (
00455         const Bits& bits, std::size_t index, Op op)
00456     {
00457         return apply_operation_basec<unique_t>(bits, map_index (index), op);
00458     }
00459 
00460     template <typename Bits> PSYNTH_FORCEINLINE
00461     static typename Op::result_type apply (Bits& bits, std::size_t index, Op op)
00462     {
00463         return apply_operation_base<unique_t>(bits, map_index(index), op);
00464     }
00465 };
00466 
00467 template <typename Types, typename Op>
00468 struct unary_reduce<Types,Op,true> : public unary_reduce_impl<Types,Op>
00469 {
00470     typedef typename unary_reduce_impl<Types,Op>::unique_t unique_t;
00471 
00472     static unsigned short inline map_index (std::size_t index)
00473     {
00474         return 0;
00475     }
00476 
00477     template <typename Bits> PSYNTH_FORCEINLINE
00478     static typename Op::result_type applyc (
00479         const Bits& bits, std::size_t index, Op op)
00480     {
00481         return op (*psynth_reinterpret_cast_c<
00482                        const typename boost::mpl::front<unique_t>::type*>(&bits));
00483     }
00484 
00485     template <typename Bits> PSYNTH_FORCEINLINE
00486     static typename Op::result_type apply (Bits& bits, std::size_t index, Op op)
00487     {
00488         return op (*psynth_reinterpret_cast<
00489                        typename boost::mpl::front<unique_t>::type*>(&bits));
00490     }
00491 };
00492 
00493 
00510 namespace detail
00511 {
00512 
00513 struct pair_generator
00514 {
00515     template <typename Vec2>
00516     struct apply
00517     {
00518         typedef std::pair<
00519             const typename boost::mpl::at_c<Vec2,0>::type*,
00520             const typename boost::mpl::at_c<Vec2,1>::type*> type;
00521 };
00522 };
00523 
00524 // When the types are not too large, applies reduce on their cross
00525 // product
00526 template <typename Unary1, typename Unary2, typename Op,
00527           bool IsComplex>
00528 struct binary_reduce_impl
00529 {
00530     // TODO: private:
00531     typedef typename boost::mpl::copy_to_vector<
00532         typename Unary1::unique_t>::type vec1_types;
00533     typedef typename boost::mpl::copy_to_vector<
00534         typename Unary2::unique_t>::type vec2_types;
00535 
00536     typedef boost::mpl::cross_vector<
00537         boost::mpl::vector2<vec1_types, vec2_types>, pair_generator> BIN_TYPES;
00538 
00539     typedef unary_reduce<BIN_TYPES,Op> bin_reduced_t;
00540         
00541     static unsigned short inline map_index (std::size_t index1,
00542                                             std::size_t index2)
00543     {
00544         unsigned short r1=Unary1::map_index(index1);
00545         unsigned short r2=Unary2::map_index(index2);
00546         return bin_reduced_t::map_index (
00547             r2 * boost::mpl::size<vec1_types>::value + r1);
00548     }
00549 
00550 public:
00551     typedef typename bin_reduced_t::unique_t unique_t;
00552     
00553     template <typename Bits1, typename Bits2>
00554     static typename Op::result_type inline apply (
00555         const Bits1& bits1, std::size_t index1,
00556         const Bits2& bits2, std::size_t index2, Op op)
00557     {
00558         std::pair<const void*,const void*> pr (&bits1, &bits2);
00559         return apply_operation_basec<unique_t> (
00560             pr, map_index (index1, index2), op);
00561     }
00562 };
00563 
00564 // When the types are large performs a double-dispatch. Binary
00565 // reduction is not done.
00566 template <typename Unary1, typename Unary2, typename Op>
00567 struct binary_reduce_impl<Unary1, Unary2,Op, true>
00568 {
00569     template <typename Bits1, typename Bits2>
00570     static typename Op::result_type inline apply (
00571         const Bits1& bits1, std::size_t index1,
00572         const Bits2& bits2, std::size_t index2, Op op)
00573     {
00574         return apply_operation_base<Unary1::unique_t, Unary2::unique_t>(
00575             bits1, index1, bits2, index2, op);
00576     }
00577 };
00578 
00579 } /* namespace detail */
00580 
00581 
00582 template <typename Types1, typename Types2, typename Op>
00583 struct binary_reduce
00584 {
00585 // TODO private:
00586     typedef unary_reduce<Types1,Op> unary1_t;
00587     typedef unary_reduce<Types2,Op> unary2_t;
00588 
00589     static const std::size_t CROSS_SIZE =
00590         boost::mpl::size<typename unary1_t::unique_t>::value * 
00591         boost::mpl::size<typename unary2_t::unique_t>::value;
00592 
00593     typedef detail::binary_reduce_impl<
00594         unary1_t, unary2_t, Op, (CROSS_SIZE > PSYNTH_BINARY_REDUCE_LIMIT)> impl;
00595 
00596 public:
00597     template <typename Bits1, typename Bits2>
00598     static typename Op::result_type inline apply (
00599         const Bits1& bits1, std::size_t index1,
00600         const Bits2& bits2, std::size_t index2, Op op)
00601     {
00602         return impl::apply (bits1, index1, bits2, index2, op);
00603     }
00604 };
00605 
00606 template <typename Types, typename UnaryOp> PSYNTH_FORCEINLINE
00607 typename UnaryOp::result_type apply_operation (variant<Types>& arg, UnaryOp op)
00608 {
00609     return unary_reduce<Types,UnaryOp>::template apply (
00610         arg._bits, arg._index, op);
00611 }
00612 
00613 template <typename Types, typename UnaryOp> PSYNTH_FORCEINLINE
00614 typename UnaryOp::result_type apply_operation (const variant<Types>& arg,
00615                                                UnaryOp op)
00616 {
00617     return unary_reduce<Types,UnaryOp>::template applyc (
00618         arg._bits, arg._index, op);
00619 }
00620 
00621 template <typename Types1, typename Types2, typename BinaryOp> PSYNTH_FORCEINLINE
00622 typename BinaryOp::result_type apply_operation (const variant<Types1>& arg1,
00623                                                 const variant<Types2>& arg2,
00624                                                 BinaryOp op)
00625 {    
00626     return binary_reduce<Types1, Types2, BinaryOp>::template apply (
00627         arg1._bits, arg1._index,
00628         arg2._bits, arg2._index, op);
00629 }
00630 
00631 #undef PSYNTH_BINARY_REDUCE_LIMIT
00632 
00633 } /* namespace sound */
00634 } /* namespace psynth */
00635 
00636 
00637 namespace psynth
00638 {
00639 namespace sound
00640 {
00641 
00642 template <typename Types, typename T> struct type_to_index;
00643 template <typename V> struct range_is_basic;
00644 
00645 #if 0 // HACK?
00646 
00647 struct stereo_space;
00648 struct mono_space;
00649 struct quad_space;
00650 struct surround_space;
00651 struct error_type;
00652 
00653 #endif
00654 
00655 namespace detail
00656 {
00657 
00658 /*
00659  *
00660  *       Generic reduce operation
00661  *
00662  */
00663 template <typename Op, typename T>
00664 struct reduce
00665 {
00666     typedef T type;
00667 };
00668 
00675 template <typename Op, typename Range, bool IsBasic>
00676 struct reduce_range_basic
00677 {
00678     typedef Range type;
00679 };
00680 
00681 template <typename Op, typename Loc>
00682 struct reduce<Op, buffer_range<Loc> > 
00683     : public reduce_range_basic<Op, buffer_range<Loc>,
00684                                range_is_basic<buffer_range<Loc> >::value> {};
00685  
00693 template <typename Op, typename Buf, bool IsBasic>
00694 struct reduce_buffer_basic
00695 {
00696     typedef Buf type;
00697 };
00698 
00699 template <typename Op, typename F, bool P, typename A>
00700 struct reduce<Op, buffer<F, P, A>> :
00701     public reduce_buffer_basic<Op,
00702                                buffer<F, P, A>,
00703                                buffer_is_basic<buffer<F, P, A>>::value > {};
00704 
00712 template <typename Op, typename V1, typename V2, bool AreBasic>
00713 struct reduce_ranges_basic
00714 {
00715     typedef std::pair<const V1*, const V2*> type;
00716 };
00717 
00718 template <typename Op, typename L1, typename L2>
00719 struct reduce<Op, std::pair<const buffer_range<L1>*, const buffer_range<L2>*> > 
00720     : public reduce_ranges_basic<Op,
00721                                 buffer_range<L1>,
00722                                 buffer_range<L2>,
00723                                 boost::mpl::and_<
00724                                     range_is_basic<buffer_range<L1> >,
00725                                     range_is_basic<buffer_range<L2> > >::value >
00726     {};
00727 
00728 
00736 template <typename Cs>
00737 struct reduce_channel_space {
00738     typedef Cs type;
00739 };
00740 
00741 /*
00742   TODO: 
00743   template <> struct reduce_channel_space<lab_t> { typedef rgb_t type; };
00744   template <> struct reduce_channel_space<hsb_t> { typedef rgb_t type; };
00745   template <> struct reduce_channel_space<cmyk_t> { typedef rgba_t type; };
00746 */
00747 
00872 // TODO: Use the old code for reduce_color_spaces above to do
00873 // color layout reduction
00874 
00875 template <typename SrcLayout, typename DstLayout>
00876 struct reduce_channel_layouts
00877 {
00878     typedef SrcLayout first_t;
00879     typedef DstLayout second_t;
00880 };
00881 
00882 
00883 /*
00884  *
00885  *       Reduce for copy_frames
00886  *
00887  */
00888 
00889 struct copy_frames_fn;
00890 
00891 /*
00892 
00893 // 1D reduce for copy_frames reduces the sample to mutable and the
00894 // channel space to its base with same dimensions
00895 
00896     template <typename Range>
00897     struct reduce_range_basic<copy_frames_fn,Range,true> {
00898     private:
00899         typedef typename reduce_channel_space<
00900             typename Range::channel_space_t>::type Cs;
00901             // reduce the channel space
00902         typedef layout<Cs, typename Range::sample_mapping_t> layout_t;
00903     public:
00904         typedef typename derived_range_type<
00905                 Range, use_default, layout_t, use_default,
00906                 use_default, boost::mpl::true_>::type type;
00907     };
00908 */
00909 
00910 // Incompatible ranges cannot be used in copy_frames - will throw
00911 // std::bad_cast
00912 template <typename V1, typename V2, bool Compatible> 
00913 struct reduce_copy_pixop_compat
00914 {
00915     typedef error_type type;
00916 };
00917     
00918 // For compatible basic ranges, reduce their channel spaces based on
00919 // their sample mapping.  Make the source immutable and the
00920 // destination mutable (they should already be that way)
00921 template <typename V1, typename V2>
00922 struct reduce_copy_pixop_compat<V1, V2, true>
00923 {
00924     typedef layout<typename V1::channel_space,
00925                    typename V1::sample_mapping> layout1;
00926     typedef layout<typename V2::channel_space,
00927                    typename V2::sample_mapping> layout2;
00928 
00929      typedef typename reduce_channel_layouts<layout1,layout2>::first_t L1;
00930      typedef typename reduce_channel_layouts<layout1,layout2>::second_t L2;
00931 
00932      typedef typename derived_range_type<
00933          V1, boost::use_default, L1,
00934          boost::use_default, 
00935          boost::use_default, boost::mpl::false_>::type DV1;
00936 
00937      typedef typename derived_range_type<
00938          V2, boost::use_default, L2,
00939          boost::use_default, 
00940          boost::use_default, boost::mpl::true_ >::type DV2;
00941         
00942      typedef std::pair<const DV1*, const DV2*> type;
00943 };
00944 
00945 // The general 2D version branches into compatible and incompatible
00946 // ranges
00947 template <typename V1, typename V2>
00948 struct reduce_ranges_basic<copy_frames_fn, V1, V2, true>
00949     : public reduce_copy_pixop_compat<
00950     V1, V2, boost::mpl::and_<ranges_are_compatible<V1,V2>,
00951                              range_is_mutable<V2> >::value >
00952 {
00953 };
00954 
00955 
00962 struct destructor_op;
00963 template <typename Range>
00964 struct reduce_range_basic<destructor_op,Range,true>
00965 {
00966     typedef mono8_range type;
00967 };
00968 
00969 
00978 struct dynamic_type_get_dimensions;
00979 template <typename Range>
00980 struct reduce_range_basic<dynamic_type_get_dimensions, Range, true>
00981 {
00982     typedef mono8_range type;
00983 };
00984 
00985 template <typename Img>
00986 struct reduce_buffer_basic<dynamic_type_get_dimensions, Img, true>
00987 {
00988     typedef mono8_buffer type;
00989 };
00990 
00991 /*
00992  *
00993  *      Reduce for get_num_samples (only channel space matters)
00994  *
00995  */
00996     
00997 struct dynamic_type_get_num_samples;
00998 template <typename Range>
00999 struct reduce_range_basic<dynamic_type_get_num_samples,Range,true>
01000 { 
01001     typedef typename Range::channel_space::base Cs;
01002 
01003     typedef typename range_type<
01004         bits8, typename reduce_channel_space<Cs>::type>::type type; 
01005 };
01006 
01007 template <typename Img>
01008 struct reduce_buffer_basic<dynamic_type_get_num_samples, Img, true>
01009 { 
01010     typedef typename Img::channel_space_t::base Cs;
01011     typedef typename buffer_type<
01012         bits8, typename reduce_channel_space<Cs>::type>::type type; 
01013 };
01014 
01015 /*
01016  *
01017  *      Reduce for resample_frames (same as copy_frames)
01018  *
01019  */    
01020 template <typename Sampler, typename MapFn> struct resample_frames_fn;
01021 
01022 template <typename S, typename M, typename V, bool IsBasic> 
01023 struct reduce_range_basic<resample_frames_fn<S,M>, V, IsBasic> :
01024     public reduce_range_basic<copy_frames_fn, V, IsBasic> {};
01025 
01026 template <typename S, typename M, typename V1, typename V2, bool IsBasic> 
01027 struct reduce_ranges_basic<resample_frames_fn<S,M>, V1, V2, IsBasic>
01028     : public reduce_ranges_basic<copy_frames_fn, V1, V2, IsBasic> {};
01029 
01030 /*
01031  *
01032  *      Reduce for copy_and_convert_frames
01033  *
01034  *      (the only reduction could be made when ranges are compatible
01035  *      and have the same mapping, planarity and stepness)
01036  *
01037  */
01038     
01039 template <typename CC> class copy_and_convert_frames_fn;
01040 
01041 // the only thing for 1D reduce is making them all mutable...
01042 template <typename CC, typename Range, bool IsBasic> 
01043 struct reduce_range_basic<copy_and_convert_frames_fn<CC>, Range, IsBasic> 
01044     : public derived_range_type<Range, boost::use_default, boost::use_default,
01045                                boost::use_default, boost::use_default, boost::mpl::true_>
01046 {
01047 };
01048 
01049 // For 2D reduce, if they have the same samples and channel spaces
01050 // (i.e. the same frames) then copy_and_convert is just copy.  In this
01051 // case, reduce their common channel space. In general make the first
01052 // immutable and the second mutable
01053 template <typename CC, typename V1, typename V2, bool AreBasic> 
01054 struct reduce_ranges_basic<copy_and_convert_frames_fn<CC>, V1, V2, AreBasic>
01055 {
01056     typedef boost::is_same<typename V1::frame_type, typename V2::frame_type> Same;
01057 
01058     typedef reduce_channel_space<typename V1::channel_space::base> CsR;
01059     typedef typename boost::mpl::if_<
01060         Same, typename CsR::type, typename V1::channel_space>::type Cs1;
01061     typedef typename boost::mpl::if_<
01062         Same, typename CsR::type, typename V2::channel_space>::type Cs2;
01063     
01064     typedef typename derived_range_type<
01065         V1, boost::use_default, layout<Cs1, typename V1::sample_mapping>,
01066         boost::use_default, boost::use_default, boost::mpl::false_>::type DV1;
01067 
01068     typedef typename derived_range_type<
01069         V2, boost::use_default, layout<Cs2, typename V2::sample_mapping_t>,
01070         boost::use_default, boost::use_default, boost::mpl::true_ >::type DV2;
01071     
01072     typedef std::pair<const DV1*, const DV2*> type;
01073 };
01074 
01075 /*
01076   TODO: What the hell is this?
01077 */
01078 
01079 //integral_buffer_generator
01080 //resize_clobber_buffer_fnobj
01081 //buffer_default_construct_fnobj
01082 //fill_converted_frames_fn
01083 //bind(gil::detail::copy_frames_fn(), _1, dst)
01084 //bind(gil::detail::copy_frames_fn(), src,_1)
01085     
01086 //bind(detail::copy_and_convert_frames_fn(), _1, dst)
01087 //bind(detail::copy_and_convert_frames_fn(), src, _1)
01088 //gil::detail::fill_frames_fn<Value>(val)
01089 
01090 //detail::copy_construct_in_place_fn<base_t>
01091 //detail::equal_to_fn<typename variant<Types>::base_t>
01092 
01093 //detail::dynamic_buffer_get_range<typename dynamic_buffer<Types>::range_t>
01094 //detail::dynamic_buffer_get_const_range<typename dynamic_buffer<Types>::range_t>
01095 //detail::flipped_up_down_range_fn<dynamic_buffer_range<RangeTypes> >
01096 //detail::flipped_left_right_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01097 //detail::tranposed_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01098 //detail::rotated90cw_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01099 //detail::rotated90ccw_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01100 //detail::rotated180_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01101 //detail::subbuffer_range_fn<dynamic_buffer_range<RangeTypes> >
01102 //detail::sub_sampled_range_fn<typename dynamic_buffer_range<RangeTypes>::dynamic_step_t>
01103 //detail::nth_sample_range_fn<typename nth_sample_range_type<dynamic_buffer_range<RangeTypes> >
01104 //detail::channel_converted_range_fn<DstP,typename channel_convert_range_type<dynamic_buffer_range<RangeTypes>, DstP>::type >
01105 
01106 } /* namespace detail */
01107 
01108 } /* namespace sound */
01109 } /* namespace psynth */
01110 
01111 #endif // PSYNTH_REDUCE_CODE_BLOAT
01112 
01113 #endif /* PSYNTH_SOUND_REDUCE */