00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef BITFLOAT_H
00020 #define BITFLOAT_H
00021
00022 #include <typeinfo>
00023 #include <stdexcept>
00024
00025 #include <bit/enums.h>
00026 #include <bit/utility.h>
00027 #include <bit/pointer.h>
00028 #include <bit/data.h>
00029
00030 namespace bit
00031 {
00032
00033 template <typename F> class Float;
00034
00035 class FloatingPoint
00036 {
00037 public:
00038
00039 typedef BitPointer<FloatingPoint> pointer;
00040
00041 FloatingPoint( ByteOrder bo=BYTEORDER_HOST ): byte_order(bo) { }
00042
00043 virtual ~FloatingPoint() { }
00044
00045 virtual Data as_data() const = 0;
00046
00047 virtual size_t size() const = 0;
00048
00049 virtual const void* voidptr() const = 0;
00050
00051 virtual pointer clone() const = 0;
00052
00058 virtual void set_value( const Data d ) = 0;
00059
00060 virtual void set_value( const void* mem, size_t size ) = 0;
00061
00067 virtual void set_value( const Data d, ByteOrder databo ) = 0;
00068
00069 template <typename T> operator T();
00070
00071 template <typename T> FloatingPoint& operator = ( T f );
00072
00073 virtual const std::type_info& int_type() = 0;
00074
00075 ByteOrder byte_order;
00076 };
00077
00078 template <typename F>
00079 class Float: public FloatingPoint {
00080 public:
00081
00082 typedef BitPointer< Float<F> > pointer;
00083
00084 Float(F v=0, ByteOrder bo=BYTEORDER_HOST): FloatingPoint(bo), value(v) { }
00085
00086 Float(ByteOrder bo): FloatingPoint(bo), value(0) { }
00087
00094 Float(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST): FloatingPoint(bo) {
00095 this->set_value(d, databo);
00096 }
00097
00098 static pointer create(F v=0, ByteOrder bo=BYTEORDER_HOST) { return pointer(new Float<F>(v,bo)); }
00099
00100 static pointer create(ByteOrder bo) { return pointer(new Float<F>(bo)); }
00101
00102 static pointer create(const Data d, ByteOrder databo=BYTEORDER_HOST, ByteOrder bo=BYTEORDER_HOST) {
00103 return pointer(new Float<F>(d,databo,bo));
00104 }
00105
00106 ~Float() { }
00107
00108 virtual FloatingPoint::pointer clone() const {
00109 pointer p = this->create(value, byte_order);
00110 return p;
00111 }
00112
00113 operator F() const { return this->host(); }
00114
00115 bool operator < ( F f ) const { return this->host() < f; }
00116 bool operator <= ( F f ) const { return this->host() <= f; }
00117 bool operator == ( F f ) const { return this->host() == f; }
00118 bool operator != ( F f ) const { return this->host() != f; }
00119 bool operator >= ( F f ) const { return this->host() >= f; }
00120 bool operator > ( F f ) const { return this->host() > f; }
00121
00122 Float<F>& operator = ( F f )
00123 {
00124 value = f;
00125 this->convert_value_from_host_to_type();
00126 return *this;
00127 }
00128
00129 Float<F> operator + ( F f ) const
00130 {
00131 this->convert_value_from_type_to_host();
00132 value += f;
00133 this->convert_value_from_host_to_type();
00134 return *this;
00135 }
00136
00137 Float<F> operator - ( F f ) const
00138 {
00139 this->convert_value_from_type_to_host();
00140 value -= f;
00141 this->convert_value_from_host_to_type();
00142 return *this;
00143 }
00144
00145 Float<F> operator * ( F f ) const
00146 {
00147 this->convert_value_from_type_to_host();
00148 value *= f;
00149 this->convert_value_from_host_to_type();
00150 return *this;
00151 }
00152
00153 Float<F> operator / ( F f ) const
00154 {
00155 this->convert_value_from_type_to_host();
00156 value /= f;
00157 this->convert_value_from_host_to_type();
00158 return *this;
00159 }
00160
00161 Float<F>& operator += ( F f )
00162 {
00163 this->convert_value_from_type_to_host();
00164 value += f;
00165 this->convert_value_from_host_to_type();
00166 return *this;
00167 }
00168
00169 Float<F>& operator -= ( F f )
00170 {
00171 this->convert_value_from_type_to_host();
00172 value -= f;
00173 this->convert_value_from_host_to_type();
00174 return *this;
00175 }
00176
00177 Float<F>& operator *= ( F f )
00178 {
00179 this->convert_value_from_type_to_host();
00180 value *= f;
00181 this->convert_value_from_host_to_type();
00182 return *this;
00183 }
00184
00185 Float<F>& operator /= ( F f )
00186 {
00187 this->convert_value_from_type_to_host();
00188 value /= f;
00189 this->convert_value_from_host_to_type();
00190 return *this;
00191 }
00192
00198 virtual void set_value( const Data d ) {
00199 if ( d.size() < sizeof(F) )
00200 throw;
00201
00202 memcpy( &value, d.data(), sizeof(F) );
00203 }
00204
00209 virtual void set_value( const void* mem, size_t size ) {
00210 if ( size < sizeof(F) )
00211 throw;
00212
00213 memcpy( &value, mem, sizeof(F) );
00214 }
00215
00221 virtual void set_value( const Data d, ByteOrder databo ) {
00222 if ( d.size() < sizeof(F) )
00223 throw;
00224
00225 memcpy( &value, d.data(), sizeof(F) );
00226
00227 switch ( byte_order ) {
00228 case BYTEORDER_HOST:
00229 switch ( databo ) {
00230 case BYTEORDER_HOST:
00231 break;
00232 case BYTEORDER_NETWORK:
00233 case BYTEORDER_BIG_ENDIAN:
00234 value = be_to_host(value);
00235 break;
00236 case BYTEORDER_LITTLE_ENDIAN:
00237 value = le_to_host(value);
00238 break;
00239 }
00240 break;
00241 case BYTEORDER_NETWORK:
00242 case BYTEORDER_BIG_ENDIAN:
00243 switch ( databo ) {
00244 case BYTEORDER_HOST:
00245 value = host_to_net(value);
00246 break;
00247 case BYTEORDER_NETWORK:
00248 case BYTEORDER_BIG_ENDIAN:
00249 break;
00250 case BYTEORDER_LITTLE_ENDIAN:
00251 value = le_to_net(value);
00252 break;
00253 }
00254 break;
00255 case BYTEORDER_LITTLE_ENDIAN:
00256 switch ( databo ) {
00257 case BYTEORDER_HOST:
00258 value = host_to_le(value);
00259 break;
00260 case BYTEORDER_NETWORK:
00261 case BYTEORDER_BIG_ENDIAN:
00262 value = net_to_le(value);
00263 break;
00264 case BYTEORDER_LITTLE_ENDIAN:
00265 break;
00266 }
00267 break;
00268 }
00269 }
00270
00271 virtual Data as_data() const
00272 {
00273 Data d( sizeof(F) );
00274 memcpy( d.data(), &value, sizeof(F) );
00275 return d;
00276 }
00277
00278 virtual size_t size() const { return sizeof(F); }
00279
00280 virtual const void* voidptr() const { return &value; }
00281
00282 virtual const std::type_info& int_type() { return typeid(F); }
00283
00284 F host() const {
00285 switch ( byte_order )
00286 {
00287 case BYTEORDER_HOST:
00288 return value;
00289 case BYTEORDER_NETWORK:
00290 case BYTEORDER_BIG_ENDIAN:
00291 return net_to_host(value);
00292 case BYTEORDER_LITTLE_ENDIAN:
00293 return le_to_host(value);
00294 }
00295 throw;
00296 }
00297
00298 F network() const {
00299 switch ( byte_order )
00300 {
00301 case BYTEORDER_HOST:
00302 return host_to_net(value);
00303 case BYTEORDER_NETWORK:
00304 case BYTEORDER_BIG_ENDIAN:
00305 return value;
00306 case BYTEORDER_LITTLE_ENDIAN:
00307 return le_to_net(value);
00308 }
00309 throw;
00310 }
00311
00312 F big_endian() const {
00313 return this->network();
00314 }
00315
00316 F little_endian() const {
00317 switch ( byte_order )
00318 {
00319 case BYTEORDER_HOST:
00320 return host_to_le(value);
00321 case BYTEORDER_NETWORK:
00322 case BYTEORDER_BIG_ENDIAN:
00323 return net_to_le(value);
00324 case BYTEORDER_LITTLE_ENDIAN:
00325 return value;
00326 }
00327 throw;
00328 }
00329
00330 F value;
00331
00332 protected:
00333 void convert_value_from_type_to_host()
00334 {
00335 switch ( byte_order )
00336 {
00337 case BYTEORDER_HOST:
00338 return;
00339 case BYTEORDER_NETWORK:
00340 case BYTEORDER_BIG_ENDIAN:
00341 value = net_to_host(value);
00342 case BYTEORDER_LITTLE_ENDIAN:
00343 value = le_to_host(value);
00344 }
00345 }
00346
00347 void convert_value_from_host_to_type()
00348 {
00349 switch ( byte_order )
00350 {
00351 case BYTEORDER_HOST:
00352 return;
00353 case BYTEORDER_NETWORK:
00354 case BYTEORDER_BIG_ENDIAN:
00355 value = host_to_net(value);
00356 case BYTEORDER_LITTLE_ENDIAN:
00357 value = host_to_le(value);
00358 }
00359 }
00360
00361 };
00362
00363 typedef Float<float> FloatSingle;
00364 typedef Float<double> FloatDouble;
00365 typedef Float<long double> FloatQuadruple;
00366
00367 template <typename T> FloatingPoint::operator T()
00368 {
00369 switch ( this->size() )
00370 {
00371 case 4:
00372 {
00373 FloatSingle* f;
00374 f = dynamic_cast<FloatSingle*>(this);
00375 return static_cast<T>(f->host());
00376 }
00377 case 8:
00378 {
00379 FloatDouble* f;
00380 f = dynamic_cast<FloatDouble*>(this);
00381 return static_cast<T>(f->host());
00382 }
00383 case 16:
00384 {
00385 FloatQuadruple* f;
00386 f = dynamic_cast<FloatQuadruple*>(this);
00387 return static_cast<T>(f->host());
00388 }
00389 }
00390 throw std::logic_error("bit::FloatingPoint bad cast");
00391 }
00392
00393 template <typename T> FloatingPoint& FloatingPoint::operator = ( T i )
00394 {
00395 switch ( this->size() )
00396 {
00397 case 4:
00398 {
00399 FloatSingle* f;
00400 f = dynamic_cast<FloatSingle*>(this);
00401 *f = (float)(i);
00402 }
00403 break;
00404 case 8:
00405 {
00406 FloatDouble* f;
00407 f = dynamic_cast<FloatDouble*>(this);
00408 *f = (double)(i);
00409 }
00410 break;
00411 case 16:
00412 {
00413 FloatQuadruple* f;
00414 f = dynamic_cast<FloatQuadruple*>(this);
00415 *f = (long double)(i);
00416 }
00417 break;
00418 }
00419 return *this;
00420 }
00421
00422 }
00423
00424 #endif