#include <iostream>
#include <utility>
template <typename T>
class Condition {
public:
using ItemType = T;
};
class OneCondition : public Condition<int>
{
public:
bool match(const Condition::ItemType& item) const
{
return item == 1;
}
};
class TwoCondition : public Condition<int>
{
public:
bool match(const Condition::ItemType& item) const
{
return item == 2;
}
};
template <typename T>
concept bool IsCondition = requires(T a, typename T::ItemType b) {
{ a.match(b) } -> bool;
};
template <typename U, typename V>
class ConditionAnd {
public:
ConditionAnd(U&& first, V&& second) :
first_(std::forward<U>(first)), second_(std::forward<V>(second)) {
}
template <typename W>
bool match(const W& item) const {
return first_.match(item) && second_.match(item);
}
private:
U first_;
V second_;
};
template <IsCondition U, IsCondition V>
decltype(auto) operator&&(U&& first, V&& second)
{
return ConditionAnd(std::forward<U>(first), std::forward<V>(second));
}
int main() {
auto cond = OneCondition{} && TwoCondition{};
std::cout << cond.match(4) << std::endl;
std::cout << "Hello, world!" << std::endl;
}