...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
A number of new functionalities are considered for inclusion into
future releases of Boost.MultiIndex. Some of them depend on the
potential for extensibility of the library, which has been a guiding
principle driving the current internal design of multi_index_container
.
Notifying indices can be implemented as decorators over preexistent index types, with the added functionality that internal events of the index (insertion, erasing, modifying of elements) are signalled to an external entity --for instance, by means of the Boost.Signals library. This functionality can have applications for:
The following is a sketch of a possible realization of notifying indices:
struct insert_log { void operator()(int x) { std::clog<<"insert: "<<x<<std::endl; } }; int main() { typedef multi_index_container< int, indexed_by< notifying<ordered_unique<identity<int> > >, // notifying index ordered_non_unique<identity<int> > > > indexed_t; indexed_t t; // on_insert is the signal associated to insertions t.on_insert.connect(insert_log()); t.insert(0); t.insert(1); return 0; } // output: // insert: 0 // insert: 1
The notifying indices functionality described above exploits a powerful design pattern based on index adaptors, decorators over preexistent indices which add some functionality or somehow change the semantics of the underlying index. This pattern can be used for the implementation of constraints, adaptors that restrict the elements accepted by an index according to some validation predicate. The following is a possible realization of how constraints syntax may look like:
struct is_even { bool operator()(int x)const{return x%2==0;} }; typedef multi_index_container< int, indexed_by< constrained<ordered_unique<identity<int> >,is_even> > > indexed_t;
The mechanisms by which Boost.MultiIndex orchestrates the
operations of the indices held by a multi_index_container
are
simple enough to make them worth documenting so that the (bold)
user can write implementations for her own indices.
multi_index_container
is rich enough to provide the basis
for implementation of indexed maps, i.e. maps which
can be looked upon several different keys. The motivation for having
such a container is mainly aesthetic convenience, since it
would not provide any additional feature to similar constructs
based directly on multi_index_container
.
The main challenge in writing an indexed map lies in the design of a
reasonable interface that resembles that of std::map
as
much as possible. There seem to be fundamental difficulties in extending
the syntax of a std::map
to multiple keys. For one example,
consider the situation:
indexed_map<int,string,double> m; // keys are int and string, double is the mapped to value ... cout<<m[0]<<endl; // OK cout<<m["zero"]<<endl; // OK m[1]=1.0; // !!
In the last sentence of the example, the user has no way of
providing the string
key mapping to the same value
as m[1]
. This and similar problems have to be devoted
a careful study when designing the interface of a potential
indexed map.
Revised April 19th 2015
© Copyright 2003-2015 Joaquín M López Muñoz. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)