| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 | //  boost/endian/buffers.hpp  ----------------------------------------------------------////  (C) Copyright Darin Adler 2000//  (C) Copyright Beman Dawes 2006, 2009, 2014//  (C) Copyright Peter Dimov 2019//  Distributed under the Boost Software License, Version 1.0.//  See http://www.boost.org/LICENSE_1_0.txt//  See library home page at http://www.boost.org/libs/endian//--------------------------------------------------------------------------------------////  Original design developed by Darin Adler based on classes developed by Mark//  Borgerding. Four original class templates were combined into a single endian//  class template by Beman Dawes, who also added the unrolled_byte_loops sign//  partial specialization to correctly extend the sign when cover integer size//  differs from endian representation size.// TODO: When a compiler supporting constexpr becomes available, try possible uses.#ifndef BOOST_ENDIAN_BUFFERS_HPP#define BOOST_ENDIAN_BUFFERS_HPP#if defined(_MSC_VER)# pragma warning(push)# pragma warning(disable: 4127)  // conditional expression is constant#endif#include <boost/endian/detail/endian_store.hpp>#include <boost/endian/detail/endian_load.hpp>#include <boost/core/scoped_enum.hpp>#include <boost/static_assert.hpp>#include <boost/cstdint.hpp>#include <boost/config.hpp>#include <boost/config/workaround.hpp>#include <iosfwd>#include <climits>#include <cstring>#if defined(__BORLANDC__) || defined( __CODEGEARC__)# pragma pack(push, 1)#endif# if CHAR_BIT != 8#   error Platforms with CHAR_BIT != 8 are not supported# endif# ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS#   define BOOST_ENDIAN_DEFAULT_CONSTRUCT {}          // C++03# else#   define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default;  // C++0x# endif// g++ pre-4.6 does not support unrestricted unions, but we have no Config macro for that# if (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || BOOST_WORKAROUND(BOOST_GCC, < 40600)) && defined(BOOST_ENDIAN_FORCE_PODNESS)#   define BOOST_ENDIAN_NO_CTORS# endif//----------------------------------  synopsis  ----------------------------------------//namespace boost{namespace endian{  BOOST_SCOPED_ENUM_START(align)  {no, yes#   ifdef BOOST_ENDIAN_DEPRECATED_NAMES      , unaligned = no, aligned = yes#   endif  }; BOOST_SCOPED_ENUM_END  template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,    BOOST_SCOPED_ENUM(align) A = align::no>      class endian_buffer;  // aligned big endian signed integer buffers  typedef endian_buffer<order::big, int8_t, 8, align::yes>       big_int8_buf_at;  typedef endian_buffer<order::big, int16_t, 16, align::yes>     big_int16_buf_at;  typedef endian_buffer<order::big, int32_t, 32, align::yes>     big_int32_buf_at;  typedef endian_buffer<order::big, int64_t, 64, align::yes>     big_int64_buf_at;  // aligned big endian unsigned integer buffers  typedef endian_buffer<order::big, uint8_t, 8, align::yes>      big_uint8_buf_at;  typedef endian_buffer<order::big, uint16_t, 16, align::yes>    big_uint16_buf_at;  typedef endian_buffer<order::big, uint32_t, 32, align::yes>    big_uint32_buf_at;  typedef endian_buffer<order::big, uint64_t, 64, align::yes>    big_uint64_buf_at;  // aligned little endian signed integer buffers  typedef endian_buffer<order::little, int8_t, 8, align::yes>    little_int8_buf_at;  typedef endian_buffer<order::little, int16_t, 16, align::yes>  little_int16_buf_at;  typedef endian_buffer<order::little, int32_t, 32, align::yes>  little_int32_buf_at;  typedef endian_buffer<order::little, int64_t, 64, align::yes>  little_int64_buf_at;  // aligned little endian unsigned integer buffers  typedef endian_buffer<order::little, uint8_t, 8, align::yes>   little_uint8_buf_at;  typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;  typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;  typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;  // aligned floating point buffers  typedef endian_buffer<order::big, float, 32, align::yes>       big_float32_buf_at;  typedef endian_buffer<order::big, double, 64, align::yes>      big_float64_buf_at;  typedef endian_buffer<order::little, float, 32, align::yes>    little_float32_buf_at;  typedef endian_buffer<order::little, double, 64, align::yes>   little_float64_buf_at;  // aligned native endian typedefs are not provided because  // <cstdint> types are superior for this use case  // unaligned big endian signed integer buffers  typedef endian_buffer<order::big, int_least8_t, 8>        big_int8_buf_t;  typedef endian_buffer<order::big, int_least16_t, 16>      big_int16_buf_t;  typedef endian_buffer<order::big, int_least32_t, 24>      big_int24_buf_t;  typedef endian_buffer<order::big, int_least32_t, 32>      big_int32_buf_t;  typedef endian_buffer<order::big, int_least64_t, 40>      big_int40_buf_t;  typedef endian_buffer<order::big, int_least64_t, 48>      big_int48_buf_t;  typedef endian_buffer<order::big, int_least64_t, 56>      big_int56_buf_t;  typedef endian_buffer<order::big, int_least64_t, 64>      big_int64_buf_t;  // unaligned big endian unsigned integer buffers  typedef endian_buffer<order::big, uint_least8_t, 8>       big_uint8_buf_t;  typedef endian_buffer<order::big, uint_least16_t, 16>     big_uint16_buf_t;  typedef endian_buffer<order::big, uint_least32_t, 24>     big_uint24_buf_t;  typedef endian_buffer<order::big, uint_least32_t, 32>     big_uint32_buf_t;  typedef endian_buffer<order::big, uint_least64_t, 40>     big_uint40_buf_t;  typedef endian_buffer<order::big, uint_least64_t, 48>     big_uint48_buf_t;  typedef endian_buffer<order::big, uint_least64_t, 56>     big_uint56_buf_t;  typedef endian_buffer<order::big, uint_least64_t, 64>     big_uint64_buf_t;  // unaligned little endian signed integer buffers  typedef endian_buffer<order::little, int_least8_t, 8>     little_int8_buf_t;  typedef endian_buffer<order::little, int_least16_t, 16>   little_int16_buf_t;  typedef endian_buffer<order::little, int_least32_t, 24>   little_int24_buf_t;  typedef endian_buffer<order::little, int_least32_t, 32>   little_int32_buf_t;  typedef endian_buffer<order::little, int_least64_t, 40>   little_int40_buf_t;  typedef endian_buffer<order::little, int_least64_t, 48>   little_int48_buf_t;  typedef endian_buffer<order::little, int_least64_t, 56>   little_int56_buf_t;  typedef endian_buffer<order::little, int_least64_t, 64>   little_int64_buf_t;  // unaligned little endian unsigned integer buffers  typedef endian_buffer<order::little, uint_least8_t, 8>    little_uint8_buf_t;  typedef endian_buffer<order::little, uint_least16_t, 16>  little_uint16_buf_t;  typedef endian_buffer<order::little, uint_least32_t, 24>  little_uint24_buf_t;  typedef endian_buffer<order::little, uint_least32_t, 32>  little_uint32_buf_t;  typedef endian_buffer<order::little, uint_least64_t, 40>  little_uint40_buf_t;  typedef endian_buffer<order::little, uint_least64_t, 48>  little_uint48_buf_t;  typedef endian_buffer<order::little, uint_least64_t, 56>  little_uint56_buf_t;  typedef endian_buffer<order::little, uint_least64_t, 64>  little_uint64_buf_t;  // unaligned native endian signed integer buffers  typedef endian_buffer<order::native, int_least8_t, 8>     native_int8_buf_t;  typedef endian_buffer<order::native, int_least16_t, 16>   native_int16_buf_t;  typedef endian_buffer<order::native, int_least32_t, 24>   native_int24_buf_t;  typedef endian_buffer<order::native, int_least32_t, 32>   native_int32_buf_t;  typedef endian_buffer<order::native, int_least64_t, 40>   native_int40_buf_t;  typedef endian_buffer<order::native, int_least64_t, 48>   native_int48_buf_t;  typedef endian_buffer<order::native, int_least64_t, 56>   native_int56_buf_t;  typedef endian_buffer<order::native, int_least64_t, 64>   native_int64_buf_t;  // unaligned native endian unsigned integer buffers  typedef endian_buffer<order::native, uint_least8_t, 8>    native_uint8_buf_t;  typedef endian_buffer<order::native, uint_least16_t, 16>  native_uint16_buf_t;  typedef endian_buffer<order::native, uint_least32_t, 24>  native_uint24_buf_t;  typedef endian_buffer<order::native, uint_least32_t, 32>  native_uint32_buf_t;  typedef endian_buffer<order::native, uint_least64_t, 40>  native_uint40_buf_t;  typedef endian_buffer<order::native, uint_least64_t, 48>  native_uint48_buf_t;  typedef endian_buffer<order::native, uint_least64_t, 56>  native_uint56_buf_t;  typedef endian_buffer<order::native, uint_least64_t, 64>  native_uint64_buf_t;  // unaligned floating point buffers  typedef endian_buffer<order::big, float, 32, align::no>       big_float32_buf_t;  typedef endian_buffer<order::big, double, 64, align::no>      big_float64_buf_t;  typedef endian_buffer<order::little, float, 32, align::no>    little_float32_buf_t;  typedef endian_buffer<order::little, double, 64, align::no>   little_float64_buf_t;  typedef endian_buffer<order::native, float, 32, align::no>    native_float32_buf_t;  typedef endian_buffer<order::native, double, 64, align::no>   native_float64_buf_t;  // Stream inserter  template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,    std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>  std::basic_ostream<charT, traits>&    operator<<(std::basic_ostream<charT, traits>& os,      const endian_buffer<Order, T, n_bits, A>& x)  {    return os << x.value();  }  // Stream extractor  template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,    std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>  std::basic_istream<charT, traits>&    operator>>(std::basic_istream<charT, traits>& is,      endian_buffer<Order, T, n_bits, A>& x)  {    T i;    if (is >> i)      x = i;    return is;  }//----------------------------------  end synopsis  ------------------------------------////  endian_buffer class template specializations  --------------------------------------////  Specializations that represent unaligned bytes.//  Taking an integer type as a parameter provides a nice way to pass both//  the size and signedness of the desired integer and get the appropriate//  corresponding integer type for the interface.// Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?// A: No. The rationale for endian_buffers is to prevent high-cost hidden//    conversions. If an implicit conversion operator is supplied, hidden conversions//    can occur.//  unaligned endian_buffer specializationtemplate< BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits >class endian_buffer<Order, T, n_bits, align::no>{private:    BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );    unsigned char value_[ n_bits / 8 ];public:    typedef T value_type;#ifndef BOOST_ENDIAN_NO_CTORS    endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT    explicit endian_buffer( T val ) BOOST_NOEXCEPT    {        boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );    }#endif    endian_buffer& operator=( T val ) BOOST_NOEXCEPT    {        boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );        return *this;    }    value_type value() const BOOST_NOEXCEPT    {        return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );    }    unsigned char const * data() const BOOST_NOEXCEPT    {        return value_;    }    unsigned char * data() BOOST_NOEXCEPT    {        return value_;    }};// aligned specializations; only n_bits == 16/32/64 supported// aligned endian_buffer specializationtemplate< BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits >class endian_buffer<Order, T, n_bits, align::yes>{private:    BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );    BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );    union    {        unsigned char value_[ n_bits / 8 ];        T align_;    };public:    typedef T value_type;#ifndef BOOST_ENDIAN_NO_CTORS    endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT    explicit endian_buffer( T val ) BOOST_NOEXCEPT    {        boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );    }#endif    endian_buffer& operator=( T val ) BOOST_NOEXCEPT    {        boost::endian::endian_store<T, n_bits / 8, Order>( value_, val );        return *this;    }    value_type value() const BOOST_NOEXCEPT    {        return boost::endian::endian_load<T, n_bits / 8, Order>( value_ );    }    unsigned char const * data() const BOOST_NOEXCEPT    {        return value_;    }    unsigned char * data() BOOST_NOEXCEPT    {        return value_;    }};// aligned native endian_buffer specializationtemplate< class T, std::size_t n_bits >class endian_buffer<order::native, T, n_bits, align::yes>{private:    BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );    BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );    T value_;public:    typedef T value_type;#ifndef BOOST_ENDIAN_NO_CTORS    endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT    explicit endian_buffer( T val ) BOOST_NOEXCEPT: value_( val )    {    }#endif    endian_buffer& operator=( T val ) BOOST_NOEXCEPT    {        value_ = val;        return *this;    }    value_type value() const BOOST_NOEXCEPT    {        return value_;    }    unsigned char const * data() const BOOST_NOEXCEPT    {        return reinterpret_cast< unsigned char const* >( &value_ );    }    unsigned char * data() BOOST_NOEXCEPT    {        return reinterpret_cast< unsigned char* >( &value_ );    }};} // namespace endian} // namespace boost#if defined(__BORLANDC__) || defined( __CODEGEARC__)# pragma pack(pop)#endif#if defined(_MSC_VER)# pragma warning(pop)#endif#endif // BOOST_ENDIAN_BUFFERS_HPP
 |