#include <boost/fusion/include/less.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <iostream>

typedef int A, B, C;
typedef const char* D;

template <typename Seq1, typename Seq2>
struct sequence_less
{
    typedef typename boost::fusion::result_of::end<Seq1>::type end1_type;
    typedef typename boost::fusion::result_of::end<Seq2>::type end2_type;

    template <typename I1, typename I2, typename F>
    static bool
    call(I1 const&, I2 const&, F const& f, boost::mpl::true_)
    {
        return false;
    }

    template <typename I1, typename I2, typename F>
    static bool
    call(I1 const& a, I2 const& b, F const& f, boost::mpl::false_)
    {
        return f(*a, *b)
            || !f(*b, *a)
            && call(boost::fusion::next(a), boost::fusion::next(b), f);
    }

    template <typename I1, typename I2, typename F>
    static bool
    call(I1 const& a, I2 const& b, F const& f)
    {
        typename boost::fusion::result_of::equal_to<I1, end1_type>::type eq;
        return call(a, b, f, eq);
    }
};

template<class Seq1, class Seq2, class F>
bool less(const Seq1& seq1, const Seq2& seq2, const F& f) {
    return sequence_less<Seq1 const, Seq2 const>::call
        (boost::fusion::begin(seq1), boost::fusion::begin(seq2), f);
}

struct s
{
  A   a;
  B   b;
  C   c;
  D d;
};

BOOST_FUSION_ADAPT_STRUCT(s, (A, a)(B, b)(C, c)(D, d));

struct pred {
    template<class T>
    bool operator()(const T& lhs, const T& rhs) const {
        return(lhs < rhs);
    }
    bool operator()(const char* lhs, const char* rhs) const {
        return(std::strcmp(lhs, rhs) < 0);
    }
};

bool operator<( const s& lhs, const s& rhs )
{
    return less(lhs, rhs, pred());
}

int main() {
    s s1 = {1, 2, 3, "abc"};
    s s2 = {1, 2, 3, "def"};
    std::cout << (s1 < s2) << std::endl;
}
