libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/buffer_range.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_BUFFER_RANGE_H_
00040 #define PSYNTH_SOUND_BUFFER_RANGE_H_
00041 
00042 #include <cstddef>
00043 #include <iterator>
00044 
00045 #include <psynth/base/compat.hpp>
00046 #include <psynth/sound/frame.hpp>
00047 #include <psynth/sound/frame_iterator_adaptor.hpp>
00048 #include <psynth/sound/step_iterator.hpp>
00049 #include <psynth/sound/planar_frame_reference.hpp>
00050 #include <psynth/sound/planar_frame_iterator.hpp>
00051 
00052 //#ifdef _MSC_VER
00053 //#pragma warning(push)
00054 //#pragma warning(disable : 4244)
00055 // conversion from 'psynth::image<V,Alloc>::size_type' to 'int', possible
00056 // loss of data (visual studio compiler doesn't realize that the two
00057 // types are the same)
00058 //#endif
00059 
00060 namespace psynth
00061 {
00062 namespace sound
00063 {
00064 
00104 template <typename Iterator>
00105 // Models 1D Frame Iterator
00106 class buffer_range
00107 {
00108 public:
00110     typedef typename std::iterator_traits<Iterator>::value_type
00111     value_type;
00112 
00113     typedef typename std::iterator_traits<Iterator>::reference
00114     reference;
00115 
00116     typedef typename std::iterator_traits<Iterator>::difference_type
00117     difference_type;
00118     
00119     typedef buffer_range<typename const_iterator_type<Iterator>::type>
00120     const_type;
00121 
00122     typedef Iterator                               iterator;
00123     typedef std::reverse_iterator<iterator>        reverse_iterator;
00124     typedef std::ptrdiff_t                         size_type;
00125 
00126     template <typename Deref>
00127     struct add_deref
00128     {
00129         typedef buffer_range <
00130             typename iterator_add_deref<Iterator, Deref>::type> type;
00131         static type make (const buffer_range<Iterator>& bv, const Deref& d)
00132         {
00133             return type (bv.size (),
00134                          iterator_add_deref<Iterator, Deref>::make (
00135                              bv.frames (), d));
00136         }
00137     };
00138 
00139     buffer_range ()
00140         : _size (0)
00141     {}
00142 
00143 #ifdef PSYNTH_BUFFER_MODEL_RANGE
00144     
00146     template <typename Range>
00147     buffer_range (Range& bv)
00148         : _size (bv.size ())
00149         , _frames (bv.frames ()) {}
00150 
00151 #endif /* PSYNTH_BUFFER_MODEL_RANGE */
00152 
00153     buffer_range (const buffer_range& bv) = default;
00154 
00155     template <typename Range>
00156     buffer_range (Range&& bv)
00157         : _size (bv.size ())
00158         , _frames (bv.frames ()) {}
00159 
00160     template <typename Range>
00161     buffer_range (const Range& bv)
00162         : _size (bv.size ())
00163         , _frames (bv.frames ()) {}
00164 
00165     template <typename I2>
00166     buffer_range (size_type sz, I2 it)
00167         : _size (sz)
00168         , _frames (it)
00169     {}
00170     
00171     template <typename Range>
00172     buffer_range& operator= (const Range& bv)
00173     {
00174         _frames = bv.frames ();
00175         _size   = bv.size ();
00176         return *this;
00177     }
00178     
00179     buffer_range& operator= (const buffer_range& bv)
00180     {
00181         _frames = bv.frames ();
00182         _size   = bv.size ();
00183         return *this;
00184     }
00185 
00186     template <typename Range>
00187     bool operator== (const Range& v) const
00188     {
00189         return frames () == v.frames () && size () == v.size();
00190     }
00191     
00192     template <typename Range>
00193     bool operator!= (const Range& v) const
00194     {
00195         return !(*this == v);
00196     }
00197 
00198     template <typename L2>
00199     friend void swap (buffer_range<L2>& x, buffer_range<L2>& y);
00200 
00201     size_type size () const
00202     {
00203         return _size;
00204     }
00205 
00206     const iterator& frames () const
00207     {
00208         return _frames;
00209     }
00210     
00211     std::size_t frame_size () const
00212     {
00213         return memunit_step (begin ());
00214     }
00215     
00216     std::size_t num_samples () const
00217     {
00218         return psynth::sound::num_samples<value_type>::value;
00219     }
00220     
00221     iterator begin () const
00222     {
00223         return _frames;
00224     }
00225     
00226     iterator end () const
00227     {
00228         return begin () + (difference_type) size();
00229     } // potential performance problem!
00230 
00231     reverse_iterator rbegin() const
00232     {
00233         return reverse_iterator (end ());
00234     }
00235     
00236     reverse_iterator rend () const
00237     {
00238         return reverse_iterator(begin());
00239     }
00240     
00241     reference operator [] (difference_type i) const
00242     {
00243         return begin() [i];
00244     } // potential performance problem!
00245 
00246     iterator at (difference_type i) const
00247     {
00248         return begin () + i;
00249     }
00250     //\}@
00251     
00252 private:
00253     template <typename L2> friend class buffer_range;
00254 
00255     size_type   _size;
00256     iterator    _frames;
00257 };
00258 
00259 template <typename I2> 
00260 inline void swap (buffer_range<I2>& x, buffer_range<I2>& y)
00261 { 
00262     using std::swap;
00263     swap (x._size, y._size); 
00264     swap (x._frames, y._frames); // TODO: Extend further
00265 }
00266 
00267 /*
00268  *
00269  *  FrameBasedConcept
00270  *
00271  */
00272 
00273 template <typename I>
00274 struct sample_type<buffer_range<I> > : public sample_type<I> {}; 
00275 
00276 template <typename I>
00277 struct channel_space_type<buffer_range<I> > : public channel_space_type<I> {}; 
00278 
00279 template <typename I>
00280 struct sample_mapping_type<buffer_range<I> > : public sample_mapping_type<I> {}; 
00281 
00282 template <typename I>
00283 struct is_planar<buffer_range<I> > : public is_planar<I> {}; 
00284 
00285 /*
00286  *
00287  *      HasDynamicStepTypeConcept
00288  *
00289  */
00290 
00291 template <typename L>
00292 struct dynamic_step_type<buffer_range<L> >
00293 {
00294     typedef buffer_range<typename dynamic_step_type<L>::type> type;
00295 };
00296 
00297 
00298 } /* namespace sound */
00299 } /* namespace psynth */
00300 
00301 //#ifdef _MSC_VER
00302 //#pragma warning(pop)
00303 //#endif
00304 
00305 #endif /* PSYNTH_BUFFER_RANGE_H_ */