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