From c41521ceadb51cbb4e8dbe20dd3b5b670fa40e26 Mon Sep 17 00:00:00 2001 From: Beman Date: Tue, 11 Nov 2014 21:08:08 -0500 Subject: [PATCH] For the endian types, add stream inserters and extractors as requested during the formal review. --- doc/index.html | 6 +-- doc/mini_review_topics.html | 7 ++- doc/types.html | 45 +++++++++++++++++-- .../boost/endian/detail/cover_operators.hpp | 30 ++++++++----- include/boost/endian/types.hpp | 6 +-- test/endian_operations_test.cpp | 45 ++++++++++++++++++- 6 files changed, 113 insertions(+), 26 deletions(-) diff --git a/doc/index.html b/doc/index.html index 6c6f3c4..4e99e37 100644 --- a/doc/index.html +++ b/doc/index.html @@ -622,6 +622,8 @@ and 16, 32, and 64-bit aligned integers.

Infrastructure file names were changed accordingly.
  • The endian types and endian conversion functions now support 32-bit (float) and 64-bit (double) floating point, as requested.
  • +
  • The endian types now have stream inserter and extractor templates, as + requested.
  • Both the endian types and endian conversion functions now support UDTs, as requested.
  • The endian type aliases have been renamed, using a naming pattern that is consistent for both integer and floating point.
  • @@ -670,13 +672,11 @@ Blechmann, Tim Moore, tymofey, Tomas Puverle, Vincente Botet, Yuval Ronen and Vitaly Budovski,.


    Last revised: -12 August, 2014

    +11 November, 2014

    © Copyright Beman Dawes, 2011, 2013

    Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

    -

     

    - \ No newline at end of file diff --git a/doc/mini_review_topics.html b/doc/mini_review_topics.html index 9d5e6bd..e8a3662 100644 --- a/doc/mini_review_topics.html +++ b/doc/mini_review_topics.html @@ -76,7 +76,7 @@ the primary use case.

    Support for user defined types (UDTs) is desirable, and should be provided where there would be no conflict with the other concerns.

    -

     

    +

    Done.

    There is some concern that endian integer/float arithmetic operations 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

    Stream insertion and extraction of the endian integer/float types should be documented and included in the test coverage.

    -

     

    +
    +

    Done. See Stream inserter and + Stream extractor.

    +

    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.

    diff --git a/doc/types.html b/doc/types.html index 1d20ae3..172a6a2 100644 --- a/doc/types.html +++ b/doc/types.html @@ -55,6 +55,8 @@     Synopsis
        Members
    +    Stream inserter
    +    Stream extractor
    FAQ
    Design
    Experience
    @@ -374,11 +376,11 @@ usual operations on integers are supplied.

    enum class align {no, yes}; - template <order Order, typename T, std::size_t n_bits, align A = align::no> + template <order Order, class T, std::size_t n_bits, align A = align::no> class endian { public: - typedef T value_type; + typedef T value_type; // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++11 POD's are not // available then these two constructors will not be present @@ -408,8 +410,20 @@ usual operations on integers are supplied.

    endian& operator--(endian& x) noexcept; endian operator++(endian& x, int) noexcept; endian operator--(endian& x, int) noexcept; + + // Stream inserter + template <class charT, class traits> + friend std::basic_ostream<charT, traits>& + operator<<(std::basic_ostream<charT, traits>& os, const T& x); + + // Stream extractor + template <class charT, class traits> + friend std::basic_istream<charT, traits>& + operator>>(std::basic_istream<charT, traits>& is, T& x); }; + // typedefs + // aligned big endian floating point types typedef endian<order::big, float, 32, align::yes> big_align_float32_t; typedef endian<order::big, double, 64, align::yes> big_align_float64_t; @@ -546,6 +560,29 @@ in *this.

    Other operators

    Other operators on endian objects are forwarded to the equivalent operator on value_type.

    +

    Stream inserter

    +
    template <class charT, class traits>
    +friend std::basic_ostream<charT, traits>&
    +  operator<<(std::basic_ostream<charT, traits>& os, const T& x);
    +
    +
    +

    Returns: os << +x.

    +
    +

    Stream extractor

    +
    template <class charT, class traits>
    +friend std::basic_istream<charT, traits>&
    +  operator>>(std::basic_istream<charT, traits>& is, T& x);
    +
    +
    +

    Effects: As if:

    +
    +
    T i;
    +if (is >> i)
    +  x = i;
    +
    +
    +

    Returns: is.

    +

    FAQ

    See the Endian home page 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.

    Are endian types POD's? Yes for C++11. No for C++03, although several macros are available to force PODness in all cases.

    -

    What are the implications endian integer types not being POD's with C++03 +

    What are the implications of endian integer types not being POD's with C++03 compilers? They 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 @@ -643,7 +680,7 @@ differs from endian representation size. Vicente Botet and other reviewers suggested supporting floating point types.


    Last revised: -15 August, 2014

    +11 November, 2014

    © Copyright Beman Dawes, 2006-2009, 2013

    Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt

    diff --git a/include/boost/endian/detail/cover_operators.hpp b/include/boost/endian/detail/cover_operators.hpp index e0abd3c..72bf395 100644 --- a/include/boost/endian/detail/cover_operators.hpp +++ b/include/boost/endian/detail/cover_operators.hpp @@ -96,19 +96,25 @@ namespace boost # endif # 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. - friend std::ostream& operator<<(std::ostream& s, const T& x) - { return s << +x; } - friend std::istream& operator>>(std::istream& s, T& x) - { - IntegerType i; - if (s >> i) - x = i; - return s; - } + // Stream inserter + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const T& x) + { + return os << +x; + } + + // Stream extractor + template + friend std::basic_istream& + operator>>(std::basic_istream& is, T& x) + { + IntegerType i; + if (is >> i) + x = i; + return is; + } # endif }; } // namespace endian diff --git a/include/boost/endian/types.hpp b/include/boost/endian/types.hpp index b46fd72..8e857ce 100644 --- a/include/boost/endian/types.hpp +++ b/include/boost/endian/types.hpp @@ -38,9 +38,9 @@ #include #include #define BOOST_MINIMAL_INTEGER_COVER_OPERATORS -#define BOOST_NO_IO_COVER_OPERATORS +//#define BOOST_NO_IO_COVER_OPERATORS #include -#undef BOOST_NO_IO_COVER_OPERATORS +//#undef BOOST_NO_IO_COVER_OPERATORS #undef BOOST_MINIMAL_INTEGER_COVER_OPERATORS #include #include @@ -90,7 +90,7 @@ namespace endian #endif BOOST_SCOPED_ENUM_START(align) {no, yes}; BOOST_SCOPED_ENUM_END - template class endian; diff --git a/test/endian_operations_test.cpp b/test/endian_operations_test.cpp index 7d225c6..5d4c252 100644 --- a/test/endian_operations_test.cpp +++ b/test/endian_operations_test.cpp @@ -46,10 +46,11 @@ #include #include -#include +#include #include #include #include +#include namespace be = boost::endian; @@ -343,6 +344,44 @@ void op_test() #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) {} // main ------------------------------------------------------------------------------// @@ -448,6 +487,8 @@ int cpp_main(int, char * []) std::clog << "\n"; be::endian_log = false; + + test_inserter_and_extractor(); // perform the indicated test on ~60*60 operand types @@ -459,5 +500,5 @@ int cpp_main(int, char * []) op_test(); op_test(); - return 0; + return boost::report_errors(); }