From b541dfb7907236df68e91067b788203d9aaec69c Mon Sep 17 00:00:00 2001
From: Beman Header boost/endian/conversion.hpp
provides byte order reversal and conversion functions that convert objects of
the multi-byte built-in
@@ -79,70 +71,6 @@ ordering. User defined types are also supported. Is the implementation header only? Yes. Does the implementation use compiler intrinsic built-in byte swapping? Yes, if available. See Intrinsic built-in support
-below. Why are the template versions of They are unsafe for general use. Consider reversing
-the bytes of a 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. What are the limitations of floating point support? The only supported types are four byte What are the limitations of integer support? Only 16-bit, 32-bit, and 64-bit integers are supported. Tests have been
-performed on machines that use two's complement arithmetic. Functions are implemented Returns (first form): Returns (first form): Effects (second form): None if the native byte order is big
+ Effects (second form): None if the native byte order is big
endian, otherwise Example: Example: Returns (first form): Returns (first form): Effects (second form): None if the native byte order is little
+ Effects (second form): None if the native byte order is little
endian, otherwise Example: Example: The effective order of an order template parameter
+ The effective order of an order template parameter
is the same as the order template parameter if the parameter is not Returns (first form): Returns (first form): Effects (second form): None if Effects (second form): None if Example: Example: Returns: Example: Returns: Example: Returns (first form): Effects (second form): None if Example: Returns (first form): Effects (second form): None if Example: Recent compilers, including GCC, Clang, and Microsoft, supply intrinsic built-in support for byte swapping. Such support is automatically detected and used since it results in smaller and much faster generated code for release builds. Defining BOOST_ENDIAN_NO_INTRINSICS will suppress use of the intrinsics. Please try defining it if you get compiler errors, such as header byteswap.h not being found. The macro BOOST_ENDIAN_INTRINSIC_MSG is defined as either Tomas Puverle was instrumental in identifying and articulating the need to
+ See the Endian home page FAQ for a library-wide
+FAQ. Why are the template versions of They are unsafe for general use. Consider reversing
+the bytes of a 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. Last revised: 20 May, 2013 © Copyright Beman Dawes, 2011 Last revised:
+28 May, 2013 © Copyright Beman Dawes, 2011, 2013 Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt See the Wikipedia's
Endianness article for an
@@ -195,6 +196,18 @@ application needs. Recent compilers, including GCC, Clang, and Microsoft, supply intrinsic
+built-in support for byte swapping. Such support is automatically detected and
+used since it may in smaller and faster generated code, particularly for release
+builds. Defining The macro Consider this problem:Boost Home
Endian Home
Conversion Functions
- Endian Types Tutorial
+ Endian Types
@@ -37,12 +37,11 @@
-
Introduction
- conversion.hpp FAQ
Reference
Synopsis
Requirements
Functions
- Intrinsic built-in support
+ FAQ
Acknowledgements
@@ -58,13 +57,6 @@
Introduction
-
-
-
-
-Please: If you haven't done so already, read
- Introduction to endianness!
- conversion.hpp FAQ
-
-
-
-
-
-
-
-
-
-reverse()
and reverse_value()
-in a detail namespace?
-
-
-
-std::pair
as a whole - the bytes from first
-would end up in second
and visa versa, and this is totally
-wrong!
-
-
-
-
-
-
-
-float
and eight byte
-double
. Even after endianness has been accounted for, floating
-point values will not be portable between systems that use different floating
-point formats. Systems where the integer endianness and floating point
-endianness are not supported.
-
-
-
Reference
inline
if appropriate. noexcept
is
@@ -152,7 +80,7 @@ Boost scoped enum emulation is used so that the library still works for compiler
Synopsis
-#define BOOST_ENDIAN_INTRINSIC_MSG "message describing presence or absence of intrinsics"
+
#define BOOST_ENDIAN_INTRINSIC_MSG "message describing presence or absence of intrinsics"
namespace boost
{
@@ -297,27 +225,27 @@ void reverse(double& x) noexcept;
template <class Reversible>
void big_endian(Reversible& x) noexcept;
-
-x
if the native byte order is big
+ x
if the native byte order is big
endian, otherwise reverse_value(x)
.reverse(x)
.
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 >
+
template <class ReversibleValue >
ReversibleValue little_endian_value(ReversibleValue x) noexcept;
template <class Reversible>
void little_endian(Reversible& x) noexcept;
-
-x
if the native byte order is little
+ x
if the native byte order is little
endian, otherwise reverse_value(x)
.reverse(x)
.
int32_t x = some-value;
int32_t y(little_endian(x));
@@ -325,51 +253,84 @@ int32_t y(little_endian(x));
// the native byte order is little-endian.
template <order From, order To, class ReversibleValue>
+
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;
-
-
order::native
, otherwise it is the constant order::big
or
order::little
that represents the actual native byte order.from
if From
+ from
if From
and To
have the same effective order, otherwise
reverse_value(from)
.From
and
+
From
and
To
have the same effective order, otherwise reverse(x)
.
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;
x
if x != order::native
, otherwise the order
constant for the actual native byte order.effective_order(order::big); // returns order::big
+
order effective_order(order x) noexcept;
+
+
+
x
if x != order::native
, otherwise the order
constant for the actual native byte order.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>
+ // 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;
from
if effect_order(from_order) == effective_order(to_order)
, otherwise reverse_value(from)
.effect_order(from_order) == effective_order(to_order)
, otherwise reverse(x)
.from
if effect_order(from_order) == effective_order(to_order)
, otherwise reverse_value(from)
.effect_order(from_order) == effective_order(to_order)
, otherwise reverse(x)
.
-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
Intrinsic built-in support
+
-"no byte swap intrinsics"
or a string describing the particular set of intrinsics being used.Acknowledgements
FAQ
+
+reverse()
and reverse_value()
+in a detail namespace?
+
+
+
+std::pair
as a whole - the bytes from first
+would end up in second
and visa versa, and this is totally
+wrong!
+
+
+
+Acknowledgements
-
float)
and
64-bit (double)
floating point, as requested.
-
@@ -34,6 +34,7 @@
Boost Home
Endian Home
Conversion Functions
- Endian Types Tutorial
+ Endian Types
@@ -40,6 +40,7 @@
Introduction to endianness
+
Introduction to the Boost.Endian library
Choosing approaches
+ Intrinsic built-in support
Performance
Timings
Conclusions
@@ -79,7 +80,7 @@ floating point, and user defined data.
@@ -103,7 +104,7 @@ ordering and the least-significant-byte-first is traditionally called
Jonathan Swift's satirical novel
-Gulliver’s Travels, where rival kingdoms opened their soft-boiled eggs
+Gulliver’s Travels, where rival kingdoms opened their soft-boiled eggs
at different ends.
int16_t i = 0x0102;
-FILE * file = fopen("test.bin", "wb"); // MUST BE BINARY
+FILE * file = fopen("test.bin", "wb"); // binary file!
fwrite(&i, sizeof(int16_t), 1, file);
fclose(file);
Intrinsic built-in support
+BOOST_ENDIAN_NO_INTRINSICS
will suppress use
+of the intrinsics. Please try defining it if you get compiler errors, such as
+header byteswap.h not being found.BOOST_ENDIAN_INTRINSIC_MSG
is defined as
+either "no byte swap intrinsics"
or a string describing the
+particular set of intrinsics being used.Performance
Is the implementation header only?
+ ++ ++ +Yes.
+ +
Does the implementation use compiler intrinsic built-in byte swapping?
+ ++ ++Yes, if available. See Intrinsic built-in support.
+ +
Why bother with endianness?
+Binary data portability is the primary use case.
@@ -448,6 +478,15 @@ files, limit usefulness to applications where the binary I/O advantages are paramount.
Which is better, big-endian or little-endian?
+++Big-endian tends to be a +bit more of an industry standard, but little-endian may be preferred for +applications that run primarily Intel/AMD on x86, x64, and other little-endian +CPU's. The Wikipedia article +gives more pros and cons.
+
Why is only big, little, and native endianness supported?
+These are the only endian schemes that have any practical value today. PDP-11 @@ -455,12 +494,33 @@ and the other middle endian approaches are interesting historical curiosities but have no relevance to C++ developers.
What are the limitations of floating point support?
+ ++ ++ +The only supported types are four byte
+ +float
and eight byte +double
. Even after endianness has been accounted for, floating +point values will not be portable between systems that use different floating +point formats. Systems where the integer endianness differs from floating point +endianness are not supported.
What are the limitations of integer support?
+ ++ ++Only 16-bit, 32-bit, and 64-bit integers are supported. Tests have only been +performed on machines that use two's complement arithmetic.
+ +
Comments and suggestions were received from Adder, Benaka Moorthi, Christopher Kohlhoff, -Cliff Green,Daniel James, Gennaro Proto, +Cliff Green, Daniel James, Gennaro Proto, Giovanni Piero Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jeff Flinn, John Filo, John Maddock, Kim Barrett, @@ -474,7 +534,7 @@ and Vitaly Budovski,.
Last revised: 28 May, 2013
-© Copyright Beman Dawes, 2011, 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 d6c89bf..d733fd5 100644 --- a/doc/types.html +++ b/doc/types.html @@ -4,7 +4,7 @@ - +*this
.
Other operators on endian objects are forwarded to the equivalent
operator on value_type
.
Why bother with endian types? External data portability and both speed -and space efficiency. Availability -of additional binary integer sizes and alignments is important in some -applications.
+ +See the Endian home page FAQ for a library-wide +FAQ.
+Why not just use Boost.Serialization? Serialization involves a conversion for every object involved in I/O. Endian integers require no conversion or copying. They are already in the desired format for binary I/O. Thus they can be read or written in bulk.
-Why bother with binary I/O? Why not just use C++ Standard Library stream -inserters and extractors? Using binary rather than character representations -can be more space efficient, with a side benefit of faster I/O. CPU time is -minimized because conversions to and from string are eliminated. -Furthermore, binary integers are fixed size, and so fixed-size disk records -are possible, easing sorting and allowing direct access. Disadvantages, such as the inability to use -text utilities on the resulting files, limit usefulness to applications where -the -binary I/O advantages are paramount.
-Do these types have any uses outside of I/O? Native endianness can be used for fine grained control over size and -alignment, so may be used to save memory in applications not related to I/O.
-Is there is a performance hit when doing arithmetic using these types? Yes, for sure, -compared to arithmetic operations on native integer types. However, these types -are usually be faster, and sometimes much faster, for I/O compared to stream -inserters and extractors, or to serialization.
Are endian types POD's? Yes for C++11. No for C++03, although several macros are available to force PODness in all cases.
What are the implications endian integer types not being POD's with C++03 @@ -541,24 +526,15 @@ can't be used in unions. Also, compilers aren't required to align or lay out storage in portable ways, although this potential problem hasn't prevented use of Boost.Endian with real compilers.
-Which is better, big-endian or little-endian? Big-endian tends to be a -bit more of an industry standard, but little-endian may be preferred for -applications that run primarily Intel/AMD on x86, x64, and other little-endian -CPU's. The Wikipedia article -gives more pros and cons.
What good is native endianness? It provides alignment and size guarantees not available from the built-in types. It eases generic programming.
Why bother with the aligned endian types? Aligned integer operations -may be faster (20 times, in one measurement) if the endianness and alignment of -the type matches the endianness and alignment requirements of the machine. On -common CPU architectures, that optimization is only available for aligned types. -That allows I/O of maximally efficient types on an application's primary -platform, yet produces data files are portable to all platforms. The code, +may be faster (as much as 10 to 20 times faster) if the endianness and alignment of +the type matches the endianness and alignment requirements of the machine. The code, however, is likely to be somewhat less portable than with the unaligned types.
-The endian types are really just byte-holders. Why provide the arithmetic -operations at all? Providing a full set of operations reduces program +
Why provide the arithmetic operations? Providing a full set of operations reduces program clutter and makes code both easier to write and to read. Consider incrementing a variable in a record. It is very convenient to write:
++record.foo;@@ -629,11 +605,12 @@ Borgerding. Four original class templates combined into a single
endianunrolled_byte_loops
sign partial specialization to correctly extend the sign when cover integer size
-differs from endian representation size.
+differs from endian representation size. Vicente Botet and other reviewers
+suggested supporting floating point types.
Last revised: -26 May, 2013
-© Copyright Beman Dawes, 2006-2009
+28 May, 2013 +© Copyright Beman Dawes, 2006-2009, 2013
Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt