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 Documentation - Acknowledgements - - - - -

boost.png (6897 bytes)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. -
-

- -

Boost 1.33 release

- -

-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 Documentation - Advanced topics - - - - -

boost.png (6897 bytes)Boost.MultiIndex Advanced topics

- - - -
- -
- -

Contents

- - - -

Hashed indices

- -

-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: -

-Check the reference for a -complete specification of the interface of hashed indices, -and example 8 and -example 9 for practical applications. -

- -

- -

Unique and non-unique variants

- -

-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. -

- -

Specification

- -

-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. -

- -

Lookup

- -

-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. -

- -

Updating

- -

-Hashed indices have -replace, -modify and -modify_key -member functions, with the same functionality as in ordered indices. -

- -

Guarantees on iterator validity and exception safety

- -

-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: -

-In general, these stronger guarantees play in favor of the user's convenience, -specially that which refers to iterator stability. A (hopefully minimal) -degradation in performance might result in exchange for these commodities, -though. -

- -

Composite keys

- -

-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 and hashed indices

- -

-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. -

- -

Advanced features of Boost.MultiIndex key -extractors

- -

-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: -

-In general, chained pointers with dereferencing distance greater than 1 are not -likely to be used in a normal program, but they can arise in frameworks -which construct "views" as 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. -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Use cases for Boost.MultiIndex key extractors.
element type key key extractorapplicable to
const elements?
read/write?
Timember<T,int,&T::i>yesyes
jmember<T,const int,&T::j>yesno
f()const_mem_fun<T,int,&T::f>yesno
g()mem_fun<T,int,&T::g>nono
reference_wrapper<T>imember<T,int,&T::i>yesyes
jmember<T,const int,&T::j>yesno
f()const_mem_fun<T,int,&T::f>yesno
g()mem_fun<T,int,&T::g>yesno
reference_wrapper<const T>imember<T,const int,&T::i>yesno
jmember<T,const int,&T::j>yesno
f()const_mem_fun<T,int,&T::f>yesno
g() 
chained pointer to T
- or to reference_wrapper<T>
imember<T,int,&T::i>yesyes
jmember<T,const int,&T::j>yesno
f()const_mem_fun<T,int,&T::f>yesno
g()mem_fun<T,int,&T::g>yesno
chained pointer to const T
- or to reference_wrapper<const T>
imember<T,const int,&T::i>yesno
jmember<T,const int,&T::j>yesno
f()const_mem_fun<T,int,&T::f>yesno
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. -

- -

Use of 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. -

- -

Serialization

- -

-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. -

- - -

Debugging support

- -

-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: -

-These two modes are independent of each other and can be set on or off -individually. It is important to note that errors detected by safe mode are -due in principle to faulty code in the user's program, while -invariant-checking mode detects potential internal bugs in the -implementation of Boost.MultiIndex. -

- -

Safe mode

- -

-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. -

- -

Serialization and safe mode

- -

-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);
-
- -

Invariant-checking mode

- -

-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. -

- -

Emulating standard containers with - multi_index_container

- -

Emulation of associative -containers

- -

-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. -

- -

Emulation of 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<> > >
-
- -

Metaprogramming and 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. -

- -

MPL analysis

- -

-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: -

-Each of these types is an MPL sequence with as many elements as indices -comprise the 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. -

- -

MPL synthesis

- -

-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 Documentation - Compiler specifics - - - - -

boost.png (6897 bytes)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. -

- -

Contents

- - - -

Borland C++ Builder 6.4

- -

-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. -

- -

Comeau C/C++ 4.3.3 for Windows (VC++ 7.0/7.1 backend)

- -

-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. -

- -

Compaq C++ 6.5-042 for Tru64 UNIX

- -

-No problems have been detected with this compiler. -

- -

GNU GCC 3.2 and later

- -

-No problems have been detected with several versions of this compiler -starting from 3.2. The following versions have been explicitly tested: -

-Boost.MultiIndex does not work with versions 3.1 and prior of GCC. -

- -

GNU GCC for Tru64 UNIX

- -

-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. -

- -

Darwin GCC 4.0

- -

-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. -

- -

HP aC++ A.06.00 for HP-UX

- -

-No problems have been detected with this compiler. -

- -

IBM VisualAge C++ V6.0 for AIX

- -

-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. -

- -

Intel C++ Compiler for Linux 7.1/8.0/8.1

- -

-No problems have been detected with these compilers. -

- -

Intel C++ Compiler Extended Memory 64 Technology 8.1 -for Linux

- -

-No problems have been detected with this compiler. -

- -

Intel C++ Compiler for Windows 32-bit 7.0/7.1

- -

-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. -

- -

-Intel C++ Compiler for Windows 32-bit 7.1 + STLport 4.5.3

- -

-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. -

- -

Intel C++ Compiler for Windows 32-bit 8.0/8.1/9.0

- -

-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. -

- -

Metrowerks CodeWarrior 8.3 and later

- -

-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. -

- -

Microsoft Visual C++ 6.0 Service Pack 5

- -

-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: -

-You can use instead their global equivalents. Also, this compiler does not -implement argument dependent lookup, so you might need to explicitly qualify -these global names with ::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: -

-

- -

-Microsoft Visual C++ 6.0 Service Pack 5 -+ STLport 4.5.3 -

- -

-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.) -

- -

Microsoft Visual C++ 7.0

- -

-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: -

-You can use instead their global equivalents. Also, this compiler does not -implement argument dependent lookup, so you might need to explicitly qualify -these global names with ::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". -

- -

Microsoft Visual C++ 7.1

- -

-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. -

- -

Microsoft Visual C++ 8.0

- -

-No problems have been detected with this compiler. The Beta 2 version of -this product was used for the testing. -

- -

Portability techniques

- -

Use of 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: -

-This program can help determine if your compiler -properly supports pointers to members as non-type template parameters: -

- -
-#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. -

- -

Use of 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 -

-that act as the missing specializations of 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;
-
- -

Reduction of symbol name lengths

- -

-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. -

- -

Limitation of maximum number of arguments

- -

-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. -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
Limiting maximum number of arguments of some class templates - of Boost.MultiIndex.
class templatelimiting macrodefault valuedefault value
(MSVC++ 6.0)
 indexed_by  BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE 205
 tag  BOOST_MULTI_INDEX_LIMIT_TAG_SIZE 203
 composite_key  BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 105
-

- -

Type hiding

- -

-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 Documentation - Examples - - - - -

boost.png (6897 bytes)Boost.MultiIndex Examples

- - - -
- -
- -

Contents

- - - -

Example 1: basic usage

- -

-See source code. -

- -

-Basic program showing the multi-indexing capabilities of Boost.MultiIndex -with an admittedly boring set of employee records. -

- -

Example 2: using member functions as keys

- -

-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. -

- -

Example 3: constructing 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. -

- -

Example 4: bidirectional map

- -

-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. -

- -

Example 5: sequenced indices

- -

-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. -

- -

Example 6: complex searches and foreign keys

- -

-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: -

    -
  1. Select the elements with the given manufacturer by means - of equal_range, -
  2. feed these elements into a multi_index_container sorted - by price, -
  3. select by price using lower_bound and - upper_bound; -
-or alternatively: -
    -
  1. Select the elements within the price range with - lower_bound and upper_bound, -
  2. feed these elements into a multi_index_container sorted - by manufacturer, -
  3. locate the elements with given manufacturer using - equal_range. -
-An interesting technique developed in the example lies in -the construction of the intermediate 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. -

- -

Example 7: composite keys

- -

-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: -

-The reason that the order is made firstly by the directory in which -the files are located obeys to the local nature of the shell commands, -like for instance ls. The shell simulation only has three -commands: - -The program exits when the user presses the Enter key at the command prompt. -

- -

-The reader is challenged to add more functionality to the program; for -instance: -

-

- -

Example 8: hashed indices

- -

-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. -

- -

Example 9: serialization and MRU lists

- -

-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 Documentation - Future work - - - - -

boost.png (6897 bytes)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. -

- -

Contents

- - - -

Ranked indices

- -

-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. -

- -

Random access 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: -

-so it might be more accurate to regard this type of indices as a variation of -sequenced indices with random access semantics. -

- -

Notifying indices

- -

-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: -

    -
  1. Logging,
  2. -
  3. interfacing to GUI-based applications,
  4. -
  5. synchronization between separate data structures.
  6. -
-

- -

-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
-
- -

Constraints

- -

-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;
-
- -

User-defined indices

- -

-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. -

- -

Bidirectional map

- -

-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. -

- -

Indexed maps

- -

-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. -

- -

Move semantics

- -

-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.MultiIndex Documentation - Index - - - - -

boost.png (6897 bytes)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: -

-

- -

Contents

- - - -
- - - -
- -
- -

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 Documentation - Performance - - - - -

boost.png (6897 bytes)Boost.MultiIndex Performance

- - - -
- -
- -

Contents

- - - -

Introduction

- -

-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. -

- -

Manual simulation of a 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: -

- -
-manual_t1 c1;
-manual_t2 c2;
-
-// insert the element 5
-manual_t1::iterator=c1.insert(5).first;
-c2.insert(&*t1);
-
- -deletion, on the other hand, necessitates a logarithmic search, whereas -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. -

- -

Spatial efficiency

- -

-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. -

- -

Time efficiency

- -

-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. -

- -

Performance tests

- -

-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: -

-with their default release settings. All tests were performed on a Wintel -box equipped with a P4 1.5GHz processor and 256 MB RAM, running -Microsoft Windows 2000 Professional SP2. -

- -

-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. -

- -

Results for 1 ordered index

- -

-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>. -

- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
100%100%100%
-Table 1: Relative memory consumption of 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. -

- -

Execution time

- -

-performance of multi_index_container with 1 ordered index
-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. -

- -

Results for 1 sequenced index

- -

-The following instantiation of multi_index_container was tested: -

- -
-multi_index_container<
-  int,
-  indexed_by<
-    sequenced<>
-  >
->
-
- -

-which is functionally equivalent to std::list<int>. -

- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
100%100%100%
-Table 2: Relative memory consumption of 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. -

- -

Execution time

- -

-performance of multi_index_container with 1 sequenced index
-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%. -

- -

Results for 2 ordered indices

- -

-The following instantiation of multi_index_container was tested: -

- -
-multi_index_container<
-  int,
-  indexed_by<
-    ordered_unique<identity<int> >,
-    ordered_non_unique<identity<int> >
-  >
->
-
- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
90%90%90%
-Table 3: Relative memory consumption of multi_index_container with 2 -ordered indices. -

- -

-These results concinde with the theoretical formula for -SI=36 and p=4. -

- -

Execution time

- -

-performance of multi_index_container with 2 ordered indices
-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. -

- -

Results for 1 ordered index + 1 sequenced index

- -

-The following instantiation of multi_index_container was tested: -

- -
-multi_index_container<
-  int,
-  indexed_by<
-    ordered_unique<identity<int> >,
-    sequenced<>
-  >
->
-
- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
87.5%87.5%87.5%
-Table 4: Relative memory consumption of multi_index_container with 1 -ordered index + 1 sequenced index. -

- -

-These results concinde with the theoretical formula for -SI=28 and p=4. -

- -

Execution time

- -

-
-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.) -

- -

Results for 3 ordered indices

- -

-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> >
-  >
->
-
- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
86.7%86.7%86.7%
-Table 5: Relative memory consumption of multi_index_container with 3 -ordered indices. -

- -

-These results concinde with the theoretical formula for -SI=52 and p=4. - -

- -

Execution time

- -

-performance of multi_index_container with 3 ordered indices
-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. -

- -

Results for 2 ordered indices + 1 sequenced index

- -

-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<>
-  >
->
-
- -

Memory consumption

- -

- - - - - - - - - - - -
GCC 3.1.1ICC 7.1MSVC 6.5
84.6%84.6%84.6%
-Table 6: Relative memory consumption of multi_index_container with 2 -ordered indices + 1 sequenced index. -

- -

-These results concinde with the theoretical formula for -SI=44 and p=4. -

- -

Execution time

- -

-
-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%. -

- -

Conclusions

- -

-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 Documentation - Hashed indices reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Hashed indices reference

- - - -
- -
- -

Contents

- - - -

-Header - -"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. -

- -

-Header - -"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
-
- -

-Index specifiers 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. -

- -

Hashed indices

- -

-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
-
- -

Complexity signature

- -

-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: -

-

- -

Instantiation types

- -

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: -

-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. -

- -

Nested types

- -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. -
- -

Constructors, copy and assignment

- -

-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: -
-a=b;
-
-where a and b are the multi_index_container -objects to which *this and x belong, respectively.
-Returns: *this.
-
- -

Modifiers

- -std::pair<iterator,bool> insert(const value_type& x); - -
-Effects: Inserts x into the multi_index_container to which -the index belongs if - -Returns: The return value is a pair p. p.second -is true if and only if insertion took place. On successful insertion, -p.first points 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: position is a valid iterator of the index.
-Effects: Inserts x into the multi_index_container to which -the index belongs if - -position is 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: InputIterator is a model of - -Input Iterator over elements of type -value_type or a type convertible to value_type. -first and last are not iterators into any -index of the multi_index_container to which this index belongs. -last is reachable from first.
-Effects: -
-iterator hint=end();
-while(first!=last)hint=insert(hint,*first++);
-
-Complexity: O(m*H(n+m)), where -m is the number of elements in [first, -last).
-Exception safety: Basic.
-
- -iterator erase(iterator position); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Deletes the element pointed to by position.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, or end() -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)), where m is -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)), where m is -the number of elements in [first,last).
-Exception safety: nothrow.
-
- -bool replace(iterator position,const value_type& x); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Assigns the value x to the element pointed -to by position into the multi_index_container to which -the index belongs if, for the value x - -Postconditions: Validity of position is preserved -in all cases.
-Returns: true if the replacement took place, -false otherwise.
-Complexity: O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation the multi_index_container to which the index -belongs remains in its original state. -
- - -template<typename Modifier> bool modify(iterator position,Modifier mod); - -
-Requires: Modifier is a model of - -Unary Function accepting arguments of type -value_type&. position is a valid dereferenceable -iterator of the index.
-Effects: Calls mod(e) where e is the element -pointed to by position and rearranges *position into -all the indices of the multi_index_container. Rearrangement is successful if - -If the rearrangement fails, the element is erased.
-Postconditions: Validity of position is preserved if the -operation succeeds.
-Returns: true if the operation succeeded, false -otherwise.
-Complexity: O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possibly mod), then -the element pointed to by position is erased. -
- - -template<typename Modifier> bool modify_key(iterator position,Modifier mod); - -
-Requires: key_from_value is a read/write -Key Extractor -from value_type. Modifier is a model of - -Unary Function accepting arguments of type -key_type&. position is a valid dereferenceable -iterator of the index.
-Effects: Calls mod(k) where k is the key -obtained by the internal KeyFromValue object of the index from -the element pointed to by position, and rearranges -*position into all the indices of the multi_index_container. -Rearrangement is successful if - -If the rearrangement fails, the element is erased.
-Postconditions:Validity of position is preserved if -the operation succeeds.
-Returns: true if the operation succeeded, false -otherwise.
-Complexity: O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possibly mod), then -the element pointed to by position is erased. -
- -

Observers

- -

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_value object used to construct -the index.
-Complexity: Constant. -
- -

Lookup

- -

-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 -

    -
  1. CompatibleHash is a hash functor on values of - type CompatibleKey,
  2. -
  3. CompatiblePred is a - - Binary Predicate over (Key, - CompatibleKey),
  4. -
  5. CompatiblePred is a - - Binary Predicate over (CompatibleKey, - Key),
  6. -
  7. if c_eq(ck,k1) then c_eq(k1,ck),
  8. -
  9. if c_eq(ck,k1) and eq(k1,k2) then - c_eq(ck,k2),
  10. -
  11. if c_eq(ck,k1) and c_eq(ck,k2) then - eq(k1,k2),
  12. -
  13. if c_eq(ck,k1) then c_hash(ck)==hash(k1),
  14. -
-for every 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: CompatibleKey is a compatible key of -(hasher, key_equal).
-Effects: Returns a pointer to an element whose key is equivalent to -x, or end() if such an element does not exist.
-Complexity: Average case O(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, or end() if such an element does not exist.
-Complexity: Average case O(1) (constant), worst case -O(n).
-
- -template<typename CompatibleKey>
-size_type count(const CompatibleKey& x)const; -
- -
-Requires: CompatibleKey is a compatible key of -(hasher, key_equal).
-Effects: Returns the number of elements with key equivalent to x.
-Complexity: Average case O(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 to x.
-Complexity: Average case O(count(x,hash,eq)), worst case -O(n).
-
- -template<typename CompatibleKey>
-std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const; -
- -
-Requires: CompatibleKey is a compatible key of -(hasher, key_equal).
-Effects: Returns a range containing all elements with keys equivalent -to x (and only those).
-Complexity: Average case O(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 -to x (and only those).
-Complexity: Average case O(count(x,hash,eq)), worst case -O(n).
-
- - -

Hash policy

- -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, and bucket_count()>=n.
-Postconditions: Validity of iterators and references to the -elements contained is preserved.
-Complexity: Average case O(size()), worst case -O(size(n)2).
-Exeption safety: Strong. -
- -

Serialization

- -

-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. -

- -Operation: saving of a 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, key_eq() -must be serialization-compatible with m.get<i>().key_eq(), -where i is 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. -
- -Operation: saving of an iterator or const_iterator -it to an output archive (XML archive) ar. - -
-Requires: it is a valid iterator of the index. The associated -multi_index_container has been previously saved. -
- -Operation: loading of an iterator or const_iterator -it' from an input archive (XML archive) ar. - -
-Postconditions: On succesful loading, if it was dereferenceable -then *it' is the restored copy of *it, otherwise -it'==end().
-Note: It is allowed that it be a const_iterator -and the restored it' an iterator, or viceversa. -
- -Operation: saving of a local_iterator or -const_local_iterator -it to an output archive (XML archive) ar. - -
-Requires: it is a valid local iterator of the index. The -associated multi_index_container has been previously saved. -
- -Operation: loading of a local_iterator or -const_local_iterator -it' from an input archive (XML archive) ar. - -
-Postconditions: On succesful loading, if it was dereferenceable -then *it' is the restored copy of *it; if it -was m.get<i>().end(n) for some n, then -it'==m'.get<i>().end(n) (where m is the original -multi_index_container, m' its restored copy -and i is the ordinal of the index.)
-Note: It is allowed that it be a const_local_iterator -and the restored it' a local_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 Documentation - Reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Reference

- - - -
- -
- -

Contents

- - - -

Header dependencies

- -

-The following dependencies among headers of Boost.MultiIndex hold: -

-So, a program using Boost.MultiIndex must include - -"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 Documentation - Index reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Index reference

- - - -
- -
- -

Contents

- - - -

Index concepts

- -

-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: -

-The last two primitives deserve some further explanation: in order to -guarantee the invariants associated to each index (e.g. some definite -ordering,) elements of a multi_index_container are not mutable. -To overcome this restriction, indices expose member functions -for 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.) -

- -

Complexity signature

- -

-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: -

- -

-Each function yields the complexity estimate of the contribution of the index -to the corresponding global primitive. Let us consider -an instantiation of multi_index_container -with N indices labelled 0,...,N-1 -whose complexity signatures are -(ci,ii,hi,di,ri,mi); -the insertion of an element in such a container is then of complexity -O(i0(n)+···+iN-1(n)) where n -is the number of elements. To abbreviate notation, we adopt the -following definitions: - -For instance, consider a multi_index_container with two ordered indices, -for which i(n)=log(n), and a sequenced index with i(n)=1 -(constant time insertion). Insertion of an element into this multi_index_container -is then of complexity -
-O(I(n))=O(2*log(n)+1)=O(log(n)). -
-

- -

Index specification

- -

-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 -

-

- -

-Header - -"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
-
- -

Class template 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

- -

-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. -

- -

-Header - -"boost/multi_index/tag.hpp" synopsis

- -
-namespace boost{
-
-namespace multi_index{
-
-template<typename T0,...,typename Tn>
-struct tag;
-
-} // namespace boost::multi_index 
-
-} // namespace boost
-
- -

Class template 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 provided by Boost.MultiIndex

- - -

Key-based indices

- -

-Indices of this type are organized around keys obtained from the -elements, as described in the key extraction -reference. -

-

- -

Other types

- -

-

-

- -
- - - -
- -
- -

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 Documentation - Key extraction reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Key extraction reference

- - - -
- -
- -

Contents

- - - -

Key Extractors

- -

-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 -

    -
  1. the type KeyFromValue::result_type is defined,
  2. -
  3. k1(ca) is defined and returns a value convertible - to const KeyFromValue::result_type&,
  4. -
  5. if k2 is a copy of k1, k1(ca) is the - same value as k2(ca),
  6. -
-for every 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: -

    -
  1. k1(a) is defined and returns a value convertible - to KeyFromValue::result_type&,
  2. -
  3. const_cast<const KeyFromValue::result_type&>(k1(a)) - is the same value as - k1(const_cast<const Type&>(a)),
  4. -
-for every k1 of type const KeyFromValue and -a of type Type&. -

- -

-Boost.MultiIndex provides five general-purpose key extractors: -

-plus replacements for some of them: - -that workaround some deficiencies in the support for non-type template parameters -by certain compilers. -

- -

Chained pointers

- -

-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 -

-that is, chained pointers are arbitrary compositions of pointer-like objects -ultimately dereferencing to values of Type& or -boost::reference_wrapper<Type>. -

- -

Header - -"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. -

- -

-Header - -"boost/multi_index/identity.hpp" synopsis

- -
-namespace boost{
-
-namespace multi_index{
-
-template<typename T> struct identity;
-
-} // namespace boost::multi_index 
-
-} // namespace boost
-
- -

Class template 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: -

-

- -

identity members

- -template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const; - -
-Requires: ChainedPtr is a chained pointer -type to Type.
-Returns: a reference to the object chained-pointed to by x. -
- -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(). -
- - -

-Header - -"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
-
- -

Class template 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: -

-

- -

member members

- -template<typename ChainedPtr> Type& operator()(const ChainedPtr& x)const; - -
-Requires: ChainedPtr is a chained pointer -type to Type.
-Returns: a reference to the object chained-pointed to by x. -
- -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. -
- -

Class template 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: -

-In this situation, 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)>. -

- -

Macro 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. -

- -

-Header - -"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
-
- -

Class template 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: -

-

- -

const_mem_fun members

- -template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - -
-Requires: ChainedPtr is a chained pointer -type to Type.
-Returns: (y.*PtrToMemberFunction)(), where y is the -object chained-pointed to by x. -
- -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)(). -
- -

Class template 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: -

-

- -

mem_fun members

- -template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - -
-Requires: ChainedPtr is a chained pointer -type to Type.
-Returns: (y.*PtrToMemberFunction)(), where y is the -object chained-pointed to by x. -
- -Type operator()(Class& x)const; - -
-Returns: (x.*PtrToMemberFunction)(). -
- -Type operator()(const reference_wrapper<Class>& x)const; - -
-Returns: (x.get().*PtrToMemberFunction)(). -
- -

Class template 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>. -

- -

Class template 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;
-};
-
- -

Macro -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. -

- - -

Macro -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. -

- -

-Header - -"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
-
- -

Class template 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: -

-

- -

composite_key members

- -composite_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_key that stores -copies of the key extractor objects supplied in x. -
- -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: ChainedPtr is a chained pointer -type to result_type.
-Returns: a result_type object dependent on -*this and y, where y is the -object chained-pointed to by x. -
- -result_type operator()(const value_type& x)const; - -
-Returns: a result_type object dependent on -*this and x. -
- -result_type operator()(const reference_wrapper<const value_type>& x)const; - -
-Returns: a result_type object dependent on -*this and x.get(). -
- -result_type operator()(const reference_wrapper<value_type>& x)const; - -
-Returns: a result_type object dependent on -*this and x.get(). -
- -

Class template -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. -

- -

Notation

- -

-Given an x of type composite_key_result<CompositeKey>, -we use the following notation: -

-Also, if y is a tuple of values, we define: - -

- -

Comparison operators

- -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==yi is valid for all i -in [0,length(x)).
-Returns: true if and only if -
-xi==yi for all i -in [0,length(x)). -
-Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at i==0. The evaluation is short-circuited as soon as -the result is determined to be false. -
- -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<yi and -yi<xi are valid for all i -in [0,min(length(x),length(y))).
-Returns: true if and only if there exists some -j in the range [0,min(length(x),length(y))) -such that -
-!(xi<yi) && !(yi<xi) -for all i in [0,j),
-  xj<yj. -
-Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at i==0. The evaluation is short-circuited as soon as -the result is determined to be false. -
- -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 -OP considered.)
-Returns: true if and only if -
-!(x==y) (OP is !=),
-  y< x  (OP is ),
-!(x< y) (OP is >=),
-!(y< x) (OP is <=). -
-
- -

Equality

- -

Class template -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. -

- -

Notation

- -

-In what follows we use the same notation -introduced for composite_key_result. - -

composite_key_equal_to members

- -composite_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_to that stores -copies of the equality predicate objects supplied in x. -
- -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 all i in [0,length(x)).
-Returns: true if and only -
-key_eqs().get<i>()(xi,yi) -for all i in [0,length(x)).
-
-Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at i==0. The evaluation is short-circuited as soon as -the result is determined to be false. -
- -

Class template -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. -

- -

Specialization of -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
-
- -

Comparison

- -

Class template -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. -

- -

Notation

- -

-In what follows we use the same notation -introduced for composite_key_result. - -

composite_key_compare members

- -composite_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_compare that stores -copies of the comparison predicate objects supplied in x. -
- -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 all i -in [0,min(length(x),length(y))).
-Returns: true if and only if there exists some -j in the range [0,min(length(x),length(y))) -such that -
-!key_comps().get<i>()(xi,yi) && !key_comps().get<i>()(yi,xi) -for all i in [0,j),
- key_comps().get<j>()(xj,yj). -
-Complexity: No more key extraction operations and comparisons -are performed than those necessary for the evaluation of the expression above, -starting at i==0. The evaluation is short-circuited as soon as -the result is determined to be false. -
- -

Class template -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. -

- -

Class template -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. -

- -

Specialization of 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
-
- -

Specialization of 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
-
- -

Hashing

- -

Class template -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. -

- -

Notation

- -

-In what follows we use the same notation -introduced for composite_key_result. - -

composite_key_hash members

- -composite_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_hash that stores -copies of the hash functors supplied in x. -
- -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 all i in [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)), -with N=length(x)-1. -
-
- -

Class template -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. -

- -

Specialization of -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
-
- -

Semantics of -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 -

-KeyFromValuei::result_type = Ti, for all i = 0,...,j. -
-Then, 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>: -
-tuple<Q0,...,Qj>,
-composite_key_result<composite_key<K0,...,Kj> >, with -Ki::result_type = Qi for all i = 0,...,j. -
-provided that each 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>: -

-tuple<Q0,...,Qk>, k <= n
-composite_key_result<composite_key<K0,...,Kk> >, with -Ki::result_type = Qi for all i = 0,...,k. -
-provided that each 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 Documentation - multi_index_container reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex -multi_index_container reference

- - - -
- -
- -

Contents

- - - -

-Header -"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. -

- -

-Header -"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
-
- -

-Class template 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
-
- -

Complexity

- -

-In the descriptions of operations of multi_index_container, we adopt the -scheme outlined in the -complexity signature section. -

- -

Instantiation types

- -

-multi_index_container is instantiated with the following types: -

    -
  1. Value is the - Assignable - type of the elements contained.
  2. -
  3. 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. -
  4. Allocator must comply with the C++ requirements for - allocators [lib.allocator.requirements]. -
-Indices of a given multi_index_container instantiation cannot have -duplicate tags, either within a single -index or in two different indices. -

- -

Nested types

- -ctor_args_list - -
-Although the exact definition of ctor_args_list is -implementation defined, from the user point of view this type can be -treated as equivalent to -::boost::tuple<C0,...,CI-1>, -where Ci is the ctor_args type of the -i-th index held by the multi_index_container, in the -same order as they were specified. Strictly speaking, there is an -implicit conversion from -const ::boost::tuple<C0,...,CI-1>& -to const ctor_args_list&. This type is used for -providing the construction arguments of the indices of the -multi_index_container. ctor_args_list is -Default -Constructible, provided that all ctor_args types -involved are default constructible. -
- -index_specifier_type_list - -
-Same type as IndexSpecifierList. -
- -index_type_list - -
-Model of - -MPL Random Access Sequence and - -MPL Extensible Sequence containing the types of the indices held by -the multi_index_container, in the same order as they were specified. -
- -iterator_type_list - -
-Model of - -MPL Random Access Sequence and - -MPL Extensible Sequence containing the types of the iterators of -the indices held by the multi_index_container, in the same order as they were -specified. -
- -const_iterator_type_list - -
-Model of - -MPL Random Access Sequence and - -MPL Extensible Sequence containing the types of the constant -iterators of the indices held by the multi_index_container, in the same order -as they were specified. -
- -

Nested class templates

- -template<int N> struct nth_index - -
-nth_index<N>::type yields the type of the -N-th (0-based) index held by the multi_index_container, in -the same order as they were specified.
-Requires: 0 <= N < I. -
- -template<typename Tag> struct index - -
-index<Tag>::type yields the type of the index which -has Tag as an associated tag type.
-Requires: Some index of the multi_index_container has Tag -as an associated tag type. -
- -template<int N> struct nth_index_iterator - -
-nth_index_iterator<N>::type is equivalent to -nth_index<N>::type::iterator.
-
- -template<int N> struct nth_index_const_iterator - -
-nth_index_const_iterator<N>::type is equivalent to -nth_index<N>::type::const_iterator.
-
- -template<typename Tag> struct index_iterator - -
-index_iterator<Tag>::type is equivalent to -index<Tag>::type::iterator.
-
- -template<typename Tag> struct index_const_iterator - -
-index_const_iterator<Tag>::type is equivalent to -index<Tag>::type::const_iterator.
-
- -

Constructors, copy and assignment

- -explicit multi_index_container(
-  const ctor_args_list& comp=ctor_args_list(),
-  const allocator_type& al=allocator_type());
- -
-Effects: Constructs an empty multi_index_container using 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: InputIterator is a model of - -Input Iterator over elements of type -Value or a type convertible to Value. -last is reachable from first.
-Effects: Constructs and empty multi_index_container using 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 the multi_index_container.
-Complexity: O(m*H(m)), where m is -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 the multi_index_container is preserved as well.
-Complexity: O(x.size()*log(x.size()) + C(x.size())). -
- -~multi_index_container() -
-Effects: Destroys the multi_index_container and 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 from x.
-Postconditions: *this==x. The order on every index -of the multi_index_container is 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 of ctor_args_list do not throw. -
- -allocator_type get_allocator()const; - -
-Returns a copy of the allocator_type object used to construct -the multi_index_container.
-Complexity: Constant. -
- -

Index retrieval operations

- -template<int N> typename nth_index<N>::type& get(); - -
-Requires: 0 <= N < I.
-Effects: Returns a reference to the -nth_index<N>::type index 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 a const reference to the -nth_index<N>::type index held by *this.
-Complexity: Constant.
-Exception safety: nothrow. -
- -template<typename Tag> typename index<Tag>::type& get() - -
-Requires: Tag is such that index<Tag>::type -is valid.
-Effects: Returns a reference to the -index<Tag>::type index held by -*this.
-Complexity: Constant.
-Exception safety: nothrow. -
- -template<typename Tag> const typename index<Tag>::type& get()const; - -
-Requires: Tag is such that index<Tag>::type -is valid.
-Effects: Returns a const reference to the -index<Tag>::type index held by -*this.
-Complexity: Constant.
-Exception safety: nothrow. -
- -

Projection operations

- -

-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: -

-

- -template<int N,typename IteratorType>
-typename nth_index_iterator<N>::type project(IteratorType it);
- -
-Requires: 0 <= N < I. IteratorType -belongs to iterator_type_list. it is a valid -iterator of some index of *this (i.e. does not refer to some -other multi_index_container.)
-Effects: Returns an nth_index_iterator<N>::type iterator -equivalent to it.
-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 to const_iterator_type_list or -iterator_type_list. it is a -valid (constant or non-constant) iterator of some index of *this -(i.e. does not refer to some other multi_index_container.)
-Effects: Returns an nth_index_const_iterator<N>::type -iterator equivalent to it.
-Complexity: Constant.
-Exception safety: nothrow. -
- -template<typename Tag,typename IteratorType>
-typename index_iterator<Tag>::type project(IteratorType it);
- -
-Requires: Tag is such that -index_iterator<Tag>::type is valid. IteratorType -belongs to iterator_type_list. it is a valid -iterator of some index of *this (i.e. does not refer to some -other multi_index_container.)
-Effects: Returns an index_iterator<Tag>::type iterator -equivalent to it.
-Complexity: Constant.
-Exception safety: nothrow. -
- -template<typename Tag,typename IteratorType>
-typename index_const_iterator<Tag>::type project(IteratorType it)const;
- -
-Requires: Tag is such that -index_const_iterator<Tag>::type is valid. IteratorType -belongs to const_iterator_type_list or -iterator_type_list. it is a valid -(constant or non-constant) iterator of some index of *this -(i.e. does not refer to some other multi_index_container.)
-Effects: Returns an index_const_iterator<Tag>::type -iterator equivalent to it.
-Complexity: Constant.
-Exception safety: nothrow. -
- -

Serialization

- -

-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: Value is serializable (XML-serializable). Additionally, -each of the indices of m can impose another requirements.
-Exception safety: Strong with respect to m. If an exception -is thrown, ar may be left in an inconsistent state. -
- -Operation: loading of a multi_index_container m' from an -input archive (XML archive) ar. - -
-Requires: Value is serializable (XML-serializable). Additionally, -each of the indices of m' can impose another requirements.
-Exception safety: Basic. If an exception is thrown, ar may 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 Documentation - Ordered indices reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Ordered indices reference

- - - -
- -
- -

Contents

- - - -

-Header - -"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. -

- -

-Header - -"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
-
- -

-Index specifiers 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. -

- -

Ordered indices

- -

-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
-
- -

Complexity signature

- -

-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: -

-

- -

Instantiation types

- -

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: -

-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. -

- -

Constructors, copy and assignment

- -

-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: -
-a=b;
-
-where a and b are the multi_index_container -objects to which *this and x belong, respectively.
-Returns: *this.
-
- -

Modifiers

- -std::pair<iterator,bool> insert(const value_type& x); - -
-Effects: Inserts x into the multi_index_container to which -the index belongs if - -Returns: The return value is a pair p. p.second -is true if and only if insertion took place. On successful insertion, -p.first points 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: position is a valid iterator of the index.
-Effects: Inserts x into the multi_index_container to which -the index belongs if - -position is 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: InputIterator is a model of - -Input Iterator over elements of type -value_type or a type convertible to value_type. -first and last are not iterators into any -index of the multi_index_container to which this index belongs. -last is reachable from first.
-Effects: -
-iterator hint=end();
-while(first!=last)hint=insert(hint,*first++);
-
-Complexity: O(m*H(n+m)), where -m is the number of elements in [first, -last).
-Exception safety: Basic.
-
- -iterator erase(iterator position); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Deletes the element pointed to by position.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, or end() -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)), where m is -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)), where m is -the number of elements in [first,last).
-Exception safety: nothrow.
-
- -bool replace(iterator position,const value_type& x); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Assigns the value x to the element pointed -to by position into the multi_index_container to which -the index belongs if, for the value x - -Postconditions: Validity of position is preserved -in all cases.
-Returns: true if the replacement took place, -false otherwise.
-Complexity: O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation the multi_index_container to which the index -belongs remains in its original state. -
- - -template<typename Modifier> bool modify(iterator position,Modifier mod); - -
-Requires: Modifier is a model of - -Unary Function accepting arguments of type -value_type&. position is a valid dereferenceable -iterator of the index.
-Effects: Calls mod(e) where e is the element -pointed to by position and rearranges *position into -all the indices of the multi_index_container. Rearrangement is successful if - -If the rearrangement fails, the element is erased.
-Postconditions: Validity of position is preserved if the -operation succeeds.
-Returns: true if the operation succeeded, false -otherwise.
-Complexity: O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possibly mod), then -the element pointed to by position is erased. -
- - -template<typename Modifier> bool modify_key(iterator position,Modifier mod); - -
-Requires: key_from_value is a read/write -Key Extractor -from value_type. Modifier is a model of - -Unary Function accepting arguments of type -key_type&. position is a valid dereferenceable -iterator of the index.
-Effects: Calls mod(k) where k is the key -obtained by the internal KeyFromValue object of the index from -the element pointed to by position, and rearranges -*position into all the indices of the multi_index_container. -Rearrangement is successful if - -If the rearrangement fails, the element is erased.
-Postconditions:Validity of position is preserved if -the operation succeeds.
-Returns: true if the operation succeeded, false -otherwise.
-Complexity: O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possibly mod), then -the element pointed to by position is erased. -
- -

Observers

- -

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_value object used to construct -the index.
-Complexity: Constant. -
- -

Set operations

- -

-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 -

    -
  1. CompatibleCompare is a - - Binary Predicate over (Key, - CompatibleKey),
  2. -
  3. CompatibleCompare is a - - Binary Predicate over (CompatibleKey, - Key),
  4. -
  5. if c_comp(ck,k1) then !c_comp(k1,ck),
  6. -
  7. if !c_comp(ck,k1) and !comp(k1,k2) then - !c_comp(ck,k2),
  8. -
  9. if !c_comp(k1,ck) and !comp(k2,k1) then - !c_comp(k2,ck),
  10. -
-for every 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: CompatibleKey is a compatible key of -key_compare.
-Effects: Returns a pointer to an element whose key is equivalent to -x, or end() 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 of key_compare.
-Effects: Returns a pointer to an element whose key is equivalent to -x, or end() if such an element does not exist.
-Complexity: O(log(n)).
-
- -template<typename CompatibleKey> size_type
-count(const CompatibleKey& x)const; -
- -
-Requires: CompatibleKey is a compatible key of -key_compare.
-Effects: Returns the number of elements with key equivalent to x.
-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 of key_compare.
-Effects: Returns the number of elements with key equivalent to x.
-Complexity: O(log(n) + count(x,comp)).
-
- -template<typename CompatibleKey>
-iterator lower_bound(const CompatibleKey& x)const; -
- -
-Requires: CompatibleKey is a compatible key of -key_compare.
-Effects: Returns an iterator pointing to the first element with -key not less than x, or end() 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 of key_compare.
-Effects: Returns an iterator pointing to the first element with -key not less than x, or end() if such an element does -not exist.
-Complexity: O(log(n)).
-
- -template<typename CompatibleKey>
-iterator upper_bound(const CompatibleKey& x)const; -
- -
-Requires: CompatibleKey is a compatible key of -key_compare.
-Effects: Returns an iterator pointing to the first element with -key greater than x, or end() 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 of key_compare.
-Effects: Returns an iterator pointing to the first element with -key greater than x, or end() 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: CompatibleKey is a compatible key of -key_compare.
-Effects: Equivalent to make_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 of key_compare.
-Effects: Equivalent to -make_pair(lower_bound(x,comp),upper_bound(x,comp)).
-Complexity: O(log(n)).
-
- - -

Range operations

- -

-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 -

    -
  1. LowerBounder is a - - Predicate over Key,
  2. -
  3. if lower(k1) and !comp(k2,k1) then - lower(k2),
  4. -
-for every lower of type LowerBounder, -comp of type Compare, and k1, -k2 of type Key. Similarly, an upper bounder -is a type UpperBounder such that -
    -
  1. UpperBounder is a - - Predicate over Key,
  2. -
  3. if upper(k1) and !comp(k1,k2) then - upper(k2),
  4. -
-for every 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: LowerBounder and UpperBounder are -a lower and upper bounder of key_compare, respectively.
-Effects: Returns a pair of iterators pointing to the beginning and one -past the end of the subsequence of elements satisfying lower and -upper simultaneously. If no such elements exist, the iterators -both point to the first element satisfying lower, or else -are equal to end() if this latter element does not exist.
-Complexity: O(log(n)).
-Variants: In place of lower or upper (or both), -the singular value boost::multi_index::unbounded can be -provided. This acts as a predicate which all values of type key_type -satisfy.
-
- -

Serialization

- -

-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. -

- -Operation: saving of a 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, value_comp() -must be serialization-compatible with m.get<i>().value_comp(), -where i is 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()). -
- -Operation: saving of an iterator or const_iterator -it to an output archive (XML archive) ar. - -
-Requires: it is a valid iterator of the index. The associated -multi_index_container has been previously saved. -
- -Operation: loading of an iterator or const_iterator -it' from an input archive (XML archive) ar. - -
-Postconditions: On succesful loading, if it was dereferenceable -then *it' is the restored copy of *it, otherwise -it'==end().
-Note: It is allowed that it be a const_iterator -and the restored it' an 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/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 Documentation - Sequenced indices reference - - - - -

boost.png (6897 bytes)Boost.MultiIndex Sequenced indices reference

- - - -
- -
- -

Contents

- - - -

-Header - -"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. -

- -

-Header - -"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

- -

-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: -

-Having these restrictions into account, sequenced indices are models -of -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
-
- -

Complexity signature

- -

-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: -

-

- -

Instantiation types

- -

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: -

-TagList must be an instantiation of -tag. -

- -

Constructors, copy and assignment

- -

-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: -
-a=b;
-
-where a and b are the multi_index_container -objects to which *this and x belong, respectively.
-Returns: *this.
-
- -template <class InputIterator>
-void assign(InputIterator first,InputIterator last);
- -
-Requires: InputIterator is a model of - -Input Iterator over elements of type -value_type or a type convertible to value_type. -first and last are not iterators into any -index of the multi_index_container to which this index belongs. -last is reachable from first.
-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);
-
-
- -

Capacity operations

- -void resize(size_type n,const value_type& x=value_type()); - -
-Effects: -
-if(n>size())insert(end(),n-size(),x);
-else if(n<size())erase(begin()+n,end());
-
-Note: If an expansion is requested, the size of the index is not guaranteed -to be n after this operation (other indices may ban insertions.) -
- -

Modifiers

- -std::pair<iterator,bool> push_front(const value_type& x); - -
-Effects: Inserts x at the beginning of the sequence if -no other index of the multi_index_container bans the insertion.
-Returns: The return value is a pair p. p.second -is true if and only if insertion took place. On successful -insertion, p.first points 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. -
- -std::pair<iterator,bool> push_back(const value_type& x); - -
-Effects: Inserts x at the end of the sequence if -no other index of the multi_index_container bans the insertion.
-Returns: The return value is a pair p. p.second -is true if and only if insertion took place. On successful -insertion, p.first points 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. -
- -std::pair<iterator,bool> insert(iterator position,const value_type& x); - -
-Requires: position is a valid iterator of the index.
-Effects: Inserts x before position if insertion -is allowed by all other indices of the multi_index_container.
-Returns: The return value is a pair p. p.second -is true if and only if insertion took place. On successful -insertion, p.first points 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. -
- -void insert(iterator position,size_type n,const value_type& x); - -
-Requires: position is 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: position is a valid iterator of the index. -InputIterator is a model of - -Input Iterator over elements of type -value_type or a type convertible to value_type. -first and last are not iterators into any -index of the multi_index_container to which this index belongs. -last is reachable from first.
-Effects: -
-while(first!=last)insert(position,*first++);
-
-Complexity: O(m*I(n+m)), where m is the -number of elements in [first,last).
-Exception safety: Basic. -
- -iterator erase(iterator position); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Deletes the element pointed to by position.
-Returns: An iterator pointing to the element immediately following -the one that was deleted, or end() -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)), where m is -the number of elements in [first,last).
-Exception safety: nothrow.
-
- -bool replace(iterator position,const value_type& x); - -
-Requires: position is a valid dereferenceable iterator -of the index.
-Effects: Assigns the value x to the element pointed -to by position into the multi_index_container to which -the index belongs if replacing is allowed by all other indices of the -multi_index_container.
-Postconditions: Validity of position is preserved -in all cases.
-Returns: true if the replacement took place, -false otherwise.
-Complexity: O(R(n)).
-Exception safety: Strong. If an exception is thrown by some -user-provided operation the multi_index_container to which the index -belongs remains in its original state. -
- - -template<typename Modifier> bool modify(iterator position,Modifier mod); - -
-Requires: Modifier is a model of - -Unary Function accepting arguments of type -value_type&. position is a valid dereferenceable -iterator of the index.
-Effects: Calls mod(e) where e is the element -pointed to by position and rearranges *position into -all the indices of the multi_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 of position is preserved if the -operation succeeds.
-Returns: true if the operation succeeded, false -otherwise.
-Complexity: O(M(n)).
-Exception safety: Basic. If an exception is thrown by some -user-provided operation (except possibly mod), then -the element pointed to by position is erased. -
- -

List operations

- -

-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: position is a valid iterator of the index. -&x!=this.
-Effects: Inserts the contents of x before position, -in the same order as they were in x. Those elements succesfully -inserted are erased from x.
-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: position is a valid iterator of the index. -i is a valid dereferenceable iterator x.
-Effects: Inserts the element pointed to by i before -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: position is a valid iterator of the index. -first and last are valid iterators of x. -last is reachable from first. position -is not in the range [first,last).
-Effects: For each element in the range [first,last), -insertion is tried before position; if the operation is succesful, -the element is erased from x. 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())) where m is 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)), where m -is the number of elements erased.
-Exception safety: Basic. -
- -template<typename Predicate> void remove_if(Predicate pred); - -
-Effects: Erases all elements x of the index for which -pred(x) holds..
-Complexity: O(n + m*D(n)), where m -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 i in the range -[first+1,last) for which *i==*(i-1).
-Complexity: O(n + m*D(n)), where m -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 i in the range -[first+1,last) for which -binary_pred(*i,*(i-1)) holds.
-Complexity: O(n + m*D(n)), where m -is the number of elements erased.
-Exception safety: Basic. -
- -void merge(index class name& x); - -
-Requires: std::less<value_type> is a - -Strict Weak Ordering over value_type. -Both the index and x are sorted according to -std::less<value_type>.
-Effects: Attempts to insert every element of x into the -corresponding position of the index (according to the order). Elements -successfully inserted are erased from x. 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 -x are sorted. -Validity of iterators to the index and of non-erased elements of x -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: Compare is a - -Strict Weak Ordering over value_type. -Both the index and x are sorted according to comp.
-Effects: Attempts to insert every element of x into the -corresponding position of the index (according to comp). -Elements successfully inserted are erased from x. 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 -x are sorted according to comp. -Validity of iterators to the index and of non-erased elements of x -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 Ordering over value_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: nothrow if -std::less<value_type> does not throw; otherwise, basic. -
- -template <typename Compare> void sort(Compare comp); - -
-Requires: Compare is a - -Strict Weak Ordering over value_type.
-Effects: Sorts the index according to comp. 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: nothrow if comp does -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. -
- -

Special list operations

- -

-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: position is a valid iterator of the index. -i is a valid dereferenceable iterator of the index.
-Effects: Inserts the element pointed to by i before -position. If position==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: position is a valid iterator of the index. -first and last are valid iterators of the index. -last is reachable from first. position -is not in the range [first,last).
-Effects: The range of elements [first,last) -is repositioned just before position.
-Postconditions: No iterator or reference is invalidated.
-Complexity: Constant.
-Exception safety: nothrow.
-
- -

Serialization

- -

-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. -

- -Operation: saving of a 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.
-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()), -where i is the position of the sequenced index in the container. -
- -Operation: saving of an iterator or const_iterator -it to an output archive (XML archive) ar. - -
-Requires: it is a valid iterator of the index. The associated -multi_index_container has been previously saved. -
- -Operation: loading of an iterator or const_iterator -it' from an input archive (XML archive) ar. - -
-Postconditions: On succesful loading, if it was dereferenceable -then *it' is the restored copy of *it, otherwise -it'==end().
-Note: It is allowed that it be a const_iterator -and the restored it' an iterator, 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 Documentation - Release notes - - - - -

boost.png (6897 bytes)Boost.MultiIndex Release notes

- - - -
- -
- - -

Contents

- - - -

Boost 1.33.1 release

- -

-

-

- -

Boost 1.33 release

- -

-

-

- -
- - - -
- -
- -

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 Documentation - Tests - - - - -

boost.png (6897 bytes)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. -

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Boost.MultiIndex test suite.
ProgramDescription
test_basic.cppSimple program along the lines of the employees example studied in the - tutorial.
test_capacity.cppempty, size and (sequenced indices only) - resize.
test_comparison.cppComparison between indices.
test_composite_key.cppcomposite_key and composite_key_compare.
test_conv_iterators.cppChecks convertibility of non-constant to constant iterators.
test_copy_assignment.cppVarious forms of assignment: copy, operator =, insertion, - (sequenced indices only) assign . -
test_hash_ops.cppHashing operations.
test_iterators.cppConstant and non-constant iterators and their reverse variants.
test_key_extractors.cppCovers all use cases of key extractors shipped with the library.
test_list_ops.cppList-like operations particular to sequenced indices.
test_modifiers.cppChecks the family of insertion and erasing operations.
test_mpl_ops.cppMetaprogramming manipulations of multi_index_container types.
test_observers.cppChecks observer member functions of ordered and hashed indices.
test_projection.cppProjection of iterators among indices.
test_range.cppExercises the range facility (ordered indices only).
test_safe_mode.cppComprehensive coverage of all conditions checked in safe mode.
test_serialization.cppSerialization support.
test_set_ops.cppSet-like operations particular to ordered indices.
test_special_list_ops.cppConvenience functions of sequenced indices not present in - std::list.
test_special_set_ops.cppChecks special lookup operations using compatible sorting criteria.
test_update.cppreplace, 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 Documentation - Tutorial - - - - -

boost.png (6897 bytes)Boost.MultiIndex Tutorial

- - - -
- -
- -

Contents

- - - -

Rationale

- -

-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. -

- -

-Namespace -

- -

-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;
-
- -

Introduction

- -

-We introduce the main concepts of Boost.MultiIndex through the study of -two typical use cases. -

- -

Multiple sorts on a single set

- -

-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: -

-Of these, probably the second solution will be the one adopted by most programmers -concerned about efficiency, but it imposes the annoying burden of keeping the two -structures in sync. If the code is additionally required to be exception-safe, this -construct easily becomes unmaintainable. -

- -

-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. -

- -

A bidirectional list with fast lookup

- -

-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. -

- -

-Index specification -

- -

-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)> >
-  >
->
-
- -

Tagging

- -

-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, -

-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;
-
- -

-Index types -

- -

-Currently, Boost.MultiIndex provides the following index types: -

-The examples in the introduction exercise ordered and sequenced -indices, which are the most commonly used; hashed indices are presented in the -advanced topics section. -

- -

-Ordered indices -

- -

-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. -

- -

-Unique and non-unique variants -

- -

-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;
-
- -

-Specification -

- -

-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. -

- -

-Key extraction -

- -

-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: -

-As an example, consider again the definition of 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. -

- -

Comparison predicates

- -

-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;
-
- -

Special lookup operations

- -

-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());
-
- -

Retrieval of ranges

- -

-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())
-
- -

Updating

- -

-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: -

-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");
-
- -

-Sequenced indices -

- -

-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. -

- -

Specification

- -

-Sequenced indices are specified with the sequenced construct: -

- -
-sequenced<[(tag)]>
-
- -

-The tag parameter is optional. -

- -

List operations

- -

-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. -

- -

Updating

- -

-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. -

- -

Projection of iterators

- -

-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. -

- -

Complexity and exception safety

- -

-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 - : $(BOOST_ROOT) - ; - -exe bimap - : bimap.cpp - : $(BOOST_ROOT) - ; - -exe complex_structs - : complex_structs.cpp - : $(BOOST_ROOT) - ; - -exe composite_keys - : composite_keys.cpp - : $(BOOST_ROOT) - ; - -exe hashed - : hashed.cpp - : $(BOOST_ROOT) - ; - -exe memfun_key - : memfun_key.cpp - : $(BOOST_ROOT) - ; - -exe non_default_ctor - : non_default_ctor.cpp - : $(BOOST_ROOT) - ; - -exe sequenced - : sequenced.cpp - : $(BOOST_ROOT) - ; - -exe serialization - : serialization.cpp - ../../serialization/build/boost_serialization - : $(BOOST_ROOT) - std::locale-support - ; diff --git a/example/basic.cpp b/example/basic.cpp deleted file mode 100644 index e907aee..0000000 --- a/example/basic.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* Boost.MultiIndex basic example. - * - * 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. - */ - -#if !defined(NDEBUG) -#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING -#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE -#endif - -#include -#include -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* an employee record holds its ID, name and age */ - -struct employee -{ - int id; - std::string name; - int age; - - employee(int id_,std::string name_,int age_):id(id_),name(name_),age(age_){} - - friend std::ostream& operator<<(std::ostream& os,const employee& e) - { - os<, BOOST_MULTI_INDEX_MEMBER(employee,int,id)>, - ordered_non_unique< - tag,BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>, - ordered_non_unique< - tag, BOOST_MULTI_INDEX_MEMBER(employee,int,age)> > -> employee_set; - -template -void print_out_by( - const MultiIndexContainer& s, - Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */ -) -{ - /* obtain a reference to the index tagged by Tag */ - - const typename boost::multi_index::index::type& i= - get(s); - - typedef typename MultiIndexContainer::value_type value_type; - - /* dump the elements of the index to cout */ - - std::copy(i.begin(),i.end(),std::ostream_iterator(std::cout)); -} - - -int main() -{ - employee_set es; - - es.insert(employee(0,"Joe",31)); - es.insert(employee(1,"Robert",27)); - es.insert(employee(2,"John",40)); - - /* next insertion will fail, as there is an employee with - * the same ID - */ - - es.insert(employee(2,"Aristotle",2387)); - - es.insert(employee(3,"Albert",20)); - es.insert(employee(4,"John",57)); - - /* list the employees sorted by ID, name and age */ - - std::cout<<"by ID"<(es); - std::cout<(es); - std::cout<(es); - std::cout< -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* tags for accessing both sides of a bidirectional map */ - -struct from{}; -struct to{}; - -/* The class template bidirectional_map wraps the specification - * of a bidirectional map based on multi_index_container. - */ - -template -struct bidirectional_map -{ - typedef std::pair value_type; - -#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\ - defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\ - defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\ - (BOOST_INTEL_CXX_VERSION<=700) - -/* see Compiler specifics: Use of member_offset for info on member<> and - * member_offset<> - */ - - BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first)); - BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second)); - - typedef multi_index_container< - value_type, - indexed_by< - ordered_unique< - tag,member_offset >, - ordered_unique< - tag, member_offset > - > - > type; - -#else - - /* A bidirectional map can be simulated as a multi_index_container - * of pairs of (FromType,ToType) with two unique indices, one - * for each member of the pair. - */ - - typedef multi_index_container< - value_type, - indexed_by< - ordered_unique< - tag,member >, - ordered_unique< - tag, member > - > - > type; - -#endif -}; - -/* a dictionary is a bidirectional map from strings to strings */ - -typedef bidirectional_map::type dictionary; - -int main() -{ - dictionary d; - - /* Fill up our microdictionary. first members Spanish, second members - * English. - */ - - d.insert(dictionary::value_type("hola","hello")); - d.insert(dictionary::value_type("adios","goodbye")); - d.insert(dictionary::value_type("rosa","rose")); - d.insert(dictionary::value_type("mesa","table")); - - - std::cout<<"enter a word"< and family instead */ - - dictionary::iterator it=get(d).find(word); - if(it!=d.end()){ - std::cout<second<<" in English"<::type it2=get<1>(d).find(word); - if(it2!=get<1>(d).end()){ - std::cout<first<<" in Spanish"<().find(word); - if(it!=d.end()){ /* found */ - - /* the second part of the element is the equivalent in English */ - - std::cout<second<<" in English"<::type it2=d.get().find(word); - if(it2!=d.get().end()){ - std::cout<first<<" in Spanish"< -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* This small utility that cascades two key extractors will be - * used througout the example. - */ - -template -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 - result_type operator()(Arg& arg)const - { - return key1(key2(arg)); - } - -private: - KeyExtractor1 key1; - KeyExtractor2 key2; -}; - -/* tags for accessing several indices defined below */ - -struct model{}; -struct manufacturer{}; -struct price{}; - -/* a manufacturer struct just holds the name of the manufacturer */ - -struct car_manufacturer -{ - std::string name; - - car_manufacturer(const std::string& name_):name(name_){} -}; - -/* car_model holds the model of car, its price and a pointer to the - * manufacturer. The pointer thing eliminates duplication of the same - * data among cars of the same manufacturer. - */ - -struct car_model -{ - std::string model; - const car_manufacturer* manufacturer; - int price; - - car_model( - const std::string& model_,const car_manufacturer* manufacturer_,int price_): - model(model_),manufacturer(manufacturer_),price(price_) - {} - - friend std::ostream& operator<<(std::ostream& os,const car_model& c) - { - os<name<<" "< does the work for us.) - */ - -typedef multi_index_container< - car_manufacturer, - indexed_by< - ordered_unique< - BOOST_MULTI_INDEX_MEMBER(car_manufacturer,std::string,name) - > - > -> car_manufacturer_table; - -/* Define a multi_index_container of car_models with following indices: - * - a unique index sorted by car_model::model, - * - a non-unique index sorted by car_model::manufacturer; note the - * non-standard manufacturer_extractor used. - * - a non-unique index sorted by car_model::price. - */ - -typedef multi_index_container< - car_model, - indexed_by< - ordered_unique< - tag,BOOST_MULTI_INDEX_MEMBER(car_model,std::string,model) - >, - ordered_non_unique< - tag, - key_from_key< - BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name), - BOOST_MULTI_INDEX_MEMBER( - car_model,const car_manufacturer *,manufacturer) - > - >, - ordered_non_unique< - tag,BOOST_MULTI_INDEX_MEMBER(car_model,int,price) - > - > -> car_table; - -/* We call a *view* to a multi_index_container storing pointers instead of - * actual objects. These views are used in the complex search performed - * in the program. Resorting to multi_index of pointers eliminates - * unnecessary copying of objects, and provides us with an opportunity - * to show how BOOST_MULTI_INDEX_MEMBER can be used with pointer - * type elements. - * car_table_price_view indexes (pointers to) car_models by price. - */ - -typedef multi_index_container< - const car_model*, - indexed_by< - ordered_non_unique - > -> car_table_price_view; - -/* car_table_manufacturer_view indexes (pointers to) car_models by - * manufacturer - */ - -typedef multi_index_container< - const car_model*, - indexed_by< - ordered_non_unique< - key_from_key< - BOOST_MULTI_INDEX_MEMBER(car_manufacturer,const std::string,name), - BOOST_MULTI_INDEX_MEMBER( - car_model,const car_manufacturer * const,manufacturer) - > - > - > -> car_table_manufacturer_view; - -int main() -{ - car_manufacturer_table cmt; - - /* Fill the car_manufacturer table and keep pointers to the - * elements inserted. - */ - - const car_manufacturer * cadillac= - &*(cmt.insert(car_manufacturer("Cadillac")).first); - const car_manufacturer * ford = - &*(cmt.insert(car_manufacturer("Ford")).first); - const car_manufacturer * bmw = - &*(cmt.insert(car_manufacturer("BMW")).first); - const car_manufacturer * audi = - &*(cmt.insert(car_manufacturer("Audi")).first); - - car_table ct; - - /* Fill the car_model_table. We use the previously initialized - * pointers to the elements of cmt. - */ - - ct.insert(car_model("XLR",cadillac,76200)); - ct.insert(car_model("SRX",cadillac,38690)); - ct.insert(car_model("CTS",cadillac,30695)); - ct.insert(car_model("Escalade",cadillac,54770)); - ct.insert(car_model("ESV",cadillac,57195)); - ct.insert(car_model("EXT",cadillac,52045)); - ct.insert(car_model("Deville",cadillac,45195)); - ct.insert(car_model("Seville",cadillac,46330)); - - ct.insert(car_model("ZX2",ford,15355)); - ct.insert(car_model("Thunderbird",ford,43995)); - ct.insert(car_model("Windstar",ford,35510)); - ct.insert(car_model("Focus",ford,19630)); - ct.insert(car_model("Taurus",ford,24290)); - ct.insert(car_model("Mustang",ford,39900)); - ct.insert(car_model("Crown Victoria",ford,30370)); - - ct.insert(car_model("325i",bmw,27800)); - ct.insert(car_model("545i",bmw,54300)); - ct.insert(car_model("745i",bmw,68500)); - ct.insert(car_model("M3 coupe",bmw,46500)); - ct.insert(car_model("Z4 roadster 3.0i",bmw,40250)); - ct.insert(car_model("X5 4.4i",bmw,49950)); - - ct.insert(car_model("A4 1.8T",audi,25940)); - ct.insert(car_model("TT Coupe",audi,33940)); - ct.insert(car_model("A6 3.0",audi,36640)); - ct.insert(car_model("Allroad quattro 2.7T",audi,40640)); - ct.insert(car_model("A8 L",audi,69190)); - - std::cout<<"enter a car manufacturer"<>min_price; - std::cout<<"enter a maximum price"<>max_price; - - { - /* method 1 */ - - /* find all the cars for the manufacturer given */ - - index_iterator::type ic0,ic1; - boost::tuples::tie(ic0,ic1)=get(ct).equal_range(cm); - - /* construct a view (indexed by price) with these */ - - car_table_price_view ctpv; - while(ic0!=ic1){ - ctpv.insert(&*ic0); - ++ic0; - } - - /* select the cars in the range given */ - - car_table_price_view::iterator ictpv0=ctpv.lower_bound(min_price); - car_table_price_view::iterator ictpv1=ctpv.upper_bound(max_price); - if(ictpv0==ictpv1){ - std::cout<<"no cars in the range given"<::type ic0,ic1; - ic0=get(ct).lower_bound(min_price); - ic1=get(ct).upper_bound(max_price); - - /* construct a view with these */ - - car_table_manufacturer_view ctmv; - while(ic0!=ic1){ - ctmv.insert(&*ic0); - ++ic0; - } - - /* select the cars with given manufacturer */ - - car_table_manufacturer_view::iterator ictmv0,ictmv1; - boost::tuples::tie(ictmv0,ictmv1)=ctmv.equal_range(cm); - if(ictmv0==ictmv1){ - std::cout<<"no cars in the range given"< -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::multi_index; - -/* A file record maintains some info on name and size as well - * as a pointer to the directory it belongs (null meaning the root - * directory.) - */ - -struct file_entry -{ - file_entry( - std::string name_,unsigned size_,bool is_dir_,const file_entry* dir_): - name(name_),size(size_),is_dir(is_dir_),dir(dir_) - {} - - std::string name; - unsigned size; - bool is_dir; - const file_entry* dir; - - friend std::ostream& operator<<(std::ostream& os,const file_entry& f) - { - os<"; - return os; - } -}; - -/* A file system is just a multi_index_container of entries with indices on - * file and size. These indices are firstly ordered by directory, as commands - * work on a current directory basis. Composite keys are just fine to model - * this. - * NB: The use of derivation here instead of simple typedef is explained in - * Compiler specifics: type hiding. - */ - -struct name_key:composite_key< - file_entry, - BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry*,dir), - BOOST_MULTI_INDEX_MEMBER(file_entry,std::string,name) ->{}; - -struct size_key:composite_key< - file_entry, - BOOST_MULTI_INDEX_MEMBER(file_entry,const file_entry* const,dir), - BOOST_MULTI_INDEX_MEMBER(file_entry,unsigned,size) ->{}; - -/* see Compiler specifics: composite_key in compilers without partial - * template specialization, for info on composite_key_result_less - */ - -typedef multi_index_container< - file_entry, - indexed_by< - /* primary index sorted by name (inside the same directory) */ - ordered_unique< - name_key -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - ,composite_key_result_less -#endif - >, - /* secondary index sorted by size (inside the same directory) */ - ordered_non_unique< - size_key -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - ,composite_key_result_less -#endif - > - > -> file_system; - -/* typedef's of the two indices of file_system */ - -typedef nth_index::type file_system_by_name; -typedef nth_index::type file_system_by_size; - -/* We build a rudimentary file system simulation out of some global - * info and a map of commands provided to the user. - */ - -static file_system fs; /* the one and only file system */ -static file_system_by_name& fs_by_name=fs; /* name index to fs */ -static file_system_by_size& fs_by_size=get<1>(fs); /* size index to fs */ -static const file_entry* current_dir=0; /* root directory */ - -/* command framework */ - -/* A command provides an execute memfun fed with the corresponding params - * (first param is stripped off as it serves to identify the command - * currently being used.) - */ - -typedef boost::tokenizer > command_tokenizer; - -class command -{ -public: - virtual ~command(){} - virtual void execute( - command_tokenizer::iterator tok1,command_tokenizer::iterator tok2)=0; -}; - -/* available commands */ - -/* cd: syntax cd [.|..|] */ - -class command_cd:public command -{ -public: - virtual void execute( - command_tokenizer::iterator tok1,command_tokenizer::iterator tok2) - { - if(tok1==tok2)return; - std::string dir=*tok1++; - - if(dir==".")return; - if(dir==".."){ - if(current_dir)current_dir=current_dir->dir; - return; - } - - file_system_by_name::iterator it=fs.find( - boost::make_tuple(current_dir,dir)); - if(it==fs.end()){ - std::cout<<"non-existent directory"<is_dir){ - std::cout<(std::cout,"\n")); - - return; - } - - /* list by name */ - - file_system_by_name::iterator it0,it1; - boost::tie(it0,it1)=fs.equal_range(boost::make_tuple(current_dir)); - std::copy(it0,it1,std::ostream_iterator(std::cout,"\n")); - } -}; -static command_ls ls; - -/* mkdir: syntax mkdir */ - -class command_mkdir:public command -{ -public: - virtual void execute( - command_tokenizer::iterator tok1,command_tokenizer::iterator tok2) - { - std::string dir; - if(tok1!=tok2)dir=*tok1++; - - if(dir.empty()){ - std::cout<<"missing parameter"< command_table; -static command_table cmt; - -int main() -{ - /* fill the file system with some data */ - - file_system::iterator it0,it1; - - fs.insert(file_entry("usr.cfg",240,false,0)); - fs.insert(file_entry("memo.txt",2430,false,0)); - it0=fs.insert(file_entry("dev",0,true,0)).first; - fs.insert(file_entry("tty0",128,false,&*it0)); - fs.insert(file_entry("tty1",128,false,&*it0)); - it0=fs.insert(file_entry("usr",0,true,0)).first; - it1=fs.insert(file_entry("bin",0,true,&*it0)).first; - fs.insert(file_entry("bjam",172032,false,&*it1)); - it0=fs.insert(file_entry("home",0,true,0)).first; - it1=fs.insert(file_entry("andy",0,true,&*it0)).first; - fs.insert(file_entry("logo.jpg",5345,false,&*it1)).first; - fs.insert(file_entry("foo.cpp",890,false,&*it1)).first; - fs.insert(file_entry("foo.hpp",93,false,&*it1)).first; - fs.insert(file_entry("foo.html",750,false,&*it1)).first; - fs.insert(file_entry("a.obj",12302,false,&*it1)).first; - fs.insert(file_entry(".bash_history",8780,false,&*it1)).first; - it1=fs.insert(file_entry("rachel",0,true,&*it0)).first; - fs.insert(file_entry("test.py",650,false,&*it1)).first; - fs.insert(file_entry("todo.txt",241,false,&*it1)).first; - fs.insert(file_entry(".bash_history",9510,false,&*it1)).first; - - /* fill the command table */ - - cmt["cd"] =&cd; - cmt["ls"] =&ls; - cmt["mkdir"]=&mkdir; - - /* main looop */ - - for(;;){ - /* print out the current directory and the prompt symbol */ - - if(current_dir)std::cout<name; - std::cout<<">"; - - /* get an input line from the user: if empty, exit the program */ - - std::string com; - std::getline(std::cin,com); - command_tokenizer tok(com,boost::char_separator(" \t\n")); - if(tok.begin()==tok.end())break; /* null command, exit */ - - /* select the corresponding command and execute it */ - - command_table::iterator it=cmt.find(*tok.begin()); - if(it==cmt.end()){ - std::cout<<"invalid command"<second->execute(++tok.begin(),tok.end()); - } - - return 0; -} diff --git a/example/hashed.cpp b/example/hashed.cpp deleted file mode 100644 index 5753e8d..0000000 --- a/example/hashed.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* Boost.MultiIndex example of use of hashed indices. - * - * 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. - */ - -#if !defined(NDEBUG) -#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING -#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* word_counter keeps the ocurrences of words inserted. A hashed - * index allows for fast checking of preexisting entries. - */ - -struct word_counter_entry -{ - std::string word; - unsigned int occurrences; - - word_counter_entry(std::string word_):word(word_),occurrences(0){} -}; - -/* see Compiler specifics: Use of member_offset for info on - * BOOST_MULTI_INDEX_MEMBER - */ - -typedef multi_index_container< - word_counter_entry, - indexed_by< - ordered_non_unique< - BOOST_MULTI_INDEX_MEMBER(word_counter_entry,unsigned int,occurrences), - std::greater /* sorted beginning with most frequent */ - >, - hashed_unique< - BOOST_MULTI_INDEX_MEMBER(word_counter_entry,std::string,word) - > - > -> word_counter; - -/* utilities */ - -template -struct increment -{ - void operator()(T& x)const{++x;} -}; - -typedef boost::tokenizer > text_tokenizer; - -int main() -{ - std::string text= - "En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha " - "mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga " - "antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que " - "carnero, salpicón las más noches, duelos y quebrantos los sábados, " - "lantejas los viernes, algún palomino de añadidura los domingos, " - "consumían las tres partes de su hacienda. El resto della concluían sayo " - "de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo " - "mesmo, y los días de entresemana se honraba con su vellorí de lo más " - "fino. Tenía en su casa una ama que pasaba de los cuarenta, y una " - "sobrina que no llegaba a los veinte, y un mozo de campo y plaza, que " - "así ensillaba el rocín como tomaba la podadera. Frisaba la edad de " - "nuestro hidalgo con los cincuenta años; era de complexión recia, seco " - "de carnes, enjuto de rostro, gran madrugador y amigo de la caza. " - "Quieren decir que tenía el sobrenombre de Quijada, o Quesada, que en " - "esto hay alguna diferencia en los autores que deste caso escriben; " - "aunque, por conjeturas verosímiles, se deja entender que se llamaba " - "Quejana. Pero esto importa poco a nuestro cuento; basta que en la " - "narración dél no se salga un punto de la verdad."; - - /* feed the text into the container */ - - word_counter wc; - text_tokenizer tok(text,boost::char_separator(" \t\n.,;:!?'\"-")); - unsigned int total_occurrences=0; - for(text_tokenizer::iterator it=tok.begin(),it_end=tok.end(); - it!=it_end;++it){ - /* Insert the word into the container. If duplicate, wit will point to - * the preexistent entry. - */ - - ++total_occurrences; - word_counter::iterator wit=wc.insert(*it).first; - - /* Increment occurrences. - * In a lambda-capable compiler, this can be written as: - * wc.modify_key(wit,++_1); - */ - - wc.modify_key(wit,increment()); - } - - /* list words by frequency of appearance */ - - std::cout<word<<": " - <occurrences/total_occurrences<<"%" - < -#include -#include -#include -#include - -using namespace boost::multi_index; - -/* A name record consists of the given name (e.g. "Charlie") - * and the family name (e.g. "Brown"). The full name, calculated - * by name_record::name() is laid out in the "phonebook order" - * family name + given_name. - */ - -struct name_record -{ - name_record(std::string given_name,std::string family_name): - given_name(given_name),family_name(family_name) - {} - - std::string name()const - { - std::string str=family_name; - str+=" "; - str+=given_name; - return str; - } - -private: - std::string given_name; - std::string family_name; -}; - -/* multi_index_container with only one index based on name_record::name(). - * See Compiler specifics: Use of const_mem_fun_explicit and - * mem_fun_explicit for info on BOOST_MULTI_INDEX_CONST_MEM_FUN. - */ - -typedef multi_index_container< - name_record, - indexed_by< - ordered_unique< - BOOST_MULTI_INDEX_CONST_MEM_FUN(name_record,std::string,name) - > - > -> name_record_set; - -int main() -{ - name_record_set ns; - - ns.insert(name_record("Joe","Smith")); - ns.insert(name_record("Robert","Nightingale")); - ns.insert(name_record("Robert","Brown")); - ns.insert(name_record("Marc","Tuxedo")); - - /* list the names in ns in phonebook order */ - - for(name_record_set::iterator it=ns.begin();it!=ns.end();++it){ - std::cout<name()< -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* modulo_less order numbers according to their division residual. - * For instance, if modulo==10 then 22 is less than 15 as 22%10==2 and - * 15%10==5. - */ - -template -struct modulo_less -{ - modulo_less(IntegralType m):modulo(m){} - - bool operator()(IntegralType x,IntegralType y)const - { - return (x%modulo)<(y%modulo); - } - -private: - IntegralType modulo; -}; - -/* multi_index_container of unsigned ints holding a "natural" index plus - * an ordering based on modulo_less. - */ - -typedef multi_index_container< - unsigned int, - indexed_by< - ordered_unique >, - ordered_non_unique, modulo_less > - > -> modulo_indexed_set; - -int main() -{ - /* define a modulo_indexed_set with modulo==10 */ - - modulo_indexed_set::ctor_args_list args_list= - boost::make_tuple( - /* ctor_args for index #0 is default constructible */ - nth_index::type::ctor_args(), - - /* first parm is key_from_value, second is our sought for key_compare */ - boost::make_tuple(identity(),modulo_less(10)) - ); - - modulo_indexed_set m(args_list); - /* this could have be written online without the args_list variable, - * left as it is for explanatory purposes. */ - - /* insert some numbers */ - - unsigned int numbers[]={0,1,20,40,33,68,11,101,60,34,88,230,21,4,7,17}; - const std::size_t numbers_length(sizeof(numbers)/sizeof(numbers[0])); - - m.insert(&numbers[0],&numbers[numbers_length]); - - /* lists all numbers in order, along with their "equivalence class", that is, - * the equivalent numbers under modulo_less - */ - - for(modulo_indexed_set::iterator it=m.begin();it!=m.end();++it){ - std::cout<<*it<<" -> ( "; - - nth_index::type::iterator it0,it1; - boost::tie(it0,it1)=get<1>(m).equal_range(*it); - std::copy(it0,it1,std::ostream_iterator(std::cout," ")); - - std::cout<<")"< -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using boost::multi_index_container; -using namespace boost::multi_index; - -/* text_container holds words as inserted and also keep them indexed - * by dictionary order. - */ - -typedef multi_index_container< - std::string, - indexed_by< - sequenced<>, - ordered_non_unique > - > -> text_container; - -/* ordered index */ - -typedef nth_index::type ordered_text; - -typedef boost::tokenizer > text_tokenizer; - -int main() -{ - 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 container */ - - text_container tc; - text_tokenizer tok(text,boost::char_separator(" \t\n.,;:!?'\"-")); - std::copy(tok.begin(),tok.end(),std::back_inserter(tc)); - - /* list all words in alphabetical order along with their number - * of occurrences - */ - - ordered_text& ot=get<1>(tc); - for(ordered_text::iterator it=ot.begin();it!=ot.end();){ - std::cout<(std::cout," ")); - std::cout<(std::cout," ")); - std::cout< /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace boost::multi_index; - -/* An MRU (most recently used) list keeps record of the last n - * inserted items, listing first the newer ones. Care has to be - * taken when a duplicate item is inserted: instead of letting it - * appear twice, the MRU list relocates it to the first position. - */ - -template -class mru_list -{ - typedef multi_index_container< - Item, - indexed_by< - sequenced<>, - hashed_unique > - > - > item_list; - -public: - typedef Item item_type; - typedef typename item_list::iterator iterator; - - mru_list(std::size_t max_num_items):max_num_items(max_num_items){} - - void insert(const item_type& item) - { - std::pair p=il.push_front(item); - - if(!p.second){ /* duplicate item */ - il.relocate(il.begin(),p.first); /* put in front */ - } - else if(il.size()>max_num_items){ /* keep the length <= max_num_items */ - il.pop_back(); - } - } - - iterator begin(){return il.begin();} - iterator end(){return il.end();} - - /* Utilities to save and load the MRU list, internally - * based on Boost.Serialization. - */ - - void save_to_file(const char* file_name)const - { - std::ofstream ofs(file_name); - boost::archive::text_oarchive oa(ofs); - oa<>boost::serialization::make_nvp("mru",*this); - } - } - -private: - item_list il; - std::size_t max_num_items; - - /* serialization support */ - - friend class boost::serialization::access; - - template - void serialize(Archive& ar,const unsigned int) - { - ar&BOOST_SERIALIZATION_NVP(il); - ar&BOOST_SERIALIZATION_NVP(max_num_items); - } -}; - -int main() -{ - const char* mru_store="mru_store"; - - /* Construct a MRU limited to 10 items and retrieve its - * previous contents. - */ - - mru_list mru(10); - mru.load_from_file(mru_store); - - /* main loop */ - - for(;;){ - std::cout<<"enter a term: "; - - std::string line; - std::getline(std::cin,line); - if(line.empty())break; - - std::string term; - std::istringstream iss(line); - iss>>term; - if(term.empty())break; - - mru.insert(term); - - std::cout<<"most recently entered terms:"<(std::cout,"\n")); - } - - /* persist the MRU list */ - - mru.save_to_file(mru_store); - - return 0; -} diff --git a/index.html b/index.html deleted file mode 100644 index c190fc1..0000000 --- a/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - -Boost.MultiIndex Documentation - - - - -Automatic redirection failed, please go to -doc/index.html - - diff --git a/perf/Jamfile b/perf/Jamfile deleted file mode 100644 index bae97b5..0000000 --- a/perf/Jamfile +++ /dev/null @@ -1,16 +0,0 @@ -# Boost.MultiIndex performance 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/perf ; - -exe test_perf - : test_perf.cpp - : $(BOOST_ROOT) - : release - ; diff --git a/perf/test_perf.cpp b/perf/test_perf.cpp deleted file mode 100644 index 5267e0c..0000000 --- a/perf/test_perf.cpp +++ /dev/null @@ -1,560 +0,0 @@ -/* Boost.MultiIndex performance test. - * - * 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. - */ - -#include /* keep it first to prevent nasty warns in MSVC */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std; -using namespace boost::multi_index; - -/* Measurement harness by Andrew Koenig, extracted from companion code to - * Stroustrup, B.: "Wrapping C++ Member Function Calls", The C++ Report, - * June 2000, Vol 12/No 6. - * Original code retrievable at: http://www.research.att.com/~bs/wrap_code.cpp - */ - -// How many clock units does it take to interrogate the clock? -static double clock_overhead() -{ - clock_t k = clock(), start, limit; - - // Wait for the clock to tick - do start = clock(); - while (start == k); - - // interrogate the clock until it has advanced at least a second - // (for reasonable accuracy) - limit = start + CLOCKS_PER_SEC; - - unsigned long r = 0; - while ((k = clock()) < limit) - ++r; - - return double(k - start) / r; -} - -// We'd like the odds to be factor:1 that the result is -// within percent% of the median -const int factor = 10; -const int percent = 20; - -// Measure a function (object) factor*2 times, -// appending the measurements to the second argument -template -void measure_aux(F f, vector& mv) -{ - static double ovhd = clock_overhead(); - - // Ensure we don't reallocate in mid-measurement - mv.reserve(mv.size() + factor*2); - - // Wait for the clock to tick - clock_t k = clock(); - clock_t start; - - do start = clock(); - while (start == k); - - // Do 2*factor measurements - for (int i = 2*factor; i; --i) { - unsigned long count = 0, limit = 1, tcount = 0; - const clock_t clocklimit = start + CLOCKS_PER_SEC/100; - clock_t t; - - do { - while (count < limit) { - f(); - ++count; - } - limit *= 2; - ++tcount; - } while ((t = clock()) < clocklimit); - - // Wait for the clock to tick again; - clock_t t2; - do ++tcount; - while ((t2 = clock()) == t); - - // Append the measurement to the vector - mv.push_back(((t2 - start) - (tcount * ovhd)) / count); - - // Establish a new starting point - start = t2; - } -} - -// Returns the number of clock units per iteration -// With odds of factor:1, the measurement is within percent% of -// the value returned, which is also the median of all measurements. -template -double measure(F f) -{ - vector mv; - - int n = 0; // iteration counter - do { - ++n; - - // Try 2*factor measurements - measure_aux(f, mv); - assert(mv.size() == 2*n*factor); - - // Compute the median. We know the size is even, so we cheat. - sort(mv.begin(), mv.end()); - double median = (mv[n*factor] + mv[n*factor-1])/2; - - // If the extrema are within threshold of the median, we're done - if (mv[n] > (median * (100-percent))/100 && - mv[mv.size() - n - 1] < (median * (100+percent))/100) - return median; - - } while (mv.size() < factor * 200); - - // Give up! - clog << "Help!\n\n"; - exit(1); -} - -/* dereferencing compare predicate */ - -template -struct it_compare -{ - bool operator()(const Iterator& x,const Iterator& y)const{return comp(*x,*y);} - -private: - Compare comp; -}; - -/* list_wrapper and multiset_wrapper adapt std::lists and std::multisets - * to make them conform to a set-like insert interface which test - * routines do assume. - */ - -template -struct list_wrapper:List -{ - typedef typename List::value_type value_type; - typedef typename List::iterator iterator; - - pair insert(const value_type& v) - { - List::push_back(v); - return pair(--List::end(),true); - } -}; - -template -struct multiset_wrapper:Multiset -{ - typedef typename Multiset::value_type value_type; - typedef typename Multiset::iterator iterator; - - pair insert(const value_type& v) - { - return pair(Multiset::insert(v),true); - } -}; - -/* space comsumption of manual simulations is determined by checking - * the node sizes of the containers involved. This cannot be done in a - * portable manner, so node_size has to be written on a per stdlibrary - * basis. Add your own versions if necessary. - */ - -#if defined(BOOST_DINKUMWARE_STDLIB) - -template -size_t node_size(const Container&) -{ - return sizeof(*Container().begin()._Mynode()); -} - -#elif defined(__GLIBCPP__) - -template -size_t node_size(const Container&) -{ - typedef typename Container::iterator::_Link_type node_ptr; - node_ptr p=0; - return sizeof(*p); -} - -template -size_t node_size(const list&) -{ - return sizeof(typename list::iterator::_Node); -} - -template -size_t node_size(const list_wrapper&) -{ - return sizeof(typename List::iterator::_Node); -} - -#else - -/* default version returns 0 by convention */ - -template -size_t node_size(const Container&) -{ - return 0; -} - -#endif - -/* mono_container runs the tested routine on multi_index and manual - * simulations comprised of one standard container. - * bi_container and tri_container run the equivalent routine for manual - * compositions of two and three standard containers, respectively. - */ - -template -struct mono_container -{ - mono_container(int n_):n(n_){} - - void operator()() - { - typedef typename Container::iterator iterator; - - Container c; - - for(int i=0;i -struct bi_container -{ - bi_container(int n_):n(n_){} - - void operator()() - { - typedef typename Container1::iterator iterator1; - typedef typename Container2::iterator iterator2; - - Container1 c1; - Container2 c2; - - for(int i=0;i -struct tri_container -{ - tri_container(int n_):n(n_){} - - void operator()() - { - typedef typename Container1::iterator iterator1; - typedef typename Container2::iterator iterator2; - typedef typename Container3::iterator iterator3; - - Container1 c1; - Container2 c2; - Container3 c3; - - for(int i=0;i -void run_tests( - const char* title - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedTest) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualTest)) -{ - cout< -void compare_structures( - const char* title - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType)) -{ - run_tests< - mono_container, - mono_container - >(title); -} - -template -void compare_structures2( - const char* title - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType1) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType2)) -{ - run_tests< - mono_container, - bi_container - >(title); -} - -template < - typename IndexedType, - typename ManualType1,typename ManualType2,typename ManualType3 -> -void compare_structures3( - const char* title - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(IndexedType) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType1) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType2) - BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(ManualType3)) -{ - run_tests< - mono_container, - tri_container - >(title); -} - -int main() -{ - { - /* 1 ordered index */ - - typedef multi_index_container indexed_t; - typedef set manual_t; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures( - "1 ordered index"); - } - { - /* 1 sequenced index */ - - typedef list_wrapper< - multi_index_container< - int, - indexed_by > - > - > indexed_t; - typedef list_wrapper > manual_t; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures( - "1 sequenced index"); - } - { - /* 2 ordered indices */ - - typedef multi_index_container< - int, - indexed_by< - ordered_unique >, - ordered_non_unique > - > - > indexed_t; - typedef set manual_t1; - typedef multiset< - manual_t1::iterator, - it_compare< - manual_t1::iterator, - manual_t1::key_compare - > - > manual_t2; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures2( - "2 ordered indices"); - } - { - /* 1 ordered index + 1 sequenced index */ - - typedef multi_index_container< - int, - indexed_by< - boost::multi_index::ordered_unique >, - sequenced<> - > - > indexed_t; - typedef list_wrapper< - list - > manual_t1; - typedef multiset< - manual_t1::iterator, - it_compare< - manual_t1::iterator, - std::less - > - > manual_t2; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures2( - "1 ordered index + 1 sequenced index"); - } - { - /* 3 ordered indices */ - - typedef multi_index_container< - int, - indexed_by< - ordered_unique >, - ordered_non_unique >, - ordered_non_unique > - > - > indexed_t; - typedef set manual_t1; - typedef multiset_wrapper< - multiset< - manual_t1::iterator, - it_compare< - manual_t1::iterator, - manual_t1::key_compare - > - > - > manual_t2; - typedef multiset< - manual_t2::iterator, - it_compare< - manual_t2::iterator, - manual_t2::key_compare - > - > manual_t3; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures3( - "3 ordered indices"); - } - { - /* 2 ordered indices + 1 sequenced index */ - - typedef multi_index_container< - int, - indexed_by< - ordered_unique >, - ordered_non_unique >, - sequenced<> - > - > indexed_t; - typedef list_wrapper< - list - > manual_t1; - typedef multiset_wrapper< - multiset< - manual_t1::iterator, - it_compare< - manual_t1::iterator, - std::less - > - > - > manual_t2; - typedef multiset< - manual_t2::iterator, - it_compare< - manual_t2::iterator, - manual_t2::key_compare - > - > manual_t3; - indexed_t dummy; /* MSVC++ 6.0 chokes if indexed_t is not instantiated */ - - compare_structures3( - "2 ordered indices + 1 sequenced index"); - } - - return 0; -} diff --git a/test/Jamfile b/test/Jamfile deleted file mode 100644 index f11baea..0000000 --- a/test/Jamfile +++ /dev/null @@ -1,79 +0,0 @@ -# Boost.MultiIndex tests 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/test ; - -# bring in rules for testing - -import testing ; - -local rule special-requirements ( toolset variant : properties * ) -{ - # GCC on Tru64 has problems with long debug symbols generated by - # Boost.MultiIndex, so we turn them off when in that platform - - if $(UNIX) && $(OS) = OSF - { - switch $(toolset) - { - case gcc* : properties = - [ replace-properties $(properties) : off ] ; - } - } - - return $(properties) ; -} - -# local specialization of rule run automatically including special requirements - -local rule local-run ( sources + : args * : input-files * : requirements * - : name ? : default-build * : args2 * ) -{ - return [ run $(sources) : $(args) : $(input-files) - : $(requirements) special-requirements - : $(name) : $(default-build) : $(args2) ] ; -} - -# make tests run by default - -DEPENDS all : test ; - -# bring in Boost.Serialization rules - -import ../../../libs/serialization/build/serialization ; - -{ - test-suite "multi_index" - : [ local-run test_basic.cpp test_basic_main.cpp ] - : [ local-run test_capacity.cpp test_capacity_main.cpp ] - : [ local-run test_comparison.cpp test_comparison_main.cpp ] - : [ local-run test_composite_key.cpp test_composite_key_main.cpp ] - : [ local-run test_conv_iterators.cpp test_conv_iterators_main.cpp ] - : [ local-run test_copy_assignment.cpp test_copy_assignment_main.cpp ] - : [ local-run test_hash_ops.cpp test_hash_ops_main.cpp ] - : [ local-run test_iterators.cpp test_iterators_main.cpp ] - : [ local-run test_key_extractors.cpp test_key_extractors_main.cpp ] - : [ local-run test_list_ops.cpp test_list_ops_main.cpp ] - : [ local-run test_modifiers.cpp test_modifiers_main.cpp ] - : [ local-run test_mpl_ops.cpp test_mpl_ops_main.cpp ] - : [ local-run test_observers.cpp test_observers_main.cpp ] - : [ local-run test_projection.cpp test_projection_main.cpp ] - : [ local-run test_range.cpp test_range_main.cpp ] - : [ local-run test_safe_mode.cpp test_safe_mode_main.cpp ] - : [ local-run test_serialization.cpp test_serialization_main.cpp - ../../serialization/build/boost_serialization - : # args - : # input files - : std::locale-support toolset::require-boost-spirit-support ] - : [ local-run test_set_ops.cpp test_set_ops_main.cpp ] - : [ local-run test_special_list_ops.cpp test_special_list_ops_main.cpp ] - : [ local-run test_special_set_ops.cpp test_special_set_ops_main.cpp ] - : [ local-run test_update.cpp test_update_main.cpp ] - ; -} diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 deleted file mode 100644 index 983f4c0..0000000 --- a/test/Jamfile.v2 +++ /dev/null @@ -1,33 +0,0 @@ -# Boost.MultiIndex 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. - -test-suite "multi_index" : - [ run test_basic.cpp test_basic_main.cpp ] - [ run test_capacity.cpp test_capacity_main.cpp ] - [ run test_comparison.cpp test_comparison_main.cpp ] - [ run test_composite_key.cpp test_composite_key_main.cpp ] - [ run test_conv_iterators.cpp test_conv_iterators_main.cpp ] - [ run test_copy_assignment.cpp test_copy_assignment_main.cpp ] - [ run test_hash_ops.cpp test_hash_ops_main.cpp ] - [ run test_iterators.cpp test_iterators_main.cpp ] - [ run test_key_extractors.cpp test_key_extractors_main.cpp ] - [ run test_list_ops.cpp test_list_ops_main.cpp ] - [ run test_modifiers.cpp test_modifiers_main.cpp ] - [ run test_mpl_ops.cpp test_mpl_ops_main.cpp ] - [ run test_observers.cpp test_observers_main.cpp ] - [ run test_projection.cpp test_projection_main.cpp ] - [ run test_range.cpp test_range_main.cpp ] - [ run test_safe_mode.cpp test_safe_mode_main.cpp ] - [ run test_serialization.cpp test_serialization_main.cpp - /boost/serialization//boost_serialization ] - [ run test_set_ops.cpp test_set_ops_main.cpp ] - [ run test_special_list_ops.cpp test_special_list_ops_main.cpp ] - [ run test_special_set_ops.cpp test_special_set_ops_main.cpp ] - [ run test_update.cpp test_update_main.cpp ] - ; diff --git a/test/employee.hpp b/test/employee.hpp deleted file mode 100644 index 04157cd..0000000 --- a/test/employee.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* Used in Boost.MultiIndex tests. - * - * 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. - */ - -#ifndef BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP -#define BOOST_MULTI_INDEX_TEST_EMPLOYEE_HPP - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct employee -{ - int id; - std::string name; - int age; - int ssn; - - employee(int id_,std::string name_,int age_,int ssn_): - id(id_),name(name_),age(age_),ssn(ssn_) - {} - - bool operator==(const employee& x)const - { - return id==x.id&&name==x.name&&age==x.age; - } - - bool operator<(const employee& x)const - { - return id (const employee& x)const{return x<*this;} - bool operator>=(const employee& x)const{return !(*this >, - boost::multi_index::hashed_non_unique< - boost::multi_index::tag, - BOOST_MULTI_INDEX_MEMBER(employee,std::string,name)>, - boost::multi_index::ordered_non_unique< - boost::multi_index::tag, - BOOST_MULTI_INDEX_MEMBER(employee,int,age)>, - boost::multi_index::sequenced< - boost::multi_index::tag >, - boost::multi_index::hashed_unique< - boost::multi_index::tag, - BOOST_MULTI_INDEX_MEMBER(employee,int,ssn)> > > - employee_set; - -#if defined(BOOST_NO_MEMBER_TEMPLATES) -typedef boost::multi_index::nth_index< - employee_set,1>::type employee_set_by_name; -#else -typedef employee_set::nth_index<1>::type employee_set_by_name; -#endif - -typedef boost::multi_index::index< - employee_set,age>::type employee_set_by_age; -typedef boost::multi_index::index< - employee_set,as_inserted>::type employee_set_as_inserted; -typedef boost::multi_index::index< - employee_set,ssn>::type employee_set_by_ssn; - -#endif diff --git a/test/pair_of_ints.hpp b/test/pair_of_ints.hpp deleted file mode 100644 index 3667c21..0000000 --- a/test/pair_of_ints.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* Used in Boost.MultiIndex tests. - * - * 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. - */ - -#ifndef BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP -#define BOOST_MULTI_INDEX_TEST_PAIR_OF_INTS_HPP - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -typedef std::pair pair_of_ints; - -inline void increment_first(pair_of_ints& p) -{ - ++p.first; -} - -inline void increment_second(pair_of_ints& p) -{ - ++p.second; -} - -inline void increment_int(int& x) -{ - ++x; -} - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -namespace boost{ -namespace serialization{ -#else -namespace std{ -#endif - -template -void serialize(Archive& ar,pair_of_ints& p,const unsigned int) -{ - ar&boost::serialization::make_nvp("first",p.first); - ar&boost::serialization::make_nvp("second",p.second); -} - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -} /* namespace serialization */ -} /* namespace boost*/ -#else -} /* namespace std */ -#endif - -#endif diff --git a/test/pre_multi_index.hpp b/test/pre_multi_index.hpp deleted file mode 100644 index e96b53d..0000000 --- a/test/pre_multi_index.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* Used in Boost.MultiIndex tests. - * - * 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. - */ - -#ifndef BOOST_MULTI_INDEX_TEST_PRE_MULTI_INDEX_HPP -#define BOOST_MULTI_INDEX_TEST_PRE_MULTI_INDEX_HPP - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -#if defined(__GNUC__)&&defined(__APPLE__)&&\ - (__GNUC__==4)&&(__GNUC_MINOR__==0)&&(__APPLE_CC__<=4061) - /* Darwin 8.1 includes a prerelease version of GCC 4.0 that, alas, - * has a regression as described in - * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17435 - * This compiler bug (fixed in the official 4.0 release) ruins the - * mechanisms upon which invariant-checking scope guards are built, - * so we can't set the invariant checking mode. - */ -#else -#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING -#endif - -#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE - -#if BOOST_WORKAROUND(__IBMCPP__,<=600) -#pragma info(nolan) /* suppress warnings about offsetof with non-POD types */ -#endif - -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);} - -#endif diff --git a/test/test_all_main.cpp b/test/test_all_main.cpp deleted file mode 100644 index 1e1d4a1..0000000 --- a/test/test_all_main.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* Boost.MultiIndex test suite. - * - * 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. - */ - -#include -#include "test_basic.hpp" -#include "test_capacity.hpp" -#include "test_comparison.hpp" -#include "test_composite_key.hpp" -#include "test_conv_iterators.hpp" -#include "test_copy_assignment.hpp" -#include "test_hash_ops.hpp" -#include "test_iterators.hpp" -#include "test_key_extractors.hpp" -#include "test_list_ops.hpp" -#include "test_modifiers.hpp" -#include "test_mpl_ops.hpp" -#include "test_observers.hpp" -#include "test_projection.hpp" -#include "test_range.hpp" -#include "test_safe_mode.hpp" -#include "test_serialization.hpp" -#include "test_set_ops.hpp" -#include "test_special_list_ops.hpp" -#include "test_special_set_ops.hpp" -#include "test_update.hpp" - -int test_main(int,char *[]) -{ - test_basic(); - test_capacity(); - test_comparison(); - test_composite_key(); - test_conv_iterators(); - test_copy_assignment(); - test_hash_ops(); - test_iterators(); - test_key_extractors(); - test_list_ops(); - test_modifiers(); - test_mpl_ops(); - test_observers(); - test_projection(); - test_range(); - test_safe_mode(); - test_serialization(); - test_set_ops(); - test_special_list_ops(); - test_special_set_ops(); - test_update(); - - return 0; -} diff --git a/test/test_basic.cpp b/test/test_basic.cpp deleted file mode 100644 index 33318ad..0000000 --- a/test/test_basic.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* Boost.MultiIndex basic test. - * - * 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. - */ - -#include "test_basic.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -struct less_by_employee_age -{ - bool operator()(const employee& e1,const employee& e2)const - { - return e1.age v; - -#if defined(BOOST_NO_MEMBER_TEMPLATES) - employee_set_by_name& i1=get(es); -#else - employee_set_by_name& i1=es.get(); -#endif - - const employee_set_by_age& i2=get<2>(es); - employee_set_as_inserted& i3=get<3>(es); - employee_set_by_ssn& i4=get(es); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(5,"Anna",41,1123)); /* clash*/ - i1.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - i3.push_back(employee(3,"Albert",20,9012)); - i4.insert(employee(4,"John",57,1002)); - i4.insert(employee(0,"Andrew",60,2302)); /* clash */ - - v.push_back(employee(0,"Joe",31,1123)); - v.push_back(employee(1,"Robert",27,5601)); - v.push_back(employee(2,"John",40,7889)); - v.push_back(employee(3,"Albert",20,9012)); - v.push_back(employee(4,"John",57,1002)); - - { - /* by insertion order */ - - BOOST_CHECK(std::equal(i3.begin(),i3.end(),v.begin())); - } - - { - /* by id */ - - std::sort(v.begin(),v.end()); - BOOST_CHECK(std::equal(es.begin(),es.end(),v.begin())); - } - - { - /* by age */ - - std::sort(v.begin(),v.end(),less_by_employee_age()); - BOOST_CHECK(std::equal(i2.begin(),i2.end(),v.begin())); - } - -} diff --git a/test/test_basic.hpp b/test/test_basic.hpp deleted file mode 100644 index 1b2a160..0000000 --- a/test/test_basic.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex basic test. - * - * 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. - */ - -void test_basic(); diff --git a/test/test_basic_main.cpp b/test/test_basic_main.cpp deleted file mode 100644 index fd2fb03..0000000 --- a/test/test_basic_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex basic test. - * - * 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. - */ - -#include -#include "test_basic.hpp" - -int test_main(int,char *[]) -{ - test_basic(); - return 0; -} diff --git a/test/test_capacity.cpp b/test/test_capacity.cpp deleted file mode 100644 index 9dabcc9..0000000 --- a/test/test_capacity.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* Boost.MultiIndex test for capacity memfuns. - * - * 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. - */ - -#include "test_capacity.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_capacity() -{ - employee_set es; - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - BOOST_CHECK(!es.empty()); - BOOST_CHECK(es.size()==5); - BOOST_CHECK(es.size()<=es.max_size()); - - es.erase(es.begin()); - BOOST_CHECK(!get(es).empty()); - BOOST_CHECK(get(es).size()==4); - BOOST_CHECK(get(es).size()<=get(es).max_size()); - - es.erase(es.begin()); - BOOST_CHECK(!get(es).empty()); - BOOST_CHECK(get(es).size()==3); - BOOST_CHECK(get(es).size()<=get(es).max_size()); - - multi_index_container > > ss; - - ss.resize(10); - BOOST_CHECK(ss.size()==10); - BOOST_CHECK(ss.size()<=ss.max_size()); - - ss.resize(20); - BOOST_CHECK(ss.size()==20); - - ss.resize(5); - BOOST_CHECK(ss.size()==5); -} diff --git a/test/test_capacity.hpp b/test/test_capacity.hpp deleted file mode 100644 index b592be3..0000000 --- a/test/test_capacity.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for capacity memfuns. - * - * 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. - */ - -void test_capacity(); diff --git a/test/test_capacity_main.cpp b/test/test_capacity_main.cpp deleted file mode 100644 index 5160fe6..0000000 --- a/test/test_capacity_main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Boost.MultiIndex test for capacity memfuns. - * - * 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. - */ - -#include -#include "test_capacity.hpp" - -int test_main(int,char *[]) -{ - test_capacity(); - return 0; -} - diff --git a/test/test_comparison.cpp b/test/test_comparison.cpp deleted file mode 100644 index 7e600be..0000000 --- a/test/test_comparison.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* Boost.MultiIndex test for comparison functions. - * - * 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. - */ - -#include "test_comparison.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -template -struct lookup_list{ - typedef multi_index_container< - Value, - indexed_by< - sequenced<>, - ordered_non_unique > - > - > type; -}; - -void test_comparison() -{ - employee_set es; - employee_set_by_age& i2=get<2>(es); - employee_set_as_inserted& i3=get<3>(es); - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - employee_set es2; - employee_set_by_age& i22=get(es2); - employee_set_as_inserted& i32=get<3>(es2); - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - - BOOST_CHECK(es==es&&es<=es&&es>=es&& - i22==i22&&i22<=i22&&i22>=i22&& - i32==i32&&i32<=i32&&i32>=i32); - BOOST_CHECK(es!=es2&&es2es2&&!(es<=es2)&&!(es2>=es)); - BOOST_CHECK(i2!=i22&&i22i22&&!(i2<=i22)&&!(i22>=i2)); - BOOST_CHECK(i3!=i32&&i32i32&&!(i3<=i32)&&!(i32>=i3)); - - lookup_list::type l1; - lookup_list::type l2; - lookup_list::type l3; - - l1.push_back(3); - l1.push_back(4); - l1.push_back(5); - l1.push_back(1); - l1.push_back(2); - - l2.push_back(char(3)); - l2.push_back(char(4)); - l2.push_back(char(5)); - l2.push_back(char(1)); - l2.push_back(char(2)); - - l3.push_back(long(3)); - l3.push_back(long(4)); - l3.push_back(long(5)); - l3.push_back(long(1)); - - BOOST_CHECK(l1==l2&&l1<=l2&&l1>=l2); - BOOST_CHECK( - get<1>(l1)==get<1>(l2)&&get<1>(l1)<=get<1>(l2)&&get<1>(l1)>=get<1>(l2)); - BOOST_CHECK(l1!=l3&&l3l3); - BOOST_CHECK( - get<1>(l1)!=get<1>(l3)&&get<1>(l1)(l3)&&get<1>(l3)>get<1>(l1)); -} diff --git a/test/test_comparison.hpp b/test/test_comparison.hpp deleted file mode 100644 index c311c24..0000000 --- a/test/test_comparison.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for comparison functions. - * - * 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. - */ - -void test_comparison(); diff --git a/test/test_comparison_main.cpp b/test/test_comparison_main.cpp deleted file mode 100644 index a0d1080..0000000 --- a/test/test_comparison_main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Boost.MultiIndex test for comparison functions. - * - * 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. - */ - -#include -#include "test_comparison.hpp" - -int test_main(int,char *[]) -{ - test_comparison(); - return 0; -} - diff --git a/test/test_composite_key.cpp b/test/test_composite_key.cpp deleted file mode 100644 index c50804a..0000000 --- a/test/test_composite_key.cpp +++ /dev/null @@ -1,638 +0,0 @@ -/* Boost.MultiIndex test for composite_key. - * - * 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. - */ - -#include "test_composite_key.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include -#include - -using namespace boost::multi_index; -using namespace boost::tuples; - -struct is_composite_key_result_helper -{ - typedef char yes; - struct no{char m[2];}; - - static no test(void*); - - template - static yes test(composite_key_result*); -}; - -template -struct is_composite_key_result -{ - typedef is_composite_key_result_helper helper; - - BOOST_STATIC_CONSTANT(bool, - value=( - sizeof(helper::test((T*)0))== - sizeof(typename helper::yes))); -}; - -template -struct composite_key_result_length -{ - BOOST_STATIC_CONSTANT(int, - value=boost::tuples::length< - BOOST_DEDUCED_TYPENAME - CompositeKeyResult::composite_key_type::key_extractor_tuple - >::value); -}; - -template -struct composite_object_length -{ - typedef typename boost::mpl::if_c< - is_composite_key_result::value, - composite_key_result_length, - boost::tuples::length - >::type type; - - BOOST_STATIC_CONSTANT(int,value=type::value); -}; - -template -struct comparison_equal_length -{ - static bool is_less(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_equal_to eq; - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::equal_to std_eq; - std::less std_lt; - std::greater std_gt; -#endif - - return (x< y) && !(y< x)&& - !(x==y) && !(y==x)&& - (x!=y) && (y!=x)&& - !(x> y) && (y> x)&& - !(x>=y) && (y>=x)&& - (x<=y) && !(y<=x)&& - - !eq(x,y) && !eq(y,x)&& - lt(x,y) && !lt(y,x)&& - !gt(x,y) && gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - !std_eq(x,y) && !std_eq(y,x)&& - std_lt(x,y) && !std_lt(y,x)&& - !std_gt(x,y) && std_gt(y,x) -#endif - ; - } - - static bool is_greater(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_equal_to eq; - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::equal_to std_eq; - std::less std_lt; - std::greater std_gt; -#endif - - return !(x< y) && (y< x)&& - !(x==y) && !(y==x)&& - (x!=y) && (y!=x)&& - (x> y) && !(y> x)&& - (x>=y) && !(y>=x)&& - !(x<=y) && (y<=x)&& - - !eq(x,y) && !eq(y,x)&& - !lt(x,y) && lt(y,x)&& - gt(x,y) && !gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - !std_eq(x,y) && !std_eq(y,x)&& - !std_lt(x,y) && std_lt(y,x)&& - std_gt(x,y) && !std_gt(y,x) -#endif - ; - } - - static bool is_equiv(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_equal_to eq; - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::equal_to std_eq; - std::less std_lt; - std::greater std_gt; -#endif - - return !(x< y) && !(y< x)&& - (x==y) && (y==x)&& - !(x!=y) && !(y!=x)&& - !(x> y) && !(y> x)&& - (x>=y) && (y>=x)&& - (x<=y) && (y<=x)&& - - eq(x,y) && eq(y,x)&& - !lt(x,y) && !lt(y,x)&& - !gt(x,y) && !gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - std_eq(x,y) && std_eq(y,x)&& - !std_lt(x,y) && !std_lt(y,x)&& - !std_gt(x,y) && !std_gt(y,x) -#endif - ; - } -}; - -template -struct comparison_different_length -{ - static bool is_less(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::less std_lt; - std::greater std_gt; -#endif - - return (x< y) && !(y< x)&& - !(x> y) && (y> x)&& - !(x>=y) && (y>=x)&& - (x<=y) && !(y<=x)&& - - lt(x,y) && !lt(y,x)&& - !gt(x,y) && gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - std_lt(x,y) && !std_lt(y,x)&& - !std_gt(x,y) && std_gt(y,x) -#endif - ; - } - - static bool is_greater(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::less std_lt; - std::greater std_gt; -#endif - - return !(x< y) && (y< x)&& - (x> y) && !(y> x)&& - (x>=y) && !(y>=x)&& - !(x<=y) && (y<=x)&& - - !lt(x,y) && lt(y,x)&& - gt(x,y) && !gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - !std_lt(x,y) && std_lt(y,x)&& - std_gt(x,y) && !std_gt(y,x) -#endif - ; - } - - static bool is_equiv(const CompositeKeyResult& x,const T2& y) - { - composite_key_result_less lt; - composite_key_result_greater gt; - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - std::less std_lt; - std::greater std_gt; -#endif - - return !(x< y) && !(y< x)&& - !(x> y) && !(y> x)&& - (x>=y) && (y>=x)&& - (x<=y) && (y<=x)&& - - !lt(x,y) && !lt(y,x)&& - !gt(x,y) && !gt(y,x) - -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - && - !std_lt(x,y) && !std_lt(y,x)&& - !std_gt(x,y) && !std_gt(y,x) -#endif - ; - } -}; - -template -struct comparison_helper: - boost::mpl::if_c< - composite_key_result_length::value== - composite_object_length::value, - comparison_equal_length, - comparison_different_length - >::type -{ -}; - -template -static bool is_less(const CompositeKeyResult& x,const T2& y) -{ - return comparison_helper::is_less(x,y); -} - -template -static bool is_greater(const CompositeKeyResult& x,const T2& y) -{ - return comparison_helper::is_greater(x,y); -} - -template -static bool is_equiv(const CompositeKeyResult& x,const T2& y) -{ - return comparison_helper::is_equiv(x,y); -} - -template -static bool is_less(const T1& x,const T2& y,const Compare& c) -{ - return c(x,y)&&!c(y,x); -} - -template -static bool is_greater(const T1& x,const T2& y,const Compare& c) -{ - return c(y,x)&&!c(x,y); -} - -template -static bool is_equiv(const T1& x,const T2& y,const Compare& c) -{ - return !c(x,y)&&!c(y,x); -} - -template -static bool is_less( - const T1& x,const T2& y,const Compare& c,const Equiv& eq) -{ - return c(x,y)&&!c(y,x)&&!eq(x,y)&&!eq(y,x); -} - -template -static bool is_greater( - const T1& x,const T2& y,const Compare& c,const Equiv& eq) -{ - return c(y,x)&&!c(x,y)&&!eq(x,y)&&!eq(y,x); -} - -template -static bool is_equiv( - const T1& x,const T2& y,const Compare& c,const Equiv& eq) -{ - return !c(x,y)&&!c(y,x)&&eq(x,y)&&eq(y,x); -} - -struct xyz -{ - xyz(int x_=0,int y_=0,int z_=0):x(x_),y(y_),z(z_){} - - int x; - int y; - int z; -}; - -struct modulo_equal -{ - modulo_equal(int i):i_(i){} - bool operator ()(int x,int y)const{return (x%i_)==(y%i_);} - -private: - int i_; -}; - -struct xystr -{ - xystr(int x_=0,int y_=0,std::string str_=0):x(x_),y(y_),str(str_){} - - int x; - int y; - std::string str; -}; - -void test_composite_key() -{ - typedef composite_key< - xyz, - BOOST_MULTI_INDEX_MEMBER(xyz,int,x), - BOOST_MULTI_INDEX_MEMBER(xyz,int,y), - BOOST_MULTI_INDEX_MEMBER(xyz,int,z) - > ckey_t1; - - typedef multi_index_container< - xyz, - indexed_by< - ordered_unique< - ckey_t1 -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - ,composite_key_result_less -#endif - > - > - > indexed_t1; - - indexed_t1 mc1; - mc1.insert(xyz(0,0,0)); - mc1.insert(xyz(0,0,1)); - mc1.insert(xyz(0,1,0)); - mc1.insert(xyz(0,1,1)); - mc1.insert(xyz(1,0,0)); - mc1.insert(xyz(1,0,1)); - mc1.insert(xyz(1,1,0)); - mc1.insert(xyz(1,1,1)); - - BOOST_CHECK(mc1.size()==8); - BOOST_CHECK( - std::distance( - mc1.find(mc1.key_extractor()(xyz(0,0,0))), - mc1.find(mc1.key_extractor()(xyz(1,0,0))))==4); - BOOST_CHECK( - std::distance( - mc1.find(make_tuple(0,0,0)), - mc1.find(make_tuple(1,0,0)))==4); - BOOST_CHECK( - std::distance( - mc1.lower_bound(make_tuple(0,0)), - mc1.upper_bound(make_tuple(1,0)))==6); - - ckey_t1 ck1; - ckey_t1 ck2(ck1); - ckey_t1 ck3( - boost::make_tuple( - BOOST_MULTI_INDEX_MEMBER(xyz,int,x)(), - BOOST_MULTI_INDEX_MEMBER(xyz,int,y)(), - BOOST_MULTI_INDEX_MEMBER(xyz,int,z)())); - ckey_t1 ck4(get<0>(ck1.key_extractors())); - - ck3=ck3; /* prevent unused var */ - - get<2>(ck4.key_extractors())= - get<2>(ck2.key_extractors()); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)))); - BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)))); - BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)))); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0))); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1))); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1))); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0))); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,1))); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,-1))); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0))); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1))); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1))); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0,1))); - - typedef composite_key_result_less ckey_comp_t1; - typedef composite_key_result_equal_to ckey_eq_t1; - - ckey_comp_t1 cp1; - ckey_eq_t1 eq1; - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp1,eq1)); - BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp1,eq1)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp1,eq1)); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp1)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1),cp1)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1),cp1)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp1)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,1),cp1)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,-1),cp1)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp1,eq1)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1),cp1,eq1)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp1,eq1)); - - typedef composite_key_result_greater ckey_comp_t2; - - ckey_comp_t2 cp2; - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp2)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp2)); - BOOST_CHECK(is_less (ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp2)); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp2)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(1),cp2)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(-1),cp2)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp2)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,1),cp2)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,-1),cp2)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp2)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,1),cp2)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp2)); - - typedef composite_key_equal_to< - modulo_equal, - modulo_equal, - std::equal_to, - std::equal_to - > ckey_eq_t2; - - ckey_eq_t2 eq2( - boost::make_tuple( - modulo_equal(2), - modulo_equal(3), - std::equal_to(), - std::equal_to())); - ckey_eq_t2 eq3(eq2); - ckey_eq_t2 eq4( - get<0>(eq3.key_eqs()), - get<1>(eq3.key_eqs())); - - eq3=eq4; /* prevent unused var */ - eq4=eq3; /* prevent unused var */ - - BOOST_CHECK( eq2(ck1(xyz(0,0,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(0,1,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(0,2,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK( eq2(ck1(xyz(0,3,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,0,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,1,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,2,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,3,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK( eq2(ck1(xyz(2,0,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(2,1,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(2,2,0)),ck1(xyz(0,0,0)))); - BOOST_CHECK( eq2(ck1(xyz(2,3,0)),ck1(xyz(0,0,0)))); - - BOOST_CHECK( eq2(make_tuple(0,0,0),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(0,1,0)) ,make_tuple(0,0,0))); - BOOST_CHECK(!eq2(make_tuple(0,2,0),ck1(xyz(0,0,0)))); - BOOST_CHECK( eq2(ck1(xyz(0,3,0)) ,make_tuple(0,0,0))); - BOOST_CHECK(!eq2(make_tuple(1,0,0),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,1,0)) ,make_tuple(0,0,0))); - BOOST_CHECK(!eq2(make_tuple(1,2,0),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(1,3,0)) ,make_tuple(0,0,0))); - BOOST_CHECK( eq2(make_tuple(2,0,0),ck1(xyz(0,0,0)))); - BOOST_CHECK(!eq2(ck1(xyz(2,1,0)) ,make_tuple(0,0,0))); - BOOST_CHECK(!eq2(make_tuple(2,2,0),ck1(xyz(0,0,0)))); - BOOST_CHECK( eq2(ck1(xyz(2,3,0)) ,make_tuple(0,0,0))); - - typedef composite_key_compare< - std::less, - std::greater, /* order reversed */ - std::less - > ckey_comp_t3; - - ckey_comp_t3 cp3; - ckey_comp_t3 cp4(cp3); - ckey_comp_t3 cp5( - boost::make_tuple( - std::less(), - std::greater(), - std::less())); - ckey_comp_t3 cp6(get<0>(cp3.key_comps())); - - cp4=cp5; /* prevent unused var */ - cp5=cp6; /* prevent unused var */ - cp6=cp4; /* prevent unused var */ - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),ck2(xyz(0,0,0)),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,1,0)),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,1)),ck2(xyz(0,0,0)),cp3)); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0),cp3)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(1),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(-1),cp3)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0),cp3)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,-1),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,1),cp3)); - BOOST_CHECK(is_equiv (ck1(xyz(0,0,0)),make_tuple(0,0,0),cp3)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),make_tuple(0,0,1),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),make_tuple(0,0,-1),cp3)); - - typedef composite_key< - xyz, - BOOST_MULTI_INDEX_MEMBER(xyz,int,y), /* members reversed */ - BOOST_MULTI_INDEX_MEMBER(xyz,int,x) - > ckey_t2; - - ckey_t2 ck5; - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)))); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)))); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)))); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp1)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp1)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp1)); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp2)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp2)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp2)); - - BOOST_CHECK(is_equiv (ck1(xyz(0,0,1)),ck5(xyz(0,0,0)),cp3)); - BOOST_CHECK(is_less (ck1(xyz(0,0,0)),ck5(xyz(-1,1,0)),cp3)); - BOOST_CHECK(is_greater(ck1(xyz(0,0,0)),ck5(xyz(1,-1,0)),cp3)); - - typedef multi_index_container< - xyz, - indexed_by< - hashed_unique< - ckey_t1 -#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - ,composite_key_result_hash - ,composite_key_result_equal_to -#endif - > - > - > indexed_t2; - - indexed_t2 mc2; - mc2.insert(xyz(0,0,0)); - mc2.insert(xyz(0,0,1)); - mc2.insert(xyz(0,1,0)); - mc2.insert(xyz(0,1,1)); - mc2.insert(xyz(1,0,0)); - mc2.insert(xyz(1,0,1)); - mc2.insert(xyz(1,1,0)); - mc2.insert(xyz(1,1,1)); - mc2.insert(xyz(0,0,0)); - mc2.insert(xyz(0,0,1)); - mc2.insert(xyz(0,1,0)); - mc2.insert(xyz(0,1,1)); - mc2.insert(xyz(1,0,0)); - mc2.insert(xyz(1,0,1)); - mc2.insert(xyz(1,1,0)); - mc2.insert(xyz(1,1,1)); - - BOOST_CHECK(mc2.size()==8); - BOOST_CHECK(mc2.find(make_tuple(0,0,1))->z==1); - BOOST_CHECK(ck1(*(mc2.find(make_tuple(1,0,1))))==make_tuple(1,0,1)); - - typedef composite_key< - xystr, - BOOST_MULTI_INDEX_MEMBER(xystr,std::string,str), - BOOST_MULTI_INDEX_MEMBER(xystr,int,x), - BOOST_MULTI_INDEX_MEMBER(xystr,int,y) - > ckey_t3; - - ckey_t3 ck6; - - typedef composite_key_hash< - boost::hash, - boost::hash, - boost::hash - > ckey_hash_t; - - ckey_hash_t ch1; - ckey_hash_t ch2(ch1); - ckey_hash_t ch3( - boost::make_tuple( - boost::hash(), - boost::hash(), - boost::hash())); - ckey_hash_t ch4(get<0>(ch1.key_hash_functions())); - - ch2=ch3; /* prevent unused var */ - ch3=ch4; /* prevent unused var */ - ch4=ch2; /* prevent unused var */ - - BOOST_CHECK( - ch1(ck6(xystr(0,0,"hello")))==ch1(make_tuple(std::string("hello"),0,0))); - BOOST_CHECK( - ch1(ck6(xystr(4,5,"world")))==ch1(make_tuple(std::string("world"),4,5))); - - typedef boost::hash > ckeyres_hash_t; - - ckeyres_hash_t crh; - - BOOST_CHECK( - ch1(ck6(xystr(0,0,"hello")))==crh(ck6(xystr(0,0,"hello")))); - BOOST_CHECK( - ch1(ck6(xystr(4,5,"world")))==crh(ck6(xystr(4,5,"world")))); -} diff --git a/test/test_composite_key.hpp b/test/test_composite_key.hpp deleted file mode 100644 index e84144f..0000000 --- a/test/test_composite_key.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for composite_key. - * - * 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. - */ - -void test_composite_key(); diff --git a/test/test_composite_key_main.cpp b/test/test_composite_key_main.cpp deleted file mode 100644 index 8b06be1..0000000 --- a/test/test_composite_key_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for composite_key. - * - * 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. - */ - -#include -#include "test_composite_key.hpp" - -int test_main(int,char *[]) -{ - test_composite_key(); - return 0; -} diff --git a/test/test_conv_iterators.cpp b/test/test_conv_iterators.cpp deleted file mode 100644 index 78dbd0a..0000000 --- a/test/test_conv_iterators.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* Boost.MultiIndex test for interconvertibilty between const and - * non-const iterators. - * - * 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. - */ - -#include "test_conv_iterators.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_conv_iterators() -{ - employee_set es; - es.insert(employee(2,"John",40,7889)); - - { - const employee_set& ces=es; - employee_set::iterator it=es.find(employee(2,"John",40,7889)); - employee_set::const_iterator it1=es.find(employee(2,"John",40,7889)); - employee_set::const_iterator it2=ces.find(employee(2,"John",40,7889)); - - BOOST_CHECK(it==it1&&it1==it2&&it2==it); - BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it); - } - { - employee_set_by_name& i1=get<1>(es); - const employee_set_by_name& ci1=get<1>(es); - employee_set_by_name::iterator it=i1.find("John"); - employee_set_by_name::const_iterator it1=i1.find("John"); - employee_set_by_name::const_iterator it2=ci1.find("John"); - - BOOST_CHECK(it==it1&&it1==it2&&it2==it); - BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it); - } - { - employee_set_by_name& i1=get<1>(es); - const employee_set_by_name& ci1=get<1>(es); - employee_set_by_name::local_iterator it=i1.begin(i1.bucket("John")); - employee_set_by_name::const_local_iterator it1=i1.begin(i1.bucket("John")); - employee_set_by_name::const_local_iterator it2=ci1.begin(ci1.bucket("John")); - - BOOST_CHECK(it==it1&&it1==it2&&it2==it); - BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it); - } - { - employee_set_as_inserted& i3=get<3>(es); - const employee_set_as_inserted& ci3=get<3>(es); - employee_set_as_inserted::iterator it=i3.begin(); - employee_set_as_inserted::const_iterator it1=i3.begin(); - employee_set_as_inserted::const_iterator it2=ci3.begin(); - - BOOST_CHECK(it==it1&&it1==it2&&it2==it); - BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it); - } -} diff --git a/test/test_conv_iterators.hpp b/test/test_conv_iterators.hpp deleted file mode 100644 index 99e118e..0000000 --- a/test/test_conv_iterators.hpp +++ /dev/null @@ -1,12 +0,0 @@ -/* Boost.MultiIndex test for interconvertibilty between const and - * non-const iterators. - * - * 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. - */ - -void test_conv_iterators(); diff --git a/test/test_conv_iterators_main.cpp b/test/test_conv_iterators_main.cpp deleted file mode 100644 index 318adff..0000000 --- a/test/test_conv_iterators_main.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* Boost.MultiIndex test for interconvertibilty between const and - * non-const iterators. - * - * 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. - */ - -#include -#include "test_conv_iterators.hpp" - -int test_main(int,char *[]) -{ - test_conv_iterators(); - return 0; -} - - diff --git a/test/test_copy_assignment.cpp b/test/test_copy_assignment.cpp deleted file mode 100644 index 2646518..0000000 --- a/test/test_copy_assignment.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* Boost.MultiIndex test for copying and assignment. - * - * 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. - */ - -#include "test_copy_assignment.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_copy_assignment() -{ - employee_set es; - employee_set es2(es); - - employee_set::allocator_type al=es.get_allocator(); - al=get<1>(es).get_allocator(); - al=get<2>(es).get_allocator(); - al=get<3>(es).get_allocator(); - al=get<4>(es).get_allocator(); - - BOOST_CHECK(es2.empty()); - - es2.insert(employee(0,"Joe",31,1123)); - es2.insert(employee(1,"Robert",27,5601)); - es2.insert(employee(2,"John",40,7889)); - es2.insert(employee(2,"Aristotle",2388,3357)); /* clash */ - es2.insert(employee(3,"Albert",20,9012)); - es2.insert(employee(4,"John",57,1002)); - es2.insert(employee(0,"Andrew",60,2302)); /* clash */ - - employee_set es3(es2); - - BOOST_CHECK(es2==es3); - BOOST_CHECK(get<2>(es2)==get<2>(es3)); - BOOST_CHECK(get<3>(es2)==get<3>(es3)); - - employee_set es4; - employee_set_by_name& i1=get(es4); - i1=get<1>(es2); - - BOOST_CHECK(es4==es2); - - employee_set es5; - employee_set_by_age& i2=get(es5); - i2=get<2>(es2); - - BOOST_CHECK(i2==get<2>(es2)); - - employee_set es6; - employee_set_as_inserted& i3=get(es6); - i3=get<3>(es2); - - BOOST_CHECK(i3==get<3>(es2)); - - std::list l; - l.push_back(employee(3,"Anna",31,5388)); - l.push_back(employee(1,"Rachel",27,9012)); - l.push_back(employee(2,"Agatha",40,1520)); - -#if BOOST_WORKAROUND(BOOST_MSVC,<1300) - employee_set es7; - es7.insert(l.begin(),l.end()); -#else - employee_set es7(l.begin(),l.end()); -#endif - - l.sort(); - - BOOST_CHECK(es7.size()==l.size()&& - std::equal(es7.begin(),es7.end(),l.begin())); - - multi_index_container > > ss; - - int a[]={0,1,2,3,4,5}; - std::size_t sa=sizeof(a)/sizeof(a[0]); - - ss.assign(&a[0],&a[sa]); - - BOOST_CHECK(ss.size()==sa&&std::equal(ss.begin(),ss.end(),&a[0])); - - ss.assign(&a[0],&a[sa]); - - BOOST_CHECK(ss.size()==sa&&std::equal(ss.begin(),ss.end(),&a[0])); - - ss.assign((std::size_t)18,37); - BOOST_CHECK(ss.size()==18&&std::accumulate(ss.begin(),ss.end(),0)==666); - - ss.assign((std::size_t)12,167); - BOOST_CHECK(ss.size()==12&&std::accumulate(ss.begin(),ss.end(),0)==2004); -} diff --git a/test/test_copy_assignment.hpp b/test/test_copy_assignment.hpp deleted file mode 100644 index 27d2e80..0000000 --- a/test/test_copy_assignment.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for copying and assignment. - * - * 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. - */ - -void test_copy_assignment(); diff --git a/test/test_copy_assignment_main.cpp b/test/test_copy_assignment_main.cpp deleted file mode 100644 index 6b5e0ba..0000000 --- a/test/test_copy_assignment_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for copying and assignment. - * - * 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. - */ - -#include -#include "test_copy_assignment.hpp" - -int test_main(int,char *[]) -{ - test_copy_assignment(); - return 0; -} diff --git a/test/test_hash_ops.cpp b/test/test_hash_ops.cpp deleted file mode 100644 index d5acdd8..0000000 --- a/test/test_hash_ops.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Boost.MultiIndex test for standard hash operations. - * - * 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. - */ - -#include "test_hash_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include - -#include - -using namespace boost::multi_index; - -template -void check_load_factor(const HashedContainer& hc) -{ - float lf=(float)hc.size()/hc.bucket_count(); - BOOST_CHECK_CLOSE(lf,hc.load_factor(),1.E-6f); - BOOST_CHECK(lf<=hc.max_load_factor()+1.E-6); -} - -typedef multi_index_container< - int, - indexed_by< - hashed_unique > - > -> hash_container; - -void test_hash_ops() -{ - hash_container hc; - - BOOST_CHECK(hc.max_load_factor()==1.0f); - BOOST_CHECK(hc.bucket_count()<=hc.max_bucket_count()); - - hc.insert(1000); - hash_container::size_type buc=hc.bucket(1000); - hash_container::local_iterator it0=hc.begin(buc); - hash_container::local_iterator it1=hc.end(buc); - BOOST_CHECK( - (hash_container::size_type)std::distance(it0,it1)==hc.bucket_size(buc)&& - hc.bucket_size(buc)==1&&*it0==1000); - - hc.clear(); - - for(hash_container::size_type s=2*hc.bucket_count();s--;){ - hc.insert((int)s); - } - check_load_factor(hc); - - hc.max_load_factor(0.5f); - BOOST_CHECK(hc.max_load_factor()==0.5f); - hc.insert(-1); - check_load_factor(hc); - - hc.rehash(1); - BOOST_CHECK(hc.bucket_count()>=1); - check_load_factor(hc); - - hc.max_load_factor(0.25f); - hc.rehash(1); - BOOST_CHECK(hc.bucket_count()>=1); - check_load_factor(hc); - - hash_container::size_type bc=4*hc.bucket_count(); - hc.max_load_factor(0.125f); - hc.rehash(bc); - BOOST_CHECK(hc.bucket_count()>=bc); - check_load_factor(hc); - - bc=2*hc.bucket_count(); - hc.rehash(bc); - BOOST_CHECK(hc.bucket_count()>=bc); - check_load_factor(hc); - - hc.clear(); - hc.insert(0); - hc.rehash(1); - BOOST_CHECK(hc.bucket_count()>=1); - check_load_factor(hc); -} diff --git a/test/test_hash_ops.hpp b/test/test_hash_ops.hpp deleted file mode 100644 index 531198c..0000000 --- a/test/test_hash_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for standard hash operations. - * - * 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. - */ - -void test_hash_ops(); diff --git a/test/test_hash_ops_main.cpp b/test/test_hash_ops_main.cpp deleted file mode 100644 index a65ff93..0000000 --- a/test/test_hash_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for standard hash operations. - * - * 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. - */ - -#include -#include "test_hash_ops.hpp" - -int test_main(int,char *[]) -{ - test_hash_ops(); - return 0; -} diff --git a/test/test_iterators.cpp b/test/test_iterators.cpp deleted file mode 100644 index 7612126..0000000 --- a/test/test_iterators.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* Boost.MultiIndex test for iterators. - * - * 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. - */ - -#include "test_iterators.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -template -void test_non_const_iterators(Index& i,int target) -{ - typedef typename Index::iterator iterator; - typedef typename Index::reverse_iterator reverse_iterator; - - int n=0; - for(iterator it=i.begin();it!=i.end();++it){ - n+=it->id; - } - int m=0; - for(reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){ - m+=rit->id; - } - int p=0; - for(iterator it2=i.end();it2!=i.begin();){ - --it2; - p+=it2->id; - } - int q=0; - for(reverse_iterator rit2=i.rend();rit2!=i.rbegin();){ - --rit2; - q+=rit2->id; - } - - BOOST_CHECK(n==target&&n==m&&n==p&&n==q); -} - -template -void test_const_iterators(const Index& i,int target) -{ - typedef typename Index::const_iterator const_iterator; - typedef typename Index::const_reverse_iterator const_reverse_iterator; - - int n=0; - for(const_iterator it=i.begin();it!=i.end();++it){ - n+=it->id; - } - int m=0; - for(const_reverse_iterator rit=i.rbegin();rit!=i.rend();++rit){ - m+=rit->id; - } - int p=0; - for(const_iterator it2=i.end();it2!=i.begin();){ - --it2; - p+=it2->id; - } - int q=0; - for(const_reverse_iterator rit2=i.rend();rit2!=i.rbegin();){ - --rit2; - q+=rit2->id; - } - - BOOST_CHECK(n==target&&n==m&&n==p&&n==q); -} - -template -void test_non_const_hashed_iterators(Index& i,int target) -{ - typedef typename Index::iterator iterator; - typedef typename Index::local_iterator local_iterator; - typedef typename Index::size_type size_type; - - int n=0; - for(iterator it=i.begin();it!=i.end();++it){ - n+=it->id; - } - int m=0; - for(size_type buc=0;bucid; - } - } - - BOOST_CHECK(n==target&&n==m); -} - -template -void test_const_hashed_iterators(Index& i,int target) -{ - typedef typename Index::const_iterator const_iterator; - typedef typename Index::const_local_iterator const_local_iterator; - typedef typename Index::size_type size_type; - - int n=0; - for(const_iterator it=i.begin();it!=i.end();++it){ - n+=it->id; - } - int m=0; - for(size_type buc=0;bucid; - } - } - - BOOST_CHECK(n==target&&n==m); -} - -void test_iterators() -{ - employee_set es; - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - int target=0+1+2+3+4; - - test_non_const_iterators (es,target); - test_const_iterators (es,target); - test_non_const_hashed_iterators(get<1>(es),target); - test_const_hashed_iterators (get<1>(es),target); - test_non_const_iterators (get<2>(es),target); - test_const_iterators (get<2>(es),target); - test_non_const_iterators (get<3>(es),target); - test_const_iterators (get<3>(es),target); - test_non_const_hashed_iterators(get<4>(es),target); - test_const_hashed_iterators (get<4>(es),target); -} diff --git a/test/test_iterators.hpp b/test/test_iterators.hpp deleted file mode 100644 index 9f47aa1..0000000 --- a/test/test_iterators.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for iterators. - * - * 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. - */ - -void test_iterators(); diff --git a/test/test_iterators_main.cpp b/test/test_iterators_main.cpp deleted file mode 100644 index 61fb496..0000000 --- a/test/test_iterators_main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Boost.MultiIndex test for iterators. - * - * 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. - */ - -#include -#include "test_iterators.hpp" - -int test_main(int,char *[]) -{ - test_iterators(); - return 0; -} - diff --git a/test/test_key_extractors.cpp b/test/test_key_extractors.cpp deleted file mode 100644 index 3cd390f..0000000 --- a/test/test_key_extractors.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/* Boost.MultiIndex test for key extractors. - * - * 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. - */ - -#include "test_key_extractors.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include -#include - -using namespace boost::multi_index; -using namespace boost::tuples; - -struct test_class -{ - int int_member; - const int int_cmember; - - bool bool_mem_fun_const()const{return true;} - bool bool_mem_fun(){return false;} - - test_class(int i=0):int_member(i),int_cmember(i){} - test_class(int i,int j):int_member(i),int_cmember(j){} - - test_class& operator=(const test_class& x) - { - int_member=x.int_member; - return *this; - } - - bool operator<(const test_class& x)const - { - if(int_member idn; -typedef identity cidn; -typedef BOOST_MULTI_INDEX_MEMBER(test_class,int,int_member) key_m; -typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_member) ckey_m; -typedef BOOST_MULTI_INDEX_MEMBER(test_class,const int,int_cmember) key_cm; -typedef BOOST_MULTI_INDEX_CONST_MEM_FUN( - test_class,bool,bool_mem_fun_const) key_cmf; -typedef BOOST_MULTI_INDEX_MEM_FUN(test_class,bool,bool_mem_fun) key_mf; -typedef composite_key< - test_class, - idn, - key_m, - key_cm, - key_cmf - > compkey; -typedef composite_key< - test_class, - cidn, - ckey_m - > ccompkey; -typedef composite_key< - boost::reference_wrapper, - key_mf - > ccompw_key; - -void test_key_extractors() -{ - idn id; - cidn cid; - key_m k_m; - ckey_m ck_m; - key_cm k_cm; - key_cmf k_cmf; - key_mf k_mf; - compkey cmpk; - ccompkey ccmpk; - ccompw_key ccmpk_w; - - test_class t; - const test_class& ctr=t; - - test_class* tp=&t; - const test_class* ctp=&t; - - test_class** tpp=&tp; - const test_class** ctpp=&ctp; - - std::auto_ptr tap(new test_class*(tp)); - std::auto_ptr ctap(new const test_class*(ctp)); - - boost::reference_wrapper tw(t); - boost::reference_wrapper ctw(t); - - id(t).int_member=0; - BOOST_CHECK(id(t).int_member==0); - BOOST_CHECK(cid(t).int_member==0); - BOOST_CHECK(k_m(t)==0); - BOOST_CHECK(ck_m(t)==0); - BOOST_CHECK(cmpk(t)==make_tuple(test_class(0,0),0,0,true)); - BOOST_CHECK(ccmpk(t)==make_tuple(test_class(0,0),0)); - BOOST_CHECK(id(ctr).int_member==0); - BOOST_CHECK(cid(ctr).int_member==0); - BOOST_CHECK(k_m(ctr)==0); - BOOST_CHECK(ck_m(ctr)==0); - BOOST_CHECK(cmpk(ctr)==make_tuple(test_class(0,0),0,0,true)); - BOOST_CHECK(ccmpk(ctr)==make_tuple(test_class(0,0),0)); - - k_m(t)=1; - BOOST_CHECK(id(tp).int_member==1); - BOOST_CHECK(cid(tp).int_member==1); - BOOST_CHECK(k_m(tp)==1); - BOOST_CHECK(ck_m(tp)==1); - BOOST_CHECK(cmpk(tp)==make_tuple(test_class(1,0),1,0,true)); - BOOST_CHECK(ccmpk(tp)==make_tuple(test_class(1,0),1)); - BOOST_CHECK(cid(ctp).int_member==1); - BOOST_CHECK(ck_m(ctp)==1); - BOOST_CHECK(cmpk(ctp)==make_tuple(test_class(1,0),1,0,true)); - BOOST_CHECK(ccmpk(ctp)==make_tuple(test_class(1,0),1)); - - k_m(tp)=2; - BOOST_CHECK(id(tpp).int_member==2); - BOOST_CHECK(cid(tpp).int_member==2); - BOOST_CHECK(k_m(tpp)==2); - BOOST_CHECK(ck_m(tpp)==2); - BOOST_CHECK(cmpk(tpp)==make_tuple(test_class(2,0),2,0,true)); - BOOST_CHECK(ccmpk(tpp)==make_tuple(test_class(2,0),2)); - BOOST_CHECK(cid(ctpp).int_member==2); - BOOST_CHECK(ck_m(ctpp)==2); - BOOST_CHECK(cmpk(ctpp)==make_tuple(test_class(2,0),2,0,true)); - BOOST_CHECK(ccmpk(ctpp)==make_tuple(test_class(2,0),2)); - - k_m(tpp)=3; - BOOST_CHECK(id(tap).int_member==3); - BOOST_CHECK(cid(tap).int_member==3); - BOOST_CHECK(k_m(tap)==3); - BOOST_CHECK(ck_m(tap)==3); - BOOST_CHECK(cmpk(tap)==make_tuple(test_class(3,0),3,0,true)); - BOOST_CHECK(ccmpk(tap)==make_tuple(test_class(3,0),3)); - BOOST_CHECK(cid(ctap).int_member==3); - BOOST_CHECK(ck_m(ctap)==3); - BOOST_CHECK(cmpk(ctap)==make_tuple(test_class(3,0),3,0,true)); - BOOST_CHECK(ccmpk(ctap)==make_tuple(test_class(3,0),3)); - - k_m(tap)=4; - BOOST_CHECK(id(tw).int_member==4); - BOOST_CHECK(cid(tw).int_member==4); - BOOST_CHECK(k_m(tw)==4); - BOOST_CHECK(ck_m(tw)==4); - BOOST_CHECK(cmpk(tw)==make_tuple(test_class(4,0),4,0,true)); - BOOST_CHECK(ccmpk(tw)==make_tuple(test_class(4,0),4)); - - k_m(tw)=5; - BOOST_CHECK(id(ctw).int_member==5); - BOOST_CHECK(cid(ctw).int_member==5); - BOOST_CHECK(k_m(ctw)==5); - BOOST_CHECK(ck_m(ctw)==5); - BOOST_CHECK(cmpk(ctw)==make_tuple(test_class(5,0),5,0,true)); - BOOST_CHECK(ccmpk(ctw)==make_tuple(test_class(5,0),5)); - - BOOST_CHECK(k_cm(t)==0); - - BOOST_CHECK(k_cm(tp)==0); - BOOST_CHECK(k_cm(ctp)==0); - BOOST_CHECK(k_cm(tpp)==0); - BOOST_CHECK(k_cm(ctpp)==0); - BOOST_CHECK(k_cm(tap)==0); - BOOST_CHECK(k_cm(ctap)==0); - - BOOST_CHECK(k_cm(tw)==0); - BOOST_CHECK(k_cm(ctw)==0); - - BOOST_CHECK(k_cmf(t)); - - BOOST_CHECK(k_cmf(tp)); - BOOST_CHECK(k_cmf(ctp)); - BOOST_CHECK(k_cmf(tpp)); - BOOST_CHECK(k_cmf(ctpp)); - BOOST_CHECK(k_cmf(tap)); - BOOST_CHECK(k_cmf(ctap)); - - BOOST_CHECK(k_cmf(tw)); - BOOST_CHECK(k_cmf(ctw)); - - BOOST_CHECK(!k_mf(t)); - - BOOST_CHECK(!k_mf(tp)); - BOOST_CHECK(!k_mf(tpp)); - BOOST_CHECK(!k_mf(tap)); - BOOST_CHECK(!k_mf(tw)); - BOOST_CHECK(ccmpk_w(tw)==make_tuple(false)); - - std::list tl; - for(int i=0;i<20;++i)tl.push_back(test_class(i)); - - int j=0; - for(std::list::iterator it=tl.begin();it!=tl.end();++it){ - BOOST_CHECK(k_m(it)==j); - BOOST_CHECK(k_cm(it)==j); - BOOST_CHECK(k_cmf(it)); - BOOST_CHECK(!k_mf(it)); - BOOST_CHECK(cmpk(it)==make_tuple(test_class(j),j,j,true)); - BOOST_CHECK(ccmpk(it)==make_tuple(test_class(j),j)); - ++j; - } -} diff --git a/test/test_key_extractors.hpp b/test/test_key_extractors.hpp deleted file mode 100644 index a1025d4..0000000 --- a/test/test_key_extractors.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for key extractors. - * - * 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. - */ - -void test_key_extractors(); diff --git a/test/test_key_extractors_main.cpp b/test/test_key_extractors_main.cpp deleted file mode 100644 index acb860b..0000000 --- a/test/test_key_extractors_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for key extractors. - * - * 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. - */ - -#include -#include "test_key_extractors.hpp" - -int test_main(int,char *[]) -{ - test_key_extractors(); - return 0; -} diff --git a/test/test_list_ops.cpp b/test/test_list_ops.cpp deleted file mode 100644 index 0768e55..0000000 --- a/test/test_list_ops.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* Boost.MultiIndex test for standard list operations. - * - * 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. - */ - -#include "test_list_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include - -using namespace boost::multi_index; - -#undef _ -#define _ , - -#undef CHECK_EQUAL -#define CHECK_EQUAL(p,check_range) \ -{\ - int v[]=check_range;\ - std::size_t size_v=sizeof(v)/sizeof(int);\ - BOOST_CHECK(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\ - BOOST_CHECK(std::equal((p).begin(),(p).end(),v));\ -} - -#undef CHECK_VOID_RANGE -#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second) - -struct is_even -{ - bool operator()(int x)const{return x%2==0;} -}; - -template -struct same_integral_div -{ - bool operator()(int x,int y)const{return (x/m)==(y/m);} -}; - -template -bool is_sorted( - const Container& c,const Compare& comp=Compare()) -{ - if(c.empty())return true; - - typedef typename Container::const_iterator const_iterator; - for(const_iterator it(c.begin());;){ - const_iterator it2=it; - ++it2; - if(it2==c.end())return true; - if(comp(*it2,*it))return false; - it=it2; - } -} - -void test_list_ops() -{ - typedef multi_index_container< - int, - indexed_by< - ordered_unique >, - sequenced<> - > - > sequenced_set; - typedef nth_index::type sequenced_index; - - sequenced_set ss,ss2; - sequenced_index &si=get<1>(ss),&si2=get<1>(ss2); - - si.push_front(0); /* 0 */ - si.push_front(4); /* 40 */ - ss.insert(2); /* 402 */ - ss.insert(5); /* 4025 */ - si.push_front(3); /* 34025 */ - si.push_back(6); /* 340256 */ - si.push_back(1); /* 3402561 */ - si.insert(project<1>(ss,ss.find(2)),8); /* 34082561 */ - si2=si; - - CHECK_EQUAL(si,{3 _ 4 _ 0 _ 8 _ 2 _ 5 _ 6 _ 1}); - - si.remove(8); - CHECK_EQUAL(si,{3 _ 4 _ 0 _ 2 _ 5 _ 6 _ 1}); - - si.remove_if(is_even()); - - CHECK_EQUAL(si,{3 _ 5 _ 1}); - - si.splice(si.end(),si2); - CHECK_EQUAL(si,{3 _ 5 _ 1 _ 4 _ 0 _ 8 _ 2 _ 6}); - CHECK_EQUAL(si2,{3 _ 5 _ 1}); - - si.splice(project<1>(ss,ss.find(4)),si,project<1>(ss,ss.find(8))); - CHECK_EQUAL(si,{3 _ 5 _ 1 _ 8 _ 4 _ 0 _ 2 _ 6}); - si2.clear(); - si2.splice(si2.begin(),si,si.begin()); - - si.splice(si.end(),si2,si2.begin()); - CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 0 _ 2 _ 6 _ 3}); - BOOST_CHECK(si2.empty()); - - si2.splice(si2.end(),si,project<1>(ss,ss.find(0)),project<1>(ss,ss.find(6))); - CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 6 _ 3}); - CHECK_EQUAL(si2,{0 _ 2}); - - si.splice(si.begin(),si,si.begin(),si.begin()); - CHECK_EQUAL(si,{5 _ 1 _ 8 _ 4 _ 6 _ 3}); - - si.splice(project<1>(ss,ss.find(8)),si,project<1>(ss,ss.find(4)),si.end()); - CHECK_EQUAL(si,{5 _ 1 _ 4 _ 6 _ 3 _ 8}); - - si.sort(); - si2.sort(); - BOOST_CHECK(is_sorted(si,std::less())); - BOOST_CHECK(is_sorted(si2,std::less())); - - si.merge(si2); - BOOST_CHECK(is_sorted(si,std::less())); - BOOST_CHECK(si2.empty()); - - { - sequenced_set ss3(ss); - sequenced_index &si3=get<1>(ss3); - - si3.sort(std::greater()); - si.reverse(); - BOOST_CHECK(si==si3); - } - - si2.splice(si2.end(),si,project<1>(ss,ss.find(6)),project<1>(ss,ss.find(3))); - CHECK_EQUAL(si2,{6 _ 5 _ 4}); - - si.merge(si2,std::greater()); - BOOST_CHECK(is_sorted(si,std::greater())); - BOOST_CHECK(si2.empty()); - - typedef multi_index_container< - int, - indexed_by > - > int_list; - - int_list il; - for(int i=0;i<10;++i){ - il.push_back(i); - il.push_back(i); - il.push_front(i); - il.push_front(i); - } /* 9988776655443322110000112233445566778899 */ - - il.unique(); - CHECK_EQUAL( - il, - {9 _ 8 _ 7 _ 6 _ 5 _ 4 _ 3 _ 2 _ 1 _ 0 _ - 1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9}); - - int_list::iterator it=il.begin(); - for(int j=0;j<9;++j,++it){} /* it points to o */ - - int_list il2; - il2.splice(il2.end(),il,il.begin(),it); - il2.reverse(); - il.merge(il2); - CHECK_EQUAL( - il, - {0 _ 1 _ 1 _ 2 _ 2 _ 3 _ 3 _ 4 _ 4 _ 5 _ 5 _ - 6 _ 6 _ 7 _ 7 _ 8 _ 8 _ 9 _ 9}); - - il.unique(same_integral_div<3>()); - CHECK_EQUAL(il,{0 _ 3 _ 6 _ 9}); - - il.unique(same_integral_div<1>()); - CHECK_EQUAL(il,{0 _ 3 _ 6 _ 9}); -} diff --git a/test/test_list_ops.hpp b/test/test_list_ops.hpp deleted file mode 100644 index c87009b..0000000 --- a/test/test_list_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for standard list operations. - * - * 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. - */ - -void test_list_ops(); diff --git a/test/test_list_ops_main.cpp b/test/test_list_ops_main.cpp deleted file mode 100644 index 60d6ff0..0000000 --- a/test/test_list_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for standard list operations. - * - * 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. - */ - -#include -#include "test_list_ops.hpp" - -int test_main(int,char *[]) -{ - test_list_ops(); - return 0; -} diff --git a/test/test_modifiers.cpp b/test/test_modifiers.cpp deleted file mode 100644 index 84f7ef1..0000000 --- a/test/test_modifiers.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* Boost.MultiIndex test for modifier memfuns. - * - * 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. - */ - -#include "test_modifiers.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_modifiers() -{ - employee_set es; - employee_set_by_name& i1=get(es); - employee_set_by_age& i2=get(es); - employee_set_as_inserted& i3=get(es); - employee_set_by_ssn& i4=get(es); - - es.insert(employee(0,"Joe",31,1123)); - BOOST_CHECK(es.insert(employee(0,"Joe",31,1123)).second==false); - BOOST_CHECK(i1.insert(employee(0,"Joe Jr.",5,2563)).second==false); - BOOST_CHECK(i2.insert(employee(1,"Victor",5,1123)).second==false); - BOOST_CHECK(i3.insert(i3.begin(),employee(1,"Victor",5,1123)).second - ==false); - BOOST_CHECK(i3.push_front(employee(0,"Joe Jr.",5,2563)).second==false); - BOOST_CHECK(i3.push_back(employee(0,"Joe Jr.",5,2563)).second==false); - - employee_set_by_name::iterator it1=i1.find("Joe"); - i1.insert(it1,employee(1,"Joe Jr.",5,2563)); - BOOST_CHECK(es.size()==2); - - employee_set_by_age::iterator it2=i2.find(31); - i2.insert(it2,employee(2,"Grandda Joe",64,7881)); - BOOST_CHECK(es.size()==3); - - employee_set_as_inserted::iterator it3=i3.begin(); - i3.insert(it3,100,employee(3,"Judy",39,6201)); - BOOST_CHECK(es.size()==4); - - es.erase(employee(1,"Joe Jr.",5,2563)); - BOOST_CHECK(i2.size()==3&&i3.size()==3); - - BOOST_CHECK(i1.erase("Judy")==1); - BOOST_CHECK(es.size()==2&&i2.size()==2); - - BOOST_CHECK(i2.erase(it2)->age==64); - BOOST_CHECK(es.size()==1&&i1.size()==1); - - i3.pop_front(); - BOOST_CHECK(es.size()==0&&i2.size()==0); - - es.insert(employee(0,"Joe",31,1123)); - BOOST_CHECK(i1.erase(i1.begin())==i1.end()); - BOOST_CHECK(i1.size()==0); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Jack",31,5032)); - BOOST_CHECK(i2.erase(31)==2); - BOOST_CHECK(i2.size()==0); - - i3.push_front(employee(1,"Jack",31,5032)); - i3.push_back(employee(0,"Joe",31,1123)); - BOOST_CHECK(i3.front()==employee(1,"Jack",31,5032)); - BOOST_CHECK(i3.back()==employee(0,"Joe",31,1123)); - - i3.pop_back(); - BOOST_CHECK(i3.back()==employee(1,"Jack",31,5032)); - BOOST_CHECK(es.size()==1); - - i3.pop_front(); - BOOST_CHECK(es.size()==0); - - std::vector ve; - ve.push_back(employee(3,"Anna",31,5388)); - ve.push_back(employee(1,"Rachel",27,9012)); - ve.push_back(employee(2,"Agatha",40,1520)); - - i1.insert(ve.begin(),ve.end()); - BOOST_CHECK(i2.size()==3); - - BOOST_CHECK(i4.erase(i4.begin(),i4.end())==i4.end()); - BOOST_CHECK(es.size()==0); - - i2.insert(ve.begin(),ve.end()); - BOOST_CHECK(i3.size()==3); - - BOOST_CHECK(*(i3.erase(i3.begin()))==employee(1,"Rachel",27,9012)); - BOOST_CHECK(i3.erase(i3.begin(),i3.end())==i3.end()); - BOOST_CHECK(es.size()==0); - - i3.insert(i3.end(),ve.begin(),ve.end()); - BOOST_CHECK(es.size()==3); - - BOOST_CHECK(es.erase(es.begin(),es.end())==es.end()); - BOOST_CHECK(i2.size()==0); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - employee_set es_backup(es); - - employee_set es2; - es2.insert(employee(3,"Anna",31,5388)); - es2.insert(employee(1,"Rachel",27,9012)); - es2.insert(employee(2,"Agatha",40,1520)); - - employee_set es2_backup(es2); - - i1.swap(get<1>(es2)); - BOOST_CHECK(es==es2_backup&&es2==es_backup); - - i2.swap(get<2>(es2)); - BOOST_CHECK(es==es_backup&&es2==es2_backup); - - i3.swap(get<3>(es2)); - BOOST_CHECK(es==es2_backup&&es2==es_backup); - -#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) - ::boost::multi_index::detail::swap(i1,get<1>(es2)); -#else - using std::swap; - swap(i1,get<1>(es2)); -#endif - - BOOST_CHECK(es==es_backup&&es2==es2_backup); - -#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) - ::boost::multi_index::detail::swap(i2,get<2>(es2)); -#else - using std::swap; - swap(i2,get<2>(es2)); -#endif - - BOOST_CHECK(es==es2_backup&&es2==es_backup); - -#if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) - ::boost::multi_index::detail::swap(i3,get<3>(es2)); -#else - using std::swap; - swap(i3,get<3>(es2)); -#endif - - BOOST_CHECK(es==es_backup&&es2==es2_backup); - - i3.clear(); - BOOST_CHECK(i3.size()==0); - - es=es2; - i4.clear(); - BOOST_CHECK(i4.size()==0); - - es2.clear(); - BOOST_CHECK(es2.size()==0); -} diff --git a/test/test_modifiers.hpp b/test/test_modifiers.hpp deleted file mode 100644 index b8e374c..0000000 --- a/test/test_modifiers.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for modifier memfuns. - * - * 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. - */ - -void test_modifiers(); diff --git a/test/test_modifiers_main.cpp b/test/test_modifiers_main.cpp deleted file mode 100644 index f88a229..0000000 --- a/test/test_modifiers_main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* Boost.MultiIndex test for modifier memfuns. - * - * 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. - */ - -#include -#include "test_modifiers.hpp" - -int test_main(int,char *[]) -{ - test_modifiers(); - return 0; -} - - diff --git a/test/test_mpl_ops.cpp b/test/test_mpl_ops.cpp deleted file mode 100644 index ffc7757..0000000 --- a/test/test_mpl_ops.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* Boost.MultiIndex test for MPL operations. - * - * 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. - */ - -#include "test_mpl_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include -#include - -using namespace boost::multi_index; - -void test_mpl_ops() -{ - typedef multi_index_container< - int, - indexed_by< - ordered_unique >, - ordered_non_unique > - > - > indexed_t1; - - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - ordered_unique > >::value)); - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - ordered_non_unique > >::value)); - - typedef boost::mpl::push_front< - indexed_t1::index_specifier_type_list, - sequenced<> - >::type index_list_t; - - typedef multi_index_container< - int, - index_list_t - > indexed_t2; - - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - sequenced<> >::value)); - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - boost::mpl::at_c::type>::value)); - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - boost::mpl::at_c::type>::value)); - - typedef multi_index_container< - int, - boost::mpl::list< - ordered_unique >, - ordered_non_unique > - > - > indexed_t3; - - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - boost::mpl::at_c::type>::value)); - BOOST_STATIC_ASSERT((boost::is_same< - boost::mpl::at_c::type, - boost::mpl::at_c::type>::value)); -} diff --git a/test/test_mpl_ops.hpp b/test/test_mpl_ops.hpp deleted file mode 100644 index d2335ba..0000000 --- a/test/test_mpl_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for for MPL operations. - * - * 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. - */ - -void test_mpl_ops(); diff --git a/test/test_mpl_ops_main.cpp b/test/test_mpl_ops_main.cpp deleted file mode 100644 index 50145c5..0000000 --- a/test/test_mpl_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for for MPL operations. - * - * 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. - */ - -#include -#include "test_mpl_ops.hpp" - -int test_main(int,char *[]) -{ - test_mpl_ops(); - return 0; -} diff --git a/test/test_observers.cpp b/test/test_observers.cpp deleted file mode 100644 index 7348e8f..0000000 --- a/test/test_observers.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* Boost.MultiIndex test for observer memfuns. - * - * 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. - */ - -#include "test_observers.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_observers() -{ - employee_set es; - const employee_set_by_name& i1=get(es); - const employee_set_by_age& i2=get(es); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - { - employee_set_by_name::key_from_value k=i1.key_extractor(); - employee_set_by_name::hasher h=i1.hash_function(); - employee_set_by_name::key_equal eq=i1.key_eq(); - - employee_set_by_name::const_iterator it0=i1.equal_range("John").first; - employee_set_by_name::const_iterator it1=it0;++it1; - BOOST_CHECK(k(*it0)=="John"&&k(*it1)=="John"); - BOOST_CHECK(h(k(*it0))==h(k(*it1))); - BOOST_CHECK(eq(k(*it0),k(*it1))==true); - } - { - employee_set_by_age::key_from_value k=i2.key_extractor(); - employee_set_by_age::key_compare c=i2.key_comp(); - employee_set_by_age::value_compare vc=i2.value_comp(); - - employee_set_by_age::const_iterator it0=i2.find(31); - employee_set_by_age::const_iterator it1=i2.find(40); - BOOST_CHECK(k(*it0)==31&&k(*it1)==40); - BOOST_CHECK(c(k(*it0),k(*it1))==true); - BOOST_CHECK(vc(*it0,*it1)==true); - } -} diff --git a/test/test_observers.hpp b/test/test_observers.hpp deleted file mode 100644 index 16f1de1..0000000 --- a/test/test_observers.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for observer memfuns. - * - * 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. - */ - -void test_observers(); diff --git a/test/test_observers_main.cpp b/test/test_observers_main.cpp deleted file mode 100644 index 7640b54..0000000 --- a/test/test_observers_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for observer memfuns. - * - * 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. - */ - -#include -#include "test_observers.hpp" - -int test_main(int,char *[]) -{ - test_observers(); - return 0; -} diff --git a/test/test_projection.cpp b/test/test_projection.cpp deleted file mode 100644 index 591498d..0000000 --- a/test/test_projection.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Boost.MultiIndex test for projection capabilities. - * - * 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. - */ - -#include "test_projection.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_projection() -{ - employee_set es; - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - employee_set::iterator it,itbis; - employee_set_by_name::iterator it1; - employee_set_by_age::iterator it2; - employee_set_as_inserted::iterator it3; - - BOOST_STATIC_ASSERT((boost::is_same< - employee_set::iterator, - nth_index_iterator::type >::value)); - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_name::iterator, - nth_index_iterator::type >::value)); -#if defined(BOOST_NO_MEMBER_TEMPLATES) - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_age::iterator, - index_iterator::type >::value)); -#else - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_age::iterator, - employee_set::index_iterator::type >::value)); -#endif - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_as_inserted::iterator, - nth_index_iterator::type >::value)); - - it= es.find(employee(1,"Robert",27,5601)); - it1= project(es,it); - it2= project(es,it1); - it3= project(es,it2); -#if defined(BOOST_NO_MEMBER_TEMPLATES) - itbis=project<0>(es,it3); -#else - itbis=es.project<0>(it3); -#endif - - BOOST_CHECK(*it==*it1&&*it1==*it2&&*it2==*it3&&itbis==it); - - const employee_set& ces=es; - - employee_set::const_iterator cit,citbis; - employee_set_by_name::const_iterator cit1; - employee_set_by_age::const_iterator cit2; - employee_set_as_inserted::const_iterator cit3; - - BOOST_STATIC_ASSERT((boost::is_same< - employee_set::const_iterator, - nth_index_const_iterator::type >::value)); - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_name::const_iterator, - nth_index_const_iterator::type >::value)); -#if defined(BOOST_NO_MEMBER_TEMPLATES) - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_age::const_iterator, - index_const_iterator::type >::value)); -#else - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_by_age::const_iterator, - employee_set::index_const_iterator::type >::value)); -#endif - BOOST_STATIC_ASSERT((boost::is_same< - employee_set_as_inserted::const_iterator, - nth_index_const_iterator::type >::value)); - - BOOST_CHECK(project(es,es.end())==get(es).end()); - BOOST_CHECK(project(es,es.end())==get(es).end()); - BOOST_CHECK(project(es,es.end())==get(es).end()); - - cit= ces.find(employee(4,"John",57,1002)); -#if defined(BOOST_NO_MEMBER_TEMPLATES) - cit1= project(ces,cit); -#else - cit1= ces.project(cit); -#endif - cit2= project(ces,cit1); -#if defined(BOOST_NO_MEMBER_TEMPLATES) - cit3= project(ces,cit2); -#else - cit3= ces.project(cit2); -#endif - citbis=project<0>(ces,cit3); - - BOOST_CHECK(*cit==*cit1&&*cit1==*cit2&&*cit2==*cit3&&citbis==cit); -} diff --git a/test/test_projection.hpp b/test/test_projection.hpp deleted file mode 100644 index 8722b49..0000000 --- a/test/test_projection.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for projection capabilities. - * - * 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. - */ - -void test_projection(); diff --git a/test/test_projection_main.cpp b/test/test_projection_main.cpp deleted file mode 100644 index 51882cb..0000000 --- a/test/test_projection_main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* Boost.MultiIndex test for projection capabilities. - * - * 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. - */ - -#include -#include "test_projection.hpp" - -int test_main(int,char *[]) -{ - test_projection(); - return 0; -} - - diff --git a/test/test_range.cpp b/test/test_range.cpp deleted file mode 100644 index 143ba51..0000000 --- a/test/test_range.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* Boost.MultiIndex test for range(). - * - * 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. - */ - -#include "test_range.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include -#include -#include -#include - -using namespace boost::multi_index; - -typedef multi_index_container int_set; -typedef int_set::iterator int_set_iterator; - -#undef _ -#define _ , - -#undef CHECK_RANGE -#define CHECK_RANGE(p,check_range) \ -{\ - int v[]=check_range;\ - std::size_t size_v=sizeof(v)/sizeof(int);\ - BOOST_CHECK(std::size_t(std::distance((p).first,(p).second))==size_v);\ - BOOST_CHECK(std::equal((p).first,(p).second,v));\ -} - -#undef CHECK_VOID_RANGE -#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second) - -void test_range() -{ - int_set is; - - for(int i=1;i<=10;++i)is.insert(i); - - std::pair p; - - p=is.range(unbounded,unbounded); - CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9 _ 10}); - - p=is.range( - std::bind1st(std::less(),5), /* 5 < x */ - unbounded); - CHECK_RANGE(p,{6 _ 7 _ 8 _ 9 _ 10}); - - p=is.range( - std::bind1st(std::less_equal(),8), /* 8 <= x */ - unbounded); - CHECK_RANGE(p,{8 _ 9 _ 10}); - - p=is.range( - std::bind1st(std::less_equal(),11), /* 11 <= x */ - unbounded); - CHECK_VOID_RANGE(p); - - p=is.range( - unbounded, - std::bind2nd(std::less(),8)); /* x < 8 */ - CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7}); - - p=is.range( - unbounded, - std::bind2nd(std::less_equal(),4)); /* x <= 4 */ - CHECK_RANGE(p,{1 _ 2 _ 3 _ 4}); - - p=is.range( - unbounded, - std::bind2nd(std::less_equal(),0)); /* x <= 0 */ - CHECK_VOID_RANGE(p); - - p=is.range( - std::bind1st(std::less(),6), /* 6 < x */ - std::bind2nd(std::less_equal(),9)); /* x <= 9 */ - CHECK_RANGE(p,{7 _ 8 _ 9}); - - p=is.range( - std::bind1st(std::less_equal(),4), /* 4 <= x */ - std::bind2nd(std::less(),5)); /* x < 5 */ - CHECK_RANGE(p,{4}); - - p=is.range( - std::bind1st(std::less_equal(),10), /* 10 <= x */ - std::bind2nd(std::less_equal(),10)); /* x <= 10 */ - CHECK_RANGE(p,{10}); - - p=is.range( - std::bind1st(std::less(),0), /* 0 < x */ - std::bind2nd(std::less(),11)); /* x < 11 */ - CHECK_RANGE(p,{1 _ 2 _ 3 _ 4 _ 5 _ 6 _ 7 _ 8 _ 9 _ 10}); - - p=is.range( - std::bind1st(std::less(),7), /* 7 < x */ - std::bind2nd(std::less_equal(),7)); /* x <= 7 */ - CHECK_VOID_RANGE(p); - - p=is.range( - std::bind1st(std::less_equal(),8), /* 8 <= x */ - std::bind2nd(std::less(),2)); /* x < 2 */ - CHECK_VOID_RANGE(p); - - p=is.range( - std::bind1st(std::less(),4), /* 4 < x */ - std::bind2nd(std::less(),5)); /* x < 5 */ - CHECK_VOID_RANGE(p); - BOOST_CHECK(p.first!=is.end()&&p.second!=is.end()); -} diff --git a/test/test_range.hpp b/test/test_range.hpp deleted file mode 100644 index be46553..0000000 --- a/test/test_range.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for range(). - * - * 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. - */ - -void test_range(); diff --git a/test/test_range_main.cpp b/test/test_range_main.cpp deleted file mode 100644 index 9cf1722..0000000 --- a/test/test_range_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for range(). - * - * 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. - */ - -#include -#include "test_range.hpp" - -int test_main(int,char *[]) -{ - test_range(); - return 0; -} diff --git a/test/test_safe_mode.cpp b/test/test_safe_mode.cpp deleted file mode 100644 index ef83fd6..0000000 --- a/test/test_safe_mode.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* Boost.MultiIndex test for safe_mode. - * - * 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. - */ - -#include "test_safe_mode.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include "pair_of_ints.hpp" -#include -#include - -using namespace boost::multi_index; - -#define TRY_SAFE_MODE \ -try{ - -#define CATCH_SAFE_MODE(err) \ - throw std::runtime_error("safe mode violation not detected");\ -}catch(const safe_mode_exception& e){\ - if(e.error_code!=(err))throw std::runtime_error(\ - "safe mode violation not expected");\ -} - -struct change_id -{ - change_id(int new_id_):new_id(new_id_){} - void operator()(employee& e){e.id=new_id;} - -private: - int new_id; -}; - -struct change_ssn -{ - change_ssn(int new_ssn_):new_ssn(new_ssn_){} - void operator()(employee& e){e.ssn=new_ssn;} - -private: - int new_ssn; -}; - -typedef multi_index_container< - pair_of_ints, - indexed_by< - ordered_unique, - ordered_unique > > -int_int_set; - -void test_safe_mode() -{ - employee_set es,es2; - employee_set_by_name& i1=get(es); - employee_set_by_name& i2=get(es2); - employee_set_as_inserted& ii=get(es); - es.insert(employee(0,"Joe",31,1123)); - - TRY_SAFE_MODE - employee_set::iterator it; - employee_set::iterator it2=es.begin(); - it2=it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - employee_set_by_name::iterator it2=i1.begin(); - it2=it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it; - employee e=*it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - employee e=*it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.end(); - employee e=*it; - CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.end(); - employee e=*it; - CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.end(); - ++it; - CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.end(); - ++it; - CATCH_SAFE_MODE(safe_mode::not_incrementable_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.begin(); - --it; - CATCH_SAFE_MODE(safe_mode::not_decrementable_iterator) - - TRY_SAFE_MODE - employee_set::iterator it; - employee_set::iterator it2; - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - employee_set_by_name::iterator it2; - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.begin(); - employee_set::iterator it2; - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.begin(); - employee_set_by_name::iterator it2; - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.begin(); - employee_set::iterator it2=es2.begin(); - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::not_same_owner) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.begin(); - employee_set_by_name::iterator it2=i2.begin(); - bool b=(it==it2); - b=true; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::not_same_owner) - - TRY_SAFE_MODE - es.erase(es.end(),es.begin()); - CATCH_SAFE_MODE(safe_mode::invalid_range) - - TRY_SAFE_MODE - i1.erase(i1.end(),i1.begin()); - CATCH_SAFE_MODE(safe_mode::invalid_range) - - TRY_SAFE_MODE - employee_set::iterator it; - es.insert(it,employee(0,"Joe",31,1123)); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - i1.insert(it,employee(0,"Joe",31,1123)); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - es.erase(es.end()); - CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator) - - TRY_SAFE_MODE - i1.erase(i1.end()); - CATCH_SAFE_MODE(safe_mode::not_dereferenceable_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.begin(); - es2.insert(it,employee(0,"Joe",31,1123)); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.begin(); - i2.insert(it,employee(0,"Joe",31,1123)); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set::iterator it=es.begin(); - employee_set::iterator it2=es2.end(); - es2.erase(it,it2); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=i1.begin(); - employee_set_by_name::iterator it2=i2.end(); - i2.erase(it,it2); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set::iterator it=es.insert(employee(1,"Robert",27,5601)).first; - es.erase(it); - es.erase(it); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it= - i1.insert(employee(1,"Robert",27,5601)).first; - i1.erase(it); - i1.erase(it); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set es3(es); - employee_set::iterator it=es3.insert(employee(1,"Robert",27,5601)).first; - es3.clear(); - es3.erase(it); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set es3(es); - employee_set_by_name::iterator it= - get(es3).insert(employee(1,"Robert",27,5601)).first; - get(es3).clear(); - get(es3).erase(it); - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it; - { - employee_set es3; - it=es3.insert(employee(0,"Joe",31,1123)).first; - } - employee e=*it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - { - employee_set es3; - it=get(es3).insert(employee(0,"Joe",31,1123)).first; - } - employee e=*it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it; - { - employee_set es3; - it=es3.insert(employee(0,"Joe",31,1123)).first; - } - employee_set::iterator it2; - it2=it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it; - { - employee_set es3; - it=get(es3).insert(employee(0,"Joe",31,1123)).first; - } - employee_set_by_name::iterator it2; - it2=it; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set es3(es); - employee_set es4; - employee_set::iterator it=es3.begin(); - es3.swap(es4); - es3.erase(it); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set es3(es); - employee_set es4; - employee_set_by_name::iterator it=get(es3).begin(); - es3.swap(es4); - get(es3).erase(it); - CATCH_SAFE_MODE(safe_mode::not_owner) - - /* these, unlike the previous case, are indeed correct, test safe mode - * gets it right - */ - { - employee_set es3(es); - employee_set es4; - employee_set::iterator it=es3.begin(); - es3.swap(es4); - es4.erase(it); - } - - { - employee_set es3(es); - employee_set es4; - employee_set_by_name::iterator it=get(es3).begin(); - es3.swap(es4); - get(es4).erase(it); - } - - TRY_SAFE_MODE - employee_set::iterator it=es.insert(employee(1,"Robert",27,5601)).first; - employee_set_by_name::iterator it2=project(es,it); - es.modify_key(it,change_id(0)); - employee e=*it2; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set_by_name::iterator it= - i1.insert(employee(1,"Robert",27,5601)).first; - employee_set::iterator it2=project<0>(es,it); - i1.modify(it,change_ssn(1123)); - employee e=*it2; - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - int_int_set iis; - int_int_set::iterator it=iis.insert(pair_of_ints(0,0)).first; - iis.insert(pair_of_ints(1,1)); - iis.modify(it,increment_first); - pair_of_ints p=*it; - p.first=0; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - int_int_set iis; - int_int_set::iterator it=iis.insert(pair_of_ints(0,0)).first; - iis.insert(pair_of_ints(1,1)); - iis.modify(it,increment_second); - pair_of_ints p=*it; - p.first=0; /* avoid warning about unused var */ - CATCH_SAFE_MODE(safe_mode::invalid_iterator) - - TRY_SAFE_MODE - employee_set::iterator it=es.end(); - employee_set_by_name::iterator it2=project(es2,it); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - employee_set_by_name::iterator it=get(es).end(); - employee_set::iterator it2=project<0>(es2,it); - CATCH_SAFE_MODE(safe_mode::not_owner) - - TRY_SAFE_MODE - ii.splice(ii.begin(),ii,ii.begin(),ii.end()); - CATCH_SAFE_MODE(safe_mode::inside_range) - - TRY_SAFE_MODE - ii.splice(ii.begin(),ii); - CATCH_SAFE_MODE(safe_mode::same_container) -} diff --git a/test/test_safe_mode.hpp b/test/test_safe_mode.hpp deleted file mode 100644 index 63fbbc4..0000000 --- a/test/test_safe_mode.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for safe mode. - * - * 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. - */ - -void test_safe_mode(); diff --git a/test/test_safe_mode_main.cpp b/test/test_safe_mode_main.cpp deleted file mode 100644 index 91a8c1c..0000000 --- a/test/test_safe_mode_main.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* Boost.MultiIndex test for safe mode. - * - * 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. - */ - -#include -#include "test_safe_mode.hpp" - -int test_main(int,char *[]) -{ - test_safe_mode(); - return 0; -} - diff --git a/test/test_serialization.cpp b/test/test_serialization.cpp deleted file mode 100644 index 28c805f..0000000 --- a/test/test_serialization.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* Boost.MultiIndex test for serialization. - * - * 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. - */ - -#include "test_serialization.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pair_of_ints.hpp" - -using namespace boost::multi_index; - -template -struct all_indices_equal_helper -{ - template - static bool compare( - const MultiIndexContainer& m1,const MultiIndexContainer& m2) - { - if(!(get(m1)==get(m2))){ - return false; - } - return all_indices_equal_helper::compare(m1,m2); - } -}; - -template<> -struct all_indices_equal_helper<0> -{ - template - static bool compare( - const MultiIndexContainer& m1,const MultiIndexContainer& m2) - { - return true; - } -}; - -template -bool all_indices_equal( - const MultiIndexContainer& m1,const MultiIndexContainer& m2) -{ - BOOST_STATIC_CONSTANT(int, - N=boost::mpl::size< - BOOST_DEDUCED_TYPENAME MultiIndexContainer::index_type_list>::type::value); - - return all_indices_equal_helper::compare(m1,m2); -} - -template -void test_serialization(const MultiIndexContainer& m) -{ - typedef typename MultiIndexContainer::iterator iterator; - typedef typename MultiIndexContainer::const_iterator const_iterator; - - std::ostringstream oss; - { - boost::archive::text_oarchive oa(oss); - oa< its(m.size()); - const_iterator it_end=m.end(); - for(const_iterator it=m.begin();it!=it_end;++it){ - its.push_back(it); - oa<(its.back()); - } - oa<(it_end); - } - - MultiIndexContainer m2; - std::istringstream iss(oss.str()); - boost::archive::text_iarchive ia(iss); - ia>>m2; - BOOST_CHECK(all_indices_equal(m,m2)); - - iterator it_end=m2.end(); - for(iterator it=m2.begin();it!=it_end;++it){ - iterator it2; - ia>>it2; - BOOST_CHECK(it==it2); - - /* exercise safe mode with this (unchecked) iterator */ - BOOST_CHECK(*it==*it2); - m2.erase(it,it2); - m2.erase(it2,it2); - m2.erase(it2,it); - iterator it3(++it2); - iterator it4; - it4=--it2; - BOOST_CHECK(it==it4); - BOOST_CHECK(it==project<0>(m2,it4)); - } - iterator it2; - ia>>it2; - BOOST_CHECK(it_end==it2); - BOOST_CHECK(it_end==project<0>(m2,it2)); -} - -void test_hashed_index_serialization() -{ - const int N=100; - const int SHUFFLE=10232; - - typedef multi_index_container< - int, - indexed_by< - hashed_unique >, - sequenced<> - > - > hashed_set; - - typedef hashed_set::iterator iterator; - typedef hashed_set::local_iterator local_iterator; - - hashed_set hs; - - for(int i=0;i(hs); - - std::vector its(N); - for(int i=0;i(its.back()); - } - iterator it=hs.end(); - oa<(it); - - std::vector lits(2*N); - for(std::size_t buc=0;buc(lits.back()); - } - local_iterator lit2=hs.end(buc); - lits.push_back(lit2); - oa<(lits.back()); - } - } - - hashed_set hs2; - std::istringstream iss(oss.str()); - boost::archive::text_iarchive ia(iss); - ia>>hs2; - BOOST_CHECK(get<1>(hs)==get<1>(hs2)); - - for(int j=0;j>it; - BOOST_CHECK(*it==j*SHUFFLE); - } - iterator it; - ia>>it; - BOOST_CHECK(it==hs2.end()); - - for(std::size_t buc=0;buc>n; - ia>>it; - BOOST_CHECK(*it==n); - } - local_iterator it2; - ia>>it2; - BOOST_CHECK(it2==hs2.end(buc)); - } -} - -void test_serialization() -{ - { - typedef multi_index_container< - int, - indexed_by< - sequenced<>, - sequenced<> - > - > multi_index_t; - - multi_index_t m; - for(int i=0;i<100;++i)m.push_back(i); - m.reverse(); - test_serialization(m); - - m.clear(); - for(int j=50;j<100;++j)m.push_back(j); - for(int k=0;k<50;++k)m.push_back(k); - m.sort(); - test_serialization(m); - } - { - typedef multi_index_container< - int, - indexed_by< - sequenced<>, - ordered_non_unique > - > - > multi_index_t; - - multi_index_t m; - for(int i=0;i<100;++i){ - m.push_back(i); - m.push_back(i); - m.push_back(i); - } - m.reverse(); - test_serialization(m); - } - { - typedef multi_index_container< - pair_of_ints, - indexed_by< - ordered_unique< - BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,first) - >, - ordered_non_unique< - BOOST_MULTI_INDEX_MEMBER(pair_of_ints,int,second) - >, - sequenced<> - > - > multi_index_t; - - multi_index_t m; - test_serialization(m); - - m.insert(pair_of_ints(4,0)); - test_serialization(m); - - m.insert(pair_of_ints(3,1)); - m.insert(pair_of_ints(2,1)); - test_serialization(m); - - m.insert(pair_of_ints(1,1)); - test_serialization(m); - - m.insert(pair_of_ints(0,0)); - test_serialization(m); - - m.insert(pair_of_ints(5,1)); - m.insert(pair_of_ints(7,1)); - m.insert(pair_of_ints(6,1)); - test_serialization(m); - - m.insert(pair_of_ints(8,1)); - m.insert(pair_of_ints(9,1)); - m.insert(pair_of_ints(12,1)); - m.insert(pair_of_ints(11,1)); - m.insert(pair_of_ints(10,1)); - test_serialization(m); - } - test_hashed_index_serialization(); -} diff --git a/test/test_serialization.hpp b/test/test_serialization.hpp deleted file mode 100644 index da7dabf..0000000 --- a/test/test_serialization.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test test for serialization. - * - * 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. - */ - -void test_serialization(); diff --git a/test/test_serialization_main.cpp b/test/test_serialization_main.cpp deleted file mode 100644 index 5dd0322..0000000 --- a/test/test_serialization_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for serialization. - * - * 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. - */ - -#include -#include "test_serialization.hpp" - -int test_main(int,char *[]) -{ - test_serialization(); - return 0; -} diff --git a/test/test_set_ops.cpp b/test/test_set_ops.cpp deleted file mode 100644 index bbf37a5..0000000 --- a/test/test_set_ops.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* Boost.MultiIndex test for standard set operations. - * - * 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. - */ - -#include "test_set_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -void test_set_ops() -{ - employee_set es; - employee_set_by_name& i1=get(es); - const employee_set_by_age& i2=get(es); - employee_set_by_ssn& i4=get(es); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - BOOST_CHECK(i1.find("John")->name=="John"); - BOOST_CHECK(i2.find(41)==i2.end()); - BOOST_CHECK(i4.find(5601)->name=="Robert"); - - BOOST_CHECK(i1.count("John")==2); - BOOST_CHECK(es.count(employee(10,"",-1,0))==0); - BOOST_CHECK(i4.count(7881)==0); - - BOOST_CHECK( - std::distance( - i2.lower_bound(31), - i2.upper_bound(60))==3); - - std::pair p= - i1.equal_range("John"); - BOOST_CHECK(std::distance(p.first,p.second)==2); - - p=i1.equal_range("Serena"); - BOOST_CHECK(p.first==i1.end()&&p.second==i1.end()); - - std::pair p2= - i2.equal_range(30); - BOOST_CHECK(p2.first==p2.second&&p2.first->age==31); -} diff --git a/test/test_set_ops.hpp b/test/test_set_ops.hpp deleted file mode 100644 index 2553301..0000000 --- a/test/test_set_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for standard set operations. - * - * 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. - */ - -void test_set_ops(); diff --git a/test/test_set_ops_main.cpp b/test/test_set_ops_main.cpp deleted file mode 100644 index 7f2ba60..0000000 --- a/test/test_set_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for standard set operations. - * - * 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. - */ - -#include -#include "test_set_ops.hpp" - -int test_main(int,char *[]) -{ - test_set_ops(); - return 0; -} diff --git a/test/test_special_list_ops.cpp b/test/test_special_list_ops.cpp deleted file mode 100644 index c601ccc..0000000 --- a/test/test_special_list_ops.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Boost.MultiIndex test for special list operations. - * - * 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. - */ - -#include "test_special_list_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include -#include -#include - -using namespace boost::multi_index; - -#undef _ -#define _ , - -#undef CHECK_EQUAL -#define CHECK_EQUAL(p,check_range) \ -{\ - int v[]=check_range;\ - std::size_t size_v=sizeof(v)/sizeof(int);\ - BOOST_CHECK(std::size_t(std::distance((p).begin(),(p).end()))==size_v);\ - BOOST_CHECK(std::equal((p).begin(),(p).end(),v));\ -} - -#undef CHECK_VOID_RANGE -#define CHECK_VOID_RANGE(p) BOOST_CHECK((p).first==(p).second) - -void test_special_list_ops() -{ - typedef multi_index_container< - int, - indexed_by< - sequenced<> - > - > sequenced_container; - - sequenced_container sc; - sc.push_back(0); - sc.push_back(1); - sc.push_back(2); - sc.push_back(3); - sc.push_back(4); - sc.push_back(5); - - sequenced_container::iterator it; - - it=sc.begin(); - std::advance(it,3); - sc.relocate(sc.begin(),it); - CHECK_EQUAL(sc,{3 _ 0 _ 1 _ 2 _ 4 _ 5}); - BOOST_CHECK(it==sc.begin()); - - sc.relocate(it,it); - CHECK_EQUAL(sc,{3 _ 0 _ 1 _ 2 _ 4 _ 5}); - - std::advance(it,3); - sc.relocate(sc.end(),it,sc.end()); - CHECK_EQUAL(sc,{3 _ 0 _ 1 _ 2 _ 4 _ 5}); - - sc.relocate(sc.begin(),it,it); - CHECK_EQUAL(sc,{3 _ 0 _ 1 _ 2 _ 4 _ 5}); - - sequenced_container::iterator it2; - - it2=sc.begin(); - ++it2; - sc.relocate(it2,it,sc.end()); - CHECK_EQUAL(sc,{3 _ 2 _ 4 _ 5 _ 0 _ 1}); - BOOST_CHECK(std::distance(it,it2)==3); - - sc.relocate(--(sc.end()),it,it2); - CHECK_EQUAL(sc,{3 _ 0 _ 2 _ 4 _ 5 _ 1}); -} diff --git a/test/test_special_list_ops.hpp b/test/test_special_list_ops.hpp deleted file mode 100644 index fef32ae..0000000 --- a/test/test_special_list_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for special list operations. - * - * 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. - */ - -void test_special_list_ops(); diff --git a/test/test_special_list_ops_main.cpp b/test/test_special_list_ops_main.cpp deleted file mode 100644 index 0dbbe79..0000000 --- a/test/test_special_list_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for special list operations. - * - * 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. - */ - -#include -#include "test_special_list_ops.hpp" - -int test_main(int,char *[]) -{ - test_special_list_ops(); - return 0; -} diff --git a/test/test_special_set_ops.cpp b/test/test_special_set_ops.cpp deleted file mode 100644 index 92b598c..0000000 --- a/test/test_special_set_ops.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* Boost.MultiIndex test for special set operations. - * - * 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. - */ - -#include "test_special_set_ops.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include - -using namespace boost::multi_index; - -static int string_to_int(const std::string& str) -{ - std::istringstream iss(str); - int res; - iss>>res; - return res; -} - -struct comp_int_string -{ - bool operator()(int x,const std::string& y)const - { - return x()(string_to_int(x)); - } -}; - -struct eq_string_int -{ - bool operator()(int x,const std::string& y)const - { - return x==string_to_int(y); - } - - bool operator()(const std::string& x,int y)const - { - return operator()(y,x); - } -}; - -void test_special_set_ops() -{ - employee_set es; - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Albert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - std::pair p= - get(es).equal_range( - "7889",hash_string_as_int(),eq_string_int()); - - BOOST_CHECK(std::distance(p.first,p.second)==1&&(p.first)->id==2); - - BOOST_CHECK( - get(es).count( - "5601",hash_string_as_int(),eq_string_int())==1); - - BOOST_CHECK( - get(es).find( - "1123",hash_string_as_int(),eq_string_int())->name=="Joe"); - - BOOST_CHECK( - std::distance( - get(es).lower_bound("27",comp_int_string()), - get(es).upper_bound("40",comp_int_string()))==3); - - BOOST_CHECK(es.count(2,employee::comp_id())==1); - BOOST_CHECK(es.count(5,employee::comp_id())==0); -} diff --git a/test/test_special_set_ops.hpp b/test/test_special_set_ops.hpp deleted file mode 100644 index fbb4545..0000000 --- a/test/test_special_set_ops.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for special set operations. - * - * 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. - */ - -void test_special_set_ops(); diff --git a/test/test_special_set_ops_main.cpp b/test/test_special_set_ops_main.cpp deleted file mode 100644 index 159b2f0..0000000 --- a/test/test_special_set_ops_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for special set operations. - * - * 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. - */ - -#include -#include "test_special_set_ops.hpp" - -int test_main(int,char *[]) -{ - test_special_set_ops(); - return 0; -} diff --git a/test/test_update.cpp b/test/test_update.cpp deleted file mode 100644 index 5effb90..0000000 --- a/test/test_update.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Boost.MultiIndex test for replace(), modify() and modify_key(). - * - * 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. - */ - -#include "test_update.hpp" - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include "pre_multi_index.hpp" -#include "employee.hpp" -#include "pair_of_ints.hpp" -#include - -using namespace boost::multi_index; - -void test_update() -{ - employee_set es; - employee_set_as_inserted& i=get(es); - - es.insert(employee(0,"Joe",31,1123)); - es.insert(employee(1,"Robert",27,5601)); - es.insert(employee(2,"John",40,7889)); - es.insert(employee(3,"Olbert",20,9012)); - es.insert(employee(4,"John",57,1002)); - - employee_set::iterator it=es.find(employee(0,"Joe",31,1123)); - employee_set_as_inserted::iterator it1= - project(es,get(es).find("Olbert")); - - BOOST_CHECK(es.replace(it,*it)); - BOOST_CHECK(!es.replace(it,employee(3,"Joe",31,1123))&&it->id==0); - BOOST_CHECK(es.replace(it,employee(0,"Joe",32,1123))&&it->age==32); - BOOST_CHECK(i.replace(it1,employee(3,"Albert",20,9012))&&it1->name== - "Albert"); - - { - typedef multi_index_container< - pair_of_ints, - indexed_by< - ordered_unique, - hashed_unique, - sequenced<> > > - int_int_set; - - int_int_set iis; - nth_index::type& ii1=get<1>(iis); - nth_index::type& ii2=get<2>(iis); - iis.insert(pair_of_ints(0,0)); - iis.insert(pair_of_ints(5,5)); - iis.insert(pair_of_ints(10,10)); - - BOOST_CHECK(!iis.replace(iis.begin(),pair_of_ints(5,0))); - BOOST_CHECK(!ii2.replace(ii2.begin(),pair_of_ints(0,5))); - BOOST_CHECK(!ii1.replace(project<1>(iis,iis.begin()),pair_of_ints(5,11))); - BOOST_CHECK(!iis.replace(iis.begin(),pair_of_ints(11,5))); - BOOST_CHECK(!iis.replace(++iis.begin(),pair_of_ints(10,5))); - BOOST_CHECK(!ii1.replace( - project<1>(iis,++iis.begin()),pair_of_ints(5,10))); - BOOST_CHECK(!iis.replace(--iis.end(),pair_of_ints(5,10))); - BOOST_CHECK(!ii2.replace(--ii2.end(),pair_of_ints(10,5))); - - BOOST_CHECK(iis.modify(iis.begin(),increment_first)); - BOOST_CHECK(ii2.modify(ii2.begin(),increment_first)); - BOOST_CHECK(ii1.modify(project<1>(iis,iis.begin()),increment_first)); - BOOST_CHECK(ii2.modify(ii2.begin(),increment_first)); - - BOOST_CHECK(!iis.modify(iis.begin(),increment_first)); - BOOST_CHECK(iis.size()==2); - - iis.insert(pair_of_ints(0,0)); - BOOST_CHECK(ii2.modify(--ii2.end(),increment_second)); - BOOST_CHECK(iis.modify(iis.begin(),increment_second)); - BOOST_CHECK(ii2.modify(--ii2.end(),increment_second)); - BOOST_CHECK(iis.modify(iis.begin(),increment_second)); - - BOOST_CHECK(!ii2.modify(--ii2.end(),increment_second)); - BOOST_CHECK(ii2.size()==2); - - iis.insert(pair_of_ints(0,0)); - BOOST_CHECK(iis.modify_key(iis.begin(),increment_int)); - BOOST_CHECK(iis.modify_key(iis.begin(),increment_int)); - BOOST_CHECK(iis.modify_key(iis.begin(),increment_int)); - BOOST_CHECK(iis.modify_key(iis.begin(),increment_int)); - - BOOST_CHECK(!iis.modify_key(iis.begin(),increment_int)); - BOOST_CHECK(iis.size()==2); - - nth_index_iterator::type it=ii1.find(5); - BOOST_CHECK(ii1.modify_key(it,increment_int)); - BOOST_CHECK(ii1.modify_key(it,increment_int)); - BOOST_CHECK(ii1.modify_key(it,increment_int)); - BOOST_CHECK(ii1.modify_key(it,increment_int)); - - BOOST_CHECK(!ii1.modify_key(it,increment_int)); - BOOST_CHECK(ii1.size()==1); - } - { - typedef multi_index_container< - pair_of_ints, - indexed_by< - hashed_unique, - sequenced<>, - ordered_unique > > - int_int_set; - - int_int_set iis; - nth_index::type& ii1=get<1>(iis); - int_int_set::iterator p1=iis.insert(pair_of_ints(0,0)).first; - int_int_set::iterator p2=iis.insert(pair_of_ints(5,5)).first; - int_int_set::iterator p3=iis.insert(pair_of_ints(10,10)).first; - - BOOST_CHECK(!iis.replace(p1,pair_of_ints(5,0))); - BOOST_CHECK(!ii1.replace(ii1.begin(),pair_of_ints(0,5))); - BOOST_CHECK(!iis.replace(p1,pair_of_ints(5,11))); - BOOST_CHECK(!iis.replace(p1,pair_of_ints(11,5))); - BOOST_CHECK(!iis.replace(p2,pair_of_ints(10,5))); - BOOST_CHECK(!iis.replace(p2,pair_of_ints(5,10))); - BOOST_CHECK(!iis.replace(p3,pair_of_ints(5,10))); - BOOST_CHECK(!ii1.replace(--ii1.end(),pair_of_ints(10,5))); - - BOOST_CHECK(iis.modify(p1,increment_first)); - BOOST_CHECK(ii1.modify(ii1.begin(),increment_first)); - BOOST_CHECK(iis.modify(p1,increment_first)); - BOOST_CHECK(ii1.modify(ii1.begin(),increment_first)); - - BOOST_CHECK(!iis.modify(p1,increment_first)); - BOOST_CHECK(iis.size()==2); - - p1=iis.insert(pair_of_ints(0,0)).first; - BOOST_CHECK(ii1.modify(--ii1.end(),increment_second)); - BOOST_CHECK(iis.modify(p1,increment_second)); - BOOST_CHECK(ii1.modify(--ii1.end(),increment_second)); - BOOST_CHECK(iis.modify(p1,increment_second)); - - BOOST_CHECK(!ii1.modify(--ii1.end(),increment_second)); - BOOST_CHECK(ii1.size()==2); - } -} diff --git a/test/test_update.hpp b/test/test_update.hpp deleted file mode 100644 index 02451e2..0000000 --- a/test/test_update.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Boost.MultiIndex test for replace(), modify() and modify_key(). - * - * 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. - */ - -void test_update(); diff --git a/test/test_update_main.cpp b/test/test_update_main.cpp deleted file mode 100644 index 230c08a..0000000 --- a/test/test_update_main.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Boost.MultiIndex test for replace(), modify() and modify_key(). - * - * 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. - */ - -#include -#include "test_update.hpp" - -int test_main(int,char *[]) -{ - test_update(); - return 0; -}