template<class T, std::size_t N>
struct any_of:std::array<T, N> {
#define MAKE_OPERATOR( OPERATOR ) \
template<class U, \
std::enable_if_t< std::is_same<void, std::void_t< \
decltype( std::declval<T const&>() == std::declval<U const&>() ) \
>>{}, bool> =true \
> \
friend bool operator OPERATOR ( any_of const& lhs, U const& rhs) { \
return std::any_of( \
lhs.begin(), lhs.end(), \
[&](auto&& lhs){ return lhs OPERATOR rhs; } \
); \
} \
template<class U, \
std::enable_if_t< std::is_same<void, std::void_t< \
decltype( std::declval<U const&>() == std::declval<T const&>() ) \
>>{} && !std::is_same< U, any_of >{} , bool> =true \
> \
friend bool operator OPERATOR ( U const& lhs, any_of const& rhs) { \
return std::any_of( \
rhs.begin(), rhs.end(), \
[&](auto&& rhs){ return lhs OPERATOR rhs; } \
); \
}
MAKE_OPERATOR(==)
MAKE_OPERATOR(!=)
MAKE_OPERATOR(<)
MAKE_OPERATOR(<=)
MAKE_OPERATOR(>=)
MAKE_OPERATOR(>)
#undef MAKE_OPERATOR
explicit any_of( std::array<T, N> arr):std::array<T, N>(std::move(arr)) {}
template<class...Ts>
explicit any_of( T t, Ts... ts ):std::array<T, N>{ std::move(t), std::move(ts)... } {}
any_of( any_of const& )=delete;
any_of& operator=( any_of const& )=delete;
any_of()=delete;
};
template<class T, std::size_t N>
any_of(T(&)[N]) -> any_of<T,N>;
template<class T, class...Ts>
any_of(T, Ts...) -> any_of<T, 1+sizeof...(Ts)>;
тестовый код:
if (any_of{1,2,3} == 2) {
std::cout << "2 is there\n";
}
if (! (any_of{1,2,3} == 7) ){
std::cout << "7 is not there\n";
}
if (any_of{1,2,3} == any_of{5,6,1}) {
std::cout << "overlap!\n";
}
if (!(any_of{1,2,3} == any_of{5,6,7})) {
std::cout << "no overlap!\n";
}
Живой пример .
Вывод в c ++ 17 компилятор:
2 is there
7 is not there
overlap!
no overlap!
Поддерживаются все различные операторы сравнения.
Кросс-тип double any_of, например:
any_of{1,2,3} == any_of{3.14, 5.7, 1.0}
не удастся скомпилировать, так как оба ==
из обоих any_of
работают.