Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <list>
- #define REQUIRES(...) typename std::enable_if<(__VA_ARGS__), int>::type = 0
- #define REQUIRE_OF(...) template<class Id> using apply = typename std::enable_if<(Id()(__VA_ARGS__)), int>::type
- template<class T>
- struct always_void
- {
- typedef void type;
- };
- template<class Concept, class Enable=void>
- struct models
- : std::false_type
- {};
- template<class Concept, class... Ts>
- struct models<Concept(Ts...), typename always_void<
- decltype(std::declval<Concept>().requires_(std::declval<Ts>()...))
- >::type>
- : std::true_type
- {};
- struct Callable
- {
- template<class F, class... Ts>
- auto requires_(F&& f, Ts&&... xs) -> decltype(
- f(std::forward<Ts>(xs)...)
- );
- };
- struct identity
- {
- template<class T>
- constexpr T operator()(T&& x) const
- {
- return std::forward<T>(x);
- }
- };
- template<class F, class=void>
- struct get_failure
- {
- template<class... Ts>
- struct of
- {
- template<class Id>
- using apply = decltype(Id()(std::declval<F>())(std::declval<Ts>()...));
- };
- };
- template<class F>
- struct get_failure<F, typename always_void<
- typename F::failure
- >::type>
- : F::failure
- {};
- template<class Failure, class... Ts>
- struct apply_failure
- : Failure::template of<Ts...>
- {};
- template<class Id, class Failure, class... Ts>
- using enabled = typename apply_failure<Failure, Ts...>::template apply<Id>;
- template<class F, class Failure>
- struct reveal_failure
- {
- template<class... Ts, class Id=identity, class=enabled<Id, Failure, Ts...>, REQUIRES(Id()(false))>
- auto operator()(Ts&&... xs) -> decltype(F()(std::forward<Ts>(xs)...))
- {
- return F()(std::forward<Ts>(xs)...);
- }
- };
- template<class F, class Failure=get_failure<F>, class=void>
- struct traverse_failure
- : reveal_failure<F, Failure>
- {};
- template<class F, class Failure>
- struct traverse_failure<F, Failure, typename always_void<
- typename Failure::children
- >::type>
- : Failure::children::template apply<F>
- {};
- template<class Failure, class... Failures>
- struct failures
- {
- template<class F>
- struct apply
- : traverse_failure<F, Failure>, failures<Failures...>::template apply<F>
- {
- using traverse_failure<F, Failure>::operator();
- using failures<Failures...>::template apply<F>::operator();
- };
- };
- template<class Failure>
- struct failures<Failure>
- {
- template<class F>
- struct apply
- : traverse_failure<F, Failure>
- {};
- };
- template<class F>
- struct reveal
- : traverse_failure<F>, F
- {
- using traverse_failure<F>::operator();
- using F::operator();
- };
- template<class F1, class F2>
- struct basic_conditional
- {
- struct failure
- {
- using children = failures<get_failure<F1>, get_failure<F2>>;
- };
- template<class... Ts>
- auto operator()(Ts&&... xs) -> decltype(F1()(std::forward<Ts>(xs)...))
- {
- return F1()(std::forward<Ts>(xs)...);
- }
- template<class... Ts, REQUIRES(!models<Callable(F1, Ts&&...)>())>
- auto operator()(Ts&&... xs) -> decltype(F2()(std::forward<Ts>(xs)...))
- {
- return F2()(std::forward<Ts>(xs)...);
- }
- };
- template<class F, class... Fs>
- struct conditional : basic_conditional<F, conditional<Fs...>>
- {};
- template<class F>
- struct conditional<F> : F
- {};
- struct Incrementable
- {
- template<class T>
- auto requires_(T&& x) -> decltype(++x);
- };
- struct Decrementable
- {
- template<class T>
- auto requires_(T&& x) -> decltype(--x);
- };
- struct Advanceable
- {
- template<class T, class I>
- auto requires_(T&& x, I&& i) -> decltype(x += i);
- };
- struct advance_advanceable
- {
- struct failure
- {
- template<class...>
- struct of;
- template<class Iterator, class T>
- struct of<Iterator, T>
- {
- REQUIRE_OF(models<Advanceable(Iterator, int)>());
- };
- };
- template<class Iterator, REQUIRES(models<Advanceable(Iterator, int)>())>
- void operator()(Iterator& it, int n) const
- {
- it += n;
- }
- };
- struct advance_decrementable
- {
- struct failure
- {
- template<class...>
- struct of;
- template<class Iterator, class T>
- struct of<Iterator, T>
- {
- REQUIRE_OF(models<Decrementable(Iterator)>());
- };
- };
- template<class Iterator, REQUIRES(models<Decrementable(Iterator)>())>
- void operator()(Iterator& it, int n) const
- {
- if (n > 0) while (n--) ++it;
- else
- {
- n *= -1;
- while (n--) --it;
- }
- }
- };
- struct advance_incrementable
- {
- struct failure
- {
- template<class...>
- struct of;
- template<class Iterator, class T>
- struct of<Iterator, T>
- {
- REQUIRE_OF(models<Incrementable(Iterator)>());
- };
- };
- template<class Iterator, REQUIRES(models<Incrementable(Iterator)>())>
- void operator()(Iterator& it, int n) const
- {
- while (n--) ++it;
- }
- };
- static reveal<conditional<advance_advanceable, advance_decrementable, advance_incrementable>> advance = {};
- struct foo {};
- int main()
- {
- foo f;
- advance(f, 1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement