From e4466edf4e1908411af0359d200b3b7159901bba Mon Sep 17 00:00:00 2001 From: Beman Date: Tue, 9 Dec 2014 20:43:47 -0500 Subject: [PATCH] Drop the _unless_big and _unless_little functions. KISS. They were confusing, and less confusing names were never found. --- doc/bikeshed.txt | 10 +- doc/conversion.html | 216 +++++++++++++++------------- example/udt_conversion_example.cpp | 10 +- include/boost/endian/conversion.hpp | 56 -------- test/speed_test_functions.cpp | 96 ++++++++----- 5 files changed, 185 insertions(+), 203 deletions(-) diff --git a/doc/bikeshed.txt b/doc/bikeshed.txt index 1ef2309..aedc22d 100644 --- a/doc/bikeshed.txt +++ b/doc/bikeshed.txt @@ -3,14 +3,15 @@ Conversion function naming bikeshed return-by-value modify-argument ------------------ --------------- -reverse_endianness reverse_endianness_in_place +reverse_endianness reverse_endianness_in_place " reverse_endianness_arg endian_reverse endian_reverse_in_place + " endian_reverse_in_situ " endian_reverse_here " endian_reverse_this " endian_reverse_self " endian_reverse_arg - " endian_reverse_in <------ + " endian_reverse_in reverse reverse_in_place reverse_endian reverse_endian_in_place @@ -47,6 +48,11 @@ be_to_ne ne_to_be from_big, to_big, reverse_unless_big +big_to_native big_to_native +native_to_big native_to_big +reverse_unless_native_big ------ <------ +conditional_reverse reverse_unless_same<...>() <------ +runtime_conditional_reverse reverse_unless_same() <------ merriam-webster.com/dictionary diff --git a/doc/conversion.html b/doc/conversion.html index cf04fa3..9203108 100644 --- a/doc/conversion.html +++ b/doc/conversion.html @@ -1,4 +1,4 @@ - + @@ -75,7 +75,7 @@ ordering. User defined types are also supported.

Reference

-

Functions are implemented inline if appropriate. noexcept is +

Functions are implemented if appropriate. noexcept is elided for compilers that do not support it. Boost scoped enum emulation is used so that the library still works for compilers that do not support scoped enums.

@@ -96,7 +96,6 @@ namespace endian native = implementation-defined // same as order::big or order::little }; - // reverse byte order (i.e. endianness) int8_t reverse_endianness(int8_t x) noexcept; int16_t reverse_endianness(int16_t x) noexcept; int32_t reverse_endianness(int32_t x) noexcept; @@ -108,34 +107,36 @@ namespace endian float reverse_endianness(float x) noexcept; double reverse_endianness(double x) noexcept; - template <class Value> - void reverse(Value& x) noexcept; - - // reverse byte order unless native endianness is big - template <class ReversibleValue > - ReversibleValue big_endian_value(ReversibleValue x) noexcept; template <class Reversible> - void big_endian(Reversible& x) noexcept; - - // reverse byte order unless native endianness is little - template <class ReversibleValue > - ReversibleValue little_endian_value(ReversibleValue x) noexcept; + Reversible big_to_native(Reversible x) noexcept; template <class Reversible> - void little_endian(Reversible& x) noexcept; - - // generic byte order conversion - 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; - - // runtime byte-order conversion - template <class ReversibleValue> - ReversibleValue convert_value(ReversibleValue from, - order from_order, order to_order) noexcept; + Reversible native_to_big(Reversible x) noexcept; template <class Reversible> - void convert(Reversible& x, - order from_order, order to_order) noexcept; + Reversible little_to_native(Reversible x) noexcept; + template <class Reversible> + Reversible native_to_little(Reversible x) noexcept; + template <order O1, order O2, class Reversible> + Reversible conditional_reverse(Reversible x) noexcept; + template <class Reversible> + Reversible runtime_conditional_reverse(Reversible x, + order order1, order order2) noexcept; + + template <class Reversible> + void reverse_endianness_in_place(Reversible& x) noexcept; + + template <class Reversible> + void big_to_native_in_place(Reversible& x) noexcept; + template <class Reversible> + void native_to_big_in_place(Reversible& x) noexcept; + template <class Reversible> + void little_to_native_in_place(Reversible& x) noexcept; + template <class Reversible> + void native_to_little_in_place(Reversible& x) noexcept; + template <order O1, order O2, class Reversible> + void conditional_reverse_in_place(Reversible& x) noexcept; + template <class Reversible> + void runtime_conditional_reverse_in_place(Reversible& x, + order order1, order order2) noexcept; } // namespace endian } // namespace boost @@ -212,7 +213,7 @@ as described in the preceding table.

udt_conversion_example.cpp for an example user-defined type.

Functions

-
int8_t  reverse_endianness(int8_t x) noexcept;
+
int8_t   reverse_endianness(int8_t x) noexcept;
 int16_t  reverse_endianness(int16_t x) noexcept;
 int32_t  reverse_endianness(int32_t x) noexcept;
 int64_t  reverse_endianness(int64_t x) noexcept;
@@ -226,81 +227,94 @@ double   reverse_endianness(double x) noexcept;

Returns: x, with the order of its constituent bytes reversed.

-
template <class Value>
-  void     reverse(Value& x) noexcept;
+ +
template <class Reversible>
+Reversible big_to_native(Reversible x) noexcept;
+
+

+ Returns: conditional_reverse<order::big, + order::native>(x).

+
+
template <class Reversible>
+Reversible native_to_big(Reversible x) noexcept; 
-

Postconditions: The order of the constituent bytes of - x are reversed.

+

Returns: conditional_reverse<order::native, order::big>(x).

-
template <class ReversibleValue >
-  ReversibleValue big_endian_value(ReversibleValue x) noexcept; 
-template <class Reversible>
-  void big_endian(Reversible& x) noexcept;
+
template <class Reversible>
+Reversible little_to_native(Reversible x) noexcept; 
+
+

Returns: conditional_reverse<order::little, order::native>(x).

+
+
template <class Reversible>
+Reversible native_to_little(Reversible x) noexcept; 
+
+

Returns: conditional_reverse<order::native, order::little>(x).

+
+
template <order O1, order O2, class Reversible>
+Reversible conditional_reverse(Reversible x) noexcept; 
+
+

Returns: x if O1 == O2, otherwise + reverse_endianness(x).

+

Remarks: Whether x or reverse_endianness(x) + is to be returned shall be determined at compile time.

+
+
template <class Reversible>
+Reversible runtime_conditional_reverse(Reversible x,
+      order order1, order order2) noexcept; 
+
+

Returns: order1 == order2 ? x : reverse_endianness(x).

+
+ +
template <class Reversible>
+void reverse_endianness_in_place(Reversible& x) noexcept; 
+
-

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

-

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

-

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 >
-  ReversibleValue little_endian_value(ReversibleValue x) noexcept; 
-template <class Reversible>
-  void little_endian(Reversible& x) noexcept;
+

Effects: x = reverse_endianness(x).

+ + +
template <class Reversible>
+void big_to_native_in_place(Reversible& x) noexcept; 
-

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

-

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

-

Example:

-
-
int32_t x = some-value;
-int32_t y(little_endian(x));
-// y has been set to x; the byte order is reversed unless
-// the native byte order is little-endian.
-
-
-
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;
-
+

+ Effects: conditional_reverse_in_place<order::big, + order::native>(x).

+ +
template <class Reversible>
+void native_to_big_in_place(Reversible& x) noexcept; 
-

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 - and To have the same effective order, otherwise - reverse_endianness(from).

-

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

-

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);
-
-
-
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_endianness(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
-
-
+

+ Effects: conditional_reverse_in_place<order::native, + order::big>(x).

+ +
template <class Reversible>
+void little_to_native_in_place(Reversible& x) noexcept; 
+
+

+ Effects: conditional_reverse_in_place<order::little, order::native>(x).

+
+
template <class Reversible>
+void native_to_little_in_place(Reversible& x) noexcept; 
+
+

+ Effects: conditional_reverse_in_place<order::native, + order::little>(x).

+
+
template <order O1, order O2, class Reversible>
+void conditional_reverse_in_place(Reversible& x) noexcept; 
+
+

Effects: None if O1 == O2, otherwise + reverse_endianness_in_place(x).

+

Remarks: Which effect applies shall be determined at compile time.

+
+
template <class Reversible>
+void runtime_conditional_reverse_in_place(Reversible& x,
+     order order1, order order2) noexcept; 
+ + +
+

Effects: If order1 == order2 then reverse_endianness_in_place(x).

+
+

FAQ

@@ -325,7 +339,7 @@ wrong!

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 +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.

@@ -337,7 +351,7 @@ Pierre Talbot provided the int8_t reverse_endianness() and template reverse() implementations.


Last revised: -07 December, 2014

+09 December, 2014

© 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/example/udt_conversion_example.cpp b/example/udt_conversion_example.cpp index 0fda762..64f304a 100644 --- a/example/udt_conversion_example.cpp +++ b/example/udt_conversion_example.cpp @@ -68,17 +68,11 @@ int main(int, char* []) reverse_endianness_in_place(x); cout << "(3) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; - reverse_in_place_unless_native_big(x); + conditional_reverse_in_place(x); cout << "(4) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; - reverse_in_place_unless_native_little(x); - cout << "(5) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; - - conditional_reverse_in_place(x); - cout << "(6) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; - runtime_conditional_reverse_in_place(x, order::big, order::little); - cout << "(7) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; + cout << "(5) " << x.id() << ' ' << x.value() << ' ' << x.desc() << endl; } #include diff --git a/include/boost/endian/conversion.hpp b/include/boost/endian/conversion.hpp index 9ccd444..00ae479 100644 --- a/include/boost/endian/conversion.hpp +++ b/include/boost/endian/conversion.hpp @@ -72,9 +72,6 @@ namespace endian template inline Reversible native_to_big(Reversible x) BOOST_NOEXCEPT; // Returns: x if native endian order is big, otherwise reverse_endianness(x) - template - inline Reversible reverse_unless_native_big(Reversible x) BOOST_NOEXCEPT; - // Returns: x if native endian order is big, otherwise reverse_endianness(x) // reverse byte order unless native endianness is little template @@ -83,9 +80,6 @@ namespace endian template inline Reversible native_to_little(Reversible x) BOOST_NOEXCEPT; // Returns: x if native endian order is little, otherwise reverse_endianness(x) - template - inline Reversible reverse_unless_native_little(Reversible x) BOOST_NOEXCEPT; - // Returns: x if native endian order is little, otherwise reverse_endianness(x) // generic conditional reverse byte order template @@ -140,9 +134,6 @@ namespace endian template inline void native_to_big_in_place(Reversible& x) BOOST_NOEXCEPT; // Effects: none if native byte-order is big, otherwise reverse_endianness_in_place(x) - template - inline void reverse_in_place_unless_native_big(Reversible& x) BOOST_NOEXCEPT; - // Effects: none if native byte-order is big, otherwise reverse_endianness_in_place(x) // reverse in place unless native endianness is little template @@ -151,9 +142,6 @@ namespace endian template inline void native_to_little_in_place(Reversible& x) BOOST_NOEXCEPT; // Effects: none if native byte-order is little, otherwise reverse_endianness_in_place(x); - template - inline void reverse_in_place_unless_native_little(Reversible& x) BOOST_NOEXCEPT; - // Effects: none if native byte-order is little, otherwise reverse_endianness_in_place(x); // generic conditional reverse in place template @@ -328,16 +316,6 @@ namespace endian # endif } - template - inline Reversible reverse_unless_native_big(Reversible x) BOOST_NOEXCEPT - { -# ifdef BOOST_BIG_ENDIAN - return x; -# else - return reverse_endianness(x); -# endif - } - template inline Reversible little_to_native(Reversible x) BOOST_NOEXCEPT { @@ -358,16 +336,6 @@ namespace endian # endif } - template - inline Reversible reverse_unless_native_little(Reversible x) BOOST_NOEXCEPT - { -# ifdef BOOST_LITTLE_ENDIAN - return x; -# else - return reverse_endianness(x); -# endif - } - namespace detail { // Primary template and specializations to support reverse_endianness(). @@ -413,9 +381,6 @@ namespace endian x = reverse_endianness(x); } - // reverse in place unless native endianness is big - // Effects: none if native endian order is big, - // otherwise reverse_endianness_in_place(x) template # ifdef BOOST_BIG_ENDIAN inline void big_to_native_in_place(Reversible&) BOOST_NOEXCEPT {} @@ -432,19 +397,7 @@ namespace endian reverse_endianness_in_place(x); } # endif - template -# ifdef BOOST_BIG_ENDIAN - inline void reverse_in_place_unless_native_big(Reversible&) BOOST_NOEXCEPT {} -# else - inline void reverse_in_place_unless_native_big(Reversible& x) BOOST_NOEXCEPT - { - reverse_endianness_in_place(x); - } -# endif - // reverse in place unless native endianness is little - // Effects: none if native endian order is little, - // otherwise reverse_endianness_in_place(x) template # ifdef BOOST_LITTLE_ENDIAN inline void little_to_native_in_place(Reversible&) BOOST_NOEXCEPT {} @@ -461,15 +414,6 @@ namespace endian reverse_endianness_in_place(x); } # endif - template -# ifdef BOOST_LITTLE_ENDIAN - inline void reverse_in_place_unless_native_little(Reversible&) BOOST_NOEXCEPT {} -# else - inline void reverse_in_place_unless_native_little(Reversible& x) BOOST_NOEXCEPT - { - reverse_endianness_in_place(x); - } -# endif namespace detail { diff --git a/test/speed_test_functions.cpp b/test/speed_test_functions.cpp index d3a687d..d4d4825 100644 --- a/test/speed_test_functions.cpp +++ b/test/speed_test_functions.cpp @@ -20,43 +20,67 @@ namespace user { - int16_t return_x_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT {return x;} - int16_t return_x_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT {return x;} - int16_t return_x_value_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT - {return reverse_unless_native_big(x);} - int16_t return_x_value_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT - {return reverse_unless_native_little(x);} - int16_t return_x_in_place_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_big(x);return x;} - int16_t return_x_in_place_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_little(x);return x;} - int16_t return_y_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT {return y;} - int16_t return_y_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT {return y;} + int16_t return_x_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT { return x; } + int16_t return_x_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT { return x; } + int16_t return_x_value_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int16_t return_x_value_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int16_t return_x_in_place_big_int16(int16_t x, big_int16_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int16_t return_x_in_place_little_int16(int16_t x, little_int16_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int16_t return_y_big_int16(int16_t x, big_int16_ut y) BOOST_NOEXCEPT { return y; } + int16_t return_y_little_int16(int16_t x, little_int16_ut y) BOOST_NOEXCEPT { return y; } - int32_t return_x_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT {return x;} - int32_t return_x_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT {return x;} - int32_t return_x_value_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT - {return reverse_unless_native_big(x);} - int32_t return_x_value_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT - {return reverse_unless_native_little(x);} - int32_t return_x_in_place_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_big(x);return x;} - int32_t return_x_in_place_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_little(x);return x;} - int32_t return_y_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT {return y;} - int32_t return_y_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT {return y;} + int32_t return_x_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT { return x; } + int32_t return_x_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT { return x; } + int32_t return_x_value_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int32_t return_x_value_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int32_t return_x_in_place_big_int32(int32_t x, big_int32_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int32_t return_x_in_place_little_int32(int32_t x, little_int32_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int32_t return_y_big_int32(int32_t x, big_int32_ut y) BOOST_NOEXCEPT { return y; } + int32_t return_y_little_int32(int32_t x, little_int32_ut y) BOOST_NOEXCEPT { return y; } - int64_t return_x_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT {return x;} - int64_t return_x_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT {return x;} - int64_t return_x_value_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT - {return reverse_unless_native_big(x);} - int64_t return_x_value_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT - {return reverse_unless_native_little(x);} - int64_t return_x_in_place_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_big(x);return x;} - int64_t return_x_in_place_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT - {reverse_in_place_unless_native_little(x);return x;} - int64_t return_y_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT {return y;} - int64_t return_y_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT {return y;} + int64_t return_x_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT { return x; } + int64_t return_x_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT { return x; } + int64_t return_x_value_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int64_t return_x_value_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT + { + return conditional_reverse(x); + } + int64_t return_x_in_place_big_int64(int64_t x, big_int64_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int64_t return_x_in_place_little_int64(int64_t x, little_int64_ut) BOOST_NOEXCEPT + { + conditional_reverse_in_place(x); return x; + } + int64_t return_y_big_int64(int64_t x, big_int64_ut y) BOOST_NOEXCEPT { return y; } + int64_t return_y_little_int64(int64_t x, little_int64_ut y) BOOST_NOEXCEPT { return y; } }