libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/concept.hpp
Go to the documentation of this file.
00001 
00016 /*
00017  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00018  *
00019  *  This file is part of Psychosynth.
00020  *   
00021  *  Psychosynth is free software: you can redistribute it and/or modify
00022  *  it under the terms of the GNU General Public License as published by
00023  *  the Free Software Foundation, either version 3 of the License, or
00024  *  (at your option) any later version.
00025  *
00026  *  Psychosynth is distributed in the hope that it will be useful,
00027  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00028  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00029  *  GNU General Public License for more details.
00030  *
00031  *  You should have received a copy of the GNU General Public License
00032  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00033  *
00034  */
00035 
00036 /*
00037  *  Copyright 2005-2007 Adobe Systems Incorporated
00038  * 
00039  *  Use, modification and distribution are subject to the Boost
00040  *  Software License, Version 1.0. (See accompanying file
00041  *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
00042  */
00043 
00044 #ifndef PSYNTH_SOUND_CONCEPT_H
00045 #define PSYNTH_SOUND_CONCEPT_H
00046 
00047 #include <psynth/base/concept.hpp>
00048 #include <psynth/sound/forwards.hpp>
00049 
00054 #include <type_traits>
00055 #include <boost/type_traits.hpp>
00056 #include <functional>
00057 #include <boost/utility/enable_if.hpp>
00058 #include <boost/iterator/iterator_concepts.hpp>
00059 #include <boost/mpl/and.hpp>
00060 #include <boost/mpl/size.hpp>
00061 
00062 namespace psynth
00063 {
00064 namespace sound
00065 {
00066 
00067 /*
00068  *
00069  *       Extra iterator concepts.
00070  *
00071  */
00072 
00073 namespace detail
00074 {
00075 
00076 template <class TT>
00077     /* Preconditions: TT Models
00078        boost_concepts::ForwardTraversalConcept */
00079 struct ForwardIteratorIsMutableConcept
00080 {
00081     void constraints() {
00082         *i++ = *i;    // require postincrement and assignment
00083     }
00084     TT i;
00085 };
00086 
00087 template <class TT>
00088 /* Preconditions: TT Models boost::BidirectionalIteratorConcept */
00089 struct BidirectionalIteratorIsMutableConcept
00090 {
00091     void constraints() {
00092         base::psynth_function_requires< ForwardIteratorIsMutableConcept<TT> >();
00093         *i-- = *i;                  // require postdecrement and assignment
00094     }
00095     TT i;
00096 };
00097 
00098 template <class TT>
00099 /* Preconditions: TT Models
00100    boost_concepts::RandomAccessTraversalConcept */
00101 struct RandomAccessIteratorIsMutableConcept
00102 {
00103     void constraints() {
00104         base::psynth_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
00105         typename std::iterator_traits<TT>::difference_type n=0;
00106         ignore_unused_variable_warning(n);
00107         i[n] = *i;
00108         // require element access and assignment
00109     }
00110     TT i;
00111 };
00112 
00113 } /* namespace detail */
00114 
00115 
00116 /*
00117  *
00118  *  Channel Space concepts.
00119  *
00120  */
00121 
00134 template <typename Cs>
00135 struct ChannelSpaceConcept
00136 {
00137     void constraints() {
00138         // An MPL Random Access Sequence, whose elements are channel tags
00139     }
00140 };
00141 
00142 template <typename ChannelSpace1, typename ChannelSpace2>
00143 // Models ChannelSpaceConcept
00144 struct channel_spaces_are_compatible :
00145     public boost::is_same<ChannelSpace1, ChannelSpace2> {};
00146 
00159 template <typename Cs1, typename Cs2>
00160 struct ChannelSpacesCompatibleConcept
00161 {
00162     void constraints() {
00163         BOOST_STATIC_ASSERT((channel_spaces_are_compatible<Cs1,Cs2>::value));
00164     }
00165 };
00166 
00167 
00168 /*
00169  *
00170  *  Sample concepts
00171  *
00172  */
00173 
00186 template <typename CM>
00187 struct SampleMappingConcept
00188 {
00189     void constraints() {
00190         // An MPL Random Access Sequence, whose elements model
00191         // MPLIntegralConstant representing a permutation
00192     }
00193 };
00194 
00195 
00238 template <typename T>
00239 struct SampleConcept
00240 {
00241     void constraints() {
00242         base::psynth_function_requires< boost::EqualityComparableConcept<T> >(); 
00243         
00244         typedef typename sample_traits<T>::value_type v;
00245         typedef typename sample_traits<T>::reference r;
00246         typedef typename sample_traits<T>::pointer p;
00247         typedef typename sample_traits<T>::const_reference cr;
00248         typedef typename sample_traits<T>::const_pointer cp;
00249 
00250         sample_traits<T>::min_value ();
00251         sample_traits<T>::max_value ();
00252         sample_traits<T>::zero_value (); // Added for sound. It is
00253                                          // important to know which is
00254                                          // the stable central value.
00255     }
00256 
00257      T c;
00258 };
00259 
00260 namespace detail
00261 {
00262 
00263 // Preconditions: T models SampleConcept
00264 template <typename T>
00265 struct SampleIsMutableConcept
00266 {
00267     void constraints() {
00268         c=c;
00269         using std::swap;
00270         swap(c,c);
00271     }
00272     T c;
00273 };
00274 
00275 } /* namespace detail*/
00276 
00286 template <typename T>
00287 struct MutableSampleConcept
00288 {
00289     void constraints() {
00290         base::psynth_function_requires<SampleConcept<T> >();
00291         base::psynth_function_requires<detail::SampleIsMutableConcept<T> >();
00292     }
00293 };
00294 
00304 template <typename T>
00305 struct SampleValueConcept
00306 {
00307     void constraints() {
00308         base::psynth_function_requires<SampleConcept<T> >();
00309         base::psynth_function_requires<base::Regular<T> >();
00310     }
00311 };
00312 
00328 template <typename T1, typename T2>  // Models Psynth Frame
00329 struct samples_are_compatible 
00330     : public boost::is_same<typename sample_traits<T1>::value_type,
00331                             typename sample_traits<T2>::value_type> {};
00332 
00345 template <typename T1, typename T2>
00346 struct SamplesCompatibleConcept
00347 {
00348     void constraints() {
00349         BOOST_STATIC_ASSERT((samples_are_compatible<T1,T2>::value));
00350     }
00351 };
00352 
00370 template <typename SrcSample, typename DstSample>
00371 struct SampleConvertibleConcept
00372 {
00373     void constraints() {
00374         base::psynth_function_requires<SampleConcept<SrcSample> >();
00375         base::psynth_function_requires<MutableSampleConcept<DstSample> >();
00376         dst = sample_convert<DstSample, SrcSample>(src);
00377         ignore_unused_variable_warning(dst);
00378     }
00379     SrcSample src;
00380     DstSample dst;
00381 };
00382 
00383 
00450 template <typename ChannelBase>
00451 struct ChannelBaseConcept
00452 {
00453     void constraints() {
00454         base::psynth_function_requires< base::CopyConstructible<ChannelBase> >();
00455         base::psynth_function_requires< base::EqualityComparable<ChannelBase> >();
00456 
00457         typedef typename ChannelBase::layout::channel_space channel_space;
00458         base::psynth_function_requires<ChannelSpaceConcept<channel_space> >();
00459 
00460         typedef typename ChannelBase::layout_t::sample_mapping sample_mapping;
00461         // TODO: sample_mapping_t must be an MPL RandomAccessSequence
00462 
00463         static const std::size_t num_elements = size<ChannelBase>::value;
00464 
00465         typedef typename kth_element_type<ChannelBase,num_elements-1>::type TN; 
00466         typedef typename kth_element_const_reference_type<
00467             ChannelBase, num_elements-1>::type CR; 
00468 
00469 #if !defined(_MSC_VER) || _MSC_VER > 1310
00470         CR cr = at_c<num_elements-1>(cb);
00471         ignore_unused_variable_warning(cr);
00472 #endif
00473 
00474         // functions that work for every frame (no need to require them)
00475         semantic_at_c<0>(cb);
00476         semantic_at_c<num_elements-1>(cb);
00477         // also static_max(cb), static_min(cb), static_fill(cb,value),
00478         // and all variations of static_for_each(), static_generate(),
00479         // static_transform()
00480     }
00481 
00482     ChannelBase cb;
00483 };
00484 
00505 template <typename ChannelBase>
00506 struct MutableChannelBaseConcept
00507 {
00508     void constraints() {
00509         base::psynth_function_requires< ChannelBaseConcept<ChannelBase> >();
00510         base::psynth_function_requires< base::Assignable<ChannelBase> >();
00511         base::psynth_function_requires< base::Swappable<ChannelBase> >();
00512 
00513         typedef typename kth_element_reference_type<ChannelBase, 0>::type CR; 
00514 
00515 #if !defined(_MSC_VER) || _MSC_VER > 1310
00516         CR r=at_c<0>(cb);
00517         at_c<0>(cb)=r;
00518 #endif
00519     }
00520 
00521     ChannelBase cb;
00522 };
00523 
00536 template <typename ChannelBase>
00537 struct ChannelBaseValueConcept
00538 {
00539     void constraints() {
00540         base::psynth_function_requires< MutableChannelBaseConcept<ChannelBase> >();
00541         base::psynth_function_requires< base::Regular<ChannelBase> >();
00542     }
00543 };
00544 
00560 template <typename ChannelBase>
00561 struct HomogeneousChannelBaseConcept
00562 {
00563     void constraints() {
00564         base::psynth_function_requires< ChannelBaseConcept<ChannelBase> >();
00565 
00566         static const std::size_t num_elements = size<ChannelBase>::value;
00567 
00568         typedef typename kth_element_type<ChannelBase,0>::type T0; 
00569         typedef typename kth_element_type<ChannelBase,num_elements-1>::type TN; 
00570 
00571         BOOST_STATIC_ASSERT((boost::is_same<T0,TN>::value));
00572         // better than nothing
00573         typedef typename kth_element_const_reference_type<
00574             ChannelBase,0>::type CRef0; 
00575         CRef0 e0=dynamic_at_c(cb,0);
00576     }
00577     ChannelBase cb;
00578 };
00579 
00595 template <typename ChannelBase>
00596 struct MutableHomogeneousChannelBaseConcept
00597 {
00598     void constraints() {
00599         base::psynth_function_requires< ChannelBaseConcept<ChannelBase> >();
00600         base::psynth_function_requires< HomogeneousChannelBaseConcept<ChannelBase> >();
00601         typedef typename kth_element_reference_type<ChannelBase, 0>::type R0;
00602         R0 x = dynamic_at_c (cb, 0);
00603         dynamic_at_c(cb,0) = dynamic_at_c (cb, 0);
00604     }
00605     ChannelBase cb;
00606 };
00607 
00622 template <typename ChannelBase>
00623 struct HomogeneousChannelBaseValueConcept
00624 {
00625     void constraints() {
00626         base::psynth_function_requires<
00627             MutableHomogeneousChannelBaseConcept<ChannelBase> >();
00628         base::psynth_function_requires< base::Regular<ChannelBase> >();
00629     }
00630 };
00631 
00632 
00651 template <typename ChannelBase1, typename ChannelBase2>
00652 struct ChannelBasesCompatibleConcept
00653 {
00654     void constraints() {
00655         BOOST_STATIC_ASSERT(
00656             (boost::is_same<typename ChannelBase1::layout_type::channel_space, 
00657              typename ChannelBase2::layout_type::channel_space>::value));
00658 //        typedef typename kth_semantic_element_type<ChannelBase1,0>::type e1;
00659 //        typedef typename kth_semantic_element_type<ChannelBase2,0>::type e2;
00660 //        "e1 is convertible to e2"
00661     }
00662 };
00663 
00664 
00665 /*
00666  *
00667  *      Frame Concepts
00668  *
00669  */
00670 
00692 template <typename P>
00693 struct FrameBasedConcept
00694 {
00695     void constraints() {
00696         typedef typename channel_space_type<P>::type channel_space;
00697         base::psynth_function_requires<ChannelSpaceConcept<channel_space> >();
00698 
00699         typedef typename sample_mapping_type<P>::type sample_mapping;
00700         base::psynth_function_requires<SampleMappingConcept<sample_mapping> >();
00701 
00702         static const bool planar = is_planar<P>::type::value;
00703         boost::ignore_unused_variable_warning(planar);
00704 
00705 
00706         // This is not part of the concept, but should still work
00707         static const std::size_t nc = num_samples<P>::value;
00708         boost::ignore_unused_variable_warning(nc);
00709     }
00710 };
00711 
00725 template <typename P>
00726 struct HomogeneousFrameBasedConcept
00727 {
00728     void constraints()
00729     {
00730         base::psynth_function_requires<FrameBasedConcept<P> >();
00731 
00732         typedef typename sample_type<P>::type sample;
00733         base::psynth_function_requires<SampleConcept<sample> >();        
00734     }
00735 };
00736 
00737 
00765 template <typename F>
00766 struct FrameConcept
00767 {
00768     void constraints() {
00769         base::psynth_function_requires<ChannelBaseConcept<F> >();
00770         base::psynth_function_requires<FrameBasedConcept<F> >();
00771 
00772         BOOST_STATIC_ASSERT((is_frame<F>::value));
00773         static const bool is_mutable = F::is_mutable;
00774         boost::ignore_unused_variable_warning(is_mutable);
00775 
00776         typedef typename F::value_type      value_type;
00777 //      base::psynth_function_requires<FrameValueConcept<value_type> >();
00778 
00779         typedef typename F::reference       reference;
00780         base::psynth_function_requires<
00781             FrameConcept<typename remove_const_and_reference<reference>::type> >();
00782 
00783         typedef typename F::const_reference const_reference;
00784         base::psynth_function_requires<
00785             FrameConcept<
00786                 typename remove_const_and_reference<const_reference>::type> >();
00787     }
00788 };
00789 
00790 
00803 template <typename F>
00804 struct MutableFrameConcept
00805 {
00806     void constraints() {
00807         base::psynth_function_requires<FrameConcept<F> >();
00808         BOOST_STATIC_ASSERT(F::is_mutable);
00809     }
00810 };
00811 
00825 template <typename F>
00826 struct HomogeneousFrameConcept
00827 {
00828     void constraints() {
00829         base::psynth_function_requires<FrameConcept<F> >();
00830         base::psynth_function_requires<HomogeneousChannelBaseConcept<F> >();
00831         base::psynth_function_requires<HomogeneousFrameBasedConcept<F> >();
00832         p[0];
00833     }
00834     F p;
00835 };
00836 
00851 template <typename F>
00852 struct MutableHomogeneousFrameConcept
00853 {
00854     void constraints() {
00855         base::psynth_function_requires<HomogeneousFrameConcept<F> >();
00856         base::psynth_function_requires<MutableHomogeneousChannelBaseConcept<F> >();
00857         p[0] = p[0];
00858     }
00859     F p;
00860 };
00861 
00873 template <typename F>
00874 struct FrameValueConcept
00875 {
00876     void constraints() {
00877         base::psynth_function_requires<FrameConcept<F> >();
00878         base::psynth_function_requires<base::Regular<F> >();
00879     }
00880 };
00881 
00893 template <typename F>
00894 struct HomogeneousFrameValueConcept
00895 {
00896     void constraints() {
00897         base::psynth_function_requires<HomogeneousFrameConcept<F> >();
00898         base::psynth_function_requires<base::Regular<F> >();
00899         BOOST_STATIC_ASSERT((boost::is_same<F, typename F::value_type>::value));
00900     }
00901 };
00902 
00903 namespace detail
00904 {
00905     template <typename F1, typename F2, int K>
00906     struct samples_are_pairwise_compatible : public 
00907         boost::mpl::and_<
00908         samples_are_pairwise_compatible<F1,F2,K-1>,
00909         samples_are_compatible<
00910             typename kth_semantic_element_reference_type<F1,K>::type,
00911             typename kth_semantic_element_reference_type<F2,K>::type> >
00912     {};
00913                                                  
00914     template <typename F1, typename F2>
00915     struct samples_are_pairwise_compatible<F1, F2, -1> :
00916         public boost::mpl::true_ {};
00917 } /* namespace detail */
00918 
00928 template <typename F1, typename F2>  // Models Psynth Frame
00929 struct frames_are_compatible 
00930     : public boost::mpl::and_<typename channel_spaces_are_compatible<
00931                                   typename channel_space_type<F1>::type, 
00932                                   typename channel_space_type<F2>::type>::type, 
00933                               detail::samples_are_pairwise_compatible<
00934                                   F1, F2, num_samples<F1>::value-1> > {};
00935 
00955 template <typename F1, typename F2>
00956 // precondition: P1 and P2 model FrameConcept
00957 struct FramesCompatibleConcept
00958 {
00959     void constraints() {
00960         BOOST_STATIC_ASSERT((frames_are_compatible<F1,F2>::value));
00961     }
00962 };
00963 
00980 template <typename SrcP, typename DstP>
00981 struct FrameConvertibleConcept
00982 {
00983     void constraints() {
00984         base::psynth_function_requires<FrameConcept<SrcP> >();
00985         base::psynth_function_requires<MutableFrameConcept<DstP> >();
00986         channel_convert(src,dst);
00987     }
00988     SrcP src;
00989     DstP dst;
00990 };
00991 
00992 
00993 /*
00994  *
00995  *      Dereference Adaptors Concepts
00996  *
00997  */
00998 
01024 template <typename D>
01025 struct FrameDereferenceAdaptorConcept
01026 {
01027     void constraints() {
01028         base::psynth_function_requires< boost::UnaryFunctionConcept<D, 
01029             typename remove_const_and_reference<typename D::result_type>::type, 
01030             typename D::argument_type> >();
01031         base::psynth_function_requires< boost::DefaultConstructibleConcept<D> >();
01032         base::psynth_function_requires< boost::CopyConstructibleConcept<D> >();
01033         base::psynth_function_requires< boost::AssignableConcept<D> >();
01034 
01035         base::psynth_function_requires<FrameConcept<
01036             typename remove_const_and_reference<
01037                 typename D::result_type>::type> >();
01038 
01039         typedef typename D::const_t const_t;
01040         base::psynth_function_requires<FrameDereferenceAdaptorConcept<const_t> >();
01041         typedef typename D::value_type value_type;
01042         base::psynth_function_requires<FrameValueConcept<value_type> >();
01043         typedef typename D::reference reference;
01044         // == FrameConcept (if you remove const and reference)
01045         typedef typename D::const_reference const_reference;
01046         // == FrameConcept (if you remove const and reference)
01047 
01048         const bool is_mutable = D::is_mutable;
01049         boost::ignore_unused_variable_warning (is_mutable);
01050     }
01051     D d;
01052 };
01053 
01054 template <typename F>
01055 struct FrameDereferenceAdaptorArchetype : public std::unary_function<F, F>
01056 {
01057     typedef FrameDereferenceAdaptorArchetype const_t;
01058     typedef typename boost::remove_reference<F>::type value_type;
01059     typedef typename boost::add_reference<F>::type reference;
01060     typedef reference const_reference;
01061     static const bool is_mutable=false;
01062     F operator()(F x) const { throw; }
01063 };
01064 
01065 
01066 /*
01067  *
01068  *     Frame iterator concepts.
01069  *
01070  */
01071 
01087 template <typename T>
01088 struct HasDynamicStepTypeConcept
01089 {   
01090     void constraints () {
01091         typedef typename dynamic_step_type<T>::type type;
01092     }
01093 };
01094 
01128 template <typename Iterator>
01129 struct FrameIteratorConcept
01130 {   
01131     void constraints()
01132     {
01133         base::psynth_function_requires<
01134             boost_concepts::RandomAccessTraversalConcept<Iterator> >();
01135         base::psynth_function_requires<FrameBasedConcept<Iterator> >();
01136         
01137         typedef typename std::iterator_traits<Iterator>::value_type value_type;
01138         base::psynth_function_requires<FrameValueConcept<value_type> >();
01139  
01140         typedef typename const_iterator_type<Iterator>::type const_t;
01141         static const bool is_mut = iterator_is_mutable<Iterator>::type::value;
01142         boost::ignore_unused_variable_warning (is_mut);
01143 
01144         const_t const_it(it);
01145         boost::ignore_unused_variable_warning(const_it);
01146         // immutable iterator must be constructible from (possibly
01147         // mutable) iterator
01148 
01149         check_base (typename is_iterator_adaptor<Iterator>::type ());
01150     }
01151     
01152     void check_base(boost::mpl::false_) {}
01153 
01154     void check_base(boost::mpl::true_)
01155     {
01156         typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
01157         base::psynth_function_requires<FrameIteratorConcept<base_t> >();
01158     }
01159 
01160     Iterator it;
01161 };
01162 
01163 namespace detail
01164 {
01165     template <typename Iterator>
01166     // Preconditions: Iterator Models FrameIteratorConcept
01167     struct FrameIteratorIsMutableConcept
01168     {
01169         void constraints()
01170         {
01171             base::psynth_function_requires<
01172                 detail::RandomAccessIteratorIsMutableConcept<Iterator> >();
01173             typedef typename boost::remove_reference<
01174                 typename std::iterator_traits<Iterator>::reference>::type ref;
01175             typedef typename element_type<ref>::type sample_t;
01176             base::psynth_function_requires<detail::SampleIsMutableConcept<sample_t> >();
01177         }
01178     };
01179 }
01180 
01192 template <typename Iterator>
01193 struct MutableFrameIteratorConcept
01194 {
01195     void constraints()
01196     {
01197         base::psynth_function_requires<FrameIteratorConcept<Iterator> >();
01198         base::psynth_function_requires<
01199             detail::FrameIteratorIsMutableConcept<Iterator> >();
01200     }
01201 };
01202 
01203 namespace detail
01204 {
01205 
01206 /*
01207   Iterators that can be used as the base of memory_based_step_iterator
01208   require some additional functions
01209 */
01210 template <typename Iterator>
01211 // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
01212 struct RandomAccessIteratorIsMemoryBasedConcept
01213 {
01214     void constraints()
01215     {
01216         std::ptrdiff_t bs=memunit_step(it);
01217         boost::ignore_unused_variable_warning (bs);
01218         it=memunit_advanced(it,3);
01219         std::ptrdiff_t bd=memunit_distance(it,it);
01220         boost::ignore_unused_variable_warning(bd);
01221         memunit_advance(it,3);
01222         // for performace you may also provide a customized
01223         // implementation of memunit_advanced_ref
01224     }
01225     Iterator it;
01226 };
01227 
01228 } /* namespace detail */
01229 
01256 template <typename Iterator>
01257 struct MemoryBasedIteratorConcept
01258 {
01259     void constraints ()
01260     {
01261         base::psynth_function_requires<
01262             boost_concepts::RandomAccessTraversalConcept<Iterator> >();
01263         base::psynth_function_requires<
01264             detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
01265     }
01266 };
01267 
01282 template <typename Iterator>
01283 struct StepIteratorConcept
01284 {
01285     void constraints()
01286     {
01287         base::psynth_function_requires<
01288             boost_concepts::ForwardTraversalConcept<Iterator> >();
01289         it.set_step(0);
01290     }
01291     Iterator it;
01292 };
01293 
01294 
01305 template <typename Iterator>
01306 struct MutableStepIteratorConcept
01307 {
01308     void constraints()
01309     {
01310         base::psynth_function_requires<StepIteratorConcept<Iterator> >();
01311         base::psynth_function_requires<
01312             detail::ForwardIteratorIsMutableConcept<Iterator> >();
01313     }
01314 };
01315 
01353 template <typename Iterator>
01354 struct IteratorAdaptorConcept
01355 {
01356     void constraints()
01357     {
01358         base::psynth_function_requires<
01359             boost_concepts::ForwardTraversalConcept<Iterator> >();
01360 
01361         typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
01362         base::psynth_function_requires<
01363             boost_concepts::ForwardTraversalConcept<base_t> >();
01364 
01365         BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
01366         typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
01367 
01368         base_t base=it.base();  boost::ignore_unused_variable_warning(base);
01369     }
01370     Iterator it;
01371 };
01372 
01384 template <typename Iterator>
01385 struct MutableIteratorAdaptorConcept
01386 {
01387     void constraints()
01388     {
01389         base::psynth_function_requires<IteratorAdaptorConcept<Iterator> >();
01390         base::psynth_function_requires<
01391             detail::ForwardIteratorIsMutableConcept<Iterator> >();
01392     }
01393 };
01394 
01395 
01396 /*
01397  *
01398  *             BUFFER RANGE CONCEPTS
01399  *
01400  */
01401 
01456 template <typename Range>
01457 struct RandomAccessBufferRangeConcept
01458 {
01459     void constraints ()
01460     {
01461         base::psynth_function_requires< base::Regular<Range> >();
01462 
01463         typedef typename Range::value_type       value_type;
01464         typedef typename Range::reference        reference;
01465         // result of dereferencing
01466         typedef typename Range::difference_type  difference_type;
01467         // result of operator-(1d_iterator,1d_iterator)
01468 
01469         typedef typename Range::iterator         iterator;
01470         typedef typename Range::reverse_iterator reverse_iterator;
01471         typedef typename Range::size_type        size_type;
01472             
01473         base::psynth_function_requires<
01474             boost_concepts::RandomAccessTraversalConcept<iterator> >();
01475         base::psynth_function_requires<
01476             boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
01477 
01478         iterator it;
01479         reverse_iterator rit;
01480         difference_type d;
01481         size_type sz;
01482         detail::initialize_it (d); boost::ignore_unused_variable_warning(d);
01483 
01484         Range (sz, it); // range must be constructible from a locator and a point
01485 
01486         // TODO: Should we minimize this interface to match Boost.Range?
01487         sz = range.size ();  boost::ignore_unused_variable_warning(sz);
01488         it = range.frames ();
01489         
01490         it  = range.begin ();
01491         it  = range.end ();
01492         rit = range.rbegin ();
01493         rit = range.rend ();
01494 
01495         reference r1=range[d]; boost::ignore_unused_variable_warning(r1);
01496         // 1D access 
01497         
01498         typedef FrameDereferenceAdaptorArchetype<typename Range::value_type>
01499             deref_t;
01500         typedef typename Range::template add_deref<deref_t>::type dtype;
01501     }
01502     Range range;
01503 };
01504 
01518 template <typename Range>
01519 struct BufferRangeConcept {
01520     void constraints() {
01521         base::psynth_function_requires<RandomAccessBufferRangeConcept<Range> >();
01522 
01523         std::size_t num_chan = range.num_samples ();
01524         boost::ignore_unused_variable_warning (num_chan);
01525 
01526     }
01527     Range range;
01528 };
01529 
01530 
01531 namespace detail {
01532 
01533 template <typename Range>
01534 // Preconditions: Range Models RandomAccessNDBufferRangeConcept
01535 struct RandomAccessBufferRangeIsMutableConcept
01536 {
01537     void constraints() {
01538         base::psynth_function_requires<
01539             detail::RandomAccessIteratorIsMutableConcept<
01540                 typename Range::iterator> >();
01541         base::psynth_function_requires<
01542             detail::RandomAccessIteratorIsMutableConcept<
01543                 typename Range::reverse_iterator> >();
01544         
01545         typename Range::difference_type diff;
01546         initialize_it(diff); boost::ignore_unused_variable_warning(diff);
01547         typename Range::value_type v; initialize_it(v);
01548         
01549         range[diff]=v;
01550     }
01551     Range range;
01552 };
01553 
01554 template <typename Range>    // preconditions: Range Models BufferRangeConcept
01555 struct FrameBufferRangeIsMutableConcept
01556 {
01557     void constraints() {        
01558         base::psynth_function_requires<
01559             detail::RandomAccessBufferRangeIsMutableConcept<Range> >();
01560     }
01561 };
01562 
01563 } /* namespace detail */
01564 
01577 template <typename Range>
01578 struct MutableRandomAccessBufferRangeConcept
01579 {
01580     void constraints() {
01581         base::psynth_function_requires<RandomAccessBufferRangeConcept<Range> >();
01582         base::psynth_function_requires<
01583             detail::RandomAccessBufferRangeIsMutableConcept<Range> >();
01584     }
01585 };
01586 
01597 template <typename Range>
01598 struct MutableBufferRangeConcept
01599 {
01600     void constraints() {
01601         base::psynth_function_requires<BufferRangeConcept<Range> >();
01602         base::psynth_function_requires<
01603             detail::FrameBufferRangeIsMutableConcept<Range> >();
01604     }
01605 };
01606 
01613 template <typename V1, typename V2>  // Model BufferRangeConcept
01614 struct ranges_are_compatible :
01615     public frames_are_compatible<typename V1::value_type,
01616                                  typename V2::value_type> {};
01617 
01618 
01633 template <typename V1, typename V2>
01634 struct RangesCompatibleConcept
01635 {
01636     void constraints () {
01637         BOOST_STATIC_ASSERT((ranges_are_compatible<V1,V2>::value));
01638     }
01639 };
01640 
01641 
01642 /*
01643  *
01644  *            BUFFER CONCEPTS
01645  *
01646  */
01647 
01672 template <typename Buf>
01673 struct RandomAccessBufferConcept
01674 {
01675     void constraints() {
01676         base::psynth_function_requires<base::Regular<Buf> >();
01677 
01678         typedef typename Buf::range       range_t;
01679         base::psynth_function_requires<
01680             MutableRandomAccessBufferRangeConcept<range_t> >();
01681 
01682         typedef typename Buf::const_range const_range_t;
01683         typedef typename Buf::value_type   frame_t;
01684 
01685         const_range_t cv = const_range(buf);
01686         boost::ignore_unused_variable_warning(cv);
01687         range_t       v  = range(buf);
01688         boost::ignore_unused_variable_warning(v);
01689 
01690         frame_t fill_value;
01691         typename Buf::size_type pt = buf.size ();
01692         Buf im1 (pt);
01693         Buf im2 (pt,1);
01694         Buf im3 (pt, fill_value, 1);
01695         buf.recreate(pt);
01696         buf.recreate(pt,1);
01697         buf.recreate(pt,fill_value,1);
01698     }
01699     Buf buf;
01700 };
01701 
01702 
01715 template <typename Buf>
01716 struct BufferConcept
01717 {
01718     void constraints() {
01719         base::psynth_function_requires<RandomAccessBufferConcept<Buf> >();
01720         base::psynth_function_requires<MutableBufferRangeConcept<
01721             typename Buf::range> >();
01722         
01723         BOOST_STATIC_ASSERT(num_samples<Buf>::value ==
01724                             boost::mpl::size<
01725                                 typename channel_space_type<Buf>::type>::value);
01726     }
01727     Buf buf;
01728 };
01729 
01730 } /* namespace sound */
01731 } /* namespace psynth */
01732 
01733 #endif /* PSYNTH_SOUND_CONCEPT */