|
libpsynth 0.2.1
|
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_FRAME_ITERATOR_ADAPTOR_H 00040 #define PSYNTH_SOUND_FRAME_ITERATOR_ADAPTOR_H 00041 00042 #include <iterator> 00043 #include <boost/iterator/iterator_facade.hpp> 00044 00045 #include <psynth/base/compat.hpp> 00046 #include <psynth/sound/concept.hpp> 00047 #include <psynth/sound/frame_iterator.hpp> 00048 00049 namespace psynth 00050 { 00051 namespace sound 00052 { 00053 00068 template <typename Iterator, 00069 // Models Iterator 00070 typename DFn 00071 // Models Returns the result of dereferencing a given 00072 // iterator of type Iterator 00073 > 00074 class dereference_iterator_adaptor : 00075 public boost::iterator_adaptor<dereference_iterator_adaptor<Iterator, DFn>, 00076 Iterator, 00077 typename DFn::value_type, 00078 typename std::iterator_traits< 00079 Iterator>::iterator_category, 00080 typename DFn::reference, 00081 boost::use_default> 00082 { 00083 DFn _deref_fn; 00084 00085 public: 00086 typedef boost::iterator_adaptor<dereference_iterator_adaptor<Iterator,DFn>, 00087 Iterator, 00088 typename DFn::value_type, 00089 typename std::iterator_traits< 00090 Iterator>::iterator_category, 00091 typename DFn::reference, 00092 boost::use_default> parent_type; 00093 typedef typename DFn::result_type reference; 00094 typedef typename std::iterator_traits<Iterator>::difference_type 00095 difference_type; 00096 typedef DFn dereference_fn; 00097 00098 dereference_iterator_adaptor () {} 00099 00100 template <typename Iterator1> 00101 dereference_iterator_adaptor ( 00102 const dereference_iterator_adaptor<Iterator1,DFn>& dit) 00103 : parent_type (dit.base()) 00104 , _deref_fn (dit._deref_fn) 00105 {} 00106 00107 dereference_iterator_adaptor (Iterator it, DFn deref_fn = DFn()) 00108 : parent_type (it) 00109 , _deref_fn (deref_fn) 00110 {} 00111 00112 template <typename Iterator1, typename DFn1> 00113 dereference_iterator_adaptor ( 00114 const dereference_iterator_adaptor<Iterator1,DFn1>& it) 00115 : parent_type (it.base()) 00116 , _deref_fn (it._deref_fn) 00117 {} 00118 00124 reference operator[] (difference_type d) const { return *(*this + d); } 00125 00126 /* 00127 although iterator_adaptor defines these, the default 00128 implementation computes distance and compares for zero. it is 00129 often faster to just apply the relation operator to the base 00130 */ 00131 bool operator> (const dereference_iterator_adaptor& p) const 00132 { return this->base_reference() > p.base_reference(); } 00133 00134 bool operator< (const dereference_iterator_adaptor& p) const 00135 { return this->base_reference() < p.base_reference(); } 00136 00137 bool operator>= (const dereference_iterator_adaptor& p) const 00138 { return this->base_reference() >= p.base_reference(); } 00139 00140 bool operator<= (const dereference_iterator_adaptor& p) const 00141 { return this->base_reference() <= p.base_reference(); } 00142 00143 bool operator== (const dereference_iterator_adaptor& p) const 00144 { return this->base_reference() == p.base_reference(); } 00145 00146 bool operator!= (const dereference_iterator_adaptor& p) const 00147 { return this->base_reference() != p.base_reference(); } 00148 00149 Iterator& base () { return this->base_reference (); } 00150 const Iterator& base () const { return this->base_reference (); } 00151 00152 const DFn& deref_fn () const { return _deref_fn; } 00153 00154 private: 00155 template <typename Iterator1, typename DFn1> 00156 friend class dereference_iterator_adaptor; 00157 friend class boost::iterator_core_access; 00158 00159 reference dereference () const 00160 { return _deref_fn(*(this->base_reference())); } 00161 }; 00162 00163 template <typename I, typename DFn> 00164 struct const_iterator_type<dereference_iterator_adaptor<I,DFn> > 00165 { 00166 typedef dereference_iterator_adaptor< 00167 typename const_iterator_type<I>::type,typename DFn::const_type> type; 00168 }; 00169 00170 template <typename I, typename DFn> 00171 struct iterator_is_mutable<dereference_iterator_adaptor<I, DFn> > : 00172 public boost::mpl::bool_<DFn::is_mutable> {}; 00173 00174 00175 template <typename I, typename DFn> 00176 struct is_iterator_adaptor<dereference_iterator_adaptor<I,DFn> > : 00177 public boost::mpl::true_ {}; 00178 00179 template <typename I, typename DFn> 00180 struct iterator_adaptor_get_base<dereference_iterator_adaptor<I,DFn> > 00181 { 00182 typedef I type; 00183 }; 00184 00185 template <typename I, typename DFn, typename NewBaseIterator> 00186 struct iterator_adaptor_rebind <dereference_iterator_adaptor<I,DFn>, 00187 NewBaseIterator> 00188 { 00189 typedef dereference_iterator_adaptor<NewBaseIterator,DFn> type; 00190 }; 00191 00192 00193 /* 00194 * 00195 * FrameBasedConcept 00196 * 00197 */ 00198 00199 template <typename I, typename DFn> 00200 struct channel_space_type<dereference_iterator_adaptor<I,DFn> > : 00201 public channel_space_type<typename DFn::value_type> {}; 00202 00203 template <typename I, typename DFn> 00204 struct sample_mapping_type<dereference_iterator_adaptor<I,DFn> > : 00205 public sample_mapping_type<typename DFn::value_type> {}; 00206 00207 template <typename I, typename DFn> 00208 struct is_planar<dereference_iterator_adaptor<I,DFn> > : 00209 public is_planar<typename DFn::value_type> {}; 00210 00211 template <typename I, typename DFn> 00212 struct sample_type<dereference_iterator_adaptor<I,DFn> > : 00213 public sample_type<typename DFn::value_type> {}; 00214 00215 00216 /* 00217 * 00218 * MemoryBasedIteratorConcept 00219 * 00220 */ 00221 00222 template <typename Iterator, typename DFn> 00223 struct byte_to_memunit<dereference_iterator_adaptor<Iterator,DFn> > : 00224 public byte_to_memunit<Iterator> {}; 00225 00226 template <typename Iterator, typename DFn> 00227 inline typename std::iterator_traits<Iterator>::difference_type 00228 memunit_step(const dereference_iterator_adaptor<Iterator, DFn>& p) 00229 { 00230 return memunit_step (p.base()); 00231 } 00232 00233 template <typename Iterator, typename DFn> 00234 inline typename std::iterator_traits<Iterator>::difference_type 00235 memunit_distance (const dereference_iterator_adaptor<Iterator,DFn>& p1, 00236 const dereference_iterator_adaptor<Iterator,DFn>& p2) 00237 { 00238 return memunit_distance (p1.base(), p2.base()); 00239 } 00240 00241 template <typename Iterator, typename DFn> 00242 inline void memunit_advance( 00243 dereference_iterator_adaptor<Iterator,DFn>& p, 00244 typename std::iterator_traits<Iterator>::difference_type diff) 00245 { 00246 memunit_advance (p.base(), diff); 00247 } 00248 00249 template <typename Iterator, typename DFn> 00250 inline dereference_iterator_adaptor<Iterator,DFn> 00251 memunit_advanced ( 00252 const dereference_iterator_adaptor<Iterator,DFn>& p, 00253 typename std::iterator_traits<Iterator>::difference_type diff) 00254 { 00255 return dereference_iterator_adaptor<Iterator,DFn> ( 00256 memunit_advanced (p.base(), diff), p.deref_fn ()); 00257 } 00258 00259 template <typename Iterator, typename DFn> inline 00260 typename std::iterator_traits< 00261 dereference_iterator_adaptor<Iterator,DFn> >::reference 00262 memunit_advanced_ref ( 00263 const dereference_iterator_adaptor<Iterator,DFn>& p, 00264 typename std::iterator_traits<Iterator>::difference_type diff) 00265 { 00266 return * memunit_advanced (p, diff); 00267 } 00268 00269 00270 /* 00271 * 00272 * HasDynamicStepTypeConcept 00273 * 00274 */ 00275 00276 template <typename Iterator, typename DFn> 00277 struct dynamic_step_type<dereference_iterator_adaptor<Iterator,DFn> > 00278 { 00279 typedef dereference_iterator_adaptor< 00280 typename dynamic_step_type<Iterator>::type, DFn> type; 00281 }; 00282 00289 template <typename Iterator, typename Deref> 00290 struct iterator_add_deref 00291 { 00292 PSYNTH_CLASS_REQUIRE(Deref, psynth::sound, FrameDereferenceAdaptorConcept) 00293 00294 typedef dereference_iterator_adaptor<Iterator, Deref> type; 00295 00296 static type make (const Iterator& it, const Deref& d) 00297 { return type (it, d); } 00298 }; 00299 00306 template <typename Iterator, typename PrevDeref, typename Deref> 00307 struct iterator_add_deref< 00308 dereference_iterator_adaptor<Iterator, PrevDeref>, Deref> 00309 { 00310 // PSYNTH_CLASS_REQUIRE(Deref, psynth::sound, FrameDereferenceAdaptorConcept) 00311 00312 typedef dereference_iterator_adaptor< 00313 Iterator, deref_compose<Deref, PrevDeref> > type; 00314 00315 static type make ( 00316 const dereference_iterator_adaptor<Iterator, PrevDeref>& it, 00317 const Deref& d) 00318 { 00319 return type (it.base(), 00320 deref_compose<Deref, PrevDeref>(d, it.deref_fn ())); 00321 } 00322 }; 00323 00324 } /* namespace sound */ 00325 } /* namespace psynth */ 00326 00327 #endif /* PSYNTH_SOUND_ITERATOR_ADAPTOR */
1.7.4