|
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_PLANAR_PTR_H 00040 #define PSYNTH_SOUND_PLANAR_PTR_H 00041 00042 #include <cassert> 00043 #include <iterator> 00044 #include <boost/iterator/iterator_facade.hpp> 00045 00046 #include <psynth/base/compat.hpp> 00047 #include <psynth/sound/frame.hpp> 00048 #include <psynth/sound/step_iterator.hpp> 00049 00050 namespace psynth 00051 { 00052 namespace sound 00053 { 00054 00055 /* 00056 forward declaration (as this file is included in 00057 planar_frame_reference.hpp) 00058 */ 00059 template <typename SampleReference, typename ChannelSpace> 00060 struct planar_frame_reference; 00061 00092 template <typename SamplePtr, typename ChannelSpace> 00093 struct planar_frame_iterator 00094 : public boost::iterator_facade< 00095 planar_frame_iterator<SamplePtr,ChannelSpace>, 00096 frame<typename std::iterator_traits< 00097 SamplePtr>::value_type, 00098 layout<ChannelSpace> >, 00099 std::random_access_iterator_tag, 00100 const planar_frame_reference< 00101 typename std::iterator_traits< 00102 SamplePtr>::reference, 00103 ChannelSpace> > 00104 00105 , public detail::homogeneous_channel_base< 00106 SamplePtr, 00107 layout<ChannelSpace>, 00108 boost::mpl::size<ChannelSpace>::value > 00109 { 00110 private: 00111 typedef 00112 boost::iterator_facade< 00113 planar_frame_iterator<SamplePtr,ChannelSpace>, 00114 frame<typename std::iterator_traits<SamplePtr>::value_type, 00115 layout<ChannelSpace> >, 00116 std::random_access_iterator_tag, 00117 const planar_frame_reference< 00118 typename std::iterator_traits<SamplePtr>::reference, 00119 ChannelSpace> > 00120 parent_type; 00121 00122 typedef detail::homogeneous_channel_base< 00123 SamplePtr, layout<ChannelSpace>, 00124 boost::mpl::size<ChannelSpace>::value> 00125 channel_base_parent_type; 00126 00127 typedef typename std::iterator_traits<SamplePtr>::value_type sample_type; 00128 00129 public: 00130 typedef typename parent_type::value_type value_type; 00131 typedef typename parent_type::reference reference; 00132 typedef typename parent_type::difference_type difference_type; 00133 00134 planar_frame_iterator () : channel_base_parent_type (0) {} 00135 planar_frame_iterator (bool) {} 00136 // constructor that does not fill with zero (for performance) 00137 00138 planar_frame_iterator (const SamplePtr& v0, 00139 const SamplePtr& v1) 00140 : channel_base_parent_type (v0, v1) {} 00141 00142 planar_frame_iterator (const SamplePtr& v0, 00143 const SamplePtr& v1, 00144 const SamplePtr& v2) 00145 : channel_base_parent_type (v0, v1, v2) {} 00146 00147 planar_frame_iterator (const SamplePtr& v0, 00148 const SamplePtr& v1, 00149 const SamplePtr& v2, 00150 const SamplePtr& v3) 00151 : channel_base_parent_type (v0, v1, v2, v3) {} 00152 00153 planar_frame_iterator (const SamplePtr& v0, 00154 const SamplePtr& v1, 00155 const SamplePtr& v2, 00156 const SamplePtr& v3, 00157 const SamplePtr& v4) 00158 : channel_base_parent_type (v0, v1, v2, v3, v4) {} 00159 00160 template <typename IC1, typename C1> 00161 planar_frame_iterator (const planar_frame_iterator<IC1,C1>& ptr) 00162 : channel_base_parent_type (ptr) {} 00163 00164 00171 template <typename P> 00172 planar_frame_iterator (P* pix) 00173 : channel_base_parent_type (pix, true) 00174 { 00175 boost::function_requires<FramesCompatibleConcept<P,value_type> >(); 00176 } 00177 00178 struct address_of 00179 { 00180 template <typename T> 00181 T* operator () (T& t) { return &t; } 00182 }; 00183 00184 template <typename P> 00185 planar_frame_iterator& operator= (P* pix) 00186 { 00187 /* 00188 TODO: 00189 It seems that the following statements are optimized away by 00190 GCC in some strange cases... 00191 */ 00192 boost::function_requires<FramesCompatibleConcept<P, value_type> >(); 00193 static_transform (*pix, *this, address_of ()); 00194 00195 /* 00196 TODO: 00197 Performance compare to this: 00198 this->template semantic_at_c<0>()=&pix->template 00199 semantic_at_c<0>(); 00200 this->template semantic_at_c<1>()=&pix->template 00201 semantic_at_c<1>(); 00202 this->template semantic_at_c<2>()=&pix->template 00203 semantic_at_c<2>(); 00204 */ 00205 return *this; 00206 } 00207 00215 reference operator[] (difference_type d) const 00216 { 00217 return memunit_advanced_ref (*this, d * sizeof (sample_type)); 00218 } 00219 00220 reference operator-> () const 00221 { 00222 return **this; 00223 } 00224 00225 // PERFORMANCE_CHECK: Remove? 00226 bool operator< (const planar_frame_iterator& ptr) const 00227 { 00228 return sound::at_c<0>(*this) < sound::at_c<0>(ptr); 00229 } 00230 00231 bool operator!= (const planar_frame_iterator& ptr) const 00232 { 00233 return sound::at_c<0>(*this) != sound::at_c<0>(ptr); 00234 } 00235 00236 private: 00237 friend class boost::iterator_core_access; 00238 00239 void increment() 00240 { 00241 static_transform (*this, *this, detail::inc<SamplePtr>()); 00242 } 00243 00244 void decrement () 00245 { 00246 static_transform (*this, *this, detail::dec<SamplePtr>()); 00247 } 00248 00249 void advance (ptrdiff_t d) 00250 { 00251 static_transform ( 00252 *this, *this, 00253 std::bind2nd (detail::plus_asymmetric<SamplePtr, ptrdiff_t>(), d)); 00254 } 00255 00256 reference dereference () const 00257 { 00258 return this->template deref<reference> (); 00259 } 00260 00261 ptrdiff_t distance_to (const planar_frame_iterator& it) const 00262 { 00263 return sound::at_c<0>(it) - sound::at_c<0>(*this); 00264 } 00265 00266 bool equal (const planar_frame_iterator& it) const 00267 { 00268 return sound::at_c<0>(*this) == sound::at_c<0>(it); 00269 } 00270 }; 00271 00272 namespace detail 00273 { 00274 00275 template <typename IC> 00276 struct sample_iterator_is_mutable : public boost::mpl::true_ {}; 00277 template <typename T> 00278 struct sample_iterator_is_mutable<const T*> : public boost::mpl::false_ {}; 00279 00280 } /* namespace detail */ 00281 00282 template <typename IC, typename C> 00283 struct const_iterator_type<planar_frame_iterator<IC,C> > 00284 { 00285 private: 00286 typedef typename std::iterator_traits<IC>::value_type sample_type; 00287 00288 public: 00289 typedef 00290 planar_frame_iterator<typename sample_traits<sample_type>::const_pointer, 00291 C> type; 00292 }; 00293 00298 template <typename IC, typename C> 00299 struct iterator_is_mutable<planar_frame_iterator<IC,C> > : 00300 public detail::sample_iterator_is_mutable<IC> {}; 00301 00302 /* 00303 * 00304 * ChannelBasedConcept 00305 * 00306 */ 00307 00308 template <typename IC, typename C, int K> 00309 struct kth_element_type<planar_frame_iterator<IC, C>, K> 00310 { 00311 typedef IC type; 00312 }; 00313 00314 template <typename IC, typename C, int K> 00315 struct kth_element_reference_type<planar_frame_iterator<IC,C>, K> : 00316 public boost::add_reference<IC> {}; 00317 00318 template <typename IC, typename C, int K> 00319 struct kth_element_const_reference_type<planar_frame_iterator<IC, C>, K> : 00320 public boost::add_reference<typename boost::add_const<IC>::type> {}; 00321 00322 00323 /* 00324 * 00325 * HomogeneousFrameBasedConcept 00326 * 00327 */ 00328 00329 template <typename IC, typename C> 00330 struct channel_space_type<planar_frame_iterator<IC,C> > 00331 { 00332 typedef C type; 00333 }; 00334 00335 template <typename IC, typename C> 00336 struct sample_mapping_type<planar_frame_iterator<IC,C> > : 00337 public sample_mapping_type< 00338 typename planar_frame_iterator<IC,C>::value_type> {}; 00339 00340 template <typename IC, typename C> 00341 struct is_planar<planar_frame_iterator<IC,C> > : public boost::mpl::true_ {}; 00342 00343 template <typename IC, typename C> 00344 struct sample_type<planar_frame_iterator<IC,C> > 00345 { 00346 typedef typename std::iterator_traits<IC>::value_type type; 00347 }; 00348 00349 00350 /* 00351 * 00352 * MemoryBasedIteratorConcept 00353 * 00354 */ 00355 00356 template <typename IC, typename C> 00357 inline std::ptrdiff_t memunit_step (const planar_frame_iterator<IC,C>&) 00358 { 00359 return sizeof (typename std::iterator_traits<IC>::value_type); 00360 } 00361 00362 template <typename IC, typename C> 00363 inline std::ptrdiff_t memunit_distance (const planar_frame_iterator<IC,C>& p1, 00364 const planar_frame_iterator<IC,C>& p2) 00365 { 00366 return memunit_distance (sound::at_c<0>(p1), sound::at_c<0>(p2)); 00367 } 00368 00369 template <typename IC> 00370 struct memunit_advance_fn 00371 { 00372 memunit_advance_fn (std::ptrdiff_t diff) 00373 : _diff (diff) {} 00374 00375 IC operator () (const IC& p) const { return memunit_advanced (p, _diff); } 00376 00377 std::ptrdiff_t _diff; 00378 }; 00379 00380 template <typename IC, typename C> 00381 inline void memunit_advance (planar_frame_iterator<IC, C>& p, 00382 std::ptrdiff_t diff) 00383 { 00384 static_transform (p, p, memunit_advance_fn<IC> (diff)); 00385 } 00386 00387 template <typename IC, typename C> 00388 inline planar_frame_iterator<IC,C> memunit_advanced ( 00389 const planar_frame_iterator<IC,C>& p, std::ptrdiff_t diff) 00390 { 00391 planar_frame_iterator<IC,C> ret = p; 00392 memunit_advance (ret, diff); 00393 return ret; 00394 } 00395 00396 template <typename SamplePtr, typename ChannelSpace> inline 00397 planar_frame_reference<typename std::iterator_traits<SamplePtr>::reference, 00398 ChannelSpace> 00399 memunit_advanced_ref (const planar_frame_iterator<SamplePtr, ChannelSpace>& ptr, 00400 std::ptrdiff_t diff) 00401 { 00402 return planar_frame_reference< 00403 typename std::iterator_traits<SamplePtr>::reference, 00404 ChannelSpace> (ptr, diff); 00405 } 00406 00407 00408 /* 00409 * 00410 * HasDynamicStepTypeConcept 00411 * 00412 */ 00413 00414 template <typename IC, typename C> 00415 struct dynamic_step_type<planar_frame_iterator<IC,C> > 00416 { 00417 typedef memory_based_step_iterator<planar_frame_iterator<IC,C> > type; 00418 }; 00419 00420 } /* namespace sound */ 00421 } /* namespace psynth */ 00422 00423 #endif /* PSYNTH_SOUND_PLANAR_FRAME_ITERATOR */
1.7.4