sane-project-backends/backend/genesys/value_filter.h

139 wiersze
3.4 KiB
C++

/* sane - Scanner Access Now Easy.
Copyright (C) 2020 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef BACKEND_GENESYS_VALUE_FILTER_H
#define BACKEND_GENESYS_VALUE_FILTER_H
#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <vector>
namespace genesys {
struct AnyTag {};
constexpr AnyTag VALUE_FILTER_ANY{};
template<class T>
class ValueFilterAny
{
public:
ValueFilterAny() : matches_any_{false} {}
ValueFilterAny(AnyTag) : matches_any_{true} {}
ValueFilterAny(std::initializer_list<T> values) :
matches_any_{false},
values_{values}
{}
bool matches(T value) const
{
if (matches_any_)
return true;
auto it = std::find(values_.begin(), values_.end(), value);
return it != values_.end();
}
bool operator==(const ValueFilterAny& other) const
{
return matches_any_ == other.matches_any_ && values_ == other.values_;
}
bool matches_any() const { return matches_any_; }
const std::vector<T>& values() const { return values_; }
private:
bool matches_any_ = false;
std::vector<T> values_;
template<class Stream, class U>
friend void serialize(Stream& str, ValueFilterAny<U>& x);
};
template<class T>
std::ostream& operator<<(std::ostream& out, const ValueFilterAny<T>& values)
{
if (values.matches_any()) {
out << "ANY";
return out;
}
out << format_vector_indent_braced(4, "", values.values());
return out;
}
template<class Stream, class T>
void serialize(Stream& str, ValueFilterAny<T>& x)
{
serialize(str, x.matches_any_);
serialize_newline(str);
serialize(str, x.values_);
}
template<class T>
class ValueFilter
{
public:
ValueFilter() = default;
ValueFilter(std::initializer_list<T> values) :
values_{values}
{}
bool matches(T value) const
{
auto it = std::find(values_.begin(), values_.end(), value);
return it != values_.end();
}
bool operator==(const ValueFilter& other) const
{
return values_ == other.values_;
}
const std::vector<T>& values() const { return values_; }
private:
std::vector<T> values_;
template<class Stream, class U>
friend void serialize(Stream& str, ValueFilter<U>& x);
};
template<class T>
std::ostream& operator<<(std::ostream& out, const ValueFilter<T>& values)
{
if (values.values().empty()) {
out << "(none)";
return out;
}
out << format_vector_indent_braced(4, "", values.values());
return out;
}
template<class Stream, class T>
void serialize(Stream& str, ValueFilter<T>& x)
{
serialize_newline(str);
serialize(str, x.values_);
}
} // namespace genesys
#endif // BACKEND_GENESYS_VALUE_FILTER_H