From 963f00ec8fd5598b26fecd94cabcdf16bf68914a Mon Sep 17 00:00:00 2001
From: Beman
Boost endian integers provide the same full set of C++ assignment, arithmetic, and relational operators as C++ standard integral types, with the standard semantics.
-Unary arithmetic operators are +
, -
, ~
,
-!
, prefix and postfix --
and ++
. Binary
-arithmetic operators are +
, +=
, -
,
--=
, *
, *=
, /
, /=
,
-%/ %=
, &
, &=
, |
, |=
,
-^
, ^=
, <<
, <<=
, >>
,
->>=
. Binary relational operators are ==
, !=
,
-<
, <=
, >
, >=
.
Automatic implicit conversion to the underlying value type is provided. A -conversion constructor from the underlying value type is provided.
+Unary arithmetic operators are +
,
+ -
, ~
,
+!
, plus both prefix and postfix --
and ++
. Binary
+arithmetic operators are +
, +=
, -
,
+
+-=
, *
, *=
, /
,
+ /=
, &
, &=
,
+ |
, |=
,
+^
, ^=
, <<
, <<=
,
+>>
, and
+>>=
. Binary relational operators are ==
,
+ !=
,
+<
, <=
, >
,
+and >=
.
Implicit conversion to the underlying value type is provided. An implicit +constructor converting from the underlying value type is provided.
The endian_example.cpp program writes a -binary file containing four byte big-endian and little-endian integers:
+binary file containing four-byte, big-endian and little-endian integers:#include <iostream> #include <cstdio> @@ -128,10 +134,10 @@ namespace int main(int, char* []) { - BOOST_STATIC_ASSERT(sizeof(header) == 16U); // reality check - header h; + BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check + h.file_code = 0x01020304; h.file_length = sizeof(header); h.version = 1; @@ -181,14 +187,14 @@ is some other value, compilation will result in an#error
. This restriction is in place because the design, implementation, testing, and documentation has only considered issues related to 8-bit bytes, and there have been no real-world use cases presented for other sizes. -In C++03,
endian
does not meet the requirements for POD types +In C++03,
endian_arithmetic
does not meet the requirements for POD types 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+problem in practice since all known C++ compilers lay out memory as if
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
+default constructor as trivial, and private data members and base classes no longer disqualify a type from being a POD +type. Thus under C++11,endian_arithmetic
will no longer be relying on unspecified behavior.Feature set
@@ -196,7 +202,7 @@ will no longer be relying on unspecified behavior.
- Signed | unsigned
- Unaligned | aligned
- Integer | floating point
-- 1-8 byte (unaligned) | 2, 4, 8 byte (aligned)
+- 1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)
- Choice of value type
Enums and typedefs
@@ -347,14 +353,14 @@ requirements vary between hardware architectures and because alignment may be affected by compiler switches or pragmas. For example, alignment of an 64-bit integer may be to a 32-bit boundary on a 32-bit machine. Furthermore, aligned types are only available on architectures with 8, 16, 32, and 64-bit integer types. -Recommendation: Prefer unaligned endian types.
+Recommendation: Prefer unaligned arithmetic types.
Recommendation: Protect yourself against alignment ills. For example:
-static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong");Note: One-byte big and little buffer types -never actually reverse endianness. They are provided to enable generic code, and +
Note: Note: One-byte arithmetic types +have identical layout on all platforms, so they never actually reverse endianness. They are provided to enable generic code, and to improve code readability and searchability.
Class template
endian
_arithmetic
An endian is an integer byte-holder with user-specified @@ -540,11 +546,11 @@ platform.
endian() = default; // C++03: endian(){}
-Effects: Constructs an object of type
+endian<E, T, n_bits, A>
.Effects: Constructs an uninitialized object of type
endian_arithmetic<E, T, n_bits, A>
.endian(T v);
-diff --git a/doc/buffers.html b/doc/buffers.html index a1f98f9..dceec38 100644 --- a/doc/buffers.html +++ b/doc/buffers.html @@ -184,7 +184,7 @@ will no longer be relying on unspecified behavior.Effects: Constructs an object of type
+endian<E, T, n_bits, A>
.Effects: Constructs an object of type
endian_arithmetic<E, T, n_bits, A>
.Postcondition:
x == v,
wherex
is the constructed object.Signed | unsigned Unaligned | aligned Integer | floating point -1-8 byte (unaligned) | 2, 4, 8 byte (aligned) +1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned) Choice of value type Enums and typedefs
@@ -336,7 +336,7 @@ affected by compiler switches or pragmas. For example, alignment of an 64-bit integer may be to a 32-bit boundary on a 32-bit machine and to a 64-bit boundary on a 64-bit machine. Furthermore, aligned types are only available on architectures with 8, 16, 32, and 64-bit integer types. -Recommendation: Prefer unaligned endian types.
+Recommendation: Prefer unaligned buffer types.
Recommendation: Protect yourself against alignment ills. For example:
@@ -415,21 +415,25 @@ usual operations on integers are supplied. typedef endian_buffer<order::little, double, 64, align::no> little_float64_buf_ut; // aligned big endian signed integer buffers + typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_t; typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_t; typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_t; typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_t; // aligned big endian unsigned integer buffers + typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_t; typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_t; typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_t; typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_t; // aligned little endian signed integer buffers + typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_t; typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_t; typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_t; typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_t; // aligned little endian unsigned integer buffers + typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_t; typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_t; typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_t; typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_t; @@ -546,7 +550,7 @@ boost::endian::endian_reverse.value_type value()const noexcept;
-Returns:
endian_value
, converted tovalue_type
+Returns:
endian_value
, converted tovalue_type
, if required, and having the endianness of the native platform.Remarks: If
Align
isalign::yes
then endianness conversion, if required, is performed by