libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/bit_aligned_frame_iterator.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_BIT_ALIGNED_FRAME_ITERATOR_HPP
00040 #define PSYNTH_SOUND_BIT_ALIGNED_FRAME_ITERATOR_HPP
00041 
00042 #include <functional>
00043 #include <boost/iterator/iterator_facade.hpp>
00044 
00045 #include <psynth/base/compat.hpp>
00046 #include <psynth/sound/bit_aligned_frame_reference.hpp>
00047 #include <psynth/sound/frame_iterator.hpp>
00048 
00049 namespace psynth
00050 {
00051 namespace sound
00052 {
00053 
00075 template <typename NonAlignedFrameReference>
00076 struct bit_aligned_frame_iterator : public boost::iterator_facade<
00077     bit_aligned_frame_iterator<NonAlignedFrameReference>,
00078     typename NonAlignedFrameReference::value_type,
00079     std::random_access_iterator_tag,
00080     const NonAlignedFrameReference,
00081     typename NonAlignedFrameReference::bit_range_type::difference_type>
00082 {
00083 private:
00084     typedef
00085     boost::iterator_facade<
00086     bit_aligned_frame_iterator<NonAlignedFrameReference>,
00087     typename NonAlignedFrameReference::value_type,
00088     std::random_access_iterator_tag,
00089     const NonAlignedFrameReference,
00090     typename NonAlignedFrameReference::bit_range_type::difference_type>
00091     parent_type;
00092 
00093     template <typename Ref> friend struct bit_aligned_frame_iterator;
00094 
00095     typedef typename NonAlignedFrameReference::bit_range_type bit_range_type;
00096 
00097 public:
00098     typedef typename parent_type::difference_type   difference_type;
00099     typedef typename parent_type::reference         reference;
00100 
00101     bit_aligned_frame_iterator () {}
00102     
00103     bit_aligned_frame_iterator (const bit_aligned_frame_iterator& p)
00104         : _bit_range (p._bit_range) {}
00105 
00106     bit_aligned_frame_iterator& operator= (const bit_aligned_frame_iterator& p)
00107     {
00108         _bit_range = p._bit_range;
00109         return *this;
00110     }
00111 
00112     template <typename Ref>
00113     bit_aligned_frame_iterator (const bit_aligned_frame_iterator<Ref>& p)
00114         : _bit_range (p._bit_range) {}
00115 
00116     bit_aligned_frame_iterator (reference* ref)
00117         : _bit_range (ref->bit_range ())
00118     {}
00119     
00120     explicit bit_aligned_frame_iterator (
00121         typename bit_range_type::byte_type* data, int bit_offset = 0)
00122         : _bit_range(data,bit_offset)
00123     {}
00124 
00132     reference operator [] (difference_type d) const
00133     {
00134         bit_aligned_frame_iterator it = *this;
00135         it.advance (d);
00136         return *it;
00137     }
00138 
00139     reference operator-> () const { return **this; }
00140     
00141     const bit_range_type& bit_range () const { return _bit_range; }
00142           bit_range_type& bit_range ()       { return _bit_range; }
00143 
00144 private:
00145     bit_range_type _bit_range;
00146     BOOST_STATIC_CONSTANT(int, bit_size = NonAlignedFrameReference::bit_size);
00147 
00148     friend class boost::iterator_core_access;
00149     reference dereference () const
00150     { return NonAlignedFrameReference(_bit_range); }
00151     
00152     void increment ()
00153     { ++_bit_range; }
00154 
00155     void decrement ()
00156     { --_bit_range; }
00157 
00158     void advance (difference_type d)
00159     { _bit_range.bit_advance (d * bit_size); }
00160 
00161     difference_type distance_to (const bit_aligned_frame_iterator& it) const
00162     { return _bit_range.bit_distance_to(it._bit_range) / bit_size; }
00163     
00164     bool equal (const bit_aligned_frame_iterator& it) const
00165     { return _bit_range == it._bit_range; }
00166 };
00167 
00168 template <typename NonAlignedFrameReference> 
00169 struct const_iterator_type<bit_aligned_frame_iterator<NonAlignedFrameReference> >
00170 { 
00171     typedef bit_aligned_frame_iterator<
00172         typename NonAlignedFrameReference::const_reference> type; 
00173 };
00174 
00175 template <typename NonAlignedFrameReference> 
00176 struct iterator_is_mutable<
00177     bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00178         public boost::mpl::bool_<NonAlignedFrameReference::is_mutable> {};
00179 
00180 template <typename NonAlignedFrameReference> 
00181 struct is_iterator_adaptor<
00182     bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00183         public boost::mpl::false_ {};
00184 
00185 /*
00186  *
00187  *    FrameBasedConcept
00188  *
00189  */
00190 
00191 template <typename NonAlignedFrameReference>
00192 struct channel_space_type<
00193     bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00194         public channel_space_type<NonAlignedFrameReference> {};
00195 
00196 template <typename NonAlignedFrameReference>
00197 struct sample_mapping_type<
00198     bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00199         public sample_mapping_type<NonAlignedFrameReference> {};
00200 
00201 template <typename NonAlignedFrameReference>
00202 struct is_planar<bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00203     public is_planar<NonAlignedFrameReference> {}; // == false
00204 
00205 
00206 /*
00207  *
00208  *    MemoryBasedIteratorConcept
00209  *
00210  */
00211 
00212 template <typename NonAlignedFrameReference>
00213 struct byte_to_memunit<bit_aligned_frame_iterator<NonAlignedFrameReference> > :
00214     public boost::mpl::int_<8> {};
00215 
00216 template <typename NonAlignedFrameReference>
00217 inline std::ptrdiff_t memunit_step (
00218     const bit_aligned_frame_iterator<NonAlignedFrameReference>&)
00219 { 
00220     return NonAlignedFrameReference::bit_size; 
00221 }
00222 
00223 template <typename NonAlignedFrameReference>
00224 inline std::ptrdiff_t memunit_distance (
00225     const bit_aligned_frame_iterator<NonAlignedFrameReference>& p1,
00226     const bit_aligned_frame_iterator<NonAlignedFrameReference>& p2)
00227 { 
00228     return
00229         (p2.bit_range().current_byte() -
00230          p1.bit_range().current_byte()) * 8 +
00231         p2.bit_range().bit_offset() -
00232         p1.bit_range().bit_offset(); 
00233 }
00234 
00235 template <typename NonAlignedFrameReference>
00236 inline void memunit_advance (
00237     bit_aligned_frame_iterator<NonAlignedFrameReference>& p,
00238     std::ptrdiff_t diff)
00239 { 
00240     p.bit_range().bit_advance(diff);
00241 }
00242 
00243 template <typename NonAlignedFrameReference>
00244 inline bit_aligned_frame_iterator<NonAlignedFrameReference>
00245 memunit_advanced (const bit_aligned_frame_iterator<NonAlignedFrameReference>& p,
00246                   std::ptrdiff_t diff)
00247 {
00248     bit_aligned_frame_iterator<NonAlignedFrameReference> ret = p;
00249     memunit_advance (ret, diff);
00250     return ret;
00251 }
00252 
00253 template <typename NonAlignedFrameReference> inline
00254 NonAlignedFrameReference memunit_advanced_ref(
00255     bit_aligned_frame_iterator<NonAlignedFrameReference> it,
00256     std::ptrdiff_t diff)
00257 {
00258     return * memunit_advanced (it, diff);
00259 }
00260 
00261 
00262 /*
00263  *
00264  *    HasDynamicStepTypeConcept
00265  *
00266  */
00267 
00268 template <typename NonAlignedFrameReference>
00269 struct dynamic_step_type<bit_aligned_frame_iterator<NonAlignedFrameReference> >
00270 {
00271     typedef memory_based_step_iterator<
00272         bit_aligned_frame_iterator<NonAlignedFrameReference> > type;
00273 };
00274 
00275 
00276 /*
00277  *
00278  *  iterator_type_from_frame
00279  *
00280  */
00281 
00282 template <typename B, typename C, typename L, bool M>
00283 struct iterator_type_from_frame<
00284     const bit_aligned_frame_reference<B,C,L,M>, false, false, false>
00285 {
00286     typedef bit_aligned_frame_iterator<
00287         bit_aligned_frame_reference<B,C,L,false> > type;
00288 };
00289 
00290 template <typename B, typename C, typename L, bool M>
00291 struct iterator_type_from_frame<
00292     const bit_aligned_frame_reference<B,C,L,M>, false, false, true>
00293 {
00294     typedef bit_aligned_frame_iterator<
00295         bit_aligned_frame_reference<B,C,L,true> > type;
00296 };
00297 
00298 template <typename B, typename C, typename L,
00299           bool M, bool IsPlanar, bool IsStep, bool IsMutable>
00300 struct iterator_type_from_frame<
00301     bit_aligned_frame_reference<B,C,L,M>, IsPlanar, IsStep, IsMutable>
00302     : public iterator_type_from_frame<const bit_aligned_frame_reference<B,C,L,M>,
00303                                       IsPlanar, IsStep, IsMutable> {};
00304 
00305 } /* namespace sound */
00306 } /* namespace psynth */
00307 
00308 namespace std
00309 {
00310 
00311 /*
00312   It is important to provide an overload of uninitialized_copy for
00313   bit_aligned_frame_iterator. The default STL implementation calls
00314   placement new, which is not defined for bit_aligned_frame_iterator.
00315 */ 
00316 template <typename NonAlignedFrameReference>
00317 psynth::sound::bit_aligned_frame_iterator<NonAlignedFrameReference>
00318 uninitialized_copy (
00319     psynth::sound::bit_aligned_frame_iterator<NonAlignedFrameReference> first,
00320     psynth::sound::bit_aligned_frame_iterator<NonAlignedFrameReference> last,
00321     psynth::sound::bit_aligned_frame_iterator<NonAlignedFrameReference> dst)
00322 {
00323     return std::copy (first, last, dst);
00324 }
00325 
00326 } /* namespace std */
00327 
00328 #endif /* PSYNTH_SOUND_BIT_ALIGNED_FRAME_ITERATOR */