diff --git a/doc/conversion.html b/doc/conversion.html index 4cf3236..3a1c369 100644 --- a/doc/conversion.html +++ b/doc/conversion.html @@ -3,7 +3,7 @@ - + Boost Endian Conversion Functions @@ -26,7 +26,7 @@ Boost Home     Endian Home     Conversion Functions     - Endian Types     Tutorial + Endian Types @@ -37,12 +37,11 @@ @@ -58,13 +57,6 @@

Introduction

-
Introduction
- conversion.hpp FAQ
Reference
    Synopsis
    Requirements
    Functions
- Intrinsic built-in support
+ FAQ
Acknowledgements
- - - -
Please: If you haven't done so already, read - Introduction to endianness!
-

Header boost/endian/conversion.hpp provides byte order reversal and conversion functions that convert objects of the multi-byte built-in @@ -79,70 +71,6 @@ ordering. User defined types are also supported.

-

conversion.hpp FAQ

- -

Is the implementation header only?

- -
- -

Yes.

- -
- -

Does the implementation use compiler intrinsic built-in byte swapping?

- -
- -

Yes, if available. See Intrinsic built-in support -below.

- -
- -

Why are the template versions of reverse() and reverse_value() -in a detail namespace?

- -
- -

They are unsafe for general use. Consider reversing -the bytes of a std::pair as a whole - the bytes from first -would end up in second and visa versa, and this is totally -wrong!

- -
- -

Why are both value returning and modify-in-place functions provided?

- -
- -

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.

- -
- -

What are the limitations of floating point support?

- -
- -

The only supported types are four byte float and eight byte -double. Even after endianness has been accounted for, floating -point values will not be portable between systems that use different floating -point formats. Systems where the integer endianness and floating point -endianness are not supported.

- -
- -

What are the limitations of integer support?

- -
- -

Only 16-bit, 32-bit, and 64-bit integers are supported. Tests have been -performed on machines that use two's complement arithmetic.

- -
-

Reference

Functions are implemented inline if appropriate. noexcept is @@ -152,7 +80,7 @@ Boost scoped enum emulation is used so that the library still works for compiler

Synopsis

-
#define BOOST_ENDIAN_INTRINSIC_MSG "message describing presence or absence of intrinsics"
+
#define BOOST_ENDIAN_INTRINSIC_MSG "message describing presence or absence of intrinsics"
 
 namespace boost
 {
@@ -297,27 +225,27 @@ void reverse(double& x) noexcept;
template <class Reversible> void big_endian(Reversible& x) noexcept;
-

Returns (first form): x if the native byte order is big +

Returns (first form): x if the native byte order is big endian, otherwise reverse_value(x).

-

Effects (second form): None if the native byte order is big +

Effects (second form): None if the native byte order is big endian, otherwise reverse(x).

-

Example:

+

Example:

int32_t x = some-value;
 big_endian(x);  // reverses the byte order of x, unless
                 // the native byte order is big-endian
-
template <class ReversibleValue >
+
template <class ReversibleValue >
   ReversibleValue little_endian_value(ReversibleValue x) noexcept; 
 template <class Reversible>
   void little_endian(Reversible& x) noexcept;
-

Returns (first form): x if the native byte order is little +

Returns (first form): x if the native byte order is little endian, otherwise reverse_value(x).

-

Effects (second form): None if the native byte order is little +

Effects (second form): None if the native byte order is little endian, otherwise reverse(x).

-

Example:

+

Example:

int32_t x = some-value;
 int32_t y(little_endian(x));
@@ -325,51 +253,84 @@ int32_t y(little_endian(x));
 // the native byte order is little-endian.
-
template <order From, order To, class ReversibleValue>
+
template <order From, order To, class ReversibleValue>
   ReversibleValue convert_value(ReversibleValue from) noexcept;
 template <order From, order To, class Reversible>
   void convert(Reversible& x) noexcept;
 
-

The effective order of an order template parameter +

The effective order of an order template parameter is the same as the order template parameter if the parameter is not order::native, otherwise it is the constant order::big or order::little that represents the actual native byte order.

-

Returns (first form): from if From +

Returns (first form): from if From and To have the same effective order, otherwise reverse_value(from).

-

Effects (second form): None if From and +

Effects (second form): None if From and To have the same effective order, otherwise reverse(x).

-

Example:

+

Example:

int32_t x;
 ... read an external big-endian value into x
 convert<order::big, order::native>(x);  // more generic equivalent of big_endian(x);
-
order effective_order(order x) noexcept;

Returns: x if x != order::native, otherwise the order constant for the actual native byte order.

Example:

effective_order(order::big);     // returns order::big
+
order effective_order(order x) noexcept;
+
+
+

Returns: x if x != order::native, otherwise the order constant for the actual native byte order.

Example:

effective_order(order::big);     // returns order::big
 effective_order(order::little);  // returns order::little
 effective_order(order::native);  // returns order::big if the native order
-                                 // is big-endian, otherwise order::little
template <class ReversibleValue>
+                                 // is big-endian, otherwise order::little
template <class ReversibleValue>
   ReversibleValue convert_value(ReversibleValue from,
     order from_order, order to_order) noexcept;
 template <class Reversible>
   void convert(Reversible& x,
-    order from_order, order to_order) noexcept;

Returns (first form): from if effect_order(from_order) == effective_order(to_order), otherwise reverse_value(from).

-

Effects (second form): None if effect_order(from_order) == effective_order(to_order), otherwise reverse(x).

-

Example:

+ order from_order, order to_order) noexcept;

Returns (first form): from if effect_order(from_order) == effective_order(to_order), otherwise reverse_value(from).

+

Effects (second form): None if effect_order(from_order) == effective_order(to_order), otherwise reverse(x).

+

Example:

int32_t x;
 ... read an external value of an endianness know only at runtime into x
 convert(x, some_order, order::native);  // convert to native byte order if needed
-

Intrinsic built-in support

+ -

Recent compilers, including GCC, Clang, and Microsoft, supply intrinsic built-in support for byte swapping. Such support is automatically detected and used since it results in smaller and much faster generated code for release builds.

Defining BOOST_ENDIAN_NO_INTRINSICS will suppress use of the intrinsics. Please try defining it if you get compiler errors, such as header byteswap.h not being found.

The macro BOOST_ENDIAN_INTRINSIC_MSG is defined as either "no byte swap intrinsics" or a string describing the particular set of intrinsics being used.

Acknowledgements

Tomas Puverle was instrumental in identifying and articulating the need to +

FAQ

+ +

See the Endian home page FAQ for a library-wide +FAQ.

+ +

Why are the template versions of reverse() and reverse_value() +in a detail namespace?

+ +
+ +

They are unsafe for general use. Consider reversing +the bytes of a std::pair as a whole - the bytes from first +would end up in second and visa versa, and this is totally +wrong!

+ +
+ +

Why are both value returning and modify-in-place functions provided?

+ +
+ +

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.

+ +
+ +

Acknowledgements

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 floating point types and 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 boost/endian/detail/intrinsic.hpp.


-

Last revised: 20 May, 2013

-

© Copyright Beman Dawes, 2011

+

Last revised: +28 May, 2013

+

© Copyright Beman Dawes, 2011, 2013

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

diff --git a/doc/done_list.html b/doc/done_list.html index 4fb97ef..23ccd3d 100644 --- a/doc/done_list.html +++ b/doc/done_list.html @@ -14,19 +14,19 @@
  • Both the endian types and endian conversion functions now support 32-bit (float) and 64-bit (double) floating point, as requested.
  • +
  • Both the endian types and endian conversion functions now support UDTs, as requested.
  • Both the endian types and endian conversion functions have been renamed, using a naming pattern that is consistent for both integer and floating point, and that emphasizes that aligned types are usually preferred compared to - unaligned types.
  • -
  • The conversion.hpp conversion functions have been much revised, + unaligned types which are deliberately given slightly uglier names.
  • +
  • The conversion functions have been much revised, refactored, and otherwise improved based on review comments.
      -
    • UDT's are supported, as requested.
    • Both return-by-value and modify-in-place interfaces are provided, as requested.
    • Synonyms for the BSD byte swapping function names popularized by OS X and Linux are provided, so that that developers already used to these name can continue to use them if they wish.
    • -
    • In addition to the fixed endianness functions, functions that perform +
    • In addition to the named-endianness functions, functions that perform compile-time (via template) and run-time (via function argument) dispatch are now provided, as requested.
    @@ -34,6 +34,7 @@
  • Compiler (Clang, GCC, VisualC++, etc.) intrinsics and built-in functions are used in the implementation where appropriate, as requested.
  • For the endian types, the implementation uses the endian conversion functions, + and thus the intrinsics, as requested.
  • Headers have been renamed to endian/types.hpp and endian/conversion.hpp. Infrastructure file names changed accordingly.
  • diff --git a/doc/index.html b/doc/index.html index 1ae47bd..bdd5c38 100644 --- a/doc/index.html +++ b/doc/index.html @@ -3,7 +3,7 @@ - + Boost Endian Library @@ -26,7 +26,7 @@ Boost Home     Endian Home     Conversion Functions     - Endian Types     Tutorial + Endian Types @@ -40,6 +40,7 @@ Introduction to endianness
    Introduction to the Boost.Endian library
    Choosing approaches
    + Intrinsic built-in support
    Performance
        Timings
        Conclusions
    @@ -79,7 +80,7 @@ floating point, and user defined data.

    int16_t i = 0x0102;
    -FILE * file = fopen("test.bin", "wb");   // MUST BE BINARY
    +FILE * file = fopen("test.bin", "wb");   // binary file!
     fwrite(&i, sizeof(int16_t), 1, file);
     fclose(file);
    @@ -103,7 +104,7 @@ ordering and the least-significant-byte-first is traditionally called Jonathan Swift's satirical novel -Gulliver’s Travels, where rival kingdoms opened their soft-boiled eggs +Gulliver’s Travels, where rival kingdoms opened their soft-boiled eggs at different ends.

    See the Wikipedia's Endianness article for an @@ -195,6 +196,18 @@ application needs.

    +

    Intrinsic built-in support

    +

    Recent compilers, including GCC, Clang, and Microsoft, supply intrinsic +built-in support for byte swapping. Such support is automatically detected and +used since it may in smaller and faster generated code, particularly for release +builds.

    +

    Defining BOOST_ENDIAN_NO_INTRINSICS will suppress use +of the intrinsics. Please try defining it if you get compiler errors, such as +header byteswap.h not being found.

    +

    The macro BOOST_ENDIAN_INTRINSIC_MSG is defined as +either "no byte swap intrinsics" or a string describing the +particular set of intrinsics being used.

    +

    Performance

    Consider this problem:

    @@ -425,6 +438,23 @@ stores, multiple instructions are required.

    Overall FAQ

    + +

    Is the implementation header only?

    + +
    + +

    Yes.

    + +
    + +

    Does the implementation use compiler intrinsic built-in byte swapping?

    + +
    + +

    Yes, if available. See Intrinsic built-in support.

    + +
    +

    Why bother with endianness?

    Binary data portability is the primary use case.

    @@ -448,6 +478,15 @@ files, limit usefulness to applications where the binary I/O advantages are paramount.

    +

    Which is better, big-endian or little-endian?

    +
    +

    Big-endian tends to be a +bit more of an industry standard, but little-endian may be preferred for +applications that run primarily Intel/AMD on x86, x64, and other little-endian +CPU's. The Wikipedia article +gives more pros and cons.

    +
    +

    Why is only big, little, and native endianness supported?

    These are the only endian schemes that have any practical value today. PDP-11 @@ -455,12 +494,33 @@ and the other middle endian approaches are interesting historical curiosities but have no relevance to C++ developers.

    +

    What are the limitations of floating point support?

    + +
    + +

    The only supported types are four byte float and eight byte +double. Even after endianness has been accounted for, floating +point values will not be portable between systems that use different floating +point formats. Systems where the integer endianness differs from floating point +endianness are not supported.

    + +
    + +

    What are the limitations of integer support?

    + +
    + +

    Only 16-bit, 32-bit, and 64-bit integers are supported. Tests have only been +performed on machines that use two's complement arithmetic.

    + +
    +

    Acknowledgements

    Comments and suggestions were received from Adder, Benaka Moorthi, Christopher Kohlhoff, -Cliff Green,Daniel James, Gennaro Proto, +Cliff Green, Daniel James, Gennaro Proto, Giovanni Piero Deretta, Gordon Woodhull, dizzy, Hartmut Kaiser, Jeff Flinn, John Filo, John Maddock, Kim Barrett, @@ -474,7 +534,7 @@ and Vitaly Budovski,.


    Last revised: 28 May, 2013

    -

    © Copyright Beman Dawes, 2011, 2013

    +

    © Copyright Beman Dawes, 2011, 2013

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

    diff --git a/doc/types.html b/doc/types.html index d6c89bf..d733fd5 100644 --- a/doc/types.html +++ b/doc/types.html @@ -4,7 +4,7 @@ - + Boost Endian Integers @@ -28,7 +28,7 @@ Boost Home     Endian Home     Conversion Functions     - Endian Types     Tutorial + Endian Types @@ -510,29 +510,14 @@ in *this.

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

    FAQ

    -

    Why bother with endian types? External data portability and both speed -and space efficiency. Availability -of additional binary integer sizes and alignments is important in some -applications.

    + +

    See the Endian home page FAQ for a library-wide +FAQ.

    +

    Why not just use Boost.Serialization? 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.

    -

    Why bother with binary I/O? Why not just use C++ Standard Library stream -inserters and extractors? Using binary rather than character representations -can be more space efficient, with a side benefit of faster I/O. CPU time is -minimized because conversions to and from string are eliminated. -Furthermore, binary integers are fixed size, and so fixed-size disk records -are possible, easing sorting and allowing direct access. 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.

    -

    Do these types have any uses outside of I/O? Native endianness can be used for fine grained control over size and -alignment, so may be used to save memory in applications not related to I/O.

    -

    Is there is a performance hit when doing arithmetic using these types? Yes, for sure, -compared to arithmetic operations on native integer types. However, these types -are usually be faster, and sometimes much faster, for I/O compared to stream -inserters and extractors, or to serialization.

    Are endian types POD's? Yes for C++11. No for C++03, although several macros are available to force PODness in all cases.

    What are the implications endian integer types not being POD's with C++03 @@ -541,24 +526,15 @@ 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.

    -

    Which is better, big-endian or little-endian? Big-endian tends to be a -bit more of an industry standard, but little-endian may be preferred for -applications that run primarily Intel/AMD on x86, x64, and other little-endian -CPU's. The Wikipedia article -gives more pros and cons.

    What good is native endianness? It provides alignment and size guarantees not available from the built-in types. It eases generic programming.

    Why bother with the aligned endian types? Aligned integer operations -may be faster (20 times, in one measurement) if the endianness and alignment of -the type matches the endianness and alignment requirements of the machine. On -common CPU architectures, that optimization is only available for aligned types. -That allows I/O of maximally efficient types on an application's primary -platform, yet produces data files are portable to all platforms. The code, +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.

    -

    The endian types are really just byte-holders. Why provide the arithmetic -operations at all? Providing a full set of operations reduces program +

    Why provide the arithmetic operations? 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:

        ++record.foo;
    @@ -629,11 +605,12 @@ Borgerding. Four original class templates combined into a single endianunrolled_byte_loops sign partial specialization to correctly extend the sign when cover integer size -differs from endian representation size.

    +differs from endian representation size. Vicente Botet and other reviewers +suggested supporting floating point types.


    Last revised: -26 May, 2013

    -

    © Copyright Beman Dawes, 2006-2009

    +28 May, 2013

    +

    © Copyright Beman Dawes, 2006-2009, 2013

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