libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/planar_frame_reference.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_PLANAR_REF_H
00040 #define PSYNTH_SOUND_PLANAR_REF_H
00041 
00042 #include <boost/mpl/range_c.hpp>
00043 
00044 #include <psynth/base/compat.hpp>
00045 #include <psynth/sound/concept.hpp>
00046 #include <psynth/sound/channel_base.hpp>
00047 #include <psynth/sound/sample.hpp>
00048 #include <psynth/sound/frame.hpp>
00049 #include <psynth/sound/planar_frame_iterator.hpp>
00050 
00051 namespace psynth
00052 {
00053 namespace sound
00054 {
00055 
00082 template <typename SampleReference, typename ChannelSpace>
00083 // SampleReference is a sample reference (const or mutable)
00084 struct planar_frame_reference  : public detail::homogeneous_channel_base<
00085     SampleReference, layout<ChannelSpace>, boost::mpl::size<ChannelSpace>::value>
00086 {
00087     typedef detail::homogeneous_channel_base<
00088         SampleReference, layout<ChannelSpace>,
00089         boost::mpl::size<ChannelSpace>::value>
00090     parent_type;
00091     
00092 private:
00093     // These three are only defined for homogeneous frames
00094     typedef typename sample_traits<SampleReference>::value_type
00095     sample_type;
00096     typedef typename sample_traits<SampleReference>::const_reference
00097     sample_const_reference;
00098 
00099 public:
00100     BOOST_STATIC_CONSTANT(
00101         bool, is_mutable = sample_traits<SampleReference>::is_mutable);
00102 
00103     typedef frame <sample_type, layout<ChannelSpace> >  value_type;
00104     typedef planar_frame_reference                      reference;
00105     typedef planar_frame_reference<sample_const_reference, ChannelSpace>
00106     const_reference;
00107 
00108     planar_frame_reference (SampleReference v0, SampleReference v1)
00109         : parent_type (v0,v1) {}
00110 
00111     planar_frame_reference (SampleReference v0, SampleReference v1,
00112                             SampleReference v2)
00113         : parent_type (v0,v1,v2) {}
00114 
00115     planar_frame_reference (SampleReference v0, SampleReference v1,
00116                             SampleReference v2, SampleReference v3)
00117         : parent_type (v0,v1,v2,v3) {}
00118 
00119     planar_frame_reference (SampleReference v0, SampleReference v1,
00120                             SampleReference v2, SampleReference v3,
00121                             SampleReference v4)
00122         : parent_type (v0,v1,v2,v3,v4) {}
00123 
00124     planar_frame_reference (SampleReference v0, SampleReference v1,
00125                             SampleReference v2, SampleReference v3,
00126                             SampleReference v4, SampleReference v5)
00127         : parent_type (v0,v1,v2,v3,v4,v5) {}
00128 
00129     template <typename P>
00130     planar_frame_reference (const P& p)
00131         : parent_type(p)
00132     { check_compatible<P>(); }
00133 
00134     // PERFORMANCE_CHECK: Is this constructor necessary?
00135     template <typename SampleV, typename Mapping>           
00136     planar_frame_reference (frame<SampleV,layout<ChannelSpace,Mapping> >& p)
00137         : parent_type (p)
00138     { check_compatible<frame<SampleV,layout<ChannelSpace,Mapping> > >();}
00139 
00140     // Construct at offset from a given location
00141     template <typename SamplePtr>
00142     planar_frame_reference (
00143         const planar_frame_iterator<SamplePtr,ChannelSpace>& p,
00144         std::ptrdiff_t diff)
00145         : parent_type (p, diff) {}
00146 
00147     const planar_frame_reference&
00148     operator= (const planar_frame_reference& p) const
00149     {
00150         static_copy (p, *this);
00151         return *this;
00152     }
00153     
00154     template <typename P>
00155     const planar_frame_reference& operator= (const P& p) const
00156     {
00157         check_compatible<P>();
00158         static_copy (p,*this);
00159         return *this;
00160     }
00161     
00162     /*
00163       This overload is necessary for a compiler implementing Core
00164       Issue 574 to prevent generation of an implicit copy assignment
00165       operator (the reason for generating implicit copy assignment
00166       operator is that according to Core Issue 574, a cv-qualified
00167       assignment operator is not considered "copy assignment
00168       operator").  EDG implemented Core Issue 574 starting with EDG
00169       Version 3.8. I'm not sure why they did it for a template member
00170       function as well.
00171     */
00172     
00173 #if BOOST_WORKAROUND(__HP_aCC, >= 61700) || \
00174     BOOST_WORKAROUND(__INTEL_COMPILER, >= 1000)
00175 
00176     const planar_frame_reference& operator= (const planar_frame_reference& p)
00177     {
00178         static_copy (p, *this);
00179         return *this;
00180     }
00181     
00182     template <typename P>
00183     const planar_frame_reference& operator= (const P& p)
00184     {
00185         check_compatible<P>();
00186         static_copy (p, *this);
00187         return *this;
00188     }
00189 
00190 #endif /* BOOST_WORKAROUND */
00191 
00192     template <typename P>
00193     bool operator== (const P& p) const
00194     {
00195         check_compatible<P>();
00196         return static_equal (*this, p);
00197     }
00198     
00199     template <typename P>
00200     bool operator!= (const P& p) const
00201     {
00202         return !(*this == p);
00203     }
00204 
00205     SampleReference operator[] (std::size_t i) const
00206     {
00207         return this->at_c_dynamic (i);
00208     }
00209 
00210     const planar_frame_reference* operator->() const
00211     {
00212         return this;
00213     }
00214     
00215 private:
00216     template <typename Frame>
00217     static void check_compatible()
00218     {
00219         base::psynth_function_requires<FramesCompatibleConcept<
00220             Frame, planar_frame_reference> >();
00221     }
00222 };
00223 
00224 
00225 /*
00226  *
00227  *    ChannelBasedConcept
00228  *
00229  */
00230 
00231 template <typename SampleReference, typename ChannelSpace, int K>  
00232 struct kth_element_type<planar_frame_reference<SampleReference,ChannelSpace>, K>
00233 {
00234     typedef SampleReference type;
00235 };
00236 
00237 template <typename SampleReference, typename ChannelSpace, int K>  
00238 struct kth_element_reference_type<
00239     planar_frame_reference<SampleReference,ChannelSpace>, K>
00240 {
00241     typedef SampleReference type;
00242 };
00243 
00244 template <typename SampleReference, typename ChannelSpace, int K>  
00245 struct kth_element_const_reference_type<planar_frame_reference<
00246                                             SampleReference,ChannelSpace>, K> 
00247     : public boost::add_reference<
00248     typename boost::add_const<SampleReference>::type> 
00249 {
00250 //    typedef typename sample_traits<SampleReference>::const_reference type;
00251 };
00252 
00253 
00254 /*
00255  *
00256  *    FrameConcept
00257  *
00258  */
00259 
00265 template <typename SampleReference, typename ChannelSpace>  
00266 struct is_frame< planar_frame_reference<SampleReference,ChannelSpace> >
00267     : public boost::mpl::true_{};
00268 
00269 
00270 /*
00271  *
00272  *    HomogeneousFrameBasedConcept
00273  *
00274  */
00275 
00281 template <typename SampleReference, typename ChannelSpace>  
00282 struct channel_space_type<planar_frame_reference<SampleReference,ChannelSpace> >
00283 {
00284     typedef ChannelSpace type;
00285 }; 
00286 
00293 template <typename SampleReference, typename ChannelSpace>  
00294 struct sample_mapping_type<planar_frame_reference<SampleReference, ChannelSpace> >
00295 {
00296     typedef typename layout<ChannelSpace>::sample_mapping_t type;
00297 }; 
00298 
00299 
00306 template <typename SampleReference, typename ChannelSpace>  
00307 struct is_planar<planar_frame_reference<SampleReference,ChannelSpace> > :
00308     boost::mpl::true_ {};
00309 
00316 template <typename SampleReference, typename ChannelSpace>  
00317 struct sample_type<planar_frame_reference<SampleReference,ChannelSpace> >
00318 {
00319     typedef typename sample_traits<SampleReference>::value_type type;
00320 }; 
00321 
00322 } /* namespace sound  */
00323 } /* namespace psynth */
00324 
00325 namespace std
00326 {
00327 
00328 /*
00329   We are forced to define swap inside std namespace because on some
00330   platforms (Visual Studio 8) STL calls swap qualified.
00331   
00332   swap with 'left bias': 
00333   - swap between proxy and anything
00334   - swap between value type and proxy
00335   - swap between proxy and proxy
00336 
00337   Having three overloads allows us to swap between different (but
00338   compatible) models of FrameConcept
00339   
00340 */
00341 
00346 template <typename CR, typename CS, typename R> inline
00347 void swap (const psynth::sound::planar_frame_reference<CR,CS> x, R& y)
00348 { 
00349     psynth::sound::swap_proxy<
00350         typename psynth::sound::planar_frame_reference<CR,CS>::value_type> (x, y); 
00351 }
00352 
00357 template <typename CR, typename CS> inline
00358 void swap (typename psynth::sound::planar_frame_reference<CR,CS>::value_type& x,
00359            const psynth::sound::planar_frame_reference<CR,CS> y)
00360 { 
00361     psynth::sound::swap_proxy<
00362         typename psynth::sound::planar_frame_reference<CR,CS>::value_type> (x, y); 
00363 }
00364 
00365 
00370 template <typename CR, typename CS> inline
00371 void swap (const psynth::sound::planar_frame_reference<CR,CS> x,
00372            const psynth::sound::planar_frame_reference<CR,CS> y)
00373 { 
00374     psynth::sound::swap_proxy<
00375         typename psynth::sound::planar_frame_reference<CR,CS>::value_type>(x, y); 
00376 }
00377 
00378 } /* namespace std */
00379 
00380 #endif /* PSYNTH_SOUND_PLANAR_FRAME_REF */