diff --git a/include/boost/endian/converters.hpp b/include/boost/endian/converters.hpp index 0ad4144..b6b4f4f 100644 --- a/include/boost/endian/converters.hpp +++ b/include/boost/endian/converters.hpp @@ -20,16 +20,10 @@ namespace boost { namespace endian { +#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED BOOST_SCOPED_ENUM_START(order) { big, little, native }; BOOST_SCOPED_ENUM_END - - // runtime byte order conversion - template - inline T convert_bytes(T from, BOOST_SCOPED_ENUM(order) from_order, - BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT; - - // compile-time generic byte order conversion - template - inline T convert_bytes(T from) BOOST_NOEXCEPT; +# define BOOST_ENDIAN_ORDER_ENUM_DEFINED +#endif // reverse byte order (i.e. endianness) // value returning interface approach suggested by Phil Endecott. @@ -66,6 +60,19 @@ namespace endian inline T little(T x) BOOST_NOEXCEPT; // Return: x if native endian order is little, otherwise reverse_bytes(x); + // compile-time generic byte order conversion + template + inline T convert_bytes(T from) BOOST_NOEXCEPT; + + // runtime actual byte-order determination + inline BOOST_SCOPED_ENUM(order) actual_order(BOOST_SCOPED_ENUM(order) o) BOOST_NOEXCEPT; + // Return: o if o != native, otherwise big or little depending on native ordering + + // runtime byte-order conversion + template + T convert_bytes(T from, BOOST_SCOPED_ENUM(order) from_order, + BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT; + //----------------------------------- implementation -----------------------------------// // -- reverse_bytes implementation approach suggested by tymofey, with avoidance of // undefined behavior as suggested by Giovanni Piero Deretta, and a further @@ -121,7 +128,6 @@ namespace endian | (step16 & 0xFF00FF00FF00FF00) >> 8; } - // general reverse_bytes function template implementation approach using std::reverse // suggested by Mathias Gaunard template @@ -155,6 +161,28 @@ namespace endian # endif } + // runtime actual byte-order determination + inline BOOST_SCOPED_ENUM(order) actual_order(BOOST_SCOPED_ENUM(order) o) BOOST_NOEXCEPT + { + return o != order::native ? o : + # ifdef BOOST_LITTLE_ENDIAN + order::little +# else + order::big +# endif + ; + } + + template + T convert_bytes(T from, BOOST_SCOPED_ENUM(order) from_order, + BOOST_SCOPED_ENUM(order) to_order) BOOST_NOEXCEPT + { + if (actual_order(from_order) == order::big) + return actual_order(to_order) == order::big ? from : reverse_bytes(from); + // actual from_order is little + return actual_order(to_order) == order::little ? from : reverse_bytes(from); + } + } // namespace endian } // namespace boost diff --git a/include/boost/endian/integers.hpp b/include/boost/endian/integers.hpp index 70bce7c..f606ee9 100644 --- a/include/boost/endian/integers.hpp +++ b/include/boost/endian/integers.hpp @@ -163,7 +163,10 @@ namespace boost // endian class template and specializations ---------------------------------------// +#ifndef BOOST_ENDIAN_ORDER_ENUM_DEFINED BOOST_SCOPED_ENUM_START(order) { big, little, native }; BOOST_SCOPED_ENUM_END +# define BOOST_ENDIAN_ORDER_ENUM_DEFINED +#endif BOOST_SCOPED_ENUM_START(alignment) { unaligned, aligned }; BOOST_SCOPED_ENUM_END template