diff --git a/boost/integer/endian.hpp b/boost/integer/endian.hpp index b267b84..47db4a8 100644 --- a/boost/integer/endian.hpp +++ b/boost/integer/endian.hpp @@ -198,6 +198,7 @@ namespace boost # endif return detail::load_big_endian(m_value); } + const char* data() const { return m_value; } private: char m_value[n_bits/8]; }; @@ -230,6 +231,7 @@ namespace boost # endif return detail::load_little_endian(m_value); } + const char* data() const { return m_value; } private: char m_value[n_bits/8]; }; @@ -257,6 +259,7 @@ namespace boost endian & operator=(T val) { detail::store_little_endian(m_value, val); return *this; } operator T() const { return detail::load_little_endian(m_value); } # endif + const char* data() const { return m_value; } private: char m_value[n_bits/8]; }; @@ -288,6 +291,7 @@ namespace boost endian & operator=(T val) { detail::store_big_endian(&m_value, val); return *this; } operator T() const { return detail::load_big_endian(&m_value); } # endif + const char* data() const { return reinterpret_cast(&m_value); } private: T m_value; }; @@ -316,6 +320,7 @@ namespace boost endian & operator=(T val) { detail::store_little_endian(&m_value, val); return *this; } operator T() const { return detail::load_little_endian(&m_value); } #endif + const char* data() const { return reinterpret_cast(&m_value); } private: T m_value; }; diff --git a/boost/integer/endian_binary_stream.hpp b/boost/integer/endian_binary_stream.hpp index 9e016aa..4d0b92d 100644 --- a/boost/integer/endian_binary_stream.hpp +++ b/boost/integer/endian_binary_stream.hpp @@ -119,7 +119,7 @@ namespace boost inline typename boost::enable_if< is_endian, std::ostream & >::type operator<=( std::ostream & os, const Endian & e ) { - return os.write( reinterpret_cast(&e), sizeof(e) ); + return os.write( e.data(), sizeof(e) ); } template < class Endian > diff --git a/libs/integer/doc/endian.html b/libs/integer/doc/endian.html index de2e49e..0cd0893 100644 --- a/libs/integer/doc/endian.html +++ b/libs/integer/doc/endian.html @@ -12,12 +12,12 @@ - +
- @@ -51,6 +51,7 @@ Example
Design
Experience
+ Motivating use cases
C++0x
Compilation
Acknowledgements @@ -290,10 +291,15 @@ usual operations on integers are supplied.

{ public: typedef T value_type; + + // if BOOST_ENDIAN_FORCE_PODNESS is defined && C++0x POD's are not + // available then these two constructors will not be present endian() = default; // = default replaced by {} on C++03 explicit endian(T v); + endian & operator=(T v); operator T() const; + const char* data() const; }; // unaligned big endian signed integer types @@ -406,6 +412,11 @@ constructed object.

Returns: The current value stored in *this, converted to value_type.

+

const char* data() const;

+
+

Returns: A pointer to the first byte of the endian binary value stored +in *this.

+

Other operators

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

@@ -436,10 +447,12 @@ are usually be faster, and sometimes much faster, for I/O compared to stream inserters and extractors, or to serialization.

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

-

What are the implications endian types not being POD's of C++03? They -can't be used in unions. In theory, compilers aren't required to align or lay -out storage in portable ways, although this problem has never been observed in a -real compiler.

+

What are the implications endian 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 +use of Boost.Endian with +real compilers.

Which is better, big-endian or little-endian? Big-endian tends to be a bit more of an industry standard, but little-endian may be preferred for applications that run primarily on x86 (Intel/AMD) and other little-endian @@ -585,6 +598,11 @@ several Boost programmers and used very successful in high-value, high-use applications for many years. These independently developed endian libraries often evolved from C libraries that were also widely used. Endian integers have proven widely useful across a wide range of computer architectures and applications.

+

Motivating use cases

+

Neil Mayhew writes: "I can also provide a meaningful use-case for this +library: reading TrueType font files from disk and processing the contents. The +data format has fixed endianness (big) and has unaligned values in various +places. Using Boost.Endian simplifies and cleans the code wonderfully."

C++0x

The availability of the C++0x @@ -622,20 +640,20 @@ Benaka Moorthi, Christopher Kohlhoff, Cliff Green, Gennaro Proto, -Jeff Flinn, +Giovanni Piero Deretta, dizzy, Jeff Flinn, John Maddock, Kim Barrett, Marsh Ray, Martin Bonner, Matias Capeletto, -Rene Rivera, -Scott McMurray, +Neil Mayhew, Phil Endecott, Rene Rivera, +Roland Schwarz, Scott McMurray, Sebastian Redl, -Tomas Puverle, and +Tomas Puverle, Vincente Botet, and Yuval Ronen.


Last revised: -19 March, 2009

+25 March, 2009

© Copyright Beman Dawes, 2006-2009

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/libs/integer/test/endian_operations_test.cpp b/libs/integer/test/endian_operations_test.cpp index 2fd4329..e3634d7 100644 --- a/libs/integer/test/endian_operations_test.cpp +++ b/libs/integer/test/endian_operations_test.cpp @@ -264,6 +264,8 @@ void op_test() #endif } +// main ------------------------------------------------------------------------------// + int main() { bi::endian_log = false; @@ -339,7 +341,21 @@ int main() std::clog << "\n"; bi::endian_log = false; - + + // test from Roland Schwarz that detected ambiguities + unsigned u; + bi::ulittle32_t u1; + bi::ulittle32_t u2; + + u = 1; + u1 = 1; + u2 = u1 + u; + + // one more wrinkle + bi::ulittle16_t u3(3); + u3 = 3; + u2 = u1 + u3; + // perform the indicated test on ~60*60 operand types op_test(); diff --git a/libs/integer/test/endian_test.cpp b/libs/integer/test/endian_test.cpp index dbd6e0e..63de0b4 100644 --- a/libs/integer/test/endian_test.cpp +++ b/libs/integer/test/endian_test.cpp @@ -142,6 +142,152 @@ namespace cout << "That should not matter and is presented for your information only.\n"; } // detect_endianness + // check_data ------------------------------------------------------------// + + void check_data() + { + big8_t big8; + big16_t big16; + big24_t big24; + big32_t big32; + big40_t big40; + big48_t big48; + big56_t big56; + big64_t big64; + + ubig8_t ubig8; + ubig16_t ubig16; + ubig24_t ubig24; + ubig32_t ubig32; + ubig40_t ubig40; + ubig48_t ubig48; + ubig56_t ubig56; + ubig64_t ubig64; + + little8_t little8; + little16_t little16; + little24_t little24; + little32_t little32; + little40_t little40; + little48_t little48; + little56_t little56; + little64_t little64; + + ulittle8_t ulittle8; + ulittle16_t ulittle16; + ulittle24_t ulittle24; + ulittle32_t ulittle32; + ulittle40_t ulittle40; + ulittle48_t ulittle48; + ulittle56_t ulittle56; + ulittle64_t ulittle64; + + native8_t native8; + native16_t native16; + native24_t native24; + native32_t native32; + native40_t native40; + native48_t native48; + native56_t native56; + native64_t native64; + + unative8_t unative8; + unative16_t unative16; + unative24_t unative24; + unative32_t unative32; + unative40_t unative40; + unative48_t unative48; + unative56_t unative56; + unative64_t unative64; + + aligned_big16_t aligned_big16; + aligned_big32_t aligned_big32; + aligned_big64_t aligned_big64; + + aligned_ubig16_t aligned_ubig16; + aligned_ubig32_t aligned_ubig32; + aligned_ubig64_t aligned_ubig64; + + aligned_little16_t aligned_little16; + aligned_little32_t aligned_little32; + aligned_little64_t aligned_little64; + + aligned_ulittle16_t aligned_ulittle16 ; + aligned_ulittle32_t aligned_ulittle32 ; + aligned_ulittle64_t aligned_ulittle64 ; + + VERIFY(big8.data() == reinterpret_cast(&big8)); + VERIFY(big16.data() == reinterpret_cast(&big16)); + VERIFY(big24.data() == reinterpret_cast(&big24)); + VERIFY(big32.data() == reinterpret_cast(&big32)); + VERIFY(big40.data() == reinterpret_cast(&big40)); + VERIFY(big48.data() == reinterpret_cast(&big48)); + VERIFY(big56.data() == reinterpret_cast(&big56)); + VERIFY(big64.data() == reinterpret_cast(&big64)); + + VERIFY(ubig8.data() == reinterpret_cast(&ubig8)); + VERIFY(ubig16.data() == reinterpret_cast(&ubig16)); + VERIFY(ubig24.data() == reinterpret_cast(&ubig24)); + VERIFY(ubig32.data() == reinterpret_cast(&ubig32)); + VERIFY(ubig40.data() == reinterpret_cast(&ubig40)); + VERIFY(ubig48.data() == reinterpret_cast(&ubig48)); + VERIFY(ubig56.data() == reinterpret_cast(&ubig56)); + VERIFY(ubig64.data() == reinterpret_cast(&ubig64)); + + VERIFY(little8.data() == reinterpret_cast(&little8)); + VERIFY(little16.data() == reinterpret_cast(&little16)); + VERIFY(little24.data() == reinterpret_cast(&little24)); + VERIFY(little32.data() == reinterpret_cast(&little32)); + VERIFY(little40.data() == reinterpret_cast(&little40)); + VERIFY(little48.data() == reinterpret_cast(&little48)); + VERIFY(little56.data() == reinterpret_cast(&little56)); + VERIFY(little64.data() == reinterpret_cast(&little64)); + + VERIFY(ulittle8.data() == reinterpret_cast(&ulittle8)); + VERIFY(ulittle16.data() == reinterpret_cast(&ulittle16)); + VERIFY(ulittle24.data() == reinterpret_cast(&ulittle24)); + VERIFY(ulittle32.data() == reinterpret_cast(&ulittle32)); + VERIFY(ulittle40.data() == reinterpret_cast(&ulittle40)); + VERIFY(ulittle48.data() == reinterpret_cast(&ulittle48)); + VERIFY(ulittle56.data() == reinterpret_cast(&ulittle56)); + VERIFY(ulittle64.data() == reinterpret_cast(&ulittle64)); + + VERIFY(native8.data() == reinterpret_cast(&native8)); + VERIFY(native16.data() == reinterpret_cast(&native16)); + VERIFY(native24.data() == reinterpret_cast(&native24)); + VERIFY(native32.data() == reinterpret_cast(&native32)); + VERIFY(native40.data() == reinterpret_cast(&native40)); + VERIFY(native48.data() == reinterpret_cast(&native48)); + VERIFY(native56.data() == reinterpret_cast(&native56)); + VERIFY(native64.data() == reinterpret_cast(&native64)); + + VERIFY(unative8.data() == reinterpret_cast(&unative8)); + VERIFY(unative16.data() == reinterpret_cast(&unative16)); + VERIFY(unative24.data() == reinterpret_cast(&unative24)); + VERIFY(unative32.data() == reinterpret_cast(&unative32)); + VERIFY(unative40.data() == reinterpret_cast(&unative40)); + VERIFY(unative48.data() == reinterpret_cast(&unative48)); + VERIFY(unative56.data() == reinterpret_cast(&unative56)); + VERIFY(unative64.data() == reinterpret_cast(&unative64)); + + VERIFY(aligned_big16.data() == reinterpret_cast(&aligned_big16)); + VERIFY(aligned_big32.data() == reinterpret_cast(&aligned_big32)); + VERIFY(aligned_big64.data() == reinterpret_cast(&aligned_big64)); + + VERIFY(aligned_ubig16.data() == reinterpret_cast(&aligned_ubig16)); + VERIFY(aligned_ubig32.data() == reinterpret_cast(&aligned_ubig32)); + VERIFY(aligned_ubig64.data() == reinterpret_cast(&aligned_ubig64)); + + VERIFY(aligned_little16.data() == reinterpret_cast(&aligned_little16)); + VERIFY(aligned_little32.data() == reinterpret_cast(&aligned_little32)); + VERIFY(aligned_little64.data() == reinterpret_cast(&aligned_little64)); + + VERIFY(aligned_ulittle16.data() == reinterpret_cast(&aligned_ulittle16)); + VERIFY(aligned_ulittle32.data() == reinterpret_cast(&aligned_ulittle32)); + VERIFY(aligned_ulittle64.data() == reinterpret_cast(&aligned_ulittle64)); + + } + // check_size ------------------------------------------------------------// void check_size() @@ -572,6 +718,8 @@ namespace } // unnamed namespace +// main ------------------------------------------------------------------------------// + int main( int argc, char * argv[] ) { cout << "Usage: " @@ -586,6 +734,7 @@ int main( int argc, char * argv[] ) check_size(); check_alignment(); check_representation_and_range_and_ops(); + check_data(); //timing_test ( "big32_t" ); //timing_test( "aligned_big32_t" ); diff --git a/libs/integer/test/test.bat b/libs/integer/test/test.bat index e998ac4..15e3781 100644 --- a/libs/integer/test/test.bat +++ b/libs/integer/test/test.bat @@ -1,11 +1,41 @@ -set ENDIAN_LOCATE_ROOT=%TEMP%\endian-regr -md %ENDIAN_LOCATE_ROOT% 2>nul +@echo off +echo Special version of boost_test for sandbox version of endian library. +xcopy /D %BOOST_TRUNK%\boost-build.jam ..\..\.. +xcopy /D %BOOST_TRUNK%\Jamroot ..\..\.. +set BOOST_BUILD_PATH=%BOOST_TRUNK%\tools\build\v2 + +if not $%1==$--help goto nohelp +echo Invoke: boost_test [-ts toolset] [bjam-options] +echo Default -ts is gcc-4.3,msvc-8.0,msvc-9.0express,msvc-10.0express +goto done +:nohelp + +if $%1==$-ts goto toolset echo Begin test processing... -bjam --dump-tests includes=/boost/trunk "-sALL_LOCATE_TARGET=%ENDIAN_LOCATE_ROOT%" %* >bjam.log 2>&1 +bjam include=%BOOST_TRUNK% --v2 --dump-tests --toolset=gcc-4.3,msvc-8.0,msvc-9.0express,msvc-10.0express %* >bjam.log 2>&1 +goto jam_log + +:toolset +echo Begin test processing... +bjam include=%BOOST_TRUNK% --v2 --dump-tests --toolset=%2 %3 %4 %5 %6 %7 %8 %9 >bjam.log 2>&1 + +:jam_log echo Begin log processing... -process_jam_log %ENDIAN_LOCATE_ROOT% %TEMP%\babsr.bat +%UTIL%\change %TEMP%\babsr.bat " Directory of " "set BOOST_TEST_ABS_ROOT=" >nul +%UTIL%\change %TEMP%\babsr.bat "C:" "c:" >nul +%UTIL%\change %TEMP%\babsr.bat "D:" "d:" >nul +%UTIL%\change %TEMP%\babsr.bat "E:" "e:" >nul +%UTIL%\change %TEMP%\babsr.bat "F:" "f:" >nul +call %TEMP%\babsr.bat +compiler_status --v2 %BOOST_TEST_ABS_ROOT% test_status.html test_links.html start test_status.html + +:done diff --git a/libs/integer/zip-endian.bat b/libs/integer/zip-endian.bat index 47f2b4d..9920990 100644 --- a/libs/integer/zip-endian.bat +++ b/libs/integer/zip-endian.bat @@ -13,7 +13,7 @@ md libs\integer\example md libs\integer\test popd copy ..\..\boost.png \temp\%1 -copy ..\..\boost\doc\html\minimal.css \temp\%1\doc\html +copy ..\..\doc\html\minimal.css \temp\%1\doc\html copy ..\..\boost\binary_stream.hpp \temp\%1\boost copy ..\..\boost\integer\endian.hpp \temp\%1\boost\integer copy ..\..\boost\integer\endian_binary_stream.hpp \temp\%1\boost\integer

boost.png (6897 bytes) + Endian Integers