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
This commit is contained in:
bemandawes
2008-05-31 19:17:24 +00:00
parent 59c79ecb75
commit a2f352794a
3 changed files with 164 additions and 38 deletions

View File

@@ -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 <typename T, std::size_t n_bits>
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<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(bytes); }
# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS)
endian() BOOST_ENDIAN_DEFAULTED
endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); }
# endif
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
private:
char bytes[n_bits/8];
char m_value[n_bits/8];
};
// unaligned little endian specialization
template <typename T, std::size_t n_bits>
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<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(bytes); }
# if !defined(BOOST_NO_DEFAULTED_FUNCTIONS) || !defined(BOOST_ENDIANS_IN_UNIONS)
endian() BOOST_ENDIAN_DEFAULTED
endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
# endif
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(m_value); }
private:
char bytes[n_bits/8];
char m_value[n_bits/8];
};
// unaligned native endian specialization
template <typename T, std::size_t n_bits>
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<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(bytes); }
endian(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); }
# else
endian(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); }
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(bytes, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(bytes); }
endian(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); }
# endif
# endif
# ifdef BOOST_BIG_ENDIAN
endian & operator=(T val) { detail::store_big_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_big_endian<T, n_bits/8>(m_value); }
# else
endian & operator=(T val) { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
operator T() const { return detail::load_little_endian<T, n_bits/8>(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 <typename T, std::size_t n_bits>
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<T, sizeof(T)>(&integer, val); }
endian & operator=(T val) { detail::store_big_endian<T, sizeof(T)>(&integer, val); return *this; }
operator T() const { return detail::load_big_endian<T, sizeof(T)>(&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<T, sizeof(T)>(&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<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const { return detail::load_big_endian<T, sizeof(T)>(&m_value); }
# endif
private:
T integer;
T m_value;
};
// aligned little endian specialization
template <typename T, std::size_t n_bits>
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<T, sizeof(T)>(&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<T, sizeof(T)>(&integer, val); }
endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&integer, val); return *this; }
operator T() const { return detail::load_little_endian<T, sizeof(T)>(&integer); }
endian & operator=(T val) { detail::store_little_endian<T, sizeof(T)>(&m_value, val); return *this; }
operator T() const { return detail::load_little_endian<T, sizeof(T)>(&m_value); }
#endif
private:
T integer;
T m_value;
};
// naming convention typedefs --------------------------------------------//

View File

@@ -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

View File

@@ -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 <boost/integer/endian.hpp>
#include <cassert>
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;
}