Advertisement
Guest User

Untitled

a guest
Jan 31st, 2015
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.97 KB | None | 0 0
  1.  
  2. #include <iostream>
  3. #include <vector>
  4. #include <list>
  5.  
  6. #define REQUIRES(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
  7. #define REQUIRE_OF(...) template<class Id> using apply = typename std::enable_if<(Id()(__VA_ARGS__)), int>::type
  8.  
  9. template<class T>
  10. struct always_void
  11. {
  12. typedef void type;
  13. };
  14.  
  15. template<class Concept, class Enable=void>
  16. struct models
  17. : std::false_type
  18. {};
  19.  
  20. template<class Concept, class... Ts>
  21. struct models<Concept(Ts...), typename always_void<
  22. decltype(std::declval<Concept>().requires_(std::declval<Ts>()...))
  23. >::type>
  24. : std::true_type
  25. {};
  26.  
  27. struct Callable
  28. {
  29. template<class F, class... Ts>
  30. auto requires_(F&& f, Ts&&... xs) -> decltype(
  31. f(std::forward<Ts>(xs)...)
  32. );
  33. };
  34.  
  35. struct identity
  36. {
  37. template<class T>
  38. constexpr T operator()(T&& x) const
  39. {
  40. return std::forward<T>(x);
  41. }
  42. };
  43.  
  44. template<class F, class=void>
  45. struct get_failure
  46. {
  47. template<class... Ts>
  48. struct of
  49. {
  50. template<class Id>
  51. using apply = decltype(Id()(std::declval<F>())(std::declval<Ts>()...));
  52. };
  53. };
  54.  
  55. template<class F>
  56. struct get_failure<F, typename always_void<
  57. typename F::failure
  58. >::type>
  59. : F::failure
  60. {};
  61.  
  62. template<class Failure, class... Ts>
  63. struct apply_failure
  64. : Failure::template of<Ts...>
  65. {};
  66.  
  67. template<class Id, class Failure, class... Ts>
  68. using enabled = typename apply_failure<Failure, Ts...>::template apply<Id>;
  69.  
  70. template<class F, class Failure>
  71. struct reveal_failure
  72. {
  73. template<class... Ts, class Id=identity, class=enabled<Id, Failure, Ts...>, REQUIRES(Id()(false))>
  74. auto operator()(Ts&&... xs) -> decltype(F()(std::forward<Ts>(xs)...))
  75. {
  76. return F()(std::forward<Ts>(xs)...);
  77. }
  78. };
  79.  
  80. template<class F, class Failure=get_failure<F>, class=void>
  81. struct traverse_failure
  82. : reveal_failure<F, Failure>
  83. {};
  84.  
  85. template<class F, class Failure>
  86. struct traverse_failure<F, Failure, typename always_void<
  87. typename Failure::children
  88. >::type>
  89. : Failure::children::template apply<F>
  90. {};
  91.  
  92. template<class Failure, class... Failures>
  93. struct failures
  94. {
  95. template<class F>
  96. struct apply
  97. : traverse_failure<F, Failure>, failures<Failures...>::template apply<F>
  98. {
  99. using traverse_failure<F, Failure>::operator();
  100. using failures<Failures...>::template apply<F>::operator();
  101. };
  102. };
  103.  
  104. template<class Failure>
  105. struct failures<Failure>
  106. {
  107. template<class F>
  108. struct apply
  109. : traverse_failure<F, Failure>
  110. {};
  111. };
  112.  
  113. template<class F>
  114. struct reveal
  115. : traverse_failure<F>, F
  116. {
  117. using traverse_failure<F>::operator();
  118. using F::operator();
  119. };
  120.  
  121. template<class F1, class F2>
  122. struct basic_conditional
  123. {
  124. struct failure
  125. {
  126. using children = failures<get_failure<F1>, get_failure<F2>>;
  127. };
  128. template<class... Ts>
  129. auto operator()(Ts&&... xs) -> decltype(F1()(std::forward<Ts>(xs)...))
  130. {
  131. return F1()(std::forward<Ts>(xs)...);
  132. }
  133.  
  134. template<class... Ts, REQUIRES(!models<Callable(F1, Ts&&...)>())>
  135. auto operator()(Ts&&... xs) -> decltype(F2()(std::forward<Ts>(xs)...))
  136. {
  137. return F2()(std::forward<Ts>(xs)...);
  138. }
  139. };
  140.  
  141. template<class F, class... Fs>
  142. struct conditional : basic_conditional<F, conditional<Fs...>>
  143. {};
  144.  
  145. template<class F>
  146. struct conditional<F> : F
  147. {};
  148.  
  149. struct Incrementable
  150. {
  151. template<class T>
  152. auto requires_(T&& x) -> decltype(++x);
  153. };
  154.  
  155. struct Decrementable
  156. {
  157. template<class T>
  158. auto requires_(T&& x) -> decltype(--x);
  159. };
  160.  
  161. struct Advanceable
  162. {
  163. template<class T, class I>
  164. auto requires_(T&& x, I&& i) -> decltype(x += i);
  165. };
  166.  
  167. struct advance_advanceable
  168. {
  169. struct failure
  170. {
  171. template<class...>
  172. struct of;
  173. template<class Iterator, class T>
  174. struct of<Iterator, T>
  175. {
  176. REQUIRE_OF(models<Advanceable(Iterator, int)>());
  177. };
  178. };
  179. template<class Iterator, REQUIRES(models<Advanceable(Iterator, int)>())>
  180. void operator()(Iterator& it, int n) const
  181. {
  182. it += n;
  183. }
  184. };
  185.  
  186. struct advance_decrementable
  187. {
  188. struct failure
  189. {
  190. template<class...>
  191. struct of;
  192. template<class Iterator, class T>
  193. struct of<Iterator, T>
  194. {
  195. REQUIRE_OF(models<Decrementable(Iterator)>());
  196. };
  197. };
  198. template<class Iterator, REQUIRES(models<Decrementable(Iterator)>())>
  199. void operator()(Iterator& it, int n) const
  200. {
  201. if (n > 0) while (n--) ++it;
  202. else
  203. {
  204. n *= -1;
  205. while (n--) --it;
  206. }
  207. }
  208. };
  209.  
  210. struct advance_incrementable
  211. {
  212. struct failure
  213. {
  214. template<class...>
  215. struct of;
  216. template<class Iterator, class T>
  217. struct of<Iterator, T>
  218. {
  219. REQUIRE_OF(models<Incrementable(Iterator)>());
  220. };
  221. };
  222. template<class Iterator, REQUIRES(models<Incrementable(Iterator)>())>
  223. void operator()(Iterator& it, int n) const
  224. {
  225. while (n--) ++it;
  226. }
  227. };
  228.  
  229. static reveal<conditional<advance_advanceable, advance_decrementable, advance_incrementable>> advance = {};
  230.  
  231. struct foo {};
  232.  
  233. int main()
  234. {
  235. foo f;
  236. advance(f, 1);
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement