Update overview; move 'choosing approach' section after it

This commit is contained in:
Peter Dimov
2020-01-21 04:26:38 +02:00
parent 7eaa25ec2a
commit 81ac17540a
3 changed files with 51 additions and 56 deletions

View File

@ -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

View File

@ -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

View File

@ -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>>
|===