1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2020 Povilas Kanapickas <povilas@radix.lt>
4
5 This file is part of the SANE package.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #ifndef BACKEND_GENESYS_VALUE_FILTER_H
22 #define BACKEND_GENESYS_VALUE_FILTER_H
23
24 #include <algorithm>
25 #include <initializer_list>
26 #include <iostream>
27 #include <vector>
28
29 namespace genesys {
30
31 struct AnyTag {};
32 constexpr AnyTag VALUE_FILTER_ANY{};
33
34 template<class T>
35 class ValueFilterAny
36 {
37 public:
ValueFilterAny()38 ValueFilterAny() : matches_any_{false} {}
ValueFilterAny(AnyTag)39 ValueFilterAny(AnyTag) : matches_any_{true} {}
ValueFilterAny(std::initializer_list<T> values)40 ValueFilterAny(std::initializer_list<T> values) :
41 matches_any_{false},
42 values_{values}
43 {}
44
matches(T value)45 bool matches(T value) const
46 {
47 if (matches_any_)
48 return true;
49 auto it = std::find(values_.begin(), values_.end(), value);
50 return it != values_.end();
51 }
52
53 bool operator==(const ValueFilterAny& other) const
54 {
55 return matches_any_ == other.matches_any_ && values_ == other.values_;
56 }
57
matches_any()58 bool matches_any() const { return matches_any_; }
values()59 const std::vector<T>& values() const { return values_; }
60
61 private:
62 bool matches_any_ = false;
63 std::vector<T> values_;
64
65 template<class Stream, class U>
66 friend void serialize(Stream& str, ValueFilterAny<U>& x);
67 };
68
69 template<class T>
70 std::ostream& operator<<(std::ostream& out, const ValueFilterAny<T>& values)
71 {
72 if (values.matches_any()) {
73 out << "ANY";
74 return out;
75 }
76 out << format_vector_indent_braced(4, "", values.values());
77 return out;
78 }
79
80 template<class Stream, class T>
serialize(Stream & str,ValueFilterAny<T> & x)81 void serialize(Stream& str, ValueFilterAny<T>& x)
82 {
83 serialize(str, x.matches_any_);
84 serialize_newline(str);
85 serialize(str, x.values_);
86 }
87
88
89 template<class T>
90 class ValueFilter
91 {
92 public:
93 ValueFilter() = default;
ValueFilter(std::initializer_list<T> values)94 ValueFilter(std::initializer_list<T> values) :
95 values_{values}
96 {}
97
matches(T value)98 bool matches(T value) const
99 {
100 auto it = std::find(values_.begin(), values_.end(), value);
101 return it != values_.end();
102 }
103
104 bool operator==(const ValueFilter& other) const
105 {
106 return values_ == other.values_;
107 }
108
values()109 const std::vector<T>& values() const { return values_; }
110
111 private:
112 std::vector<T> values_;
113
114 template<class Stream, class U>
115 friend void serialize(Stream& str, ValueFilter<U>& x);
116 };
117
118 template<class T>
119 std::ostream& operator<<(std::ostream& out, const ValueFilter<T>& values)
120 {
121 if (values.values().empty()) {
122 out << "(none)";
123 return out;
124 }
125 out << format_vector_indent_braced(4, "", values.values());
126 return out;
127 }
128
129 template<class Stream, class T>
serialize(Stream & str,ValueFilter<T> & x)130 void serialize(Stream& str, ValueFilter<T>& x)
131 {
132 serialize_newline(str);
133 serialize(str, x.values_);
134 }
135
136 } // namespace genesys
137
138 #endif // BACKEND_GENESYS_VALUE_FILTER_H
139