int_encoding.hpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. #ifndef BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED
  5. #define BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED
  6. #include <boost/config.hpp>
  7. #include <boost/typeof/constant.hpp>
  8. namespace boost { namespace type_of {
  9. template<class T> struct get_unsigned
  10. {
  11. typedef T type;
  12. };
  13. template<> struct get_unsigned<signed char>
  14. {
  15. typedef unsigned char type;
  16. };
  17. template<> struct get_unsigned<char>
  18. {
  19. typedef unsigned char type;
  20. };
  21. template<> struct get_unsigned<short>
  22. {
  23. typedef unsigned short type;
  24. };
  25. template<> struct get_unsigned<int>
  26. {
  27. typedef unsigned int type;
  28. };
  29. template<> struct get_unsigned<long>
  30. {
  31. typedef unsigned long type;
  32. };
  33. //////////////////////////
  34. template<std::size_t n, bool Overflow>
  35. struct pack
  36. {
  37. BOOST_STATIC_CONSTANT(std::size_t , value=((n + 1) * 2 + (Overflow ? 1 : 0)));
  38. };
  39. template<std::size_t m>
  40. struct unpack
  41. {
  42. BOOST_STATIC_CONSTANT(std::size_t, value = (m / 2) - 1);
  43. BOOST_STATIC_CONSTANT(std::size_t, overflow = (m % 2 == 1));
  44. };
  45. ////////////////////////////////
  46. template<class V, std::size_t n, bool overflow = (n >= 0x3fffffff)>
  47. struct encode_size_t : push_back<
  48. V,
  49. boost::type_of::constant<std::size_t,pack<n, false>::value>
  50. >
  51. {};
  52. template<class V, std::size_t n>
  53. struct encode_size_t<V, n, true> : push_back<typename push_back<
  54. V,
  55. boost::type_of::constant<std::size_t,pack<n % 0x3ffffffe, true>::value> >::type,
  56. boost::type_of::constant<std::size_t,n / 0x3ffffffe>
  57. >
  58. {};
  59. template<class V, class T, T n>
  60. struct encode_integral : encode_size_t< V, (typename get_unsigned<T>::type)n,(((typename get_unsigned<T>::type)n)>=0x3fffffff) >
  61. {};
  62. template<class V, bool b>
  63. struct encode_integral<V, bool, b> : encode_size_t< V, b?1:0, false>
  64. {};
  65. ///////////////////////////
  66. template<std::size_t n, class Iter, bool overflow>
  67. struct decode_size_t;
  68. template<std::size_t n, class Iter>
  69. struct decode_size_t<n, Iter, false>
  70. {
  71. BOOST_STATIC_CONSTANT(std::size_t,value = n);
  72. typedef Iter iter;
  73. };
  74. template<std::size_t n, class Iter>
  75. struct decode_size_t<n, Iter, true>
  76. {
  77. BOOST_STATIC_CONSTANT(std::size_t,m = Iter::type::value);
  78. BOOST_STATIC_CONSTANT(std::size_t,value = (std::size_t)m * 0x3ffffffe + n);
  79. typedef typename Iter::next iter;
  80. };
  81. template<class T, class Iter>
  82. struct decode_integral
  83. {
  84. typedef decode_integral<T,Iter> self_t;
  85. BOOST_STATIC_CONSTANT(std::size_t,m = Iter::type::value);
  86. BOOST_STATIC_CONSTANT(std::size_t,n = unpack<m>::value);
  87. BOOST_STATIC_CONSTANT(std::size_t,overflow = unpack<m>::overflow);
  88. typedef typename Iter::next nextpos;
  89. static const T value = (T)(std::size_t)decode_size_t<n, nextpos, overflow>::value;
  90. typedef typename decode_size_t<self_t::n, nextpos, self_t::overflow>::iter iter;
  91. };
  92. }}//namespace
  93. #endif//BOOST_TYPEOF_INT_ENCODING_HPP_INCLUDED