CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Predicate.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
12#include <utility>
13
14namespace CeresEngine {
15
19 template<typename T> struct Predicate {};
20
26 template<typename T, typename Predicate1, typename Predicate2> struct BinaryPredicate : Predicate<T> {
29
32
37 : predicate1(std::forward<Predicate1>(predicate1)), predicate2(std::forward<Predicate2>(predicate2)) {}
38 };
39
44 template<typename T, typename TPredicate> struct UnaryPredicate : Predicate<T> {
46 TPredicate predicate;
47
50 explicit inline constexpr UnaryPredicate(TPredicate&& predicate) noexcept : predicate(std::forward<TPredicate>(predicate)) {}
51 };
52
58 template<typename Predicate1, typename Predicate2, typename... Predicates>
59 struct AndPredicate : Predicate<AndPredicate<Predicate1, Predicate2, Predicates...>> {
62
67 inline constexpr AndPredicate(Predicate1&& predicate1, Predicate2&& predicate2, Predicates&&... predicates) noexcept
68 : predicates(std::forward<Predicate1>(predicate1), std::forward<Predicate2>(predicate2), std::forward<Predicates>(predicates)...) {}
69
74 template<typename... Input> [[nodiscard]] inline constexpr bool operator()(Input&&... input) const { return impl<0>(input...); }
75
76 private:
77 template<size_t N, typename... Input> inline constexpr bool impl(Input&... input) const {
78 if constexpr(N > sizeof...(Predicates)) {
79 return predicates.template get<N>()(input...);
80 } else {
81 return predicates.template get<N>()(input...) && impl<N + 1>(input...);
82 }
83 }
84 };
85
90 template<typename Predicate1, typename Predicate2>
91 struct AndPredicate<Predicate1, Predicate2> : BinaryPredicate<AndPredicate<Predicate1, Predicate2>, Predicate1, Predicate2> {
93
98 template<typename... Input>
99 [[nodiscard]] inline constexpr bool operator()(Input&&... input) const
100 noexcept(noexcept(((AndPredicate::predicate1(input...)) && (AndPredicate::predicate2(input...))))) {
101 return (this->predicate1(input...)) && (this->predicate2(input...));
102 }
103 };
104
110 template<typename Predicate1, typename Predicate2, typename Predicate3>
111 struct AndPredicate<Predicate1, AndPredicate<Predicate2, Predicate3>> : AndPredicate<Predicate1, Predicate2, Predicate3> {
115 inline constexpr AndPredicate(Predicate1&& predicate1, AndPredicate<Predicate2, Predicate3>&& predicate2) noexcept
116 : AndPredicate<Predicate1, Predicate2, Predicate3>(std::forward<Predicate1>(predicate1), std::forward<Predicate2>(predicate2.predicate1),
117 std::forward<Predicate3>(predicate2.predicate2)) {}
118 };
119
125 template<typename Predicate1, typename Predicate2, typename Predicate3>
126 struct AndPredicate<AndPredicate<Predicate1, Predicate2>, Predicate3> : AndPredicate<Predicate1, Predicate2, Predicate3> {
130 inline constexpr AndPredicate(AndPredicate<Predicate1, Predicate2>&& predicate1, Predicate3&& predicate2) noexcept
131 : AndPredicate<Predicate1, Predicate2, Predicate3>(std::forward<Predicate1>(predicate1.predicate1),
132 std::forward<Predicate2>(predicate1.predicate2), std::forward<Predicate3>(predicate2)) {}
133 };
134
141 template<typename Predicate1, typename Predicate2, typename Predicate3, typename Predicate4>
143 : AndPredicate<Predicate1, Predicate2, Predicate3, Predicate4> {
148 : AndPredicate<Predicate1, Predicate2, Predicate3, Predicate4>(std::forward<Predicate1>(predicate1.predicate1),
149 std::forward<Predicate2>(predicate1.predicate2), std::forward<Predicate3>(predicate2.predicate1),
150 std::forward<Predicate3>(predicate2.predicate2)) {}
151 };
152
158 template<typename Predicate1, typename Predicate2, typename... Predicates>
159 struct OrPredicate : Predicate<OrPredicate<Predicate1, Predicate2, Predicates...>> {
162
167 inline constexpr OrPredicate(Predicate1&& predicate1, Predicate2&& predicate2, Predicates&&... predicates) noexcept
168 : predicates(std::forward<Predicate1>(predicate1), std::forward<Predicate2>(predicate2), std::forward<Predicates>(predicates)...) {}
169
174 template<typename... Input> [[nodiscard]] inline constexpr bool operator()(Input&&... input) const { return impl<0>(input...); }
175
176 private:
177 template<size_t N, typename... Input> [[nodiscard]] inline constexpr bool impl(Input&... input) const {
178 if constexpr(N > sizeof...(Predicates)) {
179 return predicates.template get<N>()(input...);
180 } else {
181 return predicates.template get<N>()(input...) || impl<N + 1>(input...);
182 }
183 }
184 };
185
190 template<typename Predicate1, typename Predicate2>
191 struct OrPredicate<Predicate1, Predicate2> : BinaryPredicate<OrPredicate<Predicate1, Predicate2>, Predicate1, Predicate2> {
193
198 template<typename... Input>
199 [[nodiscard]] inline constexpr bool operator()(Input&&... input) const
200 noexcept(noexcept((OrPredicate::predicate1(input...)) || (OrPredicate::predicate2(input...)))) {
201 return (this->predicate1(input...)) || (this->predicate2(input...));
202 }
203 };
204
210 template<typename Predicate1, typename Predicate2, typename Predicate3>
211 struct OrPredicate<Predicate1, OrPredicate<Predicate2, Predicate3>> : OrPredicate<Predicate1, Predicate2, Predicate3> {
215 inline constexpr OrPredicate(Predicate1&& predicate1, OrPredicate<Predicate2, Predicate3>&& predicate2) noexcept
216 : OrPredicate<Predicate1, Predicate2, Predicate3>(std::forward<Predicate1>(predicate1), std::forward<Predicate2>(predicate2.predicate1),
217 std::forward<Predicate3>(predicate2.predicate2)) {}
218 };
219
225 template<typename Predicate1, typename Predicate2, typename Predicate3>
226 struct OrPredicate<OrPredicate<Predicate1, Predicate2>, Predicate3> : OrPredicate<Predicate1, Predicate2, Predicate3> {
230 inline constexpr OrPredicate(OrPredicate<Predicate1, Predicate2>&& predicate1, Predicate3&& predicate2) noexcept
231 : OrPredicate<Predicate1, Predicate2, Predicate3>(std::forward<Predicate1>(predicate1.predicate1),
232 std::forward<Predicate2>(predicate1.predicate2), std::forward<Predicate3>(predicate2)) {}
233 };
234
241 template<typename Predicate1, typename Predicate2, typename Predicate3, typename Predicate4>
242 struct OrPredicate<OrPredicate<Predicate1, Predicate2>, OrPredicate<Predicate3, Predicate4>> : OrPredicate<Predicate1, Predicate2, Predicate3, Predicate4> {
247 : OrPredicate<Predicate1, Predicate2, Predicate3, Predicate4>(std::forward<Predicate1>(predicate1.predicate1),
248 std::forward<Predicate2>(predicate1.predicate2), std::forward<Predicate3>(predicate2.predicate1),
249 std::forward<Predicate3>(predicate2.predicate2)) {}
250 };
251
252 template<typename TPredicate> struct NotPredicate : UnaryPredicate<NotPredicate<TPredicate>, TPredicate> {
253 using UnaryPredicate<NotPredicate<TPredicate>, TPredicate>::UnaryPredicate;
254
259 template<typename... Input>
260 [[nodiscard]] inline constexpr bool operator()(Input&&... input) const noexcept(noexcept(NotPredicate::predicate(std::forward<Input>(input)...))) {
261 return !(this->predicate(std::forward<Input>(input)...));
262 }
263 };
264
265 template<typename Callable> struct UserPredicate : Predicate<UserPredicate<Callable>> {
268
272 explicit constexpr UserPredicate(Callable&& callable) noexcept : callable(std::forward<Callable>(callable)) {}
273
278 template<typename... Input>
279 [[nodiscard]] inline constexpr bool operator()(Input&&... input) const noexcept(noexcept(callable(std::forward<Input>(input)...))) {
280 return callable(std::forward<Input>(input)...);
281 }
282 };
283
290 template<typename Predicate1, typename Predicate2>
291 struct AndPredicate<NotPredicate<Predicate1>, NotPredicate<Predicate2>> : NotPredicate<OrPredicate<Predicate1, Predicate2>> {
295 inline constexpr AndPredicate(NotPredicate<Predicate1>&& predicate1, NotPredicate<Predicate2>&& predicate2) noexcept
297 OrPredicate<Predicate1, Predicate2>(std::forward<Predicate1>(predicate1.predicate), std::forward<Predicate2>(predicate2.predicate))) {}
298 };
299
306 template<typename Predicate1, typename Predicate2>
307 struct OrPredicate<NotPredicate<Predicate1>, NotPredicate<Predicate2>> : NotPredicate<AndPredicate<Predicate1, Predicate2>> {
311 inline constexpr OrPredicate(NotPredicate<Predicate1>&& predicate1, NotPredicate<Predicate2>&& predicate2) noexcept
313 AndPredicate<Predicate1, Predicate2>(std::forward<Predicate1>(predicate1.predicate), std::forward<Predicate2>(predicate2.predicate))) {}
314 };
315
318 template<typename TPredicate> struct NotPredicate<NotPredicate<TPredicate>> : TPredicate {
319 explicit inline constexpr NotPredicate(NotPredicate<TPredicate>&& predicate) : TPredicate(predicate.predicate) {}
320 };
321
328 template<typename Predicate1, typename Predicate2>
329 inline constexpr auto operator&&(const Predicate<Predicate1>& predicate1, const Predicate<Predicate2>& predicate2) noexcept {
330 return AndPredicate<Predicate1, Predicate2>(Predicate1(static_cast<const Predicate1&>(predicate1)),
331 Predicate2(static_cast<const Predicate2&>(predicate2)));
332 }
333
340 template<typename Predicate1, typename Predicate2>
341 inline constexpr auto operator&&(Predicate<Predicate1>&& predicate1, Predicate<Predicate2>&& predicate2) noexcept {
342 return AndPredicate<Predicate1, Predicate2>(std::forward<Predicate1>(static_cast<Predicate1&&>(predicate1)),
343 std::forward<Predicate2>(static_cast<Predicate2&&>(predicate2)));
344 }
345
352 template<typename Predicate1, typename Predicate2>
353 inline constexpr auto operator||(const Predicate<Predicate1>& predicate1, const Predicate<Predicate2>& predicate2) noexcept {
354 return OrPredicate<Predicate1, Predicate2>(Predicate1(static_cast<const Predicate1&>(predicate1)),
355 Predicate2(static_cast<const Predicate2&>(predicate2)));
356 }
357
364 template<typename Predicate1, typename Predicate2>
365 inline constexpr auto operator||(Predicate<Predicate1>&& predicate1, Predicate<Predicate2>&& predicate2) noexcept {
366 return OrPredicate<Predicate1, Predicate2>(std::forward<Predicate1>(static_cast<Predicate1&&>(predicate1)),
367 std::forward<Predicate2>(static_cast<Predicate2&&>(predicate2)));
368 }
369
374 template<typename TPredicate> inline constexpr auto operator!(const Predicate<TPredicate>& predicate) noexcept {
375 return NotPredicate<TPredicate>(TPredicate(static_cast<const TPredicate&>(predicate)));
376 }
377
382 template<typename TPredicate> inline constexpr auto operator!(Predicate<TPredicate>&& predicate) noexcept {
383 return NotPredicate<TPredicate>(std::forward<TPredicate>(static_cast<TPredicate&&>(predicate)));
384 }
385
390 template<typename Callable> [[nodiscard]] inline constexpr auto predicate(Callable&& callable) noexcept {
391 return UserPredicate<Callable>(std::forward<Callable>(callable));
392 }
393
399 template<typename T> [[nodiscard]] inline constexpr auto eq(T value) noexcept {
400 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input == value)) { return input == value; });
401 }
402
408 template<typename T> [[nodiscard]] inline constexpr auto neq(T value) noexcept {
409 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input != value)) { return input != value; });
410 }
411
417 template<typename T> [[nodiscard]] inline constexpr auto gt(T value) noexcept {
418 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input > value)) { return input > value; });
419 }
420
426 template<typename T> [[nodiscard]] inline constexpr auto gte(T value) noexcept {
427 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input >= value)) { return input >= value; });
428 }
429
435 template<typename T> [[nodiscard]] inline constexpr auto lt(T value) noexcept {
436 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input < value)) { return input < value; });
437 }
438
444 template<typename T> [[nodiscard]] inline constexpr auto lte(T value) noexcept {
445 return predicate([value = std::forward<T>(value)](const auto& input) constexpr noexcept(noexcept(input <= value)) { return input <= value; });
446 }
447
448} // namespace CeresEngine
Tuple is a fixed-size collection of heterogeneous values.
Definition Tuple.hpp:15
Definition Application.hpp:19
constexpr auto lt(T value) noexcept
Creates a new predicate that compares the input object with value using < operator.
Definition Predicate.hpp:435
constexpr auto neq(T value) noexcept
Creates a new predicate that compares the input object with value using != operator.
Definition Predicate.hpp:408
constexpr auto gte(T value) noexcept
Creates a new predicate that compares the input object with value using >= operator.
Definition Predicate.hpp:426
constexpr auto operator||(const Predicate< Predicate1 > &predicate1, const Predicate< Predicate2 > &predicate2) noexcept
Helper operator to create a new OrPredicate from two predicates.
Definition Predicate.hpp:353
constexpr auto gt(T value) noexcept
Creates a new predicate that compares the input object with value using > operator.
Definition Predicate.hpp:417
constexpr auto lte(T value) noexcept
Creates a new predicate that compares the input object with value using <= operator.
Definition Predicate.hpp:444
constexpr auto operator&&(const Predicate< Predicate1 > &predicate1, const Predicate< Predicate2 > &predicate2) noexcept
Helper operator to create a new AndPredicate from two predicates.
Definition Predicate.hpp:329
constexpr auto predicate(Callable &&callable) noexcept
Helper function to create a new predicate from a lambda.
Definition Predicate.hpp:390
constexpr auto eq(T value) noexcept
Creates a new predicate that compares the input object with value using == operator.
Definition Predicate.hpp:399
@ Input
Determines that the socket takes a value as input.
constexpr auto operator!(const Predicate< TPredicate > &predicate) noexcept
Helper operator to create a new OrPredicate from two predicates.
Definition Predicate.hpp:374
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
constexpr AndPredicate(AndPredicate< Predicate1, Predicate2 > &&predicate1, Predicate3 &&predicate2) noexcept
Creates a new AndPredicate.
Definition Predicate.hpp:130
constexpr AndPredicate(AndPredicate< Predicate1, Predicate2 > &&predicate1, AndPredicate< Predicate3, Predicate4 > &&predicate2) noexcept
Creates a new AndPredicate.
Definition Predicate.hpp:147
constexpr AndPredicate(NotPredicate< Predicate1 > &&predicate1, NotPredicate< Predicate2 > &&predicate2) noexcept
Creates a new AndPredicate and applies the "De Morgan" law.
Definition Predicate.hpp:295
constexpr AndPredicate(Predicate1 &&predicate1, AndPredicate< Predicate2, Predicate3 > &&predicate2) noexcept
Creates a new AndPredicate.
Definition Predicate.hpp:115
constexpr bool operator()(Input &&... input) const noexcept(noexcept(((AndPredicate::predicate1(input...)) &&(AndPredicate::predicate2(input...)))))
Executes the predicate.
Definition Predicate.hpp:99
A predicate implementation that performs a logical AND between other predicates.
Definition Predicate.hpp:59
constexpr bool impl(Input &... input) const
Definition Predicate.hpp:77
constexpr bool operator()(Input &&... input) const
Executes the predicate.
Definition Predicate.hpp:74
Tuple< Predicate1, Predicate2, Predicates... > predicates
A tuple containing the predicates to apply the logical AND on.
Definition Predicate.hpp:61
constexpr AndPredicate(Predicate1 &&predicate1, Predicate2 &&predicate2, Predicates &&... predicates) noexcept
Creates a new AndPredicate.
Definition Predicate.hpp:67
A predicate that operates using two other predicates as-if a binary operation.
Definition Predicate.hpp:26
Predicate1 predicate1
The left-hand side predicate.
Definition Predicate.hpp:28
constexpr BinaryPredicate(Predicate1 &&predicate1, Predicate2 &&predicate2) noexcept
Creates a new BinaryPredicate.
Definition Predicate.hpp:36
Predicate2 predicate2
The right-hand side predicate.
Definition Predicate.hpp:31
Definition NamedType.hpp:237
constexpr NotPredicate(NotPredicate< TPredicate > &&predicate)
Definition Predicate.hpp:319
Definition Predicate.hpp:252
constexpr bool operator()(Input &&... input) const noexcept(noexcept(NotPredicate::predicate(std::forward< Input >(input)...)))
Executes the predicate.
Definition Predicate.hpp:260
constexpr OrPredicate(NotPredicate< Predicate1 > &&predicate1, NotPredicate< Predicate2 > &&predicate2) noexcept
Creates a new OrPredicate and applies the "De Morgan" law.
Definition Predicate.hpp:311
constexpr OrPredicate(OrPredicate< Predicate1, Predicate2 > &&predicate1, Predicate3 &&predicate2) noexcept
Creates a new OrPredicate.
Definition Predicate.hpp:230
constexpr OrPredicate(OrPredicate< Predicate1, Predicate2 > &&predicate1, OrPredicate< Predicate3, Predicate4 > &&predicate2) noexcept
Creates a new OrPredicate.
Definition Predicate.hpp:246
constexpr OrPredicate(Predicate1 &&predicate1, OrPredicate< Predicate2, Predicate3 > &&predicate2) noexcept
Creates a new OrPredicate.
Definition Predicate.hpp:215
constexpr bool operator()(Input &&... input) const noexcept(noexcept((OrPredicate::predicate1(input...))||(OrPredicate::predicate2(input...))))
Executes the predicate.
Definition Predicate.hpp:199
A predicate implementation that performs a logical OR between other predicates.
Definition Predicate.hpp:159
constexpr OrPredicate(Predicate1 &&predicate1, Predicate2 &&predicate2, Predicates &&... predicates) noexcept
Creates a new OrPredicate.
Definition Predicate.hpp:167
constexpr bool impl(Input &... input) const
Definition Predicate.hpp:177
Tuple< Predicate1, Predicate2, Predicates... > predicates
A tuple containing the predicates to apply the logical OR on.
Definition Predicate.hpp:161
constexpr bool operator()(Input &&... input) const
Executes the predicate.
Definition Predicate.hpp:174
A type that predicate types must extend to allow automatic operator overloading.
Definition Predicate.hpp:19
A predicate that operates using two other predicates as-if a unary operation.
Definition Predicate.hpp:44
TPredicate predicate
The operand predicate.
Definition Predicate.hpp:46
constexpr UnaryPredicate(TPredicate &&predicate) noexcept
Creates a new UnaryPredicate.
Definition Predicate.hpp:50
Definition Predicate.hpp:265
constexpr UserPredicate(Callable &&callable) noexcept
Creates a new UserPredicate
Definition Predicate.hpp:272
constexpr bool operator()(Input &&... input) const noexcept(noexcept(callable(std::forward< Input >(input)...)))
Executes the predicate.
Definition Predicate.hpp:279
Callable callable
The callable to be invoked when evaluating the predicate.
Definition Predicate.hpp:267