diff --git a/doc/done_list.html b/doc/done_list.html
new file mode 100644
index 0000000..28f35a4
--- /dev/null
+++ b/doc/done_list.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+New Page 1
+
+
+
+
+Endian changes since formal review
+
+ - Headers rename to endian/types.hpp and endian/conversion.hpp.
+ Infrastructure file names changed accordingly.
+ - The conversion.hpp conversion functions have been much revised, refactored,
+ renamed and otherwise improved based on review comments.
+ - UDT's are supported.
+ float
(32-bits) and double
(64-bits) are
+ supported.
+ - Both return-by-value and modify-in-place interfaces are provided.
+ - Synonyms for the BSD byte swapping function names popularized by OS X
+ and Linux are provided, so that that developers already used to these name
+ can continue to use them if they wish.
+ - In addition to the fixed endianness functions, functions that perform
+ compile-time (via template) and run-time (via function argument) dispatch
+ are now provided.
+
+
+ - Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in functions
+ are used in the implementation where appropriate.
+ - For the aligned endian integer types, the implementation uses
+ conversion.hpp conversion functions.
+ - C++11 features such as
noexcept
are used, while still
+ supporting C++03 compilers.
+ - Acknowledgements have been updated.
+ - Headers have been reorganized to make them easier to read, as requested,
+ with a synopsis at the front and implementation following.
+
+
+
+
+
diff --git a/doc/index.html b/doc/index.html
index 4172d1b..bd192a5 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -178,11 +178,14 @@ application.
Overall FAQ
-Why bother with endianness? Does endianness have any uses outside of
-portable binary file or network I/O formats?
+Why bother with endianness?
-Binary data portability is the primary use case, and that implies I/O.
-Using the 3, 5, 6, and 7 byte integer types to save internal or external
+
Binary data portability is the primary use case.
+
+Does endianness have any uses outside of portable binary file or network
+I/O formats?
+
+Using the unaligned integer types to save internal or external
memory space is a minor secondary use case.
Why bother with binary I/O? Why not just use C++ Standard Library stream
@@ -198,6 +201,13 @@ files, limit usefulness to applications where the binary I/O advantages are
paramount.
+Why is only big, little, and native endianness supported?
+
+These are the only endian schemes that have any practical value today. PDP-11
+and the other middle endian approaches are interesting historical curiosities
+but have no relevance to C++ developers.
+
+
Comments and suggestions were
received from
@@ -216,7 +226,7 @@ Tim Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen
and Vitaly Budovski,.
Last revised:
-20 May, 2013
+22 May, 2013
© Copyright Beman Dawes, 2011, 2013
Distributed under the Boost Software License, Version 1.0. See
www.boost.org/ LICENSE_1_0.txt
diff --git a/doc/types.html b/doc/types.html
index 5e5dbdc..50c43c8 100644
--- a/doc/types.html
+++ b/doc/types.html
@@ -109,64 +109,69 @@ using namespace boost::endian;
namespace
{
- // This is an extract from a very widely used GIS file format. I have no idea
- // why a designer would mix big and little endians in the same file - but
- // this is a real-world format and users wishing to write low level code
- // manipulating these files have to deal with the mixed endianness.
+ // This is an extract from a very widely used GIS file format. Who knows
+ // why a designer would mix big and little endians in the same file - but
+ // this is a real-world format and users wishing to write low level code
+ // manipulating these files have to deal with the mixed endianness.
struct header
{
- big32_t file_code;
- big32_t file_length;
- little32_t version;
- little32_t shape_type;
+ big_int32_t file_code;
+ big_int32_t file_length;
+ little_int32_t version;
+ little_int32_t shape_type;
};
- const char * filename = "test.dat";
+ const char* filename = "test.dat";
}
-int main()
+int main(int, char* [])
{
- BOOST_STATIC_ASSERT( sizeof( header ) == 16U ); // check requirement
-
+ BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
+
header h;
h.file_code = 0x01020304;
- h.file_length = sizeof( header );
- h.version = -1;
+ h.file_length = sizeof(header);
+ h.version = 1;
h.shape_type = 0x01020304;
- // Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes
- // used for binary file operations when ultimate efficiency is important.
- // Such I/O is often performed in some C++ wrapper class, but to drive home the
- // point that endian integers are often used in fairly low-level code that
- // does bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
+ // Low-level I/O such as POSIX read/write or <cstdio> fread/fwrite is sometimes
+ // used for binary file operations when ultimate efficiency is important.
+ // Such I/O is often performed in some C++ wrapper class, but to drive home the
+ // point that endian integers are often used in fairly low-level code that
+ // does bulk I/O operations, <cstdio> fopen/fwrite is used for I/O in this example.
- std::FILE * fi;
-
- if ( !(fi = std::fopen( filename, "wb" )) ) // MUST BE BINARY
+ std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
+
+ if (!fi)
{
std::cout << "could not open " << filename << '\n';
return 1;
}
- if ( std::fwrite( &h, sizeof( header ), 1, fi ) != 1 )
+ if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
{
std::cout << "write failure for " << filename << '\n';
return 1;
}
- std::fclose( fi );
+ std::fclose(fi);
std::cout << "created file " << filename << '\n';
+
return 0;
-}
+}
+
After compiling and executing endian_example.cpp,
a hex dump of test.dat
shows:
- 0102 0304 0000 0010 ffff ffff 0403 0201
+ 01020304 00000010 01000000 04030201
+Notice that the first two 32-bit integers are big endian while the second two
+are little endian, even though the machine this was compiled and run on was
+little endian.
Requires <climits>
CHAR_BIT == 8
. If CHAR_BIT
is some other value, compilation will result in an #error
. This
@@ -178,7 +183,7 @@ because it has constructors, private data members, and a base class. This means
that common use cases are relying on unspecified behavior in that the C++
Standard does not guarantee memory layout for non-POD types. This has not been a
problem in practice since all known C++ compilers do layout memory as if
-endian
were a POD type. In C++11, it will be possible to specify the
+endian were a POD type. In C++11, it is possible to specify the
default constructor as trivial, and private data members and base classes will
no longer disqualify a type from being a POD. Thus under C++11, endian
will no longer be relying on unspecified behavior.
@@ -190,15 +195,19 @@ will no longer be relying on unspecified behavior.
1-8 byte (unaligned) | 2, 4, 8 byte (aligned)
Choice of integer value type
-
+
+Two scoped enums are provided:
+
+ enum class order {big, little, native};
+enum class align {no, yes};
+
One class template is provided:
- template <endianness::enum_t E, typename T, std::size_t n_bytes,
- alignment::enum_t A = alignment::unaligned>
-class endian;
+ template <order Order, typename T, std::size_t n_bits, align A = align::no>
+ class endian;
-Sixty typedefs, such as big32_t
, provide convenient naming
+
Typedefs, such as big_int32_t
, provide convenient naming
conventions for common use cases:
@@ -210,76 +219,76 @@ conventions for common use cases:
Alignment |
- big n_t |
- big |
- signed |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- ubig n_t |
- big |
- unsigned |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- little n_t |
- little |
- signed |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- ulittle n_t |
- little |
- unsigned |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- native n_t |
- native |
- signed |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- unative n_t |
- native |
- unsigned |
- 8,16,24,32,40,48,56,64 |
- unaligned |
-
-
- aligned_big n_t |
- big |
- signed |
+ big_int n_t |
+ big |
+ signed |
16,32,64 |
- aligned |
+ yes |
- aligned_ubig n_t |
- big |
- unsigned |
+ big_uint n_t |
+ big |
+ unsigned |
16,32,64 |
- aligned |
+ yes |
- aligned_little n_t |
- little |
- signed |
+ little_int n_t |
+ little |
+ signed |
16,32,64 |
- aligned |
+ yes |
- aligned_ulittle n_t |
- little |
- unsigned |
+ little_uint n_t |
+ little |
+ unsigned |
16,32,64 |
- aligned |
+ yes |
-
+
+ big_ n_t |
+ big |
+ signed |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
+ big_u n_t |
+ big |
+ unsigned |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
+ little_ n_t |
+ little |
+ signed |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
+ little_u n_t |
+ little |
+ unsigned |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
+ native_ n_t |
+ native |
+ signed |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
+ native_u n_t |
+ native |
+ unsigned |
+ 8,16,24,32,40,48,56,64 |
+ no |
+
+
The unaligned types do not cause compilers to insert padding bytes in classes
and structs. This is an important characteristic that can be exploited to minimize wasted space in
@@ -289,8 +298,9 @@ Code that uses aligned types is inherently non-portable because alignment
requirements vary between hardware architectures and because alignment may be
affected by compiler switches or pragmas. Furthermore, aligned types
are only available on architectures with 16, 32, and 64-bit integer types.
-Note: One-byte big-endian, little-endian, and native-endian types provide identical
-functionality. All three names are provided to improve code readability and searchability.
+Note: One-byte big-endian, little-endian, and native-endian types
+have identical
+functionality. They are provided to improve code readability and searchability.
When first exposed to endian types, programmers often fit them into a mental model
based on the <cstdint>
types. Using that model, it is natural to
@@ -593,7 +603,7 @@ sign partial specialization to correctly extend the sign when cover integer size
differs from endian representation size.
Last revised:
-21 May, 2013
+22 May, 2013
© Copyright Beman Dawes, 2006-2009
Distributed under the Boost Software License, Version 1.0. See
www.boost.org/ LICENSE_1_0.txt
diff --git a/example/endian_example.cpp b/example/endian_example.cpp
index 9e6f9d3..883db8a 100644
--- a/example/endian_example.cpp
+++ b/example/endian_example.cpp
@@ -22,7 +22,7 @@ using namespace boost::endian;
namespace
{
- // This is an extract from a very widely used GIS file format. I have no idea
+ // This is an extract from a very widely used GIS file format. Who knows
// why a designer would mix big and little endians in the same file - but
// this is a real-world format and users wishing to write low level code
// manipulating these files have to deal with the mixed endianness.
@@ -35,18 +35,18 @@ namespace
little_int32_t shape_type;
};
- const char * filename = "test.dat";
+ const char* filename = "test.dat";
}
-int main(int, char * [])
+int main(int, char* [])
{
- BOOST_STATIC_ASSERT( sizeof( header ) == 16U ); // check requirement
+ BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check
header h;
h.file_code = 0x01020304;
- h.file_length = sizeof( header );
- h.version = -1;
+ h.file_length = sizeof(header);
+ h.version = 1;
h.shape_type = 0x01020304;
// Low-level I/O such as POSIX read/write or fread/fwrite is sometimes
@@ -55,21 +55,21 @@ int main(int, char * [])
// point that endian integers are often used in fairly low-level code that
// does bulk I/O operations, fopen/fwrite is used for I/O in this example.
- std::FILE * fi = std::fopen( filename, "wb" ); // MUST BE BINARY
+ std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY
- if ( !fi )
+ if (!fi)
{
std::cout << "could not open " << filename << '\n';
return 1;
}
- if ( std::fwrite( &h, sizeof( header ), 1, fi ) != 1 )
+ if (std::fwrite(&h, sizeof(header), 1, fi)!= 1)
{
std::cout << "write failure for " << filename << '\n';
return 1;
}
- std::fclose( fi );
+ std::fclose(fi);
std::cout << "created file " << filename << '\n';
diff --git a/include/boost/endian/conversion.hpp b/include/boost/endian/conversion.hpp
index 2070d4a..79da437 100644
--- a/include/boost/endian/conversion.hpp
+++ b/include/boost/endian/conversion.hpp
@@ -23,7 +23,7 @@ namespace boost
namespace endian
{
#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED
- BOOST_SCOPED_ENUM_START(order) { big, little, native }; BOOST_SCOPED_ENUM_END
+ BOOST_SCOPED_ENUM_START(order) {big, little, native}; BOOST_SCOPED_ENUM_END
# define BOOST_ENDIAN_ORDER_ENUM_DEFINED
#endif
diff --git a/include/boost/endian/detail/cover_operators.hpp b/include/boost/endian/detail/cover_operators.hpp
index 6aa8c51..e0abd3c 100644
--- a/include/boost/endian/detail/cover_operators.hpp
+++ b/include/boost/endian/detail/cover_operators.hpp
@@ -28,6 +28,7 @@
# include
# endif
+#include
#include
namespace boost
@@ -47,46 +48,46 @@ namespace boost
// built into unary +.
// Unary operations.
- friend IntegerType operator+(const T& x) { return x; }
+ friend IntegerType operator+(const T& x) BOOST_NOEXCEPT { return x; }
# ifndef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
- friend IntegerType operator-(const T& x) { return -+x; }
- friend IntegerType operator~(const T& x) { return ~+x; }
- friend IntegerType operator!(const T& x) { return !+x; }
+ friend IntegerType operator-(const T& x) BOOST_NOEXCEPT { return -+x; }
+ friend IntegerType operator~(const T& x) BOOST_NOEXCEPT { return ~+x; }
+ friend IntegerType operator!(const T& x) BOOST_NOEXCEPT { return !+x; }
// The basic ordering operations.
- friend bool operator==(const T& x, IntegerType y) { return +x == y; }
- friend bool operator<(const T& x, IntegerType y) { return +x < y; }
+ friend bool operator==(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x == y; }
+ friend bool operator<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x < y; }
# endif
// The basic arithmetic operations.
- friend T& operator+=(T& x, IntegerType y) { return x = +x + y; }
- friend T& operator-=(T& x, IntegerType y) { return x = +x - y; }
- friend T& operator*=(T& x, IntegerType y) { return x = +x * y; }
- friend T& operator/=(T& x, IntegerType y) { return x = +x / y; }
- friend T& operator%=(T& x, IntegerType y) { return x = +x % y; }
- friend T& operator&=(T& x, IntegerType y) { return x = +x & y; }
- friend T& operator|=(T& x, IntegerType y) { return x = +x | y; }
- friend T& operator^=(T& x, IntegerType y) { return x = +x ^ y; }
- friend T& operator<<=(T& x, IntegerType y) { return x = +x << y; }
- friend T& operator>>=(T& x, IntegerType y) { return x = +x >> y; }
+ friend T& operator+=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x + y; }
+ friend T& operator-=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x - y; }
+ friend T& operator*=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x * y; }
+ friend T& operator/=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x / y; }
+ friend T& operator%=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x % y; }
+ friend T& operator&=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x & y; }
+ friend T& operator|=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x | y; }
+ friend T& operator^=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x ^ y; }
+ friend T& operator<<=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x << y; }
+ friend T& operator>>=(T& x, IntegerType y) BOOST_NOEXCEPT { return x = +x >> y; }
// A few binary arithmetic operations not covered by operators base class.
- friend IntegerType operator<<(const T& x, IntegerType y) { return +x << y; }
- friend IntegerType operator>>(const T& x, IntegerType y) { return +x >> y; }
+ friend IntegerType operator<<(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x << y; }
+ friend IntegerType operator>>(const T& x, IntegerType y) BOOST_NOEXCEPT { return +x >> y; }
// Auto-increment and auto-decrement can be defined in terms of the
// arithmetic operations.
- friend T& operator++(T& x) { return x += 1; }
- friend T& operator--(T& x) { return x -= 1; }
+ friend T& operator++(T& x) BOOST_NOEXCEPT { return x += 1; }
+ friend T& operator--(T& x) BOOST_NOEXCEPT { return x -= 1; }
# ifdef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
- friend T operator++(T& x, int)
+ friend T operator++(T& x, int) BOOST_NOEXCEPT
{
T tmp(x);
x += 1;
return tmp;
}
- friend T operator--(T& x, int)
+ friend T operator--(T& x, int) BOOST_NOEXCEPT
{
T tmp(x);
x -= 1;
diff --git a/include/boost/endian/types.hpp b/include/boost/endian/types.hpp
index 7ba6886..bdbd1c2 100644
--- a/include/boost/endian/types.hpp
+++ b/include/boost/endian/types.hpp
@@ -182,17 +182,17 @@ namespace endian
{
typedef unrolled_byte_loops next;
- static T load_big(const unsigned char* bytes)
+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *(bytes - 1) | (next::load_big(bytes - 1) << 8); }
- static T load_little(const unsigned char* bytes)
+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *bytes | (next::load_little(bytes + 1) << 8); }
- static void store_big(char* bytes, T value)
+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{
*(bytes - 1) = static_cast(value);
next::store_big(bytes - 1, value >> 8);
}
- static void store_little(char* bytes, T value)
+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{
*bytes = static_cast(value);
next::store_little(bytes + 1, value >> 8);
@@ -202,13 +202,13 @@ namespace endian
template
struct unrolled_byte_loops
{
- static T load_big(const unsigned char* bytes)
+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *(bytes - 1); }
- static T load_little(const unsigned char* bytes)
+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *bytes; }
- static void store_big(char* bytes, T value)
+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{ *(bytes - 1) = static_cast(value); }
- static void store_little(char* bytes, T value)
+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{ *bytes = static_cast(value); }
};
@@ -216,19 +216,19 @@ namespace endian
template
struct unrolled_byte_loops
{
- static T load_big(const unsigned char* bytes)
+ static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *reinterpret_cast(bytes - 1); }
- static T load_little(const unsigned char* bytes)
+ static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
{ return *reinterpret_cast(bytes); }
- static void store_big(char* bytes, T value)
+ static void store_big(char* bytes, T value) BOOST_NOEXCEPT
{ *(bytes - 1) = static_cast(value); }
- static void store_little(char* bytes, T value)
+ static void store_little(char* bytes, T value) BOOST_NOEXCEPT
{ *bytes = static_cast(value); }
};
template
inline
- T load_big_endian(const void* bytes)
+ T load_big_endian(const void* bytes) BOOST_NOEXCEPT
{
return unrolled_byte_loops::load_big
(static_cast(bytes) + n_bytes);
@@ -236,7 +236,7 @@ namespace endian
template
inline
- T load_little_endian(const void* bytes)
+ T load_little_endian(const void* bytes) BOOST_NOEXCEPT
{
return unrolled_byte_loops::load_little
(static_cast(bytes));
@@ -244,7 +244,7 @@ namespace endian
template
inline
- void store_big_endian(void* bytes, T value)
+ void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
{
unrolled_byte_loops::store_big
(static_cast(bytes) + n_bytes, value);
@@ -252,7 +252,7 @@ namespace endian
template
inline
- void store_little_endian(void* bytes, T value)
+ void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
{
unrolled_byte_loops::store_little
(static_cast(bytes), value);
@@ -281,7 +281,7 @@ namespace endian
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
- explicit endian(T val)
+ explicit endian(T val) BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -290,8 +290,9 @@ namespace endian
detail::store_big_endian(m_value, val);
}
# endif
- endian & operator=(T val) { detail::store_big_endian(m_value, val); return *this; }
- operator T() const
+ endian & operator=(T val) BOOST_NOEXCEPT
+ { detail::store_big_endian(m_value, val); return *this; }
+ operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -299,7 +300,7 @@ namespace endian
# endif
return detail::load_big_endian(m_value);
}
- const char* data() const { return m_value; }
+ const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[n_bits/8];
};
@@ -314,7 +315,7 @@ namespace endian
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
- explicit endian(T val)
+ explicit endian(T val) BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -323,8 +324,9 @@ namespace endian
detail::store_little_endian(m_value, val);
}
# endif
- endian & operator=(T val) { detail::store_little_endian(m_value, val); return *this; }
- operator T() const
+ endian & operator=(T val) BOOST_NOEXCEPT
+ { detail::store_little_endian(m_value, val); return *this; }
+ operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -332,7 +334,7 @@ namespace endian
# endif
return detail::load_little_endian(m_value);
}
- const char* data() const { return m_value; }
+ const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[n_bits/8];
};
@@ -348,19 +350,23 @@ namespace endian
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
# ifdef BOOST_BIG_ENDIAN
- explicit endian(T val) { detail::store_big_endian(m_value, val); }
+ explicit endian(T val) BOOST_NOEXCEPT { detail::store_big_endian(m_value, val); }
# else
- explicit endian(T val) { detail::store_little_endian(m_value, val); }
+ explicit endian(T val) BOOST_NOEXCEPT { 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); }
+ endian & operator=(T val) BOOST_NOEXCEPT
+ { detail::store_big_endian(m_value, val); return *this; }
+ operator T() const BOOST_NOEXCEPT
+ { 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); }
+ endian & operator=(T val) BOOST_NOEXCEPT
+ { detail::store_little_endian(m_value, val); return *this; }
+ operator T() const BOOST_NOEXCEPT
+ { return detail::load_little_endian(m_value); }
# endif
- const char* data() const { return m_value; }
+ const char* data() const BOOST_NOEXCEPT { return m_value; }
private:
char m_value[n_bits/8];
};
@@ -378,7 +384,7 @@ namespace endian
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
- explicit endian(T val)
+ explicit endian(T val) BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -388,12 +394,12 @@ namespace endian
}
# endif
- endian& operator=(T val)
+ endian& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian::big_endian_value(val);
return *this;
}
- operator T() const
+ operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -401,7 +407,7 @@ namespace endian
# endif
return ::boost::endian::big_endian_value(m_value);
}
- const char* data() const {return reinterpret_cast(&m_value);}
+ const char* data() const BOOST_NOEXCEPT {return reinterpret_cast(&m_value);}
private:
T m_value;
};
@@ -417,7 +423,7 @@ namespace endian
typedef T value_type;
# ifndef BOOST_ENDIAN_NO_CTORS
endian() BOOST_ENDIAN_DEFAULT_CONSTRUCT
- explicit endian(T val)
+ explicit endian(T val) BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -427,12 +433,12 @@ namespace endian
}
# endif
- endian& operator=(T val)
+ endian& operator=(T val) BOOST_NOEXCEPT
{
m_value = ::boost::endian::little_endian_value(val);
return *this;
}
- operator T() const
+ operator T() const BOOST_NOEXCEPT
{
# ifdef BOOST_ENDIAN_LOG
if ( endian_log )
@@ -440,7 +446,7 @@ namespace endian
# endif
return ::boost::endian::little_endian_value(m_value);
}
- const char* data() const {return reinterpret_cast(&m_value);}
+ const char* data() const BOOST_NOEXCEPT {return reinterpret_cast(&m_value);}
private:
T m_value;
};