ISIS Core Library 0.7.2 (api 3.0.0)
|
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