Sprout/sprout/endian_traits.hpp
2012-08-08 22:27:06 +09:00

79 lines
1.8 KiB
C++

#ifndef SPROUT_ENDIAN_TRAITS_HPP
#define SPROUT_ENDIAN_TRAITS_HPP
#include <cstddef>
#include <climits>
#include <type_traits>
#include <sprout/config.hpp>
namespace sprout {
namespace detail {
template<typename T, typename Enable = void>
class default_big_endian_traits;
template<typename T>
class default_big_endian_traits<
T,
typename std::enable_if<std::is_integral<T>::value>::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<unsigned char>(
(t & (UCHAR_MAX << CHAR_BIT * ((size() - 1) - i)))
>> CHAR_BIT * ((size() - 1) - i)
);
}
};
template<typename T, typename Enable = void>
class default_little_endian_traits;
template<typename T>
class default_little_endian_traits<
T,
typename std::enable_if<std::is_integral<T>::value>::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<unsigned char>(
(t & (UCHAR_MAX << CHAR_BIT * i))
>> CHAR_BIT * i
);
}
};
} // namespace detail
//
// big_endian_traits
//
template<typename T>
class big_endian_traits
: public sprout::detail::default_big_endian_traits<T>
{};
//
// little_endian_traits
//
template<typename T>
class little_endian_traits
: public sprout::detail::default_little_endian_traits<T>
{};
//
// endian_traits
//
template<typename T>
class endian_traits
: public sprout::big_endian_traits<T>
{};
} // namespace sprout
#endif // #ifndef SPROUT_ENDIAN_TRAITS_HPP