1 // Copyright (C) 2004 Arkadiy Vertleyb 2 // Use, modification and distribution is subject to the Boost Software 3 // License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) 4 5 #ifndef BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED 6 #define BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED 7 8 #include <boost/config.hpp> 9 #include <boost/typeof/constant.hpp> 10 11 namespace boost { namespace type_of { 12 13 template<class T> struct get_unsigned 14 { 15 typedef T type; 16 }; 17 template<> struct get_unsigned<signed char> 18 { 19 typedef unsigned char type; 20 }; 21 template<> struct get_unsigned<char> 22 { 23 typedef unsigned char type; 24 }; 25 template<> struct get_unsigned<short> 26 { 27 typedef unsigned short type; 28 }; 29 template<> struct get_unsigned<int> 30 { 31 typedef unsigned int type; 32 }; 33 template<> struct get_unsigned<long> 34 { 35 typedef unsigned long type; 36 }; 37 38 ////////////////////////// 39 40 template<std::size_t n, bool Overflow> 41 struct pack 42 { 43 BOOST_STATIC_CONSTANT(std::size_t , value=((n + 1) * 2 + (Overflow ? 1 : 0))); 44 }; 45 46 template<std::size_t m> 47 struct unpack 48 { 49 BOOST_STATIC_CONSTANT(std::size_t, value = (m / 2) - 1); 50 BOOST_STATIC_CONSTANT(std::size_t, overflow = (m % 2 == 1)); 51 }; 52 53 //////////////////////////////// 54 55 template<class V, std::size_t n, bool overflow = (n >= 0x3fffffff)> 56 struct encode_size_t : push_back< 57 V, 58 boost::type_of::constant<std::size_t,pack<n, false>::value> 59 > 60 {}; 61 62 template<class V, std::size_t n> 63 struct encode_size_t<V, n, true> : push_back<typename push_back< 64 V, 65 boost::type_of::constant<std::size_t,pack<n % 0x3ffffffe, true>::value> >::type, 66 boost::type_of::constant<std::size_t,n / 0x3ffffffe> 67 > 68 {}; 69 70 template<class V, class T, T n> 71 struct encode_integral : encode_size_t< V, (typename get_unsigned<T>::type)n,(((typename get_unsigned<T>::type)n)>=0x3fffffff) > 72 {}; 73 74 template<class V, bool b> 75 struct encode_integral<V, bool, b> : encode_size_t< V, b?1:0, false> 76 {}; 77 /////////////////////////// 78 79 template<std::size_t n, class Iter, bool overflow> 80 struct decode_size_t; 81 82 template<std::size_t n, class Iter> 83 struct decode_size_t<n, Iter, false> 84 { 85 BOOST_STATIC_CONSTANT(std::size_t,value = n); 86 typedef Iter iter; 87 }; 88 89 template<std::size_t n, class Iter> 90 struct decode_size_t<n, Iter, true> 91 { 92 BOOST_STATIC_CONSTANT(std::size_t,m = Iter::type::value); 93 94 BOOST_STATIC_CONSTANT(std::size_t,value = (std::size_t)m * 0x3ffffffe + n); 95 typedef typename Iter::next iter; 96 }; 97 98 template<class T, class Iter> 99 struct decode_integral 100 { 101 typedef decode_integral<T,Iter> self_t; 102 BOOST_STATIC_CONSTANT(std::size_t,m = Iter::type::value); 103 104 BOOST_STATIC_CONSTANT(std::size_t,n = unpack<m>::value); 105 106 BOOST_STATIC_CONSTANT(std::size_t,overflow = unpack<m>::overflow); 107 108 typedef typename Iter::next nextpos; 109 110 static const T value = (T)(std::size_t)decode_size_t<n, nextpos, overflow>::value; 111 112 typedef typename decode_size_t<self_t::n, nextpos, self_t::overflow>::iter iter; 113 }; 114 115 }}//namespace 116 117 #endif//BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED 118