annotate DEPENDENCIES/generic/include/boost/endian/buffers.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // boost/endian/buffers.hpp ----------------------------------------------------------//
Chris@102 2
Chris@102 3 // (C) Copyright Darin Adler 2000
Chris@102 4 // (C) Copyright Beman Dawes 2006, 2009, 2014
Chris@102 5
Chris@102 6 // Distributed under the Boost Software License, Version 1.0.
Chris@102 7 // See http://www.boost.org/LICENSE_1_0.txt
Chris@102 8
Chris@102 9 // See library home page at http://www.boost.org/libs/endian
Chris@102 10
Chris@102 11 //--------------------------------------------------------------------------------------//
Chris@102 12
Chris@102 13 // Original design developed by Darin Adler based on classes developed by Mark
Chris@102 14 // Borgerding. Four original class templates were combined into a single endian
Chris@102 15 // class template by Beman Dawes, who also added the unrolled_byte_loops sign
Chris@102 16 // partial specialization to correctly extend the sign when cover integer size
Chris@102 17 // differs from endian representation size.
Chris@102 18
Chris@102 19 // TODO: When a compiler supporting constexpr becomes available, try possible uses.
Chris@102 20
Chris@102 21 #ifndef BOOST_ENDIAN_BUFFERS_HPP
Chris@102 22 #define BOOST_ENDIAN_BUFFERS_HPP
Chris@102 23
Chris@102 24 #if defined(_MSC_VER)
Chris@102 25 # pragma warning(push)
Chris@102 26 # pragma warning(disable:4365) // conversion ... signed/unsigned mismatch
Chris@102 27 #endif
Chris@102 28
Chris@102 29 #ifdef BOOST_ENDIAN_LOG
Chris@102 30 # include <iostream>
Chris@102 31 #endif
Chris@102 32
Chris@102 33 #if defined(__BORLANDC__) || defined( __CODEGEARC__)
Chris@102 34 # pragma pack(push, 1)
Chris@102 35 #endif
Chris@102 36
Chris@102 37 #include <boost/config.hpp>
Chris@102 38 #include <boost/predef/detail/endian_compat.h>
Chris@102 39 #include <boost/endian/conversion.hpp>
Chris@102 40 #include <boost/type_traits/is_signed.hpp>
Chris@102 41 #include <boost/cstdint.hpp>
Chris@102 42 #include <boost/static_assert.hpp>
Chris@102 43 #include <boost/core/scoped_enum.hpp>
Chris@102 44 #include <iosfwd>
Chris@102 45 #include <climits>
Chris@102 46
Chris@102 47 # if CHAR_BIT != 8
Chris@102 48 # error Platforms with CHAR_BIT != 8 are not supported
Chris@102 49 # endif
Chris@102 50
Chris@102 51 # ifdef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
Chris@102 52 # define BOOST_ENDIAN_DEFAULT_CONSTRUCT {} // C++03
Chris@102 53 # else
Chris@102 54 # define BOOST_ENDIAN_DEFAULT_CONSTRUCT = default; // C++0x
Chris@102 55 # endif
Chris@102 56
Chris@102 57 # if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && defined(BOOST_ENDIAN_FORCE_PODNESS)
Chris@102 58 # define BOOST_ENDIAN_NO_CTORS
Chris@102 59 # endif
Chris@102 60
Chris@102 61 //---------------------------------- synopsis ----------------------------------------//
Chris@102 62
Chris@102 63 namespace boost
Chris@102 64 {
Chris@102 65 namespace endian
Chris@102 66 {
Chris@102 67
Chris@102 68 BOOST_SCOPED_ENUM_START(align)
Chris@102 69 {no, yes
Chris@102 70 # ifdef BOOST_ENDIAN_DEPRECATED_NAMES
Chris@102 71 , unaligned = no, aligned = yes
Chris@102 72 # endif
Chris@102 73 }; BOOST_SCOPED_ENUM_END
Chris@102 74
Chris@102 75 template <BOOST_SCOPED_ENUM(order) Order, class T, std::size_t n_bits,
Chris@102 76 BOOST_SCOPED_ENUM(align) A = align::no>
Chris@102 77 class endian_buffer;
Chris@102 78
Chris@102 79 // aligned big endian signed integer buffers
Chris@102 80 typedef endian_buffer<order::big, int8_t, 8, align::yes> big_int8_buf_at;
Chris@102 81 typedef endian_buffer<order::big, int16_t, 16, align::yes> big_int16_buf_at;
Chris@102 82 typedef endian_buffer<order::big, int32_t, 32, align::yes> big_int32_buf_at;
Chris@102 83 typedef endian_buffer<order::big, int64_t, 64, align::yes> big_int64_buf_at;
Chris@102 84
Chris@102 85 // aligned big endian unsigned integer buffers
Chris@102 86 typedef endian_buffer<order::big, uint8_t, 8, align::yes> big_uint8_buf_at;
Chris@102 87 typedef endian_buffer<order::big, uint16_t, 16, align::yes> big_uint16_buf_at;
Chris@102 88 typedef endian_buffer<order::big, uint32_t, 32, align::yes> big_uint32_buf_at;
Chris@102 89 typedef endian_buffer<order::big, uint64_t, 64, align::yes> big_uint64_buf_at;
Chris@102 90
Chris@102 91 // aligned little endian signed integer buffers
Chris@102 92 typedef endian_buffer<order::little, int8_t, 8, align::yes> little_int8_buf_at;
Chris@102 93 typedef endian_buffer<order::little, int16_t, 16, align::yes> little_int16_buf_at;
Chris@102 94 typedef endian_buffer<order::little, int32_t, 32, align::yes> little_int32_buf_at;
Chris@102 95 typedef endian_buffer<order::little, int64_t, 64, align::yes> little_int64_buf_at;
Chris@102 96
Chris@102 97 // aligned little endian unsigned integer buffers
Chris@102 98 typedef endian_buffer<order::little, uint8_t, 8, align::yes> little_uint8_buf_at;
Chris@102 99 typedef endian_buffer<order::little, uint16_t, 16, align::yes> little_uint16_buf_at;
Chris@102 100 typedef endian_buffer<order::little, uint32_t, 32, align::yes> little_uint32_buf_at;
Chris@102 101 typedef endian_buffer<order::little, uint64_t, 64, align::yes> little_uint64_buf_at;
Chris@102 102
Chris@102 103 // aligned native endian typedefs are not provided because
Chris@102 104 // <cstdint> types are superior for this use case
Chris@102 105
Chris@102 106 // unaligned big endian signed integer buffers
Chris@102 107 typedef endian_buffer<order::big, int_least8_t, 8> big_int8_buf_t;
Chris@102 108 typedef endian_buffer<order::big, int_least16_t, 16> big_int16_buf_t;
Chris@102 109 typedef endian_buffer<order::big, int_least32_t, 24> big_int24_buf_t;
Chris@102 110 typedef endian_buffer<order::big, int_least32_t, 32> big_int32_buf_t;
Chris@102 111 typedef endian_buffer<order::big, int_least64_t, 40> big_int40_buf_t;
Chris@102 112 typedef endian_buffer<order::big, int_least64_t, 48> big_int48_buf_t;
Chris@102 113 typedef endian_buffer<order::big, int_least64_t, 56> big_int56_buf_t;
Chris@102 114 typedef endian_buffer<order::big, int_least64_t, 64> big_int64_buf_t;
Chris@102 115
Chris@102 116 // unaligned big endian unsigned integer buffers
Chris@102 117 typedef endian_buffer<order::big, uint_least8_t, 8> big_uint8_buf_t;
Chris@102 118 typedef endian_buffer<order::big, uint_least16_t, 16> big_uint16_buf_t;
Chris@102 119 typedef endian_buffer<order::big, uint_least32_t, 24> big_uint24_buf_t;
Chris@102 120 typedef endian_buffer<order::big, uint_least32_t, 32> big_uint32_buf_t;
Chris@102 121 typedef endian_buffer<order::big, uint_least64_t, 40> big_uint40_buf_t;
Chris@102 122 typedef endian_buffer<order::big, uint_least64_t, 48> big_uint48_buf_t;
Chris@102 123 typedef endian_buffer<order::big, uint_least64_t, 56> big_uint56_buf_t;
Chris@102 124 typedef endian_buffer<order::big, uint_least64_t, 64> big_uint64_buf_t;
Chris@102 125
Chris@102 126 // unaligned little endian signed integer buffers
Chris@102 127 typedef endian_buffer<order::little, int_least8_t, 8> little_int8_buf_t;
Chris@102 128 typedef endian_buffer<order::little, int_least16_t, 16> little_int16_buf_t;
Chris@102 129 typedef endian_buffer<order::little, int_least32_t, 24> little_int24_buf_t;
Chris@102 130 typedef endian_buffer<order::little, int_least32_t, 32> little_int32_buf_t;
Chris@102 131 typedef endian_buffer<order::little, int_least64_t, 40> little_int40_buf_t;
Chris@102 132 typedef endian_buffer<order::little, int_least64_t, 48> little_int48_buf_t;
Chris@102 133 typedef endian_buffer<order::little, int_least64_t, 56> little_int56_buf_t;
Chris@102 134 typedef endian_buffer<order::little, int_least64_t, 64> little_int64_buf_t;
Chris@102 135
Chris@102 136 // unaligned little endian unsigned integer buffers
Chris@102 137 typedef endian_buffer<order::little, uint_least8_t, 8> little_uint8_buf_t;
Chris@102 138 typedef endian_buffer<order::little, uint_least16_t, 16> little_uint16_buf_t;
Chris@102 139 typedef endian_buffer<order::little, uint_least32_t, 24> little_uint24_buf_t;
Chris@102 140 typedef endian_buffer<order::little, uint_least32_t, 32> little_uint32_buf_t;
Chris@102 141 typedef endian_buffer<order::little, uint_least64_t, 40> little_uint40_buf_t;
Chris@102 142 typedef endian_buffer<order::little, uint_least64_t, 48> little_uint48_buf_t;
Chris@102 143 typedef endian_buffer<order::little, uint_least64_t, 56> little_uint56_buf_t;
Chris@102 144 typedef endian_buffer<order::little, uint_least64_t, 64> little_uint64_buf_t;
Chris@102 145
Chris@102 146 # ifdef BOOST_BIG_ENDIAN
Chris@102 147 // unaligned native endian signed integer buffers
Chris@102 148 typedef big_int8_buf_t native_int8_buf_t;
Chris@102 149 typedef big_int16_buf_t native_int16_buf_t;
Chris@102 150 typedef big_int24_buf_t native_int24_buf_t;
Chris@102 151 typedef big_int32_buf_t native_int32_buf_t;
Chris@102 152 typedef big_int40_buf_t native_int40_buf_t;
Chris@102 153 typedef big_int48_buf_t native_int48_buf_t;
Chris@102 154 typedef big_int56_buf_t native_int56_buf_t;
Chris@102 155 typedef big_int64_buf_t native_int64_buf_t;
Chris@102 156
Chris@102 157 // unaligned native endian unsigned integer buffers
Chris@102 158 typedef big_uint8_buf_t native_uint8_buf_t;
Chris@102 159 typedef big_uint16_buf_t native_uint16_buf_t;
Chris@102 160 typedef big_uint24_buf_t native_uint24_buf_t;
Chris@102 161 typedef big_uint32_buf_t native_uint32_buf_t;
Chris@102 162 typedef big_uint40_buf_t native_uint40_buf_t;
Chris@102 163 typedef big_uint48_buf_t native_uint48_buf_t;
Chris@102 164 typedef big_uint56_buf_t native_uint56_buf_t;
Chris@102 165 typedef big_uint64_buf_t native_uint64_buf_t;
Chris@102 166 # else
Chris@102 167 // unaligned native endian signed integer buffers
Chris@102 168 typedef little_int8_buf_t native_int8_buf_t;
Chris@102 169 typedef little_int16_buf_t native_int16_buf_t;
Chris@102 170 typedef little_int24_buf_t native_int24_buf_t;
Chris@102 171 typedef little_int32_buf_t native_int32_buf_t;
Chris@102 172 typedef little_int40_buf_t native_int40_buf_t;
Chris@102 173 typedef little_int48_buf_t native_int48_buf_t;
Chris@102 174 typedef little_int56_buf_t native_int56_buf_t;
Chris@102 175 typedef little_int64_buf_t native_int64_buf_t;
Chris@102 176
Chris@102 177 // unaligned native endian unsigned integer buffers
Chris@102 178 typedef little_uint8_buf_t native_uint8_buf_t;
Chris@102 179 typedef little_uint16_buf_t native_uint16_buf_t;
Chris@102 180 typedef little_uint24_buf_t native_uint24_buf_t;
Chris@102 181 typedef little_uint32_buf_t native_uint32_buf_t;
Chris@102 182 typedef little_uint40_buf_t native_uint40_buf_t;
Chris@102 183 typedef little_uint48_buf_t native_uint48_buf_t;
Chris@102 184 typedef little_uint56_buf_t native_uint56_buf_t;
Chris@102 185 typedef little_uint64_buf_t native_uint64_buf_t;
Chris@102 186 # endif
Chris@102 187
Chris@102 188 // Stream inserter
Chris@102 189 template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
Chris@102 190 std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
Chris@102 191 std::basic_ostream<charT, traits>&
Chris@102 192 operator<<(std::basic_ostream<charT, traits>& os,
Chris@102 193 const endian_buffer<Order, T, n_bits, A>& x)
Chris@102 194 {
Chris@102 195 return os << x.value();
Chris@102 196 }
Chris@102 197
Chris@102 198 // Stream extractor
Chris@102 199 template <class charT, class traits, BOOST_SCOPED_ENUM(order) Order, class T,
Chris@102 200 std::size_t n_bits, BOOST_SCOPED_ENUM(align) A>
Chris@102 201 std::basic_istream<charT, traits>&
Chris@102 202 operator>>(std::basic_istream<charT, traits>& is,
Chris@102 203 endian_buffer<Order, T, n_bits, A>& x)
Chris@102 204 {
Chris@102 205 T i;
Chris@102 206 if (is >> i)
Chris@102 207 x = i;
Chris@102 208 return is;
Chris@102 209 }
Chris@102 210
Chris@102 211 //---------------------------------- end synopsis ------------------------------------//
Chris@102 212
Chris@102 213 namespace detail
Chris@102 214 {
Chris@102 215
Chris@102 216 // Unrolled loops for loading and storing streams of bytes.
Chris@102 217
Chris@102 218 template <typename T, std::size_t n_bytes,
Chris@102 219 bool sign=boost::is_signed<T>::value >
Chris@102 220 struct unrolled_byte_loops
Chris@102 221 {
Chris@102 222 typedef unrolled_byte_loops<T, n_bytes - 1, sign> next;
Chris@102 223
Chris@102 224 static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 225 { return static_cast<T>(*(bytes - 1) | (next::load_big(bytes - 1) << 8)); }
Chris@102 226 static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 227 { return static_cast<T>(*bytes | (next::load_little(bytes + 1) << 8)); }
Chris@102 228
Chris@102 229 static void store_big(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 230 {
Chris@102 231 *(bytes - 1) = static_cast<char>(value);
Chris@102 232 next::store_big(bytes - 1, static_cast<T>(value >> 8));
Chris@102 233 }
Chris@102 234 static void store_little(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 235 {
Chris@102 236 *bytes = static_cast<char>(value);
Chris@102 237 next::store_little(bytes + 1, static_cast<T>(value >> 8));
Chris@102 238 }
Chris@102 239 };
Chris@102 240
Chris@102 241 template <typename T>
Chris@102 242 struct unrolled_byte_loops<T, 1, false>
Chris@102 243 {
Chris@102 244 static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 245 { return *(bytes - 1); }
Chris@102 246 static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 247 { return *bytes; }
Chris@102 248 static void store_big(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 249 { *(bytes - 1) = static_cast<char>(value); }
Chris@102 250 static void store_little(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 251 { *bytes = static_cast<char>(value); }
Chris@102 252
Chris@102 253 };
Chris@102 254
Chris@102 255 template <typename T>
Chris@102 256 struct unrolled_byte_loops<T, 1, true>
Chris@102 257 {
Chris@102 258 static T load_big(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 259 { return *reinterpret_cast<const signed char*>(bytes - 1); }
Chris@102 260 static T load_little(const unsigned char* bytes) BOOST_NOEXCEPT
Chris@102 261 { return *reinterpret_cast<const signed char*>(bytes); }
Chris@102 262 static void store_big(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 263 { *(bytes - 1) = static_cast<char>(value); }
Chris@102 264 static void store_little(char* bytes, T value) BOOST_NOEXCEPT
Chris@102 265 { *bytes = static_cast<char>(value); }
Chris@102 266 };
Chris@102 267
Chris@102 268 template <typename T, std::size_t n_bytes>
Chris@102 269 inline
Chris@102 270 T load_big_endian(const void* bytes) BOOST_NOEXCEPT
Chris@102 271 {
Chris@102 272 return unrolled_byte_loops<T, n_bytes>::load_big
Chris@102 273 (static_cast<const unsigned char*>(bytes) + n_bytes);
Chris@102 274 }
Chris@102 275
Chris@102 276 template <typename T, std::size_t n_bytes>
Chris@102 277 inline
Chris@102 278 T load_little_endian(const void* bytes) BOOST_NOEXCEPT
Chris@102 279 {
Chris@102 280 # if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
Chris@102 281 // On x86 (which is little endian), unaligned loads are permitted
Chris@102 282 if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
Chris@102 283 // test and generate code only for the applicable return
Chris@102 284 // case since sizeof(T) and n_bytes are known at compile
Chris@102 285 // time.
Chris@102 286 {
Chris@102 287 return *reinterpret_cast<T const *>(bytes);
Chris@102 288 }
Chris@102 289 # endif
Chris@102 290 return unrolled_byte_loops<T, n_bytes>::load_little
Chris@102 291 (static_cast<const unsigned char*>(bytes));
Chris@102 292 }
Chris@102 293
Chris@102 294 template <typename T, std::size_t n_bytes>
Chris@102 295 inline
Chris@102 296 void store_big_endian(void* bytes, T value) BOOST_NOEXCEPT
Chris@102 297 {
Chris@102 298 unrolled_byte_loops<T, n_bytes>::store_big
Chris@102 299 (static_cast<char*>(bytes) + n_bytes, value);
Chris@102 300 }
Chris@102 301
Chris@102 302 template <typename T, std::size_t n_bytes>
Chris@102 303 inline
Chris@102 304 void store_little_endian(void* bytes, T value) BOOST_NOEXCEPT
Chris@102 305 {
Chris@102 306 # if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
Chris@102 307 // On x86 (which is little endian), unaligned stores are permitted
Chris@102 308 if (sizeof(T) == n_bytes) // GCC 4.9, VC++ 14.0, and probably others, elide this
Chris@102 309 // test and generate code only for the applicable return
Chris@102 310 // case since sizeof(T) and n_bytes are known at compile
Chris@102 311 // time.
Chris@102 312 {
Chris@102 313 *reinterpret_cast<T *>(bytes) = value;
Chris@102 314 return;
Chris@102 315 }
Chris@102 316 # endif
Chris@102 317 unrolled_byte_loops<T, n_bytes>::store_little
Chris@102 318 (static_cast<char*>(bytes), value);
Chris@102 319 }
Chris@102 320
Chris@102 321 } // namespace detail
Chris@102 322
Chris@102 323 # ifdef BOOST_ENDIAN_LOG
Chris@102 324 bool endian_log(true);
Chris@102 325 # endif
Chris@102 326
Chris@102 327 // endian_buffer class template specializations --------------------------------------//
Chris@102 328
Chris@102 329 // Specializations that represent unaligned bytes.
Chris@102 330 // Taking an integer type as a parameter provides a nice way to pass both
Chris@102 331 // the size and signedness of the desired integer and get the appropriate
Chris@102 332 // corresponding integer type for the interface.
Chris@102 333
Chris@102 334 // Q: Should endian_buffer supply "value_type operator value_type() const noexcept"?
Chris@102 335 // A: No. The rationale for endian_buffers is to prevent high-cost hidden
Chris@102 336 // conversions. If an implicit conversion operator is supplied, hidden conversions
Chris@102 337 // can occur.
Chris@102 338
Chris@102 339 // unaligned big endian_buffer specialization
Chris@102 340 template <typename T, std::size_t n_bits>
Chris@102 341 class endian_buffer< order::big, T, n_bits, align::no >
Chris@102 342 {
Chris@102 343 BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
Chris@102 344 public:
Chris@102 345 typedef T value_type;
Chris@102 346 # ifndef BOOST_ENDIAN_NO_CTORS
Chris@102 347 endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
Chris@102 348 explicit endian_buffer(T val) BOOST_NOEXCEPT
Chris@102 349 {
Chris@102 350 # ifdef BOOST_ENDIAN_LOG
Chris@102 351 if ( endian_log )
Chris@102 352 std::cout << "big, unaligned, "
Chris@102 353 << n_bits << "-bits, construct(" << val << ")\n";
Chris@102 354 # endif
Chris@102 355 detail::store_big_endian<T, n_bits/8>(m_value, val);
Chris@102 356 }
Chris@102 357 # endif
Chris@102 358 endian_buffer & operator=(T val) BOOST_NOEXCEPT
Chris@102 359 {
Chris@102 360 # ifdef BOOST_ENDIAN_LOG
Chris@102 361 if (endian_log)
Chris@102 362 std::cout << "big, unaligned, " << n_bits << "-bits, assign(" << val << ")\n";
Chris@102 363 # endif
Chris@102 364 detail::store_big_endian<T, n_bits/8>(m_value, val);
Chris@102 365 return *this;
Chris@102 366 }
Chris@102 367 value_type value() const BOOST_NOEXCEPT
Chris@102 368 {
Chris@102 369 # ifdef BOOST_ENDIAN_LOG
Chris@102 370 if ( endian_log )
Chris@102 371 std::cout << "big, unaligned, " << n_bits << "-bits, convert("
Chris@102 372 << detail::load_big_endian<T, n_bits/8>(m_value) << ")\n";
Chris@102 373 # endif
Chris@102 374 return detail::load_big_endian<T, n_bits/8>(m_value);
Chris@102 375 }
Chris@102 376 const char* data() const BOOST_NOEXCEPT { return m_value; }
Chris@102 377 protected:
Chris@102 378 char m_value[n_bits/8];
Chris@102 379 };
Chris@102 380
Chris@102 381 // unaligned little endian_buffer specialization
Chris@102 382 template <typename T, std::size_t n_bits>
Chris@102 383 class endian_buffer< order::little, T, n_bits, align::no >
Chris@102 384 {
Chris@102 385 BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
Chris@102 386 public:
Chris@102 387 typedef T value_type;
Chris@102 388 # ifndef BOOST_ENDIAN_NO_CTORS
Chris@102 389 endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
Chris@102 390 explicit endian_buffer(T val) BOOST_NOEXCEPT
Chris@102 391 {
Chris@102 392 # ifdef BOOST_ENDIAN_LOG
Chris@102 393 if ( endian_log )
Chris@102 394 std::cout << "little, unaligned, " << n_bits << "-bits, construct("
Chris@102 395 << val << ")\n";
Chris@102 396 # endif
Chris@102 397 detail::store_little_endian<T, n_bits/8>(m_value, val);
Chris@102 398 }
Chris@102 399 # endif
Chris@102 400 endian_buffer & operator=(T val) BOOST_NOEXCEPT
Chris@102 401 { detail::store_little_endian<T, n_bits/8>(m_value, val); return *this; }
Chris@102 402 value_type value() const BOOST_NOEXCEPT
Chris@102 403 {
Chris@102 404 # ifdef BOOST_ENDIAN_LOG
Chris@102 405 if ( endian_log )
Chris@102 406 std::cout << "little, unaligned, " << n_bits << "-bits, convert("
Chris@102 407 << detail::load_little_endian<T, n_bits/8>(m_value) << ")\n";
Chris@102 408 # endif
Chris@102 409 return detail::load_little_endian<T, n_bits/8>(m_value);
Chris@102 410 }
Chris@102 411 const char* data() const BOOST_NOEXCEPT { return m_value; }
Chris@102 412 protected:
Chris@102 413 char m_value[n_bits/8];
Chris@102 414 };
Chris@102 415
Chris@102 416 // align::yes specializations; only n_bits == 16/32/64 supported
Chris@102 417
Chris@102 418 // aligned big endian_buffer specialization
Chris@102 419 template <typename T, std::size_t n_bits>
Chris@102 420 class endian_buffer<order::big, T, n_bits, align::yes>
Chris@102 421 {
Chris@102 422 BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
Chris@102 423 BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
Chris@102 424 public:
Chris@102 425 typedef T value_type;
Chris@102 426 # ifndef BOOST_ENDIAN_NO_CTORS
Chris@102 427 endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
Chris@102 428 explicit endian_buffer(T val) BOOST_NOEXCEPT
Chris@102 429 {
Chris@102 430 # ifdef BOOST_ENDIAN_LOG
Chris@102 431 if ( endian_log )
Chris@102 432 std::cout << "big, aligned, " << n_bits
Chris@102 433 << "-bits, construct(" << val << ")\n";
Chris@102 434 # endif
Chris@102 435 m_value = ::boost::endian::native_to_big(val);
Chris@102 436 }
Chris@102 437
Chris@102 438 # endif
Chris@102 439 endian_buffer& operator=(T val) BOOST_NOEXCEPT
Chris@102 440 {
Chris@102 441 m_value = ::boost::endian::native_to_big(val);
Chris@102 442 return *this;
Chris@102 443 }
Chris@102 444 //operator value_type() const BOOST_NOEXCEPT
Chris@102 445 //{
Chris@102 446 // return ::boost::endian::big_to_native(m_value);
Chris@102 447 //}
Chris@102 448 value_type value() const BOOST_NOEXCEPT
Chris@102 449 {
Chris@102 450 # ifdef BOOST_ENDIAN_LOG
Chris@102 451 if ( endian_log )
Chris@102 452 std::cout << "big, aligned, " << n_bits << "-bits, convert("
Chris@102 453 << ::boost::endian::big_to_native(m_value) << ")\n";
Chris@102 454 # endif
Chris@102 455 return ::boost::endian::big_to_native(m_value);
Chris@102 456 }
Chris@102 457 const char* data() const BOOST_NOEXCEPT
Chris@102 458 {return reinterpret_cast<const char*>(&m_value);}
Chris@102 459 protected:
Chris@102 460 T m_value;
Chris@102 461 };
Chris@102 462
Chris@102 463 // aligned little endian_buffer specialization
Chris@102 464 template <typename T, std::size_t n_bits>
Chris@102 465 class endian_buffer<order::little, T, n_bits, align::yes>
Chris@102 466 {
Chris@102 467 BOOST_STATIC_ASSERT( (n_bits/8)*8 == n_bits );
Chris@102 468 BOOST_STATIC_ASSERT( sizeof(T) == n_bits/8 );
Chris@102 469 public:
Chris@102 470 typedef T value_type;
Chris@102 471 # ifndef BOOST_ENDIAN_NO_CTORS
Chris@102 472 endian_buffer() BOOST_ENDIAN_DEFAULT_CONSTRUCT
Chris@102 473 explicit endian_buffer(T val) BOOST_NOEXCEPT
Chris@102 474 {
Chris@102 475 # ifdef BOOST_ENDIAN_LOG
Chris@102 476 if ( endian_log )
Chris@102 477 std::cout << "little, aligned, " << n_bits
Chris@102 478 << "-bits, construct(" << val << ")\n";
Chris@102 479 # endif
Chris@102 480 m_value = ::boost::endian::native_to_little(val);
Chris@102 481 }
Chris@102 482
Chris@102 483 # endif
Chris@102 484 endian_buffer& operator=(T val) BOOST_NOEXCEPT
Chris@102 485 {
Chris@102 486 m_value = ::boost::endian::native_to_little(val);
Chris@102 487 return *this;
Chris@102 488 }
Chris@102 489 value_type value() const BOOST_NOEXCEPT
Chris@102 490 {
Chris@102 491 # ifdef BOOST_ENDIAN_LOG
Chris@102 492 if ( endian_log )
Chris@102 493 std::cout << "little, aligned, " << n_bits << "-bits, convert("
Chris@102 494 << ::boost::endian::little_to_native(m_value) << ")\n";
Chris@102 495 # endif
Chris@102 496 return ::boost::endian::little_to_native(m_value);
Chris@102 497 }
Chris@102 498 const char* data() const BOOST_NOEXCEPT
Chris@102 499 {return reinterpret_cast<const char*>(&m_value);}
Chris@102 500 protected:
Chris@102 501 T m_value;
Chris@102 502 };
Chris@102 503
Chris@102 504 } // namespace endian
Chris@102 505 } // namespace boost
Chris@102 506
Chris@102 507 #if defined(__BORLANDC__) || defined( __CODEGEARC__)
Chris@102 508 # pragma pack(pop)
Chris@102 509 #endif
Chris@102 510
Chris@102 511 #if defined(_MSC_VER)
Chris@102 512 # pragma warning(pop)
Chris@102 513 #endif
Chris@102 514
Chris@102 515 #endif // BOOST_ENDIAN_BUFFERS_HPP