Boost logo

Boost Users :

Subject: Re: [Boost-users] Generically comparing structs
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2009-08-27 14:42:37


AMDG

Bill Buklis wrote:
> Frequently I have to write comparison functions (usually of the "less"
> variety) that involve multiple keys or members of a struct. For example:
>
> struct s
> {
> A a;
> B b;
> C c;
> D d;
> // there may be other members not used in the comparison
> };
>
> // operator< function or an equivalent function object
> bool operator<( const s& lhs, const s& rhs )
> {
> if( lhs.a < rhs.a )
> return(true);
> else if( lhs.a == rhs.a )
> {
> if( lhs.b < rhs.b )
> return(true);
> else if( lhs.b == rhs.b )
> //and so on...
> }
> return(false);
> }
>
> This gets quite repetitive, especially if I have to write alternate sort
> orders (e.g. b,a,c,d or c,d,a,b)
>
> I'm thinking there has to an easier way to do this or a way to do a generic
> algorithm for this. Is there anything in boost that would help?
>
> I had an idea that one might be able to fill a vector with binders for each
> element and then call lexicographical_compare, but I'm not sure how to make
> it work.
>

Boost.Fusion provides several ways to do this.

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

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

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

If you need different sort orders, you can use tie:

#include <boost/fusion/include/vector_tie.hpp>

bool operator<( const s& lhs, const s& rhs )
{
    return boost::fusion::vector_tie(lhs.a, lhs.b, lhs.c, lhs.d) <
        boost::fusion::vector_tie(rhs.a, rhs.b, rhs.c, rhs.d);
}

In Christ,
Steven Watanabe


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net