#include <iostream>
#include <string>
template <typename ...>
struct List {};
template <typename _Test, auto _L, auto _R>
struct Constraint;
template <
typename _Test,
typename _L, typename _LF, _LF(_L::*_l),
typename _R, typename _RF, _RF(_R::*_r)>
struct Constraint<_Test, _l, _r> {
static
bool test(_L const &l, _R const &r) {
return _Test::test(l.*_l, r.*_r);
}
};
template <auto>
struct Term;
template <typename _T, typename _V, _V(_T::*_field)>
struct Term<_field> {
};
template <typename _T, typename _V, _V(_T::*_method)()>
struct Term<_method> {
};
template <typename _T, typename _V, _V(_T::*_method)() const>
struct Term<_method> {
};
template <typename _T, typename _V, _V(*_function)(_T &)>
struct Term<_function> {
};
template <typename _T, typename _V, _V(*_function)(_T const &)>
struct Term<_function> {
};
// TODO: How do you handle references to subobjects? What if a
// class has a field that is a class and you want to solve
// for that subfield but only within the context of the parent?
struct Equal {
template <typename _L, typename _R>
static
bool test(_L const &l, _R const &r) {
return l == r;
}
};
struct Less {
template <typename _L, typename _R>
static
bool test(_L const &l, _R const &r) {
return l < r;
}
};
struct Foo {
std::string name;
int value;
};
struct Bar {
int value;
};
using Constraints = List<
Constraint<Equal, &Foo::value, &Bar::value>,
Constraint<Less, &Foo::value, &Bar::value>
>;
int main () {
std::cout << "Hello, world!\n";
Foo foo { "foo", 5 };
Bar bar { 0 };
// std::cout << FooBarMatch::test(foo, bar) << '\n';
bar.value = 5;
// std::cout << FooBarMatch::test(foo, bar) << '\n';
return 0;
}