![]() |
Endian Conversion Functions |
| Boost Home Endian Home Conversion Functions Arithmetic Types Buffer Types |
| Contents |
|
Introduction Reference Synopsis Requirements Functions FAQ Acknowledgements |
| Headers |
|
<boost/endian/conversion.hpp> <boost/endian/arithmetic.hpp> |
Header boost/endian/conversion.hpp
provides byte order reversal and conversion functions that convert objects of
the multi-byte built-in
integer types, and also types float and double,
between native, big, or little endian byte
ordering. User defined types are also supported.
Functions are implemented inline if appropriate. noexcept is
elided for compilers that do not support it.
Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.
#define BOOST_ENDIAN_INTRINSIC_MSG "message describing presence or absence of intrinsics"
namespace boost
{
namespace endian
{
enum class order
{
big, // big-endian
little, // little-endian
native = implementation-defined // same as order::big or order::little
};
// reverse byte order (i.e. endianness)
int8_t reverse_value(int8_t x) noexcept;
int16_t reverse_value(int16_t x) noexcept;
int32_t reverse_value(int32_t x) noexcept;
int64_t reverse_value(int64_t x) noexcept;
uint8_t reverse_value(uint8_t x) noexcept;
uint16_t reverse_value(uint16_t x) noexcept;
uint32_t reverse_value(uint32_t x) noexcept;
uint64_t reverse_value(uint64_t x) noexcept;
float reverse_value(float x) noexcept;
double reverse_value(double x) noexcept;
template <class Value>
void reverse(Value& x) noexcept;
// reverse byte order unless native endianness is big
template <class ReversibleValue >
ReversibleValue big_endian_value(ReversibleValue x) noexcept;
template <class Reversible>
void big_endian(Reversible& x) noexcept;
// reverse byte order unless native endianness is little
template <class ReversibleValue >
ReversibleValue little_endian_value(ReversibleValue x) noexcept;
template <class Reversible>
void little_endian(Reversible& x) noexcept;
// synonyms, based on names popularized by BSD (e.g. OS X, Linux) endian.h
// "h" for "host" (i.e. native), "be" for "big endian",
// "le" for "little endian", "m" for "modify" in place
template <class T> T bswap(T x) noexcept {return reverse_value(x);}
template <class T> T htobe(T host) noexcept {return big_endian_value(host);}
template <class T> T htole(T host) noexcept {return little_endian_value(host);}
template <class T> T betoh(T big) noexcept {return big_endian_value(big);}
template <class T> T letoh(T little) noexcept {return little_endian_value(little);}
template <class T> void bswapm(T& x) noexcept {reverse(x);}
template <class T> void htobem(T& host) noexcept {big_endian(host);}
template <class T> void htole(mT& host noexcept) {little_endian(host);}
template <class T> void betohm(T& big) noexcept {big_endian(big);}
template <class T> void letohm(T& little) noexcept {little_endian(little);}
// generic byte order conversion
template <order From, order To, class ReversibleValue>
ReversibleValue convert_value(ReversibleValue from) noexcept;
template <order From, order To, class Reversible>
void convert(Reversible& x) noexcept;
// runtime effective byte order determination
order effective_order(order x) noexcept;
// runtime byte-order conversion
template <class ReversibleValue>
ReversibleValue convert_value(ReversibleValue from,
order from_order, order to_order) noexcept;
template <class Reversible>
void convert(Reversible& x,
order from_order, order to_order) noexcept;
} // namespace endian
} // namespace boost
The implementation-defined text above is either
big or little according to the endianness of the
platform.
The template definitions in this header refer to named requirements whose details are set out in this section. User defined types may be used in the function templates in this header only if they meet the function's template parameter requirements.
ReversibleValue is an object type to be
supplied by a C++ program instantiating a template; x is a value of
type (possibly const) ReversibleValue.
| Expression | Return type | Requirement |
|
|
|
The returned value is the value of |
Reversible is an object type to be
supplied by a C++ program instantiating a template; x is a
modifiable lvalue of type Reversible.
| Expression | Post-condition |
|
|
The order of the constituent bytes of |
See
udt_conversion_example.cpp for an example of a UDT that can used in the
big_endian,
little_endian, and
convert function templates.
int8_t reverse_value(int8_t x) noexcept; int16_t reverse_value(int16_t x) noexcept; int32_t reverse_value(int32_t x) noexcept; int64_t reverse_value(int64_t x) noexcept; uint8_t reverse_value(uint8_t x) noexcept; uint16_t reverse_value(uint16_t x) noexcept; uint32_t reverse_value(uint32_t x) noexcept; uint64_t reverse_value(uint64_t x) noexcept; float reverse_value(float x) noexcept; double reverse_value(double x) noexcept;
Returns:
x, with the order of its constituent bytes reversed.
template <class Value> void reverse(Value& x) noexcept;
Postconditions: The order of the constituent bytes of
xare reversed.
template <class ReversibleValue > ReversibleValue big_endian_value(ReversibleValue x) noexcept; template <class Reversible> void big_endian(Reversible& x) noexcept;
Returns (first form):
xif the native byte order is big endian, otherwisereverse_value(x).Effects (second form): None if the native byte order is big endian, otherwise
reverse(x).Example:
int32_t x = some-value; big_endian(x); // reverses the byte order of x, unless // the native byte order is big-endian
template <class ReversibleValue > ReversibleValue little_endian_value(ReversibleValue x) noexcept; template <class Reversible> void little_endian(Reversible& x) noexcept;
Returns (first form):
xif the native byte order is little endian, otherwisereverse_value(x).Effects (second form): None if the native byte order is little endian, otherwise
reverse(x).Example:
int32_t x = some-value; int32_t y(little_endian(x)); // y has been set to x; the byte order is reversed unless // the native byte order is little-endian.
template <order From, order To, class ReversibleValue> ReversibleValue convert_value(ReversibleValue from) noexcept; template <order From, order To, class Reversible> void convert(Reversible& x) noexcept;
The effective order of an order template parameter is the same as the order template parameter if the parameter is not
order::native, otherwise it is the constantorder::bigororder::littlethat represents the actual native byte order.Returns (first form):
fromifFromandTohave the same effective order, otherwisereverse_value(from).Effects (second form): None if
FromandTohave the same effective order, otherwisereverse(x).Example:
int32_t x; ... read an external big-endian value into x convert<order::big, order::native>(x); // more generic equivalent of big_endian(x);
order effective_order(order x) noexcept;
Returns:
xifx != order::native, otherwise theorderconstant for the actual native byte order.Example:
effective_order(order::big); // returns order::big effective_order(order::little); // returns order::little effective_order(order::native); // returns order::big if the native order // is big-endian, otherwise order::little
template <class ReversibleValue>
ReversibleValue convert_value(ReversibleValue from,
order from_order, order to_order) noexcept;
template <class Reversible>
void convert(Reversible& x,
order from_order, order to_order) noexcept;Returns (first form):
fromifeffect_order(from_order) == effective_order(to_order), otherwisereverse_value(from).Effects (second form): None if
effect_order(from_order) == effective_order(to_order), otherwisereverse(x).Example:
int32_t x; ... read an external value of an endianness know only at runtime into x convert(x, some_order, order::native); // convert to native byte order if needed
See the Endian home page FAQ for a library-wide FAQ.
Why are the template versions of reverse() and reverse_value()
in a detail namespace?
They are unsafe for general use. Consider reversing the bytes of a
std::pairas a whole - the bytes fromfirstwould end up insecondand visa versa, and this is totally wrong!
Why are both value returning and modify-in-place functions provided?
Returning the result by value is the standard C and C++ idiom for functions that compute a value from an argument. Modify-in-place functions allow cleaner code in many real-world endian use cases and are more efficient for user defined types that have members such as string data that do not need to be reversed. Thus both forms are provided.
Tomas Puverle was instrumental in identifying and articulating the need to
support endian conversion as separate from endian integer types. Phil Endecott suggested the form of the value returning signatures. Vicente Botet and other reviewers suggested supporting floating point types and user defined types. General reverse template implementation approach using std::reverse suggested by Mathias Gaunard. Portable implementation approach for 16, 32, and 64-bit integers suggested by tymofey, with avoidance of undefined behavior as suggested by Giovanni Piero Deretta, and a further refinement suggested by Pyry Jahkola. Intrinsic builtins implementation approach for 16, 32, and 64-bit integers suggested by several reviewers, and by David Stone, who provided his Boost licensed macro implementation that became the starting point for boost/endian/detail/intrinsic.hpp.
Pierre Talbot provided the int8_t reverse_value() and templated
reverse() implementations.
Last revised: 19 November, 2014
© Copyright Beman Dawes, 2011, 2013
Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt