libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/frame_iterator_adaptor.hpp
Go to the documentation of this file.
00001 
00011 /*
00012  *  Copyright (C) 2010 Juan Pedro Bolivar Puente
00013  *
00014  *  This file is part of Psychosynth.
00015  *   
00016  *  Psychosynth is free software: you can redistribute it and/or modify
00017  *  it under the terms of the GNU General Public License as published by
00018  *  the Free Software Foundation, either version 3 of the License, or
00019  *  (at your option) any later version.
00020  *
00021  *  Psychosynth is distributed in the hope that it will be useful,
00022  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *  GNU General Public License for more details.
00025  *
00026  *  You should have received a copy of the GNU General Public License
00027  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028  *
00029  */
00030 
00031 /*
00032  *  Copyright 2005-2007 Adobe Systems Incorporated
00033  * 
00034  *  Use, modification and distribution are subject to the Boost
00035  *  Software License, Version 1.0. (See accompanying file
00036  *  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
00037  */
00038 
00039 #ifndef PSYNTH_SOUND_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 */