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