|
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_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 */
1.7.4