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