Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

980 Zeilen
30 KiB

  1. #pragma once
  2. #include <tuple>
  3. #include <string>
  4. #include <cstdlib>
  5. #include <cstdint>
  6. #include <type_traits>
  7. #define MP_DEBUG
  8. #if defined __GNUC__
  9. # define LIKELY(EXPR) __builtin_expect(!!(EXPR), 1)
  10. #else
  11. # define LIKELY(EXPR) (!!(EXPR))
  12. #endif
  13. #if defined MP_DEBUG
  14. # define X_ASSERT(CHECK) void(0)
  15. #else
  16. # define X_ASSERT(CHECK) ( LIKELY(CHECK) ? void(0) : []{assert(!#CHECK);}() )
  17. #endif
  18. namespace utl
  19. {
  20. /* types */
  21. template<class T, T t>
  22. using mp_const = std::integral_constant<T, t>;
  23. template<bool B>
  24. using mp_bool = mp_const<bool, B>;
  25. template<size_t S>
  26. using mp_size_t = mp_const<size_t, S>;
  27. template<class...>
  28. struct mp_list { };
  29. template<class T>
  30. struct mp_identity
  31. { using type = T; };
  32. template<class... T>
  33. struct mp_inherit : T...
  34. { };
  35. template<class T, T... Ints>
  36. struct mp_integer_sequence
  37. { };
  38. template<size_t... Ints>
  39. using mp_index_sequence = mp_integer_sequence<size_t, Ints...>;
  40. /* constants */
  41. using mp_true = mp_bool<true>;
  42. using mp_false = mp_bool<false>;
  43. using mp_zero = mp_size_t<0>;
  44. /* modifier */
  45. template<class T>
  46. using mp_add_pointer = T*;
  47. template<class T>
  48. using mp_add_reference = T&;
  49. template<class T>
  50. using mp_remove_ptr = typename std::remove_pointer<T>::type;
  51. template<class T>
  52. using mp_remove_const = typename std::remove_const<T>::type;
  53. template<class T>
  54. using mp_remove_cv = typename std::remove_cv<T>::type;
  55. template<class T>
  56. using mp_remove_ref = typename std::remove_reference<T>::type;
  57. template<class T>
  58. using mp_clean_type = mp_remove_cv<mp_remove_ptr<mp_remove_ref<T>>>;
  59. /* conditionals */
  60. template<class T, class S>
  61. using mp_is_same = mp_bool<std::is_same<T, S>::value>;
  62. template<class Base, class Derived>
  63. using mp_is_base_of = mp_bool<std::is_base_of<Base, Derived>::value>;
  64. template<class T, class S = void>
  65. using mp_enable_if = typename std::enable_if<T::value, S>::type;
  66. template<bool B, class S = void>
  67. using mp_enable_if_c = typename std::enable_if<B, S>::type;
  68. namespace __impl
  69. {
  70. /* logical operations */
  71. template<bool C, class T, class E>
  72. struct mp_if_c_impl;
  73. template<bool C, class T, template<class...> class E, class... A>
  74. struct mp_eval_if_c_impl;
  75. template<class L>
  76. struct mp_not_impl;
  77. template<class L>
  78. struct mp_and_impl;
  79. template<class L>
  80. struct mp_or_impl;
  81. /* arithmetic */
  82. template<class L>
  83. struct mp_plus_impl;
  84. template<class L>
  85. struct mp_minus_impl;
  86. template<class L>
  87. struct mp_multiply_impl;
  88. template<class L>
  89. struct mp_divide_impl;
  90. /* generator functions */
  91. template<class S>
  92. struct next_integer_sequence;
  93. template<class T, T I, T N>
  94. struct mp_make_int_seq_impl;
  95. template<size_t N, class... T>
  96. struct mp_repeat_impl;
  97. /* list operations returning a numeric value */
  98. template<class L>
  99. struct mp_size_impl;
  100. template<class L, class V>
  101. struct mp_count_impl;
  102. template<class L, template<class...> class P>
  103. struct mp_count_if_impl;
  104. /* operations to manipulate list content */
  105. template<class L, class... T>
  106. struct mp_push_front_impl;
  107. template<class L>
  108. struct mp_pop_front_impl;
  109. template<class L, class... T>
  110. struct mp_push_back_impl;
  111. template<class... L>
  112. struct mp_concat_impl;
  113. template<class L, template<class> class F>
  114. struct mp_filter_impl;
  115. /* list operations returning a bool value */
  116. template<class... L>
  117. struct mp_empty_impl;
  118. template<class L, class V>
  119. struct mp_contains_impl;
  120. /* list operations returing elements from the list */
  121. template<class L>
  122. struct mp_front_impl;
  123. template<class L>
  124. struct mp_second_impl;
  125. template<class L, size_t I>
  126. struct mp_at_c_impl;
  127. template<class L, template<class> class F, class TDefault>
  128. struct mp_search_impl;
  129. template<class L, class V>
  130. struct mp_find_impl;
  131. template<class M, class K>
  132. struct mp_map_find_impl;
  133. /* list manipulators returning a new list */
  134. template<class L>
  135. struct mp_clear_impl;
  136. template<class L, class C>
  137. struct mp_unique_impl;
  138. template<class A, template<class...> class B>
  139. struct mp_rename_impl;
  140. template<class... L>
  141. struct mp_append_impl;
  142. template<class L, class S>
  143. struct mp_map_from_list_impl;
  144. template<template<class...> class F, class E, class... L>
  145. struct mp_transform_impl;
  146. /* unique id */
  147. template<class Counter>
  148. struct mp_unique_counter;
  149. template<class Counter, class... Args>
  150. struct mp_unique_id;
  151. /* strings */
  152. struct tag_reference { };
  153. struct tag_array { };
  154. template<size_t N, class T>
  155. struct mp_string_impl;
  156. template<class I, int Base>
  157. struct mp_int_to_string_impl;
  158. template<size_t N>
  159. using mp_array_string = mp_string_impl<N, tag_array>;
  160. template<class J, class L>
  161. struct mp_string_type_join_impl;
  162. /* tuple */
  163. template<bool, class F, class T, class... Args>
  164. struct mp_tuple_call_helper
  165. {
  166. static inline void exec(F f, T& t, Args&&... args)
  167. { }
  168. };
  169. template<class F, class T, class... Args>
  170. struct mp_tuple_call_helper<true, F, T, Args...>
  171. {
  172. static inline void exec(F f, T& t, Args&&... args)
  173. { f(t, std::forward<Args>(args)...); }
  174. };
  175. template<class T>
  176. using mp_tuple_filter = mp_true;
  177. template<template<class> class Filter, class T, class F, size_t... I, class... Args>
  178. void for_each_in_tuple_filter(T& t, F f, const mp_index_sequence<I...>&, Args&&... args)
  179. {
  180. using expander = int[];
  181. (void) f;
  182. (void) expander { (mp_tuple_call_helper<
  183. Filter<decltype(std::get<I>(t))>::value,
  184. F,
  185. decltype(std::get<I>(t)),
  186. Args...>::exec(
  187. f,
  188. std::get<I>(t),
  189. std::forward<Args>(args)...), 0)... };
  190. }
  191. }
  192. /* logical operations */
  193. template<class B, class T, class E>
  194. using mp_if = typename __impl::mp_if_c_impl<B::value != 0, T, E>::type;
  195. template<bool B, class T, class E>
  196. using mp_if_c = typename __impl::mp_if_c_impl<B, T, E>::type;
  197. template<class C, class T, template<class...> class E, class... A>
  198. using mp_eval_if = typename __impl::mp_eval_if_c_impl<C::value != 0, T, E, A...>::type;
  199. template<bool C, class T, template<class...> class E, class... A>
  200. using mp_eval_if_c = typename __impl::mp_eval_if_c_impl<C, T, E, A...>::type;
  201. template<class L>
  202. using mp_not = typename __impl::mp_not_impl<L>::type;
  203. template<class L>
  204. using mp_and = typename __impl::mp_and_impl<L>::type;
  205. template<class L>
  206. using mp_or = typename __impl::mp_or_impl<L>::type;
  207. /* arithmetic */
  208. template<class L>
  209. using mp_plus = typename __impl::mp_plus_impl<L>::type;
  210. template<class L>
  211. using mp_minus = typename __impl::mp_minus_impl<L>::type;
  212. template<class L>
  213. using mp_multiply = typename __impl::mp_multiply_impl<L>::type;
  214. template<class L>
  215. using mp_divide = typename __impl::mp_divide_impl<L>::type;
  216. /* generator functions */
  217. template<class T, T N>
  218. using mp_make_integer_sequence = typename __impl::mp_make_int_seq_impl<T, 0, N>::type;
  219. template<size_t N>
  220. using mp_make_index_sequence = mp_make_integer_sequence<size_t, N>;
  221. template<size_t N, class... T>
  222. using mp_repeat = typename __impl::mp_repeat_impl<N, T...>::type;
  223. /* list operations returning a numeric value */
  224. template<class... T>
  225. using mp_length = mp_const<size_t, sizeof...(T)>;
  226. template<class L>
  227. using mp_size = typename __impl::mp_rename_impl<L, mp_length>::type;
  228. template<class L, class V>
  229. using mp_count = typename __impl::mp_count_impl<L, V>::type;
  230. template<class L, template<class...> class P>
  231. using mp_count_if = typename __impl::mp_count_if_impl<L, P>::type;
  232. /* operations to manipulate list content */
  233. template<class L, class... T>
  234. using mp_push_front = typename __impl::mp_push_front_impl<L, T...>::type;
  235. template<class L, class... T>
  236. using mp_pop_front = typename __impl::mp_pop_front_impl<L>::type;
  237. template<class L, class... T>
  238. using mp_push_back = typename __impl::mp_push_back_impl<L, T...>::type;
  239. template<class... L>
  240. using mp_concat = typename __impl::mp_concat_impl<L...>::type;
  241. template<class L, template<class> class F>
  242. using mp_filter = typename __impl::mp_filter_impl<L, F>::type;
  243. /* list operations returning a bool value */
  244. template<class... L>
  245. using mp_empty = typename __impl::mp_empty_impl<L...>::type;
  246. template<class L, class V>
  247. using mp_contains = mp_bool<mp_count<L, V>::value != 0>;
  248. /* list operations returing elements from the list */
  249. template<class L>
  250. using mp_front = typename __impl::mp_front_impl<L>::type;
  251. template<class L>
  252. using mp_second = typename __impl::mp_second_impl<L>::type;
  253. template<class L, class I>
  254. using mp_at = typename __impl::mp_at_c_impl<L, I::value>::type;
  255. template<class L, size_t I>
  256. using mp_at_c = typename __impl::mp_at_c_impl<L, I>::type;
  257. template<class L, template<class> class F, class TDefault = void>
  258. using mp_search = typename __impl::mp_search_impl<L, F, TDefault>::type;
  259. template<class L, class V>
  260. using mp_find = typename __impl::mp_find_impl<L, V>::type;
  261. template<class M, class K>
  262. using mp_map_find = typename __impl::mp_map_find_impl<M, K>::type;
  263. /* list manipulators returning a new list */
  264. template<class L>
  265. using mp_clear = typename __impl::mp_clear_impl<L>::type;
  266. template<class L>
  267. using mp_unique = typename __impl::mp_unique_impl<L, mp_clear<L>>::type;
  268. template<class A, template<class...> class B>
  269. using mp_rename = typename __impl::mp_rename_impl<A, B>::type;
  270. template<class... L>
  271. using mp_append = typename __impl::mp_append_impl<L...>::type;
  272. template<class L>
  273. using mp_map_from_list = typename __impl::mp_map_from_list_impl<L, mp_make_index_sequence<mp_size<L>::value>>::type;
  274. template<template<class...> class F, class... L>
  275. using mp_transform = typename __impl::mp_transform_impl<F, mp_empty<L...>, L...>::type;
  276. /* unique id */
  277. template<class Counter>
  278. inline size_t nextUniqueId()
  279. { return __impl::mp_unique_counter<Counter>::next(); }
  280. template<class Counter, class... Args>
  281. inline size_t getUniqueId()
  282. { return __impl::mp_unique_id<Counter, Args...>::value(); }
  283. /* strings */
  284. template<size_t N>
  285. using mp_string = __impl::mp_string_impl<N, __impl::tag_reference>;
  286. template<class I, int Base>
  287. constexpr auto mp_int_to_string()
  288. { return __impl::mp_int_to_string_impl<I, Base>::value; }
  289. template <int N>
  290. constexpr mp_string<N - 1> mp_make_string(const char (&data)[N])
  291. { return mp_string<N - 1>(data); }
  292. template <size_t N1, size_t N2, class T1, class T2>
  293. constexpr __impl::mp_array_string<N1 + N2> mp_string_cat(
  294. const __impl::mp_string_impl<N1, T1>& s1,
  295. const __impl::mp_string_impl<N2, T2>& s2)
  296. { return __impl::mp_array_string<N1 + N2>(s1, s2); };
  297. template <size_t N1, size_t N2, class T1, class T2>
  298. constexpr auto operator + (
  299. const __impl::mp_string_impl<N1, T1>& s1,
  300. const __impl::mp_string_impl<N2, T2>& s2)
  301. { return mp_string_cat(s1, s2); };
  302. template<size_t NJ, size_t N1, size_t N2, class TJ, class T1, class T2>
  303. constexpr auto mp_string_join(
  304. const __impl::mp_string_impl<NJ, TJ>& j,
  305. const __impl::mp_string_impl<N1, T1>& s1,
  306. const __impl::mp_string_impl<N2, T2>& s2)
  307. { return mp_string_cat(s1, mp_string_cat(j, s2)); }
  308. template<size_t NJ, size_t N1, size_t... NX, class TJ, class T1, class... TX>
  309. constexpr auto mp_string_join(
  310. const __impl::mp_string_impl<NJ, TJ>& j,
  311. const __impl::mp_string_impl<N1, T1>& s,
  312. const __impl::mp_string_impl<NX, TX>&... rest)
  313. { return mp_string_cat(s, mp_string_cat(j, mp_string_join(j, rest...))); }
  314. template<class J, class L>
  315. using mp_string_type_join = __impl::mp_string_type_join_impl<J, L>;
  316. /* tuple */
  317. template<class... T, class F, class... Args>
  318. void mp_for_each_in_tuple(std::tuple<T...>& t, F f, Args&&... args)
  319. { __impl::for_each_in_tuple_filter<__impl::mp_tuple_filter>(t, f, mp_make_index_sequence<mp_length<T...>::value>(), std::forward<Args>(args)...); }
  320. template<class... T, class F, class... Args>
  321. void mp_for_each_in_tuple(const std::tuple<T...>& t, F f, Args&&... args)
  322. { __impl::for_each_in_tuple_filter<__impl::mp_tuple_filter>(t, f, mp_make_index_sequence<mp_length<T...>::value>(), std::forward<Args>(args)...); }
  323. template<template<class> class Filter, class... T, class F, class... Args>
  324. void mp_for_each_in_tuple_filter(std::tuple<T...>& t, F f, Args&&... args)
  325. { __impl::for_each_in_tuple_filter<Filter>(t, f, mp_make_index_sequence<mp_length<T...>::value>(), std::forward<Args>(args)...); }
  326. template<template<class> class Filter, class... T, class F, class... Args>
  327. void mp_for_each_in_tuple_filter(const std::tuple<T...>& t, F f, Args&&... args)
  328. { __impl::for_each_in_tuple_filter<Filter>(t, f, mp_make_index_sequence<mp_length<T...>::value>(), std::forward<Args>(args)...); }
  329. template<template<class...> class F>
  330. struct mp_for_each_proxy
  331. {
  332. template<class T, class... Args>
  333. inline void operator()(T& t, Args&&... args) const
  334. { F<mp_clean_type<T>>::exec(t, std::forward<Args>(args)...); }
  335. };
  336. namespace __impl
  337. {
  338. /* helper */
  339. constexpr size_t cx_plus()
  340. { return 0; }
  341. template<class T1, class... T>
  342. constexpr size_t cx_plus(T1 t1, T... t)
  343. { return t1 + cx_plus(t...); }
  344. constexpr bool cx_and()
  345. { return true; }
  346. template<class... T>
  347. constexpr bool cx_and(bool b, T... t)
  348. { return b && cx_and(t...); }
  349. constexpr bool cx_or()
  350. { return false; }
  351. template<class... T>
  352. constexpr bool cx_or(bool b, T... t)
  353. { return b || cx_or(t...); }
  354. constexpr size_t cx_find_index( bool const * first, bool const * last )
  355. { return first == last || *first ? 0 : 1 + cx_find_index(first + 1, last); }
  356. /* logical operations */
  357. template<class T, class F>
  358. struct mp_if_c_impl<true, T, F>
  359. { using type = T; };
  360. template<class T, class F>
  361. struct mp_if_c_impl<false, T, F>
  362. { using type = F; };
  363. template<class T, template<class...> class E, class... A>
  364. struct mp_eval_if_c_impl<true, T, E, A...>
  365. { using type = T; };
  366. template<class T, template<class...> class E, class... A>
  367. struct mp_eval_if_c_impl<false, T, E, A...>
  368. { using type = E<A...>; };
  369. template<template<class...> class L, class... T>
  370. struct mp_not_impl<L<T...>>
  371. { using type = L<mp_bool<T::value == 0>...>; };
  372. template<template<class...> class L, class... T>
  373. struct mp_and_impl<L<T...>>
  374. { using type = mp_bool<cx_and(mp_bool<T::value>::value...)>; };
  375. template<template<class...> class L, class... T>
  376. struct mp_or_impl<L<T...>>
  377. { using type = mp_bool<cx_or(mp_bool<T::value>::value...)>; };
  378. /* arithmetic */
  379. template<template<class...> class L, class T>
  380. struct mp_plus_impl<L<T>>
  381. { using type = T; };
  382. template<template<class...> class L, class T1, class... T>
  383. struct mp_plus_impl<L<T1, T...>>
  384. {
  385. using _type = mp_remove_const<decltype(T1::value)>;
  386. static constexpr _type _value = T1::value + mp_plus<L<T...>>::value;
  387. using type = mp_const<_type, _value>;
  388. };
  389. template<template<class...> class L, class T>
  390. struct mp_minus_impl<L<T>>
  391. { using type = T; };
  392. template<template<class...> class L, class T1, class... T>
  393. struct mp_minus_impl<L<T1, T...>>
  394. {
  395. using _type = mp_remove_const<decltype(T1::value)>;
  396. static constexpr _type _value = T1::value - mp_plus<L<T...>>::value;
  397. using type = mp_const<_type, _value>;
  398. };
  399. template<template<class...> class L, class T>
  400. struct mp_multiply_impl<L<T>>
  401. { using type = T; };
  402. template<template<class...> class L, class T1, class... T>
  403. struct mp_multiply_impl<L<T1, T...>>
  404. {
  405. using _type = mp_remove_const<decltype(T1::value)>;
  406. static constexpr _type _value = T1::value * mp_multiply<L<T...>>::value;
  407. using type = mp_const<_type, _value>;
  408. };
  409. template<template<class...> class L, class T>
  410. struct mp_divide_impl<L<T>>
  411. { using type = T; };
  412. template<template<class...> class L, class T1, class... T>
  413. struct mp_divide_impl<L<T1, T...>>
  414. {
  415. using _type = mp_remove_const<decltype(T1::value)>;
  416. static constexpr _type _value = T1::value / mp_multiply<L<T...>>::value;
  417. using type = mp_const<_type, _value>;
  418. };
  419. /* generator functions */
  420. template<class S>
  421. struct next_integer_sequence;
  422. template<class T, T... Ints>
  423. struct next_integer_sequence<mp_integer_sequence<T, Ints...>>
  424. { using type = mp_integer_sequence<T, Ints..., sizeof...(Ints)>; };
  425. template<class T, T I, T N>
  426. struct mp_make_int_seq_impl
  427. { using type = typename next_integer_sequence<typename mp_make_int_seq_impl<T, I+1, N>::type>::type; };
  428. template<class T, T N>
  429. struct mp_make_int_seq_impl<T, N, N>
  430. { using type = mp_integer_sequence<T>; };
  431. template<size_t N, class... T>
  432. struct mp_repeat_impl
  433. {
  434. using _l1 = typename mp_repeat_impl<N/2, T...>::type;
  435. using _l2 = typename mp_repeat_impl<N%2, T...>::type;
  436. using type = mp_append<_l1, _l1, _l2>;
  437. };
  438. template<class... T> struct mp_repeat_impl<0, T...>
  439. { using type = mp_list<>; };
  440. template<class... T> struct mp_repeat_impl<1, T...>
  441. { using type = mp_list<T...>; };
  442. /* list operations returning a numeric value */
  443. template<template<class...> class L, class... T>
  444. struct mp_size_impl<L<T...>>
  445. { using type = mp_length<T...>; };
  446. template<template<class...> class L, class... T, class V>
  447. struct mp_count_impl<L<T...>, V>
  448. { using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>; };
  449. template<template<class...> class L, class... T, template<class...> class P>
  450. struct mp_count_if_impl<L<T...>, P>
  451. { using type = mp_size_t<cx_plus(P<T>::value...)>; };
  452. /* operations to manipulate list content */
  453. template<template<class...> class L, class... U, class... T>
  454. struct mp_push_front_impl<L<U...>, T...>
  455. { using type = L<T..., U...>; };
  456. template<template<class...> class L, class T1, class... T>
  457. struct mp_pop_front_impl<L<T1, T...>>
  458. { using type = L<T...>; };
  459. template<template<class...> class L, class... U, class... T>
  460. struct mp_push_back_impl<L<U...>, T...>
  461. { using type = L<U..., T...>; };
  462. template<template<class...> class L1, template<class...> class L2, class... T1, class... T2>
  463. struct mp_concat_impl<L1<T1...>, L2<T2...>>
  464. { using type = L1<T1..., T2...>; };
  465. template<template<class...> class L1, template<class...> class L2, class... T1, class... T2, class... L>
  466. struct mp_concat_impl<L1<T1...>, L2<T2...>, L...>
  467. {
  468. using _rest = mp_concat<L2<T2...>, L...>;
  469. using type = mp_concat<L1<T1...>, _rest>;
  470. };
  471. template<template<class...> class L, template<class> class F>
  472. struct mp_filter_impl<L<>, F>
  473. { using type = L<>; };
  474. template<template<class...> class L, template<class> class F, class T1, class... T>
  475. struct mp_filter_impl<L<T1, T...>, F>
  476. {
  477. using _rest = mp_filter<L<T...>, F>;
  478. using _match = F<T1>;
  479. using type = mp_eval_if_c<_match::value == 0, _rest, mp_push_front, _rest, T1>;
  480. };
  481. /* list operations returning a bool value */
  482. template<template<class...> class L1, class... T>
  483. struct mp_empty_impl<L1<T...>>
  484. { using type = mp_bool<mp_length<T...>::value == 0>; };
  485. template<template<class...> class L1, class... T, class... L>
  486. struct mp_empty_impl<L1<T...>, L...>
  487. {
  488. static constexpr bool _first = !static_cast<bool>(mp_length<T...>::value);
  489. static constexpr bool _other = static_cast<bool>(mp_empty<L...>::value);
  490. using type = mp_bool<_first && _other>;
  491. };
  492. /* list operations returing elements from the list */
  493. template<template<class...> class L, class T1, class... T>
  494. struct mp_front_impl<L<T1, T...>>
  495. { using type = T1; };
  496. template<template<class...> class L, class T1, class T2, class... T>
  497. struct mp_second_impl<L<T1, T2, T...>>
  498. { using type = T2; };
  499. template<class L, size_t I>
  500. struct mp_at_c_impl
  501. {
  502. using map = mp_map_from_list<L>;
  503. using type = mp_second<mp_map_find<map, mp_size_t<I>>>;
  504. };
  505. template<bool B, class L, template<class> class F, class TDefault>
  506. struct mp_search_helper;
  507. template<template<class...> class L, template<class> class F, class TDefault, class T1, class... T>
  508. struct mp_search_helper<true, L<T1, T...>, F, TDefault>
  509. { using type = T1; };
  510. template<template<class...> class L, template<class> class F, class TDefault, class T1, class... T>
  511. struct mp_search_helper<false, L<T1, T...>, F, TDefault>
  512. { using type = mp_search<L<T...>, F, TDefault>; };
  513. template<template<class...> class L, template<class> class F, class TDefault>
  514. struct mp_search_impl<L<>, F, TDefault>
  515. { using type = TDefault; };
  516. template<template<class...> class L, template<class> class F, class TDefault, class T1, class... T>
  517. struct mp_search_impl<L<T1, T...>, F, TDefault>
  518. {
  519. using c_value = F<T1>;
  520. using type = typename mp_search_helper<c_value::value, L<T1, T...>, F, TDefault>::type;
  521. };
  522. template<template<class...> class L, class V>
  523. struct mp_find_impl<L<>, V>
  524. { using type = mp_zero; };
  525. template<template<class...> class L, class... T, class V>
  526. struct mp_find_impl<L<T...>, V>
  527. {
  528. static constexpr bool _v[] = { std::is_same<T, V>::value... };
  529. using type = mp_size_t<cx_find_index(_v, _v + sizeof...(T))>;
  530. };
  531. template<template<class...> class M, class... T, class K>
  532. struct mp_map_find_impl<M<T...>, K>
  533. {
  534. static mp_identity<void> f( ... );
  535. template<template<class...> class L, class... U>
  536. static mp_identity<L<K, U...>>
  537. f( mp_identity<L<K, U...>>* );
  538. using U = mp_inherit<mp_identity<T>...>;
  539. using V = decltype( f((U*)0) );
  540. using type = typename V::type;
  541. };
  542. /* list manipulators returning a new list */
  543. template<template<class...> class L, class... T>
  544. struct mp_clear_impl<L<T...>>
  545. { using type = L<>; };
  546. template<template<class...> class L, class... T>
  547. struct mp_unique_impl<L<>, L<T...>>
  548. { using type = L<T...>; };
  549. template<template<class...> class L, class C, class T1, class... T>
  550. struct mp_unique_impl<L<T1, T...>, C>
  551. {
  552. using type = mp_if<
  553. mp_contains<C, T1>,
  554. typename mp_unique_impl<L<T...>, C>::type,
  555. typename mp_unique_impl<L<T...>, mp_push_back<C, T1>>::type
  556. >;
  557. };
  558. template<template<class...> class A, class... T, template<class...> class B>
  559. struct mp_rename_impl<A<T...>, B>
  560. { using type = B<T...>; };
  561. template<>
  562. struct mp_append_impl<>
  563. { using type = mp_list<>; };
  564. template<template<class...> class L, class... T>
  565. struct mp_append_impl<L<T...>>
  566. { using type = L<T...>; };
  567. template<
  568. template<class...> class L1, class... T1,
  569. template<class...> class L2, class... T2, class... Lr>
  570. struct mp_append_impl<L1<T1...>, L2<T2...>, Lr...>
  571. { using type = mp_append<L1<T1..., T2...>, Lr...>; };
  572. template<template<class...> class L, class... T, size_t... J>
  573. struct mp_map_from_list_impl<L<T...>, mp_integer_sequence<size_t, J...>>
  574. { using type = mp_list<mp_list<mp_size_t<J>, T>...>; };
  575. template<template<class...> class F, class L1, class... L>
  576. struct mp_transform_impl<F, mp_true, L1, L...>
  577. { using type = mp_clear<L1>; };
  578. template<template<class...> class F, class... L>
  579. struct mp_transform_impl<F, mp_false, L...>
  580. {
  581. using _first = F< typename mp_front_impl<L>::type... >;
  582. using _rest = mp_transform< F, typename mp_pop_front_impl<L>::type... >;
  583. using type = mp_push_front<_rest, _first>;
  584. };
  585. /* unique id */
  586. template<class Counter>
  587. struct mp_unique_counter
  588. {
  589. static inline size_t next()
  590. {
  591. static size_t value;
  592. return value++;
  593. }
  594. };
  595. template<class Counter, class... Args>
  596. struct mp_unique_id
  597. {
  598. static inline size_t value()
  599. {
  600. static const size_t value = mp_unique_counter<Counter>::next();
  601. return value;
  602. }
  603. };
  604. /* string */
  605. template <size_t N>
  606. struct mp_string_impl<N, tag_reference>
  607. {
  608. private:
  609. const char (&_data)[N + 1];
  610. public:
  611. inline std::string str() const
  612. { return std::string(_data, N); }
  613. inline constexpr const char* data() const
  614. { return _data; }
  615. inline constexpr size_t size() const
  616. { return N; }
  617. inline constexpr char operator[](size_t i) const
  618. { return X_ASSERT(i >= 0 && i < N), _data[i]; }
  619. constexpr mp_string_impl(const char (&data)[N + 1]) :
  620. _data((X_ASSERT(data[N] == '\0'), data))
  621. { }
  622. };
  623. template <size_t N>
  624. struct mp_string_impl<N, tag_array>
  625. {
  626. private:
  627. constexpr static size_t strsize(const char* s)
  628. {
  629. size_t ret = 0;
  630. while (s[ret] != 0)
  631. ++ret;
  632. return ret;
  633. }
  634. private:
  635. char _data[N + 1];
  636. template <size_t N1, class T1, class T2, size_t... I1, size_t... I2>
  637. constexpr mp_string_impl(
  638. const mp_string_impl< N1, T1>& s1,
  639. const mp_string_impl<N - N1, T2>& s2,
  640. mp_index_sequence<I1...>,
  641. mp_index_sequence<I2...>) :
  642. _data { s1[I1]..., s2[I2]..., '\0' }
  643. { }
  644. public:
  645. inline std::string str() const
  646. { return std::string(_data, N); }
  647. inline constexpr const char* data() const
  648. { return _data; }
  649. inline constexpr size_t size() const
  650. { return N; }
  651. inline constexpr char operator[](size_t i) const
  652. { return X_ASSERT(i >= 0 && i < N), _data[i]; }
  653. template<size_t X = N, class Enable = mp_enable_if_c<(X == 1), char>>
  654. constexpr mp_string_impl(char c) :
  655. _data { c, '\0' }
  656. { }
  657. template <size_t N1, class T1, class T2, mp_enable_if_c<(N1 <= N), bool> = true>
  658. constexpr mp_string_impl(
  659. const mp_string_impl<N1, T1>& s1,
  660. const mp_string_impl<N - N1, T2>& s2) :
  661. mp_string_impl(s1, s2, mp_make_index_sequence<N1>(), mp_make_index_sequence<N - N1>())
  662. { }
  663. };
  664. template<class X, class Enable = void>
  665. struct __int_to_char;
  666. template<class X>
  667. struct __int_to_char<X, mp_enable_if_c<X::value >= 0 && X::value <= 9>>
  668. { static constexpr auto value = mp_array_string<1>('0' + X::value); };
  669. template<class X>
  670. struct __int_to_char<X, mp_enable_if_c<X::value >= 10 && X::value <= 16>>
  671. { static constexpr auto value = mp_array_string<1>('A' + X::value - 10); };
  672. template<class X, int Base, bool b>
  673. struct __int_to_string_helper
  674. {
  675. using _type = typename X::value_type;
  676. using _next = mp_const<_type, X::value / static_cast<_type>(Base)>;
  677. using _this = mp_const<_type, X::value % static_cast<_type>(Base)>;
  678. static constexpr auto value = mp_string_cat(
  679. __int_to_string_helper<_next, Base, _next::value == 0>::value,
  680. __int_to_char<_this>::value);
  681. };
  682. template<class X, int Base>
  683. struct __int_to_string_helper<X, Base, true>
  684. { static constexpr auto value = mp_make_string(""); };
  685. template<class I, int Base>
  686. struct mp_int_to_string_impl
  687. {
  688. static constexpr auto value = __int_to_string_helper<I, Base, I::value == 0>::value;
  689. };
  690. template<class J, template<class...> class L, class... T>
  691. struct mp_string_type_join_impl<J, L<T...>>
  692. {
  693. static constexpr auto value = mp_string_join(J::value, T::value...);
  694. };
  695. }
  696. }