Boost logo

Boost Users :

Subject: [Boost-users] [Multi-Index] Get container view of a non-unique-index equal_range?
From: Dominique Devienne (ddevienne_at_[hidden])
Date: 2009-06-11 12:06:01


Given for example

class Ident : public noncopyable { .. .};
class VehicleIdent : public Ident { ... };

struct ByUid {};
struct ByType {};
struct ByNKey {};
struct VehicleIdentHash { ... };
struct VehicleIdentPred { ... };

typedef boost::multi_index_container<
    shared_ptr<VehicleIdent>,
    indexed_by<
        hashed_unique< // primary (surrogate) key
            tag<ByUid>,
            BOOST_MULTI_INDEX_CONST_MEM_FUN(
                Ident, const Uid&, uid
            )
>,
        hashed_unique< // natural key (logical primary key)
            tag<ByNKey>, identity< shared_ptr<VehicleIdent> >,
            VehicleIdentHash, VehicleIdentPred
>,

        // additional index to iterate on a type range (e.g. all Cars)
        hashed_non_unique<
            tag<ByType>,
            BOOST_MULTI_INDEX_CONST_MEM_FUN(
                VehicleIdent, const string&, type
            )
>
>
> VehicleIndex;

typedef VehicleIndex::index<ByUid>::type VehicleByUid;
typedef VehicleIndex::index<ByType>::type VehicleByType;
typedef VehicleIndex::index<ByNKey>::type VehicleByNKey;

I'd like to be able to have a "view" of VehicleIndex, for example
compatible with unordered_set in this case since using a hashed index,
for a given vehicle type ("Audi" for example), and going further have
this view allow inserts which would go into the "master" vehicle index
under the cover, validated by its unique indexes.

In pseudo-code, something a bit like this:

struct VehicleMake {
    VehicleByType::EqualRangeView& models_;

    VehicleMake(const string& name)
    : models_(get<ByType>(get_vehicle_index()).equal_range_view(name))
    {}
};

With models_ behaving has a normal container one can iterate on
(begin, end), query (empty, find, count), modify (insert, erase,
clear, etc...), those operations only affecting the VehicleIndex
elements matching the VehicleByType given range, and possibly
asserting all inserts are valid for the range (the vehicles added via
the "range view" have the type matching the range's type).

Can this be done? Has it been considered as a possible extension, and
is it even feasible given the current B.MI design?

Any input on how to achieve or emulate the above would be appreciated.
Thanks, --DD

PS: The above design is synthetic of course. We have a parent-child
hierarchy of C++ objects where parents have lists of their children,
but now there's a list of all children, from all parents, in a B.MI,
indexed (non-unique) on the parent instance, and I'd like the
"concrete" list maintained by each parent to become the kind of "view"
I'm describing above. Right now I'm manually maintaining the sync of
the existing and the new "master" list (the B.MI index), having to
"sprinkle" the code to keep them in sync, but the "view" approach
above would be cleaner IMHO, and avoid many potential bugs from
forgetting to "sprinkle" in all the right places.


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