summaryrefslogtreecommitdiff
path: root/boost/spirit/home/support/detail/math/detail/fp_traits.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/support/detail/math/detail/fp_traits.hpp')
-rw-r--r--boost/spirit/home/support/detail/math/detail/fp_traits.hpp583
1 files changed, 0 insertions, 583 deletions
diff --git a/boost/spirit/home/support/detail/math/detail/fp_traits.hpp b/boost/spirit/home/support/detail/math/detail/fp_traits.hpp
deleted file mode 100644
index 199712a3b9..0000000000
--- a/boost/spirit/home/support/detail/math/detail/fp_traits.hpp
+++ /dev/null
@@ -1,583 +0,0 @@
-// fp_traits.hpp
-
-#ifndef BOOST_SPIRIT_MATH_FP_TRAITS_HPP
-#define BOOST_SPIRIT_MATH_FP_TRAITS_HPP
-
-// Copyright (c) 2006 Johan Rade
-
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt
-// or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT
-# error The VAX floating point mode on VMS is not supported.
-#endif
-
-#if defined(_MSC_VER)
-#pragma once
-#endif
-
-#include <cstring>
-
-#include <boost/assert.hpp>
-#include <boost/cstdint.hpp>
-#include <boost/detail/endian.hpp>
-#include <boost/static_assert.hpp>
-#include <boost/type_traits/is_floating_point.hpp>
-
-//------------------------------------------------------------------------------
-
-namespace boost {
-namespace spirit {
-namespace math {
-namespace detail {
-
-//------------------------------------------------------------------------------
-
-/*
-Most processors support three different floating point precisions:
-single precision (32 bits), double precision (64 bits)
-and extended double precision (>64 bits)
-
-Note that the C++ type long double can be implemented
-both as double precision and extended double precision.
-*/
-
-struct single_precision_tag {};
-struct double_precision_tag {};
-struct extended_double_precision_tag {};
-
-//------------------------------------------------------------------------------
-
-/*
-template<class T, class U> struct fp_traits_impl;
-
- This is traits class that describes the binary structure of floating
- point numbers of C++ type T and precision U
-
-Requirements:
-
- T = float, double or long double
- U = single_precision_tag, double_precision_tag
- or extended_double_precision_tag
-
-Typedef members:
-
- bits -- the target type when copying the leading bytes of a floating
- point number. It is a typedef for uint32_t or uint64_t.
-
- coverage -- tells us whether all bytes are copied or not.
- It is a typedef for all_bits or not_all_bits.
-
-Static data members:
-
- sign, exponent, flag, mantissa -- bit masks that give the meaning of the bits
- in the leading bytes.
-
-Static function members:
-
- init() -- initializes the static data members, if needed.
- (Is a no-op in the specialized versions of the template.)
-
- get_bits(), set_bits() -- provide access to the leading bytes.
-*/
-
-struct all_bits {};
-struct not_all_bits {};
-
-// Generic version -------------------------------------------------------------
-
-// The generic version uses run time initialization to determine the floating
-// point format. It is capable of handling most formats,
-// but not the Motorola 68K extended double precision format.
-
-// Currently the generic version is used only for extended double precision
-// on Itanium. In all other cases there are specializations of the template
-// that use compile time initialization.
-
-template<class T> struct uint32_t_coverage
-{
- typedef not_all_bits type;
-};
-
-template<> struct uint32_t_coverage<single_precision_tag>
-{
- typedef all_bits type;
-};
-
-template<class T, class U> struct fp_traits_impl
-{
- typedef uint32_t bits;
- typedef BOOST_DEDUCED_TYPENAME uint32_t_coverage<U>::type coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- static uint32_t exponent;
- static uint32_t flag;
- static uint32_t mantissa;
-
- static void init()
- {
- if(is_init_) return;
- do_init_();
- is_init_ = true;
- }
-
- static void get_bits(T x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
- }
-
- static void set_bits(T& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
- }
-
-private:
- static size_t offset_;
- static bool is_init_;
- static void do_init_();
-};
-
-//..............................................................................
-
-template<class T, class U> uint32_t fp_traits_impl<T,U>::exponent;
-template<class T, class U> uint32_t fp_traits_impl<T,U>::flag;
-template<class T, class U> uint32_t fp_traits_impl<T,U>::mantissa;
-template<class T, class U> size_t fp_traits_impl<T,U>::offset_;
-template<class T, class U> bool fp_traits_impl<T,U>::is_init_;
-
-// In a single-threaded program, do_init will be called exactly once.
-// In a multi-threaded program, do_init may be called simultaneously
-// by more then one thread. That should not be a problem.
-
-//..............................................................................
-
-template<class T, class U> void fp_traits_impl<T,U>::do_init_()
-{
- T x = static_cast<T>(3) / static_cast<T>(4);
- // sign bit = 0
- // exponent: first and last bit = 0, all other bits = 1
- // flag bit (if present) = 1
- // mantissa: first bit = 1, all other bits = 0
-
- uint32_t a;
-
- for(size_t k = 0; k <= sizeof(T) - 4; ++k) {
-
- memcpy(&a, reinterpret_cast<unsigned char*>(&x) + k, 4);
-
- switch(a) {
-
- case 0x3f400000: // IEEE single precision format
-
- offset_ = k;
- exponent = 0x7f800000;
- flag = 0x00000000;
- mantissa = 0x007fffff;
- return;
-
- case 0x3fe80000: // IEEE double precision format
- // and PowerPC extended double precision format
- offset_ = k;
- exponent = 0x7ff00000;
- flag = 0x00000000;
- mantissa = 0x000fffff;
- return;
-
- case 0x3ffe0000: // Motorola extended double precision format
-
- // Must not get here. Must be handled by specialization.
- // To get accurate cutoff between normals and subnormals
- // we must use the flag bit that is in the 5th byte.
- // Otherwise this cutoff will be off by a factor 2.
- // If we do get here, then we have failed to detect the Motorola
- // processor at compile time.
-
- BOOST_ASSERT(false &&
- "Failed to detect the Motorola processor at compile time");
- return;
-
- case 0x3ffe8000: // IEEE extended double precision format
- // with 15 exponent bits
- offset_ = k;
- exponent = 0x7fff0000;
- flag = 0x00000000;
- mantissa = 0x0000ffff;
- return;
-
- case 0x3ffec000: // Intel extended double precision format
-
- offset_ = k;
- exponent = 0x7fff0000;
- flag = 0x00008000;
- mantissa = 0x00007fff;
- return;
-
- default:
- continue;
- }
- }
-
- BOOST_ASSERT(false);
-
- // Unknown format.
-}
-
-
-// float (32 bits) -------------------------------------------------------------
-
-template<> struct fp_traits_impl<float, single_precision_tag>
-{
- typedef uint32_t bits;
- typedef all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7f800000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x007fffff);
-
- static void init() {}
- static void get_bits(float x, uint32_t& a) { memcpy(&a, &x, 4); }
- static void set_bits(float& x, uint32_t a) { memcpy(&x, &a, 4); }
-};
-
-
-// double (64 bits) ------------------------------------------------------------
-
-#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
-
-template<> struct fp_traits_impl<double, double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
-
- static void init() {}
-
- static void get_bits(double x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
- }
-
- static void set_bits(double& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
- }
-
-private:
-
-#if defined(BOOST_BIG_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 0);
-#elif defined(BOOST_LITTLE_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 4);
-#else
- BOOST_STATIC_ASSERT(false);
-#endif
-};
-
-//..............................................................................
-
-#else
-
-template<> struct fp_traits_impl<double, double_precision_tag>
-{
- typedef uint64_t bits;
- typedef all_bits coverage;
-
- static const uint64_t sign = (uint64_t)0x80000000 << 32;
- static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
- static const uint64_t flag = 0;
- static const uint64_t mantissa
- = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
-
- static void init() {}
- static void get_bits(double x, uint64_t& a) { memcpy(&a, &x, 8); }
- static void set_bits(double& x, uint64_t a) { memcpy(&x, &a, 8); }
-};
-
-#endif
-
-
-// long double (64 bits) -------------------------------------------------------
-
-#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
-
-template<> struct fp_traits_impl<long double, double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
-
- static void init() {}
-
- static void get_bits(long double x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
- }
-
- static void set_bits(long double& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
- }
-
-private:
-
-#if defined(BOOST_BIG_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 0);
-#elif defined(BOOST_LITTLE_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 4);
-#else
- BOOST_STATIC_ASSERT(false);
-#endif
-};
-
-//..............................................................................
-
-#else
-
-template<> struct fp_traits_impl<long double, double_precision_tag>
-{
- typedef uint64_t bits;
- typedef all_bits coverage;
-
- static const uint64_t sign = (uint64_t)0x80000000 << 32;
- static const uint64_t exponent = (uint64_t)0x7ff00000 << 32;
- static const uint64_t flag = 0;
- static const uint64_t mantissa
- = ((uint64_t)0x000fffff << 32) + (uint64_t)0xffffffff;
-
- static void init() {}
- static void get_bits(long double x, uint64_t& a) { memcpy(&a, &x, 8); }
- static void set_bits(long double& x, uint64_t a) { memcpy(&x, &a, 8); }
-};
-
-#endif
-
-
-// long double (>64 bits), x86 and x64 -----------------------------------------
-
-#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
- || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
- || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
-
-// Intel extended double precision format (80 bits)
-
-template<> struct fp_traits_impl<long double, extended_double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
-
- static void init() {}
-
- static void get_bits(long double x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + 6, 4);
- }
-
- static void set_bits(long double& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + 6, &a, 4);
- }
-};
-
-
-// long double (>64 bits), Itanium ---------------------------------------------
-
-#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
-
-// The floating point format is unknown at compile time
-// No template specialization is provided.
-// The generic definition is used.
-
-// The Itanium supports both
-// the Intel extended double precision format (80 bits) and
-// the IEEE extended double precision format with 15 exponent bits (128 bits).
-
-
-// long double (>64 bits), PowerPC ---------------------------------------------
-
-#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
- || defined(__ppc) || defined(__ppc__) || defined(__PPC__)
-
-// PowerPC extended double precision format (128 bits)
-
-template<> struct fp_traits_impl<long double, extended_double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7ff00000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x000fffff);
-
- static void init() {}
-
- static void get_bits(long double x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
- }
-
- static void set_bits(long double& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
- }
-
-private:
-
-#if defined(BOOST_BIG_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 0);
-#elif defined(BOOST_LITTLE_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 12);
-#else
- BOOST_STATIC_ASSERT(false);
-#endif
-};
-
-
-// long double (>64 bits), Motorola 68K ----------------------------------------
-
-#elif defined(__m68k) || defined(__m68k__) \
- || defined(__mc68000) || defined(__mc68000__) \
-
-// Motorola extended double precision format (96 bits)
-
-// It is the same format as the Intel extended double precision format,
-// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and
-// 3) the flag bit is not set for infinity
-
-template<> struct fp_traits_impl<long double, extended_double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00008000);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x00007fff);
-
- static void init() {}
-
- // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding.
-
- static void get_bits(long double x, uint32_t& a)
- {
- memcpy(&a, &x, 2);
- memcpy(reinterpret_cast<unsigned char*>(&a) + 2,
- reinterpret_cast<const unsigned char*>(&x) + 4, 2);
- }
-
- static void set_bits(long double& x, uint32_t a)
- {
- memcpy(&x, &a, 2);
- memcpy(reinterpret_cast<unsigned char*>(&x) + 4,
- reinterpret_cast<const unsigned char*>(&a) + 2, 2);
- }
-};
-
-
-// long double (>64 bits), All other processors --------------------------------
-
-#else
-
-// IEEE extended double precision format with 15 exponent bits (128 bits)
-
-template<> struct fp_traits_impl<long double, extended_double_precision_tag>
-{
- typedef uint32_t bits;
- typedef not_all_bits coverage;
-
- BOOST_STATIC_CONSTANT(uint32_t, sign = 0x80000000);
- BOOST_STATIC_CONSTANT(uint32_t, exponent = 0x7fff0000);
- BOOST_STATIC_CONSTANT(uint32_t, flag = 0x00000000);
- BOOST_STATIC_CONSTANT(uint32_t, mantissa = 0x0000ffff);
-
- static void init() {}
-
- static void get_bits(long double x, uint32_t& a)
- {
- memcpy(&a, reinterpret_cast<const unsigned char*>(&x) + offset_, 4);
- }
-
- static void set_bits(long double& x, uint32_t a)
- {
- memcpy(reinterpret_cast<unsigned char*>(&x) + offset_, &a, 4);
- }
-
-private:
-
-#if defined(BOOST_BIG_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 0);
-#elif defined(BOOST_LITTLE_ENDIAN)
- BOOST_STATIC_CONSTANT(int, offset_ = 12);
-#else
- BOOST_STATIC_ASSERT(false);
-#endif
-};
-
-#endif
-
-
-//------------------------------------------------------------------------------
-
-// size_to_precision is a type switch for converting a C++ floating point type
-// to the corresponding precision type.
-
-template<int n> struct size_to_precision;
-
-template<> struct size_to_precision<4>
-{
- typedef single_precision_tag type;
-};
-
-template<> struct size_to_precision<8>
-{
- typedef double_precision_tag type;
-};
-
-template<> struct size_to_precision<10>
-{
- typedef extended_double_precision_tag type;
-};
-
-template<> struct size_to_precision<12>
-{
- typedef extended_double_precision_tag type;
-};
-
-template<> struct size_to_precision<16>
-{
- typedef extended_double_precision_tag type;
-};
-
-// fp_traits is a type switch that selects the right fp_traits_impl
-
-template<class T> struct fp_traits
-{
- BOOST_STATIC_ASSERT(boost::is_floating_point<T>::value);
- typedef BOOST_DEDUCED_TYPENAME size_to_precision<sizeof(T)>::type precision;
- typedef fp_traits_impl<T, precision> type;
-};
-
-
-//------------------------------------------------------------------------------
-
-} // namespace detail
-} // namespace math
-} // namespace spirit
-} // namespace boost
-
-#endif