fork download
  1. #include <cstddef>
  2. #include <cstdint>
  3. #include <type_traits>
  4.  
  5. // bool val. to bool type
  6. template <const bool Bool>
  7. struct BoolType {};
  8.  
  9. template<>
  10. struct BoolType<true> {
  11. typedef std::true_type Type;
  12. };
  13.  
  14. template<>
  15. struct BoolType<false> {
  16. typedef std::false_type Type;
  17. };
  18.  
  19. #define BOOL_TYPE(BoolVal) BoolType<BoolVal>::Type
  20.  
  21. // std::is_fundamental [http://w...content-available-to-author-only...s.com/reference/type_traits/is_fundamental/]
  22. enum class ECFundamentalTypeTags {
  23. UNIDENTIFIED,
  24. BOOL,
  25. SIGNED_CHAR,
  26. UNSIGNED_CHAR,
  27. // Signedness of wchar_t is unspecified
  28. // [http://stackoverflow.com/questions/11953363/wchar-t-is-unsigned-or-signed]
  29. WCHAR,
  30.  
  31. //// 'char16_t' AND 'char32_t' SHOULD be a keywords since the C++11,
  32. //// BUT MS VS Community 2013 Upd 5 does NOT supports that
  33. //// AND specifys 'char16_t' AND 'char32_t' as a typdef aliases instead
  34. //// (so they are NOT presented here)
  35.  
  36. SIGNED_SHORT_INT,
  37. UNSIGNED_SHORT_INT,
  38. SIGNED_INT,
  39. UNSIGNED_INT,
  40. SIGNED_LONG_INT,
  41. UNSIGNED_LONG_INT,
  42. SIGNED_LONG_LONG_INT, // C++11
  43. UNSIGNED_LONG_LONG_INT, // C++11
  44. FLOAT,
  45. DOUBLE,
  46. LONG_DOUBLE,
  47. VOID,
  48. NULLPTR // C++11 std::nullptr_t
  49. };
  50.  
  51. template <typename T, class TypeTags = ECFundamentalTypeTags>
  52. struct TypeTag {
  53. static const auto TAG = TypeTags::UNIDENTIFIED;
  54. };
  55.  
  56. template <class TypeTags>
  57. struct TypeTag<bool, TypeTags> {
  58. static const auto TAG = TypeTags::BOOL;
  59. };
  60.  
  61. template <class TypeTags>
  62. struct TypeTag<signed char, TypeTags> {
  63. static const auto TAG = TypeTags::SIGNED_CHAR;
  64. };
  65.  
  66. template <class TypeTags>
  67. struct TypeTag<unsigned char, TypeTags> {
  68. static const auto TAG = TypeTags::UNSIGNED_CHAR;
  69. };
  70.  
  71. template <class TypeTags>
  72. struct TypeTag<wchar_t, TypeTags> {
  73. static const auto TAG = TypeTags::WCHAR;
  74. };
  75.  
  76. template <class TypeTags>
  77. struct TypeTag<signed short int, TypeTags> {
  78. static const auto TAG = TypeTags::SIGNED_SHORT_INT;
  79. };
  80.  
  81. template <class TypeTags>
  82. struct TypeTag<unsigned short int, TypeTags> {
  83. static const auto TAG = TypeTags::UNSIGNED_SHORT_INT;
  84. };
  85.  
  86. template <class TypeTags>
  87. struct TypeTag<signed int, TypeTags> {
  88. static const auto TAG = TypeTags::SIGNED_INT;
  89. };
  90.  
  91. template <class TypeTags>
  92. struct TypeTag<unsigned int, TypeTags> {
  93. static const auto TAG = TypeTags::UNSIGNED_INT;
  94. };
  95.  
  96. template <class TypeTags>
  97. struct TypeTag<signed long int, TypeTags> {
  98. static const auto TAG = TypeTags::SIGNED_LONG_INT;
  99. };
  100.  
  101. template <class TypeTags>
  102. struct TypeTag<unsigned long int, TypeTags> {
  103. static const auto TAG = TypeTags::UNSIGNED_LONG_INT;
  104. };
  105.  
  106. template <class TypeTags>
  107. struct TypeTag<signed long long int, TypeTags> {
  108. static const auto TAG = TypeTags::SIGNED_LONG_LONG_INT;
  109. };
  110.  
  111. template <class TypeTags>
  112. struct TypeTag<unsigned long long int, TypeTags> {
  113. static const auto TAG = TypeTags::UNSIGNED_LONG_LONG_INT;
  114. };
  115.  
  116. template <class TypeTags>
  117. struct TypeTag<float, TypeTags> {
  118. static const auto TAG = TypeTags::FLOAT;
  119. };
  120.  
  121. template <class TypeTags>
  122. struct TypeTag<double, TypeTags> {
  123. static const auto TAG = TypeTags::DOUBLE;
  124. };
  125.  
  126. template <class TypeTags>
  127. struct TypeTag<long double, TypeTags> {
  128. static const auto TAG = TypeTags::LONG_DOUBLE;
  129. };
  130.  
  131. template <class TypeTags>
  132. struct TypeTag<void, TypeTags> {
  133. static const auto TAG = TypeTags::VOID;
  134. };
  135.  
  136. template <class TypeTags>
  137. struct TypeTag<std::nullptr_t, TypeTags> {
  138. static const auto TAG = TypeTags::NULLPTR;
  139. };
  140.  
  141. #define TYPE_TAG(Object) TypeTag<decltype(Object)>::TAG
  142.  
  143. // Size is in bytes
  144. // Fixed width integer types (since C++11): http://e...content-available-to-author-only...e.com/w/cpp/types/integer
  145. // See also: http://w...content-available-to-author-only...4.com/en/t/0012/
  146. template <const size_t Size, const bool Signed>
  147. struct IntegralTypeBySize {
  148. static const auto TAG = ECFundamentalTypeTags::UNIDENTIFIED;
  149. };
  150.  
  151. template<>
  152. struct IntegralTypeBySize<1U, true> {
  153. typedef int8_t Type;
  154. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  155. };
  156.  
  157. template<>
  158. struct IntegralTypeBySize<2U, true> {
  159. typedef int16_t Type;
  160. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  161. };
  162.  
  163. template<>
  164. struct IntegralTypeBySize<4U, true> {
  165. typedef int32_t Type;
  166. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  167. };
  168.  
  169. template<>
  170. struct IntegralTypeBySize<8U, true> {
  171. typedef int64_t Type;
  172. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  173. };
  174.  
  175. template<>
  176. struct IntegralTypeBySize<1U, false> {
  177. typedef uint8_t Type;
  178. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  179. };
  180.  
  181. template<>
  182. struct IntegralTypeBySize<2U, false> {
  183. typedef uint16_t Type;
  184. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  185. };
  186.  
  187. template<>
  188. struct IntegralTypeBySize<4U, false> {
  189. typedef uint32_t Type;
  190. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  191. };
  192.  
  193. template<>
  194. struct IntegralTypeBySize<8U, false> {
  195. typedef uint64_t Type;
  196. static const auto TAG = TypeTag<Type, ECFundamentalTypeTags>::TAG;
  197. };
  198.  
  199. #include <iostream>
  200.  
  201. template<typename T>
  202. void f(T obj) throw() {
  203. switch(TYPE_TAG(obj)) {
  204. case ECFundamentalTypeTags::SIGNED_INT:
  205. case ECFundamentalTypeTags::UNSIGNED_INT:
  206. std::cout << "int!" << std::endl;
  207. break;
  208.  
  209. case ECFundamentalTypeTags::SIGNED_LONG_LONG_INT:
  210. case ECFundamentalTypeTags::UNSIGNED_LONG_LONG_INT:
  211. std::cout << "long long int!" << std::endl;
  212. break;
  213.  
  214. case ECFundamentalTypeTags::FLOAT:
  215. case ECFundamentalTypeTags::DOUBLE:
  216. case ECFundamentalTypeTags::LONG_DOUBLE:
  217. std::cout << "floating point number!" << std::endl;
  218. break;
  219.  
  220. default:
  221. std::cout << "unknown!" << std::endl;
  222. }
  223. }
  224.  
  225. #include <cassert>
  226. #include <typeinfo>
  227.  
  228. int main() {
  229. const BOOL_TYPE(true) btt;
  230. static_assert(btt(), "");
  231. std::cout << btt() << std::endl;
  232.  
  233. const BOOL_TYPE(false) btf;
  234. static_assert(!btf(), "");
  235. std::cout << btf() << std::endl;
  236.  
  237. auto v_1_ = false;
  238. static_assert(ECFundamentalTypeTags::BOOL == TYPE_TAG(v_1_), "");
  239. auto v_2_ = 0;
  240. static_assert(ECFundamentalTypeTags::SIGNED_INT == TYPE_TAG(v_2_), "");
  241. auto v_3_ = 0L;
  242. static_assert(ECFundamentalTypeTags::SIGNED_LONG_INT == TYPE_TAG(v_3_), "");
  243. auto v_4_ = 0ULL;
  244. static_assert(ECFundamentalTypeTags::UNSIGNED_LONG_LONG_INT == TYPE_TAG(v_4_), "");
  245.  
  246. f(1), f(1ULL), f(1.0), f(1.0L);
  247.  
  248. IntegralTypeBySize<sizeof(char), true>::Type t1_ = 0;
  249. static_assert(sizeof(t1_) == sizeof(char), "");
  250. static_assert(std::is_integral<decltype(t1_)>::value && std::is_signed<decltype(t1_)>::value, "");
  251.  
  252. IntegralTypeBySize<sizeof(int), true>::Type t2_ = 0;
  253. static_assert(sizeof(t2_) == sizeof(int), "");
  254. static_assert(std::is_integral<decltype(t2_)>::value && std::is_signed<decltype(t2_)>::value, "");
  255.  
  256. IntegralTypeBySize<sizeof(long long int), true>::Type t4_ = 0;
  257. static_assert(sizeof(t4_) == sizeof(long long int), "");
  258. static_assert(std::is_integral<decltype(t4_)>::value && std::is_signed<decltype(t4_)>::value, "");
  259.  
  260. const IntegralTypeBySize<8U, false>::Type array[32U] = {0};
  261. std::cout << "\ni've got a " << sizeof(array) / sizeof(*array) << " length array of "
  262. << typeid(*array).name() << "s here!\n";
  263.  
  264. return 0;
  265. }
Success #stdin #stdout 0s 3456KB
stdin
Standard input is empty
stdout
1
0
int!
long long int!
floating point number!
floating point number!

i've got a 32 length array of ys here!