From a2f352794a72ad846426bd419a370379ae9b3948 Mon Sep 17 00:00:00 2001 From: bemandawes Date: Sat, 31 May 2008 19:17:24 +0000 Subject: [PATCH] Add ability to compile a version that can be used in C++03 unions if requested and not compiling with C++0x. git-svn-id: http://svn.boost.org/svn/boost/sandbox/endian@45984 b8fc166d-592f-0410-95f2-cb63ce0dd405 --- boost/integer/endian.hpp | 106 +++++++++++------- .../endian-in-sandbox/endian-in-sandbox.sln | 6 + libs/integer/test/endian_in_union_test.cpp | 90 +++++++++++++++ 3 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 libs/integer/test/endian_in_union_test.cpp diff --git a/boost/integer/endian.hpp b/boost/integer/endian.hpp index a996538..a473695 100644 --- a/boost/integer/endian.hpp +++ b/boost/integer/endian.hpp @@ -38,6 +38,12 @@ # error Platforms with CHAR_BIT != 8 are not supported # endif +# ifndef BOOST_NO_DEFAULTED_FUNCTIONS +# define BOOST_ENDIAN_DEFAULTED = default; // C++0x +# else +# define BOOST_ENDIAN_DEFAULTED {} // C++03 +# endif + namespace boost { namespace detail @@ -146,6 +152,7 @@ namespace boost // the size and signedness of the desired integer and get the appropriate // corresponding integer type for the interface. + // unaligned big endian specialization template class endian< endianness::big, T, n_bits, alignment::unaligned > : cover_operators< endian< endianness::big, T, n_bits >, T > @@ -153,14 +160,17 @@ namespace boost BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); public: typedef T value_type; - endian() {} - endian(T val) { detail::store_big_endian(bytes, val); } - endian & operator=(T val) { detail::store_big_endian(bytes, val); return *this; } - operator T() const { return detail::load_big_endian(bytes); } +# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS) + endian() BOOST_ENDIAN_DEFAULTED + endian(T val) { detail::store_big_endian(m_value, val); } +# endif + endian & operator=(T val) { detail::store_big_endian(m_value, val); return *this; } + operator T() const { return detail::load_big_endian(m_value); } private: - char bytes[n_bits/8]; + char m_value[n_bits/8]; }; + // unaligned little endian specialization template class endian< endianness::little, T, n_bits, alignment::unaligned > : cover_operators< endian< endianness::little, T, n_bits >, T > @@ -168,14 +178,17 @@ namespace boost BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); public: typedef T value_type; - endian() {} - endian(T val) { detail::store_little_endian(bytes, val); } - endian & operator=(T val) { detail::store_little_endian(bytes, val); return *this; } - operator T() const { return detail::load_little_endian(bytes); } +# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS) + endian() BOOST_ENDIAN_DEFAULTED + endian(T val) { detail::store_little_endian(m_value, val); } +# endif + endian & operator=(T val) { detail::store_little_endian(m_value, val); return *this; } + operator T() const { return detail::load_little_endian(m_value); } private: - char bytes[n_bits/8]; + char m_value[n_bits/8]; }; + // unaligned native endian specialization template class endian< endianness::native, T, n_bits, alignment::unaligned > : cover_operators< endian< endianness::native, T, n_bits >, T > @@ -183,23 +196,29 @@ namespace boost BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits ); public: typedef T value_type; - endian() {} +# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS) + endian() BOOST_ENDIAN_DEFAULTED # ifdef BOOST_BIG_ENDIAN - endian(T val) { detail::store_big_endian(bytes, val); } - endian & operator=(T val) { detail::store_big_endian(bytes, val); return *this; } - operator T() const { return detail::load_big_endian(bytes); } + endian(T val) { detail::store_big_endian(m_value, val); } # else - endian(T val) { detail::store_little_endian(bytes, val); } - endian & operator=(T val) { detail::store_little_endian(bytes, val); return *this; } - operator T() const { return detail::load_little_endian(bytes); } + endian(T val) { detail::store_little_endian(m_value, val); } # endif +# endif +# ifdef BOOST_BIG_ENDIAN + endian & operator=(T val) { detail::store_big_endian(m_value, val); return *this; } + operator T() const { return detail::load_big_endian(m_value); } +# else + endian & operator=(T val) { detail::store_little_endian(m_value, val); return *this; } + operator T() const { return detail::load_little_endian(m_value); } +# endif private: - char bytes[n_bits/8]; + char m_value[n_bits/8]; }; // Specializations that mimic built-in integer types. // These typically have the same alignment as the underlying types. + // aligned big endian specialization template class endian< endianness::big, T, n_bits, alignment::aligned > : cover_operators< endian< endianness::big, T, n_bits, alignment::aligned >, T > @@ -208,20 +227,26 @@ namespace boost BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); public: typedef T value_type; - endian() {} - #ifdef BOOST_BIG_ENDIAN - endian(T val) : integer(val) { } - endian & operator=(T val) { integer = val); return *this; } - operator T() const { return integer; } - #else - endian(T val) { detail::store_big_endian(&integer, val); } - endian & operator=(T val) { detail::store_big_endian(&integer, val); return *this; } - operator T() const { return detail::load_big_endian(&integer); } - #endif +# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS) + endian() BOOST_ENDIAN_DEFAULTED +# ifdef BOOST_BIG_ENDIAN + endian(T val) : m_value(val) { } +# else + endian(T val) { detail::store_big_endian(&m_value, val); } +# endif +# endif +# ifdef BOOST_BIG_ENDIAN + endian & operator=(T val) { m_value = val); return *this; } + operator T() const { return m_value; } +# else + endian & operator=(T val) { detail::store_big_endian(&m_value, val); return *this; } + operator T() const { return detail::load_big_endian(&m_value); } +# endif private: - T integer; + T m_value; }; + // aligned little endian specialization template class endian< endianness::little, T, n_bits, alignment::aligned > : cover_operators< endian< endianness::little, T, n_bits, alignment::aligned >, T > @@ -230,18 +255,23 @@ namespace boost BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 ); public: typedef T value_type; - endian() {} - #ifdef BOOST_LITTLE_ENDIAN - endian(T val) : integer(val) { } - endian & operator=(T val) { integer = val; return *this; } - operator T() const { return integer; } +# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS) + endian() BOOST_ENDIAN_DEFAULTED +# ifdef BOOST_BIG_ENDIAN + endian(T val) : m_value(val) { } +# else + endian(T val) { detail::store_little_endian(&m_value, val); } +# endif +# endif +# ifdef BOOST_LITTLE_ENDIAN + endian & operator=(T val) { m_value = val; return *this; } + operator T() const { return m_value; } #else - endian(T val) { detail::store_little_endian(&integer, val); } - endian & operator=(T val) { detail::store_little_endian(&integer, val); return *this; } - operator T() const { return detail::load_little_endian(&integer); } + endian & operator=(T val) { detail::store_little_endian(&m_value, val); return *this; } + operator T() const { return detail::load_little_endian(&m_value); } #endif private: - T integer; + T m_value; }; // naming convention typedefs --------------------------------------------// diff --git a/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln b/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln index eaf71e5..8d53cb4 100644 --- a/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln +++ b/libs/integer/test/endian-in-sandbox/endian-in-sandbox.sln @@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_test", "endian_test\endian_test.vcproj", "{74C201F3-8308-40BE-BC0F-24974DEAF405}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endian_in_union_test", "endian_in_union_test\endian_in_union_test.vcproj", "{3926C6DC-9D1E-4227-BEF5-81F5EC621A75}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -13,6 +15,10 @@ Global {74C201F3-8308-40BE-BC0F-24974DEAF405}.Debug|Win32.Build.0 = Debug|Win32 {74C201F3-8308-40BE-BC0F-24974DEAF405}.Release|Win32.ActiveCfg = Release|Win32 {74C201F3-8308-40BE-BC0F-24974DEAF405}.Release|Win32.Build.0 = Release|Win32 + {3926C6DC-9D1E-4227-BEF5-81F5EC621A75}.Debug|Win32.ActiveCfg = Debug|Win32 + {3926C6DC-9D1E-4227-BEF5-81F5EC621A75}.Debug|Win32.Build.0 = Debug|Win32 + {3926C6DC-9D1E-4227-BEF5-81F5EC621A75}.Release|Win32.ActiveCfg = Release|Win32 + {3926C6DC-9D1E-4227-BEF5-81F5EC621A75}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/libs/integer/test/endian_in_union_test.cpp b/libs/integer/test/endian_in_union_test.cpp new file mode 100644 index 0000000..f3867bb --- /dev/null +++ b/libs/integer/test/endian_in_union_test.cpp @@ -0,0 +1,90 @@ +// endian_in_union_test.cpp -------------------------------------------------// + +// Copyright Beman Dawes 2008 + +// 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) + +// See library home page at http://www.boost.org/libs/endian + +//----------------------------------------------------------------------------// + +#define BOOST_ENDIANS_IN_UNIONS + +#include +#include + +using namespace boost::integer; + +union U +{ + big8_t big8; + big16_t big16; + big24_t big24; + big32_t big32; + big40_t big40; + big48_t big48; + big56_t big56; + big64_t big64; + + ubig8_t ubig8; + ubig16_t ubig16; + ubig24_t ubig24; + ubig32_t ubig32; + ubig40_t ubig40; + ubig48_t ubig48; + ubig56_t ubig56; + ubig64_t ubig64; + + little8_t little8; + little16_t little16; + little24_t little24; + little32_t little32; + little40_t little40; + little48_t little48; + little56_t little56; + little64_t little64; + + ulittle8_t ulittle8; + ulittle16_t ulittle16; + ulittle24_t ulittle24; + ulittle32_t ulittle32; + ulittle40_t ulittle40; + ulittle48_t ulittle48; + ulittle56_t ulittle56; + ulittle64_t ulittle64; + + native8_t native8; + native16_t native16; + native24_t native24; + native32_t native32; + native40_t native40; + native48_t native48; + native56_t native56; + native64_t native64; + + unative8_t unative8; + unative16_t unative16; + unative24_t unative24; + unative32_t unative32; + unative40_t unative40; + unative48_t unative48; + unative56_t unative56; + unative64_t unative64; +}; + +U foo; + +int main() +{ + big48_t b48; + b48 = 5; + assert(b48 == 5LL); + assert(b48 + 1 == 6LL); + big56_t b56; + b56 = 40; + assert(8 * b48 == b56); + + return 0; +} +