fork(1) download
  1. // ausgeliehen von Sones https://g...content-available-to-author-only...b.com/bingojamigo/VTMPL
  2. #include <cstddef>
  3. #include <limits>
  4. #include <type_traits>
  5.  
  6. namespace vtmpl
  7. {
  8.  
  9. using size_type = std::size_t;
  10.  
  11. using index_type = size_type;
  12.  
  13. template<typename T>
  14. struct identity
  15. {
  16. using type = T;
  17. };
  18.  
  19. template<typename A, typename B>
  20. struct type_pair : identity<type_pair<A,B>>
  21. {
  22. using first = A;
  23. using second = B;
  24. };
  25.  
  26. template <typename T, T...> struct value_list;
  27.  
  28. template <typename Type,
  29. Type... args>
  30. struct value_list_base : identity<value_list<Type, args...>>
  31. {
  32. static constexpr size_type length = sizeof...(args);
  33.  
  34. static constexpr size_type npos = std::numeric_limits<size_type>::max();
  35.  
  36. using value_type = Type;
  37.  
  38. static constexpr value_type arr[] { args... };
  39.  
  40. private:
  41.  
  42. static constexpr size_type _count_impl( char c, size_type index )
  43. {
  44. return arr[index] == c + (index == 0 ? 0 : _count_impl(c, index - 1));
  45. }
  46.  
  47. static constexpr size_type _find_impl( char c, size_type index )
  48. {
  49. return index == length ? npos : c == arr[index] ? index : _find_impl(c, index + 1);
  50. }
  51.  
  52. public:
  53.  
  54. static constexpr size_type count( char c )
  55. {
  56. return _count_impl( c, length - 1 );
  57. }
  58.  
  59. static constexpr size_type find( char c )
  60. {
  61. return _find_impl( c, 0 );
  62. }
  63. };
  64.  
  65. template <typename Type,
  66. Type... args>
  67. constexpr Type value_list_base<Type, args...>::arr[];
  68.  
  69. template<typename Type,
  70. Type... args>
  71. struct value_list : value_list_base<Type, args...> {};
  72.  
  73. template<char... args>
  74. struct value_list<char, args...> : value_list_base<char, args...>
  75. {
  76. static char constexpr nt_arr[] { args..., '\0' };
  77. };
  78.  
  79. template<index_type ... args>
  80. using index_list = value_list<index_type, args...>;
  81.  
  82. template <typename, typename> struct multiply;
  83. template <index_type... indices, index_type... tail>
  84. struct multiply<index_list<indices...>,
  85. index_list<tail... >> : index_list<indices..., (sizeof...(indices)+indices)...,
  86. (2*sizeof...(indices)+indices)...,
  87. (3*sizeof...(indices)+indices)...,
  88. (4*sizeof...(indices)+tail)...> {};
  89.  
  90. //! make_index_list: Essential function to generate a list of numbers, used in many other functions to avoid recursion.
  91. // Generates a list of natural numbers. make_index_list<4> -> {0, 1, 2, 3}, for example, and make_index_list<23510> -> {0, 1, 2, 3, 4, ..., 23509}.
  92.  
  93. template <index_type N>
  94. struct make_index_list :
  95. multiply< typename make_index_list<N/4>::type,
  96. typename make_index_list<N%4>::type > {};
  97.  
  98. template <> struct make_index_list<3> : index_list<0, 1, 2> {};
  99. template <> struct make_index_list<2> : index_list<0, 1> {};
  100. template <> struct make_index_list<1> : index_list<0> {};
  101. template <> struct make_index_list<0> : index_list<> {};
  102.  
  103. template<char... args>
  104. char constexpr value_list<char, args...>::nt_arr[];
  105.  
  106. template <typename,
  107. size_type,
  108. size_type len,
  109. typename = typename make_index_list<len>::type> struct sub_list;
  110.  
  111. template <typename Type, Type ... args,
  112. size_type pos,
  113. size_type len,
  114. index_type... indices>
  115. struct sub_list<value_list<Type, args...>,
  116. pos, len,
  117. index_list<indices...>> :
  118. value_list<Type, value_list<Type, args...>::arr[pos + indices]...> {};
  119.  
  120. /// split_at: Splits the list into to sublists as specified by the position. The value at position pos is in the first list.
  121.  
  122. template <typename list,
  123. size_type pos> struct split_at;
  124.  
  125. template <typename val_t,
  126. val_t ... values,
  127. size_type pos>
  128. struct split_at<value_list<val_t, values...>,
  129. pos> :
  130. type_pair< typename sub_list<value_list<val_t, values...>, 0, pos + 1>::type,
  131. typename sub_list<value_list<val_t, values...>, pos + 1, sizeof...(values) - pos - 1>::type > {};
  132.  
  133. /// rtrim: cuts of all values after a specific one
  134.  
  135. template<typename List, typename List::value_type> struct rtrim;
  136. template<typename Type, Type ... args, Type to_find>
  137. struct rtrim<value_list<Type, args...>, to_find> :
  138. split_at<value_list<Type, args...>,
  139. value_list<Type, args...>::find( to_find )>::first {};
  140.  
  141. template<char ... args>
  142. using const_string = value_list<char, args...>;
  143.  
  144. #define SPLIT_1(s, x) ( x < sizeof(s) ? s[x] : '\0' )
  145. #define SPLIT_4(s, x) SPLIT_1 (s, x), SPLIT_1 (s, x+1) , SPLIT_1 (s, x+2) , SPLIT_1 (s, x+3)
  146. #define SPLIT_16(s, x) SPLIT_4 (s, x), SPLIT_4 (s, x+4) , SPLIT_4 (s, x+8) , SPLIT_4 (s, x+12)
  147. #define SPLIT_64(s, x) SPLIT_16 (s, x), SPLIT_16 (s, x+16) , SPLIT_16 (s, x+32) , SPLIT_16 (s, x+48)
  148. #define SPLIT_256(s, x) SPLIT_64 (s, x), SPLIT_64 (s, x+64) , SPLIT_64 (s, x+128 , SPLIT_64 (s, x+194)
  149. #define SPLIT_1024(s, x) SPLIT_256(s, x), SPLIT_256(s, x+256), SPLIT_256(s, x+512), SPLIT_256(s, x+768)
  150.  
  151. //!: Use this macro to create a const_string from a string literal or constant pointer
  152.  
  153. #define STRING_IMPL(str, n) vtmpl::rtrim<vtmpl::const_string<SPLIT_##n(str, 0)>, '\0'>::type
  154.  
  155. #define STRING(str) STRING_IMPL(str, 64)
  156. #define STRING_256(str) STRING_IMPL(str, 256)
  157. #define STRING_1024(str) STRING_IMPL(str, 1024)
  158.  
  159. }
  160. // ende ausgeliehen
  161.  
  162. #include <string>
  163.  
  164. namespace regex_impl
  165. {
  166. // normales Zeichen
  167. template <typename String>
  168. class regex
  169. {
  170. public:
  171. static bool match(bool before, std::string string)
  172. {
  173. using string_pair = typename vtmpl::split_at<String, String::find('\0') - 1>::type;
  174. return regex<typename string_pair::second>::match(string.find(string_pair::first::nt_arr) != std::string::npos && before,
  175. string);
  176. }
  177. };
  178.  
  179. // Ende
  180. template <>
  181. class regex<vtmpl::const_string<'\0'>>
  182. {
  183. public:
  184. static bool match(bool before, std::string)
  185. {
  186. return before;
  187. }
  188. };
  189. }
  190.  
  191. template <typename Regex>
  192. class regex
  193. {
  194. public:
  195. static bool match(std::string string)
  196. {
  197. return regex_impl::regex<Regex>::match(true, string);
  198. }
  199. };
  200.  
  201. #include <iostream>
  202.  
  203. int main()
  204. {
  205. std::cout << regex<STRING("ello")>::match("Hello World!")
  206. << regex<STRING("foo")>::match("Hello World!");
  207. }
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
10