diff --git a/doc/conversion.html b/doc/conversion.html index f2a309b..cf04fa3 100644 --- a/doc/conversion.html +++ b/doc/conversion.html @@ -164,8 +164,8 @@ instantiating a template.

x is a value of a possibly const type convertible to Reversible. -

The value of x with the - order of its constituent bytes reversed is returned. +

Returns the value of x with the + order of its constituent bytes reversed. @@ -183,7 +183,13 @@ modifiable lvalue of type Reversible.

[Note: A user-defined type meets these requirements by defining a non-member function in the same namespace as the UDT itself so that the function -can be found by argument dependent lookup (ADL). —end note]

+can be found by argument dependent lookup (ADL).  —end note]

+ +

[Note: Because there is a function template for reverse_endianness_in_place +that calls reverse_endianness, only reverse_endianness +is required for a user-defined type to meet the Reversible +requirements. User-defined types may provide reverse_endianness_in_place +for improved efficiency. —end note]

@@ -192,13 +198,13 @@ can be found by argument dependent lookup (ADL). —end note]

This subsection describes requirements on the endian library's own implementation.

-

The endianness conversion function templates that return values are +

The endianness reversal function templates that return values are required to perform reversal of endianness if needed by making an unqualified call to reverse_endianness(argument), as described in the preceding table.

-

The endianness conversion function templates that modify their argument in -place are required to perform reversal of endianness if needed by making an +

The endianness reversal function templates that modify their argument in +place, except reverse_endianness_in_place itself, are required to perform reversal of endianness if needed by making an unqualified call to reverse_endianness_in_place(argument), as described in the preceding table.

diff --git a/include/boost/endian/conversion.hpp b/include/boost/endian/conversion.hpp index bd4d682..9ccd444 100644 --- a/include/boost/endian/conversion.hpp +++ b/include/boost/endian/conversion.hpp @@ -39,7 +39,7 @@ namespace endian //--------------------------------------------------------------------------------------// // // // return-by-value interfaces // -// return-by-value suggested by Phil Endecott // +// suggested by Phil Endecott // // // // user-defined types (UDTs) // // // @@ -128,17 +128,10 @@ namespace endian // // //------------------------------------------------------------------------------------// - // customization for built-in arithmetic types - inline void reverse_endianness_in_place(int8_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(int16_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(int32_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(int64_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(uint8_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(uint16_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(uint32_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(uint64_t& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(float& x) BOOST_NOEXCEPT; - inline void reverse_endianness_in_place(double& x) BOOST_NOEXCEPT; + // reverse in place + template + inline void reverse_endianness_in_place(Value& x) BOOST_NOEXCEPT; + // Effects: x = reverse_endianness(x) // reverse in place unless native endianness is big template @@ -413,27 +406,12 @@ namespace endian // reverse-in-place implementation // //--------------------------------------------------------------------------------------// - // customization for built-in arithmetic types - inline void reverse_endianness_in_place(int8_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(int16_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(int32_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(int64_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(uint8_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(uint16_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(uint32_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(uint64_t& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(float& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } - inline void reverse_endianness_in_place(double& x) BOOST_NOEXCEPT - { x = reverse_endianness(x); } + // reverse in place + template + inline void reverse_endianness_in_place(Value& x) BOOST_NOEXCEPT + { + x = reverse_endianness(x); + } // reverse in place unless native endianness is big // Effects: none if native endian order is big, diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp index 329a0a8..88dbfa3 100644 --- a/test/conversion_test.cpp +++ b/test/conversion_test.cpp @@ -260,37 +260,107 @@ namespace BOOST_TEST_EQ(x, little); } + +//--------------------------------------------------------------------------------------// + + template + void udt_test() + { + UDT udt, tmp; + int64_t big; + int64_t little; + int64_t native; + big_value(big); + little_value(little); + native_value(native); + + udt.member1 = big; + udt.member2 = little; + udt.member3 = native; + + tmp = be::conditional_reverse(udt); + BOOST_TEST_EQ(tmp.member1, be::reverse_endianness(big)); + BOOST_TEST_EQ(tmp.member2, be::reverse_endianness(little)); + BOOST_TEST_EQ(tmp.member3, be::reverse_endianness(native)); + + be::conditional_reverse_in_place(udt); + BOOST_TEST_EQ(udt.member1, be::reverse_endianness(big)); + BOOST_TEST_EQ(udt.member2, be::reverse_endianness(little)); + BOOST_TEST_EQ(udt.member3, be::reverse_endianness(native)); + + udt.member1 = big; + udt.member2 = little; + udt.member3 = native; + tmp.member1 = tmp.member2 = tmp.member3 = 0; + + tmp = be::conditional_reverse(udt); + BOOST_TEST_EQ(tmp.member1, big); + BOOST_TEST_EQ(tmp.member2, little); + BOOST_TEST_EQ(tmp.member3, native); + + be::conditional_reverse_in_place(udt); + BOOST_TEST_EQ(udt.member1, big); + BOOST_TEST_EQ(udt.member2, little); + BOOST_TEST_EQ(udt.member3, native); + } } // unnamed namespace //--------------------------------------------------------------------------------------// - // User-defined type + // User-defined types namespace user { - struct UDT + // UDT1 supplies both reverse_endianness and reverse_endianness_in_place + struct UDT1 { int64_t member1; int64_t member2; int64_t member3; }; - UDT reverse_endianness(const UDT& udt) BOOST_NOEXCEPT + UDT1 reverse_endianness(const UDT1& udt) BOOST_NOEXCEPT { - UDT tmp; + UDT1 tmp; tmp.member1 = boost::endian::reverse_endianness(udt.member1); tmp.member2 = boost::endian::reverse_endianness(udt.member2); tmp.member3 = boost::endian::reverse_endianness(udt.member3); return tmp; } - void reverse_endianness_in_place(UDT& udt) BOOST_NOEXCEPT + void reverse_endianness_in_place(UDT1& udt) BOOST_NOEXCEPT { boost::endian::reverse_endianness_in_place(udt.member1); boost::endian::reverse_endianness_in_place(udt.member2); boost::endian::reverse_endianness_in_place(udt.member3); } + // UDT2 supplies only reverse_endianness + struct UDT2 + { + int64_t member1; + int64_t member2; + int64_t member3; + }; + + UDT2 reverse_endianness(const UDT2& udt) BOOST_NOEXCEPT + { + UDT2 tmp; + tmp.member1 = boost::endian::reverse_endianness(udt.member1); + tmp.member2 = boost::endian::reverse_endianness(udt.member2); + tmp.member3 = boost::endian::reverse_endianness(udt.member3); + return tmp; + } + + // UDT3 supplies neither reverse_endianness nor reverse_endianness_in_place, + // so udt_test() should fail to compile + struct UDT3 + { + int64_t member1; + int64_t member2; + int64_t member3; + }; + } // namespace user //--------------------------------------------------------------------------------------// @@ -326,30 +396,16 @@ int cpp_main(int, char * []) cout << "double" << endl; test(); - cout << "UDT" << endl; - user::UDT udt; - int64_t big; - int64_t little; - int64_t native; - big_value(big); - little_value(little); - native_value(native); + cout << "UDT 1" << endl; + udt_test(); - udt.member1 = big; - udt.member2 = little; - udt.member3 = native; - be::conditional_reverse_in_place(udt); - BOOST_TEST_EQ(udt.member1, be::reverse_endianness(big)); - BOOST_TEST_EQ(udt.member2, be::reverse_endianness(little)); - BOOST_TEST_EQ(udt.member3, be::reverse_endianness(native)); + cout << "UDT 2" << endl; + udt_test(); - udt.member1 = big; - udt.member2 = little; - udt.member3 = native; - be::conditional_reverse_in_place(udt); - BOOST_TEST_EQ(udt.member1, big); - BOOST_TEST_EQ(udt.member2, little); - BOOST_TEST_EQ(udt.member3, native); +#ifdef BOOST_ENDIAN_COMPILE_FAIL + cout << "UDT 3" << endl; + udt_test(); // should fail to compile since has not reverse_endianness() +#endif return ::boost::report_errors(); }