For the endian types, add stream inserters and extractors as requested during the formal review.

This commit is contained in:
Beman
2014-11-11 21:08:08 -05:00
parent a1be441f8f
commit c41521cead
6 changed files with 113 additions and 26 deletions

View File

@@ -622,6 +622,8 @@ and 16, 32, and 64-bit aligned integers.</p>
Infrastructure file names were changed accordingly.</li> Infrastructure file names were changed accordingly.</li>
<li>The endian types and endian conversion functions now support 32-bit (<code>float)</code> and <li>The endian types and endian conversion functions now support 32-bit (<code>float)</code> and
64-bit <code>(double)</code> floating point, as requested.</li> 64-bit <code>(double)</code> floating point, as requested.</li>
<li>The endian types now have stream inserter and extractor templates, as
requested.</li>
<li>Both the endian types and endian conversion functions now support UDTs, as requested.</li> <li>Both the endian types and endian conversion functions now support UDTs, as requested.</li>
<li>The endian type aliases have been renamed, <li>The endian type aliases have been renamed,
using a naming pattern that is consistent for both integer and floating point.</li> using a naming pattern that is consistent for both integer and floating point.</li>
@@ -670,13 +672,11 @@ Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and
Vitaly Budovski,.</p> Vitaly Budovski,.</p>
<hr> <hr>
<p>Last revised: <p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->12 August, 2014<!--webbot bot="Timestamp" endspan i-checksum="34569" --></p> <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->11 November, 2014<!--webbot bot="Timestamp" endspan i-checksum="39483" --></p>
<p>© Copyright Beman Dawes, 2011, 2013</p> <p>© Copyright Beman Dawes, 2011, 2013</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>
<p>&nbsp;</p>
</body> </body>
</html> </html>

View File

@@ -76,7 +76,7 @@ the primary use case.</b></p>
<p><b>Support for user defined types (UDTs) is desirable, and should be <p><b>Support for user defined types (UDTs) is desirable, and should be
provided where there would be no conflict with the other concerns.</b></p> provided where there would be no conflict with the other concerns.</b></p>
<blockquote> <blockquote>
<p>&nbsp;</p> <p>Done.</p>
</blockquote> </blockquote>
<p><b>There is some concern that endian integer/float arithmetic operations <p><b>There is some concern that endian integer/float arithmetic operations
might used inadvertently or inappropriately. The impact of adding an endian_buffer might used inadvertently or inappropriately. The impact of adding an endian_buffer
@@ -86,7 +86,10 @@ might used inadvertently or inappropriately. The impact of adding an endian_buff
</blockquote> </blockquote>
<p><b>Stream insertion and extraction of the endian integer/float types should <p><b>Stream insertion and extraction of the endian integer/float types should
be documented and included in the test coverage.</b></p> be documented and included in the test coverage.</b></p>
<p>&nbsp;</p> <blockquote>
<p>Done. See <a href="types.html#Stream-inserter">Stream inserter</a> and
<a href="types.html#Stream-extractor">Stream extractor</a>.</p>
</blockquote>
<p><b>Binary I/O support that was investigated during development of the Endian <p><b>Binary I/O support that was investigated during development of the Endian
library should be put up for mini-review for inclusion in the Boost I/O library should be put up for mini-review for inclusion in the Boost I/O
library.</b></p> library.</b></p>

View File

@@ -55,6 +55,8 @@
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
<a href="#Synopsis">Synopsis</a><br> <a href="#Synopsis">Synopsis</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Members">Members</a><br> &nbsp;&nbsp;&nbsp; <a href="#Members">Members</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Stream-inserter">Stream inserter</a><br>
&nbsp;&nbsp;&nbsp; <a href="#Stream-extractor">Stream extractor</a><br>
<a href="#FAQ">FAQ</a><br> <a href="#FAQ">FAQ</a><br>
<a href="#Design">Design</a><br> <a href="#Design">Design</a><br>
<a href="#Experience">Experience</a><br> <a href="#Experience">Experience</a><br>
@@ -374,11 +376,11 @@ usual operations on integers are supplied.</p>
enum class <a name="alignment">align</a> {no, yes}; enum class <a name="alignment">align</a> {no, yes};
template &lt;order Order, typename T, std::size_t n_bits, align A = align::no&gt; template &lt;order Order, class T, std::size_t n_bits, align A = align::no&gt;
class endian class endian
{ {
public: public:
typedef T value_type; typedef T value_type;
// if BOOST_ENDIAN_FORCE_PODNESS is defined &amp;&amp; C++11 POD's are not // if BOOST_ENDIAN_FORCE_PODNESS is defined &amp;&amp; C++11 POD's are not
// available then these two constructors will not be present // available then these two constructors will not be present
@@ -408,8 +410,20 @@ usual operations on integers are supplied.</p>
endian&amp; operator--(endian&amp; x) noexcept; endian&amp; operator--(endian&amp; x) noexcept;
endian operator++(endian&amp; x, int) noexcept; endian operator++(endian&amp; x, int) noexcept;
endian operator--(endian&amp; x, int) noexcept; endian operator--(endian&amp; x, int) noexcept;
// Stream inserter
template &lt;class charT, class traits&gt;
friend std::basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;charT, traits&gt;&amp; os, const T&amp; x);
// Stream extractor
template &lt;class charT, class traits&gt;
friend std::basic_istream&lt;charT, traits&gt;&amp;
operator&gt;&gt;(std::basic_istream&lt;charT, traits&gt;&amp; is, T&amp; x);
}; };
// typedefs
// aligned big endian floating point types // aligned big endian floating point types
typedef endian&lt;order::big, float, 32, align::yes&gt; big_align_float32_t; typedef endian&lt;order::big, float, 32, align::yes&gt; big_align_float32_t;
typedef endian&lt;order::big, double, 64, align::yes&gt; big_align_float64_t; typedef endian&lt;order::big, double, 64, align::yes&gt; big_align_float64_t;
@@ -546,6 +560,29 @@ in <code>*this</code>.</p>
<h3>Other operators</h3> <h3>Other operators</h3>
<p>Other operators on endian objects are forwarded to the equivalent <p>Other operators on endian objects are forwarded to the equivalent
operator on <code>value_type</code>.</p> operator on <code>value_type</code>.</p>
<h3><a name="Stream-inserter">Stream inserter</a></h3>
<pre>template &lt;class charT, class traits&gt;
friend std::basic_ostream&lt;charT, traits&gt;&amp;
operator&lt;&lt;(std::basic_ostream&lt;charT, traits&gt;&amp; os, const T&amp; x);
</pre>
<blockquote>
<p><i>Returns:</i> <code>os &lt;&lt; +x</code>.</p>
</blockquote>
<h3><a name="Stream-extractor">Stream extractor</a></h3>
<pre>template &lt;class charT, class traits&gt;
friend std::basic_istream&lt;charT, traits&gt;&amp;
operator&gt;&gt;(std::basic_istream&lt;charT, traits&gt;&amp; is, T&amp; x);
</pre>
<blockquote>
<p><i>Effects: </i>As if:</p>
<blockquote>
<pre>T i;
if (is &gt;&gt; i)
x = i;
</pre>
</blockquote>
<p><i>Returns: </i><code>is</code><i>.</i></p>
</blockquote>
<h2><a name="FAQ">FAQ</a></h2> <h2><a name="FAQ">FAQ</a></h2>
<p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide <p>See the <a href="index.html#FAQ">Endian home page</a> FAQ for a library-wide
@@ -557,7 +594,7 @@ conversion or copying. They are already in the desired format for binary I/O.
Thus they can be read or written in bulk.</p> Thus they can be read or written in bulk.</p>
<p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several <p><b>Are endian types POD's?</b> Yes for C++11. No for C++03, although several
<a href="#Compilation">macros</a> are available to force PODness in all cases.</p> <a href="#Compilation">macros</a> are available to force PODness in all cases.</p>
<p><b>What are the implications endian integer types not being POD's with C++03 <p><b>What are the implications of endian integer types not being POD's with C++03
compilers?</b> They compilers?</b> They
can't be used in unions. Also, compilers aren't required to align or lay 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 out storage in portable ways, although this potential problem hasn't prevented
@@ -643,7 +680,7 @@ differs from endian representation size. Vicente Botet and other reviewers
suggested supporting floating point types.</p> suggested supporting floating point types.</p>
<hr> <hr>
<p>Last revised: <p>Last revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->15 August, 2014<!--webbot bot="Timestamp" endspan i-checksum="34575" --></p> <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->11 November, 2014<!--webbot bot="Timestamp" endspan i-checksum="39483" --></p>
<p>© Copyright Beman Dawes, 2006-2009, 2013</p> <p>© Copyright Beman Dawes, 2006-2009, 2013</p>
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p>

View File

@@ -96,19 +96,25 @@ namespace boost
# endif # endif
# ifndef BOOST_NO_IO_COVER_OPERATORS # ifndef BOOST_NO_IO_COVER_OPERATORS
// TODO: stream I/O needs to be templatized on the stream type, so will
// work with wide streams, etc.
// Stream input and output. // Stream inserter
friend std::ostream& operator<<(std::ostream& s, const T& x) template <class charT, class traits>
{ return s << +x; } friend std::basic_ostream<charT, traits>&
friend std::istream& operator>>(std::istream& s, T& x) operator<<(std::basic_ostream<charT, traits>& os, const T& x)
{ {
IntegerType i; return os << +x;
if (s >> i) }
x = i;
return s; // Stream extractor
} template <class charT, class traits>
friend std::basic_istream<charT, traits>&
operator>>(std::basic_istream<charT, traits>& is, T& x)
{
IntegerType i;
if (is >> i)
x = i;
return is;
}
# endif # endif
}; };
} // namespace endian } // namespace endian

View File

@@ -38,9 +38,9 @@
#include <boost/predef/detail/endian_compat.h> #include <boost/predef/detail/endian_compat.h>
#include <boost/endian/conversion.hpp> #include <boost/endian/conversion.hpp>
#define BOOST_MINIMAL_INTEGER_COVER_OPERATORS #define BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#define BOOST_NO_IO_COVER_OPERATORS //#define BOOST_NO_IO_COVER_OPERATORS
#include <boost/endian/detail/cover_operators.hpp> #include <boost/endian/detail/cover_operators.hpp>
#undef BOOST_NO_IO_COVER_OPERATORS //#undef BOOST_NO_IO_COVER_OPERATORS
#undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS #undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS
#include <boost/type_traits/is_signed.hpp> #include <boost/type_traits/is_signed.hpp>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
@@ -90,7 +90,7 @@ namespace endian
#endif #endif
BOOST_SCOPED_ENUM_START(align) {no, yes}; BOOST_SCOPED_ENUM_END BOOST_SCOPED_ENUM_START(align) {no, yes}; BOOST_SCOPED_ENUM_END
template <BOOST_SCOPED_ENUM(order) Order, typename T, std::size_t n_bits, template <BOOST_SCOPED_ENUM(order) Order, classname T, std::size_t n_bits,
BOOST_SCOPED_ENUM(align) A = align::no> BOOST_SCOPED_ENUM(align) A = align::no>
class endian; class endian;

View File

@@ -46,10 +46,11 @@
#include <boost/endian/types.hpp> #include <boost/endian/types.hpp>
#include <boost/type_traits/is_signed.hpp> #include <boost/type_traits/is_signed.hpp>
#include <boost/detail/lightweight_test.hpp> #include <boost/core/lightweight_test.hpp>
#include <boost/detail/lightweight_main.hpp> #include <boost/detail/lightweight_main.hpp>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <sstream>
namespace be = boost::endian; namespace be = boost::endian;
@@ -343,6 +344,44 @@ void op_test()
#endif #endif
} }
// test_inserter_and_extractor -----------------------------------------------------//
void test_inserter_and_extractor()
{
std::cout << "test inserter and extractor..." << std::endl;
be::big_uint64_t bu64(0x010203040506070ULL);
be::little_uint64_t lu64(0x010203040506070ULL);
uint64_t x;
std::stringstream ss;
ss << bu64;
ss >> x;
BOOST_TEST_EQ(x, 0x010203040506070ULL);
ss.clear();
ss << lu64;
ss >> x;
BOOST_TEST_EQ(x, 0x010203040506070ULL);
ss.clear();
ss << 0x010203040506070ULL;
be::big_uint64_t bu64z(0);
ss >> bu64z;
BOOST_TEST_EQ(bu64z, bu64);
ss.clear();
ss << 0x010203040506070ULL;
be::little_uint64_t lu64z(0);
ss >> lu64z;
BOOST_TEST_EQ(lu64z, lu64);
std::cout << "test inserter and extractor complete" << std::endl;
}
void f_big_int32_t(be::big_int32_t) {} void f_big_int32_t(be::big_int32_t) {}
// main ------------------------------------------------------------------------------// // main ------------------------------------------------------------------------------//
@@ -448,6 +487,8 @@ int cpp_main(int, char * [])
std::clog << "\n"; std::clog << "\n";
be::endian_log = false; be::endian_log = false;
test_inserter_and_extractor();
// perform the indicated test on ~60*60 operand types // perform the indicated test on ~60*60 operand types
@@ -459,5 +500,5 @@ int cpp_main(int, char * [])
op_test<op_plus>(); op_test<op_plus>();
op_test<op_star>(); op_test<op_star>();
return 0; return boost::report_errors();
} }