50template <
typename, 
typename = 
void>
 
   52template <
typename ... Ts>
 
   53struct printable<
std::
tuple<Ts...>, std::void_t<decltype(std::declval<std::ostream&>() << std::declval<const Ts&>())...>>
 
   59using printable_t = typename printable<T>::type;
 
   61template <typename F, typename ... Args>
 
   64    using RT = std::invoke_result_t<F, Args...>;
 
   66    template <typename F_, typename ... As>
 
   67    constexpr bound(F_&& f_, As&& ... as) : f(std::forward<F_>(f_)), args(std::forward<As>(as)...) {}
 
   69    constexpr operator RT() const
 
   70    noexcept(std::is_nothrow_invocable_v<const F&, const Args&...>)
 
   72        return std::apply(f, args);
 
   76    std::tuple<Args...> args;
 
   79template <typename ... Ts>
 
   82    std::tuple<Ts...> values;
 
   83    template <typename T, typename F>
 
   84    constexpr bound<T, Ts...> bind(const F& f) const
 
   86        return std::apply([&](auto&& ... vs){return bound<T, Ts...>{f, vs...};}, values);
 
   90class logical_tuple_base { };
 
   92template <typename ... Ts>
 
   93class logical_tuple : std::tuple<Ts...>, public logical_tuple_base
 
   95    using tuple = std::tuple<Ts...>;
 
   96    constexpr const tuple& self() const { return *this; }
 
  100    constexpr auto or_all(F&& f) const
 
  102        return std::apply([&](const auto& ... v) { return (f(v) || ...);}, self());
 
  104    template <typename F>
 
  105    constexpr auto and_all(F&& f) const
 
  107        return std::apply([&](const auto& ... v) { return (f(v) && ...);}, self());
 
  109    template <typename RT, typename ... Args>
 
  110    constexpr RT bind(Args&& ... args) const {
 
  111        return std::apply([&](auto&&... f) {
 
  112            binder<Args...> b{{args...}};
 
  113            return RT{b.template bind<Ts>(std::forward<decltype(f)>(f))...}; }, self());
 
  115    template <typename Char, typename Traits>
 
  116    std::basic_ostream<Char, Traits>& print(const Char* label, std::basic_ostream<Char, Traits>& os) const
 
  119        std::apply([&os](const auto& ... v) {
 
  121            ((os << &","[std::exchange(first, 0)] << v),...);
 
  129template <typename ... T>
 
  130class any_of : internal::logical_tuple<T...>
 
  132    using internal::logical_tuple<T...>::or_all;
 
  133    using internal::logical_tuple<T...>::and_all;
 
  135    using internal::logical_tuple<T...>::logical_tuple;
 
  137    template <typename U>
 
  138    constexpr auto operator==(const U& u) const
 
  139    noexcept(noexcept(((std::declval<const T&>() == u) || ...)))
 
  140    -> decltype(((std::declval<const T&>() == u) || ...))
 
  142        return or_all([&](auto&& v) { return v == u;});
 
  145    template <typename U>
 
  146    constexpr auto operator!=(const U& u) const
 
  147    noexcept(noexcept(((std::declval<const T&>() != u) && ...)))
 
  148    -> decltype(((std::declval<const T&>() != u) && ...))
 
  150        return and_all([&](auto v) { return v != u;});
 
  153    template <typename U>
 
  154    constexpr auto operator<(const U& u) const
 
  155    noexcept(noexcept(((std::declval<const T&>() < u) || ...)))
 
  156    -> decltype(((std::declval<const T&>() < u) || ...))
 
  158        return or_all([&](auto&& v){ return v < u;});
 
  161    template <typename U>
 
  162    constexpr auto operator<=(const U& u) const
 
  163    noexcept(noexcept(((std::declval<const T&>() <= u) || ...)))
 
  164    -> decltype(((std::declval<const T&>() <= u) || ...))
 
  166        return or_all([&](auto&& v){ return v <= u;});
 
  169    template <typename U>
 
  170    constexpr auto operator>(const U& u) const
 
  171    noexcept(noexcept(((std::declval<const T&>() > u) || ...)))
 
  172    -> decltype(((std::declval<const T&>() > u) || ...))
 
  174        return or_all([&](auto&& v) { return v > u;});
 
  177    template <typename U>
 
  178    constexpr auto operator>=(const U& u) const
 
  179    noexcept(noexcept(((std::declval<const T&>() >= u) || ...)))
 
  180    -> decltype(((std::declval<const T&>() >= u) || ...))
 
  182        return or_all([&](auto&& v) { return v >= u;});
 
  185    template <typename V = std::tuple<T...>, typename = internal::printable_t<V>>
 
  186    friend std::ostream& operator<<(std::ostream& os, const any_of& self)
 
  188        return self.print("any_of", os);
 
  191    constexpr explicit operator bool() const
 
  192    noexcept(noexcept((std::declval<const T&>() || ...)))
 
  194        return or_all([](auto&& v) { return v;});
 
  197    template <typename ... Ts>
 
  198    requires ( std::conjunction_v<std::is_copy_constructible<Ts>...>&& std::conjunction_v<std::is_invocable<T, Ts...>...> )
 
  199    constexpr auto operator()(Ts&& ... ts) const
 
  200    noexcept(std::conjunction_v<std::is_nothrow_move_constructible<T>...> && std::conjunction_v<std::is_nothrow_copy_constructible<Ts>...>)
 
  201    -> any_of<internal::bound<T, Ts...>...>
 
  203        using RT = any_of<internal::bound<T, Ts...>...>;
 
  204        return this->template bind<RT>(std::forward<Ts>(ts)...);
 
  208template <typename ... T>
 
  209class none_of : internal::logical_tuple<T...>
 
  211    using internal::logical_tuple<T...>::or_all;
 
  212    using internal::logical_tuple<T...>::and_all;
 
  214    using internal::logical_tuple<T...>::logical_tuple;
 
  216    template <typename U>
 
  217    constexpr auto operator==(const U& u) const
 
  218    noexcept(noexcept(!((std::declval<const T&>() == u) || ...)))
 
  219    -> decltype(!((std::declval<const T&>() == u) || ...))
 
  221        return !or_all([&](auto&& v) { return v == u;});
 
  224    template <typename U>
 
  225    constexpr auto operator!=(const U& u) const
 
  226    noexcept(noexcept(!((std::declval<const T&>() != u) && ...)))
 
  227    -> decltype(!((std::declval<const T&>() != u) && ...))
 
  229        return !and_all([&](auto && v){return v != u;});
 
  232    template <typename U>
 
  233    constexpr auto operator<(const U& u) const
 
  234    noexcept(noexcept(!((std::declval<const T&>() < u) || ...)))
 
  235    -> decltype(!((std::declval<const T&>() < u) || ...))
 
  237        return !or_all([&](auto&& v){ return v < u;});
 
  240    template <typename U>
 
  241    constexpr auto operator<=(const U& u) const
 
  242    noexcept(noexcept(!((std::declval<const T&>() <= u) || ...)))
 
  243    -> decltype(!((std::declval<const T&>() <= u) || ...))
 
  245        return !or_all([&](auto&& v){ return v <= u;});
 
  248    template <typename U>
 
  249    constexpr auto operator>(const U& u) const
 
  250    noexcept(noexcept(!((std::declval<const T&>() > u) || ...)))
 
  251    -> decltype(!((std::declval<const T&>() > u) || ...))
 
  253        return !or_all([&](auto&& v) { return v > u;});
 
  256    template <typename U>
 
  257    constexpr auto operator>=(const U& u) const
 
  258    noexcept(noexcept(!((std::declval<const T&>() >= u) || ...)))
 
  259    -> decltype(!((std::declval<const T&>() >= u) || ...))
 
  261        return !or_all([&](
auto&& v){ 
return v >= u;});
 
  267        return self.print(
"none_of", os);
 
  270    constexpr explicit operator bool() const
 
  271    noexcept(noexcept(!(
std::declval<const T&>() || ...)))
 
  273        return !or_all([](
auto&& v) { 
return v;});
 
  276    template <
typename ... Ts>
 
  277    requires ( std::conjunction_v<std::is_copy_constructible<Ts>...>&&std::conjunction_v<std::is_invocable<T, Ts...>...> )
 
  278    constexpr auto operator()(Ts&& ... ts) 
const 
  279    noexcept( std::conjunction_v<std::is_nothrow_move_constructible<T>...> && std::conjunction_v<std::is_nothrow_copy_constructible<Ts>...>)
 
  283        return this->
template bind<RT>(std::forward<Ts>(ts)...);
 
  287template <
typename ... T>
 
  295    template <
typename U>
 
  297    noexcept(
noexcept(((std::declval<const T&>() == u) && ...)))
 
  298    -> 
decltype(((std::declval<const T&>() == u) && ...))
 
  300        return and_all([&](
auto&& v){ 
return v == u;});
 
  303    template <
typename U>
 
  305    noexcept(
noexcept(((std::declval<const T&>() != u) || ...)))
 
  306    -> 
decltype(((std::declval<const T&>() != u) || ...))
 
  308        return or_all([&](
auto&& v){
return v != u;});
 
  311    template <
typename U>
 
  313    noexcept(
noexcept(((std::declval<const T&>() < u) && ...)))
 
  314    -> 
decltype(((std::declval<const T&>() < u) && ...))
 
  316        return and_all([&](
auto&& v){ 
return v < u;});
 
  319    template <
typename U>
 
  321    noexcept(
noexcept(((std::declval<const T&>() <= u) && ...)))
 
  322    -> 
decltype(((std::declval<const T&>() <= u) && ...))
 
  324        return and_all([&](
auto&& v){ 
return v <= u;});
 
  327    template <
typename U>
 
  329    noexcept(
noexcept(((std::declval<const T&>() > u) && ...)))
 
  330    -> 
decltype(((std::declval<const T&>() > u) && ...))
 
  332        return and_all([&](
auto&& v){ 
return v > u;});
 
  335    template <
typename U>
 
  337    noexcept(
noexcept(((std::declval<const T&>() >= u) && ...)))
 
  338    -> 
decltype(((std::declval<const T&>() >= u) && ...))
 
  340        return and_all([&](
auto&& v){ 
return v >= u;});
 
  346        return self.print(
"all_of", os);
 
  349    constexpr explicit operator bool() const
 
  350    noexcept(noexcept((
std::declval<const T&>() && ...)))
 
  352        return and_all([](
auto&& v) -> 
bool { 
return v;});
 
  355    template <
typename ... Ts>
 
  356    requires ( std::conjunction_v<std::is_copy_constructible<Ts>...>&& std::conjunction_v<std::is_invocable<T, Ts...>...> )
 
  357    constexpr auto operator()(Ts&& ... ts) 
const 
  358    noexcept( std::conjunction_v<std::is_nothrow_move_constructible<T>...> && std::conjunction_v<std::is_nothrow_copy_constructible<Ts>...>)
 
  362        return this->
template bind<RT>(std::forward<Ts>(ts)...);
 
  366template <
typename U, 
typename T>
 
  367requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  368constexpr auto operator==(
const U& u, 
const T& a)
 
  369noexcept(
noexcept(a == u))
 
  374template <
typename U, 
typename T >
 
  375requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  376constexpr auto operator!=(
const U& u, 
const T& a)
 
  377noexcept(
noexcept(a != u))
 
  382template <
typename U, 
typename T >
 
  383requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  384constexpr auto operator>(
const U& u, 
const T& a)
 
  385noexcept(
noexcept(a < u))
 
  387    return a.operator < ( u );
 
  390template <
typename U, 
typename T >
 
  391requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  392constexpr auto operator>=(
const U& u, 
const T& a)
 
  393noexcept(
noexcept(a <= u))
 
  398template <
typename U, 
typename T >
 
  399requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  400constexpr auto operator<(
const U& u, 
const T& a)
 
  401noexcept(
noexcept(a > u))
 
  403    return a.operator > ( u );
 
  406template <
typename U, 
typename T >
 
  407requires ( std::is_base_of_v<internal::logical_tuple_base, T> && ! std::is_base_of_v < internal::logical_tuple_base, U > )
 
  408constexpr auto operator<=(
const U& u, 
const T& a)
 
  409noexcept(
noexcept(a >= u))
 
  414template <
typename ... T>
 
  416template <
typename ... T>
 
  418template <
typename ... T>
 
Definition: dry-comparisons.hpp:289
constexpr auto operator==(const U &u) const noexcept(noexcept(((std::declval< const T & >()==u) &&...))) -> decltype(((std::declval< const T & >()==u) &&...))
Definition: dry-comparisons.hpp:296
constexpr auto operator>=(const U &u) const noexcept(noexcept(((std::declval< const T & >() >=u) &&...))) -> decltype(((std::declval< const T & >() >=u) &&...))
Definition: dry-comparisons.hpp:336
constexpr auto operator>(const U &u) const noexcept(noexcept(((std::declval< const T & >() > u) &&...))) -> decltype(((std::declval< const T & >() > u) &&...))
Definition: dry-comparisons.hpp:328
friend std::ostream & operator<<(std::ostream &os, const all_of &self)
Definition: dry-comparisons.hpp:344
constexpr auto operator<(const U &u) const noexcept(noexcept(((std::declval< const T & >()< u) &&...))) -> decltype(((std::declval< const T & >()< u) &&...))
Definition: dry-comparisons.hpp:312
constexpr auto operator!=(const U &u) const noexcept(noexcept(((std::declval< const T & >() !=u)||...))) -> decltype(((std::declval< const T & >() !=u)||...))
Definition: dry-comparisons.hpp:304
constexpr auto operator<=(const U &u) const noexcept(noexcept(((std::declval< const T & >()<=u) &&...))) -> decltype(((std::declval< const T & >()<=u) &&...))
Definition: dry-comparisons.hpp:320
Definition: dry-comparisons.hpp:131
Definition: dry-comparisons.hpp:94
constexpr auto and_all(F &&f) const
Definition: dry-comparisons.hpp:105
constexpr auto or_all(F &&f) const
Definition: dry-comparisons.hpp:100
Definition: dry-comparisons.hpp:210
friend std::ostream & operator<<(std::ostream &os, const none_of &self)
Definition: dry-comparisons.hpp:265
Class extending the tuple class from the standard library. Original reason is to allow printing of th...
Definition: tuple.hpp:42
typename printable< T >::type printable_t
Definition: dry-comparisons.hpp:59
Definition: sigHandler.cpp:20
none_of(T &&...) -> none_of< T... >
all_of(T &&...) -> all_of< T... >
any_of(T &&...) -> any_of< T... >
Definition: FordFulkerson.hpp:16
Definition: dry-comparisons.hpp:63
Definition: dry-comparisons.hpp:51