3rdParty/boost/1.78.0/libs/multi_index/doc/reference/indices.html
multi_index_container reference
multi_index_container instantiations comprise one or more indices specified at compile time. Each index allows read/write access to the elements contained in a definite manner. For instance, ordered indices provide a set-like interface to the elements, whereas sequenced indices mimic the functionality of std::list.
Indices are not isolated objects, and so cannot be constructed on their own. Rather they are embedded into a multi_index_container as specified by means of an index specifier. The name of the index class implementation proper is never directly exposed to the user, who has only access to the associated index specifier.
Insertion and erasing of elements are always performed through the appropriate interface of some index of the multi_index_container; these operations, however, do have an impact on all other indices as well: for instance, insertion through a given index may fail because there exists another index which bans the operation in order to preserve its invariant (like uniqueness of elements.) This circumstance, rather than being an obstacle, yields much of the power of Boost.MultiIndex: equivalent constructions based on manual composition of standard containers would have to add a fair amount of code in order to globally preserve the invariants of each container while guaranteeing that all of them are synchronized. The global operations performed in a joint manner among the various indices can be reduced to six primitives:
The last two primitives deserve some further explanation: in order to guarantee the invariants associated to each index (e.g. some definite ordering,) elements of a multi_index_container are not mutable. To overcome this restriction, indices expose member functions for replacement and modification which allow for the mutation of elements in a controlled fashion. Immutability of elements does not significantly impact the interfaces of ordered and hashed indices, as they are based upon those of associative and unordered associative containers, respectively, and these containers also have non-mutable elements; but it may come as a surprise when dealing with sequenced and random access indices, which are designed upon the functionality provided by std::list.
These global operations are not directly exposed to the user, but rather they are wrapped as appropriate by each index (for instance, ordered indices provide a set-like suite of insertion member functions, whereas sequenced and random access indices have push_back and push_front operations.) Boost.MultiIndex poses no particular conditions on the interface of indices, although each index provided satisfy the C++ requirements for standard containers to the maximum extent possible within the conceptual framework of the library.
Some member functions of an index interface are implemented by global primitives from the list above. Complexity of these operations thus depends on all indices of a given multi_index_container, not just the currently used index.
In order to establish complexity estimates, an index is characterized by its complexity signature, consisting of the following associated functions on the number of elements:
c(n): copying,i(n): insertion,h(n): hinted insertion,d(n): deletion,r(n): replacement,m(n): modifying.Each function yields the complexity estimate of the contribution of the index to the corresponding global primitive. Let us consider an instantiation of multi_index_container with N indices labelled 0,...,N-1 whose complexity signatures are (ci,ii,hi,di,ri,mi); the insertion of an element in such a container is then of complexity O(i0(n)+···+iN-1(n)) where n is the number of elements. To abbreviate notation, we adopt the following definitions:
C(n)=c0(n)+···+cN-1(n),I(n)=i0(n)+···+iN-1(n),H(n)=h0(n)+···+hN-1(n),D(n)=d0(n)+···+dN-1(n),R(n)=r0(n)+···+rN-1(n),M(n)=m0(n)+···+mN-1(n).For instance, consider a multi_index_container with two ordered indices, for which i(n)=log(n), and a sequenced index with i(n)=1 (constant time insertion). Insertion of an element into this multi_index_container is then of complexity
O(I(n))=O(2*log(n)+1)=O(log(n)).
Index specifiers are passed as instantiation arguments to multi_index_container and provide the information needed to incorporate the corresponding indices. Future releases of Boost.MultiIndex may allow for specification of user-defined indices. Meanwhile, the requirements for an index specifier remain implementation defined. Currently, Boost.MultiIndex provides the index specifiers
ordered_unique and ordered_non_unique for ordered indices,ranked_unique and ranked_non_unique for ranked indices,hashed_unique and hashed_non_unique for hashed indices,sequenced for sequenced indices,random_access for random access indices."boost/multi_index/indexed_by.hpp" synopsisnamespaceboost{namespacemulti\_index{template\<typenameT0,...,typenameTn\>structindexed\_by;}// namespace boost::multi\_index}// namespace boost
indexed_byindexed_by is a model of MPL Random Access Sequence and MPL Extensible Sequence meant to be used to specify a compile-time list of indices as the IndexSpecifierList of multi_index_container.
template\<typenameT0,...,typenameTn\>structindexed\_by;
Each user-provided element of indexed_list must be an index specifier. At least an element must be provided. The maximum number of elements of an indexed_by sequence is implementation defined.
Tags are just conventional types used as mnemonics for indices of an multi_index_container, as for instance in member function get. Each index can have none, one or more tags associated. The way tags are assigned to a given index is dependent on the particular index specifier. However, for convenience all indices of Boost.MultiIndex support tagging through the class template tag.
"boost/multi_index/tag.hpp" synopsisnamespaceboost{namespacemulti\_index{template\<typenameT0,...,typenameTn\>structtag;}// namespace boost::multi\_index}// namespace boost
tagtag is a typelist construct used to specify a compile-time sequence of tags to be assigned to an index in instantiation time.
template\<typenameT0,...,typenameTn\>structtag{typedef **implementation defined** type;};
Elements of tag can be any type, though the user is expected to provide classes with mnemonic names. Duplicate elements are not allowed. The maximum number of elements of a tag instantiation is implementation defined. The nested type is a model of MPL Random Access Sequence and MPL Extensible Sequence containing the types T0, ... , Tn in the same order as specified.
Indices of this type are organized around keys obtained from the elements, as described in the key extraction reference.
The following concept is used by the rearrange facilities of non key-based indices. Given an index i of type Index, a view of i is any range [first,last) where first and last are input iterators such that
Iterator is convertible to const Index::value_type&i appears exactly once in [first,last).Note that the view refers to the actual elements of i, not to copies of them. Additionally, a view is said to be free if its traversal order is not affected by changes in the traversal order of i. Examples of free views are:
c.begin(),c.end()), where c is any container of reference wrappers (from Boost.Ref) to the elements of i containing exactly one reference to every element.i'.begin(),i'.end()), where i' is any index belonging to the same multi_index_container as i, except i itself.c.rbegin(),c.rend()), or ranges obtained from the former with the aid of permutation_iterator from Boost.Iterator.
multi_index_container reference
Revised January 9th 2020
© Copyright 2003-2020 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)