]>
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 | ||
7c673cae | 8 | #include <boost/config.hpp> |
92f5a8d4 | 9 | #include <boost/typeof/constant.hpp> |
7c673cae FG |
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, | |
92f5a8d4 | 58 | boost::type_of::constant<std::size_t,pack<n, false>::value> |
7c673cae FG |
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, | |
92f5a8d4 TL |
65 | boost::type_of::constant<std::size_t,pack<n % 0x3ffffffe, true>::value> >::type, |
66 | boost::type_of::constant<std::size_t,n / 0x3ffffffe> | |
7c673cae FG |
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 |