ISIS Core Library 0.7.2 (api 3.0.0)

/scr/tee1/isis/lib/Core/DataStorage/valuearray_base.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2010  reimer@cbs.mpg.de
00003 
00004     This program is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 */
00018 
00019 #ifndef TYPEPTRBASE_HPP
00020 #define TYPEPTRBASE_HPP
00021 
00022 #include "../CoreUtils/value_base.hpp"
00023 #include "valuearray_converter.hpp"
00024 #include "common.hpp"
00025 #include <boost/mpl/if.hpp>
00026 #include <boost/utility/enable_if.hpp>
00027 
00028 namespace isis
00029 {
00030 namespace data
00031 {
00033 namespace _internal
00034 {
00035 class ConstValueAdapter: public util::ValueReference
00036 {
00037 public:
00038     typedef const util::ValueReference ( *Getter )( const void * );
00039     typedef void ( *Setter )( void *, const util::ValueBase & );
00040 protected:
00041     const uint8_t *const p;
00042 public:
00043     ConstValueAdapter( const uint8_t *const _p, Getter _getValueFunc );
00044     // to make some algorithms work
00045     bool operator==( const util::ValueReference &val )const;
00046     bool operator!=( const util::ValueReference &val )const;
00047 
00048     bool operator<( const util::ValueReference &val )const;
00049     bool operator>( const util::ValueReference &val )const;
00050 };
00051 class WritingValueAdapter: public ConstValueAdapter
00052 {
00053     Setter setValueFunc;
00054 public:
00055     WritingValueAdapter( uint8_t *const _p, Getter _getValueFunc, Setter _setValueFunc );
00056     WritingValueAdapter operator=( const util::ValueReference &val );
00057 };
00058 
00059 template<bool IS_CONST> class GenericValueIterator :
00060     public std::iterator < std::random_access_iterator_tag,
00061     typename boost::mpl::if_c<IS_CONST, ConstValueAdapter, WritingValueAdapter>::type,
00062     ptrdiff_t,
00063     typename boost::mpl::if_c<IS_CONST, ConstValueAdapter, WritingValueAdapter>::type,
00064     typename boost::mpl::if_c<IS_CONST, ConstValueAdapter, WritingValueAdapter>::type
00065     >
00066 {
00067     typedef typename boost::mpl::if_c<IS_CONST, const uint8_t *, uint8_t *>::type ptr_type;
00068     ptr_type p, start; //we need the starting position for operator[]
00069     size_t byteSize;
00070     ConstValueAdapter::Getter getValueFunc;
00071     ConstValueAdapter::Setter setValueFunc;
00072     friend class GenericValueIterator<true>; //yes, I'm my own friend, sometimes :-) (enables the constructor below)
00073 public:
00074     GenericValueIterator( const GenericValueIterator<false> &src ): //will become additional constructor from non const if this is const, otherwise overrride the default copy contructor
00075         p( src.p ), start( src.p ), byteSize( src.byteSize ), getValueFunc( src.getValueFunc ), setValueFunc( src.setValueFunc ) {}
00076     GenericValueIterator(): p( NULL ), start( p ), byteSize( 0 ), getValueFunc( NULL ), setValueFunc( NULL ) {}
00077     GenericValueIterator( ptr_type _p, ptr_type _start, size_t _byteSize, ConstValueAdapter::Getter _getValueFunc, ConstValueAdapter::Setter _setValueFunc ):
00078         p( _p ), start( _start ), byteSize( _byteSize ), getValueFunc( _getValueFunc ), setValueFunc( _setValueFunc )
00079     {}
00080 
00081     GenericValueIterator<IS_CONST>& operator++() {p += byteSize; return *this;}
00082     GenericValueIterator<IS_CONST>& operator--() {p -= byteSize; return *this;}
00083 
00084     GenericValueIterator<IS_CONST> operator++( int ) {GenericValueIterator<IS_CONST> tmp = *this; ++*this; return tmp;}
00085     GenericValueIterator<IS_CONST> operator--( int ) {GenericValueIterator<IS_CONST> tmp = *this; --*this; return tmp;}
00086 
00087     typename GenericValueIterator<IS_CONST>::reference operator*() const;
00088     typename GenericValueIterator<IS_CONST>::pointer  operator->() const {return operator*();}
00089 
00090     bool operator==( const GenericValueIterator<IS_CONST>& cmp )const {return p == cmp.p;}
00091     bool operator!=( const GenericValueIterator<IS_CONST>& cmp )const {return !( *this == cmp );}
00092 
00093     bool operator>( const GenericValueIterator<IS_CONST> &cmp )const {return p > cmp.p;}
00094     bool operator<( const GenericValueIterator<IS_CONST> &cmp )const {return p < cmp.p;}
00095 
00096     bool operator>=( const GenericValueIterator<IS_CONST> &cmp )const {return p >= cmp.p;}
00097     bool operator<=( const GenericValueIterator<IS_CONST> &cmp )const {return p <= cmp.p;}
00098 
00099     typename GenericValueIterator<IS_CONST>::difference_type operator-( const GenericValueIterator<IS_CONST> &cmp )const {return ( p - cmp.p ) / byteSize;}
00100 
00101     GenericValueIterator<IS_CONST> operator+( typename GenericValueIterator<IS_CONST>::difference_type n )const
00102     {return ( GenericValueIterator<IS_CONST>( *this ) += n );}
00103     GenericValueIterator<IS_CONST> operator-( typename GenericValueIterator<IS_CONST>::difference_type n )const
00104     {return ( GenericValueIterator<IS_CONST>( *this ) -= n );}
00105 
00106 
00107     GenericValueIterator<IS_CONST> &operator+=( typename GenericValueIterator<IS_CONST>::difference_type n )
00108     {p += ( n * byteSize ); return *this;}
00109     GenericValueIterator<IS_CONST> &operator-=( typename GenericValueIterator<IS_CONST>::difference_type n )
00110     {p -= ( n * byteSize ); return *this;}
00111 
00112     typename GenericValueIterator<IS_CONST>::reference operator[]( typename GenericValueIterator<IS_CONST>::difference_type n )const {
00113         //the book says it has to be the n-th elements of the whole object, so we have to start from what is hopefully the beginning
00114         return *( GenericValueIterator<IS_CONST>( start, start, byteSize, getValueFunc, setValueFunc ) += n );
00115     }
00116 
00117 };
00118 //specialise the dereferencing operators. They have to return (and create) different objects with different constructors
00119 template<> GenericValueIterator<true>::reference GenericValueIterator<true>::operator*() const;
00120 template<> GenericValueIterator<false>::reference GenericValueIterator<false>::operator*() const;
00121 
00122 } //namespace _internal
00124 
00125 class ValueArrayBase : public util::_internal::GenericValue
00126 {
00127     friend class util::_internal::GenericReference<ValueArrayBase>;
00128     static const _internal::ValueArrayConverterMap &converters();
00129     scaling_pair getScaling( const scaling_pair &scale, unsigned short ID )const;
00130 protected:
00131     size_t m_len;
00132     ValueArrayBase( size_t len = 0 );
00133 
00135     virtual ValueArrayBase *clone()const = 0;
00136 
00137 public:
00138     typedef _internal::GenericValueIterator<false> value_iterator;
00139     typedef _internal::GenericValueIterator<true> const_value_iterator;
00140     typedef value_iterator value_reference;
00141     typedef const_value_iterator const_value_reference;
00143     class DelProxy : public boost::shared_ptr<const void>
00144     {
00145     public:
00151         DelProxy( const ValueArrayBase &master );
00153         void operator()( const void *at );
00154     };
00155 
00163     virtual boost::shared_ptr<const void> getRawAddress( size_t offset = 0 )const = 0;
00164 
00166     virtual boost::shared_ptr<void> getRawAddress( size_t offset = 0 ) = 0;
00167 
00168     virtual value_iterator beginGeneric() = 0;
00169     value_iterator endGeneric();
00170     virtual const_value_iterator beginGeneric()const = 0;
00171     const_value_iterator endGeneric()const;
00172 
00173     typedef util::_internal::GenericReference<ValueArrayBase> Reference;
00174     typedef _internal::ValueArrayConverterMap::mapped_type::mapped_type Converter;
00175 
00176     template<typename T> bool is()const;
00177 
00178     const Converter &getConverterTo( unsigned short ID )const;
00179 
00185     template<typename T> const ValueArray<T>& castToValueArray() const {
00186         return m_cast_to<ValueArray<T> >();
00187     }
00188 
00194     template<typename T> ValueArray<T>& castToValueArray() {
00195         return m_cast_to<ValueArray<T> >();
00196     }
00197 
00199     size_t getLength()const;
00200 
00209     virtual std::vector<Reference> splice( size_t size )const = 0;
00210 
00212     virtual scaling_pair getScalingTo( unsigned short typeID, autoscaleOption scaleopt = autoscale )const = 0;
00213     virtual scaling_pair getScalingTo( unsigned short typeID, const std::pair<util::ValueReference, util::ValueReference> &minmax, autoscaleOption scaleopt = autoscale )const;
00214 
00221     Reference copyByID( unsigned short ID = 0, scaling_pair scaling = scaling_pair() ) const;
00222 
00233     bool copyTo( isis::data::ValueArrayBase &dst, scaling_pair scaling = scaling_pair() )const;
00234 
00245     template<typename T> bool copyToMem( T *dst, size_t len, scaling_pair scaling = scaling_pair() )const {
00246         ValueArray<T> cont( dst, len, typename ValueArray<T>::NonDeleter() );
00247         return copyTo( cont, scaling );
00248     }
00249 
00260     template<typename T> bool copyFromMem( const T *const src, size_t len, scaling_pair scaling = scaling_pair() ) {
00261         ValueArray<T> cont( const_cast<T *>( src ), len, typename ValueArray<T>::NonDeleter() ); //its ok - we're no going to change it
00262         return cont.copyTo( *this, scaling );
00263     }
00264 
00270     static Reference createByID( unsigned short ID, size_t len );
00271 
00279     template<typename T> ValueArray<T> copyAs( scaling_pair scaling = scaling_pair() )const {
00280         Reference erg = copyByID( ValueArray<T>::staticID, scaling );
00281         return erg.isEmpty() ? ValueArray<T>( 0 ) : erg->castToValueArray<T>();
00282     }
00283 
00296     ValueArrayBase::Reference  convertByID( unsigned short ID, scaling_pair scaling = scaling_pair() );
00297 
00298 
00310     template<typename T> ValueArray<T> as( scaling_pair scaling = scaling_pair() ) {
00311         Reference erg = convertByID( ValueArray<T>::staticID, scaling );
00312         return erg.isEmpty() ? ValueArray<T>( 0 ) : erg->castToValueArray<T>();
00313     }
00314 
00320     ValueArrayBase::Reference cloneToNew( size_t length )const;
00321 
00323     virtual size_t bytesPerElem()const = 0;
00324 
00325     virtual ~ValueArrayBase();
00326 
00334     void copyRange( size_t start, size_t end, ValueArrayBase &dst, size_t dst_start )const;
00335 
00337     size_t useCount()const;
00338 
00355     virtual std::pair<util::ValueReference, util::ValueReference> getMinMax()const = 0;
00356 
00368     size_t compare( size_t start, size_t end, const ValueArrayBase &dst, size_t dst_start )const;
00369     
00370     virtual void endianSwap()=0;
00371 };
00372 
00373 
00374 typedef ValueArrayBase::Reference ValueArrayReference;
00375 
00376 }
00377 }
00378 
00379 #endif // TYPEPTRBASE_HPP