forked from boostorg/endian
Update overview; move 'choosing approach' section after it
This commit is contained in:
@ -18,10 +18,10 @@ Beman Dawes
|
|||||||
|
|
||||||
include::endian/overview.adoc[]
|
include::endian/overview.adoc[]
|
||||||
include::endian/changelog.adoc[]
|
include::endian/changelog.adoc[]
|
||||||
|
include::endian/choosing_approach.adoc[]
|
||||||
include::endian/conversion.adoc[]
|
include::endian/conversion.adoc[]
|
||||||
include::endian/buffers.adoc[]
|
include::endian/buffers.adoc[]
|
||||||
include::endian/arithmetic.adoc[]
|
include::endian/arithmetic.adoc[]
|
||||||
include::endian/choosing_approach.adoc[]
|
|
||||||
include::endian/history.adoc[]
|
include::endian/history.adoc[]
|
||||||
|
|
||||||
:leveloffset: -1
|
:leveloffset: -1
|
||||||
|
@ -6,19 +6,15 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
////
|
////
|
||||||
|
|
||||||
[#choosing]
|
[#choosing]
|
||||||
# Choosing Approach
|
# Choosing between Conversion Functions, Buffer Types, and Arithmetic Types
|
||||||
:idprefix: choosing_
|
:idprefix: choosing_
|
||||||
|
|
||||||
## Introduction
|
NOTE: Deciding which is the best endianness approach (conversion functions, buffer
|
||||||
|
|
||||||
Deciding which is the best endianness approach (conversion functions, buffer
|
|
||||||
types, or arithmetic types) for a particular application involves complex
|
types, or arithmetic types) for a particular application involves complex
|
||||||
engineering trade-offs. It is hard to assess those trade-offs without some
|
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
|
understanding of the different interfaces, so you might want to read the
|
||||||
<<conversion,conversion functions>>, <<buffers,buffer types>>, and
|
<<conversion,conversion functions>>, <<buffers,buffer types>>, and
|
||||||
<<arithmetic,arithmetic types>> pages before diving into this page.
|
<<arithmetic,arithmetic types>> pages before proceeding.
|
||||||
|
|
||||||
## Choosing between conversion functions, buffer types, and arithmetic types
|
|
||||||
|
|
||||||
The best approach to endianness for a particular application depends on the
|
The best approach to endianness for a particular application depends on the
|
||||||
interaction between the application's needs and the characteristics of each of
|
interaction between the application's needs and the characteristics of each of
|
||||||
@ -30,7 +26,7 @@ invest the time to study engineering trade-offs, use
|
|||||||
maintain. Use the _<<choosing_anticipating_need,anticipating need>>_ design
|
maintain. Use the _<<choosing_anticipating_need,anticipating need>>_ design
|
||||||
pattern locally around performance hot spots like lengthy loops, if needed.
|
pattern locally around performance hot spots like lengthy loops, if needed.
|
||||||
|
|
||||||
### Background
|
## Background
|
||||||
|
|
||||||
A dealing with endianness usually implies a program portability or a data
|
A dealing with endianness usually implies a program portability or a data
|
||||||
portability requirement, and often both. That means real programs dealing with
|
portability requirement, and often both. That means real programs dealing with
|
||||||
@ -39,13 +35,13 @@ written as multiple functions spread across multiple translation units. They
|
|||||||
would involve interfaces that can not be altered as they are supplied by
|
would involve interfaces that can not be altered as they are supplied by
|
||||||
third-parties or the standard library.
|
third-parties or the standard library.
|
||||||
|
|
||||||
### Characteristics
|
## Characteristics
|
||||||
|
|
||||||
The characteristics that differentiate the three approaches to endianness are
|
The characteristics that differentiate the three approaches to endianness are
|
||||||
the endianness invariants, conversion explicitness, arithmetic operations, sizes
|
the endianness invariants, conversion explicitness, arithmetic operations, sizes
|
||||||
available, and alignment requirements.
|
available, and alignment requirements.
|
||||||
|
|
||||||
#### Endianness invariants
|
### Endianness invariants
|
||||||
|
|
||||||
*Endian conversion functions* use objects of the ordinary {cpp} arithmetic types
|
*Endian conversion functions* use objects of the ordinary {cpp} arithmetic types
|
||||||
like `int` or `unsigned short` to hold values. That breaks the implicit
|
like `int` or `unsigned short` to hold values. That breaks the implicit
|
||||||
@ -121,7 +117,7 @@ write(data);
|
|||||||
|
|
||||||
A later maintainer can add `third_party::func(data.v3)` and it will just-work.
|
A later maintainer can add `third_party::func(data.v3)` and it will just-work.
|
||||||
|
|
||||||
#### Conversion explicitness
|
### Conversion explicitness
|
||||||
|
|
||||||
*Endian conversion functions* and *buffer types* never perform implicit
|
*Endian conversion functions* and *buffer types* never perform implicit
|
||||||
conversions. This gives users explicit control of when conversion occurs, and
|
conversions. This gives users explicit control of when conversion occurs, and
|
||||||
@ -131,7 +127,7 @@ may help avoid unnecessary conversions.
|
|||||||
very easy to use, but can result in unnecessary conversions. Failure to hoist
|
very easy to use, but can result in unnecessary conversions. Failure to hoist
|
||||||
conversions out of inner loops can bring a performance penalty.
|
conversions out of inner loops can bring a performance penalty.
|
||||||
|
|
||||||
#### Arithmetic operations
|
### Arithmetic operations
|
||||||
|
|
||||||
*Endian conversion functions* do not supply arithmetic operations, but this is
|
*Endian conversion functions* do not supply arithmetic operations, but this is
|
||||||
not a concern since this approach uses ordinary {cpp} arithmetic types to hold
|
not a concern since this approach uses ordinary {cpp} arithmetic types to hold
|
||||||
@ -153,7 +149,7 @@ That's sufficient for many applications.
|
|||||||
integers. For an application where memory use or I/O speed is the limiting
|
integers. For an application where memory use or I/O speed is the limiting
|
||||||
factor, using sizes tailored to application needs can be useful.
|
factor, using sizes tailored to application needs can be useful.
|
||||||
|
|
||||||
#### Alignments
|
### Alignments
|
||||||
|
|
||||||
*Endianness conversion functions* only support aligned integer and
|
*Endianness conversion functions* only support aligned integer and
|
||||||
floating-point types. That's sufficient for most applications.
|
floating-point types. That's sufficient for most applications.
|
||||||
@ -180,7 +176,7 @@ struct S {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### Design patterns
|
## Design patterns
|
||||||
|
|
||||||
Applications often traffic in endian data as records or packets containing
|
Applications often traffic in endian data as records or packets containing
|
||||||
multiple endian data elements. For simplicity, we will just call them records.
|
multiple endian data elements. For simplicity, we will just call them records.
|
||||||
@ -189,7 +185,7 @@ If desired endianness differs from native endianness, a conversion has to be
|
|||||||
performed. When should that conversion occur? Three design patterns have
|
performed. When should that conversion occur? Three design patterns have
|
||||||
evolved.
|
evolved.
|
||||||
|
|
||||||
#### Convert only as needed (i.e. lazy)
|
### Convert only as needed (i.e. lazy)
|
||||||
|
|
||||||
This pattern defers conversion to the point in the code where the data
|
This pattern defers conversion to the point in the code where the data
|
||||||
element is actually used.
|
element is actually used.
|
||||||
@ -198,7 +194,7 @@ This pattern is appropriate when which endian element is actually used varies
|
|||||||
greatly according to record content or other circumstances
|
greatly according to record content or other circumstances
|
||||||
|
|
||||||
[#choosing_anticipating_need]
|
[#choosing_anticipating_need]
|
||||||
#### Convert in anticipation of need
|
### Convert in anticipation of need
|
||||||
|
|
||||||
This pattern performs conversion to native endianness in anticipation of use,
|
This pattern performs conversion to native endianness in anticipation of use,
|
||||||
such as immediately after reading records. If needed, conversion to the output
|
such as immediately after reading records. If needed, conversion to the output
|
||||||
@ -213,7 +209,7 @@ from native to the desired output endianness.
|
|||||||
This pattern is appropriate when all endian elements in a record are typically
|
This pattern is appropriate when all endian elements in a record are typically
|
||||||
used regardless of record content or other circumstances.
|
used regardless of record content or other circumstances.
|
||||||
|
|
||||||
#### Convert only as needed, except locally in anticipation of need
|
### Convert only as needed, except locally in anticipation of need
|
||||||
|
|
||||||
This pattern in general defers conversion but for specific local needs does
|
This pattern in general defers conversion but for specific local needs does
|
||||||
anticipatory conversion. Although particularly appropriate when coupled with the
|
anticipatory conversion. Although particularly appropriate when coupled with the
|
||||||
@ -264,9 +260,9 @@ 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
|
hand, the program may be so dominated by I/O time that even a lengthy loop will
|
||||||
be immaterial.
|
be immaterial.
|
||||||
|
|
||||||
### Use case examples
|
## Use case examples
|
||||||
|
|
||||||
#### Porting endian unaware codebase
|
### Porting endian unaware codebase
|
||||||
|
|
||||||
An existing codebase runs on big endian systems. It does not currently deal
|
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
|
with endianness. The codebase needs to be modified so it can run on little
|
||||||
@ -279,7 +275,7 @@ needs. A relatively small number of header files dealing with binary I/O layouts
|
|||||||
need to change types. For example, `short` or `int16_t` would change to
|
need to change types. For example, `short` or `int16_t` would change to
|
||||||
`big_int16_t`. No changes are required for `.cpp` files.
|
`big_int16_t`. No changes are required for `.cpp` files.
|
||||||
|
|
||||||
#### Porting endian aware codebase
|
### Porting endian aware codebase
|
||||||
|
|
||||||
An existing codebase runs on little-endian Linux systems. It already deals with
|
An existing codebase runs on little-endian Linux systems. It already deals with
|
||||||
endianness via
|
endianness via
|
||||||
@ -293,7 +289,7 @@ just mechanically changes the calls to `htobe32`, etc. to
|
|||||||
`boost::endian::native_to_big`, etc. and replaces `<endian.h>` with
|
`boost::endian::native_to_big`, etc. and replaces `<endian.h>` with
|
||||||
`<boost/endian/conversion.hpp>`.
|
`<boost/endian/conversion.hpp>`.
|
||||||
|
|
||||||
#### Reliability and arithmetic-speed
|
### Reliability and arithmetic-speed
|
||||||
|
|
||||||
A new, complex, multi-threaded application is to be developed that must run
|
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
|
on little endian machines, but do big endian network I/O. The developers believe
|
||||||
@ -304,7 +300,7 @@ slow conversions if full-blown endian arithmetic types are used.
|
|||||||
|
|
||||||
The <<buffers,endian buffers>> approach is made-to-order for this use case.
|
The <<buffers,endian buffers>> approach is made-to-order for this use case.
|
||||||
|
|
||||||
#### Reliability and ease-of-use
|
### Reliability and ease-of-use
|
||||||
|
|
||||||
A new, complex, multi-threaded application is to be developed that must run on
|
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
|
little endian machines, but do big endian network I/O. The developers believe
|
||||||
|
@ -83,7 +83,8 @@ Boost.Endian provides three different approaches to dealing with endianness. All
|
|||||||
three approaches support integers and user-define types (UDTs).
|
three approaches support integers and user-define types (UDTs).
|
||||||
|
|
||||||
Each approach has a long history of successful use, and each approach has use
|
Each approach has a long history of successful use, and each approach has use
|
||||||
cases where it is preferred to the other approaches.
|
cases where it is preferred to the other approaches. See
|
||||||
|
<<choosing,Choosing between Conversion Functions, Buffer Types, and Arithmetic Types>>.
|
||||||
|
|
||||||
<<conversion,Endian conversion functions>>::
|
<<conversion,Endian conversion functions>>::
|
||||||
The application uses the built-in integer types to hold values, and calls the
|
The application uses the built-in integer types to hold values, and calls the
|
||||||
@ -113,10 +114,6 @@ Boost Endian is a header-only library. {cpp}11 features affecting interfaces,
|
|||||||
such as `noexcept`, are used only if available. See
|
such as `noexcept`, are used only if available. See
|
||||||
<<overview_cpp03_support,{cpp}03 support for {cpp}11 features>> for details.
|
<<overview_cpp03_support,{cpp}03 support for {cpp}11 features>> for details.
|
||||||
|
|
||||||
## Choosing between conversion functions, buffer types, and arithmetic types
|
|
||||||
|
|
||||||
This section has been moved to its own <<choosing,Choosing the Approach>> page.
|
|
||||||
|
|
||||||
[#overview_intrinsics]
|
[#overview_intrinsics]
|
||||||
## Built-in support for Intrinsics
|
## Built-in support for Intrinsics
|
||||||
|
|
||||||
@ -260,6 +257,28 @@ Iterations: 10'000'000'000, Intrinsics: `<cstdlib>` `_byteswap_ushort`, etc.
|
|||||||
|64-bit aligned little endian |3.35 s |2.73 s
|
|64-bit aligned little endian |3.35 s |2.73 s
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
[#overview_cpp03_support]
|
||||||
|
## {cpp}03 support for {cpp}11 features
|
||||||
|
|
||||||
|
[%header,cols=2*]
|
||||||
|
|===
|
||||||
|
|{cpp}11 Feature
|
||||||
|
|Action with {cpp}03 Compilers
|
||||||
|
|Scoped enums
|
||||||
|
|Uses header
|
||||||
|
http://www.boost.org/libs/core/doc/html/core/scoped_enum.html[boost/core/scoped_enum.hpp]
|
||||||
|
to emulate {cpp}11 scoped enums.
|
||||||
|
|`noexcept`
|
||||||
|
|Uses `BOOST_NOEXCEPT` macro, which is defined as null for compilers not
|
||||||
|
supporting this {cpp}11 feature.
|
||||||
|
|{cpp}11 PODs
|
||||||
|
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm[N2342])
|
||||||
|
|Takes advantage of {cpp}03 compilers that relax {cpp}03 POD rules, but see
|
||||||
|
Limitations <<buffers_limitations,here>> and <<arithmetic_limitations,here>>.
|
||||||
|
Also see macros for explicit POD control <<buffers_compilation,here>> and
|
||||||
|
<<arithmetic_compilation,here>>
|
||||||
|
|===
|
||||||
|
|
||||||
[#overview_faq]
|
[#overview_faq]
|
||||||
## Overall FAQ
|
## Overall FAQ
|
||||||
|
|
||||||
@ -326,11 +345,11 @@ the same code being generated for either types.
|
|||||||
|
|
||||||
What are the limitations of integer support?::
|
What are the limitations of integer support?::
|
||||||
Tests have only been performed on machines that use two's complement
|
Tests have only been performed on machines that use two's complement
|
||||||
arithmetic. The Endian conversion functions only support 16, 32, and 64-bit
|
arithmetic. The Endian conversion functions only support 8, 16, 32, and 64-bit
|
||||||
aligned integers. The endian types only support 8, 16, 24, 32, 40, 48, 56, and
|
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.
|
64-bit unaligned integers, and 8, 16, 32, and 64-bit aligned integers.
|
||||||
|
|
||||||
Why is there no floating point support?::
|
Is there floating point support?::
|
||||||
An attempt was made to support four-byte ``float``s and eight-byte
|
An attempt was made to support four-byte ``float``s and eight-byte
|
||||||
``double``s, limited to
|
``double``s, limited to
|
||||||
http://en.wikipedia.org/wiki/IEEE_floating_point[IEEE 754] (also known as
|
http://en.wikipedia.org/wiki/IEEE_floating_point[IEEE 754] (also known as
|
||||||
@ -338,29 +357,9 @@ ISO/IEC/IEEE 60559) floating point and further limited to systems where floating
|
|||||||
point endianness does not differ from integer endianness. Even with those
|
point endianness does not differ from integer endianness. Even with those
|
||||||
limitations, support for floating point types was not reliable and was removed.
|
limitations, support for floating point types was not reliable and was removed.
|
||||||
For example, simply reversing the endianness of a floating point number can
|
For example, simply reversing the endianness of a floating point number can
|
||||||
result in a signaling-NAN. For all practical purposes, binary serialization and
|
result in a signaling-NAN.
|
||||||
endianness for integers are one and the same problem. That is not true for
|
+
|
||||||
floating point numbers, so binary serialization interfaces and formats for
|
Support for `float` and `double` has since been reinstated for `endian_buffer`
|
||||||
floating point does not fit well in an endian-based library.
|
and `endian_arithmetic`. The conversion functions still do not support floating
|
||||||
|
point due to the above issues; reversing the bytes of a floating point number
|
||||||
[#overview_cpp03_support]
|
does not necessarily produce another valid floating point number.
|
||||||
## {cpp}03 support for {cpp}11 features
|
|
||||||
|
|
||||||
[%header,cols=2*]
|
|
||||||
|===
|
|
||||||
|{cpp}11 Feature
|
|
||||||
|Action with {cpp}03 Compilers
|
|
||||||
|Scoped enums
|
|
||||||
|Uses header
|
|
||||||
http://www.boost.org/libs/core/doc/html/core/scoped_enum.html[boost/core/scoped_enum.hpp]
|
|
||||||
to emulate {cpp}11 scoped enums.
|
|
||||||
|`noexcept`
|
|
||||||
|Uses `BOOST_NOEXCEPT` macro, which is defined as null for compilers not
|
|
||||||
supporting this {cpp}11 feature.
|
|
||||||
|{cpp}11 PODs
|
|
||||||
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm[N2342])
|
|
||||||
|Takes advantage of {cpp}03 compilers that relax {cpp}03 POD rules, but see
|
|
||||||
Limitations <<buffers_limitations,here>> and <<arithmetic_limitations,here>>.
|
|
||||||
Also see macros for explicit POD control <<buffers_compilation,here>> and
|
|
||||||
<<arithmetic_compilation,here>>
|
|
||||||
|===
|
|
||||||
|
Reference in New Issue
Block a user