Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

237 lignes
5.8 KiB

  1. #pragma once
  2. #include <cxxabi.h>
  3. #include <iostream>
  4. #if defined(__linux__)
  5. # include <endian.h>
  6. #elif defined(__FreeBSD__) || defined(__NetBSD__)
  7. # include <sys/endian.h>
  8. #elif defined(__OpenBSD__)
  9. # include <sys/types.h>
  10. # define be16toh(x) betoh16(x)
  11. # define be32toh(x) betoh32(x)
  12. # define be64toh(x) betoh64(x)
  13. #endif
  14. namespace utl
  15. {
  16. /* TypeHelper ********************************************************************************/
  17. template<class T>
  18. struct TypeHelper
  19. {
  20. public:
  21. static inline std::string name()
  22. {
  23. int status;
  24. auto name = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
  25. return std::string(name ? name : typeid(T).name());
  26. }
  27. };
  28. /* simple class that stores a value of type T */
  29. template<class T>
  30. struct wrapper
  31. {
  32. using value_type = T;
  33. value_type value;
  34. inline value_type& operator*()
  35. { return value; }
  36. inline const value_type& operator*() const
  37. { return value; }
  38. inline wrapper& operator=(const value_type v)
  39. {
  40. value = v;
  41. return *this;
  42. }
  43. inline wrapper& operator=(const wrapper& other)
  44. {
  45. value = other.value;
  46. return *this;
  47. }
  48. inline wrapper& operator=(wrapper&& other)
  49. {
  50. value = std::move(other).value;
  51. return *this;
  52. }
  53. inline wrapper() :
  54. value(value_type())
  55. { }
  56. inline wrapper(const value_type& v) :
  57. value(v)
  58. { }
  59. inline wrapper(const wrapper& other) :
  60. value(other.value)
  61. { }
  62. inline wrapper(wrapper&& other) :
  63. value(std::move(other.value))
  64. { }
  65. };
  66. template<class T>
  67. struct wrapper<T&>
  68. {
  69. using value_type = T&;
  70. using storage_type = T*;
  71. storage_type value;
  72. inline value_type operator*() const
  73. {
  74. assert(value != nullptr);
  75. return *value;
  76. }
  77. inline wrapper& operator=(const value_type v)
  78. {
  79. value = &v;
  80. return *this;
  81. }
  82. inline wrapper& operator=(const wrapper& other)
  83. {
  84. value = other.value;
  85. return *this;
  86. }
  87. inline wrapper& operator=(wrapper&& other)
  88. {
  89. value = std::move(other.value);
  90. return *this;
  91. }
  92. inline wrapper() :
  93. value(nullptr)
  94. { }
  95. inline wrapper(value_type v) :
  96. value(&v)
  97. { }
  98. inline wrapper(const wrapper& other) :
  99. value(other.value)
  100. { }
  101. inline wrapper(wrapper&& other) :
  102. value(std::move(other.value))
  103. { }
  104. };
  105. /* Helper Methods ****************************************************************************/
  106. inline int bitCount(uint32_t u)
  107. {
  108. u = u
  109. - ((u >> 1) & 033333333333)
  110. - ((u >> 2) & 011111111111);
  111. return ((u + (u >> 3)) & 030707070707) % 63;
  112. }
  113. template<class T, class S>
  114. inline bool tryCast(T* t, S*& s)
  115. {
  116. s = dynamic_cast<S*>(t);
  117. return static_cast<bool>(s);
  118. }
  119. namespace __impl
  120. {
  121. template<class T, size_t N = sizeof(T)>
  122. struct network_convert_helper;
  123. }
  124. template<class T>
  125. inline T hton(const T& value)
  126. { return __impl::network_convert_helper<T>::hton(value); }
  127. template<class T>
  128. inline T ntoh(const T& value)
  129. { return __impl::network_convert_helper<T>::ntoh(value); }
  130. /* Indent Stream *****************************************************************************/
  131. namespace __impl
  132. {
  133. inline int identStreamIndex()
  134. {
  135. const int value = std::ios::xalloc();
  136. return value;
  137. }
  138. }
  139. inline std::ostream& incindent(std::ostream& os)
  140. {
  141. ++os.iword(__impl::identStreamIndex());
  142. return os;
  143. }
  144. inline std::ostream& decindent(std::ostream& os)
  145. {
  146. auto& indent = os.iword(__impl::identStreamIndex());
  147. if (--indent < 0)
  148. indent = 0;
  149. return os;
  150. }
  151. inline std::ostream& indent(std::ostream& os)
  152. {
  153. auto i = os.iword(__impl::identStreamIndex());
  154. while (i--)
  155. os << " ";
  156. return os;
  157. }
  158. /* implementation ****************************************************************************/
  159. namespace __impl
  160. {
  161. template<class T>
  162. struct network_convert_helper<T, 1>
  163. {
  164. static inline T hton(const T& t)
  165. { return t; }
  166. static inline T ntoh(const T& t)
  167. { return t; }
  168. };
  169. template<class T>
  170. struct network_convert_helper<T, 2>
  171. {
  172. static inline T hton(const T& t)
  173. { return reinterpret_cast<T>(htobe16(reinterpret_cast<uint16_t>(t))); }
  174. static inline T ntoh(const T& t)
  175. { return reinterpret_cast<T>(be16toh(reinterpret_cast<uint16_t>(t))); }
  176. };
  177. template<class T>
  178. struct network_convert_helper<T, 4>
  179. {
  180. static inline T hton(const T& t)
  181. { return reinterpret_cast<T>(htobe32(reinterpret_cast<uint32_t>(t))); }
  182. static inline T ntoh(const T& t)
  183. { return reinterpret_cast<T>(be32toh(reinterpret_cast<uint32_t>(t))); }
  184. };
  185. template<class T>
  186. struct network_convert_helper<T, 8>
  187. {
  188. static inline T hton(const T& t)
  189. { return reinterpret_cast<T>(htobe64(reinterpret_cast<uint64_t>(t))); }
  190. static inline T ntoh(const T& t)
  191. { return reinterpret_cast<T>(be64toh(reinterpret_cast<uint64_t>(t))); }
  192. };
  193. }
  194. }