forked from boostorg/endian
Revert to again supply the reverse_endianness_in_place template. This has the effect of providing a default reverse_endianness_in_place for user-defined types. Add error checking for UDT's to verify this works as desired. Provide a note in the conversion docs to that effect.
This commit is contained in:
@@ -164,8 +164,8 @@ instantiating a template.</p>
|
||||
<code>x</code> is a value of a possibly <code>const</code> type convertible
|
||||
to <code>Reversible</code>.</td>
|
||||
<td>
|
||||
<p>The value of <code>x</code> with the
|
||||
order of its constituent bytes reversed is returned.</td>
|
||||
<p>Returns the value of <code>x</code> with the
|
||||
order of its constituent bytes reversed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">
|
||||
@@ -183,7 +183,13 @@ modifiable lvalue of type <code>Reversible</code>.</td>
|
||||
|
||||
<p> [<i>Note:</i> 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). <i>—end note</i>]</p>
|
||||
can be found by argument dependent lookup (ADL). <i>—end note</i>]</p>
|
||||
|
||||
<p> [<i>Note:</i> Because there is a function template for <code>reverse_endianness_in_place</code>
|
||||
that calls <code>reverse_endianness</code>, only <code>reverse_endianness</code>
|
||||
is required for a user-defined type to meet the <code>Reversible</code>
|
||||
requirements. User-defined types may provide <code>reverse_endianness_in_place</code>
|
||||
for improved efficiency. <i>—end note</i>]</p>
|
||||
|
||||
</blockquote>
|
||||
|
||||
@@ -192,13 +198,13 @@ can be found by argument dependent lookup (ADL). <i>—end note</i>]</p>
|
||||
<p> This subsection describes requirements on the endian library's own
|
||||
implementation.</p>
|
||||
|
||||
<p> The endianness conversion function templates that return values are
|
||||
<p> The endianness reversal function templates that return values are
|
||||
required to perform reversal of endianness if needed by making an unqualified
|
||||
call to <code>reverse_endianness(<i>argument</i>)</code>, as described in the
|
||||
preceding table.</p>
|
||||
|
||||
<p> The endianness conversion function templates that modify their argument in
|
||||
place are required to perform reversal of endianness if needed by making an
|
||||
<p> The endianness reversal function templates that modify their argument in
|
||||
place, except <code>reverse_endianness_in_place</code> itself, are required to perform reversal of endianness if needed by making an
|
||||
unqualified call to <code>reverse_endianness_in_place(<i>argument</i>)</code>,
|
||||
as described in the preceding table.</p>
|
||||
|
||||
|
@@ -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 <class Value>
|
||||
inline void reverse_endianness_in_place(Value& x) BOOST_NOEXCEPT;
|
||||
// Effects: x = reverse_endianness(x)
|
||||
|
||||
// reverse in place unless native endianness is big
|
||||
template <class Reversible>
|
||||
@@ -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 <class Value>
|
||||
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,
|
||||
|
@@ -260,37 +260,107 @@ namespace
|
||||
BOOST_TEST_EQ(x, little);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
template <class UDT>
|
||||
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<be::order::big, be::order::little>(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<be::order::big, be::order::little>(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<be::order::big, be::order::big>(udt);
|
||||
BOOST_TEST_EQ(tmp.member1, big);
|
||||
BOOST_TEST_EQ(tmp.member2, little);
|
||||
BOOST_TEST_EQ(tmp.member3, native);
|
||||
|
||||
be::conditional_reverse_in_place<be::order::big, be::order::big>(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<UDT3>() 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<double>();
|
||||
|
||||
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<user::UDT1>();
|
||||
|
||||
udt.member1 = big;
|
||||
udt.member2 = little;
|
||||
udt.member3 = native;
|
||||
be::conditional_reverse_in_place<be::order::big, be::order::little>(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<user::UDT2>();
|
||||
|
||||
udt.member1 = big;
|
||||
udt.member2 = little;
|
||||
udt.member3 = native;
|
||||
be::conditional_reverse_in_place<be::order::big, be::order::big>(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<user::UDT3>(); // should fail to compile since has not reverse_endianness()
|
||||
#endif
|
||||
|
||||
return ::boost::report_errors();
|
||||
}
|
||||
|
Reference in New Issue
Block a user