libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/metafunctions.hpp
Go to the documentation of this file.
00001 
00012 /*
00013  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00014  *
00015  *  This file is part of Psychosynth.
00016  *   
00017  *  Psychosynth is free software: you can redistribute it and/or modify
00018  *  it under the terms of the GNU General Public License as published by
00019  *  the Free Software Foundation, either version 3 of the License, or
00020  *  (at your option) any later version.
00021  *
00022  *  Psychosynth is distributed in the hope that it will be useful,
00023  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00025  *  GNU General Public License for more details.
00026  *
00027  *  You should have received a copy of the GNU General Public License
00028  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00029  *
00030  */
00031 
00032 /*
00033  *  Copyright 2005-2007 Adobe Systems Incorporated
00034  * 
00035  *  Use, modification and distribution are subject to the Boost
00036  *  Software License, Version 1.0. (See accompanying file
00037  *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
00038  */
00039 
00040 #ifndef PSYNTH_SOUND_METAFUNCTIONS_HPP
00041 #define PSYNTH_SOUND_METAFUNCTIONS_HPP
00042 
00043 #include <iterator>
00044 #include <boost/mpl/accumulate.hpp>
00045 #include <boost/mpl/back.hpp>
00046 #include <boost/mpl/bool.hpp>
00047 #include <boost/mpl/if.hpp>
00048 #include <boost/mpl/pop_back.hpp>
00049 #include <boost/mpl/push_back.hpp>
00050 #include <boost/mpl/transform.hpp>
00051 #include <boost/mpl/vector.hpp>
00052 #include <boost/mpl/vector_c.hpp>
00053 #include <boost/mpl/print.hpp>
00054 #include <boost/type_traits.hpp>
00055 
00056 #include <psynth/base/compat.hpp>
00057 #include <psynth/sound/concept.hpp>
00058 #include <psynth/sound/sample.hpp>
00059 
00060 namespace psynth
00061 {
00062 namespace sound
00063 {
00064 
00065 // forward declarations
00066 template <typename T, typename L> struct frame;
00067 template <typename BitField,typename SampleRefVec,typename Layout>
00068 struct packed_frame;
00069 template <typename T, typename C> struct planar_frame_reference;
00070 template <typename IC, typename C> struct planar_frame_iterator;
00071 template <typename I> class memory_based_step_iterator;
00072 template <typename I> class memory_based_2d_locator;
00073 template <typename L> class buffer_range;
00074 template <typename Frame, bool IsPlanar, typename Alloc> class buffer;
00075 template <typename T> struct sample_type;
00076 template <typename T> struct channel_space_type;
00077 template <typename T> struct sample_mapping_type;
00078 template <typename It> struct is_iterator_adaptor;
00079 template <typename It> struct iterator_adaptor_get_base;
00080 template <typename BitField, typename SampleBitSizes, typename Layout,
00081           bool IsMutable>
00082 struct bit_aligned_frame_reference;
00083 
00084 /*
00085  *
00086  *    TYPE ANALYSIS METAFUNCTIONS
00087  *    Predicate metafunctions determining properties of GIL types
00088  *
00089  */
00090 
00091 /*
00092  \defgroup GILIsBasic xxx_is_basic
00093  \ingroup TypeAnalysis
00094 
00095  \brief Determines if GIL constructs are basic.  Basic constructs are
00096  the ones that can be generated with the type factory methods
00097  frame_reference_type, iterator_type, locator_type, range_type and
00098  buffer_type They can be mutable/immutable, planar/interleaved,
00099  step/nonstep. They must use GIL-provided models.
00100 
00101  \brief Determines if a given frame reference is basic Basic
00102  references must use gil::frame& (if interleaved),
00103  gil::planar_frame_reference (if planar). They must use the standard
00104  constness rules.
00105 
00106  \ingroup GILIsBasic
00107 */
00108 
00109 template <typename FrameRef>
00110 struct frame_reference_is_basic  : public boost::mpl::false_ {};
00111 template <typename T,  typename L>
00112 struct frame_reference_is_basic<frame<T, L>&> : public boost::mpl::true_ {};
00113 template <typename T,  typename L>
00114 struct frame_reference_is_basic<const frame<T,L>&> : public boost::mpl::true_ {};
00115 template <typename TR, typename Cs>
00116 struct frame_reference_is_basic<planar_frame_reference<TR,Cs> > :
00117         public boost::mpl::true_ {};
00118 template <typename TR, typename Cs>
00119 struct frame_reference_is_basic<const planar_frame_reference<TR,Cs> > :
00120         public boost::mpl::true_ {};
00121 
00122 
00133 template <typename Iterator>
00134 struct iterator_is_basic : public boost::mpl::false_ {};
00135 template <typename T, typename L>  // mutable   interleaved
00136 struct iterator_is_basic<      frame<T,L>*      > : public boost::mpl::true_ {};
00137 template <typename T, typename L>  // immutable interleaved
00138 struct iterator_is_basic<const frame<T,L>*      > : public boost::mpl::true_ {};
00139 template <typename T, typename Cs>  // mutable   planar
00140 struct iterator_is_basic<planar_frame_iterator<      T*,Cs> > :
00141         public boost::mpl::true_ {};
00142 template <typename T, typename Cs>    // immutable planar
00143 struct iterator_is_basic<planar_frame_iterator<const T*,Cs> > :
00144         public boost::mpl::true_ {};
00145 template <typename T, typename L>  // mutable   interleaved step
00146 struct iterator_is_basic<memory_based_step_iterator<      frame<T,L>*> > :
00147         public boost::mpl::true_ {};
00148 template <typename T, typename L>  // immutable interleaved step
00149 struct iterator_is_basic<memory_based_step_iterator<const frame<T,L>*> > :
00150         public boost::mpl::true_ {};
00151 template <typename T, typename Cs>  // mutable   planar step
00152 struct iterator_is_basic<
00153     memory_based_step_iterator<planar_frame_iterator<      T*,Cs> > > :
00154         public boost::mpl::true_ {};
00155 template <typename T, typename Cs>    // immutable planar step
00156 struct iterator_is_basic<
00157     memory_based_step_iterator<planar_frame_iterator<const T*,Cs> > > :
00158         public boost::mpl::true_ {};
00159 
00160 
00165 template <typename Range>
00166 struct range_is_basic : public boost::mpl::false_ {};
00167 template <typename Loc>
00168 struct range_is_basic<buffer_range<Loc> > : public iterator_is_basic<Loc> {};
00169 
00175 template <typename Img>
00176 struct buffer_is_basic : public boost::mpl::false_ {};
00177 template <typename Frame, bool IsPlanar, typename Alloc>
00178 struct buffer_is_basic<buffer<Frame,IsPlanar,Alloc> > : public boost::mpl::true_ {};
00179 
00180 
00188 template <typename I> struct iterator_is_step;
00189 
00190 namespace detail
00191 {
00192 
00193 template <typename It, bool IsBase, bool EqualsStepType>
00194 struct iterator_is_step_impl;
00195 
00196 // iterator that has the same type as its dynamic_step_type must be
00197 // a step iterator
00198 template <typename It, bool IsBase>
00199 struct iterator_is_step_impl<It,IsBase,true> : public boost::mpl::true_{};
00200 
00201 // base iterator can never be a step iterator
00202 template <typename It>
00203 struct iterator_is_step_impl<It,true,false> : public boost::mpl::false_{};
00204 
00205 // for an iterator adaptor, see if its base is step
00206 template <typename It> struct iterator_is_step_impl<It,false,false> 
00207     : public iterator_is_step<typename iterator_adaptor_get_base<It>::type>{};
00208 
00209 } /* namespace detail */
00210 
00211 
00217 template <typename I> struct iterator_is_step 
00218     : public detail::iterator_is_step_impl<
00219     I, 
00220     !is_iterator_adaptor<I>::type::value,
00221     boost::is_same<I,typename dynamic_step_type<I>::type>::value > {};
00222 
00223 
00229 template <typename V> struct range_is_step :
00230         public iterator_is_step<typename V::iterator> {}; 
00231 
00232 
00239 template <typename FrameReference>
00240 struct frame_reference_is_proxy
00241     : public boost::mpl::not_<
00242     boost::is_same<typename remove_const_and_reference<FrameReference>::type,
00243             typename remove_const_and_reference<
00244                 FrameReference>::type::value_type> > {};
00245 
00252 template <typename Frame>
00253 struct frame_is_reference :
00254     public boost::mpl::or_<boost::is_reference<Frame>,
00255                     frame_reference_is_proxy<Frame> > {};
00256 
00273 template <typename R>
00274 struct frame_reference_is_mutable :
00275         public boost::mpl::bool_<boost::remove_reference<R>::type::is_mutable> {};
00276 
00277 template <typename R>
00278 struct frame_reference_is_mutable<const R&>
00279     : public boost::mpl::and_<frame_reference_is_proxy<R>,
00280                        frame_reference_is_mutable<R> > {};
00281 
00287 template <typename V>
00288 struct range_is_mutable : public iterator_is_mutable<typename V::iterator> {};
00289 
00290 
00291 /*
00292  *
00293  *    TYPE FACTORY METAFUNCTIONS
00294  *    Metafunctions returning GIL types from other GIL types
00295  *
00296  */
00297 
00323 template <typename T, typename L, bool IsPlanar=false, bool IsMutable=true>
00324 struct frame_reference_type{};
00325 template <typename T, typename L>
00326 struct frame_reference_type<T,L,false,true > { typedef frame<T,L>& type; };
00327 template <typename T, typename L>
00328 struct frame_reference_type<T,L,false,false> { typedef const frame<T,L>& type; };
00329 
00330 template <typename T, typename L>
00331 struct frame_reference_type<T,L,true,true>
00332 {
00333     typedef const planar_frame_reference<
00334         typename sample_traits<T>::reference,
00335         typename channel_space_type<L>::type> type;
00336 };       // TODO: Assert M=identity
00337 
00338 template <typename T, typename L>
00339 struct frame_reference_type<T,L,true,false>
00340 {
00341     typedef const planar_frame_reference<
00342         typename sample_traits<T>::const_reference,
00343         typename channel_space_type<L>::type> type;
00344 };// TODO: Assert M=identity
00345 
00352 template <typename Frame, bool IsPlanar=false,
00353           bool IsStep=false, bool IsMutable=true>
00354 struct iterator_type_from_frame {};
00355 
00356 template <typename Frame>
00357 struct iterator_type_from_frame<Frame,false,false,true >
00358 { typedef Frame* type; };
00359 
00360 template <typename Frame>
00361 struct iterator_type_from_frame<Frame,false,false,false>
00362 { typedef const Frame* type; };
00363 
00364 template <typename Frame>
00365 struct iterator_type_from_frame<Frame,true,false,true>
00366 { 
00367     typedef planar_frame_iterator<
00368         typename sample_traits<typename sample_type<Frame>::type>::pointer,
00369         typename channel_space_type<Frame>::type> type; 
00370 };
00371 
00372 template <typename Frame>
00373 struct iterator_type_from_frame<Frame,true,false,false>
00374 { 
00375     typedef planar_frame_iterator<
00376         typename sample_traits<typename sample_type<Frame>::type>::const_pointer,
00377         typename channel_space_type<Frame>::type> type; 
00378 };
00379 
00380 template <typename Frame, bool IsPlanar, bool IsMutable>
00381 struct iterator_type_from_frame<Frame,IsPlanar,true,IsMutable>
00382 { 
00383     typedef memory_based_step_iterator<
00384         typename iterator_type_from_frame<
00385             Frame,IsPlanar,false,IsMutable>::type> type; 
00386 };
00387 
00388 
00395 template <typename T, typename L,
00396           bool IsPlanar=false, bool IsStep=false, bool IsMutable=true>
00397 struct iterator_type {};
00398 
00399 template <typename T, typename L>
00400 struct iterator_type<T,L,false,false,true >
00401 {
00402     typedef frame<T,L>* type;
00403 };
00404 
00405 template <typename T, typename L>
00406 struct iterator_type<T,L,false,false,false>
00407 {
00408     typedef const frame<T,L>* type;
00409 };
00410 
00411 template <typename T, typename L>
00412 struct iterator_type<T,L,true,false,true>
00413 {
00414     typedef planar_frame_iterator<T*,typename L::channel_space> type;
00415 };
00416 // TODO: Assert M=identity
00417 
00418 template <typename T, typename L>
00419 struct iterator_type<T,L,true,false,false>
00420 {
00421     typedef planar_frame_iterator<const T*,typename L::channel_space> type;
00422 };
00423 // TODO: Assert M=identity
00424 
00425 template <typename T, typename L, bool IsPlanar, bool IsMutable>
00426 struct iterator_type<T,L,IsPlanar,true,IsMutable>
00427 { 
00428     typedef memory_based_step_iterator<
00429         typename iterator_type<T,L,IsPlanar,false,IsMutable>::type> type; 
00430 };
00431 
00432 
00441 template <typename Iterator> 
00442 struct type_from_iterator
00443 {
00444     typedef memory_based_step_iterator<Iterator>  step_iterator;
00445     typedef buffer_range<Iterator>                 range;
00446 };
00447 
00448 namespace detail
00449 {
00450 
00451 template <typename BitField, typename FirstBit, typename NumBits>
00452 struct packed_sample_reference_type
00453 {
00454     typedef const packed_sample_reference<
00455         BitField,FirstBit::value,NumBits::value,true> type;
00456 };
00457 
00458 template <typename BitField, typename SampleBitSizesVector>
00459 class packed_sample_references_vector_type
00460 {
00461     // If SampleBitSizesVector is boost::mpl::vector<int,7,7,2> Then
00462     // first_bits_vector will be boost::mpl::vector<int,0,7,14,16>
00463     typedef typename boost::mpl::accumulate<
00464         SampleBitSizesVector,
00465         boost::mpl::vector1<boost::mpl::int_<0> >, 
00466         boost::mpl::push_back<boost::mpl::_1, boost::mpl::plus<boost::mpl::back<boost::mpl::_1>, boost::mpl::_2> >
00467         >::type first_bits_vector;
00468 
00469 public:
00470     typedef typename boost::mpl::transform<
00471     typename boost::mpl::pop_back<first_bits_vector>::type,
00472     SampleBitSizesVector,
00473     packed_sample_reference_type<BitField, boost::mpl::_1,boost::mpl::_2> >::type type;
00474 };
00475 
00476 } /* namespace detail */
00477 
00492 template <typename BitField, typename SampleBitSizeVector, typename Layout>
00493 struct packed_frame_type
00494 {
00495     typedef packed_frame<
00496         BitField,
00497         typename detail::packed_sample_references_vector_type<
00498             BitField, SampleBitSizeVector>::type, Layout> type;
00499 };
00500 
00501 
00516 /*
00517   \ingroup TypeFactoryPacked
00518   \brief Returns the type of an interleaved packed buffer: an buffer
00519   whose samples may not be byte-aligned, but whose frames are byte
00520   aligned.
00521 */
00522 template <typename BitField, typename SampleBitSizeVector,
00523           typename Layout, typename Alloc=std::allocator<unsigned char> >
00524 struct packed_buffer_type
00525 {
00526     typedef buffer<
00527         typename packed_frame_type<BitField, SampleBitSizeVector, Layout>::type,
00528         false,Alloc> type;
00529 };
00530 
00536 template <typename BitField, unsigned Size1, typename Layout,
00537           typename Alloc=std::allocator<unsigned char> >
00538 struct packed_buffer1_type :
00539     public packed_buffer_type<BitField, boost::mpl::vector1_c<unsigned, Size1>,
00540                               Layout, Alloc> {};
00541 
00547 template <typename BitField, unsigned Size1, unsigned Size2, typename Layout,
00548           typename Alloc=std::allocator<unsigned char> >
00549 struct packed_buffer2_type :
00550     public packed_buffer_type<BitField, boost::mpl::vector2_c<unsigned, Size1, Size2>,
00551                               Layout, Alloc> {};
00552 
00558 template <typename BitField, unsigned Size1, unsigned Size2,
00559           unsigned Size3, typename Layout,
00560           typename Alloc=std::allocator<unsigned char> >
00561 struct packed_buffer3_type :
00562     public packed_buffer_type<
00563     BitField, boost::mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
00564 
00570 template <typename BitField, unsigned Size1, unsigned Size2,
00571           unsigned Size3, unsigned Size4, typename Layout,
00572           typename Alloc=std::allocator<unsigned char> >
00573 struct packed_buffer4_type :
00574     public packed_buffer_type<
00575     BitField,
00576     boost::mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>,
00577     Layout, Alloc> {};
00578 
00584 template <typename BitField, unsigned Size1, unsigned Size2, unsigned Size3,
00585           unsigned Size4, unsigned Size5, typename Layout,
00586           typename Alloc=std::allocator<unsigned char> >
00587 struct packed_buffer5_type :
00588     public packed_buffer_type<
00589     BitField, boost::mpl::vector5_c<
00590                   unsigned, Size1, Size2, Size3, Size4, Size5>,
00591     Layout, Alloc> {};
00592 
00593 
00605 template <typename SampleBitSizeVector, typename Layout,
00606           typename Alloc=std::allocator<unsigned char> >
00607 struct bit_aligned_buffer_type
00608 {
00609 private:
00610     BOOST_STATIC_CONSTANT(
00611         int,
00612         bit_size = (boost::mpl::accumulate<
00613                         SampleBitSizeVector,
00614                         boost::mpl::int_<0>,
00615                         boost::mpl::plus<boost::mpl::_1,
00616                                          boost::mpl::_2> >::type::value));
00617     typedef typename detail::min_fast_uint<
00618         bit_size + 7>::type bitfield_t;  
00619     typedef const bit_aligned_frame_reference<
00620         bitfield_t, SampleBitSizeVector, Layout, true> bit_alignedref_t;
00621 
00622 public:
00623     typedef buffer<bit_alignedref_t,false,Alloc> type;
00624 };
00625 
00631 template <unsigned Size1, typename Layout,
00632           typename Alloc=std::allocator<unsigned char> >
00633 struct bit_aligned_buffer1_type :
00634     public bit_aligned_buffer_type<boost::mpl::vector1_c<unsigned, Size1>,
00635                                    Layout, Alloc> {};
00636 
00642 template <unsigned Size1, unsigned Size2, typename Layout,
00643           typename Alloc=std::allocator<unsigned char> >
00644 struct bit_aligned_buffer2_type :
00645     public bit_aligned_buffer_type<
00646     boost::mpl::vector2_c<unsigned, Size1, Size2>, Layout, Alloc> {};
00647 
00653 template <unsigned Size1, unsigned Size2, unsigned Size3,
00654           typename Layout, typename Alloc=std::allocator<unsigned char> >
00655 struct bit_aligned_buffer3_type :
00656     public bit_aligned_buffer_type<
00657     boost::mpl::vector3_c<unsigned, Size1, Size2, Size3>, Layout, Alloc> {};
00658 
00664 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4,
00665           typename Layout, typename Alloc=std::allocator<unsigned char> >
00666 struct bit_aligned_buffer4_type :
00667     public bit_aligned_buffer_type<
00668     boost::mpl::vector4_c<unsigned, Size1, Size2, Size3, Size4>, Layout, Alloc> {};
00669 
00675 template <unsigned Size1, unsigned Size2, unsigned Size3, unsigned Size4,
00676           unsigned Size5, typename Layout,
00677           typename Alloc=std::allocator<unsigned char> >
00678 struct bit_aligned_buffer5_type :
00679     public bit_aligned_buffer_type<
00680     boost::mpl::vector5_c<unsigned, Size1, Size2, Size3, Size4, Size5>,
00681     Layout, Alloc> {};
00682 
00683 
00684 
00690 template <typename Sample, typename Layout> 
00691 struct frame_value_type
00692 {
00693     typedef frame<Sample,Layout> type;
00694     // by default use gil::frame. Specializations are provided for 
00695 };
00696 
00697 // Specializations for packed samples
00698 template <typename BitField, int NumBits, bool IsMutable, typename Layout> 
00699 struct frame_value_type<packed_dynamic_sample_reference<
00700                             BitField,NumBits,IsMutable>,Layout> :
00701     public packed_frame_type<BitField,
00702                              boost::mpl::vector1_c<unsigned,NumBits>, Layout> {};
00703 
00704 template <typename BitField, int NumBits, bool IsMutable, typename Layout> 
00705 struct frame_value_type<const packed_dynamic_sample_reference<
00706                             BitField,NumBits,IsMutable>,Layout> :
00707     public packed_frame_type<BitField,
00708                              boost::mpl::vector1_c<unsigned,NumBits>, Layout> {};
00709 
00710 template <typename BitField, int FirstBit, int NumBits, bool IsMutable,
00711           typename Layout> 
00712 struct frame_value_type<packed_sample_reference<
00713                             BitField,FirstBit,NumBits,IsMutable>,Layout> :
00714     public packed_frame_type<BitField,
00715                              boost::mpl::vector1_c<unsigned,NumBits>, Layout> {};
00716 
00717 template <typename BitField, int FirstBit, int NumBits, bool IsMutable,
00718           typename Layout> 
00719 struct frame_value_type<const packed_sample_reference<
00720                             BitField,FirstBit,NumBits,IsMutable>,Layout> :
00721     public packed_frame_type<BitField,
00722                              boost::mpl::vector1_c<unsigned,NumBits>, Layout> {};
00723 
00724 template <int NumBits, typename Layout> 
00725 struct frame_value_type<packed_sample_value<NumBits>,Layout> :
00726     public packed_frame_type<typename detail::min_fast_uint<NumBits>::type,
00727                              boost::mpl::vector1_c<unsigned,NumBits>, Layout> {};
00728 
00729 
00736 template <typename T, typename L, bool IsPlanar=false,
00737           bool IsStepX=false, bool IsMutable=true> 
00738 struct range_type
00739 {
00740     typedef typename type_from_iterator<
00741         typename iterator_type<
00742             T,L,IsPlanar,IsStepX,IsMutable>::type>::range type;
00743 };
00744 
00750 template <typename T, typename L, bool IsPlanar=false,
00751           typename Alloc=std::allocator<unsigned char> > 
00752 struct buffer_type
00753 {
00754     typedef buffer<frame<T,L>, IsPlanar, Alloc> type;
00755 };
00756 
00762 template <typename Frame, bool IsPlanar=false, bool IsStepX=false,
00763           bool IsMutable=true> 
00764 struct range_type_from_frame
00765 {
00766     typedef typename type_from_iterator<
00767         typename iterator_type_from_frame<
00768             Frame,IsPlanar,IsStepX,IsMutable>::type>::range type;
00769 };
00770 
00771 
00780 template <typename Ref,
00781           typename T=boost::use_default,
00782           typename L=boost::use_default,
00783           typename IsPlanar=boost::use_default,
00784           typename IsMutable=boost::use_default>
00785 class derived_frame_reference_type
00786 {
00787     typedef typename boost::remove_reference<Ref>::type frame_t;
00788 
00789     typedef typename  boost::mpl::if_<boost::is_same<T, boost::use_default>,
00790                                typename sample_type<frame_t>::type,
00791                                T>::type sample_type;
00792     
00793     typedef typename  boost::mpl::if_<
00794         boost::is_same<L, boost::use_default>, 
00795         layout<typename channel_space_type<frame_t>::type,
00796                typename sample_mapping_type<frame_t>::type>, L>::type layout_type;
00797 
00798     static const bool mut = boost::mpl::if_<
00799         boost::is_same<IsMutable,boost::use_default>,
00800         frame_reference_is_mutable<Ref>,
00801         IsMutable>::type::value;
00802 
00803     static const bool planar = boost::mpl::if_<
00804         boost::is_same<IsPlanar,boost::use_default>,
00805         is_planar<frame_t>,
00806         IsPlanar>::type::value;
00807 
00808 public:
00809     typedef typename frame_reference_type<
00810     sample_type, layout_type, planar, mut>::type type;
00811 };
00812 
00813 
00822 template <typename Iterator,
00823           typename T=boost::use_default,
00824           typename L=boost::use_default,
00825           typename IsPlanar=boost::use_default,
00826           typename IsStep=boost::use_default,
00827           typename IsMutable=boost::use_default>
00828 class derived_iterator_type
00829 {
00830     typedef typename  boost::mpl::if_<
00831         boost::is_same<T ,boost::use_default>,
00832         typename sample_type<Iterator>::type, T >::type sample_t;
00833 
00834     typedef typename  boost::mpl::if_<
00835         boost::is_same<L,boost::use_default>, 
00836         layout<typename channel_space_type<Iterator>::type,
00837                typename sample_mapping_type<Iterator>::type>, L>::type layout_t;
00838 
00839     static const bool mut    = boost::mpl::if_<
00840         boost::is_same<IsMutable, boost::use_default>,
00841         iterator_is_mutable<Iterator>,
00842         IsMutable>::type::value;
00843 
00844     static const bool planar = boost::mpl::if_<
00845         boost::is_same<IsPlanar, boost::use_default>,
00846         is_planar<Iterator>,
00847         IsPlanar>::type::value;
00848 
00849     static const bool step   = boost::mpl::if_<
00850         boost::is_same<IsStep, boost::use_default>,
00851         iterator_is_step<Iterator>,
00852         IsStep>::type::value;
00853     
00854 public:
00855     typedef typename iterator_type<
00856     sample_t, layout_t, planar, step, mut>::type type;
00857 };
00858 
00859 
00868 template <typename Range,
00869           typename T=boost::use_default,
00870           typename L=boost::use_default,
00871           typename IsPlanar=boost::use_default,
00872           typename StepX=boost::use_default,
00873           typename IsMutable=boost::use_default>
00874 class derived_range_type
00875 {
00876     typedef typename  boost::mpl::if_<
00877         boost::is_same<T ,boost::use_default>,
00878         typename sample_type<Range>::type,
00879         T>::type sample_t;
00880 
00881     typedef typename  boost::mpl::if_<
00882         boost::is_same<L,boost::use_default>, 
00883         layout<typename channel_space_type<Range>::type,
00884                typename sample_mapping_type<Range>::type>,
00885         L>::type layout_t;
00886 
00887     static const bool mut    = boost::mpl::if_<
00888         boost::is_same<IsMutable,boost::use_default>,
00889         range_is_mutable<Range>,
00890         IsMutable>::type::value;
00891 
00892     static const bool planar = boost::mpl::if_<
00893         boost::is_same<IsPlanar,boost::use_default>,
00894         is_planar<Range>,
00895         IsPlanar>::type::value;
00896     
00897     static const bool step   = boost::mpl::if_<
00898         boost::is_same<StepX ,boost::use_default>,
00899         range_is_step<Range>, StepX>::type::value;
00900 
00901 public:
00902     typedef typename range_type<sample_t, layout_t, planar, step, mut>::type type;
00903 };
00904 
00905 
00914 template <typename Buffer, typename T=boost::use_default,
00915           typename L=boost::use_default,
00916           typename IsPlanar=boost::use_default>
00917 class derived_buffer_type
00918 {
00919     typedef typename  boost::mpl::if_<
00920         boost::is_same<T ,boost::use_default>,
00921         typename sample_type<Buffer>::type,
00922         T >::type sample_t;
00923 
00924     typedef typename  boost::mpl::if_<
00925         boost::is_same<L,boost::use_default>, 
00926         layout<typename channel_space_type<Buffer>::type,
00927                typename sample_mapping_type<Buffer>::type>,
00928         L>::type layout_t;
00929 
00930     static const bool planar = boost::mpl::if_<
00931         boost::is_same<IsPlanar,boost::use_default>,
00932         is_planar<Buffer>,
00933         IsPlanar>::type::value;
00934 
00935 public:
00936     typedef typename buffer_type<sample_t, layout_t, planar>::type type;
00937 };
00938 
00945 template <class Range>
00946 struct buffer_range_type
00947 {
00948     typedef Range type;
00949 };
00950 
00951 template <class Frame, bool Planar, class Alloc>
00952 struct buffer_range_type<buffer<Frame, Planar, Alloc> >
00953 {
00954     typedef typename buffer<Frame, Planar, Alloc>::range type;
00955 };
00956 
00961 template <class Range, typename Alloc = std::allocator<unsigned char> >
00962 struct buffer_from_range
00963 {
00964     typedef buffer<typename std::iterator_traits<
00965                        typename Range::iterator>::value_type,
00966                    is_planar<Range>::value,
00967                    Alloc>
00968     type;
00969 };
00970 
00971 } /* namespace sound */
00972 } /* namespace psynth */
00973 
00974 #endif /* PSYNTH_SOUND_METAFUNCTIONS */