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.
@@ -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();
}