/*============================================================================= Copyright (c) 2011-2019 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_ENDIAN_TRAITS_HPP #define SPROUT_ENDIAN_TRAITS_HPP #include #include #include #include namespace sprout { namespace detail { template class default_big_endian_traits; template class default_big_endian_traits< T, typename std::enable_if::value && sizeof(T) == 1>::type > { public: typedef T type; public: static SPROUT_CONSTEXPR std::size_t size() { return sizeof(type); } static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t) { return static_cast(t); } static SPROUT_CXX14_CONSTEXPR void set_byte(type& t, std::size_t, unsigned char value) { t = static_cast(value); } }; template class default_big_endian_traits< T, typename std::enable_if::value && !(sizeof(T) == 1)>::type > { public: typedef T type; public: static SPROUT_CONSTEXPR std::size_t size() { return sizeof(type); } static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t i) { return static_cast( (t & (UCHAR_MAX << CHAR_BIT * ((size() - 1) - i))) >> CHAR_BIT * ((size() - 1) - i) ); } static SPROUT_CXX14_CONSTEXPR void set_byte(type& t, std::size_t i, unsigned char value) { t &= ~(UCHAR_MAX << CHAR_BIT * ((size() - 1) - i)); t |= (value << CHAR_BIT * ((size() - 1) - i)); } }; template class default_little_endian_traits; template class default_little_endian_traits< T, typename std::enable_if::value && sizeof(T) == 1>::type > { public: typedef T type; public: static SPROUT_CONSTEXPR std::size_t size() { return sizeof(type); } static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t) { return static_cast(t); } static SPROUT_CXX14_CONSTEXPR void set_byte(type& t, std::size_t, unsigned char value) { t = static_cast(value); } }; template class default_little_endian_traits< T, typename std::enable_if::value && !(sizeof(T) == 1)>::type > { public: typedef T type; public: static SPROUT_CONSTEXPR std::size_t size() { return sizeof(type); } static SPROUT_CONSTEXPR unsigned char get_byte(type const& t, std::size_t i) { return static_cast( (t & (UCHAR_MAX << CHAR_BIT * i)) >> CHAR_BIT * i ); } static SPROUT_CXX14_CONSTEXPR void set_byte(type& t, std::size_t i, unsigned char value) { t &= ~(UCHAR_MAX << CHAR_BIT * i); t |= (value << CHAR_BIT * i); } }; } // namespace detail // // big_endian_traits // template class big_endian_traits : public sprout::detail::default_big_endian_traits {}; // // little_endian_traits // template class little_endian_traits : public sprout::detail::default_little_endian_traits {}; // // endian_traits // template class endian_traits : public sprout::big_endian_traits {}; } // namespace sprout #endif // #ifndef SPROUT_ENDIAN_TRAITS_HPP