diff --git a/Jamfile b/Jamfile deleted file mode 100644 index f5431f8..0000000 --- a/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -# Boost.MultiIndex examples and tests Jamfile -# -# Copyright 2003-2004 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) -# -# See http://www.boost.org/libs/multi_index for library home page. - -subproject libs/multi_index ; - -# please order by name to ease maintenance - -subinclude libs/multi_index/example ; -subinclude libs/multi_index/test ; -subinclude libs/multi_index/perf ; diff --git a/doc/acknowledgements.html b/doc/acknowledgements.html deleted file mode 100644 index 226bb06..0000000 --- a/doc/acknowledgements.html +++ /dev/null @@ -1,144 +0,0 @@ - - - -
- -
Boost.MultiIndex Acknowledgements-Fernando Cacciola, Darren Cook, Beman Dawes, Jeremy Maitin-Shepard and Daryle -Walker from the Boost mailing list provided useful suggestions for improvement -on the first alpha releases of the library. Gang Wang discovered several -bugs in the code. Thomas Wenisch brought out the idea of "sequence sets" -from which sequenced indices were designed. Giovanni Bajo, Chris Little and -Maxim Yegorushkin tested the library on several platforms. Daniel Wallin -contributed fixes for MSVC++ 7.0. Ron Liechty and the support staff at -Metrowerks provided assistance during the porting of the library to CW 8.3. -Porting to VisualAge 6.0 counted on Toon Knapen's help. Markus Schöpflin -aided with Compaq C++ 6.5 and GCC for Tru64 UNIX. Rosa Bernárdez proofread the -last versions of the tutorial. -
- --Pavel Voženílek has been immensely helpful in thoroughly reviewing -every single bit of the library, and he also suggested several extra -functionalities, most notably range querying, safe mode, polymorphic key -extractors and MPL support. Thank you! -
- --The Boost acceptance review took place between March 20th and 30th 2004. -Pavel Voženílek was the review manager. Thanks to all the people -who participated and specially to those who submitted reviews: -Fredrik Blomqvist, Tom Brinkman, Paul A Bristow, Darren Cook, Jeff Garland, -David B. Held, Brian McNamara, Gary Powell, Rob Stewart, Arkadiy Vertleyb, -Jörg Walter. Other Boost members also contributed ideas, particularly -in connection with the library's naming scheme: Pavol Droba, -Dave Gomboc, Jeremy Maitin-Shepard, Thorsten Ottosen, Matthew Vogt, -Daryle Walker. My apologies if I inadvertently left somebody out of this -list. -
- --Boost.MultiIndex could not have been written without Aleksey Gurtovoy -et al. superb Boost MPL -Library. Also, Aleksey's techniques for dealing with ETI-related -problems in MSVC++ 6.0 helped solve some internal issues of the library. -
- --The internal implementation of red-black trees is based on that of SGI STL -stl_tree.h file: -
- --Copyright (c) 1996,1997 -Silicon Graphics Computer Systems, Inc. -- -
-Permission to use, copy, modify, distribute and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation. Silicon Graphics makes no -representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. -
-
-Copyright (c) 1994 -Hewlett-Packard Company -
-Permission to use, copy, modify, distribute and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation. Hewlett-Packard Company makes no -representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. -
-
-I would like to dedicate this piece of work to Rosa Bernárdez, my very first
-C++ teacher, for her unconditional support in many endeavors of which programming is
-by no means the most important. In memory of my cat López (2001-2003): he
-lived too fast, died too young.
-
-
-Many thanks again to Pavel Voženílek, who has carefully reviewed -the new material and suggested many improvements. The design of hashed indices -has benefited from discussions with several Boost members, most notably -Howard Hinnant and Daniel James. Daniel has also contributed -Boost.Hash -to the community: hashed indices depend on this library as -their default hash function provider. Robert Ramey's -Boost Serialization Library -provides the very solid framework upon which Boost.MultiIndex serialization -capabilities are built. Toon Knapen helped adjust the library for VisualAge 6.0. -Markus Schöpflin provided a Jamfile tweak for GCC under Tru64 UNIX. -
- -Revised July 11th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/advanced_topics.html b/doc/advanced_topics.html deleted file mode 100644 index 2c8b3b8..0000000 --- a/doc/advanced_topics.html +++ /dev/null @@ -1,1589 +0,0 @@ - - - - - -
Boost.MultiIndex Advanced topicsctor_args_listmulti_index_container
-
- multi_index_container
-
-Hashed indices constitute a trade-off with respect to ordered indices: if correctly used,
-they provide much faster lookup of elements, at the expense of losing sorting
-information.
-Let us revisit our employee_set example: suppose a field for storing
-the Social Security number is added, with the requisite that lookup by this
-number should be as fast as possible. Instead of the usual ordered index, a
-hashed index can be resorted to:
-
- --struct employee -{ - int id; - std::string name; - int ssnumber; - - employee(int id,const std::string& name,int ssnumber): - id(id),name(name),ssnumber(ssnumber){} - - bool operator<(const employee& e)const{return id<e.id;} -}; - -typedef multi_index_container< - employee, - indexed_by< - // sort by employee::operator< - ordered_unique<identity<employee> >, - - // sort by less<string> on name - ordered_non_unique<member<employee,std::string,&employee::name> >, - - // hashed on ssnumber - hashed_unique<member<employee,int,&employee::ssnumber> > - > -> employee_set -
-Note that the hashed index does not guarantee any particular ordering of the -elements: so, for instance, we cannot efficiently query the employees whose SSN is -greater than a given number. Usually, you must consider these restrictions when -determining whether a hashed index is preferred over an ordered one. -
- -
-If you are familiar with non-standard hash_sets provided
-by some compiler vendors, then learning to use hashed indices should be straightforward.
-However, the interface of hashed indices is modeled after the specification
-for unordered associative containers by the
-C++ Standard
-Library Technical Report (TR1),
-which differs in some significant aspects from existing pre-standard
-implementations:
-
lower_bound or upper_bound
- member functions (unlike Dinkumware's solution.)
-Just like ordered indices, hashed indices have unique and non-unique variants, selected
-with the specifiers hashed_unique and hashed_non_unique,
-respectively. In the latter case, elements with equivalent keys are kept together and can
-be jointly retrieved by means of the equal_range member function.
-
-Hashed indices specifiers have two alternative syntaxes, depending on whether -tags are provided or not: -
- -- --(hashed_unique | hashed_non_unique) - <[(tag)[,(key extractor)[,(hash function)[,(equality predicate)]]]]> - -(hashed_unique | hashed_non_unique) - <[(key extractor)[,(hash function)[,(equality predicate)]]]> -
-The key extractor parameter works in exactly the same way as for -ordered indices; lookup, insertion, -etc., are based on the key returned by the extractor rather than the whole -element. -
- -
-The hash function is the very core of the fast lookup capabilities of this type of
-indices: a hasher
-is just a Unary
-Function returning an std::size_t value for any given
-key. In general, it is impossible that every key map to a different hash value, for
-the space of keys can be greater than the number of permissible hash codes: what
-makes for a good hasher is that the probability of a collision (two different
-keys with the same hash value) is as close to zero as possible. This is a statistical
-property depending on the typical distribution of keys in a given application, so
-it is not feasible to have a general-purpose hash function with excellent results
-in every possible scenario; the default value for this parameter uses
-Boost.Hash, which often provides good
-enough results.
-
-The equality predicate is used to determine whether two keys are to be treated
-as the same. The default
-value std::equal_to<KeyFromValue::result_type> is in most
-cases exactly what is needed, so very rarely will you have to provide
-your own predicate. Note that hashed indices require that two
-equivalent keys have the same hash value, which
-in practice greatly reduces the freedom in choosing an equality predicate.
-
-The lookup interface of hashed indices consists in member functions
-find, count and equal_range.
-Note that lower_bound and upper_bound are not
-provided, as there is no intrinsic ordering of keys in this type of indices.
-
-Just as with ordered indices, these member functions take keys
-as their search arguments, rather than entire objects. Remember that
-ordered indices lookup operations are further augmented to accept
-compatible keys, which can roughly be regarded as "subkeys".
-For hashed indices, a concept of
-compatible key is also
-supported, though its usefulness is much more limited: basically,
-a compatible key is an object which is entirely equivalent to
-a native object of key_type value, though maybe with
-a different internal representation:
-
- --// US SSN numbering scheme -struct ssn -{ - ssn(int area_no,int group_no,int serial_no): - area_no(area_no),group_no(group_no),serial_no(serial_no) - {} - - int to_int()const - { - return serial_no+10000*group_no+1000000*area_no; - } - -private: - int area_no; - int group_no; - int serial_no; -}; - -// interoperability with SSNs in raw int form - -struct ssn_equal -{ - bool operator()(const ssn& x,int y)const - { - return x.to_int()==y; - } - - bool operator()(int x,const ssn& y)const - { - return x==y.to_int(); - } -}; - -struct ssn_hash -{ - std::size_t operator()(const ssn& x)const - { - return boost::hash<int>()(x.to_int()); - } - - std::size_t operator()(int x)const - { - return boost::hash<int>()(x); - } -}; - -typedef employee_set::nth_index<2>::type employee_set_by_ssn; - -employee_set es; -employee_set_by_ssn& ssn_index=es.get<2>(); -... -// find an employee by ssn -employee e=*(ssn_index.find(ssn(12,1005,20678),ssn_hash(),ssn_equal())); -
-In the example, we provided a hash functor ssn_hash and an
-equality predicate ssn_equal allowing for interoperability
-between ssn objects and the raw ints stored as
-SSNs in employee_set.
-
-By far, the most useful application of compatible keys in the context -of hashed indices lies in the fact that they allow for seamless usage of -composite keys. -
- -
-Hashed indices have
-replace,
-modify and
-modify_key
-member functions, with the same functionality as in ordered indices.
-
-Due to the internal constraints imposed by the Boost.MultiIndex framework, -hashed indices provide guarantees on iterator validity and -exception safety that are actually stronger than required by the -C++ Standard Library Technical Report (TR1) with respect -to unordered associative containers: -
rehash provides the strong exception safety guarantee
- unconditionally. TR1 only warrants it if the internal hash function and
- equality predicate objects do not throw. The somewhat surprising consequence
- is that a TR1-compliant unordered associative container might erase
- elements if an exception is thrown during rehashing!
-In relational databases, composite keys depend on two or more fields of a given table.
-The analogous concept in Boost.MultiIndex is modeled by means of
-
-composite_key, as shown in the example:
-
- --struct phonebook_entry -{ - std::string family_name; - std::string given_name; - std::string phone_number; - - phonebook_entry( - std::string family_name, - std::string given_name, - std::string phone_number): - family_name(family_name),given_name(given_name),phone_number(phone_number) - {} -}; - -// define a multi_index_container with a composite key on -// (family_name,given_name) -typedef multi_index_container< - phonebook_entry, - indexed_by< - //non-unique as some subscribers might have more than one number - ordered_non_unique< - composite_key< - phonebook_entry, - member<phonebook_entry,std::string,&phonebook_entry::family_name>, - member<phonebook_entry,std::string,&phonebook_entry::given_name> - > - >, - ordered_unique< // unique as numbers belong to only one subscriber - member<phonebook_entry,std::string,&phonebook_entry::phone_number> - > - > -> phonebook; -
-composite_key accepts two or more key extractors on the same
-value (here, phonebook_entry). Lookup operations on a composite
-key are accomplished by passing tuples with the values searched:
-
- --phonebook pb; -... -// search for Dorothea White's number -phonebook::iterator it=pb.find( - boost::make_tuple(std::string("White"),std::string("Dorothea"))); -std::string number=it->phone_number; -
-Composite keys are sorted by lexicographical order, i.e. sorting is performed -by the first key, then the second key if the first one is equal, etc. This -order allows for partial searches where only the first keys are specified: -
- -- --phonebook pb; -... -// look for all Whites -std::pair<phonebook::iterator,phonebook::iterator> p= - pb.equal_range(boost::make_tuple(std::string("White"))); -
-On the other hand, partial searches without specifying the first keys are not -allowed. -
- -
-By default, the corresponding std::less predicate is used
-for each subkey of a composite key. Alternate comparison predicates can
-be specified with
-composite_key_compare:
-
- --// phonebook with given names in reverse order - -typedef multi_index_container< - phonebook_entry, - indexed_by< - ordered_non_unique< - composite_key< - phonebook_entry, - member<phonebook_entry,std::string,&phonebook_entry::family_name>, - member<phonebook_entry,std::string,&phonebook_entry::given_name> - >, - composite_key_compare< - std::less<std::string>, // family names sorted as by default - std::greater<std::string> // given names reversed - > - >, - ordered_unique< - member<phonebook_entry,std::string,&phonebook_entry::phone_number> - > - > -> phonebook; -
-See example 7 in the examples section
-for an application of composite_key.
-
-Composite keys can also be used with hashed indices in a straightforward manner: -
- -- --struct street_entry -{ - // quadrant coordinates - int x; - int y; - - std::string name; - - street_entry(int x,int y,const std::string& name):x(x),y(y),name(name){} -}; - -typedef multi_index_container< - street_entry, - indexed_by< - hashed_non_unique< // indexed by quadrant coordinates - composite_key< - street_entry, - member<street_entry,int,&street_entry::x>, - member<street_entry,int,&street_entry::y> - > - >, - hashed_non_unique< // indexed by street name - member<street_entry,std::string,&street_entry::name> - > - > -> street_locator; - -street_locator sl; -... -void streets_in_quadrant(int x,int y) -{ - std::pair<street_locator::iterator,street_locator::iterator> p= - sl.equal_range(boost::make_tuple(x,y)); - - while(p.first!=p.second){ - std::cout<<p.first->name<<std::endl; - ++p.first; - } -} -
-Note that hashing is automatically taken care of: boost::hash is
-specialized to hash a composite key as a function of the boost::hash
-values of its elements. Should we need to specify different hash functions for the
-elements of a composite key, we can explicitly do so by using the
-composite_key_hash
-utility:
-
- --struct tuned_int_hash -{ - int operator()(int x)const - { - // specially tuned hash for this application - } -}; - -typedef multi_index_container< - street_entry, - indexed_by< - hashed_non_unique< // indexed by quadrant coordinates - composite_key< - street_entry, - member<street_entry,int,&street_entry::x>, - member<street_entry,int,&street_entry::y> - >, - composite_key_hash< - tuned_int_hash, - tuned_int_hash - > - >, - hashed_non_unique< // indexed by street name - member<street_entry,std::string,&street_entry::name> - > - > -> street_locator; -
-Also, equality of composite keys can be tuned with
-composite_key_equal_to,
-though in most cases the default equality predicate (relying on
-the std::equal_to instantiations for the element types)
-will be the right choice.
-
-Unlike with ordered indices, we cannot perform partial searches specifying -only the first elements of a composite key: -
- -- --// try to locate streets in quadrants with x==0 -// compile-time error: hashed indices do not allow such operations -std::pair<street_locator::iterator,street_locator::iterator> p= - sl.equal_range(boost::make_tuple(0)); -
-The reason for this limitation is quite logical: as the hash value of a composite -key depends on all of its elements, it is impossible to calculate it from -partial information. -
- -
-The Key Extractor
-concept allows the same object to extract keys from several different types,
-possibly through suitably defined overloads of operator():
-
- --// example of a name extractor from employee and employee * -struct name_extractor -{ - const std::string& operator()(const employee& e)const{return e.name;} - std::string& operator()(employee& e)const{return e.name;} - std::string& operator()(employee* e)const{return e->name;} -}; -
-This possibility is fully exploited by predefined key extractors provided
-by Boost.MultiIndex, making it simpler to define multi_index_containers
-where elements are pointers or references to the actual objects. The following
-specifies a multi_index_container of pointers to employees sorted by their
-names.
-
- --typedef multi_index_container< - employee *, - indexed_by< - ordered_non_unique<member<employee,std::string,&employee::name> > > -> employee_set; -
-Note that this is specified in exactly the same manner as a multi_index_container
-of actual employee objects: member takes care of the
-extra dereferencing needed to gain access to employee::name. A similar
-functionality is provided for interoperability with reference wrappers from
-Boost.Ref:
-
- --typedef multi_index_container< - boost::reference_wrapper<const employee>, - indexed_by< - ordered_non_unique<member<employee,std::string,&employee::name> > > -> employee_set; -
-In fact, support for pointers is further extended to accept what we call
-chained pointers. Such a chained pointer is defined by induction as a raw or
-smart pointer or iterator to the actual element, to a reference wrapper of the
-element or to another chained pointer; that is, chained pointers are arbitrary
-compositions of pointer-like types ultimately dereferencing
-to the element from where the key is to be extracted. Examples of chained
-pointers to employee are:
-
employee *,const employee *,std::auto_ptr<employee>,std::list<boost::reference_wrapper<employee> >::iterator,employee **,boost::shared_ptr<const employee *>.multi_index_containers from preexisting
-multi_index_containers.
-
-
--In order to present a short summary of the different usages of Boost.MultiIndex -key extractors in the presence of reference wrappers and pointers, consider the -following final type: -
- -- --struct T -{ - int i; - const int j; - int f()const; - int g(); -}; -
-The table below lists the appropriate key extractors to be used for
-different pointer and reference wrapper types based on T, for
-each of its members.
-
-
| element type | -key | -key extractor | -applicable toconst elements? |
- read/write? | -
|---|---|---|---|---|
T |
- i |
- member<T,int,&T::i> |
- yes | -yes | -
j |
- member<T,const int,&T::j> |
- yes | -no | -|
f() |
- const_mem_fun<T,int,&T::f> |
- yes | -no | -|
g() |
- mem_fun<T,int,&T::g> |
- no | -no | -|
reference_wrapper<T> |
- i |
- member<T,int,&T::i> |
- yes | -yes | -
j |
- member<T,const int,&T::j> |
- yes | -no | -|
f() |
- const_mem_fun<T,int,&T::f> |
- yes | -no | -|
g() |
- mem_fun<T,int,&T::g> |
- yes | -no | -|
reference_wrapper<const T> |
- i |
- member<T,const int,&T::i> |
- yes | -no | -
j |
- member<T,const int,&T::j> |
- yes | -no | -|
f() |
- const_mem_fun<T,int,&T::f> |
- yes | -no | -|
g() |
- - | |||
chained pointer to T- or to reference_wrapper<T> |
- i |
- member<T,int,&T::i> |
- yes | -yes | -
j |
- member<T,const int,&T::j> |
- yes | -no | -|
f() |
- const_mem_fun<T,int,&T::f> |
- yes | -no | -|
g() |
- mem_fun<T,int,&T::g> |
- yes | -no | -|
chained pointer to const T- or to reference_wrapper<const T> |
- i |
- member<T,const int,&T::i> |
- yes | -no | -
j |
- member<T,const int,&T::j> |
- yes | -no | -|
f() |
- const_mem_fun<T,int,&T::f> |
- yes | -no | -|
g() |
- - | |||
-The column "applicable to const elements?" states whether the
-corresponding key extractor can be used when passed constant elements (this
-relates to the elements specified in the first column, not the referenced
-T objects). The only negative case is for T::g when
-the elements are raw T objects, which make sense as we are dealing
-with a non-constant member function: this also implies that multi_index_containers
-of elements of T cannot be sorted by T::g, because
-elements contained within a multi_index_container are treated as constant.
-
-A key extractor is called read/write if it returns a non-constant reference
-to the key when passed a non-constant element, and it is called read-only
-otherwise. In order to use multi_index_container::modify_key, the associated
-key extractor must be read/write. The column "read/write?" shows that most
-combinations yield read-only extractors.
-
-Some care has to be taken to preserve const-correctness in the
-specification of the key extractors: in some sense, the const
-qualifier is carried along to the member part, even if that particular
-member is not defined as const. For instance, if the elements
-are of type const T *, sorting by T::i is not
-specified as member<const T,int,&T::i>, but rather as
-member<T,const int,&T::i>.
-
-For practical demonstrations of use of these key extractors, refer to -example 2 and -example 6 in the examples section. -
- -ctor_args_list
-Although in most cases multi_index_containers will be default constructed
-(or copied from a preexisting multi_index_container), sometimes it is
-necessary to specify particular values for the internal objects used (key extractors,
-comparison predicates, allocator), for instance if some of these objects do not have
-a default constructor. The same situation can arise with standard STL containers,
-which allow for the optional specification of such objects:
-
- --// example of non-default constructed std::set -template<typename IntegralType> -struct modulo_less -{ - modulo_less(IntegralType m):modulo(m){} - - bool operator()(IntegralType x,IntegralType y)const - { - return (x%modulo)<(y%modulo); - } - -private: - IntegralType modulo; -}; - -typedef std::set<unsigned int,modulo_less<unsigned int> > modulo_set; - -modulo_set m(modulo_less<unsigned int>(10)); -
-multi_index_container does also provide this functionality, though in a
-considerably more complex fashion, due to the fact that the constructor
-of a multi_index_container has to accept values for all the internal
-objects of its indices. The full form of multi_index_container constructor
-is
-
- --explicit multi_index_container( - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()); -
-The specification of the allocator object poses no particular problems;
-as for the ctor_args_list, this object is designed so as to hold
-the necessary construction values for every index in the multi_index_container.
-From the point of view of the user, ctor_args_list is equivalent
-to the type
-
- --boost::tuple<C0,...,CI-1> -
-where I is the number of indices, and Ci is
-
- --nth_index<i>::type::ctor_args -
-that is, the nested type ctor_args of the i-th index. Each
-ctor_args type is in turn a tuple holding values for constructor
-arguments of the associated index: so, ordered indices demand a key extractor object
-and a comparison predicate, hashed indices take an initial number of buckets,
-a key extractor, a hash function and an equality predicate; while sequenced indices do
-not need any construction argument. For instance, given the definition
-
- --typedef multi_index_container< - unsigned int, - indexed_by< - hashed_unique<identity<unsigned int> >, - ordered_non_unique<identity<unsigned int>, modulo_less<unsigned int> >, - sequenced<> - > -> modulo_indexed_set; -
-the corresponding ctor_args_list type is equivalent to
-
- --boost::tuple< - // ctr_args of index #0 - boost::tuple< - std::size_t, // initial number of buckets; 0 if unspecified - identity<unsigned int>, - boost::hash<unsigned int>, - std::equal_to<unsigned int> >, - - // ctr_args of index #1 - boost::tuple< - identity<unsigned int>, - modulo_less<unsigned int> >, - - // sequenced indices do not have any construction argument - boost::tuple<> -> -
-Such a modulo_indexed_set cannot be default constructed, because
-modulo_less does not provide a default constructor. The following shows
-how the construction can be done:
-
- --modulo_indexed_set::ctor_args_list args_list= - boost::make_tuple( - // ctor_args for index #0 is default constructible - modulo_indexed_set::nth_index<0>::type::ctor_args(), - - boost::make_tuple(identity<unsigned int>(),modulo_less<unsigned int>(10)), - - // this is also default constructible (actually, an empty tuple) - modulo_indexed_set::nth_index<2>::type::ctor_args(), - ); - -modulo_indexed_set m(args_list); -
-A program is provided in the examples section that -puts in practise these concepts. -
- -
-multi_index_containers can be archived and retrieved by means of the
-Boost Serialization Library. Both regular
-and XML archives are supported. The usage is straightforward and does not
-differ from any other serializable type. For instance:
-
- --#include <boost/archive/text_oarchive.hpp> -#include <boost/archive/text_iarchive.hpp> -#include <fstream> - -... - -void save(const employee_set& es) -{ - std::ofstream ofs("data"); - boost::archive::text_oarchive oa(ofs); - oa<<es; -} - -void load(employee_set& es) -{ - std::ifstream ifs("data"); - boost::archive::text_iarchive ia(ifs); - ia>>es; -} - -... - -employee_set es; -... // fill it with data -save(es); - -... - -employee_set restored_es; -load(restored_es); -
-Serialization capabilities are automatically provided by just linking with
-the appropriate Boost.Serialization library module: it is not necessary
-to explicitly include any header from Boost.Serialization,
-apart from those declaring the type of archive used in the process. If not used,
-however, serialization support can be disabled by globally defining the macro
-BOOST_MULTI_INDEX_DISABLE_SERIALIZATION. Disabling serialization
-for Boost.MultiIndex can yield a small improvement in build times, and may
-be necessary in those defective compilers that fail to correctly process
-Boost.Serialization headers.
-
-When retrieving an archived multi_index_container, not only
-the elements are restored, but also the order they were arranged into for
-every index of the container. This is specially important with sequenced
-indices, whose ordering is not automatically fixed, as happens for
-ordered unique indices. Ordered non-unique indices are an in-between
-case: elements with different keys are sorted in ascending order, but
-there is no implicit traversal order for elements with the same key.
-Serialization of multi_index_container addresses this issue,
-so that restored ordered non-unique indices are sorted in exactly the
-same way as their originals. As for hashed indices, no guarantee is made
-about the order in which elements will be iterated in the restored
-container: in general, it is unwise to rely on the ordering of elements
-of a hashed index, since it can change in arbitrary ways during
-insertion or rehashing.
-
-Iterators to indices of a multi_index_container can also be
-serialized. Serialization of iterators must be done only after serializing
-its corresponding container.
-
-Example 9 in the examples section shows -the serialization capabilities of Boost.MultiIndex. -
- - -
-The concept of Design by Contract, originally developed as part
-of Bertrand Meyer's Eiffel language,
-revolves around the formulation of a contract between the user
-of a library and the implementor, by which the first is required to
-respect some preconditions on the values passed when invoking
-methods of the library, and the implementor guarantees in return
-that certain constraints on the results are met (postconditions),
-as well as the honoring of specified internal consistency rules, called
-invariants. Eiffel natively supports the three parts of the
-contract just described by means of constructs require,
-ensure and invariant, respectively.
-
-C++ does not enjoy direct support for Design by Contract techniques: these -are customarily implemented as assertion code, often turned off in -release mode for performance reasons. Following this approach, -Boost.MultiIndex provides two distinct debugging modes: -
-The idea of adding precondition checking facilities to STL as a debugging aid -was first introduced by Cay S. Horstmann in his -Safe STL library and later -adopted by STLport Debug -Mode. Similarly, Boost.MultiIndex features the so-called safe mode -in which all sorts of preconditions are checked when dealing with iterators -and functions of the library. -
- -
-Boost.MultiIndex safe mode is set by globally defining the macro
-BOOST_MULTI_INDEX_ENABLE_SAFE_MODE. Error conditions
-are checked via the macro BOOST_MULTI_INDEX_SAFE_MODE_ASSERT, which
-by default resolves to a call to
-BOOST_ASSERT.
-
-If the user decides to define her own version of
-BOOST_MULTI_INDEX_SAFE_MODE_ASSERT, it has to take the form
-
- --BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) -
-where expr is the condition checked and error_code
-is one value of the safe_mode::error_code enumeration:
-
- --namespace boost{ - -namespace multi_index{ - -namespace safe_mode{ - -enum error_code -{ - invalid_iterator, // vg. default cted or pointing to erased element - not_dereferenceable_iterator, // iterator is not dereferenceable - not_incrementable_iterator, // iterator points to end of sequence - not_decrementable_iterator, // iterator points to beginning of sequence - not_owner, // iterator does not belong to the container - not_same_owner, // iterators belong to different containers - invalid_range, // last not reachable from first - inside_range, // iterator lies within a range (and it mustn't) - same_container // containers ought to be different -}; - -} // namespace multi_index::safe_mode - -} // namespace multi_index - -} // namespace boost -
-For instance, the following replacement of
-BOOST_MULTI_INDEX_SAFE_MODE_ASSERT throws an exception instead of
-asserting:
-
- --#include <boost/multi_index_container/safe_mode_errors.hpp> - -struct safe_mode_exception -{ - safe_mode_exception(boost::multi_index::safe_mode::error_code error_code): - error_code(error_code) - {} - - boost::multi_index::safe_mode::error_code error_code; -}; - -#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) \ -if(!(expr)){throw safe_mode_exception(error_code);} - -// This has to go before the inclusion of any header from Boost.MultiIndex, -// except possibly safe_error_codes.hpp. -
-Other possibilites, like outputting to a log or firing some kind of alert, are -also implementable. -
- -
-Warning: Safe mode adds a very important overhead to the program
-both in terms of space and time used, so in general it should not be set for
-NDEBUG builds. Also, this mode is intended solely as a debugging aid,
-and programs must not rely on it as part of their normal execution flow: in
-particular, no guarantee is made that all possible precondition errors are diagnosed,
-or that the checks remain stable across different versions of the library.
-
-Iterators restored from an archive are not subject to safe mode checks. This is
-so because it is not possible to automatically know the associated
-multi_index_container of an iterator from the serialization
-information alone. However, if desired, a restored iterator can be converted to a
-checked value by using the following workaround:
-
- --employee_set es; -employee_set::nth_index<1>::iterator it; - -// restore es and it from an archive ar -ar>>es; -ar>>it; // it won't benefit from safe mode checks - -// turn it into a checked value by providing -// Boost.MultiIndex with info about the associated container -it=es.project<1>(it); -
-The so called invariant-checking mode of Boost.MultiIndex can be
-set by globally defining the macro
-BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING.
-When this mode is in effect, all public functions of Boost.MultiIndex
-will perform post-execution tests aimed at ensuring that the basic
-internal invariants of the data structures managed are preserved.
-
-If an invariant test fails, Boost.MultiIndex will indicate the failure
-by means of the unary macro BOOST_MULTI_INDEX_INVARIANT_ASSERT.
-Unless the user provides a definition for this macro, it defaults to
-
-BOOST_ASSERT. Any assertion of this kind should
-be regarded in principle as a bug in the library. Please report such
-problems, along with as much contextual information as possible, to the
-maintainer of the library.
-
-It is recommended that users of Boost.MultiIndex always set the -invariant-checking mode in debug builds. -
- -multi_index_container
-Academic movitations aside, there is a practical interest in emulating standard
-associative containers by means of multi_index_container, namely to take
-advantage of extended functionalities provided by multi_index_container for
-lookup, range querying and updating.
-
-In order to emulate a std::set one can follow the substitution
-rule:
-
- --std::set<Key,Compare,Allocator> -> - multi_index_container< - Key, - indexed_by<ordered_unique<identity<Key>,Compare> >, - Allocator - > -
-In the default case where Compare=std::less<Key> and
-Allocator=std::allocator<Key>, the substitution rule is
-simplified as
-
- --std::set<Key> -> multi_index_container<Key> -
-The substitution of multi_index_container for std::set keeps
-the whole set of functionality provided by std::set, so in
-principle it is a drop-in replacement needing no further adjustments.
-
-std::multiset can be emulated in a similar manner, according to the
-following rule:
-
- --std::multiset<Key,Compare,Allocator> -> - multi_index_container< - Key, - indexed_by<ordered_non_unique<identity<Key>,Compare> >, - Allocator - > -
-When default values are taken into consideration, the rule takes the form -
- -- --std::multiset<Key> -> - multi_index_container< - Key, - indexed_by<ordered_non_unique<identity<Key> > > - > -
-The emulation of std::multisets with multi_index_container
-results in a slight difference with respect to the interface offered: the member
-function insert(const value_type&) does not return an
-iterator as in std::multisets, but rather a
-std::pair<iterator,bool> in the spirit of std::sets.
-In this particular case, however, the bool member of the returned
-pair is always true.
-
-The case of std::maps and std::multimaps does not lend
-itself to such a direct emulation by means of multi_index_container. The main
-problem lies in the fact that elements of a multi_index_container are treated
-as constant, while the std::map and std::multimap handle
-objects of type std::pair<const Key,T>, thus allowing for free
-modification of the value part. To overcome this difficulty we need to create an ad
-hoc pair class:
-
- --template <typename T1,typename T2> -struct mutable_pair -{ - typedef T1 first_type; - typedef T2 second_type; - - mutable_pair():first(T1()),second(T2()){} - mutable_pair(const T1& f,const T2& s):first(f),second(s){} - mutable_pair(const std::pair<T1,T2>& p):first(p.first),second(p.second){} - - T1 first; - mutable T2 second; -}; -
-and so the substitution rules are: -
- -- --std::map<Key,T,Compare,Allocator> -> - multi_index_container< - Element, - indexed_by< - ordered_unique<member<Element,Key,&Element::first>,Compare> - >, - typename Allocator::template rebind<Element>::other - > - -std::multimap<Key,T,Compare,Allocator> -> - multi_index_container< - Element, - indexed_by< - ordered_non_unique<member<Element,Key,&Element::first>,Compare> - >, - typename Allocator::template rebind<Element>::other - > - -(with Element=mutable_pair<Key,T>) -
-If default values are considered, the rules take the form: -
- -- --std::map<Key,T> -> - multi_index_container< - Element, - indexed_by<ordered_unique<member<Element,Key,&Element::first> > > - > - -std::multimap<Key,T> -> - multi_index_container< - Element, - indexed_by<ordered_non_unique<member<Element,Key,&Element::first> > > - > - -(with Element=mutable_pair<Key,T>) -
-Unlike as with standard sets, the interface of these multi_index_container-emulated
-maps does not exactly conform to that of std::maps and
-std::multimaps. The most obvious difference is the lack of
-operator [], either in read or write mode; this, however, can be
-emulated with appropriate use of find and insert.
-
-These emulations of standard associative containers with multi_index_container
-are comparable to the original constructs in terms of space and time efficiency.
-See the performance section for further details.
-
std::list
-Unlike the case of associative containers, emulating std::list
-in Boost.MultiIndex does not add any significant functionality, so the following
-is presented merely for completeness sake.
-
-Much as with standard maps, the main difficulty to overcome when emulating
-std::list derives from the constant nature of elements of a
-multi_index_container. Again, some sort of adaption class is needed, like
-for instance the following:
-
- --template <typename T> -struct mutable_value -{ - mutable_value(const T& t):t(t){} - operator T&()const{return t;} - -private: - mutable T t; -}; -
-which allows us to use the substitution rule: -
- -- --std::list<T,Allocator> -> - multi_index_container< - Element, - indexed_by<sequenced<> >, - typename Allocator::template rebind<Element>::other - > - -(with Element=mutable_value<T>) -
-or, if the default value Allocator=std::allocator<T> is used:
-
- --std::list<T> -> - multi_index_container<mutable_value<T>,indexed_by<sequenced<> > > -
multi_index_container
-Boost.MultiIndex provides a number of facilities intended to allow the analysis and
-synthesis of multi_index_container instantiations by
-MPL metaprograms.
-
-Given a multi_index_container instantiation, the following nested types are
-provided for compile-time inspection of the various types occurring in the
-definition of the multi_index_container:
-
index_specifier_type_list,index_type_list,iterator_type_list,const_iterator_type_list.multi_index_container: for instance, the n-th
-element of iterator_type_list is the same as
-nth_index_iterator<n>::type.
-
-
-
-A subtle but important distinction exists between
-index_specifier_type_list and index_type_list:
-the former typelist holds the index specifiers
-with which the multi_index_container instantiation was defined,
-while the latter gives access to the actual implementation classes
-corresponding to each specifier. An example will help to clarify
-this distinction. Given the instantiation:
-
- --typedef multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - sequenced<> - > -> indexed_t; -
-indexed_t::index_specifier_type_list is a type list with
-elements
-
- --ordered_unique<identity<int> > -sequenced<> -
-while indexed_t::index_type_list holds the types
-
- --multi_index_container::nth_type<0>::type -multi_index_container::nth_type<1>::type -
-so the typelists are radically different. Check the -reference -for the exact MPL sequence concepts modeled by these type lists. -
- -
-Although typically indices are specified by means of the
-indexed_by construct, actually any MPL sequence of
-index specifiers can be provided instead:
-
- --typedef mpl::vector<ordered_unique<identity<int> >,sequenced<> > index_list_t; - -typedef multi_index_container< - int, - index_list_t -> indexed_t; -
-This possibility enables the synthesis of instantiations of
-multi_index_container through MPL metaprograms, as the following
-example shows:
-
- --// original multi_index_container instantiation -typedef multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> > - > -> indexed_t1; - -// we take its index list and add an index -typedef boost::mpl::push_front< - indexed_t1::index_specifier_type_list, - sequenced<> ->::type index_list_t; - -// augmented multi_index_container -typedef multi_index_container< - int, - index_list_t -> indexed_t2; -
Revised August 24th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/compiler_specifics.html b/doc/compiler_specifics.html deleted file mode 100644 index 306907e..0000000 --- a/doc/compiler_specifics.html +++ /dev/null @@ -1,941 +0,0 @@ - - - - - -
Boost.MultiIndex Compiler specifics-Boost.MultiIndex has been tried in different compilers, with -various degrees of success. We list the limitations encountered, -along with suitable workarounds when available. -
- --Currently, Boost.MultiIndex cannot be used with BCB 6.4. The -number of problems encountered during the tests makes it unlikely that -future versions of the library can be made to work under -this compiler. -
- --No problems have been detected with this compiler. The library fails to compile, -however, when Microsoft Visual C++ 6.0 is used as the backend. -
- --No problems have been detected with this compiler. -
- --No problems have been detected with several versions of this compiler -starting from 3.2. The following versions have been explicitly tested: -
-On this platform, GCC is not able to handle debug symbol names whose length
-exceeds 32,768 bytes, resulting in the error mips-tfile, ... string
-too big. You may encounter this issue with heavily templatized
-code like Boost.MultiIndex, which typically produces long symbol names. The problem
-can be overcome by omitting the compiler option -g (generate debugging
-information.) Alternatively, consult the section on
-reduction of symbol name lengths for various
-applicable workarounds.
-
-Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and -prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces -a regression bug -related to binding of references to temporary objects. This bug precludes the -usage of Boost.MultiIndex -invariant-checking mode; other -than this, Boost.MultiIndex works correctly. -The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official -release of GNU GCC 4.0.0, so the invariant-checking mode is available from this -upgrade. -
- --No problems have been detected with this compiler. -
- -
-member not supported,
-refer to the section on
-use of member_offset for workarounds.
-member_offset causes the compiler to emit warnings about the
-use of offsetof with non-POD types: these warnings can be suppressed
-by setting the compiler option -qsuppress=1540-1281, or, alternatively,
-by inserting the following preprocessor directive:
-
- --#pragma info(nolan) -
-This latter pragma, however, may also eliminate other warnings not related
-to the use of offsetof.
-
- -
-Serialization capabilities are not available as Boost.Serialization is not -supported on this platform. -
- --No problems have been detected with these compilers. -
- --No problems have been detected with this compiler. -
- -
-member not supported,
-refer to the section on
-use of member_offset for workarounds.
-
- -
-When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
-disabled by default. This will cause problems with many Boost libraries,
-and in particular with the serialization part of Boost.MultiIndex.
-Argument dependent lookup is enabled by adding
-/Qoption,c,--arg_dep_lookup to the project options.
-
-Boost.MultiIndex works for this configuration. The same limitations apply as -in Intel C++ 7.1 with its original Dinkumware standard library. STLport 4.6.2 has -also been confirmed to work correctly. -
- -
-When used on top of MSVC++ 7.0 or prior, argument dependent lookup is
-disabled by default. This will cause problems with many Boost libraries,
-and in particular with the serialization part of Boost.MultiIndex.
-Argument dependent lookup is enabled by adding
-/Qoption,c,--arg_dep_lookup to the project options.
-Other than this, Boost.MultiIndex works without problems.
-
-Boost.MultiIndex works correctly with versions of this compiler from 8.3 to -9.5, under the two operating systems tested: Mac OS and Windows. -
- -
-member not supported,
-refer to the section on
-use of member_offset for workarounds.
-
-const_mem_fun and
-mem_fun
-not supported, refer to the section on
-use of const_mem_fun_explicit and
-mem_fun_explicit for workarounds.
-
- -
-No support for index retrieval -and projection -nested types and member functions: -
nth_index,index,nth_index_iterator,nth_index_const_iterator,index_iterator,index_const_iterator,get,project.::boost::multi_index.
-
-
-- -
-boost::multi_index::multi_index_container is imported to
-namespace boost by means of a using declaration.
-MSVC++ 6.0, however, does not properly handle this import. So, instead of
-writing:
-
- --boost::multi_index_container<...> -
-use the following: -
- -- --boost::multi_index::multi_index_container<...> -
-or else resort to a directive using namespace boost::multi_index.
-
- -
-The lack of partial template specialization support in MSVC++ 6.0
-results in some inconveniences when using composite_key that
-can be remedied as explained in
-"composite_key
-in compilers without partial template specialization".
-
- -
-MSVC++ 6.0 presents serious limitations for the maximum length of
-symbol names generated by the compiler, which might result in the
-linker error
-LNK1179:
-invalid or corrupt file: duplicate comdat
-comdat. To overcome this problem, consult the section on
-reduction of symbol name lengths for various
-applicable workarounds.
-
- -
-Under some circumstances, the compiler emits the error
-
-C2587: '_U' : illegal use of local variable as
-default parameter, inside the MSVC internal header
-<xlocnum>.
-This problem is a recurrent bug of the compiler, and has been reported in
-other unrelated libraries, like the
-Boost Graph Library,
-Boost.MultiArray,
-Boost.Regex,
-CGAL and
-MySQL++.
-The error is triggered, though not in a systematic manner, by the use
-of multi_index_container iterator constructor. Two workarounds exist:
-the first consists of avoiding this constructor and replacing
-code like:
-
- --multi_index_container<...> s(c.begin(),c.end()); -
-with equivalent operations: -
- -- --multi_index_container<...> s; -s.insert(c.begin(),c.end()); -
-The second workaround has not been confirmed by the author, but it is given
-on the Internet in connection with this error appearing in other libraries.
-Replace line 84 of <xlocnum>
-
-
- -- #define _VIRTUAL virtual -
-with the following: -
- -- -- #define _VIRTUAL -
-Warning: it is not known whether this
-replacement can result in unexpected side effects in code implicitly
-using <xlocnum>.
-
- -
-In general, the extensive use of templates by Boost.MultiIndex puts this compiler -under severe stress, so that several internal limitations may be reached. -The following measures can help alleviate these problems: -
/Zm (Specify Memory Allocation Limit)
- to increase the amount of memory available for compilation. Usual values for
- this option range from 300 to 800./ZI (Program Database for
- Edit and Continue) to a less demanding type of debugging information
- (/Zi, /Z7 or /Zd.)C1055: compiler limit : out of keys, try
- disabling the option /Gm (Enable Minimal Rebuild.) In these
- cases, it is also beneficial to split the project into smaller
- subprojects.-Boost.MultiIndex works for this configuration. The same limitations apply as -in MSVC++ 6.0 with its original Dinkumware standard library. STLport 4.6.2 has -also been confirmed to work correctly. -
- -- -
-It is not possible to use the serialization capabilities of Boost.MultiIndex -along with the dynamic version of STLport, as some linking errors result. -Use instead the static version of STLport. This bug is reportedly fixed in -STLport 5.0 (in beta stage as of this writing.) -
- -
-member not supported,
-refer to the section on
-use of member_offset for workarounds.
-
- -
-No support for index retrieval -and projection -nested types and member functions: -
nth_index,index,nth_index_iterator,nth_index_const_iterator,index_iterator,index_const_iterator,get,project.::boost::multi_index.
-
-
-- -
-boost::multi_index::multi_index_container is imported to
-namespace boost by means of a using declaration.
-MSVC++ 7.0, however, does not properly handle this import. So, instead of
-writing:
-
- --boost::multi_index_container<...> -
-use the following: -
- -- --boost::multi_index::multi_index_container<...> -
-or else resort to a directive using namespace boost::multi_index.
-
- -
-The lack of partial template specialization support in MSVC++ 7.0
-results in some inconveniences when using composite_key that
-can be remedied as explained in
-"composite_key
-in compilers without partial template specialization".
-
-Problems have been reported when compiling the library with the /Gm
-option (Enable Minimal Rebuild.) Seemingly, this is due to an
-internal defect of the compiler (see for instance
-
-this mention of a similar issue in the Boost Users mailing list.)
-If /Gm is turned off, Boost.MultiIndex compiles and runs
-without further problems.
-
-No problems have been detected with this compiler. The Beta 2 version of -this product was used for the testing. -
- -member_offset
-The member key extractor poses some problems in compilers
-that do not properly support pointers to members as non-type
-template arguments, as indicated by the
-Boost Configuration Library
-defect macro BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS.
-The following compilers have been confirmed not
-to work correctly with member:
-
- --#include <iostream> - -struct pair -{ - int x,y; - - pair(int x_,int y_):x(x_),y(y_){} -}; - -template<int pair::* PtrToPairMember> -struct foo -{ - int bar(pair& p){return p.*PtrToPairMember;} -}; - -int main() -{ - pair p(0,1); - foo<&pair::x> fx; - foo<&pair::y> fy; - - if(fx.bar(p)!=0||fy.bar(p)!=1)std::cout<<"KO"<<std::endl; - else std::cout<<"OK"<<std::endl; - - return 0; -} - -
-If you find a compiler that does not pass the test, and for which
-BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is not defined,
-please report to the Boost developers mailing list.
-
To overcome this defect, a replacement utility
-member_offset
-has been provided that does the work of member at the
-expense of less convenient notation and the possibility of
-non-conformance with the standard. Please consult
-the reference for further information on member_offset.
-As an example of use, given the class
-
- --class A -{ - int x; -} -
-the instantiation member<A,int,&A::x> can be simulated then
-as member_offset<A,int,offsetof(A,x)>.
-
-For those writing portable code, Boost.MultiIndex provides the ternary macro
-BOOST_MULTI_INDEX_MEMBER.
-Continuing with the example above, the
-expression
-
- --BOOST_MULTI_INDEX_MEMBER(A,int,x) -
-expands by default to -
- -- --member<A,int,&A::x> -
-or alternatively to -
- -- --member_offset<A,int,offsetof(A,x)> -
-if BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined.
-
const_mem_fun_explicit and
-mem_fun_explicit
-MSVC++ 6.0 has problems with const member functions as non-type
-template parameters, and thus does not accept the const_mem_fun
-key extractor. A simple workaround, fortunately, has been found, consisting
-in specifying the type of these pointers as an additional template
-parameter. The alternative
-const_mem_fun_explicit
-extractor adopts this solution; for instance, given the type
-
- --struct A -{ - int f()const; -}; -
-the extractor const_mem_fun<A,int,&A::f> can be replaced by
-const_mem_fun_explicit<A,int,int (A::*)()const,&A::f>. A similar
-mem_fun_explicit class template is provided for non-constant
-member functions.
-
-If you are writing cross-platform code, the selection of either key extractor
-is transparently handled by the macro
-BOOST_MULTI_INDEX_CONST_MEM_FUN,
-so that
-
- --BOOST_MULTI_INDEX_CONST_MEM_FUN(A,int,f) -
-expands by default to -
- -- --const_mem_fun<A,int,&A::f> -
-but resolves to -
- -- --const_mem_fun_explicit<A,int,int (A::*)()const,&A::f> -
-in MSVC++ 6.0. Non-const member functions are covered by
-mem_fun_explicit
-and the macro
-BOOST_MULTI_INDEX_MEM_FUN.
-
composite_key in compilers
-without partial template specialization
-When using composite_keys, lookup is performed by passing
-tuples of values: this ability is achieved by suitably specializing
-the class templates std::equal_to, std::less,
-std::greater and boost::hash for
-
-composite_key_result instantiations so that they
-provide the appropriate overloads accepting tuples --and in the case
-of std::less and std::greater, also partial
-tuples where only the first components are specified.
-
-In those compilers that do not support partial template specialization,
-these specializations cannot be provided, and so
-tuple-based lookup is not available by default. In this case,
-multi_index_container instantiations using composite keys
-will work as expected, both for ordered and hashed indices,
-except that lookup operations will not accept tuples as an argument.
-For ordered indices, the most obvious workaround
-to this deficiency involves explicitly specifying the comparison
-predicate with
-composite_key_compare;
-in the case of hashed indices we can use the analogous
-composite_key_equal_to
-and
-composite_key_hash.
-This substitution is tedious as the elementary components for all the constituent key extractors must
-be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement
-class templates
-
composite_key_result_equal_to,composite_key_result_less,composite_key_result_greater andcomposite_key_result_hash,std::equal_to, std::less,
-std::greater and boost::hash for composite_key_results.
-They can be used as follows:
-
-
-- --typedef composite_key< - phonebook_entry, - member<phonebook_entry,std::string,&phonebook_entry::family_name>, - member<phonebook_entry,std::string,&phonebook_entry::given_name> -> ckey_t; - -typedef multi_index_container< - phonebook_entry, - indexed_by< - ordered_non_unique< - ckey_t, - // composite_key_result_less plays the role of - // std::less<ckey_t::result_type> - composite_key_result_less<ckey_t::result_type> - >, - ordered_unique< - member<phonebook_entry,std::string,&phonebook_entry::phone_number> - > - > -> phonebook; -
-The types generated on the instantiations of multi_index_containers
-typically produce very long symbol names, sometimes beyond the internal limits
-of some compilers. There are several techniques to shorten generated symbol
-names: these techniques have also the beneficial side effect that resulting error
-messages are more readable.
-
-The class templates indexed_by,
-tag and
-composite_key
-accept a variable number of arguments whose maximum number is limited by
-internal macros. Even non-used arguments contribute to the final types,
-so manually adjusting the corresponding macros can result in a modest reduction
-of symbol names.
-
-
| class template | -limiting macro | -default value | -default value (MSVC++ 6.0) |
-
|---|---|---|---|
indexed_by |
- BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE |
- 20 | -5 | -
tag |
- BOOST_MULTI_INDEX_LIMIT_TAG_SIZE |
- 20 | -3 | -
composite_key |
- BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE |
- 10 | -5 | -
-Consider a typical instantiation of multi_index_container:
-
- --typedef multi_index_container< - employee, - indexed_by< - ordered_unique<identity<employee> >, - ordered_non_unique<member<employee,std::string,&employee::name> >, - ordered_unique<member<employee,int,&employee::ssnumber> > - > -> employee_set; -
-Then, for instance, the type employee_set::nth_type<0>::type
-resolves to the following in GCC:
-
- --boost::multi_index::detail::ordered_index< - boost::multi_index::identity<employee>, - std::less<employee>, - boost::multi_index::detail::nth_layer< - 1, employee, - boost::multi_index::indexed_by< - boost::multi_index::ordered_unique< - boost::multi_index::identity<employee>, mpl_::na, mpl_::na - >, - boost::multi_index::ordered_non_unique< - boost::multi_index::member<employee, std::string, &employee::name>, - mpl_::na, mpl_::na - >, - boost::multi_index::ordered_unique< - boost::multi_index::member<employee, int, &employee::ssnumber>, - mpl_::na, mpl_::na - >, - mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, - mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, - mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na - >, - std::allocator<employee> - >, - boost::mpl::vector0<mpl_::na>, - boost::multi_index::detail::ordered_unique_tag -> -
-It can be seen that a significant portion of the type name is contributed by
-the indexed_by<...> part, which is nothing but an expanded
-version of the index specifier list provided in the definition of
-employee_set. We can prevent this very long name from appearing
-in the final type by encapsulating it into another, shorter-named construct:
-
- --// reducing symbol names through type hiding -// type hide the index spexifier list within employee_set_indices - -struct employee_set_indices: - indexed_by< - ordered_unique<identity<employee> >, - ordered_non_unique<member<employee,std::string,&employee::name> >, - ordered_unique<member<employee,int,&employee::ssnumber> > - > -{}; - -typedef multi_index_container< - employee, - employee_set_indices -> employee_set; -
-employee_set_indices works as a conventional typedef
-in all respects, save for a detail: its name does not explicitly
-include the information contained in the indexed_by instantiation.
-Applying this technique, employee_set::nth_type<0>::type
-now becomes:
-
- --boost::multi_index::detail::ordered_index< - boost::multi_index::identity<employee>, - std::less<employee>, - boost::multi_index::detail::nth_layer< - 1, employee, - employee_set_indices, - std::allocator<employee> - >, - boost::mpl::vector0<mpl_::na>, - boost::multi_index::detail::ordered_unique_tag -> -
-which is considerably shorter than the original, and also more
-easily parsed by a human reader. Type hiding would not work if, instead of
-making employee_set_indices a derived struct of
-indexed_by<...>, we had defined it as a typedef:
-typedefs are syntactic aliases and usually get expanded
-by the compiler before doing any further type handling.
-
-Type hiding techniques can also be applied to composite_key intantiations,
-which often contribute a great deal to symbol name lengths.
-
Revised July 26th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/examples.html b/doc/examples.html deleted file mode 100644 index 019a0ff..0000000 --- a/doc/examples.html +++ /dev/null @@ -1,360 +0,0 @@ - - - - - -
Boost.MultiIndex Examplesmulti_index_containers
- with ctor_args_list-See source code. -
- -
-Basic program showing the multi-indexing capabilities of Boost.MultiIndex
-with an admittedly boring set of employee records.
-
-See source code. -
- -
-Usually keys assigned to an index are based on a member variable of the
-element, but key extractors can be defined which take their value from
-a member function. This has some similarity with the concept of
-calculated keys supported by some relational database engines.
-The example shows how to use the predefined const_mem_fun
-key extractor to deal with this situation.
-
-Keys based on member functions usually will not be actual references,
-but rather the temporary values resulting from the invocation of the
-member function used. This implies that modify_key cannot be
-applied to this type of extractors, which is a perfectly logical
-constraint anyway.
-
multi_index_containers
-with ctor_args_list-See source code. -
- -
-We show a practical example of usage of multi_index_container::ctor_arg_list,
-whose definition and purpose are explained in the
-Advanced topics section. The
-program groups a sorted collection of numbers based on identification through
-modulo arithmetics, by which x and y are equivalent
-if (x%n)==(y%n), for some fixed n.
-
-See source code. -
- -
-This example shows how to construct a bidirectional map with
-multi_index_container. By a bidirectional map we mean
-a container of elements of std::pair<const FromType,const ToType>
-such that no two elements exists with the same first
-or second value (std::map only
-guarantees uniqueness of the first member). Fast lookup is provided
-for both keys. The program features a tiny Spanish-English
-dictionary with online query of words in both languages.
-
-See source code. -
- -
-The combination of a sequenced index with an index of type ordered_non_unique
-yields a list-like structure with fast lookup capabilities. The
-example performs some operations on a given text, like word counting and
-selective deletion of some words.
-
-See source code. -
- -
-This program illustrates some advanced techniques that can be applied
-for complex data structures using multi_index_container.
-Consider a car_model class for storing information
-about automobiles. On a first approach, car_model can
-be defined as:
-
- --struct car_model -{ - std::string model; - std::string manufacturer; - int price; -}; -
-This definition has a design flaw that any reader acquainted with
-relational databases can easily spot: The manufacturer
-member is duplicated among all cars having the same manufacturer.
-This is a waste of space and poses difficulties when, for instance,
-the name of a manufacturer has to be changed. Following the usual
-principles in relational database design, the appropriate design
-involves having the manufactures stored in a separate
-multi_index_container and store pointers to these in
-car_model:
-
- --struct car_manufacturer -{ - std::string name; -}; - -struct car_model -{ - std::string model; - car_manufacturer* manufacturer; - int price; -}; -
-Although predefined Boost.MultiIndex key extractors can handle many -situations involving pointers (see -advanced features -of Boost.MultiIndex key extractors in the Advanced topics section), this case -is complex enough that a suitable key extractor has to be defined. The following -utility cascades two key extractors: -
- -- --template<class KeyExtractor1,class KeyExtractor2> -struct key_from_key -{ -public: - typedef typename KeyExtractor1::result_type result_type; - - key_from_key( - const KeyExtractor1& key1_=KeyExtractor1(), - const KeyExtractor2& key2_=KeyExtractor2()): - key1(key1_),key2(key2_) - {} - - template<typename Arg> - result_type operator()(Arg& arg)const - { - return key1(key2(arg)); - } - -private: - KeyExtractor1 key1; - KeyExtractor2 key2; -}; -
-so that access from a car_model to the name field
-of its associated car_manufacturer can be accomplished with
-
- --key_from_key< - member<car_manufacturer,const std::string,&car_manufacturer::name>, - member<car_model,const car_manufacturer *,car_model::manufacturer> -> -
-The program asks the user for a car manufacturer and a range of prices -and returns the car models satisfying these requirements. This is a complex -search that cannot be performed on a single operation. Broadly sketched, -one procedure for executing the selection is: -
equal_range,
- multi_index_container sorted
- by price,
- lower_bound and
- upper_bound;
-lower_bound and upper_bound,
- multi_index_container sorted
- by manufacturer,
- equal_range.
-multi_index_container.
-In order to avoid object copying, appropriate view types
-are defined with multi_index_containers having as elements
-pointers to car_models instead of actual objects.
-These views have to be supplemented with appropriate
-dereferencing key extractors.
-
-
--See source code. -
- -
-Boost.MultiIndex
-composite_key construct provides a flexible tool for
-creating indices with non-trivial sorting criteria.
-The program features a rudimentary simulation of a file system
-along with an interactive Unix-like shell. A file entry is represented by
-the following structure:
-
- --struct file_entry -{ - std::string name; - unsigned size; - bool is_dir; // true if the entry is a directory - const file_entry* dir; // directory this entry belongs in -}; -
-Entries are kept in a multi_index_container maintaining two indices
-with composite keys:
-
ls. The shell simulation only has three
-commands:
-cd [.|..|<directory>]ls [-s] (-s orders the output by size)mkdir <directory>-The reader is challenged to add more functionality to the program; for -instance: -
cp.-See source code. -
- --Hashed indices can be used as an alternative to ordered indices when -fast lookup is needed and sorting information is of no interest. The -example features a word counter where duplicate entries are checked -by means of a hashed index. Confront the word counting algorithm with -that of example 5. -
- --See source code. -
- -
-A typical application of serialization capabilities allows a program to
-restore the user context between executions. The example program asks
-the user for words and keeps a record of the ten most recently entered
-ones, in the current or in previous sessions. The serialized data structure,
-sometimes called an MRU (most recently used) list, has some interest
-on its own: an MRU list behaves as a regular FIFO queue, with the exception
-that, when inserting a preexistent entry, this does not appear twice, but
-instead the entry is moved to the front of the list. You can observe this
-behavior in many programs featuring a "Recent files" menu command. This
-data structure is implemented with multi_index_container by
-combining a sequenced index and an index of type hashed_unique.
-
Revised August 22nd 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/future_work.html b/doc/future_work.html deleted file mode 100644 index affb878..0000000 --- a/doc/future_work.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - -
Boost.MultiIndex Future work
-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.
-
-Ordered indices are implemented using red-black trees; these trees
-can be augmented with additional information to obtain a type
-of data structure called
-order-statistics
-trees, allowing for logarithmic search of the n-th element. It
-has been proposed that order-statistics trees be used to devise a new type of
-ranked indices that support operator[] while retaining
-the functionality of ordered indices.
-
-These indices provide random access iterators and location of elements
-by their position ordinal. Although they seem at first glance to model
-the semantics of std::vector, random access indices present
-important differences:
-
std::sort) will in general
- not work with random access indices, as elements of a
- multi_index_container cannot be directly moved or swapped;-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.
-
-Example 4 in the examples section
-features a bidirectional map, implemented as a
-multi_index_container with two unique ordered indices. This particular
-structure is deemed important enough as to provide it as a separate
-class template, relying internally in multi_index_container. As
-feedback is collected from the users of Boost.MultiIndex, other singular
-instantiations of multi_index_container might be encapsulated
-to form a component library of ready to use containers.
-
-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.
-
-Andrei Alexandrescu introduced a technique for simulating move
-constructors called Mojo (see his article in C/C++ User Journal
-
-"Generic<Programming>: Move Constructors".) Move semantics
-alleviates the computational load involved in the creation and copying
-of temporary objects, specially for heavy classes as
-multi_index_containers are. David Abrahams and Gary Powell provide
-an alternative implementation of move semantics in their paper
-
-"Clarification of Initialization of Class Objects by rvalues" for
-the C++ Evolution Working Group.
-
-Adding move semantics to multi_index_container is particularly
-beneficial when the container is used as an internal building block in other
-libraries (vg. relational database frameworks), enabling the efficient
-development of functions returning multi_index_containers. Without support
-for move semantics, this scheme is impractical and less elegant syntaxes
-should be resorted to.
-
Revised July 5th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 4265896..0000000 --- a/doc/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - -
Boost Multi-index Containers Library
-The Boost Multi-index Containers Library provides a class template named
-multi_index_container which enables the construction of containers
-maintaining one or more indices with different sorting and access semantics.
-Indices provide interfaces similar to those of STL containers, making using them
-familiar. The concept of multi-indexing over the same collection of elements is
-borrowed from relational database terminology and allows for the specification of
-complex data structures in the spirit of multiply indexed relational tables where
-simple sets and maps are not enough. A wide selection of indices is provided,
-modeled after analogous STL containers like std::set,
-std::list and hashed sets.
-
-Boost.MultiIndex features additional functionalities, like subobject searching,
-range querying and in-place updating of elements, which make it a convenient replacement
-for std::set and set::multiset even when no multi-indexing
-capabilities are needed.
-
-The versatile nature of Boost.MultiIndex allows for the specification of -a wide spectrum of different data structures. The following are possible -examples of use developed in the documentation: -
Revised March 15th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/lopez.jpg b/doc/lopez.jpg deleted file mode 100644 index ac37b4a..0000000 Binary files a/doc/lopez.jpg and /dev/null differ diff --git a/doc/multi_index_cont_example.png b/doc/multi_index_cont_example.png deleted file mode 100644 index 120cfdd..0000000 Binary files a/doc/multi_index_cont_example.png and /dev/null differ diff --git a/doc/next.gif b/doc/next.gif deleted file mode 100644 index d6c18a5..0000000 Binary files a/doc/next.gif and /dev/null differ diff --git a/doc/perf_1o.png b/doc/perf_1o.png deleted file mode 100644 index 061c8ec..0000000 Binary files a/doc/perf_1o.png and /dev/null differ diff --git a/doc/perf_1o1s.png b/doc/perf_1o1s.png deleted file mode 100644 index 4408092..0000000 Binary files a/doc/perf_1o1s.png and /dev/null differ diff --git a/doc/perf_1s.png b/doc/perf_1s.png deleted file mode 100644 index d76c2bb..0000000 Binary files a/doc/perf_1s.png and /dev/null differ diff --git a/doc/perf_2o.png b/doc/perf_2o.png deleted file mode 100644 index eeb820b..0000000 Binary files a/doc/perf_2o.png and /dev/null differ diff --git a/doc/perf_2o1s.png b/doc/perf_2o1s.png deleted file mode 100644 index e25371f..0000000 Binary files a/doc/perf_2o1s.png and /dev/null differ diff --git a/doc/perf_3o.png b/doc/perf_3o.png deleted file mode 100644 index 198d363..0000000 Binary files a/doc/perf_3o.png and /dev/null differ diff --git a/doc/performance.html b/doc/performance.html deleted file mode 100644 index 34bc036..0000000 --- a/doc/performance.html +++ /dev/null @@ -1,724 +0,0 @@ - - - - - -
Boost.MultiIndex Performancemulti_index_container
-Boost.MultiIndex helps the programmer to avoid the manual construction of cumbersome
-compositions of containers when multi-indexing capabilities are needed. Furthermore,
-it does so in an efficient manner, both in terms of space and time consumption. The
-space savings stem from the compact representation of the underlying data structures,
-requiring a single node per element. As for time efficiency, Boost.MultiIndex
-intensively uses metaprogramming techniques producing very tight implementations
-of member functions which take care of the elementary operations for each index:
-for multi_index_containers with two or more indices, the running time
-can be reduced to half as long as with manual simulations involving several
-STL containers.
-
multi_index_container
-The section on emulation
-of standard containers with multi_index_container shows the equivalence
-between single-index multi_index_containers and some STL containers. Let us now
-concentrate on the problem of simulating a multi_index_container with two
-or more indices with a suitable combination of standard containers.
-
-Consider the following instantiation of multi_index_container:
-
- --typedef multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - ordered_non_unique<identity<int>, std::greater >, - > -> indexed_t; -
-indexed_t maintains two internal indices on elements of type
-int. In order to simulate this data structure resorting only to
-standard STL containers, one can use on a first approach the following types:
-
- --// dereferencing compare predicate -template<typename Iterator,typename Compare> -struct it_compare -{ - bool operator()(const Iterator& x,const Iterator& y)const - { - return comp(*x,*y); - } - -private: - Compare comp; -}; - -typedef std::set<int> manual_t1; // equivalent to indexed_t's index #0 -typedef std::multiset< - const int*, - it_compare< - const int*, - std::greater<int> - > -> manual_t2; // equivalent to indexed_t's index #1 -
-where manual_t1 is the "base" container that holds
-the actual elements, and manual_t2 stores pointers to
-elements of manual_t1. This scheme turns out to be quite
-inefficient, though: while insertion into the data structure is simple enough:
-
- -deletion, on the other hand, necessitates a logarithmic search, whereas --manual_t1 c1; -manual_t2 c2; - -// insert the element 5 -manual_t1::iterator=c1.insert(5).first; -c2.insert(&*t1); -
indexed_t deletes in constant time:
-
-- --// remove the element pointed to by it2 -manual_t2::iterator it2=...; -c1.erase(*it2); // watch out! performs in logarithmic time -c2.erase(it1); -
-The right approach consists of feeding the second container not with
-raw pointers, but with elements of type manual_t1::iterator:
-
- --typedef std::set<int> manual_t1; // equivalent to indexed_t's index #0 -typedef std::multiset< - manual_t1::iterator, - it_compare< - manual_t1::iterator, - std::greater<int> - > -> manual_t2; // equivalent to indexed_t's index #1 -
-Now, insertion and deletion can be performed with complexity bounds
-equivalent to those of indexed_t:
-
- --manual_t1 c1; -manual_t2 c2; - -// insert the element 5 -manual_t1::iterator=c1.insert(5).first; -c2.insert(t1); - -// remove the element pointed to by it2 -manual_t2::iterator it2=...; -c1.erase(*it2); // OK: constant time -c2.erase(it1); -
-The construction can be extended in a straightworward manner to
-handle more than two indices. In what follows, we will compare
-instantiations of multi_index_container against this sort of
-manual simulations.
-
-The gain in space consumption of multi_index_container with
-respect to its manual simulations is amenable to a very simple
-theoretical analysis. For simplicity, we will ignore alignment
-issues (which in general play in favor of multi_index_container.)
-
-Nodes of a multi_index_container with N indices hold the value
-of the element plus N headers containing linking information for
-each index. Thus the node size is
-
-SI = e + h0 + ··· + -hN-1, where- -
-e = size of the element,
-hi = size of the i-th header. -
-On the other hand, the manual simulation allocates N nodes per -element, the first holding the elements themselves and the rest -storing iterators to the "base" container. In practice, an iterator -merely holds a raw pointer to the node it is associated to, so its size -is independent of the type of the elements. Suming all contributions, -the space allocated per element in a manual simulation is -
- --SM = (e + h0) + -(p + h1) + ··· + -(p + hN-1) = -SI + (N-1)p, where- -
-p = size of a pointer.
-
-The relative amount of memory taken up by multi_index_container
-with respect to its manual simulation is just
-SI / SM, which can be expressed
-then as:
-
-SI / SM = -SI / (SI + (N-1)p). -- -
-The formula shows that multi_index_container is more efficient
-with regard to memory consumption as the number of indices grow.
-
-These considerations have overlooked an aspect of the greatest practical
-importance: the fact that multi_index_container allocates a single
-node per element, compared to the many nodes of different sizes
-built by manual simulations, diminishes memory fragmentation, which
-can show up in more usable memory available and better performance.
-
-From the point of view of computational complexity (i.e. big-O
-characterization), multi_index_container and its corresponding manual
-simulations are equivalent: inserting an element into
-a multi_index_container reduces to a simple combination of
-elementary insertion operations on each of the indices, and
-similarly for deletion. Hence, the most we can expect is a reduction
-(or increase) of execution time by a roughly constant factor. As we
-will see later, the reduction can be very significative for
-multi_index_containers with two or more indices.
-
In the special case of multi_index_containers with only one index,
-the best we can hope for is equal performance: the tests show that the
-performance degradation in this particular situation ranges from negligible
-to small, depending on the compiler used.
-
-See source code used for measurements. -
-In order to assess the efficiency of multi_index_container, the following
-basic algorithm
-
- --multi_index_container<...> c; -for(int i=0;i<n;++i)c.insert(i); -for(iterator it=c.begin();it!=c.end();)c.erase(it++); -
-has been measured for different instantiations of multi_index_container
-at values of n 1,000, 10,000 and 100,000,
-and its execution time compared with that of the equivalent algorithm
-for the corresponding manual simulation of the data structure based on
-STL containers. The following compilers have been used:
-
-The relative memory consumption (i.e. the amount of memory allocated
-by a multi_index_container with respect to its manual simulation)
-is determined by dividing the size of a multi_index_container node
-by the sum of node sizes of all the containers integrating the
-simulating data structure.
-
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> > - > -> -
-which is functionally equivalent to std::set<int>.
-
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 100% | -100% | -100% | -
multi_index_container with 1
-ordered index.
-
-
-
-The figures confirm that in this case multi_index_container nodes are the
-same size than those of its std::set counterpart.
-
-
-Fig. 1: Performance of multi_index_container with 1 ordered index.
-
-As expected, multi_index_container does perform in this case somewhat
-worse than std::set. The degradation is within 10% for ICC and
-MSVC compilers, while in GCC peaks to 20%, which can be significative
-in certain applications. This latter result is presumably accounted for by
-a lower quality of the optimizing stage carried out by GCC.
-
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - sequenced<> - > -> -
-which is functionally equivalent to std::list<int>.
-
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 100% | -100% | -100% | -
multi_index_container with 1
-sequenced index.
-
-
-
-The figures confirm that in this case multi_index_container nodes are the
-same size than those of its std::list counterpart.
-
-
-Fig. 2: Performance of multi_index_container with 1 sequenced index.
-
-As in the former case, multi_index_container does not attain the performance
-of its STL counterpart. Again, worst results are those of GCC, with a
-degradation of up to 20% , while ICC and MSVC do not exceed a mere 5%.
-
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - ordered_non_unique<identity<int> > - > -> -
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 90% | -90% | -90% | -
multi_index_container with 2
-ordered indices.
-
-
--These results concinde with the theoretical formula for -SI=36 and p=4. -
- -
-
-Fig. 3: Performance of multi_index_container with 2 ordered indices.
-
-The experimental results confirm our hypothesis that multi_index_container
-provides an improvement on execution time by an approximately constant factor,
-which in this case ranges from 65% to 75% depending on the compiler.
-
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - sequenced<> - > -> -
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 87.5% | -87.5% | -87.5% | -
multi_index_container with 1
-ordered index + 1 sequenced index.
-
-
--These results concinde with the theoretical formula for -SI=28 and p=4. -
- -
-
-Fig. 4: Performance of multi_index_container with 1 ordered index
-+ 1 sequenced index.
-
-For n=103 and n=104, the results
-are in agreement with our theoretical analysis, showing a constant factor
-improvement of 60-75% with respect to the STL-based manual simulation.
-Curiously enough, this speedup gets even higher when
-n=105 for two of the compilers (35% for ICC,
-25% for MSVC.) In order to rule out spurious results, the tests
-have been run many times, yielding similar outcoumes. A tentative
-explanation of this unexpected behavior may point to a degradation in
-the execution time of the manual simulation, attributable to poor
-performance of the standard STL allocator in ICC and MSVC when dealing
-with many objects of diverse sizes (the manual simulation is comprised of
-an std::set and a std::list, which demand
-differently sized nodes.)
-
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - ordered_non_unique<identity<int> >, - ordered_non_unique<identity<int> > - > -> -
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 86.7% | -86.7% | -86.7% | -
multi_index_container with 3
-ordered indices.
-
-
--These results concinde with the theoretical formula for -SI=52 and p=4. - -
- -
-
-Fig. 5: Performance of multi_index_container with 3 ordered indices.
-
-Execution time for this case is between 55% and 65% lower than achieved with -an STL-based manual simulation of the same data structure. -
- -
-The following instantiation of multi_index_container was tested:
-
- --multi_index_container< - int, - indexed_by< - ordered_unique<identity<int> >, - ordered_non_unique<identity<int> >, - sequenced<> - > -> -
-
| GCC 3.1.1 | -ICC 7.1 | -MSVC 6.5 | -
|---|---|---|
| 84.6% | -84.6% | -84.6% | -
multi_index_container with 2
-ordered indices + 1 sequenced index.
-
-
--These results concinde with the theoretical formula for -SI=44 and p=4. -
- -
-
-Fig. 6: Performance of multi_index_container with 2 ordered indices
-+ 1 sequenced index.
-
-In accordance to the expectations, execution time is improved by a fairly constant -factor, which ranges from 45% to 55%. -
- -
-We have shown that multi_index_container outperforms, both in space and
-time efficiency, equivalent data structures obtained from the manual
-combination of STL containers. This improvement gets larger when the number
-of indices increase.
-
-In the special case of replacing standard containers with single-indexed
-multi_index_containers, the programmer should balance the benefits brought on
-by Boost.MultiIndex (subobject searching, in-place updating, etc.) against the
-resulting degradation in execution time. Depending on the compiler, this degradation
-can reach up to 20% of the original time.
-
Revised May 18th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/prev.gif b/doc/prev.gif deleted file mode 100644 index c35dfee..0000000 Binary files a/doc/prev.gif and /dev/null differ diff --git a/doc/reference/hash_indices.html b/doc/reference/hash_indices.html deleted file mode 100644 index e635450..0000000 --- a/doc/reference/hash_indices.html +++ /dev/null @@ -1,904 +0,0 @@ - - - - - -
Boost.MultiIndex Hashed indices reference"boost/multi_index/hashed_index_fwd.hpp" synopsis"boost/multi_index/hashed_index.hpp" synopsis
-
- "boost/multi_index/hashed_index_fwd.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// index specifiers hashed_unique and hashed_non_unique - -template<consult hashed_unique reference for arguments> -struct hashed_unique; -template<consult hashed_non_unique reference for arguments> -struct hashed_non_unique; - -// indices - -namespace detail{ - -template<implementation defined> class index name is implementation defined; - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-hashed_index_fwd.hpp provides forward declarations for index specifiers
-hashed_unique and hashed_non_unique and
-their associated hashed index classes.
-
"boost/multi_index/hashed_index.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// index specifiers hashed_unique and hashed_non_unique - -template<consult hashed_unique reference for arguments> -struct hashed_unique; -template<consult hashed_non_unique reference for arguments> -struct hashed_non_unique; - -// indices - -namespace detail{ - -template<implementation defined> class index class name implementation defined; - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
hashed_unique and hashed_non_unique
-
-These index specifiers allow
-for insertion of hashed indices without and with
-allowance of duplicate elements, respectively. The syntax of hashed_unique
-and hashed_non_unique coincide, thus we describe them in a grouped manner.
-hashed_unique and hashed_non_unique can be instantiated in
-two different forms, according to whether a tag list for the index is provided or not:
-
- --template< - typename KeyFromValue, - typename Hash=boost::hash<KeyFromValue::result_type>, - typename Pred=std::equal_to<KeyFromValue::result_type> -> -struct (hashed_unique | hashed_non_unique); - -template< - typename TagList, - typename KeyFromValue, - typename Hash=boost::hash<KeyFromValue::result_type>, - typename Pred=std::equal_to<KeyFromValue::result_type> -> -struct (hashed_unique | hashed_non_unique); -
-If provided, TagList must be an instantiation of the class template
-tag.
-The template arguments are used by the corresponding index implementation,
-refer to the hashed indices reference section for further
-explanations on their acceptable type values.
-
-A hashed index provides fast retrieval of elements of a multi_index_container
-through hashing tecnhiques. The interface and semantics of hashed indices are modeled according
-to the proposal for unordered associative containers given in the C++
-Proposed
-Draft Tecnhical Report on Standard Library Extensions, also known as TR1. A hashed
-index is particularized according to a given
-Key Extractor
-that retrieves keys from elements of multi_index_container, a Hash
-function object which returns hash values for the keys and a binary predicate Pred
-acting as an equivalence relation on values of Key.
-
-There are two variants of hashed indices: unique, which do -not allow duplicate elements (with respect to its associated equality -predicate) and non-unique, which accept those duplicates. -The interface of these two variants is the same, so they are documented -together, with minor differences explicitly stated when they exist. -
- -
-Except where noted, hashed indices (both unique and non-unique) are models of
-Unordered Associative Container, in the spirit of
-std::tr1::unordered_sets. Validity of iterators and references to
-elements is preserved in all cases. Occasionally, the exception safety guarantees provided
-are actually stronger than required by the extension draft. We only provide descriptions
-of those types and operations that are either not present in the concepts modeled or
-do not exactly conform to the requirements for unordered associative containers.
-
- --namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template<implementation defined: dependent on types Value, Allocator, - TagList, KeyFromValue, Hash, Pred> -class name is implementation defined -{ -public: - // types: - - typedef typename KeyFromValue::result_type key_type; - typedef Value value_type; - typedef KeyFromValue key_from_value; - typedef Hash hasher; - typedef Pred key_equal; - typedef tuple< - size_type,key_from_value,hasher,key_equal> ctor_args; - typedef Allocator allocator_type; - typedef typename Allocator::pointer pointer; - typedef typename Allocator::const_pointer const_pointer; - typedef typename Allocator::reference reference; - typedef typename Allocator::const_reference const_reference; - typedef implementation defined size_type; - typedef implementation defined difference_type; - typedef implementation defined iterator; - typedef implementation defined const_iterator; - typedef implementation defined local_iterator; - typedef implementation defined const_local_iterator; - - // construct/destroy/copy: - - index class name& operator=(const index class name& x); - - allocator_type get_allocator()const; - - // size and capacity: - - bool empty()const; - size_type size()const; - size_type max_size()const; - - // iterators: - - iterator begin(); - const_iterator begin()const; - iterator end(); - const_iterator end()const; - - // modifiers: - - std::pair<iterator,bool> insert(const value_type& x); - iterator insert(iterator position,const value_type& x); - template<typename InputIterator> - void insert(InputIterator first,InputIterator last); - - iterator erase(iterator position); - size_type erase(const key_type& x); - iterator erase(iterator first,iterator last); - - bool replace(iterator position,const value_type& x); - template<typename Modifier> bool modify(iterator position,Modifier mod); - template<typename Modifier> bool modify_key(iterator position,Modifier mod); - - void clear(); - void swap(index class name& x); - - // observers: - - key_from_value key_extractor()const; - hasher hash_function()const; - key_equal key_eq()const; - - // lookup: - - template<typename CompatibleKey> - iterator find(const CompatibleKey& x)const; - template< - typename CompatibleKey,typename CompatibleHash, typename CompatiblePred - > - iterator find( - const CompatibleKey& x, - const CompatibleHash& hash,const CompatiblePred& eq)const; - - template<typename CompatibleKey> - size_type count(const CompatibleKey& x)const; - template< - typename CompatibleKey,typename CompatibleHash, typename CompatiblePred - > - size_type count( - const CompatibleKey& x, - const CompatibleHash& hash,const CompatiblePred& eq)const; - - template<typename CompatibleKey> - std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const; - template< - typename CompatibleKey,typename CompatibleHash, typename CompatiblePred - > - std::pair<iterator,iterator> equal_range( - const CompatibleKey& x, - const CompatibleHash& hash,const CompatiblePred& eq)const; - - // bucket interface: - - size_type bucket_count()const; - size_type max_bucket_count()const; - size_type bucket_size(size_type n)const; - size_type bucket(const key_type& k)const; - - local_iterator begin(size_type n); - const_local_iterator begin(size_type n)const; - local_iterator end(size_type n); - const_local_iterator end(size_type n)const; - - // hash policy: - - float load_factor()const; - float max_load_factor()const; - void max_load_factor(float z); - void rehash(size_type n); -}; - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-Here and in the descriptions of operations of hashed indices, we adopt the -scheme outlined in the -complexity signature -section. The complexity signature of hashed indices is: -
c(n)=n*log(n),i(n)=1 (constant),
- worst case i(n)=n,h(n)=1 (constant),
- worst case h(n)=n,d(n)=1 (constant),
- worst case d(n)=n,r(n)=1 (constant),r(n)=1 (constant),
- worst case r(n)=n,m(n)=1 (constant),
- worst case m(n)=n.Hashed indices are instantiated internally to multi_index_container and
-specified by means of indexed_by
-with index specifiers hashed_unique
-and hashed_non_unique. Instantiations are dependent on the
-following types:
-
Value from multi_index_container,Allocator from multi_index_container,TagList from the index specifier (if provided),KeyFromValue from the index specifier,Hash from the index specifier,Pred from the index specifier.TagList must be an instantiation of
-tag. The type KeyFromValue,
-which determines the mechanism for extracting a key from Value,
-must be a model of
-Key Extractor from Value. Hash is a
-Unary Function
-taking a single argument of type KeyFromValue::result_type and returning a
-value of type std::size_t in the range
-[0, std::numeric_limits<std::size_t>::max()).
-Pred is a
-
-Binary Predicate inducing an equivalence relation
-on elements of KeyFromValue::result_type. It is required that
-the Hash object return the same value for keys
-equivalent under Pred.
-
-
-ctor_args
-
--The first element of this tuple indicates the minimum number of buckets -set up by the index on construction time. If the default value 0 is used, -an implementation defined number is used instead. -- -
iterator
-const_iterator
-local_iterator
-const_local_iterator
-
-
-These types are models of
-Forward
-Iterator.
-
-
-
-As explained in the index
-concepts section, indices do not have public constructors or destructors.
-Assignment, on the other hand, is provided. Upon construction,
-max_load_factor() is 1.0.
-
index class name& operator=(const index class name& x);
-
--Effects: -- --where-a=b; -aandbare themulti_index_container-objects to which*thisandxbelong, respectively.
-Returns:*this.
-
std::pair<iterator,bool> insert(const value_type& x);
-
--Effects: Inserts- -xinto themulti_index_containerto which -the index belongs if --
-Returns: The return value is a pair- the index is non-unique OR no other element exists with - equivalent key,
-- AND insertion is allowed by all other indices of the -
-multi_index_container.p.p.second-istrueif and only if insertion took place. On successful insertion, -p.firstpoints to the element inserted; otherwise,p.first-points to an element that caused the insertion to be banned. Note that more than -one element can be causing insertion not to be allowed.
-Complexity:O(I(n)).
-Exception safety: Strong.
-
iterator insert(iterator position,const value_type& x);
-
--Requires:- -positionis a valid iterator of the index. -Effects: Insertsxinto themulti_index_containerto which -the index belongs if --
-- the index is non-unique OR no other element exists with - equivalent key,
-- AND insertion is allowed by all other indices of the -
-multi_index_container.positionis used as a hint to improve the efficiency of the -operation.
-Returns: On successful insertion, an iterator to the newly inserted -element. Otherwise, an iterator to an element that caused the insertion to be -banned. Note that more than one element can be causing insertion not to be -allowed.
-Complexity:O(H(n)).
-Exception safety: Strong.
-
template<typename InputIterator>
-void insert(InputIterator first,InputIterator last);
-
--Requires:- -InputIteratoris a model of - -Input Iteratorover elements of type -value_typeor a type convertible tovalue_type. -firstandlastare not iterators into any -index of themulti_index_containerto which this index belongs. -lastis reachable fromfirst. -Effects: --Complexity:-iterator hint=end(); -while(first!=last)hint=insert(hint,*first++); -O(m*H(n+m)), where -mis the number of elements in [first, -last).
-Exception safety: Basic.
-
iterator erase(iterator position);
-
--Requires:- -positionis a valid dereferenceable iterator -of the index. -Effects: Deletes the element pointed to byposition.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, orend()-if no such element exists.
-Complexity:O(D(n)).
-Exception safety:nothrow.
-
size_type erase(const key_type& x);
-
--Effects: Deletes the elements with key equivalent to- -x.
-Returns: Number of elements deleted.
-Complexity: Average case,O(1 + m*D(n)), worst case -O(n + m*D(n)), wheremis -the number of elements deleted.
-Exception safety: Basic.
-
iterator erase(iterator first,iterator last);
-
--Requires: [- -first,last) is a valid -range of the index.
-Effects: Deletes the elements in [first,last).
-Returns:last.
-Complexity:O(m*D(n)), wheremis -the number of elements in [first,last).
-Exception safety:nothrow.
-
bool replace(iterator position,const value_type& x);
-
--Requires:- - -positionis a valid dereferenceable iterator -of the index. -Effects: Assigns the valuexto the element pointed -to bypositioninto themulti_index_containerto which -the index belongs if, for the valuex--
-Postconditions: Validity of- the index is non-unique OR no other element exists - (except possibly
-*position) with equivalent key,- AND replacing is allowed by all other indices of the -
-multi_index_container.positionis preserved -in all cases.
-Returns:trueif the replacement took place, -falseotherwise.
-Complexity:O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation themulti_index_containerto which the index -belongs remains in its original state. -
template<typename Modifier> bool modify(iterator position,Modifier mod);
-
--Requires:- - -Modifieris a model of - -Unary Functionaccepting arguments of type -value_type&.positionis a valid dereferenceable -iterator of the index. -Effects: Callsmod(e)whereeis the element -pointed to bypositionand rearranges*positioninto -all the indices of themulti_index_container. Rearrangement is successful if --
-If the rearrangement fails, the element is erased.- the index is non-unique OR no other element exists - with equivalent key,
-- AND rearrangement is allowed by all other indices of the -
-multi_index_container.
-Postconditions: Validity ofpositionis preserved if the -operation succeeds.
-Returns:trueif the operation succeeded,false-otherwise.
-Complexity:O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possiblymod), then -the element pointed to bypositionis erased. -
template<typename Modifier> bool modify_key(iterator position,Modifier mod);
-
--Requires:- -key_from_valueis a read/write -Key Extractor-fromvalue_type.Modifieris a model of - -Unary Functionaccepting arguments of type -key_type&.positionis a valid dereferenceable -iterator of the index. -Effects: Callsmod(k)wherekis the key -obtained by the internalKeyFromValueobject of the index from -the element pointed to byposition, and rearranges -*positioninto all the indices of themulti_index_container. -Rearrangement is successful if --
-If the rearrangement fails, the element is erased.- the index is non-unique OR no other element exists - with equivalent key,
-- AND rearrangement is allowed by all other indices of the -
-multi_index_container.
-Postconditions:Validity ofpositionis preserved if -the operation succeeds.
-Returns:trueif the operation succeeded,false-otherwise.
-Complexity:O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possiblymod), then -the element pointed to bypositionis erased. -
Apart from standard hash_function and key_eq,
-hashed indices have a member function for retrieving the internal key extractor
-used.
-
key_from_value key_extractor()const;
-
--Returns a copy of the- -key_from_valueobject used to construct -the index.
-Complexity: Constant. -
-Hashed indices provide the full lookup functionality required by
-unordered associative containers, namely find,
-count, and equal_range. Additionally,
-these member functions are templatized to allow for non-standard
-arguments, so extending the types of search operations allowed.
-The kind of arguments permissible when invoking the lookup member
-functions is defined by the following concept.
-
-Consider a pair (Hash, Pred) where
-Hash is a hash functor over values of type Key
-and Pred is a
-
-Binary Predicate inducing an equivalence relation
-on Key, whit the additional constraint that equivalent
-keys have the same hash value.
-A triplet of types (CompatibleKey, CompatibleHash,
-CompatiblePred) is said to be a compatible extension
-of (Hash, Pred) if
-
CompatibleHash is a hash functor on values of
- type CompatibleKey,CompatiblePred is a
-
- Binary Predicate over (Key,
- CompatibleKey),CompatiblePred is a
-
- Binary Predicate over (CompatibleKey,
- Key),c_eq(ck,k1) then c_eq(k1,ck),c_eq(ck,k1) and eq(k1,k2) then
- c_eq(ck,k2),c_eq(ck,k1) and c_eq(ck,k2) then
- eq(k1,k2),c_eq(ck,k1) then c_hash(ck)==hash(k1),c_hash of type CompatibleHash,
-c_eq of type CompatiblePred,
-hash of type Hash,
-eq of type Pred, ck of type
-CompatibleKey and k1, k2 of type
-Key.
-
-
-Additionally, a type CompatibleKey is said to be a
-compatible key of (Hash, Pred) if
-(CompatibleKey, Hash, Pred)
-is a compatible extension of (Hash, Pred).
-This implies that Hash and Pred accept arguments
-of type CompatibleKey, which usually means they have
-several overloads of therir corresponding operator()
-member functions.
-
-In the context of a compatible extension or a compatible key, the expression -"equivalent key" takes on its obvious interpretation. -
- -template<typename CompatibleKey> iterator find(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -(hasher,key_equal). -Effects: Returns a pointer to an element whose key is equivalent to -x, orend()if such an element does not exist.
-Complexity: Average caseO(1)(constant), worst case -O(n).
-
template<
- typename CompatibleKey,typename CompatibleHash, typename CompatiblePred
->
-iterator find(
- const CompatibleKey& x,
- const CompatibleHash& hash,const CompatiblePred& eq)const;
-
-
--Requires: (- -CompatibleKey,CompatibleHash, -CompatiblePred) is a compatible extension of -(hasher,key_equal). -Effects: Returns a pointer to an element whose key is equivalent to -x, orend()if such an element does not exist.
-Complexity: Average caseO(1)(constant), worst case -O(n).
-
template<typename CompatibleKey>
-size_type count(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -(hasher,key_equal). -Effects: Returns the number of elements with key equivalent tox.
-Complexity: Average caseO(count(x)), worst case -O(n).
-
template<
- typename CompatibleKey,typename CompatibleHash, typename CompatiblePred
->
-size_type count(
- const CompatibleKey& x,
- const CompatibleHash& hash,const CompatiblePred& eq)const;
-
-
--Requires: (- -CompatibleKey,CompatibleHash, -CompatiblePred) is a compatible extension of -(hasher,key_equal). -Effects: Returns the number of elements with key equivalent tox.
-Complexity: Average caseO(count(x,hash,eq)), worst case -O(n).
-
template<typename CompatibleKey>
-std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -(hasher,key_equal). -Effects: Returns a range containing all elements with keys equivalent -tox(and only those).
-Complexity: Average caseO(count(x)), worst case -O(n).
-
template<
- typename CompatibleKey,typename CompatibleHash, typename CompatiblePred
->
-std::pair<iterator,iterator> equal_range(
- const CompatibleKey& x,
- const CompatibleHash& hash,const CompatiblePred& eq)const;
-
-
--Requires: (- - -CompatibleKey,CompatibleHash, -CompatiblePred) is a compatible extension of -(hasher,key_equal). -Effects: Returns a range containing all elements with keys equivalent -tox(and only those).
-Complexity: Average caseO(count(x,hash,eq)), worst case -O(n).
-
void rehash(size_type n);
-
--Effects: Increases if necessary the number of internal buckets -so that- -size()/bucket_count()does not exceed the maximum -load factor, andbucket_count()>=n.
-Postconditions: Validity of iterators and references to the -elements contained is preserved.
-Complexity: Average caseO(size()), worst case -O(size(n)2).
-Exeption safety: Strong. -
-Indices cannot be serialized on their own, but only as part of the
-multi_index_container into which they are embedded. In describing
-the additional preconditions and guarantees associated to hashed indices
-with respect to serialization of their embedding containers, we
-use the concepts defined in the multi_index_container
-serialization section.
-
multi_index_container m to an
-output archive (XML archive) ar.
-
--Requires: No additional requirements to those imposed by the container. -- -Operation: loading of a
multi_index_container m' from an
-input archive (XML archive) ar.
-
--Requires: Additionally to the general requirements,- -Operation: saving of ankey_eq()-must be serialization-compatible withm.get<i>().key_eq(), -whereiis the position of the hashed index in the container.
-Postconditions: On succesful loading, the range -[begin(),end()) contains restored copies of every -element in [m.get<i>().begin(),m.get<i>().end()), -though not necessarily in the same order. -
iterator or const_iterator
-it to an output archive (XML archive) ar.
-
--Requires:- -Operation: loading of anitis a valid iterator of the index. The associated -multi_index_containerhas been previously saved. -
iterator or const_iterator
-it' from an input archive (XML archive) ar.
-
--Postconditions: On succesful loading, if- -Operation: saving of aitwas dereferenceable -then*it'is the restored copy of*it, otherwise -it'==end().
-Note: It is allowed thatitbe aconst_iterator-and the restoredit'aniterator, or viceversa. -
local_iterator or
-const_local_iterator
-it to an output archive (XML archive) ar.
-
--Requires:- -Operation: loading of aitis a valid local iterator of the index. The -associatedmulti_index_containerhas been previously saved. -
local_iterator or
-const_local_iterator
-it' from an input archive (XML archive) ar.
-
--Postconditions: On succesful loading, if- -itwas dereferenceable -then*it'is the restored copy of*it; ifit-wasm.get<i>().end(n)for somen, then -it'==m'.get<i>().end(n)(wheremis the original -multi_index_container,m'its restored copy -andiis the ordinal of the index.)
-Note: It is allowed thatitbe aconst_local_iterator-and the restoredit'alocal_iterator, or viceversa. -
Revised August 24th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/index.html b/doc/reference/index.html deleted file mode 100644 index e5fc570..0000000 --- a/doc/reference/index.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - -
Boost.MultiIndex Referencemulti_index_container-The following dependencies among headers of Boost.MultiIndex hold: -
"boost/multi_index_container.hpp"
- includes
-
- "boost/multi_index/ordered_index.hpp" includes
-
- "boost/multi_index/hashed_index.hpp" includes
-
- "boost/multi_index/sequenced_index.hpp" includes
-
- "boost/multi_index/key_extractors.hpp"
- includes
-
- "boost/multi_index_container.hpp",
-the headers defining the index types to be used and possibly one or more key
-extraction headers for key-based indices. Note that all the key extractors
-provided by Boost.MultiIndex are automatically included with
-
-"boost/multi_index/key_extractors.hpp".
-
-
--In order to use the serialization capabilities of Boost.MultiIndex, -the appropriate Boost.Serialization library module must be linked. Other -than that, Boost.MultiIndex is a header-only library, requiring no additional -object modules. -
- -Revised May 30th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/indices.html b/doc/reference/indices.html deleted file mode 100644 index b59a65c..0000000 --- a/doc/reference/indices.html +++ /dev/null @@ -1,335 +0,0 @@ - - - - - -
Boost.MultiIndex Index reference"boost/multi_index/indexed_by.hpp" synopsis
-
- "boost/multi_index/tag.hpp" synopsis
-
-
-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 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:
-
multi_index_container are not mutable.
-To overcome this restriction, indices expose member functions
-for updating and modifying, which allow for the mutation of elements
-in a controlled fashion. Immutability of elements does not significantly
-impact the interface of ordered indices, as it is based upon that of
-std::set and std:multiset, and these containers
-also have non-mutable elements; but it may come as a surprise when dealing
-with sequenced 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
-indices do have push_back and push_front
-operations.) Boost.MultiIndex poses no particular conditions on
-the interface of indices, save that they must model
-
-Container (without the requirement of being
-
-Assignable.)
-
-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.
-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).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,hashed_unique and
- hashed_non_unique for
- hashed indices,sequenced for
- sequenced indices."boost/multi_index/indexed_by.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -template<typename T0,...,typename Tn> -struct indexed_by; - -} // namespace boost::multi_index - -} // namespace boost -
indexed_by
-indexed_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<typename T0,...,typename Tn> -struct indexed_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" synopsis- --namespace boost{ - -namespace multi_index{ - -template<typename T0,...,typename Tn> -struct tag; - -} // namespace boost::multi_index - -} // namespace boost -
tag
-tag is a typelist construct used to specify a compile-time
-sequence of tags to be assigned to an index in instantiation time.
-
- --template<typename T0,...,typename Tn> -struct tag; -
-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.
-
-Indices of this type are organized around keys obtained from the -elements, as described in the key extraction -reference. -
-
Revised May 30th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/key_extraction.html b/doc/reference/key_extraction.html deleted file mode 100644 index d4b92b1..0000000 --- a/doc/reference/key_extraction.html +++ /dev/null @@ -1,2025 +0,0 @@ - - - - - -
Boost.MultiIndex Key extraction reference"boost/multi_index/key_extractors.hpp" synopsis
- "boost/multi_index/identity.hpp" synopsis
-
- "boost/multi_index/member.hpp" synopsis
-
- "boost/multi_index/mem_fun.hpp" synopsis
-
- "boost/multi_index/composite_key.hpp" synopsis
- composite_keycomposite_key_resultcomposite_key_result
-Key extraction classes are used by
-key-based indices to
-obtain the indexing keys from the elements of a multi_index_container.
-An Assignable
-class KeyFromValue is said to be a key extractor from a
-type Type if
-
KeyFromValue::result_type is defined,k1(ca) is defined and returns a value convertible
- to const KeyFromValue::result_type&,k2 is a copy of k1, k1(ca) is the
- same value as k2(ca),k1, k2 of type const KeyFromValue,
-and ca of type const Type&.
-
-
-
-Additionally, KeyFromValue is a read/write key extractor
-if the following extra conditions are met:
-
k1(a) is defined and returns a value convertible
- to KeyFromValue::result_type&,const_cast<const KeyFromValue::result_type&>(k1(a))
- is the same value as
- k1(const_cast<const Type&>(a)),k1 of type const KeyFromValue and
-a of type Type&.
-
-
--Boost.MultiIndex provides five general-purpose key extractors: -
identity,member,const_mem_fun,mem_fun andcomposite_key,member_offset,const_mem_fun_explicit andmem_fun_explicit,
-The key extractors provided by Boost.MultiIndex are templatized according
-to the type Type and serve to extract keys not only from objects
-of type Type, but also from reference wrappers provided by
-Boost.Ref and from chained pointers
-to Type (or to reference wrappers of Type): a chained pointer
-is any type P such that, for an object p of type
-const P
-
*p yields an object of type Type& or
- boost::reference_wrapper<Type>, OR*p yields a chained pointer to Type,Type& or
-boost::reference_wrapper<Type>.
-- -
"boost/multi_index/key_extractors.hpp" synopsis
-- --#include <boost/multi_index/identity.hpp> -#include <boost/multi_index/member.hpp> -#include <boost/multi_index/mem_fun.hpp> -#include <boost/multi_index/composite_key.hpp> -
-This header includes all the key extractors provided by Boost.MultiIndex. -
- -"boost/multi_index/identity.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -template<typename T> struct identity; - -} // namespace boost::multi_index - -} // namespace boost -
identity
-identity is a Key Extractor
-that acts as a do-nothing identity functor.
-
- --template<typename Type> -struct identity -{ - typedef Type result_type; - - template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const; - const Type& operator()(const Type& x)const; - Type& operator()(Type& x)const; // only provided if Type is non-const - - // only provided if Type is non-const - const Type& operator()(const reference_wrapper<const Type>& x)const; - - // only provided if Type is const - Type& operator()( - const reference_wrapper<typename remove_const<Type>::type>& x)const; - - Type& operator()(const reference_wrapper<Type>& x)const; -}; -
-identity<Type> is a model of:
-
Key Extractor
- from Type,Key Extractor
- from reference_wrapper<const Type>,Key Extractor
- from reference_wrapper<Type>,Key Extractor
- from any chained pointer to
- const Type,Key Extractor
- from any chained pointer
- to Type.identity memberstemplate<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;
-
--Requires:- -ChainedPtris a chained pointer -type toType.
-Returns: a reference to the object chained-pointed to byx. -
const Type& operator()(const Type& x)const;
-
-
-Returns: x.
-
-
-Type& operator()(Type& x)const;
-
-
-Returns: x.
-
-
-const Type& operator()(const reference_wrapper<const Type>& x)const;
-
-Returns: x.get().
-
-
-Type& operator()(const reference_wrapper<typename remove_const<Type>::type>& x)const;
-
-Returns: x.get().
-
-
-Type& operator()(const reference_wrapper<Type>& x)const;
-
-Returns: x.get().
-
-
-
-"boost/multi_index/member.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -template<class Class,typename Type,Type Class::*PtrToMember> -struct member; - -template<class Class,typename Type,std::size_t OffsetOfMember> -struct member_offset; - -#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) implementation defined - -} // namespace boost::multi_index - -} // namespace boost -
member
-member is a Key Extractor
-aimed at accessing a given member of a class.
-
- --template<class Class,typename Type,Type Class::*PtrToMember> -struct member -{ - typedef Type result_type; - - template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const; - const Type& operator()(const Class& x)const; - Type& operator()(Class& x)const; // only provided if Type is non-const - const Type& operator()(const reference_wrapper<const Class>& x)const; - Type& operator()(const reference_wrapper<Class>& x)const; -}; -
-The PtrToMember template argument specifies the particular
-Type Class::* pointer to the member to be extracted.
-member<Class,Type,PtrToMember> is a model of:
-
Key Extractor
- from Class,Key Extractor
- from reference_wrapper<const Class>,Key Extractor
- from reference_wrapper<Class>,Key Extractor
- from any chained pointer
- to const Class,Key Extractor
- from any chained pointer
- to Class.member memberstemplate<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const;
-
--Requires:- -ChainedPtris a chained pointer -type toType.
-Returns: a reference to the object chained-pointed to byx. -
const Type& operator()(const Class& x)const;
-
-
-Returns: x.*PtrToMember.
-
-
-Type& operator()(Class& x)const;
-
-
-Returns: x.*PtrToMember.
-
-
-const Type& operator()(const reference_wrapper<const Class>& x)const;
-
-
-Returns: x.get().*PtrToMember.
-
-
-Type& operator()(const reference_wrapper<Class>& x)const;
-
-
-Returns: x.get().*PtrToMember.
-
-
-member_offset-Some compilers do not properly support pointers to members as non-type -template arguments. The following have been confirmed to have bugs in -this respect: -
member_offset provides an
-alternative to member accepting offsets
-instead of pointers to members. Please note that the use of
-offsetof on non-POD types is forbidden by the standard;
-luckily enough, most compilers accept it nevertheless, so
-member_offset serves as a workaround for most practical purposes.
-
-
-- --template<class Class,typename Type,std::size_t OffsetOfMember> -struct member_offset -{ - typedef Type result_type; - - template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const; - const Type& operator()(const Class& x)const; - Type& operator()(Class& x)const; // only provided if Type is non-const - const Type& operator()(const reference_wrapper<const Class>& x)const; - Type& operator()(const reference_wrapper<Class>& x)const; -}; -
As an example of use, given the class
- -- --class A -{ - int x; -} -
-the instantiation member<A,int,&A::x> can be simulated then
-as member_offset<A,int,offsetof(A,x)>.
-
BOOST_MULTI_INDEX_MEMBER- --BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) -
-This macro is provided as an aid for using member and
-member_offset when writing cross-platform code. In the usual cases,
-it expands to
-
- --::boost::multi_index::member<Class,Type,&Class::MemberName> -
-but it resolves to -
- -- --::boost::multi_index::member_offset<Class,Type,offsetof(Class,MemberName)> -
-if the Boost Configuration Library
-defect macro BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS
-is defined.
-
"boost/multi_index/mem_fun.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const> -struct const_mem_fun; - -template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()> -struct mem_fun; - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct const_mem_fun_explicit; - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct mem_fun_explicit; - -#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ -implementation defined -#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ -implementation defined - -} // namespace boost::multi_index - -} // namespace boost -
const_mem_fun
-const_mem_fun is a Key Extractor
-returning as key the result of invoking a given constant member function of a class.
-
- --template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const> -struct const_mem_fun -{ - typedef typename remove_reference<Type>::type result_type; - - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - Type operator()(const Class& x)const; - Type operator()(const reference_wrapper<const Class>& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
-The PtrToMemberFunction template argument specifies the particular
-Type (Class::*PtrToMemberFunction)()const pointer to the the constant
-member function used in the extraction.
-const_mem_fun<Class,Type,PtrToMemberFunction> is a model of:
-
Key Extractor
- from Class,Key Extractor
- from reference_wrapper<const Class>,Key Extractor
- from reference_wrapper<Class>,Key Extractor
- from any chained pointer
- to const Class,Key Extractor
- from any chained pointer
- to Class.const_mem_fun memberstemplate<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;
-
--Requires:- -ChainedPtris a chained pointer -type toType.
-Returns:(y.*PtrToMemberFunction)(), whereyis the -object chained-pointed to byx. -
Type operator()(const Class& x)const;
-
-
-Returns: (x.*PtrToMemberFunction)().
-
-
-Type operator()(const reference_wrapper<const Class>& x)const;
-
-
-Returns: (x.get().*PtrToMemberFunction)().
-
-
-Type operator()(const reference_wrapper<Class>& x)const;
-
-
-Returns: (x.get().*PtrToMemberFunction)().
-
-
-mem_fun
-mem_fun is a Key Extractor
-returning as key the result of invoking a given member function of a class.
-
- --template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()> -struct mem_fun -{ - typedef typename remove_reference<Type>::type result_type; - - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - Type operator()(Class& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
-The PtrToMemberFunction template argument specifies the particular
-Type (Class::*PtrToMemberFunction)() pointer to the the member
-function used in the extraction.
-mem_fun<Class,Type,PtrToMemberFunction> is a model of:
-
Key Extractor
- from reference_wrapper<Class>,Key Extractor
- from any chained pointer
- to Class.mem_fun memberstemplate<typename ChainedPtr> Type operator()(const ChainedPtr& x)const;
-
--Requires:- -ChainedPtris a chained pointer -type toType.
-Returns:(y.*PtrToMemberFunction)(), whereyis the -object chained-pointed to byx. -
Type operator()(Class& x)const;
-
-
-Returns: (x.*PtrToMemberFunction)().
-
-
-Type operator()(const reference_wrapper<Class>& x)const;
-
-
-Returns: (x.get().*PtrToMemberFunction)().
-
-
-const_mem_fun_explicit
-MSVC++ 6.0 do not properly support pointers to constant member functions as non-type
-template parameters, thus const_mem_fun cannot be
-used in this compiler. A simple workaround consists in specifying the type of
-these pointers as an additional template parameter.
-
- --template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct const_mem_fun_explicit -{ - typedef typename remove_reference<Type>::type result_type; - - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - Type operator()(const Class& x)const; - Type operator()(const reference_wrapper<const Class>& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
-const_mem_fun_explicit provides the very same functionality as
-its const_mem_fun analogous instantiation. For example, given the type
-
- --struct A -{ - int f()const; -}; -
-the extractor const_mem_fun<A,int,&A::f> can be replaced by
-const_mem_fun_explicit<A,int,int (A::*)()const,&A::f>.
-
mem_fun_explicit
-For analogy with const_mem_fun_explicit,
-a variation of mem_fun is provided accepting
-an additional parameter with the type of the pointer to non-constant member function
-used for extraction.
-
- --template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct mem_fun_explicit -{ - typedef typename remove_reference<Type>::type result_type; - - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - Type operator()(Class& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
BOOST_MULTI_INDEX_CONST_MEM_FUN- --BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) -
-Use this macro when writing cross-platform code selectively using
-const_mem_fun_explicit in place of const_mem_fun for
-compilers not supporting the latter. In the usual cases, the macro expands to
-
- --::boost::multi_index::const_mem_fun<Class,Type,&Class::MemberFunName> -
-but it resolves to -
- -- --::boost::multi_index::const_mem_fun_explicit< - Class,Type,Type (Class::*)()const,&Class::MemberFunName -> -
-for MSVC++ 6.0 or lower. -
- - -BOOST_MULTI_INDEX_MEM_FUN- --BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) -
-By default, the macro expands to -
- -- --::boost::multi_index::mem_fun<Class,Type,&Class::MemberFunName> -
-but it resolves to -
- -- --::boost::multi_index::mem_fun_explicit< - Class,Type,Type (Class::*)(),&Class::MemberFunName -> -
-for MSVC++ 6.0 or lower. -
- -"boost/multi_index/composite_key.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -template<typename Value,typename KeyFromValue0,...,typename KeyFromValuen> -struct composite_key; - -template<typename CompositeKey> -struct composite_key_result; - -// comparison operators for composite_key_result: - -// OP is any of =,<,!=,>,>=,<= - -template<typename CompositeKey1,typename CompositeKey2> -bool operator OP( - const composite_key_result<CompositeKey1>& x, - const composite_key_result<CompositeKey2>& y); - -template<typename CompositeKey,typename Value0,...,typename Valuen> -bool operator OP( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y); - -template<typename Value0,...,typename Valuen,typename CompositeKey> -bool operator OP( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y); - -// equality functors: - -template<typename Pred0,...,typename Predn> -struct composite_key_equal_to; - -template<typename CompositeKeyResult> -struct composite_key_result_equal_to; - -// comparison functors: - -template<typename Compare0,...,typename Comparen> -struct composite_key_compare; - -template<typename CompositeKeyResult> -struct composite_key_result_less; - -template<typename CompositeKeyResult> -struct composite_key_result_greater; - -// hash functors: - -template<typename Hash0,...,typename Hashn> -struct composite_key_hash; - -template<typename CompositeKeyResult> -struct composite_key_result_hash; - -} // namespace boost::multi_index - -} // namespace boost - -// specializations of external functors for composite_key_result: - -namespace std{ - -template<typename CompositeKey> -struct equal_to<boost::multi_index::composite_key_result<CompositeKey> >; - -template<typename CompositeKey> -struct less<boost::multi_index::composite_key_result<CompositeKey> >; - -template<typename CompositeKey> -struct greater<boost::multi_index::composite_key_result<CompositeKey> >; - -} // namespace std - -namespace boost{ - -template<typename CompositeKey> -struct hash<boost::multi_index::composite_key_result<CompositeKey> >; - -} // namespace boost -
composite_key
-composite_key is a Key Extractor
-returning the combined value of several key extractors whose type is specified
-at compile time. The returned object is of type
-
-composite_key_result<composite_key>.
-
- --template<typename Value,typename KeyFromValue0,...,typename KeyFromValuen> -struct composite_key -{ - typedef tuple<KeyFromValue0,...,KeyFromValuen> key_extractor_tuple; - typedef Value value_type; - typedef composite_key_result<composite_key> result_type; - - composite_key( - const KeyFromValue0& k0=KeyFromValue0(), - ... - const KeyFromValuen& kn=KeyFromValuen()); - - composite_key(const key_extractor_tuple& x); - - const key_extractor_tuple& key_extractors()const; - key_extractor_tuple& key_extractors() - - template<typename ChainedPtr> - result_type operator()(const ChainedPtr& x)const; - - result_type operator()(const value_type& x)const; - result_type operator()(const reference_wrapper<const value_type>& x)const; - result_type operator()(const reference_wrapper<value_type>& x)const; -}; -
-KeyFromValue0, ... , KeyFromValuen are the types of
-the key extractors combined into the composite key. Each of these types
-must be a Key Extractor from
-Value. At least a key extractor must be provided. The maximum
-number of key extractors of a composite_key instantiation is
-implementation defined. composite_key internally stores an
-object of every constituent key extractor type.
-composite_key<Value,KeyFromValue0,...,KeyFromValuen> is a model
-of:
-
Key Extractor
- from Value,Key Extractor
- from reference_wrapper<const Value>,Key Extractor
- from reference_wrapper<Value>,Key Extractor
- from any chained pointer
- to const Value,Key Extractor
- from any chained pointer
- to Value.composite_key memberscomposite_key(
- const KeyFromValue0& k0=KeyFromValue0(),
- ...
- const KeyFromValuen& kn=KeyFromValuen());
-
-
-
-Effects: Constructs a composite_key that stores
-copies of the key extractor objects supplied.
-
-
-composite_key(const key_extractor_tuple& x);
-
--Effects: Constructs a- -composite_keythat stores -copies of the key extractor objects supplied inx. -
const key_extractor_tuple& key_extractors()const;
-
-
-Returns: a constant reference to a tuple holding the
-key extractors internally stored by the composite_key.
-
-
-key_extractor_tuple& key_extractors();
-
-
-Returns: a reference to a tuple holding the
-key extractors internally stored by the composite_key.
-
-
-template<typename ChainedPtr>
-result_type operator()(const ChainedPtr& x)const;
-
--Requires:- -ChainedPtris a chained pointer -type toresult_type.
-Returns: aresult_typeobject dependent on -*thisandy, whereyis the -object chained-pointed to byx. -
result_type operator()(const value_type& x)const;
-
--Returns: a- -result_typeobject dependent on -*thisandx. -
result_type operator()(const reference_wrapper<const value_type>& x)const;
-
--Returns: a- -result_typeobject dependent on -*thisandx.get(). -
result_type operator()(const reference_wrapper<value_type>& x)const;
-
--Returns: a- -result_typeobject dependent on -*thisandx.get(). -
composite_key_result
-This is an opaque type returned by composite_key
-instantiations as their extracted key.
-
- --template<typename CompositeKey> -struct composite_key_result -{ - no public interface available -}; - -// comparison: - -// OP is any of =,<,!=,>,>=,<= - -template<typename CompositeKey1,typename CompositeKey2> -bool operator OP( - const composite_key_result<CompositeKey1>& x, - const composite_key_result<CompositeKey2>& y); - -template<typename CompositeKey,typename Value0,...,typename Valuen> -bool operator OP( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y); - -template<typename Value0,...,typename Valuen,typename CompositeKey> -bool operator OP( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y); -
CompositeKey is the composite_key instantiation to
-which the composite_key_result type is associated. Objects of type
-composite_key_result returned by a composite key must be always treated
-as temporary, i.e. they should not be stored or copied.
-composite_key_result is not guaranteed to be a model of
-
-Default Constructible or
-Assignable.
-Every object of type composite_key_result<CompositeKey> is
-internally associated to the CompositeKey from which it is returned
-and the object of type CompositeKey::value_type to which the
-composite key was applied.
-
-
-
-Given an x of type composite_key_result<CompositeKey>,
-we use the following notation:
-
ck(x) is the CompositeKey object associated to
- x,v(x) is the object of type CompositeKey::value_type
- associated to x,ki(x) = ck(x).key_extractors().get<i>(),
- that is, is the i-th key extractor of ck(x),xi = ki(x)(v(x)), that is, the
- key extracted from v(x) by the i-th key extractor,length(x) is the number of key extractors of ck(x).y is a tuple of values, we define:
-yi=y.get<i>(),length(y) is the number of elements of y.template<typename CompositeKey1,typename CompositeKey2>
-bool operator==(
- const composite_key_result<CompositeKey1>& x,
- const composite_key_result<CompositeKey2>& y);
-template<typename CompositeKey,typename Value0,...,typename Valuen>
-bool operator==(
- const composite_key_result<CompositeKey>& x,
- const tuple<Value0,...,Valuen>& y);
-template<typename Value0,...,typename Valuen,typename CompositeKey>
-bool operator==(
- const tuple<Value0,...,Valuen>& x,
- const composite_key_result<CompositeKey>& y);
-
-
--Requires:- -length(x)==length(y). The expression -xi==yiis valid for alli-in[0,length(x)). -Returns:trueif and only if ---Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting atxi==yifor alli-in[0,length(x)). -i==0. The evaluation is short-circuited as soon as -the result is determined to befalse. -
template<typename CompositeKey1,typename CompositeKey2>
-bool operator<(
- const composite_key_result<CompositeKey1>& x,
- const composite_key_result<CompositeKey2>& y);
-template<typename CompositeKey,typename Value0,...,typename Valuen>
-bool operator<(
- const composite_key_result<CompositeKey>& x,
- const tuple<Value0,...,Valuen>& y);
-template<typename Value0,...,typename Valuen,typename CompositeKey>
-bool operator<(
- const tuple<Value0,...,Valuen>& x,
- const composite_key_result<CompositeKey>& y);
-
-
--Requires: The expressions -- -xi<yiand -yi<xiare valid for alli-in[0,min(length(x),length(y))). -Returns:trueif and only if there exists some -jin the range[0,min(length(x),length(y)))-such that ---Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at!(xi<yi) && !(yi<xi)-for alliin[0,j),
-xj<yj. -i==0. The evaluation is short-circuited as soon as -the result is determined to befalse. -
template<typename CompositeKey1,typename CompositeKey2>
-bool operator OP(
- const composite_key_result<CompositeKey1>& x,
- const composite_key_result<CompositeKey2>& y);
-template<typename CompositeKey,typename Value0,...,typename Valuen>
-bool operator OP(
- const composite_key_result<CompositeKey>& x,
- const tuple<Value0,...,Valuen>& y);
-template<typename Value0,...,typename Valuen,typename CompositeKey>
-bool operator OP(
- const tuple<Value0,...,Valuen>& x,
- const composite_key_result<CompositeKey>& y);
-
-
-
-(OP is any of !=, >,
->=, <=.)
-
-Requires: The expressions given below are valid (for the particular -- -OPconsidered.) -Returns:trueif and only if ---!(x==y)(OPis!=),
-y< x(OPis>),
-!(x< y)(OPis>=),
-!(y< x)(OPis<=). -
composite_key_equal_to
-composite_key_equal_to tests for equality between
-composite_key_result instantiations and between
-these and tuples of values, using an internally stored
-collection of elementary equality predicates.
-
- --template<typename Pred0,...,typename Predn> -struct composite_key_equal_to -{ - typedef tuple<Pred0,...,Predn> key_eq_tuple; - - composite_key_equal_to( - const Pred0& p0=Pred0(), - ... - const Predn& pn=Predn()); - - composite_key_equal_to(const key_eq_tuple& x); - - const key_eq_tuple& key_eqs()const; - key_eq_tuple& key_eqs(); - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const composite_key_result<CompositeKey1> & x, - const composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y)const; -}; -
-Pred0, ... , Predn are the types of the equality
-predicates stored by composite_key_equal_to. Each of these types
-must be a
-Binary Predicate. At least an
-equality predicate must be provided. The maximum number of equality predicates of
-a composite_key_equal_to instantiation is implementation defined.
-composite_key_equal_to is
-Assignable.
-It is also
-
-Default Constructible
-if each Predi is
-
-Default Constructible.
-
-Note that formally it is not required that the Predi types
-behave as equality predicates in any definite way. However, the
-semantics of composite_key_equal_to is well defined if this
-is the case, as explained in the section on the
-semantics of composite_key_result.
-
-In what follows we use the same notation
-introduced for composite_key_result.
-
-
composite_key_equal_to memberscomposite_key_equal_to(
- const Pred0& p0=Pred0(),
- ...
- const Predn& pn=Predn());
-
-
-
-Effects: Constructs a composite_key_equal_to that stores
-copies of the equality predicates supplied.
-
-
-composite_key_equal_to(const key_eq_tuple& x);
-
--Effects: Constructs a- -composite_key_equal_tothat stores -copies of the equality predicate objects supplied inx. -
const key_eq_tuple& key_eqs()const;
-
-
-Returns: a constant reference to a tuple holding the
-equality predicate objects internally stored by the
-composite_key_equal_to.
-
-
-key_eq_tuple& key_eqs();
-
-
-Returns: a reference to a tuple holding the
-equality predicate objects internally stored by the
-composite_key_equal_to.
-
-
-
-template<typename CompositeKey1,typename CompositeKey2>
-bool operator()(
- const composite_key_result<CompositeKey1> & x,
- const composite_key_result<CompositeKey2> & y)const;
-template<typename CompositeKey,typename Value0,...,typename Valuen>
-bool operator()(
- const composite_key_result<CompositeKey>& x,
- const tuple<Value0,...,Valuen>& y)const;
-template<typename Value0,...,typename Valuen,typename CompositeKey>
-bool operator()(
- const tuple<Value0,...,Valuen>& x,
- const composite_key_result<CompositeKey>& y)const;
-
-
--Requires:- -length(x)==length(y). The expressions -key_eqs().get<i>()(xi,yi)and -key_eqs().get<i>()(yi,xi)-are valid for alliin[0,length(x)). -Returns:trueif and only ---Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting atkey_eqs().get<i>()(xi,yi)-for alliin[0,length(x)).
-i==0. The evaluation is short-circuited as soon as -the result is determined to befalse. -
composite_key_result_equal_to
-composite_key_result_equal_to acts as a particularization of
-composite_key_equal_to where all the comparison predicates supplied
-are instantiations of std::equal_to.
-
- --template<typename CompositeKeyResult> -struct composite_key_result_equal_to -{ - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const composite_key_result<CompositeKey1> & x, - const composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y)const; -}; -
-CompositeKeyResult must be an instantiation of
-composite_key_result for some type
-composite_key<KeyFromValue0,...,KeyFromValuen>.
-composite_key_result_equal_to<CompositeKeyResult>::operator() is
-then equivalent to
-composite_key_equal_to<Pred0,...,Predn>::operator(), taking
-
-- - -Predi = std::equal_to<KeyFromValuei::result_type>for all -i = 0,...,n. -
-In addition to the requirements on Predi imposed by
-composite_key_equal_to, each of these types must be
-
-Default Constructible. composite_key_result_equal_to
-is
-Default Constructible and
-Assignable.
-
std::equal_to for composite_key results
-std::equal_to<CompositeKeyResult>, for CompositeKeyResult
-being an instantiation of composite_key_result, has the same interface
-and functionality as composite_key_result_equal_to<CompositeKeyResult>.
-
- --namespace std{ - -template<typename CompositeKey> -struct equal_to<boost::multi_index::composite_key_result<CompositeKey> > -{ - typedef - boost::multi_index::composite_key_result< - CompositeKey> first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey1> & x, - const boost::multi_index::composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey>& x, - const boost::tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const boost::tuple<Value0,...,Valuen>& x, - const boost::multi_index::composite_key_result<CompositeKey>& y)const; -}; - -} // namespace std -
composite_key_compare
-composite_key_compare compares composite_key_result
-instantiations between them and with tuples of values using an internally stored
-collection of elementary comparison predicates.
-
- --template<typename Compare0,...,typename Comparen> -struct composite_key_compare -{ - typedef tuple<Compare0,...,Comparen> key_comp_tuple; - - composite_key_compare( - const Compare0& c0=Compare0(), - ... - const Comparen& cn=Comparen()); - - composite_key_compare(const key_comp_tuple& x); - - const key_comp_tuple& key_comps()const; - key_comp_tuple& key_comps(); - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const composite_key_result<CompositeKey1> & x, - const composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y)const; -}; -
-Compare0, ... , Comparen are the types of the comparison
-predicates stored by composite_key_compare. Each of these types
-must be a
-Binary Predicate. At least a
-comparison predicate must be provided. The maximum number of comparison predicates of
-a composite_key_compare instantiation is implementation defined.
-composite_key_compare is
-Assignable.
-It is also
-
-Default Constructible
-if each Comparei is
-
-Default Constructible.
-
-Note that formally it is not required that the Comparei types
-behave as comparison predicates in any definite way. However, the
-semantics of composite_key_compare is well defined if this
-is the case, as explained in the section on the
-semantics of composite_key_result.
-
-In what follows we use the same notation
-introduced for composite_key_result.
-
-
composite_key_compare memberscomposite_key_compare(
- const Compare0& c0=Compare0(),
- ...
- const Comparen& cn=Comparen());
-
-
-
-Effects: Constructs a composite_key_compare that stores
-copies of the comparison predicates supplied.
-
-
-composite_key_compare(const key_comp_tuple& x);
-
--Effects: Constructs a- -composite_key_comparethat stores -copies of the comparison predicate objects supplied inx. -
const key_comp_tuple& key_comps()const;
-
-
-Returns: a constant reference to a tuple holding the
-comparison predicate objects internally stored by the
-composite_key_compare.
-
-
-key_comp_tuple& key_comps();
-
-
-Returns: a reference to a tuple holding the
-comparison predicate objects internally stored by the
-composite_key_compare.
-
-
-
-template<typename CompositeKey1,typename CompositeKey2>
-bool operator()(
- const composite_key_result<CompositeKey1> & x,
- const composite_key_result<CompositeKey2> & y)const;
-template<typename CompositeKey,typename Value0,...,typename Valuen>
-bool operator()(
- const composite_key_result<CompositeKey>& x,
- const tuple<Value0,...,Valuen>& y)const;
-template<typename Value0,...,typename Valuen,typename CompositeKey>
-bool operator()(
- const tuple<Value0,...,Valuen>& x,
- const composite_key_result<CompositeKey>& y)const;
-
-
--Requires: The expressions -- -key_comps().get<i>()(xi,yi)and -key_comps().get<i>()(yi,xi)-are valid for alli-in[0,min(length(x),length(y))). -Returns:trueif and only if there exists some -jin the range[0,min(length(x),length(y)))-such that ---Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at!key_comps().get<i>()(xi,yi) && !key_comps().get<i>()(yi,xi)-for alliin[0,j),
-key_comps().get<j>()(xj,yj). -i==0. The evaluation is short-circuited as soon as -the result is determined to befalse. -
composite_key_result_less
-composite_key_result_less acts as a particularization of
-composite_key_compare where all the comparison predicates supplied
-are instantiations of std::less.
-
- --template<typename CompositeKeyResult> -struct composite_key_result_less -{ - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const composite_key_result<CompositeKey1> & x, - const composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y)const; -}; -
-CompositeKeyResult must be an instantiation of
-composite_key_result for some type
-composite_key<KeyFromValue0,...,KeyFromValuen>.
-composite_key_result_less<CompositeKeyResult>::operator() is
-then equivalent to
-composite_key_compare<Compare0,...,Comparen>::operator(), taking
-
-- - -Comparei = std::less<KeyFromValuei::result_type>for all -i = 0,...,n. -
-In addition to the requirements on Comparei imposed by
-composite_key_compare, each of these types must be
-
-Default Constructible. composite_key_result_less
-is
-Default Constructible and
-Assignable.
-
composite_key_result_greater
-composite_key_result acts as a particularization of
-composite_key_compare where all the comparison predicates supplied
-are instantiations of std::greater.
-
- --template<typename CompositeKeyResult> -struct composite_key_result_greater -{ - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const composite_key_result<CompositeKey1> & x, - const composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const composite_key_result<CompositeKey>& x, - const tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const tuple<Value0,...,Valuen>& x, - const composite_key_result<CompositeKey>& y)const; -}; -
-CompositeKeyResult must be an instantiation of
-composite_key_result for some type
-composite_key<KeyFromValue0,...,KeyFromValuen>.
-composite_key_result_greater<CompositeKeyResult>::operator() is
-then equivalent to
-composite_key_compare<Compare0,...,Comparen>::operator(), taking
-
-- - -Comparei = std::greater<KeyFromValuei::result_type>for all -i = 0,...,n. -
-In addition to the requirements on Comparei imposed by
-composite_key_compare, each of these types must be
-
-Default Constructible. composite_key_result_greater
-is
-Default Constructible and
-Assignable.
-
std::less for
-composite_key results
-std::less<CompositeKeyResult>, for CompositeKeyResult
-being an instantiation of composite_key_result, has the same interface
-and functionality as composite_key_result_less<CompositeKeyResult>.
-
- --namespace std{ - -template<typename CompositeKey> -struct less<boost::multi_index::composite_key_result<CompositeKey> > -{ - typedef - boost::multi_index::composite_key_result< - CompositeKey> first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey1> & x, - const boost::multi_index::composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey>& x, - const boost::tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const boost::tuple<Value0,...,Valuen>& x, - const boost::multi_index::composite_key_result<CompositeKey>& y)const; -}; - -} // namespace std -
std::greater for
-composite_key results
-std::greater<CompositeKeyResult>, for CompositeKeyResult
-being an instantiation of composite_key_result, has the same interface
-and functionality as composite_key_result_greater<CompositeKeyResult>.
-
- --namespace std{ - -template<typename CompositeKey> -struct greater<boost::multi_index::composite_key_result<CompositeKey> > -{ - typedef - boost::multi_index::composite_key_result< - CompositeKey> first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - template<typename CompositeKey1,typename CompositeKey2> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey1> & x, - const boost::multi_index::composite_key_result<CompositeKey2> & y)const; - - template<typename CompositeKey,typename Value0,...,typename Valuen> - bool operator()( - const boost::multi_index::composite_key_result<CompositeKey>& x, - const boost::tuple<Value0,...,Valuen>& y)const; - - template<typename Value0,...,typename Valuen,typename CompositeKey> - bool operator()( - const boost::tuple<Value0,...,Valuen>& x, - const boost::multi_index::composite_key_result<CompositeKey>& y)const; -}; - -} // namespace std -
composite_key_hash
-composite_key_hash produces hash values for composite_key_result
-instantiations based on a collection of elementary hash functors.
-
- --template<typename Hash0,...,typename Hashn> -struct composite_key_hash -{ - typedef tuple<Hash0,...,Hashn> key_hasher_tuple; - - composite_key_hash( - const Hash0& h0=Hash0(), - ... - const Hashn& hn=Hashn()); - - composite_key_hash(const key_hasher_tuple& x); - - const key_hasher_tuple& key_hash_functions()const; - key_hasher_tuple& key_hash_functions(); - - template<typename CompositeKey> - std::size_t operator()( - const composite_key_result<CompositeKey>& x)const; - - template<typename Value0,...,typename Valuen> - std::size_t operator()( - const tuple<Value0,...,Valuen>& x)const; -}; -
-Hash0, ... , Hashn are the types of the hash functors
-stored by composite_key_hash. Each of these types
-must be a
-Unary Function
-returning a value of type std::size_t in the range
-[0, std::numeric_limits<std::size_t>::max()).
-At least a
-hash functor must be provided. The maximum number of hash functors of
-a composite_key_hash instantiation is implementation defined.
-composite_key_hash is
-Assignable.
-It is also
-
-Default Constructible
-if each Hashi is
-
-Default Constructible.
-
-In what follows we use the same notation
-introduced for composite_key_result.
-
-
composite_key_hash memberscomposite_key_hash(
- const Hash0& h0=Hash0(),
- ...
- const Hashn& hn=Hashn());
-
-
-
-Effects: Constructs a composite_key_hash that stores
-copies of the hash functors supplied.
-
-
-composite_key_hash(const key_hasher_tuple& x);
-
--Effects: Constructs a- -composite_key_hashthat stores -copies of the hash functors supplied inx. -
const key_hasher_tuple& key_hash_functions()const;
-
-
-Returns: a constant reference to a tuple holding the
-hash functors internally stored by the
-composite_key_hash.
-
-
-key_hasher_tuple& key_hash_functions();
-
-
-Returns: a reference to a tuple holding the
-hash functors internally stored by the
-composite_key_hash.
-
-
-
-template<typename CompositeKey>
-bool operator()(
- const composite_key_result<CompositeKey>& x)const;
-template<typename Value0,...,typename Valuen>
-bool operator()(
- const tuple<Value0,...,Valuen>& x)const;
-
-
--Requires:- -length(x)==length(key_hash_functions()). -The expression -key_hash_functions().get<i>()(xi)-is valid for alliin[0,length(x)). -
-Returns: A value in the range -[0, std::numeric_limits<std::size_t>::max())that -solely depends on the numerical tuple --(-key_hash_functions().get<0>()(x0), ... , -key_hash_functions().get<N>()(xN)), -withN=length(x)-1. -
composite_key_result_hash
-composite_key_result_hash acts as a particularization of
-composite_key_hash where all the hash functors supplied
-are instantiations of
-boost::hash.
-
- --template<typename CompositeKeyResult> -struct composite_key_result_hash -{ - typedef CompositeKeyResult argument_type; - typedef std::size_t result_type; - - template<typename CompositeKey> - std::size_t operator()( - const composite_key_result<CompositeKey>& x)const; - - template<typename Value0,...,typename Valuen> - std::size_t operator()( - const tuple<Value0,...,Valuen>& x)const; -}; -
-CompositeKeyResult must be an instantiation of
-composite_key_result for some type
-composite_key<KeyFromValue0,...,KeyFromValuen>.
-composite_key_result_hash<CompositeKeyResult>::operator() is
-then equivalent to
-composite_key_hash<Hash0,...,Hashn>::operator(), taking
-
-- - -Hashi = boost::hash<KeyFromValuei::result_type>for all -i = 0,...,n. -
-In addition to the requirements on Hashi imposed by
-composite_key_hash, each of these types must be
-
-Default Constructible. composite_key_result_hash
-is
-Default Constructible and
-Assignable.
-
boost::hash
-for composite_key results
-boost::hash<CompositeKeyResult>, for CompositeKeyResult
-being an instantiation of composite_key_result, has the same interface
-and functionality as composite_key_result_hash<CompositeKeyResult>.
-
- --namespace boost{ - -template<typename CompositeKey> -struct hash<multi_index::composite_key_result<CompositeKey> > -{ - typedef multi_index::composite_key_result<CompositeKey> argument_type; - typedef std::size_t result_type; - - template<typename CompositeKey> - std::size_t operator()( - const multi_index::composite_key_result<CompositeKey>& x)const; - - template<typename Value0,...,typename Valuen> - std::size_t operator()( - const tuple<Value0,...,Valuen>& x)const; -}; - -} // namespace boost -
composite_key_result
-The design of equality, comparison and hash operations for
-composite_key_result objects is based on the following rationale:
-a composite_key_result is regarded as a "virtual" tuple, each
-of its elements being the result of the corresponding elementary
-key extractor. Accordingly, any given operation resolves to a
-combination of the corresponding elementwise operations.
-This mapping preserves the fundamental properties of the elementary operations
-involved; for instance, it defines a true equivalence relation if the
-basic predicates induce equivalence relations themselves.
-We can state these facts in a formal way as follows.
-
-Consider an instantiation of composite_key_equal_to
-with types Pred0, ... , Predn such that each
-Predi induces an equivalence relation on a certain type Ti,
-and let CompositeKey be a type of the form
-composite_key<Value,KeyFromValue0,...,KeyFromValuej>,
-with j <= n, such that
-
--Then,KeyFromValuei::result_type = Ti, for alli = 0,...,j. -
composite_key_equal_to induces an equivalence relation
-on elements of type composite_key_result<CompositeKey>;
-such two objects are equivalent if all its elementary key extractor values
-are also equivalent. Additionally, given an instantiation
-composite_key_hash<Hash0,...,Hashj>, the following types are
-Compatible Keys of
-(composite_key_hash, composite_key_equal_to)
-with respect to composite_key_result<CompositeKey>:
---provided that eachtuple<Q0,...,Qj>,
-composite_key_result<composite_key<K0,...,Kj> >, with -Ki::result_type = Qifor alli = 0,...,j. -
Qi is either Ti or a
-Compatible Key
-of (Hashi, Predi).
-
-
-As for comparison, consider an instantiation of composite_key_compare
-with types Compare0, ... , Comparen such that each
-Comparei is a
-Strict
-Weak Ordering on the type Ti. Then, for a
-CompositeKey type defined in the same manner as above,
-composite_key_compare is a
-Strict
-Weak Ordering on elements of type
-composite_key_result<CompositeKey>, and the order induced
-is lexicographical. Also, the following types are
-Compatible Keys of
-composite_key_compare with respect to
-composite_key_result<CompositeKey>:
-
--provided that eachtuple<Q0,...,Qk>,k <= n
-composite_key_result<composite_key<K0,...,Kk> >, with -Ki::result_type = Qifor alli = 0,...,k. -
Qi is either Ti or a
-Compatible Key
-of Comparei. In this case, the comparison is done
-lexicographically only on the first 1+min(j,k) elements.
-
-
-
-Analogous properties hold for the equality and comparison operators
-of composite_key_result. Note, however,
-that equality is only defined for objects of the same length, whilst
-comparison takes the minimum length of the operands considered.
-Therefore, the equivalence classes induced by x==y are
-subsets of those associated to !(x<y)&&!(y<x).
-
Revised September 5th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/multi_index_container.html b/doc/reference/multi_index_container.html deleted file mode 100644 index 99dbd74..0000000 --- a/doc/reference/multi_index_container.html +++ /dev/null @@ -1,891 +0,0 @@ - - - - - -
Boost.MultiIndex
-multi_index_container reference"boost/multi_index_container_fwd.hpp" synopsis"boost/multi_index_container.hpp" synopsis
-
- "boost/multi_index_container_fwd.hpp"
-synopsis
-- --namespace boost{ - -namespace multi_index{ - -template< - typename Value, - typename IndexSpecifierList=indexed_by<ordered_unique<identity<Value> > >, - typename Allocator=std::allocator<Value> > -class multi_index_container; - -} // namespace boost::multi_index - -using multi_index::multi_index_container; - -} // namespace boost -
-multi_index_container_fwd.hpp forward declares the class template
-multi_index_container and specifies its default parameters.
-
"boost/multi_index_container.hpp"
-synopsis
-- --namespace boost{ - -namespace multi_index{ - -template<typename Value,typename IndexSpecifierList,typename Allocator> -class multi_index_container; - -// multi_index_container associated global class templates: - -template<typename MultiIndexContainer,int N> struct nth_index; -template<typename MultiIndexContainer,typename Tag> struct index; -template<typename MultiIndexContainer,int N> struct nth_index_iterator; -template<typename MultiIndexContainer,int N> struct nth_index_const_iterator; -template<typename MultiIndexContainer,typename Tag> struct index_iterator; -template<typename MultiIndexContainer,typename Tag> struct index_const_iterator; - -// multi_index_container global functions for index retrieval: - -template< - int N,typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type& -get(multi_index_container<Value,IndexSpecifierList,Allocator>& m); - -template< - int N,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename nth_index< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type& -get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m); - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -typename index< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type& -get(multi_index_container<Value,IndexSpecifierList,Allocator>& m); - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename index< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type& -get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m); - -// multi_index_container global functions for projection of iterators: - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type -project( - multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it); - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index_const_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type -project( - const multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it); - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename index_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type -project( - multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it); - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename index_const_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type -project( - const multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it); - -// comparison: - -// OP is any of ==,<,!=,>,>=,<= - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator OP( - const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, - const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y); - -// specialized algorithms: - -template<typename Value,typename IndexSpecifierList,typename Allocator> -void swap( - multi_index_container<Value,IndexSpecifierList,Allocator>& x, - multi_index_container<Value,IndexSpecifierList,Allocator>& y); - -} // namespace boost::multi_index - -using multi_index::multi_index_container; -using multi_index::get; -using multi_index::project; - -} // namespace boost -
multi_index_container
-
-This is the main component of Boost.MultiIndex. A multi_index_container
-is a container class template holding a compile-time user-defined list of
-indices. These indices provide different interfaces
-for the management of the elements of the multi_index_container. By itself,
-multi_index_container only provides basic functionality for construction
-and for access to the indices held.
-
-A multi_index_container type is instantiated with the type of the
-elements contained and a non-empty
-
-MPL Forward Sequence specifying which indices conform the
-class.
-
-For convenience of use, all public methods and types of the first index
-specified are inherited by multi_index_container. This also includes global
-operators and functions associated with the index (vg. comparison and
-swap.)
-
- --template< - typename Value, - typename IndexSpecifierList=indexed_by<ordered_unique<identity<Value> > >, - typename Allocator=std::allocator<Value> > -class multi_index_container -{ -public: - - // types: - - typedef implementation defined ctor_args_list; - typedef implementation defined index_specifier_type_list; - typedef implementation defined index_type_list; - typedef implementation defined iterator_type_list; - typedef implementation defined const_iterator_type_list; - typedef Allocator allocator_type; - - // nested class templates: - - template<int N> - struct nth_index {typedef implementation defined type;}; - template<typename Tag> - struct index {typedef implementation defined type;}; - template<int N> - struct nth_index_iterator {typedef implementation defined type;}; - template<int N> - struct nth_index_const_iterator {typedef implementation defined type;}; - template<typename Tag> - struct index_iterator {typedef implementation defined type;}; - template<typename Tag> - struct index_const_iterator {typedef implementation defined type;}; - - // construct/copy/destroy: - - explicit multi_index_container( - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()); - template<typename InputIterator> - multi_index_container( - InputIterator first,InputIterator last, - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()); - multi_index_container( - const multi_index_container<Value,IndexSpecifierList,Allocator>& x); - - ~multi_index_container(); - - multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( - const multi_index_container<Value,IndexSpecifierList,Allocator>& x); - - allocator_type get_allocator()const; - - // retrieval of indices - - template<int N> typename nth_index<N>::type& get(); - template<int N> const typename nth_index<N>::type& get()const; - template<typename Tag> typename index<Tag>::type& get() - template<typename Tag> const typename index<Tag>::type& get()const; - - // projection of iterators - - template<int N,typename IteratorType> - typename nth_index_iterator<N>::type project(IteratorType it); - template<int N,typename IteratorType> - typename nth_index_const_iterator<N>::type project(IteratorType it)const; - template<typename Tag,typename IteratorType> - typename index_iterator<Tag>::type project(IteratorType it); - template<typename Tag,typename IteratorType> - typename index_const_iterator<Tag>::type project(IteratorType it)const; -}; - -// multi_index_container associated global class templates: - -template<typename MultiIndexContainer,int N> struct nth_index -{ - typedef typename MultiIndexContainer::nth_index<N>::type type; -}; - -template<typename MultiIndexContainer,typename Tag> struct index -{ - typedef typename MultiIndexContainer::index<Tag>::type type; -}; - -template<typename MultiIndexContainer,int N> struct nth_index_iterator -{ - typedef typename MultiIndexContainer::nth_index_iterator<N>::type type; -}; - -template<typename MultiIndexContainer,int N> struct nth_index_const_iterator -{ - typedef typename MultiIndexContainer::nth_index_const_iterator<N>::type type; -}; - -template<typename MultiIndexContainer,typename Tag> struct index_iterator -{ - typedef typename MultiIndexContainer::index_iterator<Tag>::type type; -}; - -template<typename MultiIndexContainer,typename Tag> struct index_const_iterator -{ - typedef typename MultiIndexContainer::index_const_iterator<Tag>::type type; -}; - -// multi_index_container global functions for index retrieval: - -template< - int N,typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type& -get(multi_index_container<Value,IndexSpecifierList,Allocator>& m) -{ - return m.get<N>(); -} - -template< - int N,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename nth_index< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type& -get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m) -{ - return m.get<N>(); -} - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -typename index< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type& -get(multi_index_container<Value,IndexSpecifierList,Allocator>& m) -{ - return m.get<Tag>(); -} - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename index< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type& -get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m) -{ - return m.get<Tag>(); -} - -// multi_index_container global functions for projection of iterators: - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type -project( - multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it) -{ - return m.project<N>(it); -} - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename nth_index_const_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,N ->::type -project( - const multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it) -{ - return m.project<N>(it); -} - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename index_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type -project( - multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it) -{ - return m.project<Tag>(it); -} - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator -> -typename index_const_iterator< - multi_index_container<Value,IndexSpecifierList,Allocator>,Tag ->::type -project( - const multi_index_container<Value,IndexSpecifierList,Allocator>& m, - IteratorType it) -{ - return m.project<Tag>(it); -} - -// comparison: - -// OP is any of ==,<,!=,>,>=,<= - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator OP( - const multi_index_container<Value1,IndexSpecifierList1,Allocator1>& x, - const multi_index_container<Value2,IndexSpecifierList2,Allocator2>& y) - { - return get<0>(x) OP get<0>(y); - } - -// specialized algorithms: - -template<typename Value,typename IndexSpecifierList,typename Allocator> -void swap( - multi_index_container<Value,IndexSpecifierList,Allocator>& x, - multi_index_container<Value,IndexSpecifierList,Allocator>& y) - { - x.swap(y); - } - -} // namespace boost::multi_index - -} // namespace boost -
-In the descriptions of operations of multi_index_container, we adopt the
-scheme outlined in the
-complexity signature section.
-
-multi_index_container is instantiated with the following types:
-
Value is the
- Assignable
- type of the elements contained.IndexSpecifierList specifies the indices that the
- multi_index_container is composed of. It must be a non-empty
-
- MPL Forward Sequence (and, preferrably,
- an
- MPL Random Access Sequence) of index specifiers. For
- syntactic convenience, the
- indexed_by
- MPL sequence can be used.
- Allocator must comply with the C++ requirements for
- allocators [lib.allocator.requirements].
-multi_index_container instantiation cannot have
-duplicate tags, either within a single
-index or in two different indices.
-
-
-ctor_args_list
-
--Although the exact definition of- -ctor_args_listis -implementation defined, from the user point of view this type can be -treated as equivalent to -::boost::tuple<C0,...,CI-1>, -whereCiis thector_argstype of the -i-th index held by themulti_index_container, in the -same order as they were specified. Strictly speaking, there is an -implicit conversion from -const ::boost::tuple<C0,...,CI-1>&-toconst ctor_args_list&. This type is used for -providing the construction arguments of the indices of the -multi_index_container.ctor_args_listis -Default -Constructible, provided that allctor_argstypes -involved are default constructible. -
index_specifier_type_list
-
-
-Same type as IndexSpecifierList.
-
-
-index_type_list
-
--Model of - -- -MPL Random Access Sequenceand - -MPL Extensible Sequencecontaining the types of the indices held by -themulti_index_container, in the same order as they were specified. -
iterator_type_list
-
--Model of - -- -MPL Random Access Sequenceand - -MPL Extensible Sequencecontaining the types of the iterators of -the indices held by themulti_index_container, in the same order as they were -specified. -
const_iterator_type_list
-
--Model of - -- -MPL Random Access Sequenceand - -MPL Extensible Sequencecontaining the types of the constant -iterators of the indices held by themulti_index_container, in the same order -as they were specified. -
template<int N> struct nth_index
-
--- -nth_index<N>::typeyields the type of the -N-th (0-based) index held by themulti_index_container, in -the same order as they were specified.
-Requires:0 <= N < I. -
template<typename Tag> struct index
-
--- -index<Tag>::typeyields the type of the index which -hasTagas an associated tag type. -Requires: Some index of themulti_index_containerhasTag-as an associated tag type. -
template<int N> struct nth_index_iterator
-
--- -nth_index_iterator<N>::typeis equivalent to -nth_index<N>::type::iterator.
-
template<int N> struct nth_index_const_iterator
-
--- -nth_index_const_iterator<N>::typeis equivalent to -nth_index<N>::type::const_iterator.
-
template<typename Tag> struct index_iterator
-
--- -index_iterator<Tag>::typeis equivalent to -index<Tag>::type::iterator.
-
template<typename Tag> struct index_const_iterator
-
--- -index_const_iterator<Tag>::typeis equivalent to -index<Tag>::type::const_iterator.
-
explicit multi_index_container(
- const ctor_args_list& comp=ctor_args_list(),
- const allocator_type& al=allocator_type());
-
--Effects: Constructs an empty- -multi_index_containerusing the -specified argument list and allocator.
-Complexity: Constant. -
template<typename InputIterator>
-multi_index_container(
- InputIterator first,InputIterator last,
- const ctor_args_list& comp=ctor_args_list(),
- const allocator_type& al=allocator_type());
-
--Requires:- -InputIteratoris a model of - -Input Iteratorover elements of type -Valueor a type convertible toValue. -lastis reachable fromfirst. -Effects: Constructs and emptymulti_index_containerusing the -specified argument list and allocator and fills it with -the elements in the range [first,last). -Insertion of each element may or may not succeed depending -on the acceptance by all the indices of themulti_index_container.
-Complexity:O(m*H(m)), wheremis -the number of elements in [first,last).
-
multi_index_container(
- const multi_index_container<Value,IndexSpecifierList,Allocator>& x);
-
--Effects: Constructs a copy of- -x, copying its -elements as well as its internal objects (key extractors, comparison objects, -allocator.)
-Postconditions:*this==x. The order on every index -of themulti_index_containeris preserved as well.
-Complexity:O(x.size()*log(x.size()) + C(x.size())). -
~multi_index_container()
--Effects: Destroys the- -multi_index_containerand all the elements -contained. The order in which the elements are destroyed is not specified.
-Complexity:O(n). -
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
- const multi_index_container<Value,IndexSpecifierList,Allocator>& x);
-
--Replaces the elements and internal objects of the- -multi_index_container-with copies fromx.
-Postconditions:*this==x. The order on every index -of themulti_index_containeris preserved as well.
-Returns:*this.
-Complexity:O(n + x.size()*log(x.size()) + -C(x.size())).
-Exception safety: Strong, provided the copy and assignment operations -of the types ofctor_args_listdo not throw. -
allocator_type get_allocator()const;
-
--Returns a copy of the- -allocator_typeobject used to construct -themulti_index_container.
-Complexity: Constant. -
template<int N> typename nth_index<N>::type& get();
-
--Requires:- -0 <= N < I.
-Effects: Returns a reference to the -nth_index<N>::typeindex held by*this.
-Complexity: Constant.
-Exception safety:nothrow. -
template<int N> const typename nth_index<N>::type& get()const;
-
--Requires:- -0 <= N < I.
-Effects: Returns aconstreference to the -nth_index<N>::typeindex held by*this.
-Complexity: Constant.
-Exception safety:nothrow. -
template<typename Tag> typename index<Tag>::type& get()
-
--Requires:- -Tagis such thatindex<Tag>::type-is valid.
-Effects: Returns a reference to the -index<Tag>::typeindex held by -*this.
-Complexity: Constant.
-Exception safety:nothrow. -
template<typename Tag> const typename index<Tag>::type& get()const;
-
--Requires:- -Tagis such thatindex<Tag>::type-is valid.
-Effects: Returns aconstreference to the -index<Tag>::typeindex held by -*this.
-Complexity: Constant.
-Exception safety:nothrow. -
-Given a multi_index_container with indices i1
-and i2, we say than an i1-iterator
-it1 and an i2-iterator it2
-are equivalent if:
-
it1==i1.end() AND it2==i2.end(),it1 and it2 point to the
- same element.template<int N,typename IteratorType>
-typename nth_index_iterator<N>::type project(IteratorType it);
-
--Requires:- -0 <= N < I.IteratorType-belongs toiterator_type_list.itis a valid -iterator of some index of*this(i.e. does not refer to some -othermulti_index_container.)
-Effects: Returns annth_index_iterator<N>::typeiterator -equivalent toit.
-Complexity: Constant.
-Exception safety:nothrow. -
template<int N,typename IteratorType>
-typename nth_index_const_iterator<N>::type project(IteratorType it)const;
-
--Requires:- -0 <= N < I.IteratorType-belongs toconst_iterator_type_listor -iterator_type_list.itis a -valid (constant or non-constant) iterator of some index of*this-(i.e. does not refer to some othermulti_index_container.)
-Effects: Returns annth_index_const_iterator<N>::type-iterator equivalent toit.
-Complexity: Constant.
-Exception safety:nothrow. -
template<typename Tag,typename IteratorType>
-typename index_iterator<Tag>::type project(IteratorType it);
-
--Requires:- -Tagis such that -index_iterator<Tag>::typeis valid.IteratorType-belongs toiterator_type_list.itis a valid -iterator of some index of*this(i.e. does not refer to some -othermulti_index_container.)
-Effects: Returns anindex_iterator<Tag>::typeiterator -equivalent toit.
-Complexity: Constant.
-Exception safety:nothrow. -
template<typename Tag,typename IteratorType>
-typename index_const_iterator<Tag>::type project(IteratorType it)const;
-
--Requires:- -Tagis such that -index_const_iterator<Tag>::typeis valid.IteratorType-belongs toconst_iterator_type_listor -iterator_type_list.itis a valid -(constant or non-constant) iterator of some index of*this-(i.e. does not refer to some othermulti_index_container.)
-Effects: Returns anindex_const_iterator<Tag>::type-iterator equivalent toit.
-Complexity: Constant.
-Exception safety:nothrow. -
-multi_index_containers can be archived/retrieved by means of
-Boost.Serialization.
-Boost.MultiIndex does not expose a public serialization interface, as this
-is provided by Boost.Serialization itself. Both regular and XML
-archives are supported.
-
-Each of the indices comprising a given multi_index_container contributes
-its own preconditions as well as guarantees on the retrieved containers. In describing
-these, the following concepts are used. A type T is serializable
-(resp. XML-serializable) if any object of type T can be saved to an output
-archive (XML archive) and later retrieved from an input archive (XML archive) associated to
-the same storage. If x' of type T is loaded from the
-serialization information saved from another object x, we say that
-x' is a restored copy of x. Given a
-Binary Predicate
-Pred over (T, T), and objects p
-and q of type Pred, we say that q
-is serialization-compatible with p if
-
-p(x,y) == q(x',y')
-
-for every x and y of type T and x' and
-y' being restored copies of x and y,
-respectively.
-
-
-Operation: saving of a multi_index_container m to an
-output archive (XML archive) ar.
-
--Requires:- -Operation: loading of aValueis serializable (XML-serializable). Additionally, -each of the indices ofmcan impose another requirements.
-Exception safety: Strong with respect tom. If an exception -is thrown,armay be left in an inconsistent state. -
multi_index_container m' from an
-input archive (XML archive) ar.
-
--Requires:- -Valueis serializable (XML-serializable). Additionally, -each of the indices ofm'can impose another requirements.
-Exception safety: Basic. If an exception is thrown,armay be -left in an inconsistent state. -
Revised May 30th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/ord_indices.html b/doc/reference/ord_indices.html deleted file mode 100644 index d345769..0000000 --- a/doc/reference/ord_indices.html +++ /dev/null @@ -1,963 +0,0 @@ - - - - - -
Boost.MultiIndex Ordered indices reference"boost/multi_index/ordered_index_fwd.hpp" synopsis"boost/multi_index/ordered_index.hpp" synopsis
-
- "boost/multi_index/ordered_index_fwd.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// index specifiers ordered_unique and ordered_non_unique - -template<consult ordered_unique reference for arguments> -struct ordered_unique; -template<consult ordered_non_unique reference for arguments> -struct ordered_non_unique; - -// indices - -namespace detail{ - -template<implementation defined> class index name is implementation defined; - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-ordered_index_fwd.hpp provides forward declarations for index specifiers
-ordered_unique and ordered_non_unique and
-their associated ordered index classes.
-
"boost/multi_index/ordered_index.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// index specifiers ordered_unique and ordered_non_unique - -template<consult ordered_unique reference for arguments> -struct ordered_unique; -template<consult ordered_non_unique reference for arguments> -struct ordered_non_unique; - -// indices - -namespace detail{ - -template<implementation defined> class index class name implementation defined; - -// index comparison: - -// OP is any of ==,<,!=,>,>=,<= - -template<arg set 1,arg set 2> -bool operator OP( - const index class name<arg set 1>& x,const index class name<arg set 2>& y); - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
ordered_unique and ordered_non_unique
-
-These index specifiers allow
-for insertion of ordered indices without and with
-allowance of duplicate elements, respectively. The syntax of ordered_unique
-and ordered_non_unique coincide, thus we describe them in a grouped manner.
-ordered_unique and ordered_non_unique can be instantiated in
-two different forms, according to whether a tag list for the index is provided or not:
-
- --template< - typename KeyFromValue, - typename Compare=std::less<KeyFromValue::result_type> -> -struct (ordered_unique | ordered_non_unique); - -template< - typename TagList, - typename KeyFromValue, - typename Compare=std::less<KeyFromValue::result_type> -> -struct (ordered_unique | ordered_non_unique); -
-If provided, TagList must be an instantiation of the class template
-tag.
-The template arguments are used by the corresponding index implementation,
-refer to the ordered indices reference section for further
-explanations on their acceptable type values.
-
-An ordered index provides a set-like interface to the underlying heap of
-elements contained in a multi_index_container. An ordered index is
-particularized according to a given
-Key Extractor
-that retrieves keys from elements of multi_index_container and a comparison
-predicate.
-
-There are two variants of ordered indices: unique, which do -not allow duplicate elements (with respect to its associated comparison -predicate) and non-unique, which accept those duplicates. -The interface of these two variants is the same, so they are documented -together, with minor differences explicitly stated when they exist. -
- -
-Except where noted, ordered indices (both unique and non-unique) are models of
-
-Sorted Associative Container and
-
-Unique Associative Container, much as std::sets
-are. Accordingly, validity of iterators and references to elements is
-preserved. We only provide descriptions of those types and operations that are
-either not present in the concepts modeled or do not exactly conform to the
-requirements for these types of containers.
-
- --namespace boost{ - -namespace multi_index{ - -namespace{ implementation defined unbounded; } // see range() - -namespace detail{ - -template<implementation defined: dependent on types Value, Allocator, - TagList, KeyFromValue, Compare> -class name is implementation defined -{ -public: - // types: - - typedef typename KeyFromValue::result_type key_type; - typedef Value value_type; - typedef KeyFromValue key_from_value; - typedef Compare key_compare; - typedef implementation defined value_compare; - typedef tuple<key_from_value,key_compare> ctor_args; - typedef Allocator allocator_type; - typedef typename Allocator::reference reference; - typedef typename Allocator::const_reference const_reference; - typedef implementation defined iterator; - typedef implementation defined const_iterator; - typedef implementation defined size_type; - typedef implementation defined difference_type; - typedef typename Allocator::pointer pointer; - typedef typename Allocator::const_pointer const_pointer; - typedef equivalent to - std::reverse_iterator<iterator> reverse_iterator; - typedef equivalent to - std::reverse_iterator<const_iterator> const_reverse_iterator; - - // construct/copy/destroy: - - index class name& operator=(const index class name& x); - - allocator_type get_allocator()const; - - // iterators: - - iterator begin(); - const_iterator begin()const; - iterator end(); - const_iterator end()const; - reverse_iterator rbegin(); - const_reverse_iterator rbegin()const; - reverse_iterator rend(); - const_reverse_iterator rend()const; - - // capacity: - - bool empty()const; - size_type size()const; - size_type max_size()const; - - // modifiers: - - std::pair<iterator,bool> insert(const value_type& x); - iterator insert(iterator position,const value_type& x); - template<typename InputIterator> - void insert(InputIterator first,InputIterator last); - - iterator erase(iterator position); - size_type erase(const key_type& x); - iterator erase(iterator first,iterator last); - - bool replace(iterator position,const value_type& x); - template<typename Modifier> bool modify(iterator position,Modifier mod); - template<typename Modifier> bool modify_key(iterator position,Modifier mod); - - void swap(index class name& x); - void clear(); - - // observers: - - key_from_value key_extractor()const; - key_compare key_comp()const; - value_compare value_comp()const; - - // set operations: - - template<typename CompatibleKey> - iterator find(const CompatibleKey& x)const; - template<typename CompatibleKey,typename CompatibleCompare> - iterator find( - const CompatibleKey& x,const CompatibleCompare& comp)const; - - template<typename CompatibleKey> - size_type count(const CompatibleKey& x)const; - template<typename CompatibleKey,typename CompatibleCompare> - size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const; - - template<typename CompatibleKey> - iterator lower_bound(const CompatibleKey& x)const; - template<typename CompatibleKey,typename CompatibleCompare> - iterator lower_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const; - - template<typename CompatibleKey> - iterator upper_bound(const CompatibleKey& x)const; - template<typename CompatibleKey,typename CompatibleCompare> - iterator upper_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const; - - template<typename CompatibleKey> - std::pair<iterator,iterator> equal_range( - const CompatibleKey& x)const; - template<typename CompatibleKey,typename CompatibleCompare> - std::pair<iterator,iterator> equal_range( - const CompatibleKey& x,const CompatibleCompare& comp)const; - - // range: - - template<typename LowerBounder,typename UpperBounder> - std::pair<iterator,iterator> range( - LowerBounder lower,UpperBounder upper)const; -}; - -// index comparison: - -template<arg set 1,arg set 2> -bool operator==( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template<arg set 1,arg set 2> -bool operator<( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template<arg set 1,arg set 2> -bool operator!=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x==y); -} - -template<arg set 1,arg set 2> -bool operator>( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return y<x; -} - -template<arg set 1,arg set 2> -bool operator>=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x<y); -} - -template<arg set 1,arg set 2> -bool operator<=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x>y); -} - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-Here and in the descriptions of operations of ordered indices, we adopt the -scheme outlined in the -complexity signature -section. The complexity signature of ordered indices is: -
c(n)=n*log(n),i(n)=log(n),h(n)=1 (constant) if the hint element
- precedes the point of insertion, h(n)=log(n) otherwise,d(n)=1 (constant),r(n)=1 (constant) if the element position does not
- change, r(n)=log(n) otherwise,m(n)=1 (constant) if the element position does not
- change, m(n)=log(n) otherwise.Ordered indices are instantiated internally to multi_index_container and
-specified by means of indexed_by
-with index specifiers ordered_unique
-and ordered_non_unique. Instantiations are dependent on the
-following types:
-
Value from multi_index_container,Allocator from multi_index_container,TagList from the index specifier (if provided),KeyFromValue from the index specifier,Compare from the index specifier.TagList must be an instantiation of
-tag. The type KeyFromValue,
-which determines the mechanism for extracting a key from Value,
-must be a model of
-Key Extractor from Value. Compare is a
-
-Strict Weak Ordering on elements of
-KeyFromValue::result_type.
-
-
--As explained in the index -concepts section, indices do not have public constructors or destructors. -Assignment, on the other hand, is provided. -
- -index class name& operator=(const index class name& x);
-
--Effects: -- --where-a=b; -aandbare themulti_index_container-objects to which*thisandxbelong, respectively.
-Returns:*this.
-
std::pair<iterator,bool> insert(const value_type& x);
-
--Effects: Inserts- -xinto themulti_index_containerto which -the index belongs if --
-Returns: The return value is a pair- the index is non-unique OR no other element exists with - equivalent key,
-- AND insertion is allowed by all other indices of the -
-multi_index_container.p.p.second-istrueif and only if insertion took place. On successful insertion, -p.firstpoints to the element inserted; otherwise,p.first-points to an element that caused the insertion to be banned. Note that more than -one element can be causing insertion not to be allowed.
-Complexity:O(I(n)).
-Exception safety: Strong.
-
iterator insert(iterator position,const value_type& x);
-
--Requires:- -positionis a valid iterator of the index. -Effects: Insertsxinto themulti_index_containerto which -the index belongs if --
-- the index is non-unique OR no other element exists with - equivalent key,
-- AND insertion is allowed by all other indices of the -
-multi_index_container.positionis used as a hint to improve the efficiency of the -operation.
-Returns: On successful insertion, an iterator to the newly inserted -element. Otherwise, an iterator to an element that caused the insertion to be -banned. Note that more than one element can be causing insertion not to be -allowed.
-Complexity:O(H(n)).
-Exception safety: Strong.
-
template<typename InputIterator>
-void insert(InputIterator first,InputIterator last);
-
--Requires:- -InputIteratoris a model of - -Input Iteratorover elements of type -value_typeor a type convertible tovalue_type. -firstandlastare not iterators into any -index of themulti_index_containerto which this index belongs. -lastis reachable fromfirst. -Effects: --Complexity:-iterator hint=end(); -while(first!=last)hint=insert(hint,*first++); -O(m*H(n+m)), where -mis the number of elements in [first, -last).
-Exception safety: Basic.
-
iterator erase(iterator position);
-
--Requires:- -positionis a valid dereferenceable iterator -of the index. -Effects: Deletes the element pointed to byposition.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, orend()-if no such element exists.
-Complexity:O(D(n)).
-Exception safety:nothrow.
-
size_type erase(const key_type& x);
-
--Effects: Deletes the elements with key equivalent to- -x.
-Returns: Number of elements deleted.
-Complexity:O(log(n) + m*D(n)), wheremis -the number of elements deleted.
-Exception safety: Basic.
-
iterator erase(iterator first,iterator last);
-
--Requires: [- -first,last) is a valid -range of the index.
-Effects: Deletes the elements in [first,last).
-Returns:last.
-Complexity:O(log(n) + m*D(n)), wheremis -the number of elements in [first,last).
-Exception safety:nothrow.
-
bool replace(iterator position,const value_type& x);
-
--Requires:- - -positionis a valid dereferenceable iterator -of the index. -Effects: Assigns the valuexto the element pointed -to bypositioninto themulti_index_containerto which -the index belongs if, for the valuex--
-Postconditions: Validity of- the index is non-unique OR no other element exists - (except possibly
-*position) with equivalent key,- AND replacing is allowed by all other indices of the -
-multi_index_container.positionis preserved -in all cases.
-Returns:trueif the replacement took place, -falseotherwise.
-Complexity:O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation themulti_index_containerto which the index -belongs remains in its original state. -
template<typename Modifier> bool modify(iterator position,Modifier mod);
-
--Requires:- - -Modifieris a model of - -Unary Functionaccepting arguments of type -value_type&.positionis a valid dereferenceable -iterator of the index. -Effects: Callsmod(e)whereeis the element -pointed to bypositionand rearranges*positioninto -all the indices of themulti_index_container. Rearrangement is successful if --
-If the rearrangement fails, the element is erased.- the index is non-unique OR no other element exists - with equivalent key,
-- AND rearrangement is allowed by all other indices of the -
-multi_index_container.
-Postconditions: Validity ofpositionis preserved if the -operation succeeds.
-Returns:trueif the operation succeeded,false-otherwise.
-Complexity:O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possiblymod), then -the element pointed to bypositionis erased. -
template<typename Modifier> bool modify_key(iterator position,Modifier mod);
-
--Requires:- -key_from_valueis a read/write -Key Extractor-fromvalue_type.Modifieris a model of - -Unary Functionaccepting arguments of type -key_type&.positionis a valid dereferenceable -iterator of the index. -Effects: Callsmod(k)wherekis the key -obtained by the internalKeyFromValueobject of the index from -the element pointed to byposition, and rearranges -*positioninto all the indices of themulti_index_container. -Rearrangement is successful if --
-If the rearrangement fails, the element is erased.- the index is non-unique OR no other element exists - with equivalent key,
-- AND rearrangement is allowed by all other indices of the -
-multi_index_container.
-Postconditions:Validity ofpositionis preserved if -the operation succeeds.
-Returns:trueif the operation succeeded,false-otherwise.
-Complexity:O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possiblymod), then -the element pointed to bypositionis erased. -
Apart from standard key_comp and value_comp,
-ordered indices have a member function for retrieving the internal key extractor
-used.
-
key_from_value key_extractor()const;
-
--Returns a copy of the- -key_from_valueobject used to construct -the index.
-Complexity: Constant. -
-Ordered indices provide the full lookup functionality required by
-
-Sorted Associative Containers and
-
-Unique Associative Containers, namely find,
-count, lower_bound, upper_bound
-and equal_range. Additionally, these member functions are
-templatized to allow for non-standard arguments, so extending
-the types of search operations allowed. The kind of arguments permissible
-when invoking the lookup member functions is defined by the following
-concept.
-
-Consider a
-
-Strict Weak Ordering Compare over values
-of type Key. A pair of types (CompatibleKey,
-CompatibleCompare) is said to be a compatible extension
-of Compare if
-
CompatibleCompare is a
-
- Binary Predicate over (Key,
- CompatibleKey),CompatibleCompare is a
-
- Binary Predicate over (CompatibleKey,
- Key),c_comp(ck,k1) then !c_comp(k1,ck),!c_comp(ck,k1) and !comp(k1,k2) then
- !c_comp(ck,k2),!c_comp(k1,ck) and !comp(k2,k1) then
- !c_comp(k2,ck),c_comp of type CompatibleCompare,
-comp of type Compare, ck of type
-CompatibleKey and k1, k2 of type
-Key.
-
-
-
-
-Additionally, a type CompatibleKey is said to be a
-compatible key of Compare if (CompatibleKey,
-Compare) is a compatible extension of Compare.
-This implies that Compare, as well as being a strict
-weak ordering, accepts arguments of type CompatibleKey,
-which usually means it has several overloads of operator().
-
-In the context of a compatible extension or a compatible key, the expressions -"equivalent", "less than" and "greater than" take on their obvious -interpretations. -
- -template<typename CompatibleKey> iterator find(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -key_compare. -Effects: Returns a pointer to an element whose key is equivalent to -x, orend()if such an element does not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey,typename CompatibleCompare>
-iterator find(const CompatibleKey& x,const CompatibleCompare& comp)const;
-
-
--Requires: (- -CompatibleKey,CompatibleCompare) -is a compatible extension ofkey_compare. -Effects: Returns a pointer to an element whose key is equivalent to -x, orend()if such an element does not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey> size_type
-count(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -key_compare. -Effects: Returns the number of elements with key equivalent tox.
-Complexity:O(log(n) + count(x)).
-
template<typename CompatibleKey,typename CompatibleCompare>
-size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const;
-
-
--Requires: (- -CompatibleKey,CompatibleCompare) -is a compatible extension ofkey_compare. -Effects: Returns the number of elements with key equivalent tox.
-Complexity:O(log(n) + count(x,comp)).
-
template<typename CompatibleKey>
-iterator lower_bound(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -key_compare. -Effects: Returns an iterator pointing to the first element with -key not less thanx, orend()if such an element does -not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey,typename CompatibleCompare>
-iterator lower_bound(const CompatibleKey& x,const CompatibleCompare& comp)const;
-
-
--Requires: (- -CompatibleKey,CompatibleCompare) -is a compatible extension ofkey_compare. -Effects: Returns an iterator pointing to the first element with -key not less thanx, orend()if such an element does -not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey>
-iterator upper_bound(const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -key_compare. -Effects: Returns an iterator pointing to the first element with -key greater thanx, orend()if such an element does -not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey,typename CompatibleCompare>
-iterator upper_bound(const CompatibleKey& x,const CompatibleCompare& comp)const;
-
-
--Requires: (- -CompatibleKey,CompatibleCompare) -is a compatible extension ofkey_compare. -Effects: Returns an iterator pointing to the first element with -key greater thanx, orend()if such an element does -not exist.
-Complexity:O(log(n)).
-
template<typename CompatibleKey>
-std::pair<iterator,iterator> equal_range(
- const CompatibleKey& x)const;
-
-
--Requires:- -CompatibleKeyis a compatible key of -key_compare. -Effects: Equivalent tomake_pair(lower_bound(x),upper_bound(x)).
-Complexity:O(log(n)).
-
template<typename CompatibleKey,typename CompatibleCompare>
-std::pair<iterator,iterator> equal_range(
- const CompatibleKey& x,const CompatibleCompare& comp)const;
-
-
--Requires: (- - -CompatibleKey,CompatibleCompare) -is a compatible extension ofkey_compare. -Effects: Equivalent to -make_pair(lower_bound(x,comp),upper_bound(x,comp)).
-Complexity:O(log(n)).
-
-The member function range is not defined for sorted associative
-containers, but ordered indices provide it as a convenient utility. A range
-or interval is defined by two conditions for the lower and upper bounds, which
-are modeled after the following concepts.
-
-Consider a
-
-Strict Weak Ordering Compare over values
-of type Key. A type LowerBounder is said to be
-a lower bounder of Compare if
-
LowerBounder is a
-
- Predicate over Key,lower(k1) and !comp(k2,k1) then
- lower(k2),lower of type LowerBounder,
-comp of type Compare, and k1,
-k2 of type Key. Similarly, an upper bounder
-is a type UpperBounder such that
-UpperBounder is a
-
- Predicate over Key,upper(k1) and !comp(k1,k2) then
- upper(k2),upper of type UpperBounder,
-comp of type Compare, and k1,
-k2 of type Key.
-
-
-template<typename LowerBounder,typename UpperBounder>
-std::pair<iterator,iterator> range(
- LowerBounder lower,UpperBounder upper)const;
-
-
--Requires:- -LowerBounderandUpperBounderare -a lower and upper bounder ofkey_compare, respectively. -Effects: Returns a pair of iterators pointing to the beginning and one -past the end of the subsequence of elements satisfyinglowerand -uppersimultaneously. If no such elements exist, the iterators -both point to the first element satisfyinglower, or else -are equal toend()if this latter element does not exist.
-Complexity:O(log(n)).
-Variants: In place oflowerorupper(or both), -the singular valueboost::multi_index::unboundedcan be -provided. This acts as a predicate which all values of typekey_type-satisfy.
-
-Indices cannot be serialized on their own, but only as part of the
-multi_index_container into which they are embedded. In describing
-the additional preconditions and guarantees associated to ordered indices
-with respect to serialization of their embedding containers, we
-use the concepts defined in the multi_index_container
-serialization section.
-
multi_index_container m to an
-output archive (XML archive) ar.
-
--Requires: No additional requirements to those imposed by the container. -- -Operation: loading of a
multi_index_container m' from an
-input archive (XML archive) ar.
-
--Requires: Additionally to the general requirements,- -Operation: saving of anvalue_comp()-must be serialization-compatible withm.get<i>().value_comp(), -whereiis the position of the ordered index in the container.
-Postconditions: On succesful loading, each of the elements of -[begin(),end()) is a restored copy of the corresponding -element in [m.get<i>().begin(),m.get<i>().end()). -
iterator or const_iterator
-it to an output archive (XML archive) ar.
-
--Requires:- -Operation: loading of anitis a valid iterator of the index. The associated -multi_index_containerhas been previously saved. -
iterator or const_iterator
-it' from an input archive (XML archive) ar.
-
--Postconditions: On succesful loading, if- -itwas dereferenceable -then*it'is the restored copy of*it, otherwise -it'==end().
-Note: It is allowed thatitbe aconst_iterator-and the restoredit'aniterator, or viceversa. -
Revised August 24th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/reference/seq_indices.html b/doc/reference/seq_indices.html deleted file mode 100644 index 15c1260..0000000 --- a/doc/reference/seq_indices.html +++ /dev/null @@ -1,892 +0,0 @@ - - - - - -
Boost.MultiIndex Sequenced indices reference"boost/multi_index/sequenced_index_fwd.hpp" synopsis"boost/multi_index/sequenced_index.hpp" synopsis
-
- "boost/multi_index/sequenced_index_fwd.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// sequenced index specifier - -template<typename TagList=tag<> > struct sequenced; - -// indices - -namespace detail{ - -template<implementation defined> class index class name implementation defined; - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-sequenced_index_fwd.hpp provides forward declarations for the
-sequenced index specifier and
-its associated sequenced index class.
-
"boost/multi_index/sequenced_index.hpp" synopsis- --namespace boost{ - -namespace multi_index{ - -// sequenced index specifier - -template<typename TagList=tag<> > struct sequenced; - -// indices - -namespace detail{ - -template<implementation defined> class index class name implementation defined; - -// index comparison: - -// OP is any of ==,<,!=,>,>=,<= - -template<arg set 1,arg set 2> -bool operator OP( - const index class name<arg set 1>& x,const index class name<arg set 2>& y); - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
sequenced index specifier
--This index specifier allows for insertion of a sequenced -index.
- -- --template<typename TagList=tag<> > struct sequenced; -
If provided, TagList must be an instantiation of
-tag.
-
-Sequenced indices are modeled after the semantics of a bidirectional list
-like std::list. Elements in a sequenced index are by default
-sorted according to their order of insertion: this means that new elements
-inserted through a different index of the multi_index_container are appended
-to the end of the sequenced index. Additionally, the index allows for free
-reordering of elements in the same vein as std::list does. Validity
-of iterators and references to elements is preserved in all operations.
-
-There are a number of differences with respect to std::lists:
-
Assignable (like any other index.)std::list, insertions into a sequenced index
- may fail due to clashings with other indices. This alters the semantics
- of the operations provided with respect to their analogues in
- std::list.
- replace and
- modify member functions.
- Reversible Container,
-
-Front Insertion Sequence and
-
-Back Insertion Sequence. We only provide descriptions
-of those types and operations that are that are either not present in the
-concepts modeled or do not exactly conform to the requirements for these
-types of containers.
-
-
-- --namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template<implementation defined: dependent on types Value, Allocator, TagList> -class name is implementation defined -{ -public: - // types: - - typedef typename node_type::value_type value_type; - typedef tuples::null_type ctor_args; - typedef typename Allocator allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef implementation defined iterator; - typedef implementation defined const_iterator; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef equivalent to - std::reverse_iterator<iterator> reverse_iterator; - typedef equivalent to - std::reverse_iterator<const_iterator> const_reverse_iterator; - - // construct/copy/destroy: - - index class name& operator=(const index class name& x); - - template <class InputIterator> - void assign(InputIterator first,InputIterator last); - void assign(size_type n,const value_type& value); - - allocator_type get_allocator()const; - - // iterators: - - iterator begin(); - const_iterator begin()const; - iterator end(); - const_iterator end()const; - reverse_iterator rbegin(); - const_reverse_iterator rbegin()const; - reverse_iterator rend(); - const_reverse_iterator rend()const; - - // capacity: - - bool empty()const; - size_type size()const; - size_type max_size()const; - - void resize(size_type n,const value_type& x=value_type()); - - // access: - - const_reference front()const; - const_reference back()const; - - // modifiers: - - std::pair<iterator,bool> push_front(const value_type& x); - void pop_front(); - std::pair<iterator,bool> push_back(const value_type& x); - void pop_back(); - - std::pair<iterator,bool> insert(iterator position,const value_type& x); - void insert(iterator position,size_type n,const value_type& x); - template<typename InputIterator> - void insert(iterator position,InputIterator first,InputIterator last); - - iterator erase(iterator position); - iterator erase(iterator first,iterator last); - - bool replace(iterator position,const value_type& x); - template<typename Modifier> bool modify(iterator position,Modifier mod); - - void swap(index class name& x); - - void clear(); - - // list operations: - - void splice(iterator position,index class name& x); - void splice(iterator position,index class name& x,iterator i); - void splice( - iterator position,index class name& x,iterator first,iterator last); - - void remove(const value_type& value); - template<typename Predicate> void remove_if(Predicate pred); - - void unique(); - template <class BinaryPredicate> - void unique(BinaryPredicate binary_pred); - - void merge(index class name& x); - template <typename Compare> void merge(index class name& x,Compare comp); - - void sort(); - template <typename Compare> void sort(Compare comp); - - void reverse(); - - // relocate operations: - - void relocate(iterator position,iterator i); - void relocate(iterator position,iterator first,iterator last); -} - -// index comparison: - -template<arg set 1,arg set 2> -bool operator==( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template<arg set 1,arg set 2> -bool operator<( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template<arg set 1,arg set 2> -bool operator!=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x==y); -} - -template<arg set 1,arg set 2> -bool operator>( - const index class name<arg set 1>& x - ,const index class name<arg set 2>& y) -{ - return y<x; -} - -template<arg set 1,arg set 2> -bool operator>=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x<y); -} - -template<arg set 1,arg set 2> -bool operator<=( - const index class name<arg set 1>& x, - const index class name<arg set 2>& y) -{ - return !(x>y); -} - -// index specialized algorithms: - -template<implementation defined> -void swap(index class name& x,index class name& y); - -} // namespace boost::multi_index::detail - -} // namespace boost::multi_index - -} // namespace boost -
-Here and in the descriptions of operations of sequenced indices, we adopt the -scheme outlined in the -complexity signature -section. The complexity signature of sequenced indices is: -
c(n)=n*log(n),i(n)=1 (constant),h(n)=1 (constant),d(n)=1 (constant),r(n)=1 (constant),m(n)=1 (constant).Sequenced indices are instantiated internally to multi_index_container
-and specified by means of
-indexed_by with the sequenced
-index specifier. Instantiations are dependent on the following types:
-
Value from multi_index_container,Allocator from multi_index_container,TagList from the index specifier (if provided).TagList must be an instantiation of
-tag.
-
-
--As explained in the index -concepts section, indices do not have public constructors or destructors. -Assignment, on the other hand, is provided. -
- -index class name& operator=(const index class name& x);
-
--Effects: -- --where-a=b; -aandbare themulti_index_container-objects to which*thisandxbelong, respectively.
-Returns:*this.
-
template <class InputIterator>
-void assign(InputIterator first,InputIterator last);
-
--Requires:- -InputIteratoris a model of - -Input Iteratorover elements of type -value_typeor a type convertible tovalue_type. -firstandlastare not iterators into any -index of themulti_index_containerto which this index belongs. -lastis reachable fromfirst. -Effects: ---clear(); -insert(end(),first,last); -
void assign(size_type n,const value_type& value);
-
--Effects: -- ---clear(); -for(size_type i=0;i<n;++n)push_back(v); -
void resize(size_type n,const value_type& x=value_type());
-
--Effects: -- --Note: If an expansion is requested, the size of the index is not guaranteed -to be-if(n>size())insert(end(),n-size(),x); -else if(n<size())erase(begin()+n,end()); -nafter this operation (other indices may ban insertions.) -
std::pair<iterator,bool> push_front(const value_type& x);
-
--Effects: Inserts- -xat the beginning of the sequence if -no other index of themulti_index_containerbans the insertion.
-Returns: The return value is a pairp.p.second-istrueif and only if insertion took place. On successful -insertion,p.firstpoints to the element inserted; otherwise, -p.firstpoints to an element that caused the insertion to be banned. -Note that more than one element can be causing insertion not to be allowed.
-Complexity:O(I(n)).
-Exception safety: Strong. -
std::pair<iterator,bool> push_back(const value_type& x);
-
--Effects: Inserts- -xat the end of the sequence if -no other index of themulti_index_containerbans the insertion.
-Returns: The return value is a pairp.p.second-istrueif and only if insertion took place. On successful -insertion,p.firstpoints to the element inserted; otherwise, -p.firstpoints to an element that caused the insertion to be banned. -Note that more than one element can be causing insertion not to be allowed.
-Complexity:O(I(n)).
-Exception safety: Strong. -
std::pair<iterator,bool> insert(iterator position,const value_type& x);
-
--Requires:- -positionis a valid iterator of the index. -Effects: Insertsxbeforepositionif insertion -is allowed by all other indices of themulti_index_container.
-Returns: The return value is a pairp.p.second-istrueif and only if insertion took place. On successful -insertion,p.firstpoints to the element inserted; otherwise, -p.firstpoints to an element that caused the insertion to be banned. -Note that more than one element can be causing insertion not to be allowed.
-Complexity:O(I(n)).
-Exception safety: Strong. -
void insert(iterator position,size_type n,const value_type& x);
-
--Requires:- -positionis a valid iterator of the index. -Effects: ---for(size_type i=0;i<n;++i)insert(position,x); -
template<typename InputIterator>
-void insert(iterator position,InputIterator first,InputIterator last);
-
--Requires:- -positionis a valid iterator of the index. -InputIteratoris a model of - -Input Iteratorover elements of type -value_typeor a type convertible tovalue_type. -firstandlastare not iterators into any -index of themulti_index_containerto which this index belongs. -lastis reachable fromfirst. -Effects: --Complexity:-while(first!=last)insert(position,*first++); -O(m*I(n+m)), wheremis the -number of elements in [first,last).
-Exception safety: Basic. -
iterator erase(iterator position);
-
--Requires:- -positionis a valid dereferenceable iterator -of the index. -Effects: Deletes the element pointed to byposition.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, orend()-if no such element exists.
-Complexity:O(D(n)).
-Exception safety:nothrow.
-
iterator erase(iterator first,iterator last);
-
--Requires: [- -first,last) is a valid -range of the index.
-Effects: Deletes the elements in [first,last).
-Returns:last.
-Complexity:O(m*D(n)), wheremis -the number of elements in [first,last).
-Exception safety:nothrow.
-
bool replace(iterator position,const value_type& x);
-
--Requires:- - -positionis a valid dereferenceable iterator -of the index. -Effects: Assigns the valuexto the element pointed -to bypositioninto themulti_index_containerto which -the index belongs if replacing is allowed by all other indices of the -multi_index_container.
-Postconditions: Validity ofpositionis preserved -in all cases.
-Returns:trueif the replacement took place, -falseotherwise.
-Complexity:O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation themulti_index_containerto which the index -belongs remains in its original state. -
template<typename Modifier> bool modify(iterator position,Modifier mod);
-
--Requires:- -Modifieris a model of - -Unary Functionaccepting arguments of type -value_type&.positionis a valid dereferenceable -iterator of the index. -Effects: Callsmod(e)whereeis the element -pointed to bypositionand rearranges*positioninto -all the indices of themulti_index_container. Rearrangement on sequenced -indices does not change the position of the element with respect to the index; -rearrangement on other indices may or might not suceed. If the rearrangement -fails, the element is erased.
-Postconditions: Validity ofpositionis preserved if the -operation succeeds.
-Returns:trueif the operation succeeded,false-otherwise.
-Complexity:O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possiblymod), then -the element pointed to bypositionis erased. -
-Sequenced indices provides the full set of list operations provided by
-std::list; the semantics of these member functions, however,
-differ from that of std::list in some cases as insertions
-might not succeed due to banning by other indices. Similarly, the complexity
-of the operations may depend on the other indices belonging to the
-same multi_index_container.
-
void splice(iterator position,index class name& x);
-
--Requires:- -positionis a valid iterator of the index. -&x!=this. -Effects: Inserts the contents ofxbeforeposition, -in the same order as they were inx. Those elements succesfully -inserted are erased fromx.
-Complexity:O(x.size()*I(n+x.size()) + x.size()*D(x.size())).
-Exception safety: Basic.
-
void splice(iterator position,index class name& x,iterator i);
-
--Requires:- -positionis a valid iterator of the index. -iis a valid dereferenceable iteratorx.
-Effects: Inserts the element pointed to byibefore -position: if insertion is succesful, the element is erased from -x. In the special case&x==this, no copy or -deletion is performed, and the operation is always succesful. If -position==i, no operation is performed.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this, constant; otherwise -O(I(n) + D(n)).
-Exception safety: If&x==this,nothrow; -otherwise, strong.
-
void splice(iterator position,index class name& x,iterator first,iterator last);
-
--Requires:- -positionis a valid iterator of the index. -firstandlastare valid iterators ofx. -lastis reachable fromfirst.position-is not in the range [first,last).
-Effects: For each element in the range [first,last), -insertion is tried beforeposition; if the operation is succesful, -the element is erased fromx. In the special case -&x==this, no copy or deletion is performed, and insertions are -always succesful.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this, constant; otherwise -O(m*I(n+m) + m*D(x.size()))wheremis the number -of elements in [first,last).
-Exception safety: If&x==this,nothrow; -otherwise, basic.
-
void remove(const value_type& value);
-
--Effects: Erases all elements of the index which compare equal to -- -value.
-Complexity:O(n + m*D(n)), wherem-is the number of elements erased.
-Exception safety: Basic. -
template<typename Predicate> void remove_if(Predicate pred);
-
--Effects: Erases all elements- -xof the index for which -pred(x)holds..
-Complexity:O(n + m*D(n)), wherem-is the number of elements erased.
-Exception safety: Basic. -
void unique();
-
--Effects: Eliminates all but the first element from every consecutive -group of equal elements referred to by the iterator- -iin the range -[first+1,last) for which*i==*(i-1).
-Complexity:O(n + m*D(n)), wherem-is the number of elements erased.
-Exception safety: Basic. -
template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
-
--Effects: Eliminates all but the first element from every consecutive -group of elements referred to by the iterator- -iin the range -[first+1,last) for which -binary_pred(*i,*(i-1))holds.
-Complexity:O(n + m*D(n)), wherem-is the number of elements erased.
-Exception safety: Basic. -
void merge(index class name& x);
-
--Requires:- -std::less<value_type>is a - -Strict Weak Orderingovervalue_type. -Both the index andxare sorted according to -std::less<value_type>.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according to the order). Elements -successfully inserted are erased fromx. The resulting sequence -is stable, i.e. equivalent elements of either container preserve their -relative position. In the special case&x==this, no operation -is performed.
-Postconditions: Elements in the index and remaining elements in -xare sorted. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
-Complexity: If&x==this, constant; otherwise -O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
-Exception safety: If&x==this,nothrow; -otherwise, basic.
-
template <typename Compare> void merge(index class name& x,Compare comp);
-
--Requires:- -Compareis a - -Strict Weak Orderingovervalue_type. -Both the index andxare sorted according tocomp.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according tocomp). -Elements successfully inserted are erased fromx. The resulting -sequence is stable, i.e. equivalent elements of either container preserve -their relative position. In the special case&x==this, no -operation is performed.
-Postconditions: Elements in the index and remaining elements in -xare sorted according tocomp. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
-Complexity: If&x==this, constant; otherwise -O(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
-Exception safety: If&x==this,nothrow; -otherwise, basic.
-
void sort();
-
--Requires:- -std::less<value_type>is a - -Strict Weak Orderingovervalue_type.
-Effects: Sorts the index according to -std::less<value_type>. The sorting is stable, i.e. -equivalent elements preserve their relative position.
-Postconditions: Validity of iterators and references is preserved.
-Complexity:O(n*log(n)).
-Exception safety:nothrowif -std::less<value_type>does not throw; otherwise, basic. -
template <typename Compare> void sort(Compare comp);
-
--Requires:- -Compareis a - -Strict Weak Orderingovervalue_type.
-Effects: Sorts the index according tocomp. The sorting -is stable, i.e. equivalent elements preserve their relative position.
-Postconditions: Validity of iterators and references is preserved.
-Complexity:O(n*log(n)).
-Exception safety:nothrowifcompdoes -not throw; otherwise, basic. -
void reverse();
-
--Effects: Reverses the order of the elements in the index.- -
-Postconditions: Validity of iterators and references is preserved.
-Complexity:O(n).
-Exception safety:nothrow. -
-Sequenced indices provide some convenience member functions without
-counterparts in std::list. These operations are aimed at
-improving the usability of sequenced indices in points where
-the support offered by standard list operations is insufficient or
-difficult to use.
-
void relocate(iterator position,iterator i);
-
--Requires:- -positionis a valid iterator of the index. -iis a valid dereferenceable iterator of the index.
-Effects: Inserts the element pointed to byibefore -position. Ifposition==i, no operation is -performed.
-Postconditions: No iterator or reference is invalidated.
-Complexity: Constant.
-Exception safety:nothrow.
-
void relocate(iterator position,iterator first,iterator last);
-
--Requires:- -positionis a valid iterator of the index. -firstandlastare valid iterators of the index. -lastis reachable fromfirst.position-is not in the range [first,last).
-Effects: The range of elements [first,last) -is repositioned just beforeposition.
-Postconditions: No iterator or reference is invalidated.
-Complexity: Constant.
-Exception safety:nothrow.
-
-Indices cannot be serialized on their own, but only as part of the
-multi_index_container into which they are embedded. In describing
-the additional preconditions and guarantees associated to sequenced indices
-with respect to serialization of their embedding containers, we
-use the concepts defined in the multi_index_container
-serialization section.
-
multi_index_container m to an
-output archive (XML archive) ar.
-
--Requires: No additional requirements to those imposed by the container. -- -Operation: loading of a
multi_index_container m' from an
-input archive (XML archive) ar.
-
--Requires: No additional requirements to those imposed by the container.- -Operation: saving of an
-Postconditions: On succesful loading, each of the elements of -[begin(),end()) is a restored copy of the corresponding -element in [m.get<i>().begin(),m.get<i>().end()), -whereiis the position of the sequenced index in the container. -
iterator or const_iterator
-it to an output archive (XML archive) ar.
-
--Requires:- -Operation: loading of anitis a valid iterator of the index. The associated -multi_index_containerhas been previously saved. -
iterator or const_iterator
-it' from an input archive (XML archive) ar.
-
--Postconditions: On succesful loading, if- -itwas dereferenceable -then*it'is the restored copy of*it, otherwise -it'==end().
-Note: It is allowed thatitbe aconst_iterator-and the restoredit'aniterator, or viceversa. -
Revised August 22nd 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/release_notes.html b/doc/release_notes.html deleted file mode 100644 index 398e24e..0000000 --- a/doc/release_notes.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - -
Boost.MultiIndex Release notes-
erase(it) and
- erase(first,last) now return an iterator to the element
- following those being deleted (previously nothing was returned), in
- accordance with the C++ Standard Library
- Defect
- Report 130 and issue 6.19 of TR1
- Issues
- List.
- -
multi_index_containers and clear
- memfuns now perform faster.
- Revised September 5th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/style.css b/doc/style.css deleted file mode 100644 index 99e7da3..0000000 --- a/doc/style.css +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright 2003-2004 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) - */ - -pre{ - BORDER-RIGHT: gray 1pt solid; - PADDING-RIGHT: 2pt; - BORDER-TOP: gray 1pt solid; - DISPLAY: block; - PADDING-LEFT: 2pt; - PADDING-BOTTOM: 2pt; - BORDER-LEFT: gray 1pt solid; - MARGIN-RIGHT: 32pt; - PADDING-TOP: 2pt; - BORDER-BOTTOM: gray 1pt solid; - FONT-FAMILY: "Courier New", Courier, mono; - background-color: #EEEEEE; -} - -table{ - PADDING-RIGHT: 2pt; - BORDER-TOP: gray 1pt solid; - DISPLAY: block; - PADDING-LEFT: 2pt; - PADDING-BOTTOM: 2pt; - BORDER-LEFT: gray 1pt solid; - MARGIN-RIGHT: 32pt; - PADDING-TOP: 2pt; - background-color: #EEEEEE; -} -td{ - BORDER-STYLE: solid; - BORDER-WIDTH: 1pt; - BORDER-LEFT: ; - BORDER-RIGHT: gray 1pt solid; - BORDER-TOP: ; - BORDER-BOTTOM: gray 1pt solid; -} -th{color: #ffffff; background-color: #000000;} -.odd_tr{background-color: #ffffff;} - -.keyword{color: #0000FF;} -.identifier{} -.comment{font-style: italic; color: #008000;} -.special{color: #800040;} -.preprocessor{color: #3F007F;} -.string{font-style: italic; color: #666666;} -.literal{font-style: italic; color: #666666;} - -.prev_link{width: 30%; float: left; text-align: left;} -.up_link{width: 39.9%; float: left; text-align: center;} -.next_link{width: 30%; float: left; text-align: right;} diff --git a/doc/tests.html b/doc/tests.html deleted file mode 100644 index 4aa6f57..0000000 --- a/doc/tests.html +++ /dev/null @@ -1,157 +0,0 @@ - - - - - -
Boost.MultiIndex Tests-The Boost.MultiIndex test suite exercises the whole spectrum of -functionalities provided by the library. Although the tests are not meant -to serve as a learning guide, the interested reader may find it -useful to inspect the source code to gain familiarity -with some of the least common features offered by Boost.MultiIndex. -
- --
| Program | -Description | -
|---|---|
test_basic.cpp |
- Simple program along the lines of the employees example studied in the - tutorial. | -
test_capacity.cpp |
- empty, size and (sequenced indices only)
- resize. |
-
test_comparison.cpp |
- Comparison between indices. | -
test_composite_key.cpp |
- composite_key and composite_key_compare. |
-
test_conv_iterators.cpp |
- Checks convertibility of non-constant to constant iterators. | -
test_copy_assignment.cpp |
- Various forms of assignment: copy, operator =, insertion,
- (sequenced indices only) assign .
- |
test_hash_ops.cpp |
- Hashing operations. | -
test_iterators.cpp |
- Constant and non-constant iterators and their reverse variants. | -
test_key_extractors.cpp |
- Covers all use cases of key extractors shipped with the library. | -
test_list_ops.cpp |
- List-like operations particular to sequenced indices. | -
test_modifiers.cpp |
- Checks the family of insertion and erasing operations. | -
test_mpl_ops.cpp |
- Metaprogramming manipulations of multi_index_container types. |
-
test_observers.cpp |
- Checks observer member functions of ordered and hashed indices. | -
test_projection.cpp |
- Projection of iterators among indices. | -
test_range.cpp |
- Exercises the range facility (ordered indices only). |
-
test_safe_mode.cpp |
- Comprehensive coverage of all conditions checked in safe mode. | -
test_serialization.cpp |
- Serialization support. | -
test_set_ops.cpp |
- Set-like operations particular to ordered indices. | -
test_special_list_ops.cpp |
- Convenience functions of sequenced indices not present in
- std::list. |
-
test_special_set_ops.cpp |
- Checks special lookup operations using compatible sorting criteria. | -
test_update.cpp |
- replace, modify and modify_key. |
-
Revised July 27th 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/tutorial.html b/doc/tutorial.html deleted file mode 100644 index df1a38e..0000000 --- a/doc/tutorial.html +++ /dev/null @@ -1,1292 +0,0 @@ - - - - - -
Boost.MultiIndex Tutorial
-STL containers are designed around the concept that each container controls its
-own collection of elements, giving access to them in a manner specified by the
-container's type: so, an std::set maintains the elements ordered
-by a specified sorting criterium, std::list allows for free
-positioning of elements along a linear sequence, and so on.
-
-Sometimes, the necessity arises of having different access interfaces
-to the same underlying collection: for instance, some data might need to be
-sorted according to more than one comparison predicate, or a bidirectional list
-might benefit from a supplemental logarithmic lookup interface. In these
-situations, programmers typically resort to manual compositions of different
-containers, a solution that generally involves a fair amount of code
-devoted to preserve the synchronization of the different parts of
-the composition. Boost.MultiIndex allows for the specification of
-multi_index_containers comprised of one or more indices with
-different interfaces to the same collection of elements. The resulting constructs
-are conceptually cleaner than manual compositions, and often perform much better.
-An important design decision has been taken that the indices of a given
-multi_index_container instantiation be specified at compile time: this
-gives ample room for static type checking and code optimization.
-
-Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the
-theory of relational databases, though it is not intended to provide a full-fledged
-relational database framework. multi_index_container integrates seamlessly
-into the STL container/algorithm design, and features some extra capabilities regarding
-lookup operations and element updating which are useful extensions even for
-single-indexed containers.
-
-
-Fig. 1: Diagram of a multi_index_container with three indices.
-
-The figure above depicts a multi_index_container composed of three indices:
-the first two present a set-like interface to the elements sorted by
-shape and id, respectively, while the latter index provides the functionality
-of a bidirectional list in the spirit of std::list. These
-indices act as "views" to the internal collection of elements, but they do not only
-provide read access to the set: insertion/deletion methods are also implemented much
-as those of std::sets or std::lists. Insertion of an
-element through one given index will only succeed if the uniqueness constraints of all
-indices are met.
-
-All the types of Boost.MultiIndex reside in namespace ::boost::multi_index.
-Additionaly, the main class template multi_index_container and global functions
-get and project are lifted to namespace ::boost
-by means of using declarations. For brevity of exposition, the fragments
-of code in the documentation are written as if the following declarations were in effect:
-
- --using namespace ::boost; -using namespace ::boost::multi_index; -
-We introduce the main concepts of Boost.MultiIndex through the study of -two typical use cases. -
- --STL sets and multisets are varying-length containers where elements are efficiently -sorted according to a given comparison predicate. These container classes fall short -of functionality when the programmer wishes to efficiently sort and look up the elements -following a different sorting criterium. Consider for instance: -
- -- --struct employee -{ - int id; - std::string name; - - employee(int id,const std::string& name):id(id),name(name){} - - bool operator<(const employee& e)const{return id<e.id;} -}; -
The fact that IDs are unique to each employee is reflected by the way
-operator< is defined, so a natural data structure for storing of
-employees is just a std::set<employee>. Now,
-if one wishes to print out a listing of all employees in alphabetical order, available
-solutions may have disadvantages either in terms of storage space, complexity or ease
-of maintenance:
-
employee::name.
-
-Boost.MultiIndex features ordered indices, which
-sort the elements according to a particular key, and are designed to help programmers
-in need of sequences of elements for which more than one sorting criteria are
-relevant. We do so by defining a multi_index_container
-instantiation composed of several ordered indices: each index, viewed in isolation,
-behaves much as an ordered std::set (or std::multiset), whilst
-the overall integrity of the entire data structure is preserved. Our example problem
-thus can be solved with Boost.MultiIndex as follows:
-
- --// define a multiply indexed set with indices by id and name -typedef multi_index_container< - employee, - indexed_by< - // sort by employee::operator< - ordered_unique<identity<employee> >, - - // sort by less<string> on name - ordered_non_unique<member<employee,std::string,&employee::name> > - > -> employee_set; - -void print_out_by_name(const employee_set& es) -{ - // get a view to index #1 (name) - const employee_set::nth_index<1>::type& name_index=es.get<1>(); - // use name_index as a regular std::set - std::copy( - name_index.begin(),name_index.end(), - std::ostream_iterator<employee>(std::cout)); -} -
-Instead of a single comparison predicate type, as it happens for STL associative
-containers, multi_index_container is passed a typelist of index
-specifications (indexed_by), each one inducing the corresponding index.
-Indices are accessed via
-get<N>()
-where N ranges between 0 and the number of comparison
-predicates minus one. The functionality of index #0 can be accessed directly from an
-multi_index_container object without using get<0>(): for instance,
-es.begin() is equivalent to es.get<0>().begin().
-
-Note that get returns a reference to the index, and not
-an index object. Indices cannot be constructed as separate objects from the
-container they belong to, so the following
-
- --// Wrong: we forgot the & after employee_set::nth_index<1>::type -const employee_set::nth_index<1>::type name_index=es.get<1>(); -
-does not compile, since it is trying to construct the index object
-name_index. This is a common source of errors in user code.
-
-This study case allows us to introduce so-called -sequenced indices, and how they -interact with ordered indices to construct powerful containers. Suppose -we have a text parsed into words and stored in a list like this: -
- -- --typedef std::list<std::string> text_container; - -std::string text= - "Alice was beginning to get very tired of sitting by her sister on the " - "bank, and of having nothing to do: once or twice she had peeped into the " - "book her sister was reading, but it had no pictures or conversations in " - "it, 'and what is the use of a book,' thought Alice 'without pictures or " - "conversation?'"; - -// feed the text into the list -text_container tc; -boost::tokenizer<boost::char_separator<char> > tok - (text,boost::char_separator<char>(" \t\n.,;:!?'\"-")); -std::copy(tok.begin(),tok.end(),std::back_inserter(tc)); -
-If we want to count the occurrences of a given word into the text we will resort
-to std::count:
-
- --std::size_t occurrences(const std::string& word) -{ - return std::count(tc.begin(),tc.end(),word); -} -
-But this implementation of occurrences performs in linear time, which
-could be unacceptable for large quantities of text. Similarly, other operations like
-deletion of selected words are just too costly to carry out on a
-std::list:
-
- --void delete_word(const std::string& word) -{ - tc.remove(word); // scans the entire list looking for word -} -
-When performance is a concern, we will need an additional data structure that indexes
-the elements in tc, presumably in alphabetical order. Boost.MultiIndex
-does precisely this through the combination of sequenced and ordered indices:
-
- --// define a multi_index_container with a list-like index and an ordered index -typedef multi_index_container< - std::string, - indexed_by< - sequenced<>, // list-like index - ordered_non_unique<identity<std::string> > // words by alphabetical order - > -> text_container; - -std::string text=... - -// feed the text into the list -text_container tc; -boost::tokenizer<boost::char_separator<char> > tok - (text,boost::char_separator<char>(" \t\n.,;:!?'\"-")); -std::copy(tok.begin(),tok.end(),std::back_inserter(tc)); -
-So far, the substitution of multi_index_container for std::list
-does not show any advantage. The code for inserting the text into the container
-does not change as sequenced indices provide an interface similar to that of
-std::list (no explicit access to this index through
-get<0>() is needed as multi_index_container inherits the
-functionality of index #0.) But the specification of an additional ordered index
-allows us to implement occurrences and delete_word
-in a much more efficient manner:
-
- --std::size_t occurrences(const std::string& word) -{ - // get a view to index #1 - text_container::nth_index<1>::type& sorted_index=tc.get<1>(); - - // use sorted_index as a regular std::set - return sorted_index.count(word); -} - -void delete_word(const std::string& word) -{ - // get a view to index #1 - text_container::nth_index<1>::type& sorted_index=tc.get<1>(); - - // use sorted_index as a regular std::set - sorted_index.erase(word); -} -
-Now, occurrences and delete_word have logarithmic
-complexity. The programmer can use index #0 for accessing the text as with
-std::list, and use index #1 when logarithmic lookup is needed.
-
-The indices of a multi_index_container instantiation are specified by
-means of the
-indexed_by construct. For instance, the instantiation
-
- --typedef multi_index_container< - employee, - indexed_by< - ordered_unique<identity<employee> >, - ordered_non_unique<member<employee,std::string,&employee::name> > - > -> employee_set; -
-is comprised of a unique ordered index and a -non-unique ordered index, while in -
- -- --typedef multi_index_container< - std::string, - indexed_by< - sequenced<>, - ordered_non_unique<identity<std::string> > - > -> text_container; -
-we specifiy two indices, the first of sequenced type,
-the second a non-unique ordered index. In general, we
-can specify an arbitrary number of indices: each of the arguments of
-indexed_by is called an
-index specifier.
-Depending on the type of index being specified, the corresponding specifier
-will need additional information: for instance, the specifiers ordered_unique
-and ordered_non_unique are provided with a
-key extractor and an optional
-comparison predicate which jointly indicate
-how the sorting of elements will be performed.
-
-A multi_index_container instantiation can be declared without supplying
-the indexed_by part: in this case, default index values are taken
-so that the resulting type is equivalent to a regular std::set.
-Concretely, the instantiation
-
- --multi_index_container<(element)> -
-is equivalent to -
- -- --multi_index_container< - (element), - indexed_by< - ordered_unique<identity<(element)> > - > -> -
-In order to retrieve (a reference to) an index of a given multi_index_container,
-the programmer must provide its order number, which is cumbersome and not very
-self-descriptive. Optionally, indices can be assigned tags (C++ types) that
-act as more convenient mnemonics. If provided, tags must be passed as the
-first parameter of the corresponding index specifier. The following is a revised version of
-employee_set with inclusion of tags:
-
- --// tags -struct name{}; - -typedef multi_index_container< - employee, - indexed_by< - ordered_unique<identity<employee> >, - ordered_non_unique<tag<name>,member<employee,std::string,&employee::name> > - > -> employee_set; -
-Tags have to be passed inside the tag construct. Any type can be
-used as a tag for an index, although in general one will choose names that are
-descriptive of the index they are associated with. The tagging mechanism allows
-us to write expressions like
- --typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name::iterator it=es.get<name>().begin(); -
-If no tag is provided for an index (as is the case for index #0 of the previous
-example), access to that index can only be performed by number. Note the existence
-of two different typedefs nth_index and
-index for referring to an index by number and by tag, respectively;
-for instance,
-
employee_set::nth_index<1>::type is the type of
- index #1,employee_set::index<name>::type is the type of the index
- tagged with name (the same index #1 in this case.)get(), on the other hand, is overloaded to serve both styles of access:
-
-
-- --employee_set::index<name>::type& name_index=es.get<name>(); -employee_set::nth_index<1>::type& name_index2=es.get<1>(); // same index -
-Additionally, the tag class template accepts several tags for one
-index, that we can use interchangeably: for instance, the specification of index #1
-in the previous example can be rewritten to hold two different tags
-name and by_name:
-
- --// tags -struct name{}; -struct by_name{}; - -typedef multi_index_container< - ... - ordered_non_unique< - tag<name,by_name>, - member<employee,std::string,&employee::name> - > - ... -> employee_set; -
-Currently, Boost.MultiIndex provides the following index types: -
std::sets do and
- provide a similar interface. There are unique and non-unique
- variants: the former do not allow for duplicates, while the latter permit
- them (like std::multiset.)hash_sets provided
- by some vendors. Recently, unordered associative containers have been
- proposed as part of an extension of the C++ standard library known
- in the standardization commitee as TR1. Hashed indices closely model this
- proposal.std::list: they arrange the elements as if in a bidirectional
- list.
-Ordered indices sort the elements in a multi_index_container according
-to a specified key and an associated comparison predicate. These indices can
-be viewed as analogues of the standard container std::set, and in fact
-they do replicate its interface, albeit with some minor differences dictated
-by the general constraints of Boost.MultiIndex.
-
-Ordered indices are classified into unique, which prohibit two -elements to have the same key value, and non-unique indices, -which allow for duplicates. Consider again the definition -
- -- --typedef multi_index_container< - employee, - indexed_by< - ordered_unique<identity<employee> >, - ordered_non_unique<member<employee,std::string,&employee::name> > - > -> employee_set; -
-In this instantiation of multi_index_container, the first index is to be
-treated as unique (since IDs are exclusive to each employee) and thus is declared using
-ordered_unique, whereas the second index is non-unique (as the possibility exists
-that say two John Smiths are hired in the same company), which is specified by the use
-of ordered_non_unique.
-
-The classification of ordered indices in unique and non-unique has an impact on which
-elements are allowed to be inserted into a given multi_index_container; briefly put,
-unique ordered indices mimic the behavior of std::sets while non-unique
-ordered indices are similar to std::multisets. For instance, an
-employee_set can hold the objects employee(0,"George Brown")
-and employee(1,"George Brown"), but will not accept the insertion of an
-employee object whose ID coincides with that of some previously inserted
-employee.
-
-More than one unique index can be specified. For instance, if we augment
-employee to include an additional member for the Social Security number,
-which is reasonably treated as unique, the following captures this design:
-
- --struct employee -{ - int id; - std::string name; - int ssnumber; - - employee(int id,const std::string& name,int ssnumber): - id(id),name(name),ssnumber(ssnumber){} - - bool operator<(const employee& e)const{return id<e.id;} -}; - -typedef multi_index_container< - employee, - indexed_by< - // sort by employee::operator< - ordered_unique<identity<employee> >, - - // sort by less<string> on name - ordered_non_unique<member<employee,std::string,&employee::name> >, - - // sort by less<int> on ssnumber - ordered_unique<member<employee,int,&employee::ssnumber> > - > -> employee_set; -
-Ordered index specifiers in indexed_by must conform to one of the
-following syntaxes:
-
- --(ordered_unique | ordered_non_unique) - <[(tag)[,(key extractor)[,(comparison predicate)]]]> - -(ordered_unique | ordered_non_unique) - <[(key extractor)[,(comparison predicate)]]> -
-The first optional argument is used if tags are associated -with the index. We now proceed to briefly discuss the remaining arguments -of an ordered index specifier. -
- -
-The first template parameter (or the second, if tags are supplied)
-in the specification of an ordered index provides a key extraction predicate.
-This predicate takes a whole element (in our example, a reference to an
-employee object) and returns the piece of information by which
-the sorting is performed. In most cases, one of the following two situations arises:
-
employee_set. The predefined
-identity predicate
-can be used here as a key extractor; identity returns as the key the
-same object passed as argument.member, which returns
-as the key a member of the element specified by a given pointer.employee_set. The
-definition of the first index:
-
-
-- --ordered_unique<identity<employee> > -
-specifies by means of identity that element
-objects themselves serve as key for this index. On the other hand, in the second
-index:
-
- --ordered_non_unique<member<employee,std::string,&employee::name> > -
-we use member to extract the name part of the
-employee object. The key type of this index is then
-std::string.
-
-Another common situation arises when the sorting is performed on the result
-of a particular member function. This resembles the notion of
-calculated indices supported by some relational databases.
-In these cases, the key is not a data member of the element, but rather it is
-a value returned by a particular member function. Boost.MultiIndex supports this
-kind of key extraction through
-const_mem_fun.
-Consider the following extension of our example where sorting on the third index
-is based upon the length of the name field:
-
- --struct employee -{ - int id; - std::string name; - - employee(int id,const std::string& name):id(id),name(name){} - - bool operator<(const employee& e)const{return id<e.id;} - - // returns the length of the name field - std::size_t name_length()const{return name.size();} -}; - -typedef multi_index_container< - employee, - indexed_by< - // sort by employee::operator< - ordered_unique<identity<employee> >, - - // sort by less<string> on name - ordered_non_unique<member<employee,std::string,&employee::name> >, - - // sort by less<int> on name_length() - ordered_non_unique< - const_mem_fun<employee,std::size_t,&employee::name_length> - > - > -> employee_set; -
Example 2 in the examples section
-provides a complete program showing how to use const_mem_fun.
-Almost always you will want to use a const member function,
-since elements in a multi_index_container are treated as constant, much
-as elements of an std::set. However, a
-mem_fun
-counterpart is provided for use with non-constant member functions, whose
-applicability is discussed on the paragraph on
-advanced features
-of Boost.MultiIndex key extractors in the advanced topics section.
-
- -
-More complex scenarios may require the use of
-composite keys combining the results of several key extractors.
-Composite keys are supported by Boost.MultiIndex through the
-composite_key
-construct.
-
-identity, member and const_mem_fun
-(occasionally combined with composite_key) serve
-most common situations in the design of a multi_index_container. However, the
-user is free to provide her own key extractors in more exotic situations, as long as
-these conform to the Key
-Extractor concept. For instance,
-example 6 implements several key
-extraction techniques called for when elements and/or keys are accessed via
-pointers.
-
-The last part of the specification of an ordered index is the associated
-comparison predicate, which must order the keys in a less-than fashion.
-These comparison predicates are not different from those used by STL containers like
-std::set. By default (i.e. if no comparison predicate is provided),
-an index with keys of type key_type sorts the elements by
-std::less<key_type>. Should other comparison criteria be needed,
-they can be specified as an additional parameter in the index declaration:
-
- --// define a multiply indexed set with indices by id and by name -// in reverse alphabetical order -typedef multi_index_container< - employee, - indexed_by< - ordered_unique<identity<employee> >, // as usual - ordered_non_unique< - member<employee,std::string,&employee::name>, - std::greater<std::string> // default would be std::less<std::string> - > - > -> employee_set; -
-A given ordered index allows for lookup based on its key type, rather than the
-whole element. For instance, to find Veronica Cruz in an
-employee_set one would write:
-
- --employee_set es; -... -typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name::iterator it=es.get<name>().find("Veronica Cruz"); -
As a plus, Boost.MultiIndex provides lookup operations accepting search keys
-different from the key_type of the index, which is a specially useful
-facility when key_type objects are expensive to create. Ordered STL containers
-fail to provide this functionality, which often leads to inelegant workarounds: consider for
-instance the problem of determining the employees whose IDs fall in the range [0,100]. Given
-that the key of employee_set index #0
-is employee itself, on a first approach one would write the following:
-
- --employee_set::iterator p0=es.lower_bound(employee(0,"")); -employee_set::iterator p1=es.upper_bound(employee(100,"")); -
-Note however that std::less<employee> actually only depends
-on the IDs of the employees, so it would be more convenient to avoid
-the creation of entire employee objects just for the sake of
-their IDs. Boost.MultiIndex allows for this: define an appropriate
-comparison predicate
-
- --struct comp_id -{ - // compare an ID and an employee - bool operator()(int x,const employee& e2)const{return x<e2.id;} - - // compare an employee and an ID - bool operator()(const employee& e1,int x)const{return e1.id<x;} -}; -
and now write the search as
- -- --employee_set::iterator p0=es.lower_bound(0,comp_id()); -employee_set::iterator p1=es.upper_bound(100,comp_id()); -
-Here we are not only passing IDs instead of employee objects:
-an alternative comparison predicate is passed as well. In general, lookup operations
-of ordered indices are overloaded to accept
-compatible sorting
-criteria. The somewhat cumbersone definition of compatibility in this context
-is given in the reference, but roughly speaking we say that a comparison predicate
-C1 is compatible with C2 if any sequence sorted by
-C2 is also sorted with respect to C1.
-The following shows a more interesting use of compatible predicates:
-
- --// sorting by name's initial -struct comp_initial -{ - bool operator()(char ch,const std::string& s)const{ - if(s.empty())return false; - return ch<s[0]; - } - - bool operator()(const std::string& s,char ch)const{ - if(s.empty())return true; - return s[0]<ch; - } -}; - -// obtain first employee whose name begins with 'J' (ordered by name) -typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); -employee_set_by_name::const_iterator it= - name_index.lower_bound('J',comp_initial()); -
-Range searching, i.e. the lookup of all elements in a given interval, is a very
-frequent operation for which standard lower_bound and
-upper_bound can be resorted to, though in a cumbersome manner.
-For instance, the following code retrieves the elements of an
-multi_index_container<double> in the interval [100,200]:
-
- --typedef multi_index_container<double> double_set; -// note: default template parameters resolve to -// multi_index_container<double,indexed_by<unique<identity<double> > > >. - -double_set s; -... -double_set::iterator it0=s.lower_bound(100.0); -double_set::iterator it1=s.upper_bound(200.0); -// range [it0,it1) contains the elements in [100,200] -
-Subtle changes to the code are required when strict inequalities are considered. -To retrieve the elements greater than 100 and less than 200, the -code has to be rewritten as -
- -- --double_set::iterator it0=s.upper_bound(100.0); -double_set::iterator it1=s.lower_bound(200.0); -// range [it0,it1) contains the elements in (100,200) -
-To add to this complexity, the careful programmer has to take into account
-that the lower and upper bounds of the interval searched be compatible: for
-instance, if the lower bound is 200 and the upper bound is 100, the iterators
-it0 and it1 produced by the code above will be in reverse
-order, with possibly catastrophic results if a traversal from it0
-to it1 is tried. All these details make range searching a tedious
-and error prone task.
-
-The range
-member function, often in combination with
-Boost.Lambda expressions, can
-greatly help alleviate this situation:
-
- --using namespace boost::lambda; - -typedef multi_index_container<double> double_set; -double_set s; -... -std::pair<double_set::iterator,double_set::iterator> p= - s.range(100.0<=_1,_1<=200); // 100<= x <=200 -... -p=s.range(100.0<_1,_1<200); // 100< x < 200 -... -p=s.range(100.0<=_1,_1<200); // 100<= x < 200 -
-range simply accepts predicates specifying the lower and upper bounds
-of the interval searched. Please consult the reference for a detailed explanation
-of the permissible predicates passed to range.
-One or both bounds can be omitted with the special unbounded marker:
-
- --p=s.range(100.0<=_1,unbounded); // 100 <= x -p=s.range(unbounded,_1<200.0); // x < 200 -p=s.range(unbounded,unbounded); // equiv. to std::make_pair(s.begin(),s.end()) -
-The replace member function
-performs in-place replacement of a given element as the following example shows:
-
- --typedef index<employee_set,name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); - -employee_set_by_name::iterator it=name_index.find("Anna Jones"); -employee anna=*it; -anna.name="Anna Smith"; // she just got married to Calvin Smith -name_index.replace(it,anna); // update her record -
-replace performs this substitution in such a manner that:
-
multi_index_container
-remains unchanged if some exception (originated by the system or the user's data
-types) is thrown.
-replace is a powerful operation not provided by standard STL
-containers, and one that is specially handy when strong exception-safety is
-required.
-
-
-
-The observant reader might have noticed that the convenience of replace
-comes at a cost: namely the whole element has to be copied twice to do
-the updating (when retrieving it and inside replace). If elements
-are expensive to copy, this may be quite a computational cost for the modification
-of just a tiny part of the object. To cope with this situation, Boost.MultiIndex
-provides an alternative updating mechanism called
-modify:
-
- --struct change_name -{ - change_name(const std::string& new_name):new_name(new_name){} - - void operator()(employee& e) - { - e.name=new_name; - } - -private: - std::string new_name; -}; -... -typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); - -employee_set_by_name::iterator it=name_index.find("Anna Jones"); -name_index.modify(it,change_name("Anna Smith")); -
modify accepts a functor (or pointer to function) that is
-passed a reference to the element to be changed, thus eliminating the need
-for spurious copies. Like replace, modify does preserve
-the internal orderings of all the indices of the multi_index_container.
-However, the semantics of modify is not entirely equivalent to
-replace. Consider what happens if a collision occurs as a result
-of modifying the element, i.e. the modified element clashes with another with
-respect to some unique ordered index. In the case of replace, the
-original value is kept and the method returns without altering the container, but
-modify cannot afford such an approach, since the modifying functor
-leaves no trace of the previous value of the element. Integrity constraints
-thus lead to the following policy: when a collision happens in the
-process of calling modify, the element is erased and the method returns
-false. This difference in behavior between replace and
-modify has to be considered by the programmer on a case-by-case basis.
-
-A key-based version of modify, named
-modify_key, is
-provided as well. In this case, the modifying functor is passed a reference to
-the key_value part of the element instead of the whole object. Note
-that modify_key cannot be used for key extractors which return calculated
-values instead of references to data members of the elements, such
-as const_mem_fun.
-
- --struct change_str -{ - change_str(const std::string& new_str):new_str(new_str){} - - // note this is passed a string, not an employee - void operator()(std::string& str) - { - str=new_str; - } - -private: - std::string new_str; -}; -... -typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); - -employee_set_by_name::iterator it=name_index.find("Anna Jones"); -name_index.modify_key(it,change_str("Anna Smith")); -
-Just as modify does, modify_key erases the element if
-the modification results in collisions in some index. modify and
-modify_key are particularly well suited to use in conjunction to
-Boost.Lambda
-for defining the modifying functors:
-
- --using namespace boost::lambda; - -typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); - -employee_set_by_name::iterator it=name_index.find("Anna Jones"); -name_index.modify_key(it,_1="Anna Smith"); -
-Unlike ordered indices, sequenced indices do not impose a fixed order on the
-elements: instead, these can be arranged in any position on the sequence, in the
-same way as std::list permits. The interface of sequenced indices
-is thus designed upon that of std::list; nearly every operation
-provided in the standard container is replicated here, occasionally with changes
-in the syntax and/or semantics to cope with the constraints imposed by
-Boost.MultiIndex. In particular, there is an important limitation of sequenced
-indices with respect to std::lists, namely that elements of an
-multi_index_container are not mutable through an iterator:
-
- --multi_index_container< - int, - indexed_by<sequenced<> > -> s; // list-like container - -s.push_front(0); -*(s.begin())==1; // ERROR: the element cannot be changed -
-That is, iterators of a sequenced index (of all types of indices, actually)
-point to constant elements. This limitation might come as a surprise, but
-it is imposed by the way multi_index_containers work; if elements were
-allowed to be changed in this manner, we could introduce inconsistencies
-in other ordered indices of the multi_index_container. Element modification
-can nevertheless be done by means of
-update operations.
-
-Consider a multi_index_container with two or more indices, one of them
-of sequenced type. If an element is inserted through another index,
-then it will be automatically appended to the end of the sequenced index.
-An example will help to clarify this:
-
- --multi_index_container< - int, - indexed_by< - sequenced<>, // sequenced type - ordered_unique<identity<int> > // another index - > -> s; - -s.get<1>().insert(1); // insert 1 through index #1 -s.get<1>().insert(0); // insert 0 through index #1 - -// list elements through sequenced index #0 -std::copy(s.begin(),s.end(),std::ostream_iterator<int>(std::cout)); - -// result: 1 0 -
-Thus the behavior of sequenced indices when insertions are not made through -them is to preserve insertion order. -
- -
-Sequenced indices are specified with the sequenced construct:
-
- --sequenced<[(tag)]> -
-The tag parameter is optional. -
- -
-As mentioned before, sequenced indices mimic the interface of
-std::list, and most of the original operations therein are
-provided as well. The semantics and complexity of these operations, however,
-do not always coincide with those of the standard container. Differences
-result mainly from the fact that insertions into a sequenced index are not
-guaranteed to succeed, due to the possible banning by other indices
-of the multi_index_container. Consult the
-reference for further details.
-
-Like ordered indices, sequenced indices provide
-replace and
-modify
-operations, with identical functionality. There is however no analogous
-modify_key, since sequenced indices are not key-based.
-
-Given indices i1 and i2 on the same multi_index_container,
-project can be used to
-retrieve an i2-iterator from an i1-iterator, both of them
-pointing to the same element of the container. This functionality allows the programmer to
-move between different indices of the same multi_index_container when performing
-elaborate operations:
-
- --typedef employee_set::index<name>::type employee_set_by_name; -employee_set_by_name& name_index=es.get<name>(); - -// list employees by ID starting from Robert Brown's ID - -employee_set_by_name::iterator it1=name_index.find("Robert Brown"); - -// obtain an iterator of index #0 from it1 -employee_set::iterator it2=es.project<0>(it1); - -std::copy(it2,es.end(),std::ostream_iterator<employee>(std::cout)); -
-A slightly more interesting example: -
- -- --text_container tc; - -// get a view to index #1 (ordered index on the words) -text_container::nth_index<1>::type& sorted_index=tc.get<1>(); - -// prepend "older" to all occurrences of "sister" - -text_container::nth_index_iterator<1>::type it1= - sorted_index.lower_bound("sister"); - -while(it1!=sorted_index.end()&&*it1=="sister"){ - // convert to an iterator to the sequenced index - text_container::iterator it2=tc.project<0>(it1); - - tc.insert(it2,"older"); - ++it1; -} -
-When provided, project can also be used with
-tags.
-
-multi_index_container provides the same complexity and exception safety
-guarantees as the equivalent STL containers do. Iterator and reference validity
-is preserved in the face of insertions, even for replace and modify operations.
-
-Appropriate instantiations of multi_index_container can in fact simulate
-std::set, std::multiset and (with more limitations)
-std::list, as shown in the
-advanced topics
-section. These simulations are as nearly as efficient as the original STL
-containers; consult the reference for further
-information on complexity guarantees and the
-performance section for practical measurements of
-efficiency.
-
Revised March 31st 2005
- -© Copyright 2003-2005 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) -
- - - diff --git a/doc/up.gif b/doc/up.gif deleted file mode 100644 index acb3777..0000000 Binary files a/doc/up.gif and /dev/null differ diff --git a/example/Jamfile b/example/Jamfile deleted file mode 100644 index f14722a..0000000 --- a/example/Jamfile +++ /dev/null @@ -1,57 +0,0 @@ -# Boost.MultiIndex examples Jamfile -# -# Copyright 2003-2005 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) -# -# See http://www.boost.org/libs/multi_index for library home page. - -subproject libs/multi_index/example ; - -exe basic - : basic.cpp - :