Simple-Utility v2.3.1
Loading...
Searching...
No Matches
Equality.hpp
Go to the documentation of this file.
1// Copyright Dominic Koepke 2019 - 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef SIMPLE_UTILITY_FUNCTIONAL_MIXINS_EQUALITY_HPP
7#define SIMPLE_UTILITY_FUNCTIONAL_MIXINS_EQUALITY_HPP
8
9#pragma once
10
11#include <concepts>
12#include <functional>
13#include <tuple>
14
17
18namespace sl::functional
19{
21 {
22 template <class... PackedFns, class... Args>
23 requires (... && std::predicate<PackedFns, Args...>)
24 [[nodiscard]]
25 constexpr bool operator ()(
26 std::tuple<PackedFns...>&& fnPack,
27 Args&&... args
28 ) const
29 noexcept((... && std::is_nothrow_invocable_v<PackedFns, Args...>))
30 {
31 return std::apply(
32 [&]<class FirstFn, class... OtherFns>(FirstFn&& firstFn, OtherFns&&... otherFns)
33 {
34 const auto& firstResult = std::invoke(std::forward<FirstFn>(firstFn), args...);
35
36 // This workaround is necessary, due to some strange compile errors in the msvc v142 toolset
37 const auto equalResults = [&]<class Fn>(Fn&& fn)
38 {
39 return firstResult == std::invoke(std::forward<Fn>(fn), args...);
40 };
41 return (equalResults(std::forward<OtherFns>(otherFns)) && ...);
42 },
43 std::move(fnPack));
44 }
45 };
46
47 template <concepts::unqualified Derived>
49 {
50 private:
52
53 protected:
54 [[nodiscard]]
55 constexpr EqualityOperator() noexcept
56 {
57 static_assert(std::is_base_of_v<EqualityOperator, Derived>, "Derived doesn't inherit from EqualityOperator.");
58 static_assert(
59 std::copy_constructible<Derived> || std::move_constructible<Derived>,
60 "Derived is neither move- nor copy-constructible.");
61 }
62
63 [[nodiscard]]
66
67 [[nodiscard]]
70
71 ~EqualityOperator() = default;
72
73 public:
74 template <class Other>
76 [[nodiscard]]
77 friend constexpr auto operator ==(
78 const Derived& first,
79 Other&& other
80 ) noexcept(noexcept(make_composition<Strategy>(first, std::declval<Other>())))
81 {
82 return envelop<closure_template<Derived>::template type>(
83 make_composition<Strategy>(first, std::forward<Other>(other)));
84 }
85
86 template <class Other>
88 [[nodiscard]]
89 friend constexpr auto operator ==(
90 Derived&& first,
91 Other&& other
92 ) noexcept(noexcept(make_composition<Strategy>(std::move(first), std::declval<Other>())))
93 {
94 return envelop<closure_template<Derived>::template type>(
95 make_composition<Strategy>(std::move(first), std::forward<Other>(other)));
96 }
97 };
98}
99
100#endif
Definition: Equality.hpp:49
EqualityOperator & operator=(const EqualityOperator &)=default
EqualityOperator(const EqualityOperator &)=default
friend constexpr auto operator==(const Derived &first, Other &&other) noexcept(noexcept(make_composition< Strategy >(first, std::declval< Other >())))
Definition: Equality.hpp:77
EqualityOperator(EqualityOperator &&)=default
constexpr EqualityOperator() noexcept
Definition: Equality.hpp:55
Determines whether the given type satisfies the constraints of a function type.
Definition: BasicClosure.hpp:79
Definition: Arithmetic.hpp:13
Definition: Equality.hpp:21