ISIS Core Library 0.7.2 (api 3.0.0)
|
00001 // 00002 // C++ Interface: type_base 00003 // 00004 // Description: 00005 // 00006 // 00007 // Author: Enrico Reimer<reimer@cbs.mpg.de>, (C) 2009 00008 // 00009 // Copyright: See COPYING file that comes with this distribution 00010 // 00011 // 00012 00013 #ifndef ISISTYPE_BASE_HPP 00014 #define ISISTYPE_BASE_HPP 00015 00016 #include <boost/shared_ptr.hpp> 00017 #include <boost/scoped_ptr.hpp> 00018 #include <boost/lexical_cast.hpp> 00019 00020 #include "types.hpp" 00021 #include "value_converter.hpp" 00022 #include "generic_value.hpp" 00023 #include "common.hpp" 00024 00025 00026 namespace isis 00027 { 00028 namespace util 00029 { 00030 API_EXCLUDE_BEGIN 00032 namespace _internal 00033 { 00034 template<typename TYPE> struct __cast_to { 00035 template<typename SOURCE> TYPE operator()( Value<TYPE>*, const SOURCE &value ) { 00036 return boost::lexical_cast<TYPE>( value ); //generic version types are different - so do lexical cast 00037 } 00038 TYPE operator()( Value<TYPE>*, const TYPE &value ) { 00039 return value; //special version types are same - so just return the value 00040 } 00041 }; 00042 template<> struct __cast_to<uint8_t> { // we cannot lexical_cast to uint8_t - we'll get "characters" (1 => '1' == 49) 00043 template<typename SOURCE> uint8_t operator()( Value<uint8_t>*, const SOURCE &value ) { 00044 // lexical cast to unsigned short 00045 const unsigned short val = boost::lexical_cast<unsigned short>( value ); 00046 00047 // have to check by hand because the lexical cast will only check against unsigned short 00048 if( val > std::numeric_limits<uint8_t>::max() ) { 00049 throw boost::bad_lexical_cast( typeid( SOURCE ), typeid( uint8_t ) ); 00050 } 00051 00052 // and then static_cast to uint8_t 00053 return static_cast<uint8_t>( val ); 00054 } 00055 uint8_t operator()( Value<uint8_t> *, const uint8_t &value ) { 00056 return value; //special version types are same - so just return the value 00057 } 00058 }; 00059 } 00061 API_EXCLUDE_END 00062 00063 /* 00064 * This is the mostly abstract base class for all scalar values (see types.hpp). 00065 * Additionally, there's the ValueArrayBase containing the more complex data handling stuff with abstract values. 00066 * Both are derived from GenericValue containing the description of the actual value type. 00067 */ 00068 00069 class ValueBase : public _internal::GenericValue 00070 { 00071 static const _internal::ValueConverterMap &converters(); 00072 friend class _internal::GenericReference<ValueBase>; 00073 protected: 00080 virtual ValueBase *clone()const = 0; 00081 public: 00082 typedef _internal::GenericReference<ValueBase> Reference; 00083 typedef _internal::ValueConverterMap::mapped_type::mapped_type Converter; 00084 00086 template<typename T> bool is()const; 00087 00088 const Converter &getConverterTo( unsigned short ID )const; 00089 00098 static bool convert( const ValueBase &from, ValueBase &to ); 00099 00114 template<class T> T as()const { 00115 if( is<T>() ) 00116 return castTo<T>(); 00117 00118 Reference ret = copyByID( Value<T>::staticID ); 00119 00120 if ( ret.isEmpty() ) { 00121 LOG( Debug, error ) 00122 << "Interpretation of " << toString( true ) << " as " << Value<T>::staticName() 00123 << " failed. Returning " << Value<T>().toString() << "."; 00124 return T(); 00125 } else 00126 return ret->castTo<T>(); 00127 } 00128 00135 template<typename T> const Value<T>& castToType() const; 00136 00143 template<typename T> const T &castTo() const; 00144 00151 template<typename T> Value<T>& castToType(); 00152 00159 template<typename T> T &castTo(); 00160 00162 virtual bool operator==( const ValueBase &second )const = 0; 00163 00165 Reference copyByID( unsigned short ID ) const; 00166 00171 bool fitsInto( unsigned short ID ) const; 00172 00173 virtual ~ValueBase(); 00174 00175 virtual bool gt( const ValueBase &ref )const = 0; 00176 virtual bool lt( const ValueBase &ref )const = 0; 00177 virtual bool eq( const ValueBase &ref )const = 0; 00178 }; 00179 00180 00181 typedef ValueBase::Reference ValueReference; 00182 00183 } 00184 } 00185 00186 namespace std 00187 { 00189 template<typename charT, typename traits> basic_ostream<charT, traits>& 00190 operator<<( basic_ostream<charT, traits> &out, const isis::util::_internal::GenericValue &s ) 00191 { 00192 return out << s.toString(); 00193 } 00195 template<typename charT, typename traits, typename TYPE_TYPE> basic_ostream<charT, traits>& 00196 operator<<( basic_ostream<charT, traits> &out, const isis::util::_internal::GenericReference<TYPE_TYPE> &s ) 00197 { 00198 return out << s.toString( true ); 00199 } 00200 } 00201 00202 #endif //ISISTYPE_BASE_HPP