noober
noober

Reputation: 4938

C++ container for storing sorted unique values with different predicates for sorting and uniqueness

I have a record with 2 fields (say, A and B). 2 instances of the record should be considered equal, if their As are equal. On the other hand, a collection of the record instances should be sorted by the B field.

Is there a container like std::set, which can be defined with two different predicates, one for sorting and one for uniqueness, so I could avoid explicit sorting and just append elements? If no, how can it be workarounded?

Regards,

Upvotes: 2

Views: 568

Answers (2)

There is nothing in the standard library which would support your use case directly. You could use Boost.MultiIndexContainer for this purpose, though. Something like this:

typedef multi_index_container<
  Record,
  indexed_by<
    ordered_non_unique<member<Record, decltype(Record::B), &Record::B>>,
    hashed_unique<member<Record, decltype(Record::A), &Record::A>>
  >
> RecordContainer;

(Code assuming correct headers and using namespace directives for brevity).

The idea is to create a container with two indices, one which will guarantee the ordering based on B and the other which will guarantee uniqueness based on A. decltype() in the code can of course be replaced by the actual types of A and B which you know, but I don't.

The order of the indices matters slightly, since for convenience, the container itself offers the same interface as its first index. You can always access any index by using container.get(), though.

The code is not intended as a copy&paste solution, but as a starting point. You can add customisations, index tags etc. Refer to Boost documentation for details.

Upvotes: 4

ravi
ravi

Reputation: 10733

Is there a container like std::set, which can be defined with two different predicates, one for sorting and one for uniqueness

std::set defines whether particular element is unique OR not in terms of the sorting criteria you provide to it( by default it uses less<>) . There's no need to explicitly pass another criteria for checking equality of elements. With that said, however, you can use a predicate with algorithms to check for equality of elements of std::set.

Upvotes: 1

Related Questions