//chaining comparison object
template<class T>
class comparison {
    const bool result;
    const T& last;
public:
    comparison(const T& l, bool r=true) :result(r), last(l) {}
    operator bool() const {return result;}
    comparison operator<(const T& rhs) const {return comparison(rhs, (result && last<rhs));}
    comparison operator<=(const T& rhs) const {return comparison(rhs, (result && last<=rhs));}
    comparison operator>(const T& rhs) const {return comparison(rhs, (result && last>rhs));}
    comparison operator>=(const T& rhs) const {return comparison(rhs, (result && last>=rhs));}
};

//random object that has operator chaining built in
struct a {
    int val;
    comparison<a> operator<(const a& rhs) const {return comparison<a>(rhs, val<rhs.val);}
    comparison<a> operator<=(const a& rhs) const {return comparison<a>(rhs, val<=rhs.val);}
    comparison<a> operator>(const a& rhs) const {return comparison<a>(rhs, val>rhs.val);}
    comparison<a> operator>=(const a& rhs) const {return comparison<a>(rhs, val>=rhs.val);}
};

#include <iostream>
int main() {
    a v0 = {0};
    a v1 = {1};
    a v2 = {2};
    //testing of chained comparisons with builtin
    std::cout << (v0<v1<v2) << '\n';
    std::cout << (v0<v1>v2) << '\n';
    std::cout << (v0>v1<v2) << '\n';
    std::cout << (v0>v1>v2) << '\n';
    //testing of chained comparisons with int
    std::cout << (comparison<int>(0)<1<2) << '\n';
    std::cout << (comparison<int>(0)<1>2) << '\n';
    std::cout << (comparison<int>(0)>1<2) << '\n';
    std::cout << (comparison<int>(0)>1>2) << '\n';
}
    