|
libpsynth 0.2.1
|
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 */
1.7.4