#ifndef BOOST_INTERFACE_ENDIAN_HPP #define BOOST_INTERFACE_ENDIAN_HPP #pragma once #include #include #include #include #include namespace boost { namespace interface { struct uninitialized_t { }; static const uninitialized_t uninitialized; enum endian_t { little, big }; #ifdef BOOST_BIG_ENDIAN static const endian_t native = big; #else static const endian_t native = little; #endif namespace detail { template inline void unrolled_reverse_copy(char* dst, const char* src) { *dst = *src; unrolled_reverse_copy(dst+1, src-1); } template<> inline void unrolled_reverse_copy<1>(char* dst, const char* src) { *dst = *src; } template<> inline void unrolled_reverse_copy<0>(char*, const char*) { } template struct reverse_copy_helper { static void copy(char* dst, const char* src) { std::reverse_copy(src, src+L, dst); } }; template struct reverse_copy_helper { static void copy(char* dst, const char* src) { unrolled_reverse_copy(dst, src+(L-1)); } }; template inline void reverse_copy(char* dst, const char* src) { reverse_copy_helper< L, (L<=8) >::copy(dst, src); } } // detail #pragma pack(push, 1) template class endian { public: static const endian_t endian_type = E; typedef T value_type; private: char m_storage[sizeof(value_type)]; void store(const value_type& v) { detail::reverse_copy(m_storage, reinterpret_cast(&v)); } // store value_type retrieve() const { value_type result; detail::reverse_copy(reinterpret_cast(&result), m_storage); return result; } // retrieve public: endian() { store(value_type()); } endian(uninitialized_t) { } endian(const value_type& x) { store(x); } value_type value() const { return retrieve(); } operator value_type() const { return value(); } endian& operator=(const value_type& rhs) { store(rhs); return *this; } }; // endian // Specialize for native endian. template class endian { public: static const endian_t endian_type = native; typedef T value_type; private: value_type m_value; public: endian() : m_value() { } endian(uninitialized_t) { } endian(const value_type& x) : m_value(x) { } const value_type& value() const { return m_value; } operator value_type() const { return value(); } endian& operator=(const value_type& rhs) { m_value = rhs; return *this; } }; // endian #pragma pack(pop) } } // boost::interface #endif