var_int.h
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:10k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_var_int_h__
  3. #define __febird_io_var_int_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include <limits>
  8. #include <boost/config.hpp>
  9. #include <boost/strong_typedef.hpp>
  10. #include <boost/static_assert.hpp>
  11. #include "../stdtypes.h"
  12. #include "../pass_by_value.h"
  13. #include "byte_swap.h"
  14. #include "is_primitive.h"
  15. #undef min
  16. #undef max
  17. namespace febird {
  18. template<class VarIntT> struct var_int_org;
  19. template<class T> struct var_int;
  20. template<class T> struct is_var_int : boost::mpl::false_ {};
  21. #define FEBIRD_DEFINE_VAR_INT_IMPL(IntT, VarIntT)
  22. BOOST_STRONG_TYPEDEF(IntT, VarIntT)
  23. template<> struct is_var_int<VarIntT> : boost::mpl::true_ {}; 
  24. template<> struct is_primitive<VarIntT> : boost::mpl::true_ {}; 
  25. template<> struct var_int<IntT> : VarIntT { typedef VarIntT type; }; 
  26. template<> struct var_int<VarIntT> : VarIntT { typedef VarIntT type; };  
  27. template<> struct var_int_org<VarIntT> { typedef IntT type; };
  28. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  29. // var int is  var_+IntT, var_int16_t, var_uint16_t, ...
  30. // var_int_org<IntT>::type is original int of the var int
  31. // is_var_int is the typetrait of var int
  32. FEBIRD_DEFINE_VAR_INT_IMPL(         short, var_int16_t)
  33. FEBIRD_DEFINE_VAR_INT_IMPL(unsigned short, var_uint16_t)
  34. #if defined(BOOST_HAS_LONG_LONG)
  35. FEBIRD_DEFINE_VAR_INT_IMPL(         long long, var_int64_t)
  36. FEBIRD_DEFINE_VAR_INT_IMPL(unsigned long long, var_uint64_t)
  37. #elif defined(BOOST_HAS_MS_INT64)
  38. FEBIRD_DEFINE_VAR_INT_IMPL(         __int64, var_int64_t)
  39. FEBIRD_DEFINE_VAR_INT_IMPL(unsigned __int64, var_uint64_t)
  40. #endif
  41. #if ULONG_MAX == 0xFFFFFFFF
  42. FEBIRD_DEFINE_VAR_INT_IMPL(         long, var_int32_t)
  43. FEBIRD_DEFINE_VAR_INT_IMPL(unsigned long, var_uint32_t)
  44.   #if UINT_MAX == 0xFFFFFFFF
  45. template<> struct var_int<         int> : var_int32_t  { typedef var_int32_t type; };
  46. template<> struct var_int<unsigned int> : var_uint32_t { typedef var_uint32_t type; };
  47.   #elif UINT_MAX == 0xFFFF
  48. template<> struct var_int<         int> : var_int16_t  { typedef var_int16_t type; };
  49. template<> struct var_int<unsigned int> : var_uint16_t { typedef var_uint16_t type; };
  50.   #endif
  51. #elif UINT_MAX == 0xFFFFFFFF
  52. FEBIRD_DEFINE_VAR_INT_IMPL(         int, var_int32_t)
  53. FEBIRD_DEFINE_VAR_INT_IMPL(unsigned int, var_uint32_t)
  54. template<> struct var_int<         long> : var_int64_t  { typedef var_int64_t type; };
  55. template<> struct var_int<unsigned long> : var_uint64_t { typedef var_uint64_t type; };
  56. #else
  57. #   error no int32
  58. #endif
  59. inline void byte_swap_in(var_int16_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  60. inline void byte_swap_in(var_int32_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  61. inline void byte_swap_in(var_int64_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  62. inline void byte_swap_in(var_uint16_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  63. inline void byte_swap_in(var_uint32_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  64. inline void byte_swap_in(var_uint64_t& x, boost::mpl::true_) { x.t = byte_swap(x.t); }
  65. template<class IntT>
  66. class as_var_int_ref
  67. {
  68. IntT& val;
  69. public:
  70. explicit as_var_int_ref(IntT& x) : val(x) {}
  71. template<class Input>
  72. friend void DataIO_loadObject(Input& in, as_var_int_ref x)
  73. {
  74. typename var_int<IntT>::type v;
  75. in >> v;
  76. x.val = v.t;
  77. }
  78. template<class Output>
  79. friend void DataIO_saveObject(Output& out, as_var_int_ref x)
  80. {
  81. // 必须有这个函数,因为有可能把一个 non-const int& 传递给 as_var_int 来输出
  82. out << typename var_int<IntT>::type(x.val);
  83. }
  84. };
  85. //! for load as var int
  86. template<class IntT>
  87. inline
  88. pass_by_value<as_var_int_ref<IntT> >
  89. as_var_int(IntT& x)
  90. {
  91. return pass_by_value<as_var_int_ref<IntT> >(as_var_int_ref<IntT>(x));
  92. }
  93. //! for save as var int
  94. template<class IntT>
  95. inline
  96. typename var_int<IntT>::type
  97. as_var_int(const IntT& x)
  98. {
  99. return typename var_int<IntT>::type(x);
  100. }
  101. inline unsigned int sizeof_int_aux(char x, boost::mpl::false_) { return 1; }
  102. inline unsigned int sizeof_int_aux(signed char x, boost::mpl::false_) { return 1; }
  103. inline unsigned int sizeof_int_aux(unsigned char x, boost::mpl::false_) { return 1; }
  104. inline unsigned int sizeof_int_aux(uint16_t x, boost::mpl::false_) { return 2; }
  105. inline unsigned int sizeof_int_aux(uint32_t x, boost::mpl::false_) { return 4; }
  106. inline unsigned int sizeof_int_aux(uint64_t x, boost::mpl::false_) { return 8; }
  107. inline unsigned int sizeof_int_aux(int16_t x, boost::mpl::false_) { return 2; }
  108. inline unsigned int sizeof_int_aux(int32_t x, boost::mpl::false_) { return 4; }
  109. inline unsigned int sizeof_int_aux(int64_t x, boost::mpl::false_) { return 8; }
  110. inline unsigned int sizeof_int_aux(var_uint16_t x, boost::mpl::true_)
  111. {
  112. if (x.t < 1<< 7) return 1;
  113. if (x.t < 1<<14) return 2;
  114. return 3;
  115. }
  116. inline unsigned int sizeof_int_aux(var_uint32_t x, boost::mpl::true_)
  117. {
  118. if (x.t < uint32_t(1)<< 7) return 1;
  119. if (x.t < uint32_t(1)<<14) return 2;
  120. if (x.t < uint32_t(1)<<21) return 3;
  121. if (x.t < uint32_t(1)<<28) return 4;
  122. return 5;
  123. }
  124. inline unsigned int sizeof_int_aux(var_uint64_t x, boost::mpl::true_)
  125. {
  126. if (x.t < uint64_t(1)<< 7) return 1;
  127. if (x.t < uint64_t(1)<<14) return 2;
  128. if (x.t < uint64_t(1)<<21) return 3;
  129. if (x.t < uint64_t(1)<<28) return 4;
  130. if (x.t < uint64_t(1)<<35) return 5;
  131. if (x.t < uint64_t(1)<<42) return 6;
  132. if (x.t < uint64_t(1)<<49) return 7;
  133. if (x.t < uint64_t(1)<<56) return 8;
  134. return 9;
  135. }
  136. inline unsigned int sizeof_int_aux(var_int16_t x, boost::mpl::true_)
  137. {
  138. if (x.t >= 0)
  139. return sizeof_int_aux(var_uint16_t(x.t << 1), boost::mpl::true_());
  140. else
  141. return sizeof_int_aux(var_uint16_t(-x.t << 1), boost::mpl::true_());
  142. }
  143. inline unsigned int sizeof_int_aux(var_int32_t x, boost::mpl::true_)
  144. {
  145. if (x.t >= 0)
  146. return sizeof_int_aux(var_uint32_t(x.t << 1), boost::mpl::true_());
  147. else
  148. return sizeof_int_aux(var_uint32_t(-x.t << 1), boost::mpl::true_());
  149. }
  150. inline unsigned int sizeof_int_aux(var_int64_t x, boost::mpl::true_)
  151. {
  152. if (x.t >= 0)
  153. return sizeof_int_aux(var_uint64_t(x.t << 1), boost::mpl::true_());
  154. else
  155. return sizeof_int_aux(var_uint64_t(-x.t << 1), boost::mpl::true_());
  156. }
  157. template<class IntType>
  158. unsigned int sizeof_int(IntType x)
  159. {
  160. return sizeof_int_aux(x, typename is_var_int<IntType>::type());
  161. }
  162. // lowest bit is sign bit
  163. // 
  164. template<class IntType, class UIntType>
  165. inline UIntType var_int_s2u(IntType x)
  166. {
  167. // BOOST_STATIC_ASSERT(IntType(-1) < IntType(0));
  168. // BOOST_STATIC_ASSERT(UIntType(-1) > UIntType(0));
  169. BOOST_STATIC_ASSERT(sizeof(IntType)==sizeof(UIntType));
  170. if (x < 0) {
  171. if (std::numeric_limits<IntType>::min() == x)
  172. return UIntType(1);
  173. else
  174. return UIntType(-x << 1 | 1);
  175. } else
  176. return UIntType(x << 1);
  177. }
  178. template<class UIntType, class IntType>
  179. inline IntType var_int_u2s(UIntType u)
  180. {
  181. // BOOST_STATIC_ASSERT(IntType(-1) < IntType(0));
  182. // BOOST_STATIC_ASSERT(UIntType(-1) > UIntType(0));
  183. BOOST_STATIC_ASSERT(sizeof(IntType)==sizeof(UIntType));
  184. if (u & 1) {
  185. if (0 == u >> 1)
  186. return std::numeric_limits<IntType>::min();
  187. else
  188. return -(IntType)(u >> 1);
  189. } else
  190. return (IntType)(u >> 1);
  191. }
  192. inline uint16_t var_int16_s2u(int16_t x) { return var_int_s2u<int16_t, uint16_t>(x); }
  193. inline uint32_t var_int32_s2u(int32_t x) { return var_int_s2u<int32_t, uint32_t>(x); }
  194. inline int16_t var_int16_u2s(uint16_t u) { return var_int_u2s<uint16_t, int16_t>(u); }
  195. inline int32_t var_int32_u2s(uint32_t u) { return var_int_u2s<uint32_t, int32_t>(u); }
  196. #if !defined(BOOST_NO_INT64_T)
  197. inline uint64_t var_int64_s2u(int64_t x) { return var_int_s2u<int64_t, uint64_t>(x); }
  198. inline int64_t var_int64_u2s(uint64_t u) { return var_int_u2s<uint64_t, int64_t>(u); }
  199. #endif
  200. ////////////////////////////////////////////////////////////////////////////////////////
  201. FEBIRD_DLL_EXPORT std::pair<uint16_t, int> load_var_uint16(const unsigned char* buf);
  202. FEBIRD_DLL_EXPORT std::pair<uint32_t, int> load_var_uint32(const unsigned char* buf);
  203. FEBIRD_DLL_EXPORT std::pair<uint64_t, int> load_var_uint64(const unsigned char* buf);
  204. FEBIRD_DLL_EXPORT std::pair<int16_t, int> load_var_int16(const unsigned char* buf);
  205. FEBIRD_DLL_EXPORT std::pair<int32_t, int> load_var_int32(const unsigned char* buf);
  206. FEBIRD_DLL_EXPORT std::pair<int64_t, int> load_var_int64(const unsigned char* buf);
  207. //--------------------------------------------------------------------------------------
  208. FEBIRD_DLL_EXPORT unsigned char* save_var_uint16(unsigned char* buf, uint16_t x);
  209. FEBIRD_DLL_EXPORT unsigned char* save_var_uint32(unsigned char* buf, uint32_t x);
  210. FEBIRD_DLL_EXPORT unsigned char* save_var_uint64(unsigned char* buf, uint64_t x);
  211. FEBIRD_DLL_EXPORT unsigned char* save_var_int16(unsigned char* buf, int16_t x);
  212. FEBIRD_DLL_EXPORT unsigned char* save_var_int32(unsigned char* buf, int32_t x);
  213. FEBIRD_DLL_EXPORT unsigned char* save_var_int64(unsigned char* buf, int64_t x);
  214. ////////////////////////////////////////////////////////////////////////////////////////
  215. FEBIRD_DLL_EXPORT uint32_t reverse_get_var_uint32(const unsigned char* buf, unsigned char const ** cur);
  216. FEBIRD_DLL_EXPORT int32_t reverse_get_var_int32(const unsigned char* buf, unsigned char const ** cur);
  217. FEBIRD_DLL_EXPORT uint16_t reverse_get_var_uint16(const unsigned char* buf, unsigned char const ** cur);
  218. FEBIRD_DLL_EXPORT int16_t reverse_get_var_int16(const unsigned char* buf, unsigned char const ** cur);
  219. #if !defined(BOOST_NO_INT64_T)
  220. FEBIRD_DLL_EXPORT uint64_t reverse_get_var_uint64(const unsigned char* buf, unsigned char const ** cur);
  221. FEBIRD_DLL_EXPORT int64_t reverse_get_var_int64(const unsigned char* buf, unsigned char const ** cur);
  222. #endif
  223. } // namespace febird
  224. #endif // __febird_io_var_int_h__