| |
1 #pragma once |
| |
2 #include <array> |
| |
3 |
| |
4 namespace detail |
| |
5 { |
| |
6 template<typename T, typename Vt> |
| |
7 constexpr bool oneOfCompare(const T& value, Vt *first, Vt *last) |
| |
8 { |
| |
9 return (first == last) |
| |
10 ? false |
| |
11 : (*first) == value |
| |
12 ? true |
| |
13 : detail::oneOfCompare(value, first + 1, last); |
| |
14 } |
| |
15 |
| |
16 template<typename Vt, std::size_t N> |
| |
17 struct OneOfClass |
| |
18 { |
| |
19 std::array<Vt, N> parameters; |
| |
20 |
| |
21 template<typename... Ts> |
| |
22 constexpr OneOfClass(Ts&&... parameters) : |
| |
23 parameters {{parameters...}} {} |
| |
24 |
| |
25 template<typename T> |
| |
26 constexpr bool operator==(const T& value) const |
| |
27 { |
| |
28 return detail::oneOfCompare(value, ¶meters[0], ¶meters[N]); |
| |
29 } |
| |
30 |
| |
31 template<typename T> |
| |
32 constexpr bool operator!=(const T& value) const |
| |
33 { |
| |
34 return !(*this == value); |
| |
35 } |
| |
36 |
| |
37 template<typename T> |
| |
38 constexpr friend bool operator==(const T& value, const OneOfClass<Vt, N>& array) |
| |
39 { |
| |
40 return array == value; |
| |
41 } |
| |
42 |
| |
43 template<typename T> |
| |
44 constexpr friend bool operator!=(const T& value, const OneOfClass<Vt, N>& array) |
| |
45 { |
| |
46 return array != value; |
| |
47 } |
| |
48 }; |
| |
49 }; |
| |
50 |
| |
51 /* |
| |
52 * Returns such an object that compares equal to some value if and only if any of the parameters do. |
| |
53 * Example: (x == any(1, 2, 3)) is equivalent to (x == 1 || x == 2 || x == 3) other than the lack of lazy-evaluation |
| |
54 */ |
| |
55 template<typename... Ts> |
| |
56 constexpr auto oneOf(Ts&&... parameters) |
| |
57 { |
| |
58 using Vt = typename std::common_type<Ts...>::type; |
| |
59 return detail::OneOfClass<Vt, sizeof...(Ts)>({parameters...}); |
| |
60 } |
| |
61 |
| |
62 static_assert(oneOf(1,2,3) == 3, "oneOf unit test"); |
| |
63 static_assert(oneOf(1,2,3) != 5, "oneOf unit test"); |
| |
64 static_assert(3 == oneOf(1,2,3), "oneOf unit test"); |
| |
65 static_assert(5 != oneOf(1,2,3), "oneOf unit test"); |