diff options
Diffstat (limited to 'libs/endian/doc')
-rw-r--r-- | libs/endian/doc/arithmetic.html | 643 | ||||
-rw-r--r-- | libs/endian/doc/bikeshed.txt | 79 | ||||
-rw-r--r-- | libs/endian/doc/buffers.html | 614 | ||||
-rw-r--r-- | libs/endian/doc/choosing_approach.html | 412 | ||||
-rw-r--r-- | libs/endian/doc/conversion.html | 371 | ||||
-rw-r--r-- | libs/endian/doc/fp_concerns.html | 97 | ||||
-rw-r--r-- | libs/endian/doc/index.html | 616 | ||||
-rw-r--r-- | libs/endian/doc/mini_review_topics.html | 150 | ||||
-rw-r--r-- | libs/endian/doc/msvc_readme.txt | 31 | ||||
-rw-r--r-- | libs/endian/doc/publish.bat | 8 | ||||
-rw-r--r-- | libs/endian/doc/styles.css | 20 | ||||
-rw-r--r-- | libs/endian/doc/todo_list.html | 106 |
12 files changed, 3147 insertions, 0 deletions
diff --git a/libs/endian/doc/arithmetic.html b/libs/endian/doc/arithmetic.html new file mode 100644 index 000000000..1066d14b0 --- /dev/null +++ b/libs/endian/doc/arithmetic.html @@ -0,0 +1,643 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Endian Arithmetic Types</title> +<link href="styles.css" rel="stylesheet"> +</style> +</head> + +<body> + + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> + <td align="middle"> + <b> + <font size="6">Endian Arithmetic Types</font> </b> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> + +<p></p> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> + <a href="#Introduction">Introduction</a><br> + <a href="#Example">Example</a><br> + <a href="#Limitations">Limitations</a><br> + <a href="#Feature-set">Feature set</a><br> + <a href="#Types">Enums and typedefs</a><br> + <a href="#Class_template_endian">Class template <code>endian</code></a><br> + + <a href="#Synopsis">Synopsis</a><br> + <a href="#Members">Members</a><br> + <a href="#Stream-inserter">Stream inserter</a><br> + <a href="#Stream-extractor">Stream extractor</a><br> + <a href="#FAQ">FAQ</a><br> + <a href="#Design">Design</a><br> + <a href="#Experience">Experience</a><br> + <a href="#Motivating-use-cases">Motivating use cases</a><br> + <a href="#C++0x">C++11</a><br> + <a href="#Compilation">Compilation</a><br> + <a href="#Acknowledgements">Acknowledgements</a> + </td> + </tr> + </table> +<h2><a name="Introduction">Introduction</a></h2> +<p>Header <a href="arithmetic.html">boost/endian/arithmetic.hpp</a> +provides integer binary types with control over +byte order, value type, size, and alignment. Typedefs provide easy-to-use names +for common configurations.</p> +<p>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 +also be used to reduce memory use, file size, or network activity since they +provide binary integer sizes not otherwise available.</p> +<p>Such integer byte-holder types are traditionally called <b><i> +endian</i></b> types. See the +<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for +a full +exploration of <b><i>endianness</i></b>, including definitions of <i><b>big +endian</b></i> and <i><b>little endian</b></i>.</p> +<p>Boost endian integers provide the same full set of C++ assignment, +arithmetic, and relational operators as C++ standard integral types, with +the standard semantics.</p> +<p>Unary arithmetic operators are <b> <code><font face="Courier New">+</font></code></b>, +<b> <code>-</code></b>, <b> <code>~</code></b>, <b> +<code>!</code></b>, plus both prefix and postfix <b> <code>--</code></b> and <b> <code>++</code></b>. Binary +arithmetic operators are <b> <code>+</code></b>, <b> <code>+=</code></b>, <b> <code>-</code></b>, +<b> <code> +-=</code></b>, <b> <code>*</code></b>, <b> <code>*=</code></b>, <b> <code>/</code></b>, +<b> <code>/=</code></b>, <b> <code>&</code></b>, <b> <code>&=</code></b>, +<b> <code>|</code></b>, <b> <code>|=</code></b>, <b> +<code>^</code></b>, <b> <code>^=</code></b>, <b> <code><<</code></b>, <b> <code><<=</code></b>, <code> +<b>>></b></code>, and <b> +<code>>>=</code></b>. Binary relational operators are <b> <code>==</code></b>, +<b> <code>!=</code></b>, <b> +<code><</code></b>, <b> <code><=</code></b>, <b> <code>></code></b>, +and <b> <code>>=</code></b>.</p> +<p>Implicit conversion to the underlying value type is provided. An implicit +constructor converting from the underlying value type is provided. </p> +<h2><a name="Example">Example</a></h2> +<p>The <a href="../example/endian_example.cpp">endian_example.cpp</a> program writes a +binary file containing four-byte, big-endian and little-endian integers:</p> +<blockquote> + <pre>#include <iostream> +#include <cstdio> +#include <boost/endian/arithmetic.hpp> +#include <boost/static_assert.hpp> + +using namespace boost::endian; + +namespace +{ + // 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; + }; + + const char* filename = "test.dat"; +} + +int main(int, char* []) +{ + header h; + + BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check + + h.file_code = 0x01020304; + h.file_length = sizeof(header); + h.version = 1; + h.shape_type = 0x01020304; + + // Low-level I/O such as POSIX read/write or <cstdio> + // fread/fwrite is sometimes used for binary file operations + // when ultimate efficiency is important. Such I/O is often + // performed in some C++ wrapper class, but to drive home the + // point that endian integers are often used in fairly + // low-level code that does bulk I/O operations, <cstdio> + // fopen/fwrite is used for I/O in this example. + + std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY + + if (!fi) + { + std::cout << "could not open " << filename << '\n'; + return 1; + } + + if (std::fwrite(&h, sizeof(header), 1, fi)!= 1) + { + std::cout << "write failure for " << filename << '\n'; + return 1; + } + + std::fclose(fi); + + std::cout << "created file " << filename << '\n'; + + return 0; +} +</pre> +</blockquote> +<p>After compiling and executing <a href="../example/endian_example.cpp">endian_example.cpp</a>, +a hex dump of <code>test.dat</code> shows:</p> +<blockquote> + <pre>01020304 00000010 01000000 04030201</pre> +</blockquote> +<p>Notice that the first two 32-bit integers are big endian while the second two +are little endian, even though the machine this was compiled and run on was +little endian.</p> +<h2><a name="Limitations">Limitations</a></h2> +<p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code> +is some other value, compilation will result in an <code>#error</code>. 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.</p> +<p>In C++03, <code>endian_arithmetic</code> 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 lay out memory as if <code> +endian</code> were a POD type. In C++11, it is possible to specify the +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, <code>endian_arithmetic</code> +will no longer be relying on unspecified behavior.</p> +<h2><a name="Feature-set">Feature set</a></h2> +<ul> + <li>Big endian| little endian | native endian byte ordering.</li> + <li>Signed | unsigned</li> + <li>Unaligned | aligned</li> + <li>1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)</li> + <li>Choice of value type</li> +</ul> +<h2>Enums and t<a name="Types">ypedefs</a></h2> +<p>Two scoped enums are provided:</p> +<blockquote> + <pre>enum class order {big, little, native}; + +enum class align {no, yes}; </pre> +</blockquote> +<p>One class template is provided:</p> +<blockquote> + <pre>template <order Order, typename T, std::size_t n_bits, + align Align = align::no> +class endian_arithmetic; +</pre> +</blockquote> +<p>Typedefs, such as <code>big_int32_t</code>, provide convenient naming +conventions for common use cases:</p> +<blockquote> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%"> + <tr> + <td width="18%" align="center"><b><i>Name</i></b></td> + <td width="49%" align="center"><b><i>Alignment</i></b></td> + <td width="10%" align="center"><b><i>Endianness</i></b></td> + <td width="10%" align="center"><b><i>Sign</i></b></td> + <td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td> + </tr> + <tr> + <td width="18%"><code>big_int</code><b><i>n</i></b><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>big_uint</code><i><b>n</b></i><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>little_int</code><i><b>n</b></i><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>little_uint</code><i><b>n</b></i><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>native_int</code><i><b>n</b></i><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>native</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>native_uint</code><i><b>n</b></i><code>_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>native</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>big_int</code><i><b>n</b></i><code>_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,32,64</td> + </tr> + <tr> + <td width="18%"><code>big_uint</code><i><b>n</b></i><code>_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,32,64</td> + </tr> + <tr> + <td width="18%" dir="ltr"><code>little_int</code><i><b>n</b></i><code>_at</code></td> + <td width="49%" align="center" dir="ltr"><code>yes</code></td> + <td width="10%" align="center" dir="ltr"><code>little</code></td> + <td width="10%" align="center" dir="ltr">signed</td> + <td width="15%" dir="ltr">8,16,32,64</td> + </tr> + <tr> + <td width="18%" dir="ltr"><code>little_uint</code><i><b>n</b></i><code>_at</code></td> + <td width="49%" align="center" dir="ltr"><code>yes</code></td> + <td width="10%" align="center" dir="ltr"><code>little</code></td> + <td width="10%" align="center" dir="ltr">unsigned</td> + <td width="15%" dir="ltr">8,16,32,64</td> + </tr> + </table> +</blockquote> +<p>The unaligned types do not cause compilers to insert padding bytes in classes +and structs. This is an important characteristic that can be exploited to minimize wasted space in +memory, files, and network transmissions. </p> +<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF"> +Code that uses a</span>ligned types is possibly non-portable because alignment +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.</p> +<p><i><b>Recommendation:</b></i> Prefer unaligned arithmetic types.</p> +<p><i><b>Recommendation:</b></i> Protect yourself against alignment ills. For +example:</p> +<blockquote> + <pre>static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong"); </pre> +</blockquote> +<p><b><i>Note:</i></b> <b><i>Note:</i></b> 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.</p> +<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_arithmetic</code></h2> +<p>An endian is an integer byte-holder with user-specified <a href="#endianness"> +endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The +usual operations on integers are supplied.</p> +<h3><a name="Synopsis">Synopsis</a></h3> +<pre>namespace boost +{ + namespace endian + { + // C++11 features emulated if not available + + enum class <a name="order">order</a> + { + big, // big-endian + little, // little-endian + native = <b><i>implementation-defined</i></b> // same as order::big or order::little<b><i> + </i></b>}; + + enum class <a name="alignment">align</a> {no, yes}; + + template <order Order, class T, std::size_t n_bits, + align Align = align::no> + class endian_arithmetic + : public endian_buffer<Order, T, n_bits, Align> + { + public: + typedef T value_type; + + // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 PODs are not + // available then these two constructors will not be present + <a href="#endian">endian_arithmetic</a>() noexcept = default; + <a href="#explicit-endian">endian_arithmetic</a>(T v) noexcept; + + endian_arithmetic& <a href="#operator-eq">operator=</a>(T v) noexcept; + <a href="#operator-T">operator value_type</a>() const noexcept; + value_type value() const noexcept; // for exposition; see endian_buffer + const char* <a href="#data">data</a>() const noexcept; // for exposition; see endian_buffer + + // 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); + }; + + // typedefs + + // unaligned big endian signed integer types + typedef endian<order::big, int_least8_t, 8> big_int8_t; + typedef endian<order::big, int_least16_t, 16> big_int16_t; + typedef endian<order::big, int_least32_t, 24> big_int24_t; + typedef endian<order::big, int_least32_t, 32> big_int32_t; + typedef endian<order::big, int_least64_t, 40> big_int40_t; + typedef endian<order::big, int_least64_t, 48> big_int48_t; + typedef endian<order::big, int_least64_t, 56> big_int56_t; + typedef endian<order::big, int_least64_t, 64> big_int64_t; + + // unaligned big endian unsigned integer types + typedef endian<order::big, uint_least8_t, 8> big_uint8_t; + typedef endian<order::big, uint_least16_t, 16> big_uint16_t; + typedef endian<order::big, uint_least32_t, 24> big_uint24_t; + typedef endian<order::big, uint_least32_t, 32> big_uint32_t; + typedef endian<order::big, uint_least64_t, 40> big_uint40_t; + typedef endian<order::big, uint_least64_t, 48> big_uint48_t; + typedef endian<order::big, uint_least64_t, 56> big_uint56_t; + typedef endian<order::big, uint_least64_t, 64> big_uint64_t; + + // unaligned little endian signed integer types + typedef endian<order::little, int_least8_t, 8> little_int8_t; + typedef endian<order::little, int_least16_t, 16> little_int16_t; + typedef endian<order::little, int_least32_t, 24> little_int24_t; + typedef endian<order::little, int_least32_t, 32> little_int32_t; + typedef endian<order::little, int_least64_t, 40> little_int40_t; + typedef endian<order::little, int_least64_t, 48> little_int48_t; + typedef endian<order::little, int_least64_t, 56> little_int56_t; + typedef endian<order::little, int_least64_t, 64> little_int64_t; + + // unaligned little endian unsigned integer types + typedef endian<order::little, uint_least8_t, 8> little_uint8_t; + typedef endian<order::little, uint_least16_t, 16> little_uint16_t; + typedef endian<order::little, uint_least32_t, 24> little_uint24_t; + typedef endian<order::little, uint_least32_t, 32> little_uint32_t; + typedef endian<order::little, uint_least64_t, 40> little_uint40_t; + typedef endian<order::little, uint_least64_t, 48> little_uint48_t; + typedef endian<order::little, uint_least64_t, 56> little_uint56_t; + typedef endian<order::little, uint_least64_t, 64> little_uint64_t; + + // unaligned native endian signed integer types + typedef <b><i>implementation-defined</i></b>_int8_t native_int8_t; + typedef <b><i>implementation-defined</i></b>_int16_t native_int16_t; + typedef <b><i>implementation-defined</i></b>_int24_t native_int24_t; + typedef <b><i>implementation-defined</i></b>_int32_t native_int32_t; + typedef <b><i>implementation-defined</i></b>_int40_t native_int40_t; + typedef <b><i>implementation-defined</i></b>_int48_t native_int48_t; + typedef <b><i>implementation-defined</i></b>_int56_t native_int56_t; + typedef <b><i>implementation-defined</i></b>_int64_t native_int64_t; + + // unaligned native endian unsigned integer types + typedef <b><i>implementation-defined</i></b>_uint8_t native_uint8_t; + typedef <b><i>implementation-defined</i></b>_uint16_t native_uint16_t; + typedef <b><i>implementation-defined</i></b>_uint24_t native_uint24_t; + typedef <b><i>implementation-defined</i></b>_uint32_t native_uint32_t; + typedef <b><i>implementation-defined</i></b>_uint40_t native_uint40_t; + typedef <b><i>implementation-defined</i></b>_uint48_t native_uint48_t; + typedef <b><i>implementation-defined</i></b>_uint56_t native_uint56_t; + typedef <b><i>implementation-defined</i></b>_uint64_t native_uint64_t; + + // aligned big endian signed integer types + typedef endian<order::big, int8_t, 8, align::yes> big_int8_at; + typedef endian<order::big, int16_t, 16, align::yes> big_int16_at; + typedef endian<order::big, int32_t, 32, align::yes> big_int32_at; + typedef endian<order::big, int64_t, 64, align::yes> big_int64_at; + + // aligned big endian unsigned integer types + typedef endian<order::big, uint8_t, 8, align::yes> big_uint8_at; + typedef endian<order::big, uint16_t, 16, align::yes> big_uint16_at; + typedef endian<order::big, uint32_t, 32, align::yes> big_uint32_at; + typedef endian<order::big, uint64_t, 64, align::yes> big_uint64_at; + + // aligned little endian signed integer types + typedef endian<order::little, int8_t, 8, align::yes> little_int8_at; + typedef endian<order::little, int16_t, 16, align::yes> little_int16_at; + typedef endian<order::little, int32_t, 32, align::yes> little_int32_at; + typedef endian<order::little, int64_t, 64, align::yes> little_int64_at; + + // aligned little endian unsigned integer types + typedef endian<order::little, uint8_t, 8, align::yes> little_uint8_at; + typedef endian<order::little, uint16_t, 16, align::yes> little_uint16_at; + typedef endian<order::little, uint32_t, 32, align::yes> little_uint32_at; + typedef endian<order::little, uint64_t, 64, align::yes> little_uint64_at; + + // aligned native endian typedefs are not provided because + // <cstdint> types are superior for that use case + + } // namespace endian +} // namespace boost</pre> +<p>The <i><b><code>implementation-defined</code></b></i> text above is either +<code>big</code> or <code>little</code> according to the endianness of the +platform.</p> +<h3><a name="Members">Members</a></h3> +<div dir="ltr"> + <pre><code><a name="endian">endian</a>() = default; // C++03: endian(){}</code></pre> +</div> +<blockquote> +<p><i>Effects:</i> Constructs an uninitialized object of type <code>endian_arithmetic<E, T, n_bits, A></code>.</p> +</blockquote> +<pre><code><a name="explicit-endian">endian</a>(T v);</code></pre> +<blockquote> +<p><i>Effects:</i> Constructs an object of type <code>endian_arithmetic<E, T, n_bits, A></code>.</p> +<p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the +constructed object.</p> +</blockquote> +<pre><code>endian& <a name="operator-eq">operator=</a>(T v);</code></pre> +<blockquote> + <p><i>Postcondition:</i> <code>x == v,</code> where <code>x</code> is the + constructed object.</p> + <p><i>Returns:</i> <code>*this</code>.</p> +</blockquote> +<pre><code><a name="operator-T">operator T</a>() const;</code></pre> +<blockquote> +<p><i>Returns:</i> The current value stored in <code>*this</code>, converted to +<code>value_type</code>.</p> +</blockquote> +<pre><code>const char* <a name="data">data</a>() const;</code></pre> +<blockquote> +<p><i>Returns:</i> A pointer to the first byte of the endian binary value stored +in <code>*this</code>.</p> +</blockquote> +<h3>Other operators</h3> +<p>Other operators on endian objects are forwarded to the equivalent +operator on <code>value_type</code>.</p> +<h3><a name="Stream-inserter">Stream inserter</a></h3> +<pre>template <class charT, class traits> +friend std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& os, const T& x); +</pre> +<blockquote> +<p><i>Returns:</i> <code>os << +x</code>.</p> +</blockquote> +<h3><a name="Stream-extractor">Stream extractor</a></h3> +<pre>template <class charT, class traits> +friend std::basic_istream<charT, traits>& + operator>>(std::basic_istream<charT, traits>& is, T& x); +</pre> +<blockquote> +<p><i>Effects: </i>As if:</p> + <blockquote> + <pre>T i; +if (is >> i) + x = i; +</pre> + </blockquote> + <p><i>Returns: </i><code>is</code><i>.</i></p> +</blockquote> +<h2><a name="FAQ">FAQ</a></h2> + +<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide +FAQ.</p> + +<p><b>Why not just use Boost.Serialization?</b> 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.</p> +<p><b>Are endian types PODs?</b> Yes for C++11. No for C++03, although several +<a href="#Compilation">macros</a> are available to force PODness in all cases.</p> +<p><b>What are the implications of endian integer types not being PODs with C++03 +compilers?</b> They +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.</p> +<p><b>What good is <i>native </i>endianness?</b> It provides alignment and +size guarantees not available from the built-in types. It eases generic +programming.</p> +<p><b>Why bother with the aligned endian types?</b> Aligned integer operations +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, will be somewhat less portable than with the unaligned types.</p> +<p><b>Why provide the arithmetic operations?</b> 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:</p> +<pre wrap> ++record.foo;</pre> +<p wrap>Rather than:</p> +<pre wrap> int temp(record.foo); + ++temp; + record.foo = temp;</pre> +<h2><a name="Design">Design</a> considerations for Boost.Endian types</h2> +<ul> + <li>Must be suitable for I/O - in other words, must be memcpyable.</li> + <li>Must provide exactly the size and internal byte ordering specified.</li> + <li>Must work correctly when the internal integer representation has more bits + that the sum of the bits in the external byte representation. Sign extension + must work correctly when the internal integer representation type has more + bits than the sum of the bits in the external bytes. For example, using + a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for + both positive and negative values.</li> + <li>Must work correctly (including using the same defined external + representation) regardless of whether a compiler treats char as signed or + unsigned.</li> + <li>Unaligned types must not cause compilers to insert padding bytes.</li> + <li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian + integers often become pessimizations when changing + machines or compilers. Pessimizations can also happen when changing compiler switches, + compiler versions, or CPU models of the same architecture.</li> +</ul> +<h2><a name="Experience">Experience</a></h2> +<p>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.</p> +<h2><a name="Motivating-use-cases">Motivating use cases</a></h2> +<p>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."</p> +<h2><a name="C++0x">C++11</a></h2> +<p>The availability of the C++11 +<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> +Defaulted Functions</a> feature is detected automatically, and will be used if +present to ensure that objects of <code>class endian_arithmetic</code> are trivial, and +thus PODs.</p> +<h2><a name="Compilation">Compilation</a></h2> +<p>Boost.Endian is implemented entirely within headers, with no need to link to +any Boost object libraries.</p> +<p>Several macros allow user control over features:</p> +<ul> + <li>BOOST_ENDIAN_NO_CTORS causes <code>class endian_arithmetic</code> to have no + constructors. The intended use is for compiling user code that must be + portable between compilers regardless of C++11 + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> + Defaulted Functions</a> support. Use of constructors will always fail, <br> + </li> + <li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if + the compiler does not support C++11 + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> + Defaulted Functions</a>. This is ensures that objects of <code>class endian_arithmetic</code> + are PODs, and so can be used in C++03 unions. + In C++11, <code>class endian_arithmetic</code> objects are PODs, even though they have + constructors, so can always be used in unions.</li> +</ul> +<h2><a name="Acknowledgements">Acknowledgements</a></h2> +<p>Original design developed by Darin Adler based on classes developed by Mark +Borgerding. Four original class templates combined into a single <code>endian_arithmetic</code> +class template by Beman Dawes, who put the library together, provided +documentation, added the typedefs, and also added the <code>unrolled_byte_loops</code> +sign partial specialization to correctly extend the sign when cover integer size +differs from endian representation size.</p> +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->25 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28920" --></p> +<p>© Copyright Beman Dawes, 2006-2009, 2013</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/bikeshed.txt b/libs/endian/doc/bikeshed.txt new file mode 100644 index 000000000..da1700188 --- /dev/null +++ b/libs/endian/doc/bikeshed.txt @@ -0,0 +1,79 @@ +Conversion function naming bikeshed + +return-by-value modify-argument +------------------ --------------- + +reverse_endianness reverse_endianness_in_place + " reverse_endianness_arg +endian_reverse endian_reverse_in_place + " endian_reverse_inplace + " endian_reverse_replace + " endian_reverse_in_situ + " endian_reverse_here + " endian_reverse_this + " endian_reverse_self + " endian_reverse_arg + " endian_reverse_in + +reverse reverse_in_place +reverse_endian reverse_endian_in_place + +swap_endianness swap_endianness_in_place +swap_endian swap_endian_in_place +endian_swap endian_swap_this + +flip_endianness flip_endianness_in_place +flip_endian flip_endian_in_place +endian_flip endian_flip_in_place + + +reverse_order reverse_order_in_place + + +Key points: + +* The above names are defined in a user namespace as customization points to be found by + ADL, and so cannot depend on the enclosing namespace name to signal readers that they + are related to endianness. +* The above functions are rarely called directly by user code, which is more likely to use + the various conditional functions instead. So explicitness is more important than + brevity. + +Conditional names + +big_to_native native_to_big little_to_native native_to_little + +big_to_host host_to_big + +be_to_ne ne_to_be + +from_big, to_big + +big_to_native big_to_native +native_to_big native_to_big + +conditional_reverse runtime_conditional_reverse +conditional_reverse conditional_reverse <------ + +merriam-webster.com/dictionary + +reverse [1] (adjective): opposite or contrary to a previous or normal condition <reverse order> +reverse [2] (verb) : to change (something) to an opposite state or condition + +swap (verb) : to give something to someone and receive something in return : to trade or exchange (things) + +flip (verb) + +: to turn (something) over by throwing it up in the air with a quick movement + +: to cause (something) to turn or turn over quickly + +: to move (something) with a quick light movement + +-------------------------------------------------- + +Copyright Beman Dawes, 2014 +Distributed under the Boost Software License, Version 1.0. +See www.boost.org/LICENSE_1_0.txt + +
\ No newline at end of file diff --git a/libs/endian/doc/buffers.html b/libs/endian/doc/buffers.html new file mode 100644 index 000000000..85aae22e5 --- /dev/null +++ b/libs/endian/doc/buffers.html @@ -0,0 +1,614 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Endian Buffer Types</title> +<link href="styles.css" rel="stylesheet"> +</style> +</head> + +<body> + + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> + <td align="middle"> + <b> + <font size="6">Endian Buffer Types</font> </b> + </td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> + +<p></p> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> + <a href="#Introduction">Introduction</a><br> + <a href="#Example">Example</a><br> + <a href="#Limitations">Limitations</a><br> + <a href="#Feature-set">Feature set</a><br> + <a href="#Types">Enums and typedefs</a><br> + <a href="#Class_template_endian">Class template <code>endian_buffer</code></a><br> + + <a href="#Synopsis">Synopsis</a><br> + <a href="#Members">Members</a><br> + <a href="#Non-member-functions">Non-Members</a><br> + <a href="#FAQ">FAQ</a><br> + <a href="#Design">Design</a><br> + <a href="#C++0x">C++11</a><br> + <a href="#Compilation">Compilation</a></td> + </tr> + </table> +<h2><a name="Introduction">Introduction</a></h2> +<p>The internal byte order of arithmetic types is traditionally called <b><i>endianness</i></b>. See +the +<a href="http://en.wikipedia.org/wiki/Endian" name="endianness">Wikipedia</a> for +a full +exploration of <b><i>endianness</i></b>, including definitions of <i><b>big +endian</b></i> and <i><b>little endian</b></i>.</p> +<p>Header <b><code>boost/endian/buffers.hpp</code></b> +provides <code>endian_buffer</code>, a portable endian integer binary buffer +class template with control over +byte order, value type, size, and alignment independent of the platform's native +endianness. Typedefs provide easy-to-use names +for common configurations.</p> +<p>Use cases primarily involve data portability, either via files or network +connections, but these byte-holders may +also be used to reduce memory use, file size, or network activity since they + +provide binary numeric sizes not otherwise available.</p> +<p dir="ltr">Class <code>endian_buffer</code> is aimed at users who wish +explicit control over when endianness conversions occur. It also serves as the +base class for the <code><a href="arithmetic.html">endian_arithmetic</a></code> +class template, which is aimed at users who wish fully automatic endianness +conversion and direct support for all normal arithmetic operations.</p> +<h2><a name="Example">Example</a></h2> +<p>The <b><code>example/endian_example.cpp</code></b> program writes a +binary file containing four-byte, big-endian and little-endian integers:</p> +<blockquote> + <pre>#include <iostream> +#include <cstdio> +#include <boost/endian/buffers.hpp> // see <a href="#Synopsis">Synopsis</a> below +#include <boost/static_assert.hpp> + +using namespace boost::endian; + +namespace +{ + // 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_<code>buf_</code>t file_code; + big_int32_<code>buf_</code>t file_length; + little_int32_<code>buf_</code>t version; + little_int32_<code>buf_</code>t shape_type; + }; + + const char* filename = "test.dat"; +} + +int main(int, char* []) +{ + header h; + + BOOST_STATIC_ASSERT(sizeof(h) == 16U); // reality check + + h.file_code = 0x01020304; + h.file_length = sizeof(header); + h.version = 1; + h.shape_type = 0x01020304; + + // Low-level I/O such as POSIX read/write or <cstdio> + // fread/fwrite is sometimes used for binary file operations + // when ultimate efficiency is important. Such I/O is often + // performed in some C++ wrapper class, but to drive home the + // point that endian integers are often used in fairly + // low-level code that does bulk I/O operations, <cstdio> + // fopen/fwrite is used for I/O in this example. + + std::FILE* fi = std::fopen(filename, "wb"); // MUST BE BINARY + + if (!fi) + { + std::cout << "could not open " << filename << '\n'; + return 1; + } + + if (std::fwrite(&h, sizeof(header), 1, fi)!= 1) + { + std::cout << "write failure for " << filename << '\n'; + return 1; + } + + std::fclose(fi); + + std::cout << "created file " << filename << '\n'; + + return 0; +} +</pre> +</blockquote> +<p>After compiling and executing <b><code>example/endian_example.cpp</code></b>, +a hex dump of <code>test.dat</code> shows:</p> +<blockquote> + <pre>01020304 00000010 01000000 04030201</pre> +</blockquote> +<p>Notice that the first two 32-bit integers are big endian while the second two +are little endian, even though the machine this was compiled and run on was +little endian.</p> +<h2><a name="Limitations">Limitations</a></h2> +<p>Requires <code><climits></code> <code>CHAR_BIT == 8</code>. If <code>CHAR_BIT</code> +is some other value, compilation will result in an <code>#error</code>. 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.</p> +<p>In C++03, <code>endian_buffer</code> 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 lay out memory as if <code> +endian</code> were a POD type. In C++11, it is possible to specify the +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, <code>endian_buffer</code> +will no longer be relying on unspecified behavior.</p> +<h2><a name="Feature-set">Feature set</a></h2> +<ul> + <li>Big endian| little endian | native endian byte ordering.</li> + <li>Signed | unsigned</li> + <li>Unaligned | aligned</li> + <li>1-8 byte (unaligned) | 1, 2, 4, 8 byte (aligned)</li> + <li>Choice of value type</li> +</ul> +<h2>Enums and t<a name="Types">ypedefs</a></h2> +<p>Two scoped enums are provided:</p> +<blockquote> + <pre>enum class order {big, little, native}; + +enum class align {no, yes}; </pre> +</blockquote> +<p>One class template is provided:</p> +<blockquote> + <pre>template <order Order, typename T, std::size_t Nbits, + align Align = align::no> +class endian_buffer; +</pre> +</blockquote> +<p>Typedefs, such as <code>big_int32_buf_t</code>, provide convenient naming +conventions for common use cases:</p> +<blockquote> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="49%"> + <tr> + <td width="18%" align="center"><b><i>Name</i></b></td> + <td width="49%" align="center"><b><i>Alignment</i></b></td> + <td width="10%" align="center"><b><i>Endianness</i></b></td> + <td width="10%" align="center"><b><i>Sign</i></b></td> + <td width="15%" align="center"><b><i>Sizes in bits (n)</i></b></td> + </tr> + <tr> + <td width="18%" dir="ltr"><code>big_int</code><b><i>n</i></b><code>_buf_t</code></td> + <td width="49%" align="center" dir="ltr"><code>no</code></td> + <td width="10%" align="center" dir="ltr"><code>big</code></td> + <td width="10%" align="center" dir="ltr">signed</td> + <td width="15%" dir="ltr">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%" dir="ltr"><code>big_uint</code><i><b>n</b></i><code>_buf_t</code></td> + <td width="49%" align="center" dir="ltr"><code>no</code></td> + <td width="10%" align="center" dir="ltr"><code>big</code></td> + <td width="10%" align="center" dir="ltr">unsigned</td> + <td width="15%" dir="ltr">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>little_int</code><i><b>n</b></i><code>_buf_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>little_uint</code><i><b>n</b></i><code>_buf_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>native_int</code><i><b>n</b></i><code>_buf_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>native</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>native_uint</code><i><b>n</b></i><code>_buf_t</code></td> + <td width="49%" align="center"><code>no</code></td> + <td width="10%" align="center"><code>native</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,24,32,40,48,56,64</td> + </tr> + <tr> + <td width="18%"><code>big_int</code><i><b>n</b></i><code>_buf_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,32,64</td> + </tr> + <tr> + <td width="18%"><code>big_uint</code><i><b>n</b></i><code>_</code><code>buf_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>big</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,32,64</td> + </tr> + <tr> + <td width="18%"><code>little_int</code><i><b>n</b></i><code>_</code><code>buf_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">signed</td> + <td width="15%">8,16,32,64</td> + </tr> + <tr> + <td width="18%"><code>little_uint</code><i><b>n</b></i><code>_</code><code>buf_at</code></td> + <td width="49%" align="center"><code>yes</code></td> + <td width="10%" align="center"><code>little</code></td> + <td width="10%" align="center">unsigned</td> + <td width="15%">8,16,32,64</td> + </tr> +</table> +</blockquote> +<p>The unaligned types do not cause compilers to insert padding bytes in classes +and structs. This is an important characteristic that can be exploited to minimize wasted space in +memory, files, and network transmissions. </p> +<p><font color="#FF0000"><b><i><span style="background-color: #FFFFFF">Warning:</span></i></b></font><span style="background-color: #FFFFFF"> +Code that uses a</span>ligned types is possibly non-portable because alignment +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 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. </p> +<p><i><b>Recommendation:</b></i> Prefer unaligned buffer types.</p> +<p><i><b>Recommendation:</b></i> Protect yourself against alignment ills. For +example:</p> +<blockquote> + <pre>static_assert(sizeof(containing_struct) == 12, "sizeof(containing_struct) is wrong"); </pre> +</blockquote> +<p><b><i>Note:</i></b> One-byte big and little buffer 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.</p> +<h2><a name="Class_template_endian">Class template <code>endian</code></a><code>_buffer</code></h2> +<p>An <code>endian_buffer</code> is an integer byte-holder with user-specified <a href="#endianness"> +endianness</a>, value type, size, and <a href="#alignment">alignment</a>. The +usual operations on integers are supplied.</p> +<h3><a name="Synopsis">Synopsis</a></h3> +<pre>namespace boost +{ + namespace endian + { + // C++11 features emulated if not available + + enum class <a name="order">order</a> + { + big, // big-endian + little, // little-endian + native = <b><i>implementation-defined</i></b> // same as order::big or order::little<b><i> + </i></b>}; + + enum class <a name="alignment">align</a> {no, yes}; + + template <order Order, class T, std::size_t Nbits, + align Align = align::no> + class endian_buffer + { + public: + typedef T value_type; + + <a href="#endian">endian_buffer</a>() noexcept = default; + explicit <a href="#explicit-endian">endian_buffer</a>(T v) noexcept; + + endian_buffer& <a href="#operator-eq">operator=</a>(T v) noexcept; + value_type <a href="#value">value</a>() const noexcept; + const char* <a href="#data">data</a>() const noexcept; + protected: + <b><i>implementaton-defined</i></b> endian_value; // for exposition only + }; + + // stream inserter + template <class charT, class traits, order Order, class T, + std::size_t n_bits, align Align> + std::basic_ostream<charT, traits>& + <a href="#inserter">operator<<</a>(std::basic_ostream<charT, traits>& os, + const endian_buffer<Order, T, n_bits, Align>& x); + + // stream extractor + template <class charT, class traits, order Order, class T, + std::size_t n_bits, align A> + std::basic_istream<charT, traits>& + <a href="#extractor">operator>></a>(std::basic_istream<charT, traits>& is, + endian_buffer<Order, T, n_bits, Align>& x); + + // typedefs + + // unaligned big endian signed integer buffers + typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t; + typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t; + typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t; + typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t; + typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t; + typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t; + typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t; + typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t; + + // unaligned big endian unsigned integer buffers + typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t; + typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t; + typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t; + typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t; + typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t; + typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t; + typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t; + typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t; + + // unaligned little endian signed integer buffers + typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t; + typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t; + typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t; + typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t; + typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t; + typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t; + typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t; + typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t; + + // unaligned little endian unsigned integer buffers + typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t; + typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t; + typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t; + typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t; + typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t; + typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t; + typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t; + typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t; + + // unaligned native endian signed integer types + typedef <b><i>implementation-defined</i></b>_int8_buf_t native_int8_buf_t; + typedef <b><i>implementation-defined</i></b>_int16_buf_t native_int16_buf_t; + typedef <b><i>implementation-defined</i></b>_int24_buf_t native_int24_buf_t; + typedef <b><i>implementation-defined</i></b>_int32_buf_t native_int32_buf_t; + typedef <b><i>implementation-defined</i></b>_int40_buf_t native_int40_buf_t; + typedef <b><i>implementation-defined</i></b>_int48_buf_t native_int48_buf_t; + typedef <b><i>implementation-defined</i></b>_int56_buf_t native_int56_buf_t; + typedef <b><i>implementation-defined</i></b>_int64_buf_t native_int64_buf_t; + + // unaligned native endian unsigned integer types + typedef <b><i>implementation-defined</i></b>_uint8_buf_t native_uint8_buf_t; + typedef <b><i>implementation-defined</i></b>_uint16_buf_t native_uint16_buf_t; + typedef <b><i>implementation-defined</i></b>_uint24_buf_t native_uint24_buf_t; + typedef <b><i>implementation-defined</i></b>_uint32_buf_t native_uint32_buf_t; + typedef <b><i>implementation-defined</i></b>_uint40_buf_t native_uint40_buf_t; + typedef <b><i>implementation-defined</i></b>_uint48_buf_t native_uint48_buf_t; + typedef <b><i>implementation-defined</i></b>_uint56_buf_t native_uint56_buf_t; + typedef <b><i>implementation-defined</i></b>_uint64_buf_t native_uint64_buf_t; + + // aligned big endian signed integer buffers + typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at; + typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at; + typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at; + typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at; + + // aligned big endian unsigned integer buffers + typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at; + typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at; + typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at; + typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at; + + // aligned little endian signed integer buffers + typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at; + typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at; + typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at; + typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at; + + // aligned little endian unsigned integer buffers + typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at; + typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at; + typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at; + typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at; + + // aligned native endian typedefs are not provided because + // <cstdint> types are superior for this use case + + } // namespace endian +} // namespace boost</pre> +<p>The <i><b><code>implementation-defined</code></b></i> text in typedefs above is either +<code>big</code> or <code>little</code> according to the native endianness of the +platform.</p> +<p>The expository data member <code>endian_value</code> stores the current value +of an <code>endian_value</code> object as a sequence of bytes ordered as +specified by the <code>Order</code> template parameter. The <i><b><code> +implementation-defined</code></b></i> type of <code>endian_value</code> is a +type such as <code><span style="font-size: 85%">char[Nbits/CHAR_BIT]</span></code> +or <code><span style="font-size: 85%">T</span></code> that meets the +requirements imposed by the <code>Nbits</code> and <code>Align</code> template +parameters. The <code><span style="font-size: 85%">CHAR_BIT</span></code> +macro is defined in <code><span style="font-size: 85%"><climits></span></code>. +The only value of <code><span style="font-size: 85%">CHAR_BIT</span></code> that +is required to be supported is 8.</p> +<p>Template parameter <code><span style="font-size: 85%">T</span></code> is +required to be a standard integer type (C++std, 3.9.1) and <code> +<span style="font-size: 85%">sizeof(T)*CHAR_BIT</span></code> is required to be +greater or equal to <span style="font-size: 85%"> <code>Nbits</code>.</span></p> +<h3><a name="Members">Members</a></h3> + <pre><code><a name="endian">endian</a>_buffer() noexcept = default;</code></pre> +<blockquote> +<p><i>Effects:</i> Constructs an uninitialized object of type <code>endian_buffer<Order, T, +Nbits, Align></code>.</p> +</blockquote> +<pre><code>explicit <a name="explicit-endian">endian</a>_buffer(T v) noexcept;</code></pre> +<blockquote> +<p><i>Effects:</i> Constructs an object of type <code>endian_buffer<Order, T, +Nbits, Align></code>.</p> +<p><i>Postcondition:</i> <code>value() == v & mask</code>, where <code>mask</code> +is a constant of type <code>value_type</code> with <code>Nbits</code> low-order +bits set to one.</p> +<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then +endianness conversion, if required, is performed by <code> +boost::endian::endian_reverse</code>.</p> +</blockquote> +<pre><code>endian_buffer& <a name="operator-eq">operator=</a>(T v) noexcept;</code></pre> +<blockquote> + <p><i>Postcondition:</i> <code>value() == v & mask</code>, where <code>mask</code> + is a constant of type <code>value_type</code> with <code>Nbits</code> + low-order bits set to one.</p> + <p><i>Returns:</i> <code>*this</code>.</p> +<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then +endianness conversion, if required, is performed by <code> +boost::endian::endian_reverse</code>.</p> +</blockquote> +<pre>value_type <a name="value">value</a>()<code> const noexcept;</code></pre> +<blockquote> +<p><i>Returns:</i> <code>endian_value</code>, converted to <code>value_type</code>, +if required, and having the endianness of the native platform.</p> +<p><i>Remarks:</i> If <code>Align</code> is <code>align::yes</code> then +endianness conversion, if required, is performed by <code> +boost::endian::endian_reverse</code>.</p> +</blockquote> +<pre><code>const char* <a name="data">data</a>() const noexcept;</code></pre> +<blockquote> +<p><i>Returns:</i> A pointer to the first byte of <code>endian_value</code>.</p> +</blockquote> +<h3><a name="Non-member-functions">Non-member functions</a></h3> +<pre>template <class charT, class traits, order Order, class T, + std::size_t n_bits, align Align> +std::basic_ostream<charT, traits>& <a name="inserter">operator<<</a>(std::basic_ostream<charT, traits>& os, + const endian_buffer<Order, T, n_bits, Align>& x); +</pre> +<blockquote> + <p><i>Returns:</i> <code>os << x.value()</code>.</p> +</blockquote> +<pre>template <class charT, class traits, order Order, class T, + std::size_t n_bits, align A> +std::basic_istream<charT, traits>& <a name="extractor">operator>></a>(std::basic_istream<charT, traits>& is, + endian_buffer<Order, T, n_bits, Align>& x); +</pre> +<blockquote> + <p><i>Effects: </i>As if:</p> + <blockquote> + <pre>T i; +if (is >> i) + x = i; +</pre> + </blockquote> + <p><i>Returns:</i> <code>is</code>.</p> +</blockquote> +<h2><a name="FAQ">FAQ</a></h2> + +<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide +FAQ.</p> + +<p><b>Why not just use Boost.Serialization?</b> 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.</p> +<p><b>Are endian types PODs?</b> Yes for C++11. No for C++03, although several +<a href="#Compilation">macros</a> are available to force PODness in all cases.</p> +<p><b>What are the implications of endian integer types not being PODs with C++03 +compilers?</b> They +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.</p> +<p><b>What good is <i>native </i>endianness?</b> It provides alignment and +size guarantees not available from the built-in types. It eases generic +programming.</p> +<p><b>Why bother with the aligned endian types?</b> Aligned integer operations +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.</p> +<p><b>Why provide the arithmetic operations?</b> 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:</p> +<pre wrap> ++record.foo;</pre> +<p wrap>Rather than:</p> +<pre wrap> int temp(record.foo); + ++temp; + record.foo = temp;</pre> +<h2><a name="Design">Design</a> considerations for Boost.Endian buffers</h2> +<ul> + <li>Must be suitable for I/O - in other words, must be memcpyable.</li> + <li>Must provide exactly the size and internal byte ordering specified.</li> + <li>Must work correctly when the internal integer representation has more bits + that the sum of the bits in the external byte representation. Sign extension + must work correctly when the internal integer representation type has more + bits than the sum of the bits in the external bytes. For example, using + a 64-bit integer internally to represent 40-bit (5 byte) numbers must work for + both positive and negative values.</li> + <li>Must work correctly (including using the same defined external + representation) regardless of whether a compiler treats char as signed or + unsigned.</li> + <li>Unaligned types must not cause compilers to insert padding bytes.</li> + <li>The implementation should supply optimizations with great care. Experience has shown that optimizations of endian + integers often become pessimizations when changing + machines or compilers. Pessimizations can also happen when changing compiler switches, + compiler versions, or CPU models of the same architecture.</li> +</ul> +<h2><a name="C++0x">C++11</a></h2> +<p>The availability of the C++11 +<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> +Defaulted Functions</a> feature is detected automatically, and will be used if +present to ensure that objects of <code>class endian_buffer</code> are trivial, and +thus PODs.</p> +<h2><a name="Compilation">Compilation</a></h2> +<p>Boost.Endian is implemented entirely within headers, with no need to link to +any Boost object libraries.</p> +<p>Several macros allow user control over features:</p> +<ul> + <li>BOOST_ENDIAN_NO_CTORS causes <code>class endian_buffer</code> to have no + constructors. The intended use is for compiling user code that must be + portable between compilers regardless of C++11 + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> + Defaulted Functions</a> support. Use of constructors will always fail, <br> + </li> + <li>BOOST_ENDIAN_FORCE_PODNESS causes BOOST_ENDIAN_NO_CTORS to be defined if + the compiler does not support C++11 + <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm"> + Defaulted Functions</a>. This is ensures that objects of <code>class endian_buffer</code> + are PODs, and so can be used in C++03 unions. + In C++11, <code>class endian_buffer</code> objects are PODs, even though they have + constructors, so can always be used in unions.</li> +</ul> +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->25 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28920" --></p> +<p>© Copyright Beman Dawes, 2006-2009, 2013</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/choosing_approach.html b/libs/endian/doc/choosing_approach.html new file mode 100644 index 000000000..effb79fdd --- /dev/null +++ b/libs/endian/doc/choosing_approach.html @@ -0,0 +1,412 @@ +<html> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Choosing Approach</title> +<link href="styles.css" rel="stylesheet"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="339"> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> + <td align="middle" width="1253"> + <font size="6"><b>Choosing the Approach</b></font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> +<p></p> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> +<a href="#Introduction">Introduction</a><br> +<a href="#Choosing">Choosing between conversion functions,</a><br> + <a href="#Choosing">buffer types, and arithmetic types</a><br> + <a href="#Characteristics">Characteristics</a><br> + <a href="#Endianness-invariants">Endianness invariants</a><br> + <a href="#Conversion-explicitness">Conversion explicitness</a><br> + <a href="#Arithmetic-operations">Arithmetic operations</a><br> + <a href="#Sizes">Sizes</a><br> + <a href="#Alignments">Alignments</a><br> + <a href="#Design-patterns">Design patterns</a><br> + <a href="#As-needed">Convert only as needed (i.e. lazy)</a><br> + <a href="#Anticipating-need">Convert in anticipation of need</a><br> + <a href="#Convert-generally-as-needed-locally-in-anticipation">Generally +as needed, locally in anticipation</a><br> + <a href="#Use-cases">Use case examples</a><br> + <a href="#Porting-endian-unaware-codebase">Porting endian unaware codebase</a><br> + <a href="#Porting-endian-aware-codebase">Porting endian aware codebase</a><br> + <a href="#Reliability-arithmetic-speed">Reliability and arithmetic-speed</a><br> + <a href="#Reliability-ease-of-use">Reliability and ease-of-use</a></td> + </tr> + </table> + +<h2><a name="Introduction">Introduction</a></h2> + +<p>Deciding which is the best endianness approach (conversion functions, buffer +types, or arithmetic types) for a particular application involves complex +engineering trade-offs. It is hard to assess those trade-offs without some +understanding of the different interfaces, so you might want to read the +<a href="conversion.html">conversion functions</a>, <a href="buffers.html"> +buffer types</a>, and <a href="arithmetic.html">arithmetic types</a> pages +before diving into this page.</p> + +<h2><a name="Choosing">Choosing</a> between conversion functions, buffer types, +and arithmetic types</h2> + +<p>The best approach to endianness for a particular application depends on the interaction between +the application's needs and the characteristics of each of the three approaches.</p> + +<p><b>Recommendation:</b> If you are new to endianness, uncertain, or don't want to invest +the time to +study +engineering trade-offs, use <a href="arithmetic.html">endian arithmetic types</a>. They are safe, easy +to use, and easy to maintain. Use the +<a href="#Anticipating-need"> <i> +anticipating need</i></a> design pattern locally around performance hot spots +like lengthy loops, if needed.</p> + +<h3><a name="Background">Background</a> </h3> + +<p>A dealing with endianness usually implies a program portability or a data +portability requirement, and often both. That means real programs dealing with +endianness are usually complex, so the examples shown here would really be +written as multiple functions spread across multiple translation units. They +would involve interfaces that can not be altered as they are supplied by +third-parties or the standard library. </p> + +<h3><a name="Characteristics">Characteristics</a></h3> + +<p>The characteristics that differentiate the three approaches to endianness are the endianness +invariants, conversion explicitness, arithmetic operations, sizes available, and +alignment requirements.</p> + +<h4><a name="Endianness-invariants">Endianness invariants</a></h4> + +<blockquote> + +<p><b>Endian conversion functions</b> use objects of the ordinary C++ arithmetic +types like <code>int</code> or <code>unsigned short</code> to hold values. That +breaks the implicit invariant that the C++ language rules apply. The usual +language rules only apply if the endianness of the object is currently set to the native endianness for the platform. That can +make it very hard to reason about logic flow, and result in difficult to +find bugs.</p> + +<p>For example:</p> + +<blockquote> + <pre>struct data_t // big endian +{ + int32_t v1; // description ... + int32_t v2; // description ... + ... additional character data members (i.e. non-endian) + int32_t v3; // description ... +}; + +data_t data; + +read(data); +big_to_native_inplace(data.v1); +big_to_native_inplace(data.v2); + +... + +++v1; +third_party::func(data.v2); + +... + +native_to_big_inplace(data.v1); +native_to_big_inplace(data.v2); +write(data); +</pre> + <p>The programmer didn't bother to convert <code>data.v3</code> to native + endianness because that member isn't used. A later maintainer needs to pass + <code>data.v3</code> to the third-party function, so adds <code>third_party::func(data.v3);</code> + somewhere deep in the code. This causes a silent failure because the usual + invariant that an object of type <code>int32_t</code> holds a value as + described by the C++ core language does not apply.</p> +</blockquote> +<p><b>Endian buffer and arithmetic types</b> hold values internally as arrays of +characters with an invariant that the endianness of the array never changes. +That makes these types easier to use and programs easier to maintain. </p> +<p>Here is the same example, using an endian arithmetic type:</p> +<blockquote> + <pre>struct data_t +{ + big_int32_t v1; // description ... + big_int32_t v2; // description ... + ... additional character data members (i.e. non-endian) + big_int32_t v3; // description ... +}; + +data_t data; + +read(data); + +... + +++v1; +third_party::func(data.v2); + +... + +write(data); +</pre> + <p>A later maintainer can add <code>third_party::func(data.v3)</code>and it + will just-work.</p> +</blockquote> + +</blockquote> + +<h4><a name="Conversion-explicitness">Conversion explicitness</a></h4> + +<blockquote> + +<p><b>Endian conversion functions</b> and <b>buffer types</b> never perform +implicit conversions. This gives users explicit control of when conversion +occurs, and may help avoid unnecessary conversions.</p> + +<p><b>Endian arithmetic types</b> perform conversion implicitly. That makes +these types very easy to use, but can result in unnecessary conversions. Failure +to hoist conversions out of inner loops can bring a performance penalty.</p> + +</blockquote> + +<h4><a name="Arithmetic-operations">Arithmetic operations</a></h4> + +<blockquote> + +<p><b>Endian conversion functions</b> do not supply arithmetic +operations, but this is not a concern since this approach uses ordinary C++ +arithmetic types to hold values.</p> + +<p><b>Endian buffer types</b> do not supply arithmetic operations. Although this +approach avoids unnecessary conversions, it can result in the introduction of +additional variables and confuse maintenance programmers.</p> + +<p><b>Endian</b> <b>arithmetic types</b> do supply arithmetic operations. They +are very easy to use if lots of arithmetic is involved. </p> + +</blockquote> + +<h4><a name="Sizes">Sizes</a></h4> + +<blockquote> + +<p><b>Endianness conversion functions</b> only support 1, 2, 4, and 8 byte +integers. That's sufficient for many applications.</p> + +<p><b>Endian buffer and arithmetic types</b> support 1, 2, 3, 4, 5, 6, 7, and 8 +byte integers. For an application where memory use or I/O speed is the limiting +factor, using sizes tailored to application needs can be useful.</p> + +</blockquote> + +<h4><a name="Alignments">Alignments</a></h4> + +<blockquote> + +<p><b>Endianness conversion functions</b> only support aligned integer and +floating-point types. That's sufficient for most applications.</p> + +<p><b>Endian buffer and arithmetic types</b> support both aligned and unaligned +integer and floating-point types. Unaligned types are rarely needed, but when +needed they are often very useful and workarounds are painful. For example,</p> + +<blockquote> + <p>Non-portable code like this:<blockquote> + <pre>struct S { + uint16_t a; // big endian + uint32_t b; // big endian +} __attribute__ ((packed));</pre> + </blockquote> + <p>Can be replaced with portable code like this:</p> + <blockquote> + <pre>struct S { + big_uint16_ut a; + big_uint32_ut b; +};</pre> + </blockquote> + </blockquote> + +</blockquote> + +<h3><a name="Design-patterns">Design patterns</a></h3> + +<p>Applications often traffic in endian data as records or packets containing +multiple endian data elements. For simplicity, we will just call them records.</p> + +<p>If desired endianness differs from native endianness, a conversion has to be +performed. When should that conversion occur? Three design patterns have +evolved.</p> + +<h4><a name="As-needed">Convert only as needed</a> (i.e. lazy)</h4> + +<p>This pattern defers conversion to the point in the code where the data +element is actually used.</p> + +<p>This pattern is appropriate when which endian element is actually used varies +greatly according to record content or other circumstances</p> + +<h4><a name="Anticipating-need">Convert in anticipation of need</a></h4> + +<p>This pattern performs conversion to native endianness in anticipation of use, +such as immediately after reading records. If needed, conversion to the output +endianness is performed after all possible needs have passed, such as just +before writing records.</p> + +<p>One implementation of this pattern is to create a proxy record with +endianness converted to native in a read function, and expose only that proxy to +the rest of the implementation. If a write function, if needed, handles the +conversion from native to the desired output endianness.</p> + +<p>This pattern is appropriate when all endian elements in a record are +typically used regardless of record content or other circumstances</p> + +<h4><a name="Convert-generally-as-needed-locally-in-anticipation">Convert +only as needed, except locally in anticipation of need</a></h4> + +<p>This pattern in general defers conversion but for specific local needs does +anticipatory conversion. Although particularly appropriate when coupled with the endian buffer +or arithmetic types, it also works well with the conversion functions.</p> + +<p>Example:</p> + +<blockquote> + <pre>struct data_t +{ + big_int32_t v1; + big_int32_t v2; + big_int32_t v3; +}; + +data_t data; + +read(data); + +... +++v1; +... + +int32_t v3_temp = data.v3; // hoist conversion out of loop + +for (int32_t i = 0; i < <i><b>large-number</b></i>; ++i) +{ + ... <i><b>lengthy computation that accesses </b></i>v3_temp<i><b> many times</b></i> ... +} +data.v3 = v3_temp; + +write(data); +</pre> +</blockquote> + +<p dir="ltr">In general the above pseudo-code leaves conversion up to the endian +arithmetic type <code>big_int32_t</code>. But to avoid conversion inside the +loop, a temporary is created before the loop is entered, and then used to set +the new value of <code>data.v3</code> after the loop is complete.</p> + +<blockquote> + +<p dir="ltr">Question: Won't the compiler's optimizer hoist the conversion out +of the loop anyhow?</p> + +<p dir="ltr">Answer: VC++ 2015 Preview, and probably others, does not, even for +a toy test program. Although the savings is small (two register <code> +<span style="font-size: 85%">bswap</span></code> instructions), the cost might +be significant if the loop is repeated enough times. On the other hand, the +program may be so dominated by I/O time that even a lengthy loop will be +immaterial.</p> + +</blockquote> + +<h3><a name="Use-cases">Use case examples</a></h3> + +<h4><a name="Porting-endian-unaware-codebase">Porting endian unaware codebase</a></h4> + +<p>An existing codebase runs on big endian systems. It does not +currently deal with endianness. The codebase needs to be modified so it can run +on little endian systems under various operating systems. To ease +transition and protect value of existing files, external data will continue to +be maintained as big endian.</p> + +<p dir="ltr">The <a href="arithmetic.html">endian +arithmetic approach</a> is recommended to meet these needs. A relatively small +number of header files dealing with binary I/O layouts need to change types. For +example, +<code>short</code> or <code>int16_t</code> would change to <code>big_int16_t</code>. No +changes are required for <code>.cpp</code> files.</p> + +<h4><a name="Porting-endian-aware-codebase">Porting endian aware codebase</a></h4> + +<p>An existing codebase runs on little-endian Linux systems. It already +deals with endianness via +<a href="http://man7.org/linux/man-pages/man3/endian.3.html">Linux provided +functions</a>. Because of a business merger, the codebase has to be quickly +modified for Windows and possibly other operating systems, while still +supporting Linux. The codebase is reliable and the programmers are all +well-aware of endian issues. </p> + +<p dir="ltr">These factors all argue for an <a href="conversion.html">endian conversion +approach</a> that just mechanically changes the calls to <code>htobe32</code>, +etc. to <code>boost::endian::native_to_big</code>, etc. and replaces <code><endian.h></code> +with <code><boost/endian/conversion.hpp></code>.</p> + +<h4><a name="Reliability-arithmetic-speed">Reliability and arithmetic-speed</a></h4> + +<p>A new, complex, multi-threaded application is to be developed that must run +on little endian machines, but do big endian network I/O. The developers believe +computational speed for endian variable is critical but have seen numerous bugs +result from inability to reason about endian conversion state. They are also +worried that future maintenance changes could inadvertently introduce a lot of +slow conversions if full-blown endian arithmetic types are used.</p> + +<p>The <a href="buffers.html">endian buffers</a> approach is made-to-order for +this use case.</p> + +<h4><a name="Reliability-ease-of-use">Reliability and ease-of-use</a></h4> + +<p>A new, complex, multi-threaded application is to be developed that must run +on little endian machines, but do big endian network I/O. The developers believe +computational speed for endian variables is <b>not critical</b> but have seen +numerous bugs result from inability to reason about endian conversion state. +They are also concerned about ease-of-use both during development and long-term +maintenance.</p> + +<p>Removing concern about conversion speed and adding concern about ease-of-use +tips the balance strongly in favor the <a href="arithmetic.html">endian +arithmetic approach</a>.</p> + +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->19 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38903" --></p> +<p>© Copyright Beman Dawes, 2011, 2013, 2014</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +<p> </p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/conversion.html b/libs/endian/doc/conversion.html new file mode 100644 index 000000000..d811e07dd --- /dev/null +++ b/libs/endian/doc/conversion.html @@ -0,0 +1,371 @@ +<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40"> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +<title>Endian Conversion Functions</title> +<link href="styles.css" rel="stylesheet"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86" ></a></td> + <td align="middle"> + <b> + <font size="6">Endian Conversion Functions</font></b></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> + +<p></p> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> + <a href="#Introduction">Introduction</a><br> + <a href="#Reference">Reference</a><br> + <a href="#Synopsis">Synopsis</a><br> + <a href="#Requirements">Requirements</a><br> + <code><a href="#EndianReversible">EndianReversible</a></code><br> + <a href="#Customization-points">Customization for + UDTs</a><br> + <a href="#Functions">Functions</a><br> + <a href="#FAQ">FAQ</a><br> + <a href="#Acknowledgements">Acknowledgements</a></td> + </tr> + </table> + +<h2><a name="Introduction">Introduction</a></h2> + +<p>Header <a href="../include/boost/endian/conversion.hpp">boost/endian/conversion.hpp</a> +provides byte order reversal and conversion functions that convert objects of +the built-in +integer types +between native, big, or little endian byte +ordering. User defined types are also supported.</p> + +<h2><a name="Reference">Reference</a></h2> + +<p>Functions are implemented <code>inline</code> if appropriate.<code> </code> +For C++03 compilers, <code> noexcept</code> is +elided . +Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.</p> + +<h3> +Header <code><boost/endian/conversion.hpp></code> +<a name="Synopsis">Synopsis</a></h3> + +<pre>#define BOOST_ENDIAN_INTRINSIC_MSG \ + "<b><font face="Arial"><i>message describing presence or absence of intrinsics</i></font></b>" + +namespace boost +{ +namespace endian +{ + enum class <a name="order">order</a> + { + big, // big endian + little, // little endian + native = <b><i>implementation-defined-as-big-or-little + </i></b>}; + + int8_t <a href="#endian_reverse">endian_reverse</a>(int8_t x) noexcept; + int16_t <a href="#endian_reverse">endian_reverse</a>(int16_t x) noexcept; + int32_t <a href="#endian_reverse">endian_reverse</a>(int32_t x) noexcept; + int64_t <a href="#endian_reverse">endian_reverse</a>(int64_t x) noexcept; + uint8_t <a href="#endian_reverse">endian_reverse</a>(uint8_t x) noexcept; + uint16_t <a href="#endian_reverse">endian_reverse</a>(uint16_t x) noexcept; + uint32_t <a href="#endian_reverse">endian_reverse</a>(uint32_t x) noexcept; + uint64_t <a href="#endian_reverse">endian_reverse</a>(uint64_t x) noexcept; + + template <class EndianReversible> + EndianReversible big_to_native(EndianReversible x) noexcept; + template <class EndianReversible> + EndianReversible native_to_big(EndianReversible x) noexcept; + template <class EndianReversible> + EndianReversible little_to_native(EndianReversible x) noexcept; + template <class EndianReversible> + EndianReversible native_to_little(EndianReversible x) noexcept; + template <order O1, order O2, class EndianReversible> + EndianReversible conditional_reverse(EndianReversible x) noexcept; + template <class EndianReversible> + EndianReversible conditional_reverse(EndianReversible x, + order order1, order order2) noexcept; + + template <class EndianReversible> + void endian_reverse_inplace(EndianReversible& x) noexcept; + + template <class EndianReversibleInplace> + void big_to_native_inplace(EndianReversibleInplace& x) noexcept; + template <class EndianReversibleInplace> + void native_to_big_inplace(EndianReversibleInplace& x) noexcept; + template <class EndianReversibleInplace> + void little_to_native_inplace(EndianReversibleInplace& x) noexcept; + template <class EndianReversibleInplace> + void native_to_little_inplace(EndianReversibleInplace& x) noexcept; + template <order O1, order O2, class EndianReversibleInplace> + void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; + template <class EndianReversibleInplace> + void conditional_reverse_inplace(EndianReversibleInplace& x, + order order1, order order2) noexcept; + +} // namespace endian +} // namespace boost</pre> +<p dir="ltr">The implementation is required to define the <code>enum class order</code> +constant <code>native</code> as +<code>big</code> on big endian platforms and <code>little</code> on little +endian platforms.</p> +<h3 dir="ltr"><a name="Definitions">Definitions</a></h3> +<p dir="ltr">The standard integral types (C++std 3.9.1) except <code>bool</code>, +are collectively called the <i>endian types</i>.</p> +<h3><a name="Requirements">Requirements</a></h3> +<h4><a name="Template-argument-requirements">Template argument requirements</a></h4> +<p dir="ltr">The template definitions in the <code>boost/endian/conversion.hpp</code> +header refer to various named requirements whose details are set out in the +tables in this subsection. In these tables, <code>T</code> is an object or +reference type to be supplied by a C++ program instantiating a template; <code>x</code> +is a value of type (possibly <code>const</code>) <code>T</code>; <code>mlx</code> is a +modifiable lvalue of type <code>T</code>.</p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td colspan="3" align="center"><b><code><a name="EndianReversible">EndianReversible</a></code></b> + requirements (in addition to <b><code>CopyConstructible</code></b>)</td> + </tr> + <tr> + <td><b>Expression</b></td> + <td><b>Return<br> + type</b></td> + <td><b>Requirements</b></td> + </tr> + <tr> + <td valign="top"><code>endian_reverse(x)</code></td> + <td align="center" valign="top"><code>T</code></td> + <td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is + an endian type, returns the value of <code>x</code> with the order of bytes + reversed.</p> + <p>If <code>T</code> is a class type, the function:</p> + <ul> + <li>Returns the value of <code>x</code> + with the order of bytes reversed for all data members of types or arrays of + types that meet the <code>EndianReversible</code> requirements, and;</li> + <li>Is a non-member function in the same namespace as <code>T</code> that +can be found by argument dependent lookup (ADL). </li> + </ul> + </td> + </tr> +</table> +<p> </p> +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td colspan="2" align="center"><b><code><a name="EndianReversibleInplace">EndianReversibleInplace</a></code></b> + requirements (in addition to <b><code>CopyConstructible</code></b>)</td> + </tr> + <tr> + <td><b>Expression</b></td> + <td><b>Requirements</b></td> + </tr> + <tr> + <td valign="top"><code>endian_reverse_inplace(mlx)</code></td> + <td> <code>T</code> is an endian type or a class type.<p>If <code>T</code> is + an endian type, reverses the order of bytes in <code>mlx</code>.</p> + <p>If <code>T</code> is a class type, the function:</p> + <ul> + <li>Reverses the order of bytes of all data members of <code>mlx</code> + that have types or arrays of + types that meet the <code>EndianReversible</code> or <code>EndianReversibleInplace</code> + requirements, and;</li> + <li>Is a non-member function in the same namespace as <code>T</code> that +can be found by argument dependent lookup (ADL). </li> + </ul> + </td> + </tr> +</table> + +<p> [<i>Note:</i> Because there is a function template for <code>endian_reverse_inplace</code> +that calls <code>endian_reverse</code>, only <code>endian_reverse</code> +is required for a user-defined type to meet the <code>EndianReversibleInplace</code> +requirements. Although User-defined types are not required to supply an <code>endian_reverse_inplace</code> +function, doing so may improve efficiency. <i> —end note</i>]</p> + +<h4> <a name="Customization-points">Customization points</a> for user-defined types (<a name="UDT">UDT</a>s)</h4> + +<p> This subsection describes requirements on the Endian library's implementation.</p> + +<p> The library's function templates requiring <code> +<a href="#EndianReversible">EndianReversible</a></code> are +required to perform reversal of endianness if needed by making an unqualified +call to <code>endian_reverse()</code>.</p> + +<p> The library's function templates requiring <code> +<a href="#EndianReversibleInplace">EndianReversibleInplace</a></code> are required to perform reversal of endianness if needed by making an +unqualified call to <code>endian_reverse_inplace()</code>.</p> + +<p> See <b><code>example/udt_conversion_example.cpp</code></b> for an example user-defined type.</p> + +<h3><a name="Functions">Functions</a></h3> +<pre><a name="endian_reverse"></a>int8_t endian_reverse(int8_t x) noexcept; +int16_t endian_reverse(int16_t x) noexcept; +int32_t endian_reverse(int32_t x) noexcept; +int64_t endian_reverse(int64_t x) noexcept; +uint8_t endian_reverse(uint8_t x) noexcept; +uint16_t endian_reverse(uint16_t x) noexcept; +uint32_t endian_reverse(uint32_t x) noexcept; +uint64_t endian_reverse(uint64_t x) noexcept;</pre> +<blockquote> + <p dir="ltr"><i>Returns:</i> <i><code>x</code></i>, with the order of its + constituent bytes reversed.</p> + <p><i>Remarks:</i> The type of <i><code>x</code></i> meets the <code>EndianReversible</code> requirements.</p> + <p>[<i>Note:</i> The Boost.Endian library does not provide overloads for the C++ standard library + supplied types. <i>—end note</i>]</p> +</blockquote> + +<pre>template <class EndianReversible> +EndianReversible big_to_native(EndianReversible x) noexcept;</pre> + <blockquote> + <p> + <i>Returns:</i> <code>conditional_reverse<order::big, order::native>(x)</code>.</p> + </blockquote> +<pre>template <class EndianReversible> +EndianReversible native_to_big(EndianReversible x) noexcept; </pre> +<blockquote> + <p><i>Returns:</i> <code>conditional_reverse<order::native, order::big>(x)</code>.</p> +</blockquote> +<pre>template <class EndianReversible> +EndianReversible little_to_native(EndianReversible x) noexcept; </pre> + <blockquote> + <p><i>Returns:</i> <code>conditional_reverse<order::little, order::native>(x)</code>.</p> + </blockquote> +<pre>template <class EndianReversible> +EndianReversible native_to_little(EndianReversible x) noexcept; </pre> + <blockquote> + <p><i>Returns:</i> <code>conditional_reverse<order::native, order::little>(x)</code>.</p> + </blockquote> +<pre>template <order O1, order O2, class EndianReversible> +EndianReversible conditional_reverse(EndianReversible x) noexcept; </pre> + <blockquote> + <p><i>Returns:</i> <code>x</code> if <code>O1 == O2,</code> otherwise <code>endian_reverse(x)</code>.</p> + <p><i>Remarks: </i>Whether <code>x</code> or <code>endian_reverse(x)</code> is to be returned shall be determined at compile time.</p> + </blockquote> +<pre>template <class EndianReversible> +EndianReversible conditional_reverse(EndianReversible x, + order order1, order order2) noexcept; </pre> + <blockquote> + <p><i>Returns:</i> <code>order1 == order2 ? x : endian_reverse(x)</code>.</p> + </blockquote> + +<pre>template <class EndianReversible> +void endian_reverse_inplace(EndianReversible& x) noexcept; </pre> + +<blockquote> + <p><i>Effects:</i> <code>x</code> <code>= endian_reverse(x)</code>.</p> + </blockquote> + +<pre>template <class EndianReversibleInplace> +void big_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre> +<blockquote> + <p> + <i>Effects:</i> <code>conditional_reverse_inplace<order::big, order::native>(x)</code>.</p> + </blockquote> +<pre>template <class EndianReversibleInplace> +void native_to_big_inplace(EndianReversibleInplace& x) noexcept; </pre> +<blockquote> + <p> + <i>Effects:</i> <code>conditional_reverse_inplace<order::native, order::big>(x)</code>.</p> + </blockquote> +<pre>template <class EndianReversibleInplace> +void little_to_native_inplace(EndianReversibleInplace& x) noexcept; </pre> +<blockquote> + <p> + <i>Effects:</i> <code>conditional_reverse_inplace<order::little, order::native>(x)</code>.</p> + </blockquote> +<pre>template <class EndianReversibleInplace> +void native_to_little_inplace(EndianReversibleInplace& x) noexcept; </pre> +<blockquote> + <p> + <i>Effects:</i> <code>conditional_reverse_inplace<order::native, order::little>(x)</code>.</p> + </blockquote> +<pre>template <order O1, order O2, class EndianReversibleInplace> +void conditional_reverse_inplace(EndianReversibleInplace& x) noexcept; </pre> +<blockquote> + <p><i>Effects:</i> None if <code>O1 == O2,</code> otherwise <code>endian_reverse_inplace(x)</code>.</p> + <p><i>Remarks: </i>Which effect applies shall be determined at compile time.</p> + </blockquote> +<pre>template <class EndianReversibleInplace> +void conditional_reverse_inplace(EndianReversibleInplace& x, + order order1, order order2) noexcept; </pre> + + +<blockquote> + <p><i>Effects: </i>If <code>order1 == order2</code> then <code>endian_reverse_inplace(x)</code>.</p> + </blockquote> + + +<h2> <a name="FAQ">FAQ</a></h2> + +<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide +FAQ.</p> + +<p><b>Why are both value returning and modify-in-place functions provided?</b></p> + +<blockquote> + +<p>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.</p> + +</blockquote> + +<p><b>Why are exact-length 8, 16, 32, and 64-bit integers supported rather than the built-in +char, short, int, long, long long, etc?</b></p> + +<blockquote> + +<p>The primary use case, portable file or network data, needs these de facto +standard sizes. Using types that vary with the platform would greatly limit +portability for both programs and data.</p> + +</blockquote> + +<h2><a name="Acknowledgements">Acknowledgements</a></h2><p>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 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 <b><code>boost/endian/detail/intrinsic.hpp</code></b>. +Pierre Talbot provided the <code>int8_t endian_reverse()</code> and templated +<code>endian_reverse_inplace()</code> implementations.</p> +<hr> +<p>Last revised: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->26 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28922" --></p> +<p>© Copyright Beman Dawes, 2011, 2013</p> +<p>Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/fp_concerns.html b/libs/endian/doc/fp_concerns.html new file mode 100644 index 000000000..5c5f67c81 --- /dev/null +++ b/libs/endian/doc/fp_concerns.html @@ -0,0 +1,97 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> +<title>Floating Point Concerns</title> +<link href="styles.css" rel="stylesheet"> +</head> + +<body> + +<h1>Floating Point Concerns</h1> + +<p>Consider this simple implementation of <code>endian_reverse</code>:</p> + +<blockquote> + <pre>template <class T> +inline T endian_reverse(T x) BOOST_NOEXCEPT +{ + std::reverse(reinterpret_cast<unsigned char*>(&x), + reinterpret_cast<unsigned char*>(&x) + sizeof(T)); + return x; +}</pre> +</blockquote> +<p><b>Under what conditions with this code fail?</b></p> +<p dir="ltr">It will fail if an object of type <code>T</code> has one or more +bit patterns that cause a failure. Failures usually occur when an invalid +or otherwise special bit pattern is loaded into or saved from a hardware +register.</p> +<p dir="ltr">The problem could in theory occur with both integers and floating +point numbers, but the <a href="http://en.wikipedia.org/wiki/Two's_complement"> +two's complement integers</a> ubiquitous in modern computer architectures do not +have any invalid or otherwise special bit patterns that cause failure when +byte-wise reversed.</p> +<p dir="ltr">But floating point numbers are a different story. Even if we limit +discussion to IEEE 754 (aka ISO/IEC/IEEE 60559) binary representations of 4 and +8 byte sizes, several problems are easy to demonstrate:</p> +<ul> + <li dir="ltr"> + <p dir="ltr">...</li> +</ul> +<h2 dir="ltr">Safe interfaces and possible reference implementations</h2> +<h3 dir="ltr">In-place interface</h3> +<blockquote> + <pre dir="ltr">template <class T> +inline void endian_reverse_inplace(T& x) +{ + std::reverse(reinterpret_cast<unsigned char*>(&x), + reinterpret_cast<unsigned char*>(&x) + sizeof(T)); +}</pre> +</blockquote> +<p dir="ltr">This is the same as the current (i.e integer) customization point +interface, so there is no need for any change.</p> +<p dir="ltr"><b>Warning:</b> Even thought <code>x</code> may have had a valid +value on the originating platform, after calling this function the value of +<code>x</code> may differ or be invalid on this platform.</p> +<h3 dir="ltr">Copy interface</h3> +<blockquote> + <pre dir="ltr">template <class T> +inline void endian_reverse_copy(const T& from, T& to) +{ + std::reverse_copy(reinterpret_cast<const unsigned char*>(&from), + reinterpret_cast<const unsigned char*>(&from) + sizeof(T), + reinterpret_cast<unsigned char*>(&to)); +}</pre> +</blockquote> +<p><b>Warning:</b> Even thought <code>from</code> may have been a valid value on +the originating platform, after calling this function the value of <code>to</code> +may differ or be invalid on this platform.</p> +<h3>Return-by-value interface</h3> +<blockquote> + <pre>template <class T> +inline T endian_reverse_to_native(<span style="background-color: #FFFF00">const</span><span style="background-color: #FFFF00"> T&</span> x) BOOST_NOEXCEPT +{ + T tmp; + std::reverse_copy(reinterpret_cast<const unsigned char*>(&x), + reinterpret_cast<const unsigned char*>(&x) + sizeof(T), + reinterpret_cast<unsigned char*>(&tmp)); + return tmp; +}</pre> +</blockquote> +<p><b>Warning:</b> Even thought <code>x</code> may have had a valid value on the +originating platform, the value of returned by this function may differ or be +invalid on this platform.</p> +<h2>Acknowledgements</h2> +<hr> +<p>Last revised: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->27 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28924" --></p> +<p>© Copyright Beman Dawes, 2015</p> +<p>Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +<p> </p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/index.html b/libs/endian/doc/index.html new file mode 100644 index 000000000..627977d35 --- /dev/null +++ b/libs/endian/doc/index.html @@ -0,0 +1,616 @@ +<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns="http://www.w3.org/TR/REC-html40"> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + +<title>Endian Library</title> +<link href="styles.css" rel="stylesheet"> +</head> + +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="339"> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> + <td align="middle" width="1253"> + <b> + <font size="6">Endian Library</font></b></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> +<p></p> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> + <tr> + <td width="100%" bgcolor="#D7EEFF" align="center"> + <i><b>Contents</b></i></td> + </tr> + <tr> + <td width="100%" bgcolor="#E8F5FF"> +<a href="#Abstract">Abstract</a><br> +<a href="#Introduction-to-endianness">Introduction to endianness</a><br> +<a href="#Introduction">Introduction to the Boost.Endian library</a><br> +<a href="#Choosing">Choosing between conversion functions,</a><br> + <a href="#Choosing">buffer types, and arithmetic types</a><br> +<a href="#Intrinsic">Built-in support for Intrinsics</a><br> +<a href="#Performance">Performance</a><br> + <a href="#Timings">Timings</a><br> +<a href="#FAQ">Overall FAQ</a><br> +<a href="#Release-history">Release history</a><br> + <a href="#Changes-requested-by-formal-review">Changes +requested by formal review</a><br> + <a href="#Other-changes-since-formal-review">Other changes since +formal review</a><br> +<a href="#Compatibility">Compatibility with interim releases</a><br> +<a href="#C++03-support">C++03 support for C++11 features</a><br> +<a href="#Future-directions">Future directions</a><br> +<a href="#Acknowledgements">Acknowledgements</a><br> + </td> + </tr> + </table> + +<h2><a name="Abstract">Abstract</a></h2> + +<p>Boost.Endian provides facilities to manipulate the +<a href="#Introduction-to-endianness">endianness</a> of integers and user-defined types.</p> +<ul> + <li>Three approaches to endianness are supported. Each has a + long history of successful use, and each approach has use cases where it is + preferred over the other approaches.<br> + </li> + <li>Primary uses:<br> + <ul> + <li>Data portability. The Endian library supports binary data exchange, via either external media or network transmission, + regardless of platform endianness.<br> + </li> + <li>Program portability. POSIX-based and + Windows-based operating systems traditionally supply libraries with + non-portable functions to perform endian conversion. There are at least four + incompatible sets of functions in common use. The Endian library is + portable across all C++ platforms.<br> + </li> +</ul> + + </li> + <li>Secondary use: Minimizing data size via sizes and/or alignments not supported by the + standard C++ arithmetic types.<br> + </li> +</ul> + +<div align="center"> + <center> + <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="90%"> + <tr> + <td width="100%"> + <p align="center"><b><font size="4">Notice</font></b></p> + <p align="left">This first release (1.58.0) of the Endian library as an + official Boost library removes for floating point type support that was + present in the mini-review pre-release. Floating point types will be + supported in the Boost 1.59.0 release with a slightly modified floating + point conversion interface and implementation that addresses reliability + concerns.</td> + </tr> + </table> + </center> +</div> + +<h2><a name="Introduction-to-endianness">Introduction to endianness</a></h2> + +<p>Consider the following code:</p> + +<blockquote> + <pre>int16_t i = 0x0102; +FILE * file = fopen("test.bin", "wb"); // binary file! +fwrite(&i, sizeof(int16_t), 1, file); +fclose(file);</pre> +</blockquote> +<p>On OS X, Linux, or Windows systems with an Intel CPU, a hex dump +of the "test.bin" output file produces:</p> +<blockquote> + <p><code>0201</code></p> +</blockquote> +<p>On OS X systems with a PowerPC CPU, or Solaris systems with a SPARC CPU, a hex dump of the "test.bin" +output file produces:</p> +<blockquote> + <p><code>0102</code></p> +</blockquote> +<p>What's happening here is that Intel CPUs order the bytes of an integer with +the least-significant byte first, while SPARC CPUs place the most-significant +byte first. Some CPUs, such as the PowerPC, allow the operating system to +choose which ordering applies.</p> +<p><a name="definition"></a>Most-significant-byte-first ordering is traditionally called "big endian" +ordering and least-significant-byte-first is traditionally called +"little-endian" ordering. The names are derived from +<a href="http://en.wikipedia.org/wiki/Jonathan_Swift" title="Jonathan Swift"> +Jonathan Swift</a>'s satirical novel <i> +<a href="http://en.wikipedia.org/wiki/Gulliver's_Travels" title="Gulliver's Travels"> +Gulliver’s Travels</a></i>, where rival kingdoms opened their soft-boiled eggs +at different ends.</p> +<p>See Wikipedia's +<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> article for an +extensive discussion of endianness.</p> +<p>Programmers can usually ignore endianness, except when reading a core +dump on little-endian systems. But programmers have to deal with endianness when exchanging binary integers and binary floating point +values between computer systems with differing endianness, whether by physical file transfer or over a network. +And programmers may also want to use the library when minimizing either internal or +external data sizes is advantageous.</p> +<h2><a name="Introduction">Introduction</a> to the Boost.Endian library</h2> + +<p>Boost.Endian provides three different approaches to dealing with + +endianness. All three approaches support integers and user-define types (UDTs).</p> + +<p>Each approach has a long history of successful use, and each approach has use +cases where it is preferred to the other approaches.</p> + +<blockquote> + +<p><b><a href="conversion.html">Endian conversion functions</a> -</b> The +application uses the built-in integer types to hold values, and calls the +provided conversion functions to convert byte ordering as needed. Both mutating +and non-mutating conversions are supplied, and each comes in unconditional and +conditional variants.</p> + +<p><b><a href="buffers.html">Endian buffer types</a> -</b> The application uses the provided endian +buffer types +to hold values, and explicitly converts to and from the built-in integer types. Buffer sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. +1, 2, 3, 4, 5, 6, 7, and 8 bytes) are provided. Unaligned integer buffer types +are provided for all sizes, and aligned buffer types are provided for 16, 32, and +64-bit sizes. The provided specific types are typedefs for a generic class +template that may be used directly for less common use cases.</p> + +<p><b><a href="arithmetic.html">Endian arithmetic types</a> -</b> The +application uses the provided endian arithmetic types, which supply the same +operations as the built-in C++ arithmetic types. All conversions are implicit. +Arithmetic sizes of 8, 16, 24, 32, 40, 48, 56, and 64 bits (i.e. 1, 2, 3, 4, 5, +6, 7, and 8 bytes) are provided. Unaligned integer types are provided for all +sizes and aligned +arithmetic types are provided for 16, 32, and 64-bit sizes. The provided +specific types are typedefs for a generic class template that may be used +directly in generic code of for less common use cases.</p> + +</blockquote> + +<p>Boost Endian is a header-only library. C++11 features +affecting interfaces, such as <code>noexcept</code>, are used only if available. +See <a href="#C++03-support">C++03 support for C++11 features</a> for details.</p> + +<h2><a name="Choosing">Choosing</a> between conversion functions, buffer types, +and arithmetic types</h2> + +<p>This section has been moved to its own <a href="choosing_approach.html"> +Choosing the Approach</a> page. </p> + +<h2>Built-in support for <a name="Intrinsic">Intrinsic</a>s</h2> +<p>Most compilers, including GCC, Clang, and Visual C++, supply built-in support for byte swapping intrinsics. +The Endian library uses these intrinsics when available since they may result in smaller and faster generated code, particularly for +optimized +builds.</p> +<p>Defining the macro <code>BOOST_ENDIAN_NO_INTRINSICS</code> will suppress use +of the intrinsics. This is useful when a compiler has no intrinsic support or +fails to locate the appropriate header, perhaps because it +is an older release or has very limited supporting libraries.</p> +<p>The macro <code>BOOST_ENDIAN_INTRINSIC_MSG</code> is defined as +either <code>"no byte swap intrinsics"</code> or a string describing the +particular set of intrinsics being used. This is useful for eliminating missing +intrinsics as a source of performance issues.</p> + +<h2><a name="Performance">Performance</a></h2> + +<p>Consider this problem:</p> + +<div align="center"> + <center> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td colspan="2"> + <p align="center"><i><b><a name="Example-1">Example 1</a></b></i></td> + </tr> + <tr> + <td colspan="2"><b><i>Add 100 to a big endian value in a file, then write the + result to a file</i> </b> </td> + </tr> + <tr> + <td><i><b>Endian arithmetic type approach</b></i></td> + <td><i><b>Endian conversion function approach</b></i></td> + </tr> + <tr> + <td valign="top"> + <pre>big_int32_at x; + +... read into x from a file ... + +x += 100; + +... write x to a file ... +</pre> + </td> + <td> + <pre> +int32_t x; + +... read into x from a file ... + +big_to_native_inplace(x); +x += 100; +native_to_big_inplace(x); + +... write x to a file ... +</pre> + </td> + </tr> +</table> + + </center> +</div> + +<p><b>There will be no performance difference between the two approaches in +optimized builds, +regardless of the native endianness of the machine.</b> That's because optimizing compilers will generate exactly the same code for each. That conclusion was confirmed by +studying the generated assembly code for GCC and Visual C++. Furthermore, time +spent doing I/O will determine the speed of this application.</p> + +<p>Now consider a slightly different problem: </p> + +<div align="center"> + <center> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td colspan="2"> + <p align="center"><b><i><a name="Example-2">Example 2</a></i></b></td> + </tr> + <tr> + <td colspan="2"><i><b>Add a million values to a big endian value in a file, then write the + result to a file </b></i> </td> + </tr> + <tr> + <td><i><b>Endian arithmetic type approach</b></i></td> + <td><i><b>Endian conversion function approach</b></i></td> + </tr> + <tr> + <td valign="top"> + <pre>big_int32_at x; + +... read into x from a file ... + +for (int32_t i = 0; i < 1000000; ++i) + x += i; + +... write x to a file ... +</pre> + </td> + <td> + <pre>int32_t x; + +... read into x from a file ... + +big_to_native_inplace(x); + +for (int32_t i = 0; i < 1000000; ++i) + x += i; + +native_to_big_inplace(x); + +... write x to a file ... +</pre> + </td> + </tr> +</table> + + </center> +</div> + +<p>With the Endian arithmetic approach, on little endian platforms an implicit conversion from and then back to +big endian is done inside the loop. With the Endian conversion function +approach, the user has ensured the conversions are done outside the loop, so the +code may run more quickly on little endian platforms.</p> + +<h3><a name="Timings">Timings</a></h3> +<p>These tests were run against release builds on a circa 2012 4-core little endian X64 Intel Core i5-3570K +CPU @ 3.40GHz under Windows 7.</p> + +<p><b>Caveat emptor: The Windows CPU timer has very high granularity. Repeated +runs of the same tests often yield considerably different results.</b></p> + +<p>See <b>test/loop_time_test.cpp</b> for the actual code and <b>benchmark/Jamfile.v2</b> for the build +setup.</p> + + +<div align="center"> + <center> +<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> +<tr><td colspan="6" align="center"><b>GNU C++ version 4.8.2 on Linux virtual + machine</b></td></tr> +<tr><td colspan="6" align="center"><b> Iterations: 10'000'000'000, Intrinsics: __builtin_bswap16, etc.</b></td></tr> +<tr><td><b>Test Case</b></td> +<td align="center"><b>Endian<br>arithmetic<br>type</b></td> +<td align="center"><b>Endian<br>conversion<br>function</b></td> +</tr> +<tr><td>16-bit aligned big endian</td><td align="right">8.46 s</td><td align="right">5.28 s</td></tr> +<tr><td>16-bit aligned little endian</td><td align="right">5.28 s</td><td align="right">5.22 s</td></tr> +<tr><td>32-bit aligned big endian</td><td align="right">8.40 s</td><td align="right">2.11 s</td></tr> +<tr><td>32-bit aligned little endian</td><td align="right">2.11 s</td><td align="right">2.10 s</td></tr> +<tr><td>64-bit aligned big endian</td><td align="right">14.02 s</td><td align="right">3.10 s</td></tr> +<tr><td>64-bit aligned little endian</td><td align="right">3.00 s</td><td align="right">3.03 s</td></tr> + +</table> + </center> +</div> +<p></p> + +<div align="center"> <center> +<table border="1" cellpadding="5" cellspacing="0"style="border-collapse: collapse" bordercolor="#111111"> +<tr><td colspan="6" align="center"><b>Microsoft Visual C++ version 14.0</b></td></tr> +<tr><td colspan="6" align="center"><b> Iterations: 10'000'000'000, Intrinsics: cstdlib _byteswap_ushort, etc.</b></td></tr> +<tr><td><b>Test Case</b></td> +<td align="center"><b>Endian<br>arithmetic<br>type</b></td> +<td align="center"><b>Endian<br>conversion<br>function</b></td> +</tr> +<tr><td>16-bit aligned big endian</td><td align="right">8.27 s</td><td align="right">5.26 s</td></tr> +<tr><td>16-bit aligned little endian</td><td align="right">5.29 s</td><td align="right">5.32 s</td></tr> +<tr><td>32-bit aligned big endian</td><td align="right">8.36 s</td><td align="right">5.24 s</td></tr> +<tr><td>32-bit aligned little endian</td><td align="right">5.24 s</td><td align="right">5.24 s</td></tr> +<tr><td>64-bit aligned big endian</td><td align="right">13.65 s</td><td align="right">3.34 s</td></tr> +<tr><td>64-bit aligned little endian</td><td align="right">3.35 s</td><td align="right">2.73 s</td></tr> +</table> + </center></div> + + +<h2>Overall <a name="FAQ">FAQ</a></h2> + +<p><b>Is the implementation header only?</b></p> + +<blockquote> + +<p>Yes.</p> + +</blockquote> + +<p><b>Are C++03 compilers supported?</b></p> + +<blockquote> + +<p>Yes.</p> + +</blockquote> + +<p><b>Does the implementation use compiler intrinsic built-in byte swapping?</b></p> + +<blockquote> + +<p>Yes, if available. See <a href="#Intrinsic">Intrinsic built-in support</a>.</p> + +</blockquote> + +<p><b>Why bother with endianness?</b></p> +<blockquote> +<p>Binary data portability is the primary use case.</p> +</blockquote> +<p><b>Does endianness have any uses outside of portable binary file or network +I/O formats?</b> </p> +<blockquote> +<p>Using the unaligned integer types with a size tailored to the application's +needs is a minor secondary use that saves internal or external memory space. For +example, using <code>big_int40_buf_t</code> or <code>big_int40_t</code> in a +large array saves a lot of space compared to one of the 64-bit types.</p> +</blockquote> +<p><b>Why bother with binary I/O? Why not just use C++ Standard Library stream +inserters and extractors?</b></p> +<blockquote> +<p>Data interchange formats often specify binary arithmetic data.</p> +<p>Binary arithmetic data is smaller and therefore I/O is faster and file sizes +are smaller. Transfer between systems is less expensive.</p> +<p dir="ltr">Furthermore, binary arithmetic data is of fixed size, and so fixed-size disk +records are possible without padding, easing sorting and allowing random access.</p> +<p dir="ltr">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.</p> +</blockquote> + +<p><b>Which is better, big-endian or little-endian?</b></p> +<blockquote> +<p>Big-endian tends to be preferred in a networking environment and is a bit +more of an industry standard, but little-endian may be preferred for +applications that run primarily on x86, x86-64, and other little-endian +CPU's. The <a href="http://en.wikipedia.org/wiki/Endian">Wikipedia</a> article +gives more pros and cons.</p> +</blockquote> + +<p><b>Why are only big, little, and native endianness supported?</b></p> +<blockquote> +<p>These are the only endian schemes that have any practical value today. PDP-11 +and the other middle endian approaches are interesting historical curiosities +but have no relevance to today's C++ developers.</p> +</blockquote> + +<p><b>Why do both the buffer and arithmetic types exist?</b></p> +<blockquote> +<p>Conversions in the buffer types are explicit. Conversions in the arithmetic +types are implicit. This fundamental difference is a deliberate design feature +that would be lost if the inheritance hierarchy were collapsed.</p> +<p>The original design provided only arithmetic types. Buffer types were +requested during formal review by those wishing total control over when +conversion occurs. They also felt that buffer types would be less likely to be +misused by maintenance programmers not familiar with the implications of +performing a lot of arithmetic operations on the endian arithmetic types.</p> +</blockquote> +<p><b>What is gained by using the buffer types rather than always just using the +arithmetic types?</b></p> +<blockquote> +<p>Assurance than hidden conversions are not performed. This is of overriding +importance to users concerned about achieving the ultimate in terms of speed. </p> +<p>"Always just using the arithmetic types" is fine for other users. When the +ultimate in speed needs to be ensured, the arithmetic types can be used in the +same design patterns or idioms that would be used for buffer types, resulting in +the same code being generated for either types.</p> +</blockquote> + +<p><b>What are the limitations of floating point support?</b></p> + +<blockquote> + +<p><strike>The only supported types are four-byte <code>float</code> and eight-byte +<code>double</code>. The only supported format is +<a href="http://en.wikipedia.org/wiki/IEEE_floating_point">IEEE 754</a> (also +know as ISO/IEC/IEEE 60559). Systems on which integer endianness differs from floating point +endianness are not supported.</strike></p> + +<p>Support for floating point types was removed from Boost 1.58.0 because there +was not enough time to resolve reliability concerns. It is expected that +floating point support will be available in Boost 1.59.0.</p> + +</blockquote> + +<p><b>What are the limitations of integer support?</b></p> + +<blockquote> + +<p>Tests have only been +performed on machines that use two's complement arithmetic. The Endian +conversion functions only support 16, 32, and 64-bit aligned integers. The +endian types only support 8, 16, 24, 32, 40, 48, 56, and 64-bit unaligned integers, +and 8, 16, 32, and 64-bit aligned integers.</p> + +</blockquote> + +<h2><a name="Release-history">Release history</a></h2> +<h3><a name="Changes-requested-by-formal-review">Changes requested by formal review</a></h3> +<p>The library was reworked from top to bottom to accommodate changes requested +during the formal review. See <a href="mini_review_topics.html">Mini-Review</a> +page for details.</p> +<h3><a name="Other-changes-since-formal-review">Other changes since formal +review</a></h3> +<ul> + <li>Header <code>boost/endian/endian.hpp</code> has been renamed to <code> + boost/endian/arithmetic.hpp</code>. Headers + <code>boost/endian/conversion.hpp</code> and <code>boost/endian/buffers.hpp</code> have been + added. + Infrastructure file names were changed accordingly.</li> + <li>The endian arithmetic type aliases have been renamed, + using a naming pattern that is consistent for both integer and floating point, + and a consistent set of aliases supplied for the endian buffer types.</li> + <li>The unaligned-type alias names still have the <code>_t</code> suffix, but + the aligned-type alias names now have an <code>_at</code> suffix..</li> + <li><code>endian_reverse()</code> overloads for <code>int8_t</code> and <code> + uint8_t</code> have been added for improved generality. (Pierre Talbot)</li> + <li>Overloads of <code>endian_reverse_inplace()</code> have been replaced with a single <code> + endian_reverse_inplace()</code> template. (Pierre Talbot)</li> + <li>For X86 and X64 architectures, which permit unaligned loads and stores, + unaligned little endian buffer and arithmetic types use regular loads and + stores when the size is exact. This makes unaligned little endian buffer and + arithmetic types significantly more efficient on these architectures. (Jeremy + Maitin-Shepard)</li> + <li>C++11 features affecting interfaces, such as <code>noexcept</code>, are now used. + C++03 compilers are still + supported.</li> + <li>Acknowledgements have been updated.</li> +</ul> + +<h2><a name="Compatibility">Compatibility</a> with interim releases</h2> + +<p>Prior to the official Boost release, class template <code> +endian_arithmetic</code> has been used for a decade or more with the same +functionality but under the name <code>endian</code>. Other names also changed +in the official release. If the macro <code>BOOST_ENDIAN_DEPRECATED_NAMES</code> +is defined, those old now deprecated names are still supported. However, the +class template <code>endian</code> name is only provided for compilers +supporting C++11 template aliases. For C++03 compilers, the name will have to be +changed to <code>endian_arithmetic</code>.</p> + +<p>To support backward header compatibility, deprecated header <code>boost/endian/endian.hpp</code> +forwards to <code>boost/endian/arithmetic.hpp</code>. It requires <code> +BOOST_ENDIAN_DEPRECATED_NAMES</code> be defined. It should only be used while +transitioning to the official Boost release of the library as it will be removed +in some future release.</p> + +<h2><a name="C++03-support">C++03 support</a> for C++11 features</h2> + +<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> + <tr> + <td><b>C++11 Feature</b></td> + <td><b>Action with C++03 Compilers </b></td> + </tr> + <tr> + <td>Scoped enums </td> + <td>Uses header <code class="computeroutput"> + <a href="http://www.boost.org/libs/core/doc/html/core/scoped_enum.html"> + <span class="identifier">boost</span><span class="special">/</span><span class="identifier">core</span><span class="special">/</span><span class="identifier">scoped_enum</span><span class="special">.</span><span class="identifier">hpp</span></a></code><span class="identifier"> + to emulate C++11 scoped enums.</span></td> + </tr> + <tr> + <td><code>noexcept</code></td> + <td><span class="identifier">Uses BOOST_NOEXCEPT macro, which is defined as + null for compilers not supporting this C++11 feature.</span></td> + </tr> + <tr> + <td>C++11 PODs (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm">N2342</a>)</td> + <td><span class="identifier">Takes advantage of C++03 compilers that + relax C++03 POD rules, but see Limitations + <a href="buffers.html#Limitations">here</a> and + <a href="arithmetic.html#Limitations">here</a>. Also see macros for explicit + POD control <a href="buffers.html#Compilation">here</a> and + <a href="arithmetic.html#Compilation">here</a>.</span></td> + </tr> +</table> + +<h2><a name="Future-directions">Future directions</a></h2> + +<p><b>Standardization.</b> The plan is to submit Boost.Endian to the C++ +standards committee for possible inclusion in a Technical Specification or the +C++ standard itself.</p> + +<p><b>Specializations for <code>numeric_limits</code>.</b> Roger Leigh +requested that all <code>boost::endian</code> types provide <code>numeric_limits</code> +specializations. See <a href="https://github.com/boostorg/endian/issues/4"> +GitHub issue 4</a>.</p> + +<p><b>Character buffer support.</b> Peter Dimov pointed out during the +mini-review that getting and setting basic arithmetic types (or <code><cstdint></code> +equivalents) from/to an offset into an array of unsigned char is a common need. +See <a href="http://lists.boost.org/Archives/boost/2015/01/219574.php"> +Boost.Endian mini-review posting</a>.</p> + +<p><b>Out-of-range detection.</b> Peter Dimov pointed suggested during the +mini-review that throwing an exception on buffer values being out-of-range might +be desirable. See the end of +<a href="http://lists.boost.org/Archives/boost/2015/01/219659.php">this posting</a> +and subsequent replies.</p> + +<h2><a name="Acknowledgements">Acknowledgements</a></h2> +<p>Comments and suggestions were received from Adder, Benaka Moorthi, +Christopher Kohlhoff, Cliff Green, Daniel James, Gennaro Proto, Giovanni Piero +Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jason Newton, Jeff Flinn, Jeremy Maitin-Shepard, John Filo, John +Maddock, Kim Barrett, Marsh Ray, Martin Bonner, Mathias Gaunard, Matias +Capeletto, Neil Mayhew, Nevin Liber, +Olaf van der Spek, Paul Bristow, Peter Dimov, Pierre Talbot, Phil Endecott, +Philip Bennefall, Pyry Jahkola, +Rene Rivera, Robert Stewart, Roger Leigh, Roland Schwarz, Scott McMurray, Sebastian Redl, Tim +Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and +Vitaly Budovsk. Apologies if anyone has been missed.</p> +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->25 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28920" --></p> +<p>© Copyright Beman Dawes, 2011, 2013</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/mini_review_topics.html b/libs/endian/doc/mini_review_topics.html new file mode 100644 index 000000000..d7a7f3ccf --- /dev/null +++ b/libs/endian/doc/mini_review_topics.html @@ -0,0 +1,150 @@ +<html> + +<head> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Endian Mini-Review</title> +</head> +<link href="styles.css" rel="stylesheet"> +<body> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> + <tr> + <td width="339"> +<a href="../../../index.html"> +<img src="../../../boost.png" alt="Boost logo" align="middle" border="0" width="277" height="86"></a></td> + <td align="middle" width="1253"> + <b> + <font size="6">Endian </font></b><font size="6"><b>Mini-Review</b></font></td> + </tr> +</table> + +<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" + bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> + <tr> + <td><b> + <a href="index.html">Endian Home</a> + <a href="conversion.html">Conversion Functions</a> + <a href="arithmetic.html">Arithmetic Types</a> + <a href="buffers.html">Buffer Types</a> + <a href="choosing_approach.html">Choosing Approach</a></b></td> + </tr> +</table> +<p></p> + +<p>The results of the Boost.Endian formal review included a list of issues to be +resolved before a mini-review.</p> + +<p>The issues are shown in <b>bold</b> below, with the resolution indicated.</p> + + <p><b>1. Common use case scenarios should be developed.</b></p> + <blockquote> + + <p>Done. The documentation have been refactored. A page is now devoted to + <a href="choosing_approach.html">Choosing the Approach</a> to endianness. See + <a href="choosing_approach.html#Use-cases">Use cases</a> for use case + scenarios.</p> + </blockquote> + <p><b>2. Example programs should be developed for the common use case scenarios.</b></p> + <blockquote> + <p>Done. See <a href="choosing_approach.html">Choosing the Approach</a>. + Example code has been added throughout.</p> + </blockquote> + <p><b>3. Documentation should illuminate the differences between endian +integer/float type and endian conversion approaches to the common use +case scenarios, and provide guidelines for choosing the most appropriate +approach in user's applications.</b></p> + <blockquote> + <p>Done. See <a href="choosing_approach.html">Choosing the Approach</a>.</p> + </blockquote> + <p><b>4 .Conversion functions supplying results via return should be provided.</b></p> + <blockquote> + <p>Done. See <a href="conversion.html">ConversionFunctions</a>.</p> + </blockquote> + <p><b>5. Platform specific performance enhancements such as use of compiler intrinsics or relaxed alignment requirements should be supported.</b></p> + <blockquote> + <p>Done. Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in + functions are used in the implementation where appropriate, as requested. See + <a href="index.html#Intrinsic">Built-in support for Intrinsics</a>. See + <a href="index.html#Timings">Timings for Example 2</a> to gauge the impact of + intrinsics.</p> + </blockquote> + <p><b>6. Endian integer (and floating) types should be implemented via the +conversion functions. If that can't be done efficiently, consideration +should be given to expanding the conversion function signatures to +resolve the inefficiencies.</b></p> + <blockquote> + <p>Done. For the endian types, the implementation uses the endian conversion + functions, and thus the intrinsics, as requested.</p> + </blockquote> + <p><b>7. Benchmarks that measure performance should be provided. It should be +possible to compare platform specific performance enhancements against +portable base implementations, and to compare endian integer approaches +against endian conversion approaches for the common use case scenarios.</b></p> + <blockquote> + <p>Done. See <a href="index.html#Timings">Timings for Example 2</a>. The <code>endian/test</code> directory + also contains several additional benchmark and speed test programs.</p> + </blockquote> + <p><b>8. Float (32-bits) and double (64-bits) should be supported. IEEE 754 is +the primary use case.</b></p> + <blockquote> + <p>Done. The <a href="buffers.html">endian buffer types</a>, + <a href="arithmetic.html">endian arithmetic types</a> and + <a href="conversion.html">endian conversion functions</a> now support 32-bit (<code>float)</code> + and 64-bit <code>(double)</code> floating point, as requested.</p> + </blockquote> + <p><b>9. Support for user defined types (UDTs) is desirable, and should be +provided where there would be no conflict with the other concerns.</b></p> + <blockquote> + <p>Done. See <a href="conversion.html#Customization-points">Customization + points for user-defined types (UDTs)</a>.</p> + </blockquote> + <p><b>10. There is some concern that endian integer/float arithmetic operations +might used inadvertently or inappropriately. The impact of adding an endian_buffer + class without arithmetic operations should be investigated.</b></p> + <blockquote> + <p>Done. The endian types have been decomposed into class template <code> + <a href="buffers.html">endian_buffer</a></code> and class template <code> + <a href="arithmetic.html">endian_arithmetic</a></code>. Class + <code>endian_buffer</code> is a public base class for <code>endian_arithmetic</code>, + and can also be used by users as a stand-alone class.</p> + </blockquote> + <p><b>11. Stream insertion and extraction of the endian integer/float types should + be documented and included in the test coverage.</b></p> + <blockquote> + <p>Done. See <a href="buffers.html#Stream-inserter">Stream inserter</a> and + <a href="buffers.html#Stream-extractor">Stream extractor</a>.</p> + </blockquote> + <p><b>12. Binary I/O support that was investigated during development of the Endian + library should be put up for mini-review for inclusion in the Boost I/O + library.</b></p> + +<blockquote> + <p>Not done yet. Will be handled as a separate min-review soon after the + Endian mini-review.</p> + +</blockquote> + <p><b>13. Other requested changes.</b></p> + +<blockquote> + <ul> + <li>In addition to the named-endianness conversion functions, functions that perform + compile-time (via template) and run-time (via function argument) dispatch + are now provided.</li> + <li><code>order::native</code> is now a synonym for <code>order::big</code> + or <code>order::little</code> according to the endianness of the platform. This reduces the number of template specializations required.</li> + <li>Headers have been reorganized to make them easier to read, + with a synopsis at the front and implementation following.</li> + </ul> +</blockquote> +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->19 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38903" --></p> +<p>© Copyright Beman Dawes, 2014</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> + +</body> + +</html>
\ No newline at end of file diff --git a/libs/endian/doc/msvc_readme.txt b/libs/endian/doc/msvc_readme.txt new file mode 100644 index 000000000..88ea31c75 --- /dev/null +++ b/libs/endian/doc/msvc_readme.txt @@ -0,0 +1,31 @@ +Windows +------- + +Prerequisites + +Boost libraries available in boost-root\stage\lib. Example: + + cd boost-root + .\bootstrap + .\b2 --with-system --with-chrono --with-timer link=shared stage + +The provided Visual Studio solution (endian/test/msvc/endian.sln) has a property page +(endian/test/msvc/common.prop) with these Common Properties set (do not include the +double quotes): + + VC++ Directores|Executable Directories: prefix default value with "..\..\..\..\..\stage\lib;" + (Click "Inherit from parent or project defaults" if not checked) + + C/C++|General|Additional Include Directories: prefix default value with "..\..\..\..\..\stage\lib;" + + Linker|General|Additional Library Directories: prefix default value with "..\..\..\..\..\stage\lib;" + + C/C++|Preprocessor: prefix default value with "BOOST_ALL_DYN_LINK;" + +IMPORTANT: If Preprocessor macros are supplied via a common property page, +<inherit from parent or project defaults> must be set for each project! + +------------------------------------------------------------------------------------------ +Copyright Beman Dawes, 2013 +Distributed under the Boost Software License, Version 1.0. +See http://www.boost.org/LICENSE_1_0.txt diff --git a/libs/endian/doc/publish.bat b/libs/endian/doc/publish.bat new file mode 100644 index 000000000..a8fdb91bc --- /dev/null +++ b/libs/endian/doc/publish.bat @@ -0,0 +1,8 @@ +copy /y c:\boost\develop\libs\endian\doc\* d:\boost\endian-gh-pages +pushd d:\boost\endian-gh-pages +git commit -a -m "copy from develop" +git push +popd +rem Copyright Beman Dawes, 2014 +rem Distributed under the Boost Software License, Version 1.0. +rem See www.boost.org/LICENSE_1_0.txt
\ No newline at end of file diff --git a/libs/endian/doc/styles.css b/libs/endian/doc/styles.css new file mode 100644 index 000000000..2018ec0ba --- /dev/null +++ b/libs/endian/doc/styles.css @@ -0,0 +1,20 @@ + +body +{ + font-family: arial, sans-serif; + max-width: 6.5in; + margin: 0px auto; + font-size: 85%; +} + ins {background-color: #CCFFCC;} + del {background-color: #FFCACA;} + pre {background-color: #D7EEFF; font-size: 95%; font-family: "courier new", courier, serif;} + code {font-size: 110%; font-family: "courier new", courier, serif;} + table {font-size: 100%;} + + /* + © Copyright Beman Dawes, 2014 + Distributed under the Boost Software License, Version 1.0. + See www.boost.org/LICENSE_1_0.txt + */ +
\ No newline at end of file diff --git a/libs/endian/doc/todo_list.html b/libs/endian/doc/todo_list.html new file mode 100644 index 000000000..fed67d33b --- /dev/null +++ b/libs/endian/doc/todo_list.html @@ -0,0 +1,106 @@ +<html> + +<head> +<meta http-equiv="Content-Language" content="en-us"> +<meta name="GENERATOR" content="Microsoft FrontPage 5.0"> +<meta name="ProgId" content="FrontPage.Editor.Document"> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Endian Library Do List</title> +</head> + +<body> + +<h1>Endian Library TODO List</h1> + +<h2>To Do</h2> +<h2>Format Review Comments</h2> +<h3 dir="ltr">Interesting</h3> +<ul> + <li dir="ltr"> + <p dir="ltr">John Filo - "Absolutely. I'd like to see support for float and + double, but<br> + even without those additions, I still vote yes." "For those who deal with + non-native endian data, this library is<br> + extremely useful. It automatically eliminates a whole class of common<br> + programming errors when dealing with such data."<br> + </li> + <li dir="ltr"> + <p dir="ltr">Hartmut Kaiser - "Even if this is not a full review, I would like + to vote YES to include this <br> + library into Boost. + <p>Boost.Spirit is using (and shipping) with an older version of this library + <br> + for several years now and we never had any problems with its usage in <br> + Spirit. It is used as the underlying framework for the binary parsers and <br> + generators and it is functioning as advertised.</p> + <p>As a quick test I replaced the internal (older) version of Boost.Endian in + <br> + Spirit with the reviewed version. All of Spirits regression tests still <br> + pass. "<br> + </li> +</ul> +<h3>Executive summary</h3> +<ul> + <li>Common use case scenarios should be developed.</li> + <li>Example programs should be developed for the common use case scenarios.</li> + <li>Documentation should illuminate the differences between endian + integer/float type and endian conversion approaches to the common use case + scenarios, and provide guidelines for choosing the most appropriate approach + for user's applications.</li> + <li>Conversion functions supplying results via <code>return</code> should be + provided.</li> + <li>Platform specific performance enhancements such as use of compiler + intrinsics or relaxed alignment requirements should be supported.</li> + <li>Endian integer (and floating) types should be implemented via the + conversion functions. If that can't be done efficiently, consideration should + be given to expanding the conversion function signatures to resolve the + inefficiencies.</li> + <li>Benchmarks that measure performance should be provided. It should be + possible to compare platform specific performance enhancements against + portable base implementations, and to compare endian integer approaches + against endian conversion approaches for the common use case scenarios.</li> + <li>Float (32-bits) and double (64-bits) should be supported. IEEE 754 is the + primary use case.</li> + <li>Support for user defined types (UDTs) is desirable, and should be + supported where there would be no conflict with the other concerns.</li> + <li>There is some concern that endian integer/float arithmetic operations + might used + inadvertently or inappropriately. The impact of adding an endian_buffer class without arithmetic + operations should be investigated.</li> + <li>Stream insertion and extraction of the endian integer/float types should + be documented and included in the test coverage.</li> + <li>Binary I/O support that was investigated during development of the Endian + library should be put up for min-review for inclusion in the Boost I/O + library.</li> +</ul> +<h3>Docs</h3> +<ul> + <li>one other point ... the help file seems to directly link to the c++ + headers.<br> + this should be changed:<br> + <br> + * some browsers (at least chromium) will not display the header when clicking<br> + the link, but will save them on disk.<br> + <br> + * providing a direct link to the source code from the docs implies that the<br> + user will get some information that are necessary to use the library by<br> + reading the sources. imo, this is not the case for using boost.endian.<br> + <br> + * if a user opens integer.hpp, the first 60 lines just contain copyright, some<br> + historical notes, compiler-specific stuff, includes and ifdefs. imo, this is<br> + the implementation part, which should not be exposed to a user.<br> + <br> + so i'd suggest to completely remove the links to the c++ headers.<br> + </li> +</ul> +<hr> +<p>Last revised: +<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->17 January, 2015<!--webbot bot="Timestamp" endspan i-checksum="38899" --></p> +<p>© Copyright Beman Dawes, 2012</p> +<p>Distributed under the Boost Software License, Version 1.0. See +<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> +<p> </p> + +</body> + +</html>
\ No newline at end of file |