diff --git a/doc/buffers.html b/doc/buffers.html index e76a07c..c747a54 100644 --- a/doc/buffers.html +++ b/doc/buffers.html @@ -1,4 +1,4 @@ - + @@ -49,20 +49,14 @@ Limitations
Feature set
Enums and typedefs
- Class template endian
+ Class template endian_buffer
    Synopsis
    Members
-    Stream inserter
-    Stream extractor
FAQ
Design
- Experience
- Motivating use cases
C++11
- Compilation
- Acknowledgements - + Compilation @@ -76,58 +70,44 @@

Introduction

Header boost/endian/buffers.hpp -provides integer and floating point binary types with control over -byte order, value type, size, and alignment. Typedefs provide easy-to-use names -for common configurations.

-

These types provide portable byte-holders for integer data, independent of -particular computer architectures. Use cases almost always involve I/O, either via files or -network connections. Although data portability is the primary motivation, these -integer byte-holders may +provides portable integer and floating-point binary buffer types with control over +byte order, value type, size, and alignment independent of the native computer +architecture. Typedefs provide easy-to-use names +for common configurations. Use cases almost always involve I/O, either via files or +network connections.

+

Although data portability is the primary motivation, these byte-holders may also be used to reduce memory use, file size, or network activity since they -provide binary integer sizes not otherwise available.

-

Such integer byte-holder types are traditionally called -endian types. See the +also +provide binary numeric sizes not otherwise available.

+

The byte order of arithmetic types is traditionally called endianness. See the Wikipedia for a full exploration of endianness, including definitions of big 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. An -conversion constructor 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:

#include <iostream>
 #include <cstdio>
-#include <boost/endian/arithmetic.hpp>
+#include <boost/endian/buffers.hpp>
 #include <boost/static_assert.hpp>
 
 using namespace boost::endian;
 
 namespace 
 {
-  //  This is an extract from a very widely used GIS file format. It seems odd
-  //  to mix big and little endians in the same file - but this is a real-world
-  //  format and users wishing to write low level code manipulating these files
-  //  must deal with the mixed endianness.
+  //  This is an extract from a very widely used GIS file format. Why the designer
+  //  decided to mix big and little endians in the same file is not known. But
+  //  this is a real-world format and users wishing to write low level code
+  //  manipulating these files have to deal with the mixed endianness.
 
   struct header
   {
-    big_int32_t     file_code;
-    big_int32_t     file_length;
-    little_int32_t  version;
-    little_int32_t  shape_type;
+    big_int32_buf_t     file_code;
+    big_int32_buf_t     file_length;
+    little_int32_buf_t  version;
+    little_int32_buf_t  shape_type;
   };
 
   const char* filename = "test.dat";
@@ -186,14 +166,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_buffer 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 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 +no longer disqualify a type from being a POD. Thus under C++11, endian_buffer will no longer be relying on unspecified behavior.

Feature set

One class template is provided:

-
template <order Order, typename T, std::size_t n_bits, align A = align::no>
-  class endian_arithmetic;
+  
template <order Order, typename T, std::size_t Nbits, align A = align::no>
+  class endian_buffer;
 
-

Typedefs, such as big_int32_t, provide convenient naming +

Typedefs, such as big_int32_buf_t, provide convenient naming conventions for common use cases:

- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - + + + + + + + + + + - + - + - + - + - + - +
Name EndiannessAlignment Sign Sizes in bits (n)Alignment
big_intn_tbig_intn_buf_t bigyes signed 16,32,64yes
big_uintn_tbig_uintn_buf_t bigyes unsigned 16,32,64yes
big_floatn_tbig_floatn_buf_t bigyes signed 32,64yes
big_intn_utbig_intn_buf_ut bigno signed 8,16,24,32,40,48,56,64no
big_uintn_utbig_uintn_buf_ut bigno unsigned 8,16,24,32,40,48,56,64no
big_floatn_utbig_floatn_buf_ut bigno signed 32,64no
little_intn_tlittle_intn_buf_t littleyes signed 16,32,64yes
little_uintn_tlittle_uintn_buf_t littleyes unsigned 16,32,64yes
little_floatn_tlittle_floatn_buf_t littleyes signed 32,64yes
little_intn_utlittle_intn_buf_ut littleno signed 8,16,24,32,40,48,56,64no
little_uintn_utlittle_uintn_buf_ut littleno unsigned 8,16,24,32,40,48,56,64
little_floatn_utlittle nosigned32,64
native_floatn_tnativeyeslittle_floatn_buf_utlittle signed 32,64no
native_floatn_buf_tnativesigned32,64yes
native_intn_utnative_intn_buf_ut nativeno signed 8,16,24,32,40,48,56,64no
native_uintn_utnative_uintn_buf_ut nativeno unsigned 8,16,24,32,40,48,56,64no
native_floatn_utnative_floatn_buf_ut nativeno signed 32,64no
@@ -354,8 +334,8 @@ are only available on architectures with 16, 32, and 64-bit integer types.

Note: One-byte types have identical functionality. They are provided to improve code readability and searchability.

-

Class template endian_arithmetic

-

An endian is an integer byte-holder with user-specified +

Class template endian_buffer

+

An endian_buffer is an integer byte-holder with user-specified endianness, value type, size, and alignment. The usual operations on integers are supplied.

Synopsis

@@ -374,178 +354,162 @@ usual operations on integers are supplied.

enum class align {no, yes}; - template <order Order, class T, std::size_t n_bits, align A = align::no> - class endian + template <order Order, class T, std::size_t Nbits, align Align = align::no> + class endian_buffer { public: typedef T value_type; // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 POD's are not // available then these two constructors will not be present - endian() noexcept = default; - endian(T v) noexcept; + endian_buffer() noexcept = default; + explicit endian_buffer(T v) noexcept; - endian& operator=(T v) noexcept; - operator T() const noexcept; - const char* data() const noexcept; - - // arithmetic operations - // note that additional operations are provided by the value_type - value_type operator+(const endian& x) noexcept; - endian& operator+=(endian& x, value_type y) noexcept; - endian& operator-=(endian& x, value_type y) noexcept; - endian& operator*=(endian& x, value_type y) noexcept; - endian& operator/=(endian& x, value_type y) noexcept; - endian& operator%=(endian& x, value_type y) noexcept; - endian& operator&=(endian& x, value_type y) noexcept; - endian& operator|=(endian& x, value_type y) noexcept; - endian& operator^=(endian& x, value_type y) noexcept; - endian& operator<<=(endian& x, value_type y) noexcept; - endian& operator>>=(endian& x, value_type y noexcept; - value_type operator<<(const endian& x, value_type y) noexcept; - value_type operator>>(const endian& x, value_type y) noexcept; - endian& operator++(endian& x) noexcept; - endian& operator--(endian& x) noexcept; - endian operator++(endian& x, int) noexcept; - endian operator--(endian& x, int) noexcept; - - // Stream inserter - template <class charT, class traits> - friend std::basic_ostream<charT, traits>& - operator<<(std::basic_ostream<charT, traits>& os, const T& x); - - // Stream extractor - template <class charT, class traits> - friend std::basic_istream<charT, traits>& - operator>>(std::basic_istream<charT, traits>& is, T& x); + endian_buffer& operator=(T v) noexcept; + value_type value() const noexcept; + const char* data() const noexcept; + protected: + implementaton-defined endian_value; // for exposition only }; // typedefs - // aligned big endian floating point types - typedef endian<order::big, float, 32, align::yes> big_float32_t; - typedef endian<order::big, double, 64, align::yes> big_float64_t; - - // aligned little endian floating point types - typedef endian<order::little, float, 32, align::yes> little_float32_t; - typedef endian<order::little, double, 64, align::yes> little_float64_t; - - // unaligned big endian floating point types - typedef endian<order::big, float, 32, align::no> big_float32un_t; - typedef endian<order::big, double, 64, align::no> big_float64un_t; + // aligned big endian floating point buffers + typedef endian_buffer<order::big, float, 32, align::yes> big_float32_buf_t; + typedef endian_buffer<order::big, double, 64, align::yes> big_float64_buf_t; - // unaligned little endian floating point types - typedef endian<order::little, float, 32, align::no> little_float32un_t; - typedef endian<order::little, double, 64, align::no> little_float64un_t; + // aligned little endian floating point buffers + typedef endian_buffer<order::little, float, 32, align::yes> little_float32_buf_t; + typedef endian_buffer<order::little, double, 64, align::yes> little_float64_buf_t; + + // unaligned big endian floating point buffers + typedef endian_buffer<order::big, float, 32, align::no> big_float32_buf_ut; + typedef endian_buffer<order::big, double, 64, align::no> big_float64_buf_ut; + + // unaligned little endian floating point buffers + typedef endian_buffer<order::little, float, 32, align::no> little_float32_buf_ut; + typedef endian_buffer<order::little, double, 64, align::no> little_float64_buf_ut; + + // aligned big endian signed integer buffers + 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, 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, 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, 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; - // aligned big endian signed integer types - typedef endian<order::big, int16_t, 16, align::yes> big_int16_t; - typedef endian<order::big, int32_t, 32, align::yes> big_int32_t; - typedef endian<order::big, int64_t, 64, align::yes> big_int64_t; - - // aligned big endian unsigned integer types - typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_t; - typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_t; - typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_t; - - // aligned little endian signed integer types - typedef endian<order::little, int16_t, 16, align::yes> little_int16_t; - typedef endian<order::little, int32_t, 32, align::yes> little_int32_t; - typedef endian<order::little, int64_t, 64, align::yes> little_int64_t; - - // aligned little endian unsigned integer types - typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_t; - typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_t; - typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_t; - // aligned native endian typedefs are not provided because - // <cstdint> types are superior for that use case + // <cstdint> types are superior for this use case - // unaligned big endian signed integer types - typedef endian<order::big, int_least8_t, 8> big_int8_ut; - typedef endian<order::big, int_least16_t, 16> big_int16_ut; - typedef endian<order::big, int_least32_t, 24> big_int24_ut; - typedef endian<order::big, int_least32_t, 32> big_int32_ut; - typedef endian<order::big, int_least64_t, 40> big_int40_ut; - typedef endian<order::big, int_least64_t, 48> big_int48_ut; - typedef endian<order::big, int_least64_t, 56> big_int56_ut; - typedef endian<order::big, int_least64_t, 64> big_int64_ut; + // unaligned big endian signed integer buffers + typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_ut; + typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_ut; + typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_ut; + typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_ut; + typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_ut; + typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_ut; + typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_ut; + typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_ut; - // unaligned big endian unsigned integer types - typedef endian<order::big, uint_least8_t, 8> big_uint8_ut; - typedef endian<order::big, uint_least16_t, 16> big_uint16_ut; - typedef endian<order::big, uint_least32_t, 24> big_uint24_ut; - typedef endian<order::big, uint_least32_t, 32> big_uint32_ut; - typedef endian<order::big, uint_least64_t, 40> big_uint40_ut; - typedef endian<order::big, uint_least64_t, 48> big_uint48_ut; - typedef endian<order::big, uint_least64_t, 56> big_uint56_ut; - typedef endian<order::big, uint_least64_t, 64> big_uint64_ut; + // unaligned big endian unsigned integer buffers + typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_ut; + typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_ut; + typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_ut; + typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_ut; + typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_ut; + typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_ut; + typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_ut; + typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_ut; - // unaligned little endian signed integer types - typedef endian<order::little, int_least8_t, 8> little_int8_ut; - typedef endian<order::little, int_least16_t, 16> little_int16_ut; - typedef endian<order::little, int_least32_t, 24> little_int24_ut; - typedef endian<order::little, int_least32_t, 32> little_int32_ut; - typedef endian<order::little, int_least64_t, 40> little_int40_ut; - typedef endian<order::little, int_least64_t, 48> little_int48_ut; - typedef endian<order::little, int_least64_t, 56> little_int56_ut; - typedef endian<order::little, int_least64_t, 64> little_int64_ut; + // unaligned little endian signed integer buffers + typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_ut; + typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_ut; + typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_ut; + typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_ut; + typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_ut; + typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_ut; + typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_ut; + typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_ut; - // unaligned little endian unsigned integer types - typedef endian<order::little, uint_least8_t, 8> little_uint8_ut; - typedef endian<order::little, uint_least16_t, 16> little_uint16_ut; - typedef endian<order::little, uint_least32_t, 24> little_uint24_ut; - typedef endian<order::little, uint_least32_t, 32> little_uint32_ut; - typedef endian<order::little, uint_least64_t, 40> little_uint40_ut; - typedef endian<order::little, uint_least64_t, 48> little_uint48_ut; - typedef endian<order::little, uint_least64_t, 56> little_uint56_ut; - typedef endian<order::little, uint_least64_t, 64> little_uint64_ut; + // unaligned little endian unsigned integer buffers + typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_ut; + typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_ut; + typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_ut; + typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_ut; + typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_ut; + typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_ut; + typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_ut; + typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_ut; - // unaligned native endian signed integer types - typedef implementation-defined_int8_t native_int8_ut; - typedef implementation-defined_int16_t native_int16_ut; - typedef implementation-defined_int24_t native_int24_ut; - typedef implementation-defined_int32_t native_int32_ut; - typedef implementation-defined_int40_t native_int40_ut; - typedef implementation-defined_int48_t native_int48_ut; - typedef implementation-defined_int56_t native_int56_ut; - typedef implementation-defined_int64_t native_int64_ut; + // unaligned native endian signed integer types + typedef implementation-defined_int8_buf_ut native_int8_buf_ut; + typedef implementation-defined_int16_buf_ut native_int16_buf_ut; + typedef implementation-defined_int24_buf_ut native_int24_buf_ut; + typedef implementation-defined_int32_buf_ut native_int32_buf_ut; + typedef implementation-defined_int40_buf_ut native_int40_buf_ut; + typedef implementation-defined_int48_buf_ut native_int48_buf_ut; + typedef implementation-defined_int56_buf_ut native_int56_buf_ut; + typedef implementation-defined_int64_buf_ut native_int64_buf_ut; + + // unaligned native endian unsigned integer types + typedef implementation-defined_uint8_buf_ut native_uint8_buf_ut; + typedef implementation-defined_uint16_buf_ut native_uint16_buf_ut; + typedef implementation-defined_uint24_buf_ut native_uint24_buf_ut; + typedef implementation-defined_uint32_buf_ut native_uint32_buf_ut; + typedef implementation-defined_uint40_buf_ut native_uint40_buf_ut; + typedef implementation-defined_uint48_buf_ut native_uint48_buf_ut; + typedef implementation-defined_uint56_buf_ut native_uint56_buf_ut; + typedef implementation-defined_uint64_buf_ut native_uint64_buf_ut; - // unaligned native endian unsigned integer types - typedef implementation-defined_uint8_t native_uint8_ut; - typedef implementation-defined_uint16_t native_uint16_ut; - typedef implementation-defined_uint24_t native_uint24_ut; - typedef implementation-defined_uint32_t native_uint32_ut; - typedef implementation-defined_uint40_t native_uint40_ut; - typedef implementation-defined_uint48_t native_uint48_ut; - typedef implementation-defined_uint56_t native_uint56_ut; - typedef implementation-defined_uint64_t native_uint64_ut; } // namespace endian } // namespace boost -

The implementation-defined text above is either -big or little according to the endianness of the +

The implementation-defined text in typedefs above is either +big or little according to the native endianness of the platform.

+

The expository data member endian_value stores the current value +of an endian_value object as a sequence of bytes ordered as +specified by the Order template parameter.  The +implementation-defined type of endian_value is a +type such as char[Nbits/CHAR_BIT] +or T that meets the +requirements imposed by the Nbits and Align template +parameters.  The CHAR_BIT +macro is defined in <climits>. +The only value of CHAR_BIT that +is required to be supported is 8.

Members

-
endian() = default;  // C++03: endian(){}
+
endian_buffer() = default;  // C++03: endian(){}
-

Effects: Constructs an object of type endian<E, T, n_bits, A>.

+

Effects: Constructs an object of type endian_buffer<Order, T, +Nbits, Align>.

-
endian(T v);
+
explicit endian_buffer(T v);
-

Effects: Constructs an object of type endian<E, T, n_bits, A>.

-

Postcondition: x == v, where x is the -constructed object.

+

Effects: Constructs an object of type endian_buffer<Order, T, +Nbits, Align>.

+

Postcondition: value() == v.

-
endian& operator=(T v);
+
endian_buffer& operator=(T v);
-

Postcondition: x == v, where x is the - constructed object.

+

Postcondition: value() == v.

Returns: *this.

-
operator T() const;
+
value_type value() const;

Returns: The current value stored in *this, converted to value_type.

@@ -555,32 +519,6 @@ constructed object.

Returns: A pointer to the first byte of the endian binary value stored in *this.

-

Other operators

-

Other operators on endian objects are forwarded to the equivalent -operator on value_type.

-

Stream inserter

-
template <class charT, class traits>
-friend std::basic_ostream<charT, traits>&
-  operator<<(std::basic_ostream<charT, traits>& os, const T& x);
-
-
-

Returns: os << +x.

-
-

Stream extractor

-
template <class charT, class traits>
-friend std::basic_istream<charT, traits>&
-  operator>>(std::basic_istream<charT, traits>& is, T& x);
-
-
-

Effects: As if:

-
-
T i;
-if (is >> i)
-  x = i;
-
-
-

Returns: is.

-

FAQ

See the Endian home page FAQ for a library-wide @@ -614,7 +552,7 @@ incrementing a variable in a record. It is very convenient to write:

    int temp(record.foo);
     ++temp;
     record.foo = temp;
-

Design considerations for Boost.Endian types

+

Design considerations for Boost.Endian buffers

-

Experience

-

Classes with similar functionality have been independently developed by -several Boost programmers and used very successful in high-value, high-use -applications for many years. These independently developed endian libraries -often evolved from C libraries that were also widely used. Endian types have proven widely useful across a wide -range of computer architectures and applications.

-

Motivating use cases

-

Neil Mayhew writes: "I can also provide a meaningful use-case for this -library: reading TrueType font files from disk and processing the contents. The -data format has fixed endianness (big) and has unaligned values in various -places. Using Boost.Endian simplifies and cleans the code wonderfully."

C++11

The availability of the C++11 @@ -668,17 +595,9 @@ any Boost object libraries.

In C++11, class endian objects are POD's even though they have constructors. -

Acknowledgements

-

Original design developed by Darin Adler based on classes developed by Mark -Borgerding. Four original class templates combined into a single endian -class template by Beman Dawes, who put the library together, provided -documentation, added the typedefs, and also added the unrolled_byte_loops -sign partial specialization to correctly extend the sign when cover integer size -differs from endian representation size. Vicente Botet and other reviewers -suggested supporting floating point types.


Last revised: -27 November, 2014

+05 December, 2014

© Copyright Beman Dawes, 2006-2009, 2013

Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt