From 963f00ec8fd5598b26fecd94cabcdf16bf68914a Mon Sep 17 00:00:00 2001 From: Beman Date: Sat, 21 Feb 2015 07:38:03 -0500 Subject: [PATCH] Add missing one byte aligned types, plus other minor fixes. --- doc/arithmetic.html | 52 +++++++++++++++++++++++++-------------------- doc/buffers.html | 10 ++++++--- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/doc/arithmetic.html b/doc/arithmetic.html index ea4f5ee..522b8b5 100644 --- a/doc/arithmetic.html +++ b/doc/arithmetic.html @@ -86,19 +86,25 @@ endian and little endian.

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.

Example

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);
-

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, where x is the constructed object.

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.

  • 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 to value_type +

    Returns: endian_value, converted to value_type, if required, and having the endianness of the native platform.

    Remarks: If Align is align::yes then endianness conversion, if required, is performed by