diff --git a/doc/compiler_specifics.html b/doc/compiler_specifics.html index ce80c4d..341ccb0 100644 --- a/doc/compiler_specifics.html +++ b/doc/compiler_specifics.html @@ -28,911 +28,63 @@ Performance
-Boost.MultiIndex has been tried in different compilers, with -various degrees of success. We list the limitations encountered, -along with suitable workarounds when available. +Boost.MultiIndex utilizes some C++11 capabilities but is also equipped +to work reasonably well in decent C++03-compliant environments. +We list some of the possible limitations along with suitable workarounds when available.
-Currently, Boost.MultiIndex cannot be used with any of BCB 6.4 up to BCB 2006
-and CodeGear C++Builder 2010.
-The number of problems encountered during the tests makes it unlikely that
-future versions of the library can be made to work under these compilers.
+Boost.MultiIndex uses Boost.Move
+to support compilers without rvalue references. In such scenarios, taking
+advantage of multi_index_container<Value>
capabilities for
+increased efficiency in insertion and handling of moveable-only elements will
+require that Value
be suitably instrumented.
-Note: Last tested in Boost 1.38. The information might be no longer accurate.
+In compilers without variadic template support, Boost.MultiIndex emplace
+functions emulate this missing functionality by accepting up to
+BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
+construction arguments that are internally forwarded with
+Boost.Move:
+only constant lvalue references and rvalues are permitted as construction arguments
+in such case.
-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. Last time they were
-tested (Boost.1.34.1), VC++ 7.0/7.1 backends worked correctly. The beta 2 version of
-the Comeau compiler 4.3.10.1 has been used.
+BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS
, which by default is 5, can
+be globally defined by the user to a different value.
-Note: Last tested in Boost 1.38. The information might be no longer accurate.
+No transparent emulation of this functionality can be provided in the absence of
+std::initializer_list
: consider
+Boost.Assign as a
+possible replacement.
-No problems have been detected with this compiler. Last tested for version 7.1-006. -
- --No problems have been detected with several versions of this compiler -starting from 3.2. The following versions have been explicitly tested: -
-On this platform, GCC is not able to handle debug symbol names whose length
-exceeds 32,768 bytes, resulting in the error mips-tfile, ... string
-too big
. You may encounter this issue with heavily templatized
-code like Boost.MultiIndex, which typically produces long symbol names. The problem
-can be overcome by omitting the compiler option -g
(generate debugging
-information.) Alternatively, consult the section on
-reduction of symbol name lengths for various
-applicable workarounds.
-
-Build 4061 of GCC 4.0, shipped with Darwin 8.2 and prior (Mac OS X 10.4.2 and -prior), corresponds to a prerelease version of GNU GCC 4.0.0 which introduces -a regression bug -related to binding of references to temporary objects. This bug precludes the -usage of Boost.MultiIndex -invariant-checking mode; other -than this, Boost.MultiIndex works correctly. -The bug is corrected in GCC 4.0 Apple build 5026, which is in sync with the official -release of GNU GCC 4.0.0, so the invariant-checking mode is available from this -upgrade. -
- --Note: Last tested in Boost 1.38. The information might be no longer accurate. -
- --No problems have been detected with this compiler. -Last tested for version A.06.17. -
- --Note: Last tested in Boost 1.38. The information might be no longer accurate. -
- --No problems have been detected with this compiler. -Last tested for version A.03.85. -
- --Note: Last tested in Boost 1.33.1. The information might be no longer accurate. -
- -- -
-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. -
- -
-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
.
-Other than this, Boost.MultiIndex works without problems.
-Last tested for version V10.1.
-
-No problems have been detected with this compiler. -Last tested for compiler versions 10.0 to 11.1. -
- --No problems have been detected with this compiler. -Tested from version 10.1 to 11.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.
-Last tested for compiler version 11.1.
-
-No problems have been detected with this compiler. -Last tested for compiler version 11.1. -
- --Note: Last tested in Boost 1.36. The information might be no longer accurate. -
- --Predefined key extractors instantiated on a given type do not accept -objects of derived types. For instance: -
- -- --struct base{}; -struct derived:public base{}; -... - -identity<base> key_extractor; -derived x; - -// not accepted by this compiler: an explicit cast to base is required -key_extractor(x); -
-Other than this, Boost.MultiIndex works without problems under Mac OS and Windows (last -tested under Windows only). -
- --Note: Last tested in Boost 1.34.1. The information might be no longer accurate. -
- --Boost.MultiIndex works correctly with versions of this compiler from 9.0 to -9.5, both under Mac OS and Windows. -
- --Note: Last tested in Boost 1.36. The information might be no longer accurate. -
- -- -
-Beginning with Boost.1.36, Boost.Serialization is no longer supported in this -compiler, thus the serialization capabilities cannot be used. -
- -- -
-member
not supported,
-refer to the section on
-use of member_offset
for workarounds.
-
-const_mem_fun
and
-mem_fun
-not supported, refer to the section on
-use of const_mem_fun_explicit
and
-mem_fun_explicit
for workarounds.
-
- -
-No support for index retrieval -and projection -nested types and member functions: -
nth_index
,index
,nth_index_iterator
,nth_index_const_iterator
,index_iterator
,index_const_iterator
,get
,project
.::boost::multi_index
.
-
-
-- -
-boost::multi_index::multi_index_container
is imported to
-namespace boost
by means of a using
declaration.
-MSVC++ 6.0, however, does not properly handle this import. So, instead of
-writing:
-
- --boost::multi_index_container<...> -
-use the following: -
- -- --boost::multi_index::multi_index_container<...> -
-or else resort to a directive using namespace boost::multi_index
.
-
- -
-The lack of partial template specialization support in MSVC++ 6.0
-results in some inconveniences when using composite_key
that
-can be remedied as explained in
-"composite_key
-in compilers without partial template specialization".
-
- -
-Due to problems with function template ordering support,
-composite_key_compare
-and related classes do not accept the notational variations of
-operator()
where one of the operands is treated as if
-included into a tuple of length 1. As a result, the user cannot ever
-omit tuple enclosing when specifying the arguments of lookup operations
-involving composite keys.
-
- -
-Predefined key extractors instantiated on a given type do not accept -objects of derived types. For instance: -
- -- --struct base{}; -struct derived:public base{}; -... - -identity<base> key_extractor; -derived x; - -// not accepted by this compiler: an explicit cast to base is required -key_extractor(x); -
- -
-MSVC++ 6.0 presents serious limitations for the maximum length of
-symbol names generated by the compiler, which might result in the
-linker error
-LNK1179:
-invalid or corrupt file: duplicate comdat
-comdat
. To overcome this problem, consult the section on
-reduction of symbol name lengths for various
-applicable workarounds.
-
- -
-Under some circumstances, the compiler emits the error
-
-C2587
: '_U' : illegal use of local variable as
-default parameter
, inside the MSVC internal header
-<xlocnum>
.
-This problem is a recurrent bug of the compiler, and has been reported in
-other unrelated libraries, like the
-Boost Graph Library,
-Boost.MultiArray,
-Boost.Regex,
-CGAL and
-MySQL++.
-The error is triggered, though not in a systematic manner, by the use
-of multi_index_container
iterator constructor. Two workarounds exist:
-the first consists of avoiding this constructor and replacing
-code like:
-
- --multi_index_container<...> s(c.begin(),c.end()); -
-with equivalent operations: -
- -- --multi_index_container<...> s; -s.insert(c.begin(),c.end()); -
-The second workaround has not been confirmed by the author, but it is given
-on the Internet in connection with this error appearing in other libraries.
-Replace line 84 of <xlocnum>
-
-
- -- #define _VIRTUAL virtual -
-with the following: -
- -- -- #define _VIRTUAL -
-Warning: it is not known whether this
-replacement can result in unexpected side effects in code implicitly
-using <xlocnum>
.
-
- -
-In general, the extensive use of templates by Boost.MultiIndex puts this compiler -under severe stress, so that several internal limitations may be reached. -The following measures can help alleviate these problems: -
/Zm
(Specify Memory Allocation Limit)
- to increase the amount of memory available for compilation. Usual values for
- this option range from 300 to 800./ZI
(Program Database for
- Edit and Continue) to a less demanding type of debugging information
- (/Zi
, /Z7
or /Zd
.)C1055
: compiler limit : out of keys
, try
- disabling the option /Gm
(Enable Minimal Rebuild.) In these
- cases, it is also beneficial to split the project into smaller
- subprojects.-Note: Last tested in Boost 1.36. The information might be no longer accurate. -
- --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 and -5.0.1 has also been confirmed to work correctly. -
- --Note: Last tested in Boost 1.35. The information might be no longer accurate. -
- -- -
-Beginning with Boost.1.36, Boost.Serialization is no longer supported in this -compiler, thus the serialization capabilities cannot be used. -
- -- -
-member
not supported,
-refer to the section on
-use of member_offset
for workarounds.
-
- -
-No support for index retrieval -and projection -nested types and member functions: -
nth_index
,index
,nth_index_iterator
,nth_index_const_iterator
,index_iterator
,index_const_iterator
,get
,project
.::boost::multi_index
.
-
-
-- -
-boost::multi_index::multi_index_container
is imported to
-namespace boost
by means of a using
declaration.
-MSVC++ 7.0, however, does not properly handle this import. So, instead of
-writing:
-
- --boost::multi_index_container<...> -
-use the following: -
- -- --boost::multi_index::multi_index_container<...> -
-or else resort to a directive using namespace boost::multi_index
.
-
- -
-The lack of partial template specialization support in MSVC++ 7.0
-results in some inconveniences when using composite_key
that
-can be remedied as explained in
-"composite_key
-in compilers without partial template specialization".
-
- -
-Due to problems with function template ordering support,
-composite_key_compare
-and related classes do not accept the notational variations of
-operator()
where one of the operands is treated as if
-included into a tuple of length 1. As a result, the user cannot ever
-omit tuple enclosing when specifying the arguments of lookup operations
-involving composite keys.
-
- -
-Predefined key extractors instantiated on a given type do not accept -objects of derived types. For instance: -
- -- --struct base{}; -struct derived:public base{}; -... - -identity<base> key_extractor; -derived x; - -// not accepted by this compiler: an explicit cast to base is required -key_extractor(x); -
-Note: Last tested in Boost 1.35. The information might be no longer accurate. -
- --Boost.MultiIndex works for this configuration. The same issues apply as in -MSVC++ 7.0 with its original Dinkumware standard library. -
- -
-Problems have been reported when compiling the library with the /Gm
-option (Enable Minimal Rebuild.) Seemingly, this is due to an
-internal defect of the compiler (see for instance
-
-this mention of a similar issue in the Boost Users mailing list.)
-If /Gm
is turned off, Boost.MultiIndex compiles and runs
-without further problems.
-
-No problems have been detected with this compiler, both in 32-bit and 64-bit modes. -Last tested for compiler versions 8.0 to 10.0. -
- -
-No problems have been detected with this platform. Last tested for compiler version
-Sun C++ 5.10 (Sun Studio 12 Update 1).
-The option -library=stlport4
was used to replace the default
-standard library with STLport.
-
member_offset
-The member
key extractor poses some problems in compilers
-that do not properly support pointers to members as non-type
-template arguments, as indicated by the
-Boost Configuration Library
-defect macro BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS
.
-The following compilers have been confirmed not
-to work correctly with member
:
-
- --#include <iostream> - -struct pair -{ - int x,y; - - pair(int x_,int y_):x(x_),y(y_){} -}; - -template<int pair::* PtrToPairMember> -struct foo -{ - int bar(pair& p){return p.*PtrToPairMember;} -}; - -int main() -{ - pair p(0,1); - foo<&pair::x> fx; - foo<&pair::y> fy; - - if(fx.bar(p)!=0||fy.bar(p)!=1)std::cout<<"KO"<<std::endl; - else std::cout<<"OK"<<std::endl; - - return 0; -} - -
-If you find a compiler that does not pass the test, and for which
-BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS
is not defined,
-please report to the Boost developers mailing list.
-
To overcome this defect, a replacement utility
-member_offset
-has been provided that does the work of member
at the
-expense of less convenient notation and the possibility of
-non-conformance with the standard. Please consult
-the reference for further information on member_offset
.
-As an example of use, given the class
-
- --class A -{ - int x; -} -
-the instantiation member<A,int,&A::x>
can be simulated then
-as member_offset<A,int,offsetof(A,x)>
.
-
-For those writing portable code, Boost.MultiIndex provides the ternary macro
-BOOST_MULTI_INDEX_MEMBER
.
-Continuing with the example above, the
-expression
-
- --BOOST_MULTI_INDEX_MEMBER(A,int,x) -
-expands by default to -
- -- --member<A,int,&A::x> -
-or alternatively to -
- -- --member_offset<A,int,offsetof(A,x)> -
-if BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS
is defined.
-
const_mem_fun_explicit
and
-mem_fun_explicit
-MSVC++ 6.0 has problems with const
member functions as non-type
-template parameters, and thus does not accept the const_mem_fun
-key extractor. A simple workaround, fortunately, has been found, consisting
-in specifying the type of these pointers as an additional template
-parameter. The alternative
-const_mem_fun_explicit
-extractor adopts this solution; for instance, given the type
-
- --struct A -{ - int f()const; -}; -
-the extractor const_mem_fun<A,int,&A::f>
can be replaced by
-const_mem_fun_explicit<A,int,int (A::*)()const,&A::f>
. A similar
-mem_fun_explicit
class template is provided for non-constant
-member functions.
-
-If you are writing cross-platform code, the selection of either key extractor
-is transparently handled by the macro
-BOOST_MULTI_INDEX_CONST_MEM_FUN
,
-so that
-
- --BOOST_MULTI_INDEX_CONST_MEM_FUN(A,int,f) -
-expands by default to -
- -- --const_mem_fun<A,int,&A::f> -
-but resolves to -
- -- --const_mem_fun_explicit<A,int,int (A::*)()const,&A::f> -
-in MSVC++ 6.0. Non-const
member functions are covered by
-mem_fun_explicit
-and the macro
-BOOST_MULTI_INDEX_MEM_FUN
.
-
composite_key
in compilers
-without partial template specialization
-When using composite_key
s, lookup is performed by passing
-tuples of values: this ability is achieved by suitably specializing
-the class templates std::equal_to
, std::less
,
-std::greater
and boost::hash
for
-
-composite_key_result
instantiations so that they
-provide the appropriate overloads accepting tuples --and in the case
-of std::less
and std::greater
, also partial
-tuples where only the first components are specified.
-
-In those compilers that do not support partial template specialization,
-these specializations cannot be provided, and so
-tuple-based lookup is not available by default. In this case,
-multi_index_container
instantiations using composite keys
-will work as expected, both for ordered and hashed indices,
-except that lookup operations will not accept tuples as an argument.
-For ordered indices, the most obvious workaround
-to this deficiency involves explicitly specifying the comparison
-predicate with
-composite_key_compare
;
-in the case of hashed indices we can use the analogous
-composite_key_equal_to
-and
-composite_key_hash
.
-This substitution is tedious as the elementary components for all the constituent key extractors must
-be explicitly typed. For this reason, Boost.MultiIndex provides the following replacement
-class templates
-
composite_key_result_equal_to
,composite_key_result_less
,composite_key_result_greater
andcomposite_key_result_hash
,std::equal_to
, std::less
,
-std::greater
and boost::hash
for composite_key_result
s.
-They can be used as follows:
-
-
-- --typedef composite_key< - phonebook_entry, - member<phonebook_entry,std::string,&phonebook_entry::family_name>, - member<phonebook_entry,std::string,&phonebook_entry::given_name> -> ckey_t; - -typedef multi_index_container< - phonebook_entry, - indexed_by< - ordered_non_unique< - ckey_t, - // composite_key_result_less plays the role of - // std::less<ckey_t::result_type> - composite_key_result_less<ckey_t::result_type> - >, - ordered_unique< - member<phonebook_entry,std::string,&phonebook_entry::phone_number> - > - > -> phonebook; -
The types generated on the instantiations of multi_index_container
s
@@ -942,7 +94,7 @@ names: these techniques have also the beneficial side effect that resulting erro
messages are more readable.
The class templates indexed_by
,
@@ -985,7 +137,7 @@ of symbol names.
Consider a typical instantiation of multi_index_container
:
@@ -1098,6 +250,114 @@ Type hiding techniques can also be applied to composite_key
intanti
which often contribute a great deal to symbol name lengths.
+Boost.MultiIndex support for legacy compilers is not actively kept, so if you happen +to work with an old environment you might need to use a former version of the library. +A table is provided of some legacy compilers along with the latest version of +Boost.MultiIndex known to work for them (frequently with limitations as explained +in the corresponding compiler specifics section.) If you successfully try one of those +with newer versions of Boost.MultiIndex than stated here, please report back so that +the information can be udated. +
+ ++
Compiler | +Latest known compatible version |
+ Date | +
---|---|---|
Borland C++ Builder 6.4 through 2006, CodeGear C++Builder 2010 | +Never worked with Boost.MultiIndex | ++ |
Comeau C/C++ 4.3.10.1 for Windows (VC++ 9.0 backend) | +Boost 1.38 | +February 2009 | +
Compaq C++ 6.5-042 through 7.1-006 for Tru64 UNIX | +Boost 1.38 | +February 2009 | +
GCC 3.2 through 3.4 | +Boost 1.41 | +November 2009 | +
HP aC++ A.06.12 through A.06.17 for HP-UX IA64 | +Boost 1.38 | +February 2009 | +
HP aC++ A.03.80 through A.03.85 for HP-UX PA-RISC | +Boost 1.38 | +February 2009 | +
IBM VisualAge C++ V6.0 for AIX | +Boost 1.33.1 | +December 2006 | +
IBM XL C/C++ V9.0 through V10.1 for AIX | +Boost 1.41 | +November 2009 | +
Intel C++ Compiler for Linux 8.1 through 11.1 | +Boost 1.41 | +November 2009 | +
Intel C++ Compiler for Mac OS 9.1 through 11.0 | +Boost 1.41 | +November 2009 | +
Intel C++ Compiler for Windows 32-bit 8.0 through 11.1 | +Boost 1.41 | +November 2009 | +
Intel C++ Compiler for Windows 64-bit 10.0 through 11.11 | +Boost 1.41 | +November 2009 | +
Metrowerks CodeWarrior 8.3 | +Boost 1.36 | +August 2008 | +
Metrowerks CodeWarrior 9 through 9.5 | +Boost 1.34.1 | +July 2007 | +
Microsoft Visual C++ 6.0 Service Pack 5 | +Boost 1.36 | +August 2008 | +
Microsoft Visual C++ 7.0 | +Boost 1.35 | +March 2008 | +
Sun Studio 10 through 12 Update 1for Solaris | +Boost 1.41 | +November 2009 | +
Revised October 14th 2009
+Revised July 7th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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
diff --git a/doc/future_work.html b/doc/future_work.html
index b0e5a04..bf4046d 100644
--- a/doc/future_work.html
+++ b/doc/future_work.html
@@ -42,7 +42,6 @@ principle driving the current internal design of multi_index_containerConstraints
Ranked indices
@@ -187,31 +186,6 @@ a careful study when designing the interface of a potential
indexed map.
-Andrei Alexandrescu introduced a technique for simulating move
-constructors called Mojo (see his article in C/C++ User Journal
-
-"Generic<Programming>: Move Constructors".) Move semantics
-alleviates the computational load involved in the creation and copying
-of temporary objects, specially for heavy classes as
-multi_index_container
s 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_container
s. Without support
-for move semantics, this scheme is impractical and less elegant syntaxes
-should be resorted to.
-
Revised July 5th 2007
+Revised July 6th 2013
-© Copyright 2003-2007 Joaquín M López Muñoz. +
© Copyright 2003-2013 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
diff --git a/doc/reference/hash_indices.html b/doc/reference/hash_indices.html
index a6d902a..b8e1985 100644
--- a/doc/reference/hash_indices.html
+++ b/doc/reference/hash_indices.html
@@ -99,6 +99,8 @@ their associated hashed index classes.
"boost/multi_index/hashed_index.hpp"
+#include <initializer_list> + namespace boost{ namespace multi_index{ @@ -170,11 +172,8 @@ explanations on their acceptable type values.A hashed index provides fast retrieval of elements of a
multi_index_container
-through hashing tecnhiques. The interface and semantics of hashed indices are modeled according -to the proposal for unordered associative containers given in the C++ -Proposed -Draft Tecnhical Report on Standard Library Extensions, also known as TR1. A hashed -index is particularized according to a given +through hashing tecnhiques. +A hashed index is particularized according to a givenKey Extractor
that retrieves keys from elements ofmulti_index_container
, aHash
function object which returns hash values for the keys and a binary predicatePred
@@ -190,13 +189,14 @@ 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_set
s. Validity of iterators and references to +Except where noted or if the corresponding interface does not exist, hashed indices +(both unique and non-unique) satisfy the C++ requirements for undordered associative +containers at [unord.req] (supporting unique and equivalent keys, respectively.) +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. +are actually stronger than required by the standard. We only provide descriptions of +those types and operations that do not exactly conform to or are not mandated by the standard +requirements.+@@ -236,6 +236,7 @@ do not exactly conform to the requirements for unordered associative containers. // construct/destroy/copy: index class name& operator=(const index class name& x); + index class name& operator=(std::initializer_list<value_type> list); allocator_type get_allocator()const; @@ -259,16 +260,25 @@ do not exactly conform to the requirements for unordered associative containers. // modifiers: + + template<typename... Args> + std::pair<iterator,bool> emplace(Args&&... args); + template<typename... Args> + iterator emplace_hint(iterator position,Args&&... args); std::pair<iterator,bool> insert(const value_type& x); + std::pair<iterator,bool> insert(value_type&& x); iterator insert(iterator position,const value_type& x); + iterator insert(iterator position,value_type&& x); template<typename InputIterator> void insert(InputIterator first,InputIterator last); + void insert(std::initializer_list<value_type> list); 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); + bool replace(iterator position,value_type&& x); template<typename Modifier> bool modify(iterator position,Modifier mod); template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back); @@ -397,13 +407,11 @@ following types: which determines the mechanism for extracting a key fromValue
, must be a model ofKey Extractor
fromValue
.Hash
is a -Unary Function
+CopyConstructible
unary function object taking a single argument of typeKeyFromValue::result_type
and returning a value of typestd::size_t
in the range[0, std::numeric_limits<std::size_t>::max())
. -Pred
is a - -Binary Predicate
inducing an equivalence relation +Pred
is aCopyConstructible
binary predicate inducing an equivalence relation on elements ofKeyFromValue::result_type
. It is required that theHash
object return the same value for keys equivalent underPred
. @@ -425,9 +433,7 @@ local_iterator
const_local_iterator-These types are models of -Forward -Iterator
. +These types are forward iterators.Constructors, copy and assignment
@@ -451,6 +457,18 @@ objects to which*this
andx
belong, respectively.
Returns:*this
.
index class name& operator=(std::initializer_list<value_type> list);
+ ++Effects: +++where+a=list; +a
is themulti_index_container
+object to which*this
belongs.
+Returns:*this
.
+Iterators
iterator iterator_to(const value_type& x);
@@ -465,9 +483,64 @@ const_iterator iterator_to(const value_type& x)const;Modifiers
-std::pair<iterator,bool> insert(const value_type& x);
+template<typename... Args>
+std::pair<iterator,bool> emplace(Args&&... args);+Requires:+ +value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
into themulti_index_container
to which +the index belongs if ++
+Returns: The return value is a pair- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.p
.p.second
+istrue
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.
+template<typename... Args>
+ +
+iterator emplace_hint(iterator position, Args&&... args);+Requires:+ +value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
. +position
is a valid iterator of the index.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
into themulti_index_container
to which +the index belongs if ++
+- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.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.
+std::pair<iterator,bool> insert(const value_type& x);
+std::pair<iterator,bool> insert(value_type&& x);
+ ++Requires (first version):-value_type
isCopyInsertable
+intomulti_index_container
.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
.
Effects: Insertsx
into themulti_index_container
to which the index belongs if@@ -485,10 +558,16 @@ one element can be causing insertion not to be allowed.
Exception safety: Strong.
iterator insert(iterator position,const value_type& x);
+iterator insert(iterator position,const value_type& x);
+iterator insert(iterator position,value_type&& x);
-Requires:position
is a valid iterator of the index.
+Requires (first version):value_type
isCopyInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
Effects: Insertsx
into themulti_index_container
to which the index belongs if@@ -511,24 +590,38 @@ allowed.
If the rearrangement fails, the element is erased.
void insert(InputIterator first,InputIterator last);-Requires:+InputIterator
is a model of - -Input Iterator
over elements of type -value_type
or a type convertible tovalue_type
. +Requires:InputIterator
is an input iterator. +value_type
is +EmplaceConstructible
into +multi_index_container
from*first
.first
andlast
are not iterators into any index of themulti_index_container
to which this index belongs.last
is reachable fromfirst
.
Effects: --Complexity:-iterator hint=end(); -while(first!=last)hint=insert(hint,*first++); -O(m*H(n+m))
, where +For each element of [first
,last
), in this +order, inserts it into themulti_index_container
+to which this index belongs if ++
+Complexity:- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.O(m*I(n+m))
, wherem
is the number of elements in [first
,last
).
Exception safety: Basic.
void insert(std::initializer_list<value_type> list);
+ ++Effects: ++++insert(list.begin(),list.end()) +iterator erase(iterator position);
@@ -565,11 +658,14 @@ the number of elements in [-first
,last
).
Exception safety:nothrow
.
bool replace(iterator position,const value_type& x);
+bool replace(iterator position,const value_type& x);
+bool replace(iterator position,value_type&& x);
-Requires:position
is a valid dereferenceable iterator -of the index.
+Requires (first version):value_type
isCopyAssignable
. +position
is a valid dereferenceable iterator of the index.
+Requires (second version):value_type
isMoveAssignable
. +position
is a valid dereferenceable iterator of the index.
Effects: Assigns the valuex
to the element pointed to byposition
into themulti_index_container
to which the index belongs if, for the valuex
@@ -594,9 +690,8 @@ 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 +Requires:mod
is a unary function object +accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Callsmod(e)
wheree
is the element @@ -610,8 +705,8 @@ all the indices of themulti_index_container
. Rearrangement is succ
Postconditions: Validity ofposition
is preserved if the -operation succeeds. If the key of the modified value is equivalent to that of the original -value, the position of the element does not change.
+operation succeeds. If the key of the modified value is equivalent to that of the +original value, the position of the element does not change.
Returns:true
if the operation succeeded,false
otherwise.
Complexity:O(M(n))
.
@@ -624,9 +719,8 @@ the element pointed to byposition
is erased. bool modify(iterator position,Modifier mod,Rollback back);-Requires:Modifier
andRollback
are models of - -Unary Function
accepting arguments of type +Requires:mod
andback
are unary function +objects accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(e)
,back(e)
, wheree
is the element @@ -644,8 +738,9 @@ all the indices of themulti_index_container
. Rearrangement is succ If the rearrangement fails,back(e)
is invoked and the element is kept at its original position in all indices.
Postconditions: Validity ofposition
is preserved except if -the element is erased under the conditions described below. If the key of the modified value -is equivalent to that of the original value, the position of the element does not change.
+the element is erased under the conditions described below. +If the key of the modified value is equivalent to that of the +original value, the position of the element does not change.
Returns:true
if the operation succeeded,false
otherwise.
Complexity:O(M(n))
.
@@ -662,9 +757,8 @@ is rethrown.Requires:key_from_value
is a read/writeKey Extractor
-fromvalue_type
.Modifier
is a model of - -Unary Function
accepting arguments of type +fromvalue_type
.mod
is a +unary function object accepting arguments of typekey_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Equivalent tomodify(position,mod')
, @@ -679,14 +773,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);Requires:key_from_value
is a read/writeKey Extractor
-fromvalue_type
.Modifier
andRollback
-are models of -Unary Function
accepting arguments of type +fromvalue_type
.mod
andback
+are unary function objects accepting arguments of typekey_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(k)
,back(k)
, wherek
is the key of the element -pointed to byposition
, restores k to its original state.
+pointed to byposition
, restoresk
to its original state.
Effects: Equivalent tomodify(position,mod',back')
, withmod'
andback
defined in such a way thatmod'(x)
is the same asmod(key(x))
and @@ -713,7 +806,7 @@ the index.
Hashed indices provide the full lookup functionality required by -unordered associative containers, namely
find
, +[unord.req], namelyfind
,count
, andequal_range
. Additionally, these member functions are templatized to allow for non-standard arguments, so extending the types of search operations allowed. @@ -724,9 +817,8 @@ functions is defined by the following concept.Consider a pair (
Hash
,Pred
) whereHash
is a hash functor over values of typeKey
-andPred
is a - -Binary Predicate
inducing an equivalence relation +andPred
is a binary predicate +inducing an equivalence relation onKey
, with the additional constraint that equivalent keys have the same hash value. A triplet of types (CompatibleKey
,CompatibleHash
, @@ -735,13 +827,9 @@ of (Hash
,Pred
) if
- -
CompatibleHash
is a hash functor on values of typeCompatibleKey
,CompatiblePred
is a - -Binary Predicate
over (Key
, +- -
CompatiblePred
is a binary predicate over (Key
,CompatibleKey
),CompatiblePred
is a - -Binary Predicate
over (CompatibleKey
, +CompatiblePred
is a binary predicate over (CompatibleKey
,Key
),- if
c_eq(ck,k1)
thenc_eq(k1,ck)
,- if
c_eq(ck,k1)
andeq(k1,k2)
then @@ -981,9 +1069,9 @@ Sequenced indices
-Revised July 21st 2009
+Revised July 6th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/indices.html b/doc/reference/indices.html index d28c9c7..75995f9 100644 --- a/doc/reference/indices.html +++ b/doc/reference/indices.html @@ -105,12 +105,13 @@ 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
@@ -120,11 +121,9 @@ they are wrapped as appropriate by each index (for instance, ordered indices provide a set-like suite of insertion member functions, whereas sequenced and random access indices havemulti_index_container
are not mutable. To overcome this restriction, indices expose member functions -for updating and modifying, which allow for the mutation of elements +for replacement and modification 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
andstd:multiset
, and these containers +impact the interfaces of ordered and hashed indices, as they are based upon +those of associative and unordered associative containers, respectively, +and these containers also have non-mutable elements; but it may come as a surprise when dealing -with sequenced indices, which are designed upon the functionality provided +with sequenced and random access indices, which are designed upon the functionality provided bystd::list
.push_back
andpush_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
.) +the interface of indices, although each index provided satisfy the C++ requirements for +standard containers to the maximum extent possible within the conceptual framework +of the library.Complexity signature
@@ -333,10 +332,7 @@ reference. The following concept is used by the rearrange facilities of non key-based indices. Given an indexi
of typeIndex
, a view ofi
is any range [first
,last
) -wherefirst
andlast
are objects of a type -Iterator
modelling - -Input Iterator
such that +wherefirst
andlast
are input iterators such that
- the associated value type of
Iterator
is convertible toconst Index::value_type&
@@ -383,9 +379,9 @@ Ordered indices
-Revised July 21st 2009
+Revised July 7th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/key_extraction.html b/doc/reference/key_extraction.html index 11bac12..103bd1f 100644 --- a/doc/reference/key_extraction.html +++ b/doc/reference/key_extraction.html @@ -57,10 +57,8 @@ Compiler specifics
- Class template
const_mem_fun
- Class template
-mem_fun
- Class template
-const_mem_fun_explicit
- Class template
-mem_fun_explicit
- Macro
-BOOST_MULTI_INDEX_CONST_MEM_FUN
- Macro
+BOOST_MULTI_INDEX_MEM_FUN
- Class templates
+const_mem_fun_explicit
andmem_fun_explicit
- Macros
BOOST_MULTI_INDEX_CONST_MEM_FUN
andBOOST_MULTI_INDEX_MEM_FUN
- Header @@ -108,7 +106,7 @@ Compiler specifics Key extraction classes are used by key-based indices to obtain the indexing keys from the elements of a
multi_index_container
. -AnAssignable
+ACopyConstructible
andCopyAssignable
classKeyFromValue
is said to be a key extractor from a typeType
if@@ -144,16 +142,8 @@ Boost.MultiIndex provides six general-purpose key extractors:
const_mem_fun
,mem_fun
,- -
global_fun
and- +
composite_key
,- -plus replacements for some of them: -
composite_key
.-
-that workaround some deficiencies in the support for non-type template parameters -by certain compilers.- -
member_offset
,- -
const_mem_fun_explicit
and- -
mem_fun_explicit
,Chained pointers
@@ -310,7 +300,7 @@ type toType
.
struct member; template<class Class,typename Type,std::size_t OffsetOfMember> -struct member_offset; +struct member_offset; // deprecated #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) implementation defined @@ -399,53 +389,10 @@ type toType
.
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,- MSVC++ 6.0 (see - Microsoft - Knowledge Base article #249045),
-- MSVC++ 7.0 (not officially confirmed by Microsoft),
-- Intel C++ 7.0/7.1 for Windows (support issue #207321),
-- VisualAge 6.0 for AIX (internal defect #288539.)
-member_offset
provides an -alternative tomember
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; - - // only provided if const ChainedPtr& is not convertible to const Class& - 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 -asmember_offset<A,int,offsetof(A,x)>
. +member_offset
was designed to overcome limitations of some legacy +compilers and its use is currently deprecated. Refer to a +former version +of Boost.MultiIndex for further information.Macro
@@ -455,27 +402,10 @@ asBOOST_MULTI_INDEX_MEMBER
member_offset<A,int,offsetof(A,x)>
.
-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.
+This macro was designed as a portability mechanism for legacy compilers where member
+could not be supported.
+As such it is no longer needed in modern environments, though some users might still prefer it
+to plain member
because it provides a slightly more concise syntax.
x
.
Returns: (x.get().*PtrToMemberFunction)()
.
-const_mem_fun_explicit
const_mem_fun_explicit
and 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.
+These extractors were provided as a workaround for MSVC++ 6.0 and are now deprecated.
+Refer to a
+former version
+of Boost.MultiIndex for further information.
- --template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct const_mem_fun_explicit -{ - typedef typename remove_reference<Type>::type result_type; - - // only provided if const ChainedPtr& is not convertible to const Class& - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - - Type operator()(const Class& x)const; - Type operator()(const reference_wrapper<const Class>& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
-const_mem_fun_explicit
provides the very same functionality as
-its const_mem_fun
analogous instantiation. For example, given the type
-
- --struct A -{ - int f()const; -}; -
-the extractor const_mem_fun<A,int,&A::f>
can be replaced by
-const_mem_fun_explicit<A,int,int (A::*)()const,&A::f>
.
-
mem_fun_explicit
-For analogy with const_mem_fun_explicit
,
-a variation of mem_fun
is provided accepting
-an additional parameter with the type of the pointer to non-constant member function
-used for extraction.
-
- --template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction -> -struct mem_fun_explicit -{ - typedef typename remove_reference<Type>::type result_type; - - // only provided if ChainedPtr& is not convertible to Class& - template<typename ChainedPtr> Type operator()(const ChainedPtr& x)const; - - Type operator()(Class& x)const; - Type operator()(const reference_wrapper<Class>& x)const; -}; -
BOOST_MULTI_INDEX_CONST_MEM_FUN
BOOST_MULTI_INDEX_CONST_MEM_FUN
+and BOOST_MULTI_INDEX_MEM_FUN
- -BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) -
-Use this macro when writing cross-platform code selectively using
-const_mem_fun_explicit
in place of const_mem_fun
for
-compilers not supporting the latter. In the usual cases, the macro expands to
-
- --::boost::multi_index::const_mem_fun<Class,Type,&Class::MemberFunName> -
-but it resolves to -
- -- --::boost::multi_index::const_mem_fun_explicit< - Class,Type,Type (Class::*)()const,&Class::MemberFunName -> -
-for MSVC++ 6.0 or lower. -
- - -BOOST_MULTI_INDEX_MEM_FUN
BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName)
-By default, the macro expands to -
- -- --::boost::multi_index::mem_fun<Class,Type,&Class::MemberFunName> -
-but it resolves to -
- -- --::boost::multi_index::mem_fun_explicit< - Class,Type,Type (Class::*)(),&Class::MemberFunName -> -
-for MSVC++ 6.0 or lower.
+Portability macros for usage of const_mem_fun
and mem_fun
.
+Although no longer needed in modern compilers, some users might still decide to
+resort to them as they provide a slightly more concise syntax.
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
.
+composite_key_result
is not guaranteed to be
+DefaultConstructible
or CopyAssignable
.
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
@@ -1351,19 +1172,14 @@ collection of elementary equality predicates.
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
+binary predicates stored by composite_key_equal_to
. Each of these predicates
+must be CopyConstructible
and CopyAssignable
. 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
.
+CopyConstructible
and CopyAssignable
.
+It is also DefaultConstructible
+if each Predi
is DefaultConstructible
in its turn.
@@ -1451,66 +1267,18 @@ the result is determined to be false
.
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
.
+Deprecated. Use std::equal_to<CompositeKeyResult>
instead.
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>
.
+std::equal_to<CompositeKeyResult>
, with CompositeKeyResult
+an instantiation of composite_key_result
,
+behaves as a particularization of
+composite_key_equal_to
where all the comparison predicates supplied
+are instantiations of std::equal_to
.
+@@ -1544,6 +1312,27 @@ and functionality ascomposite_key_result_equal_to<CompositeKeyResult>< } // namespace std
+CompositeKeyResult
must be an instantiation of
+composite_key_result
for some type
+composite_key<KeyFromValue0,...,KeyFromValuen>
.
+std::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
+DefaultConstructible
. std::equal_to<CompositeKeyResult>
+is DefaultConstructible
, CopyConstructible
and
+CopyAssignable
.
+
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
+binary predicates stored by composite_key_compare
. Each of these predicates must be
+CopyConstructible
and CopyAssignable
. 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
.
+CopyConstructible
and CopyAssignable
.
It is also
-
-Default Constructible
-if each Comparei
is
-
-Default Constructible
.
+DefaultConstructible
+if each Comparei
is DefaultConstructible
in its turn.
@@ -1728,139 +1513,24 @@ bool operator()(
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; - - template<typename CompositeKey,typename Value> - bool operator()( - const composite_key_result<CompositeKey>& x,const Value& y)const; - - template<typename Value,typename CompositeKey> - bool operator()( - const Value& 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
.
+Deprecated. Use std::less<CompositeKeyResult>
instead.
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; - - template<typename CompositeKey,typename Value> - bool operator()( - const composite_key_result<CompositeKey>& x,const Value& y)const; - - template<typename Value,typename CompositeKey> - bool operator()( - const Value& 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
.
+Deprecated. Use std::greater<CompositeKeyResult>
instead.
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>
.
+std::less<CompositeKeyResult>
, with CompositeKeyResult
+an instantiation of composite_key_result
, behaves as a particularization of
+composite_key_compare
where all the comparison predicates supplied are
+instantiations of std::less
.
+@@ -1904,15 +1574,38 @@ and functionality ascomposite_key_result_less<CompositeKeyResult>} // namespace std
+CompositeKeyResult
must be an instantiation of
+composite_key_result
for some type
+composite_key<KeyFromValue0,...,KeyFromValuen>
.
+std::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
+DefaultConstructible
. std::less<CompositeKeyResult>
+is CopyConstructible
, CopyConstructible
+and CopyAssignable
.
+
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>
.
+std::greater<CompositeKeyResult>
, with CompositeKeyResult
+an instantiation of composite_key_result
, behaves as a particularization of
+composite_key_compare
where all the comparison predicates supplied
+are instantiations of std::greater
.
+namespace std{ @@ -1954,6 +1647,27 @@ and functionality ascomposite_key_result_greater<CompositeKeyResult> } // namespace std
+CompositeKeyResult
must be an instantiation of
+composite_key_result
for some type
+composite_key<KeyFromValue0,...,KeyFromValuen>
.
+std::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
+DefaultConstructible
. std::greater<CompositeKeyResult>
+is CopyConstructible
, CopyConstructible
+and CopyAssignable
.
+
-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
+Hash0
, ... , Hashn
are the types of the hash unary function objects
+stored by composite_key_hash
. Each of these objects
+must be CopyConstructible
and CopyAssignable
+and return 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
.
+CopyConstructible
and CopyAssignable
.
+It is also DefaultConstructible
+if each Hashi
is DefaultConstructible
in its turn.
N=length(x)-1
.
composite_key_result_hash
-composite_key_result_hash
acts as a particularization of
-composite_key_hash
where all the hash functors supplied
-are instantiations of
-boost::hash
.
-
- --template<typename CompositeKeyResult> -struct composite_key_result_hash -{ - typedef CompositeKeyResult argument_type; - typedef std::size_t result_type; - - template<typename CompositeKey> - std::size_t operator()( - const composite_key_result<CompositeKey>& x)const; - - template<typename Value0,...,typename Valuen> - std::size_t operator()( - const tuple<Value0,...,Valuen>& x)const; -}; -
-CompositeKeyResult
must be an instantiation of
-composite_key_result
for some type
-composite_key<KeyFromValue0,...,KeyFromValuen>
.
-composite_key_result_hash<CompositeKeyResult>::operator()
is
-then equivalent to
-composite_key_hash<Hash0,...,Hashn>::operator()
, taking
-
-- - -Hashi = boost::hash<KeyFromValuei::result_type>
for all -i = 0,...,n
. -
-In addition to the requirements on Hashi
imposed by
-composite_key_hash
, each of these types must be
-
-Default Constructible
. composite_key_result_hash
-is
-Default Constructible
and
-Assignable
.
+Deprecated. Use boost::hash<CompositeKeyResult>
instead.
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>
.
+boost::hash<CompositeKeyResult>
, with CompositeKeyResult
+an instantiation of composite_key_result
, behaves as a particularization of
+composite_key_hash
where all the hash functors supplied
+are instantiations of
+boost::hash
.
+@@ -2158,6 +1825,27 @@ and functionality ascomposite_key_result_hash<CompositeKeyResult>} // namespace boost
+CompositeKeyResult
must be an instantiation of
+composite_key_result
for some type
+composite_key<KeyFromValue0,...,KeyFromValuen>
.
+boost::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
+DefaultConstructible
. boost::hash<CompositeKeyResult>
is
+DefaultConstructible
, CopyConstructible
+and CopyAssignable
.
+
composite_key_result
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
+Comparei
induces 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_compare
induces 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
@@ -2263,9 +1948,9 @@ Compiler specifics
-
Revised June 25th 2008
+Revised July 7th 2013
-© Copyright 2003-2008 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/multi_index_container.html b/doc/reference/multi_index_container.html index 3556bed..e4e294f 100644 --- a/doc/reference/multi_index_container.html +++ b/doc/reference/multi_index_container.html @@ -88,6 +88,8 @@ synopsis
+#include <initializer_list> + namespace boost{ namespace multi_index{ @@ -269,7 +271,6 @@ operators and functions associated with the index (vg. comparison and struct nth_index {typedef implementation defined type;}; template<typename Tag> struct index {typedef implementation defined type;}; - template<int N> template<int N> struct nth_index_iterator // deprecated @@ -295,13 +296,23 @@ operators and functions associated with the index (vg. comparison and InputIterator first,InputIterator last, const ctor_args_list& args_list=ctor_args_list(), const allocator_type& al=allocator_type()); + multi_index_container( + std::initializer_list<Value> list, + 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>&& x); ~multi_index_container(); multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( const multi_index_container<Value,IndexSpecifierList,Allocator>& x); + multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( + multi_index_container<Value,IndexSpecifierList,Allocator>&& x); + multi_index_container<Value,IndexSpecifierList,Allocator>& operator=( + std::initializer_list<Value> list) allocator_type get_allocator()const; @@ -507,9 +518,8 @@ scheme outlined in the
multi_index_container
is instantiated with the following types:-
Value
is the -Assignable
- type of the elements contained. +Value
is the type of the elements contained.Value
must be +Erasable
frommulti_index_container
.IndexSpecifierList
specifies the indices that themulti_index_container
is composed of. It must be a non-empty @@ -522,17 +532,15 @@ scheme outlined in the MPL sequence can be used.- s
Allocator
must be an allocator ofValue
objects - satisfying the associated C++ requirements at [lib.allocator.requirements]. + satisfying the associated C++ requirements at [allocator.requirements]. The following relaxations to the standard requirements are allowed:
- Non-equal allocator instances are supported: swapping two non-equal instances must not throw any exception. -
+- For every type
T
, the typeAllocator::rebind<T>::other::pointer
can be any - kind of -Random - Access Iterator
, provided that it is explicitly constructible from + kind of random access iterator, provided that it is explicitly constructible from the literal0
(standing here as the null pointer) or from anyp
of typeT*
pointing into an area allocated by some instance ofAllocator
or some other allocator type rebound @@ -564,9 +572,8 @@ implicit conversion from toconst ctor_args_list&
. This type is used for providing the construction arguments of the indices of themulti_index_container
.ctor_args_list
is -Default -Constructible
, provided that allctor_args
types -involved are default constructible. +DefaultConstructible
, provided that allctor_args
types +involved areDefaultConstructible
.
index_specifier_type_list
@@ -685,14 +692,14 @@ specified allocator and the default value of ctor_args_list
.template<typename InputIterator>
multi_index_container(
InputIterator first,InputIterator last,
- const ctor_args_list& comp=ctor_args_list(),
+ const ctor_args_list& args_list=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 toValue
. +Requires:InputIterator
is an input iterator. +Value
is +EmplaceConstructible
intomulti_index_container
+from*first
.last
is reachable fromfirst
.
Effects: Constructs and emptymulti_index_container
using the specified argument list and allocator and fills it with @@ -703,18 +710,43 @@ on the acceptance by all the indices of themulti_index_container
.< the number of elements in [first
,last
).
multi_index_container(
+ std::initializer_list<Value> list,
+ const ctor_args_list& args_list=ctor_args_list(),
+ const allocator_type& al=allocator_type());
+
+
+Effects: Equivalent to
+multi_index_container(list.begin(),list.end(),args_list,al)
.
+
+
multi_index_container(
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);
+Requires:+Value
isCopyInsertable
into +multi_index_container
.
Effects: Constructs a copy ofx
, copying its -elements as well as its internal objects (key extractors, comparison objects, -allocator.)
+elements as well as its internal objects (those specified +inctor_args_list
and the allocator.)
Postconditions:*this==x
. The order on every index of themulti_index_container
is preserved as well.
Complexity:O(x.size()*log(x.size()) + C(x.size()))
.
multi_index_container(
+ multi_index_container<Value,IndexSpecifierList,Allocator>&& x);
+
++Effects: Constructs a+multi_index_container
by moving the +elements ofx
and copying its internal objects (those specified +inctor_args_list
and the allocator.)
+Postconditions: Ifx==y
just +before the movement,*this==y
. The order on every index +of themulti_index_container
is preserved as well.
+Complexity: Constant. +
~multi_index_container()
Effects: Destroys themulti_index_container
and all the elements @@ -726,7 +758,9 @@ contained. The order in which the elements are destroyed is not specified.
const multi_index_container<Value,IndexSpecifierList,Allocator>& x);-Replaces the elements and internal objects of the+multi_index_container
+Requires:Value
isCopyInsertable
into +multi_index_container
.
+Effects: Replaces the elements and internal objects of themulti_index_container
with copies fromx
.
Postconditions:*this==x
. The order on every index of themulti_index_container
is preserved as well.
@@ -737,6 +771,39 @@ C(x.size())).
of the types ofctor_args_list
do not throw.multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
+ +
+ multi_index_container<Value,IndexSpecifierList,Allocator>&& x);+Effects: Replaces the elements of+ +multi_index_container
+with those ofx
and its internal objects with copies from the +corresponding objects inx
.
+Postconditions: Ifx==y
just +before the movement,*this==y
. The order on every index +of themulti_index_container
is preserved as well.
+Returns:*this
.
+Complexity:O(n)
.
+Exception safety: Strong, provided the copy and assignment operations +of the types ofctor_args_list
do not throw. +multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
+ +
+ std::initializer_list<Value> list);+Requires:+Value
isCopyInsertable
into +multi_index_container
.
+Effects: Replaces the elements themulti_index_container
+with copies of the elements oflist
, inserted in the specified order. +Insertion of each element may or may not succeed depending +on the acceptance by all the indices of themulti_index_container
.
+Returns:*this
.
+Complexity:O(n + I(m))
, wherem
is the +number of elements oflist
.
+Exception safety: Strong, provided the copy and assignment operations +of the types ofctor_args_list
do not throw. +allocator_type get_allocator()const;
@@ -883,8 +950,7 @@ these, the following concepts are used. A typeT
is serializable archive (XML archive) and later retrieved from an input archive (XML archive) associated to the same storage. Ifx'
of typeT
is loaded from the serialization information saved from another objectx
, we say that -x'
is a restored copy ofx
. Given a -Binary Predicate
+x'
is a restored copy ofx
. Given a binary predicatePred
over (T
,T
), and objectsp
andq
of typePred
, we say thatq
is serialization-compatible withp
if @@ -930,9 +996,9 @@ Index reference
-Revised November 6th 2008
+Revised July 3rd 2013
-© Copyright 2003-2008 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/ord_indices.html b/doc/reference/ord_indices.html index bb85dd1..de74590 100644 --- a/doc/reference/ord_indices.html +++ b/doc/reference/ord_indices.html @@ -97,6 +97,8 @@ their associated ordered index classes.
"boost/multi_index/ordered_index.hpp"
synopsis+#include <initializer_list> + namespace boost{ namespace multi_index{ @@ -190,15 +192,13 @@ 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 asstd::set
s -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. +Except where noted or if the corresponding interface does not exist, +ordered indices (both unique and non-unique) satisfy the C++ requirements +for associative containers at [associative.reqmts] +(supporting unique and equivalent keys, respectively.) +Accordingly, validity of iterators and references to elements is +preserved. We only provide descriptions of those types and operations that +do not exactly conform to or are not mandated by the standard requirements.+@@ -241,6 +241,7 @@ requirements for these types of containers. // construct/copy/destroy: index class name& operator=(const index class name& x); + index class name& operator=(std::initializer_list<value_type> list); allocator_type get_allocator()const; @@ -270,16 +271,24 @@ requirements for these types of containers. // modifiers: + template<typename... Args> + std::pair<iterator,bool> emplace(Args&&... args); + template <typename... Args> + iterator emplace_hint(iterator position,Args&&... args); std::pair<iterator,bool> insert(const value_type& x); + std::pair<iterator,bool> insert(value_type&& x); iterator insert(iterator position,const value_type& x); + iterator insert(iterator position,value_type&& x); template<typename InputIterator> void insert(InputIterator first,InputIterator last); + void insert(std::initializer_list<value_type> list); 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); + bool replace(iterator position,value_type&& x); template<typename Modifier> bool modify(iterator position,Modifier mod); template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back); @@ -436,9 +445,8 @@ following types: which determines the mechanism for extracting a key fromValue
, must be a model ofKey Extractor
fromValue
.Compare
is a - -Strict Weak Ordering
on elements of -KeyFromValue::result_type
. +CopyConstructible
binary predicate inducing a strict weak order +on elements ofKeyFromValue::result_type
.Constructors, copy and assignment
@@ -461,6 +469,18 @@ objects to which*this
andx
belong, respectively.
Returns:*this
.
index class name& operator=(std::initializer_list<value_type> list);
+ ++Effects: +++where+a=list; +a
is themulti_index_container
+object to which*this
belongs.
+Returns:*this
.
+Iterators
iterator iterator_to(const value_type& x);
@@ -475,9 +495,65 @@ const_iterator iterator_to(const value_type& x)const;Modifiers
-std::pair<iterator,bool> insert(const value_type& x);
+template<typename... Args>
+std::pair<iterator,bool> emplace(Args&&... args);+Requires:+ +value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
into themulti_index_container
to which +the index belongs if ++
+Returns: The return value is a pair- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.p
.p.second
+istrue
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.
+template<typename... Args>
+ +
+iterator emplace_hint(iterator position, Args&&... args);+Requires:+ +value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
. +position
is a valid iterator of the index.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
into themulti_index_container
to which +the index belongs if ++
+- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.position
is used as a hint to improve the efficiency of the +operation. If succesful, insertion happens as close as possible to the +location just prior toposition
.
+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.
+std::pair<iterator,bool> insert(const value_type& x);
+std::pair<iterator,bool> insert(value_type&& x);
+ ++Requires (first version):-value_type
isCopyInsertable
+intomulti_index_container
.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
.
Effects: Insertsx
into themulti_index_container
to which the index belongs if@@ -495,10 +571,16 @@ one element can be causing insertion not to be allowed.
Exception safety: Strong.
iterator insert(iterator position,const value_type& x);
+iterator insert(iterator position,const value_type& x);
+iterator insert(iterator position,value_type&& x);
-Requires:position
is a valid iterator of the index.
+Requires (first version):value_type
isCopyInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
Effects: Insertsx
into themulti_index_container
to which the index belongs if@@ -522,24 +604,37 @@ allowed.
void insert(InputIterator first,InputIterator last);-Requires:+InputIterator
is a model of - -Input Iterator
over elements of type -value_type
or a type convertible tovalue_type
. +Requires:InputIterator
is an input iterator. +value_type
isEmplaceConstructible
into +multi_index_container
from*first
.first
andlast
are not iterators into any index of themulti_index_container
to which this index belongs.last
is reachable fromfirst
.
Effects: -+For each element of [-iterator hint=end(); -while(first!=last)hint=insert(hint,*first++); -first
,last
), in this +order, inserts it into themulti_index_container
+to which this index belongs if ++
Complexity:- the index is non-unique OR no other element exists with + equivalent key,
+- AND insertion is allowed by all other indices of the +
+multi_index_container
.O(m*H(n+m))
, wherem
is the number of elements in [first
,last
).
Exception safety: Basic.
void insert(std::initializer_list<value_type> list);
+ ++Effects: ++++insert(list.begin(),list.end()) +iterator erase(iterator position);
@@ -575,11 +670,14 @@ the number of elements in [-first
,last
).
Exception safety:nothrow
.
bool replace(iterator position,const value_type& x);
+bool replace(iterator position,const value_type& x);
+bool replace(iterator position,value_type&& x);
-Requires:position
is a valid dereferenceable iterator -of the index.
+Requires (first version):value_type
isCopyAssignable
. +position
is a valid dereferenceable iterator of the index.
+Requires (second version):value_type
isMoveAssignable
. +position
is a valid dereferenceable iterator of the index.
Effects: Assigns the valuex
to the element pointed to byposition
into themulti_index_container
to which the index belongs if, for the valuex
@@ -604,9 +702,8 @@ 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 +Requires:mod
is a unary function object +accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Callsmod(e)
wheree
is the element @@ -634,9 +731,8 @@ the element pointed to byposition
is erased. bool modify(iterator position,Modifier mod,Rollback back);-Requires:Modifier
andRollback
are models of - -Unary Function
accepting arguments of type +Requires:mod
andback
are unary function +objects accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(e)
,back(e)
, wheree
is the element @@ -673,9 +769,8 @@ is rethrown.Requires:key_from_value
is a read/writeKey Extractor
-fromvalue_type
.Modifier
is a model of - -Unary Function
accepting arguments of type +fromvalue_type
.mod
is a +unary function object accepting arguments of typekey_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Equivalent tomodify(position,mod')
, @@ -690,14 +785,13 @@ bool modify_key(iterator position,Modifier mod,Rollback back);Requires:key_from_value
is a read/writeKey Extractor
-fromvalue_type
.Modifier
andRollback
-are models of -Unary Function
accepting arguments of type +fromvalue_type
.mod
andback
+are unary function objects accepting arguments of typekey_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(k)
,back(k)
, wherek
is the key of the element -pointed to byposition
, restores k to its original state.
+pointed to byposition
, restoresk
to its original state.
Effects: Equivalent tomodify(position,mod',back')
, withmod'
andback
defined in such a way thatmod'(x)
is the same asmod(key(x))
and @@ -724,10 +818,7 @@ the index.
Ordered indices provide the full lookup functionality required by - -
Sorted Associative Containers
and - -Unique Associative Containers
, namelyfind
, +[associative.reqmts], namelyfind
,count
,lower_bound
,upper_bound
andequal_range
. Additionally, these member functions are templatized to allow for non-standard arguments, so extending @@ -737,20 +828,14 @@ concept.-Consider a - -
Strict Weak Ordering
Compare
over values -of typeKey
. A pair of types (CompatibleKey
, +Consider a binary predicateCompare
inducing a strict +weak order over values of typeKey
. A pair of types (CompatibleKey
,CompatibleCompare
) is said to be a compatible extension ofCompare
if-
CompatibleCompare
is a - -Binary Predicate
over (Key
, +- -
CompatibleCompare
is a binary predicate over (Key
,CompatibleKey
),CompatibleCompare
is a - -Binary Predicate
over (CompatibleKey
, +CompatibleCompare
is a binary predicate over (CompatibleKey
,Key
),- if
c_comp(ck,k1)
then!c_comp(k1,ck)
,- if
!c_comp(ck,k1)
and!comp(k1,k2)
then @@ -913,15 +998,11 @@ are modeled after the following concepts.-Consider a - -
Strict Weak Ordering
Compare
over values -of typeKey
. A typeLowerBounder
is said to be +Consider a binary predicateCompare
inducing a strict +weak order over values of typeKey
. A typeLowerBounder
is said to be a lower bounder ofCompare
if-
@@ -930,9 +1011,7 @@ for every- +
LowerBounder
is a - -Predicate
overKey
,LowerBounder
is a predicate overKey
,- if
lower(k1)
and!comp(k2,k1)
thenlower(k2)
,lower
of typeLowerBounder
,k2
of typeKey
. Similarly, an upper bounder is a typeUpperBounder
such that-
@@ -1024,9 +1103,9 @@ Hashed indices- +
UpperBounder
is a - -Predicate
overKey
,UpperBounder
is a predcate overKey
,- if
upper(k1)
and!comp(k1,k2)
thenupper(k2)
,
-Revised December 21st 2009
+Revised July 6th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/rnd_indices.html b/doc/reference/rnd_indices.html index b3b10af..0e2dd7b 100644 --- a/doc/reference/rnd_indices.html +++ b/doc/reference/rnd_indices.html @@ -92,6 +92,8 @@ its associated random access index class.
"boost/multi_index/random_access_index.hpp"
synopsis+#include <initializer_list> + namespace boost{ namespace multi_index{ @@ -161,33 +163,31 @@ is preserved in all operations, regardless of the capacity status.-As is the case with sequenced indices, random access indices have the -following limitations with respect to STL sequence containers: +Except where noted or if the corresponding interface does not exist, random access +indices verify the same container requirements as
std::vector
+plus the requirements forstd::list
specific list operations at +[list.ops]. Some of the most important differences with respect to +std::vector
are:-
-Having these restrictions into account, random access indices are models -of -- Random access indices are not -
-Assignable
(like any other index.)- Insertions into a random access index may fail due to clashings - with other indices. This alters the semantics of the operations - provided with respect to their analogues in STL sequence containers. +
- Random access indices do not provide memory contiguity, and hence do not + have
-data
member functions.- Elements in a random access index are not mutable, and can only be changed + +
- The complexity of some operations, notably insertion and deletion, differ + from those of
+std::vector
. +- Unlike as in
+std::vector
, insertions into a random access index + may fail due to clashings with other indices. This alters the semantics + of the operations provided with respect to their analogues in +std::vector
. +- Elements in a randon access index are not mutable, and can only be changed by means of
-replace
andmodify
member functions.Random Access Container
and - -Back Insertion Sequence
. Although these indices do -not model - -Front Insertion Sequence
, because front insertion -and deletion take linear time, front operations are nonetheless provided -to match the interface of sequenced indices. -We only describe 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. +push_front
andpop_front
are provided for + compatibility with sequenced indices, even though they take linear time to execute. ++@@ -203,7 +203,7 @@ to the requirements for these types of containers. public: // types: - typedef typename node_type::value_type value_type; + typedef Value value_type; typedef tuples::null_type ctor_args; typedef TagList tag_list; typedef Allocator allocator_type; @@ -223,9 +223,11 @@ to the requirements for these types of containers. // construct/copy/destroy: index class name& operator=(const index class name& x); + index class name& operator=(std::initializer_list<value_type> list); template <class InputIterator> void assign(InputIterator first,InputIterator last); + void assign(std::initializer_list<value_type> list) void assign(size_type n,const value_type& value); allocator_type get_allocator()const; @@ -255,8 +257,10 @@ to the requirements for these types of containers. size_type max_size()const; size_type capacity()const; void reserve(size_type m); + void shrink_to_fit(); - void resize(size_type n,const value_type& x=value_type()); + void resize(size_type n); + void resize(size_type n,const value_type& x); // access: @@ -267,20 +271,32 @@ to the requirements for these types of containers. // modifiers: + template<typename... Args> + std::pair<iterator,bool> emplace_front(Args&&... args); std::pair<iterator,bool> push_front(const value_type& x); + std::pair<iterator,bool> push_front(value_type&& x); void pop_front(); + + template<typename... Args> + std::pair<iterator,bool> emplace_back(Args&&... args); std::pair<iterator,bool> push_back(const value_type& x); + std::pair<iterator,bool> push_back(value_type&& x); void pop_back(); + template<typename... Args> + std::pair<iterator,bool> emplace(iterator position,Args&&... args); std::pair<iterator,bool> insert(iterator position,const value_type& x); + std::pair<iterator,bool> insert(iterator position,value_type&& x); void insert(iterator position,size_type m,const value_type& x); template<typename InputIterator> void insert(iterator position,InputIterator first,InputIterator last); + void insert(iterator position,std::initializer_list<value_type> list); iterator erase(iterator position); iterator erase(iterator first,iterator last); bool replace(iterator position,const value_type& x); + bool replace(iterator position,value_type&& x); template<typename Modifier> bool modify(iterator position,Modifier mod); template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back); @@ -445,17 +461,22 @@ objects to which*this
andx
belong, respectively.
Returns:*this
.
index class name& operator=(std::initializer_list<value_type> list);
+ ++Effects: +++where+a=list; +a
is themulti_index_container
+object to which*this
belongs.
+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 tovalue_type
. -first
andlast
are not iterators into any -index of themulti_index_container
to which this index belongs. -last
is reachable fromfirst
.
Effects:clear(); @@ -463,6 +484,15 @@ index of themulti_index_container
to which this index belongs.void assign(std::initializer_list<value_type> list);
+ ++Effects: ++++assign(list.begin(),list.end()); +void assign(size_type n,const value_type& value);
@@ -500,6 +530,7 @@ is preserved in all insertions, regardless of the capacity status.void reserve(size_type m);
+Effects: If the previous value of-capacity()
was greater than or equal tom
, nothing is done; @@ -511,52 +542,123 @@ otherwiseO(n)
.
otherwise, strong.
void resize(size_type n,const value_type& x=value_type());
+void shrink_to_fit();
-Effects: -+ ++Effects: Reduces-if(n>size())insert(end(),n-size(),x); -else if(n<size())erase(begin()+n,end()); -capacity()
tosize()
.
+Complexity: If the capacity is not changed, constant; +otherwiseO(n)
.
+Exception safety: If the capacity is not changed,nothrow
; +otherwise, strong.
+void resize(size_type n);
+ +
+void resize(size_type n,const value_type& x);+Requires (first version):value_type
isDefaultInsertable
+intomulti_index_container
.
+Requires (second version):value_type
isCopyInsertable
+intomulti_index_container
.
+Effects: Ifsize()<n
, tries to appendn-size()
default-inserted +elements (first version) or copies ofx
(second version) at the end of +the index. Ifn<size()
, erases the lastsize()-n
elements.
Note: If an expansion is requested, the size of the index is not guaranteed to ben
after this operation (other indices may ban insertions.)Modifiers
-std::pair<iterator,bool> push_front(const value_type& x);
+template<typename... Args>
+std::pair<iterator,bool> emplace_front(Args&&... args);-Effects: Inserts- -x
at the beginning of the sequence if -no other index of themulti_index_container
bans the insertion.
+Effects: +Returns: The return value is a pair+emplace(begin(),std::forward<Args>(args)...); +p
.p.second
istrue
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(n+I(n))
.
-Exception safety: Strong.std::pair<iterator,bool> push_back(const value_type& x);
+ +std::pair<iterator,bool> push_front(const value_type& x);
+std::pair<iterator,bool> push_front(value_type&& x);
-Effects: Inserts+ +x
at the end of the sequence if -no other index of themulti_index_container
bans the insertion.
+Effects: +Returns: The return value is a pair+insert(begin(),x); // lvalue ref version +insert(begin(),std::move(x)); // rvalue ref version +p
.p.second
istrue
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.
+template<typename... Args>
+ +
+std::pair<iterator,bool> emplace_back(Args&&... args);+Effects: ++ ++Returns: The return value is a pair+emplace(end(),std::forward<Args>(args)...); +p
.p.second
+istrue
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.
+std::pair<iterator,bool> push_back(const value_type& x);
+std::pair<iterator,bool> push_back(value_type&& x);
+ ++Effects: ++ ++Returns: The return value is a pair+insert(end(),x); // lvalue ref version +insert(end(),std::move(x)); // rvalue ref version +p
.p.second
+istrue
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.
+template<typename... Args>
+ +
+ std::pair<iterator,bool> emplace(iterator position,Args&&... args);+Requires:-value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
beforeposition
if insertion +is allowed by all other indices of themulti_index_container
.
+Returns: The return value is a pairp
.p.second
+istrue
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. +Exception safety: Strong.
std::pair<iterator,bool> insert(iterator position,const value_type& x);
+std::pair<iterator,bool> insert(iterator position,const value_type& x);
+std::pair<iterator,bool> insert(iterator position,value_type&& x);
-Requires:@@ -584,23 +686,32 @@ void insert(iterator position,InputIterator first,InputIterator last);position
is a valid iterator of the index.
+Requires (first version):value_type
isCopyInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
Effects: Insertsx
beforeposition
if insertion is allowed by all other indices of themulti_index_container
.
Returns: The return value is a pairp
.p.second
@@ -564,7 +666,7 @@ istrue
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(shl(end()-position,1) + I(n))
.
+Complexity:O(I(n))
.
Exception safety: Strong.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 tovalue_type
. +InputIterator
is an input iterator. +value_type
is +EmplaceConstructible
into +multi_index_container
from*first
.first
andlast
are not iterators into any index of themulti_index_container
to which this index belongs.last
is reachable fromfirst
.
Effects: -+For each element of [-while(first!=last)insert(position,*first++); -first
,last
), in this +order, inserts it beforeposition
if insertion is allowed by all +other indices of themulti_index_container
.
Complexity:O(shl(end()-position,m) + m*I(n+m))
, wherem
is the number of elements in [first
,last
).
Exception safety: Basic.void insert(iterator position,std::initializer_list<value_type> list);
+ ++Effects: ++++insert(position,list.begin(),list.end()); +iterator erase(iterator position);
@@ -626,11 +737,14 @@ the number of elements in [-first
,last
).
Exception safety:nothrow
.
bool replace(iterator position,const value_type& x);
+bool replace(iterator position,const value_type& x);
+bool replace(iterator position,value_type&& x);
-Requires:position
is a valid dereferenceable iterator -of the index.
+Requires (first version):value_type
isCopyAssignable
. +position
is a valid dereferenceable iterator of the index.
+Requires (second version):value_type
isMoveAssignable
. +position
is a valid dereferenceable iterator of the index.
Effects: Assigns the valuex
to the element pointed to byposition
into themulti_index_container
to which the index belongs if replacing is allowed by all other indices of the @@ -649,17 +763,16 @@ 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 +Requires:mod
is a unary function object +accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Callsmod(e)
wheree
is the element pointed to byposition
and rearranges*position
into -all the indices of themulti_index_container
. Rearrangement on -random access indices does not change the position of the element with respect -to the index; rearrangement on other indices may or might not succeed. If the -rearrangement fails, the element is erased.
+all the indices of themulti_index_container
. Rearrangement on sequenced +indices does not change the position of the element with respect to the index; +rearrangement on other indices may or might not succeed. If the rearrangement +fails, the element is erased.
Postconditions: Validity ofposition
is preserved if the operation succeeds.
Returns:true
if the operation succeeded,false
@@ -674,9 +787,8 @@ the element pointed to byposition
is erased. bool modify(iterator position,Modifier mod,Rollback back);-Requires:Modifier
andRollback
are models of - -Unary Function
accepting arguments of type +Requires:mod
andback
are unary function +objects accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(e)
,back(e)
, wheree
is the element @@ -684,10 +796,10 @@ pointed to byposition
, restores all keys of the element to their original state.
Effects: Callsmod(e)
wheree
is the element pointed to byposition
and tries to rearrange*position
into -all the indices of themulti_index_container
. Rearrangement on -random access indices does not change the position of the element with respect -to the index; rearrangement on other indices may or might not succeed. If the -rearrangement fails,back(e)
is invoked and the +all the indices of themulti_index_container
. Rearrangement on sequenced +indices does not change the position of the element with respect to the index; +rearrangement on other indices may or might not succeed. If the rearrangement +fails,back(e)
is invoked and the element is kept at its original position in all indices.
Postconditions: Validity ofposition
is preserved except if the element is erased under the conditions described below.
@@ -808,11 +920,10 @@ is the number of elements erased.
void merge(index class name& x);
-Requires:std::less<value_type>
is a - -Strict Weak Ordering
overvalue_type
. +Requires:std::less<value_type>
induces a +strict weak ordering overvalue_type
. Both the index andx
are sorted according to -std::less<value_type>
.
+std::less<value_type>
.
Effects: Attempts to insert every element ofx
into the corresponding position of the index (according to the order). Elements successfully inserted are erased fromx
. The resulting sequence @@ -832,9 +943,8 @@ otherwise, basic.
template <typename Compare> void merge(index class name& x,Compare comp);
-Requires:Compare
is a - -Strict Weak Ordering
overvalue_type
. +Requires:Compare
induces a +strict weak ordering overvalue_type
. Both the index andx
are sorted according tocomp
.
Effects: Attempts to insert every element ofx
into the corresponding position of the index (according tocomp
). @@ -855,9 +965,8 @@ otherwise, basic.
void sort();
-Requires:std::less<value_type>
is a - -Strict Weak Ordering
overvalue_type
.
+Requires:std::less<value_type>
induces a +strict weark ordering overvalue_type
.
Effects: Sorts the index according tostd::less<value_type>
. The sorting is stable, i.e. equivalent elements preserve their relative position.
@@ -869,9 +978,8 @@ equivalent elements preserve their relative position.
template <typename Compare> void sort(Compare comp);
-Requires:Compare
is a - -Strict Weak Ordering
overvalue_type
.
+Requires:Compare
induces a +strict weak ordering overvalue_type
.
Effects: Sorts the index according tocomp
. The sorting is stable, i.e. equivalent elements preserve their relative position.
Postconditions: Validity of iterators and references is preserved.
@@ -1000,9 +1108,9 @@ Key extraction
-Revised July 21st 2009
+Revised July 14th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/reference/seq_indices.html b/doc/reference/seq_indices.html index ae29470..b9c93b5 100644 --- a/doc/reference/seq_indices.html +++ b/doc/reference/seq_indices.html @@ -92,6 +92,8 @@ its associated sequenced index class.
"boost/multi_index/sequenced_index.hpp"
synopsis+#include <initializer_list> + namespace boost{ namespace multi_index{ @@ -155,10 +157,15 @@ of iterators and references to elements is preserved in all operations.-There are a number of differences with respect to
std::lists
: +Except where noted or if the corresponding interface does not exist, sequenced +indices verify the same container requirements asstd::list
: +we only provide descriptions of those types and operations that are either not +present instd::list
or behave differently. Some of the +most important differences are:-
-Having these restrictions into account, sequenced indices are models -of -- Sequenced indices are not -
+Assignable
(like any other index.)- The complexity of some operations, notably insertion and deletion, differ + from those of
std::list
. +- Unlike as in
std::list
, insertions into a sequenced index may fail due to clashings with other indices. This alters the semantics of the operations provided with respect to their analogues in @@ -169,16 +176,6 @@ There are a number of differences with respect tostd::lists
:modify
member functions.Reversible Container
, - -Front Insertion Sequence
and - -Back Insertion Sequence
. 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.+@@ -194,7 +191,7 @@ types of containers. public: // types: - typedef typename node_type::value_type value_type; + typedef Value value_type; typedef tuples::null_type ctor_args; typedef TagList tag_list; typedef Allocator allocator_type; @@ -214,9 +211,11 @@ types of containers. // construct/copy/destroy: index class name& operator=(const index class name& x); + index class name& operator=(std::initializer_list<value_type> list); template <class InputIterator> void assign(InputIterator first,InputIterator last); + void assign(std::initializer_list<value_type> list); void assign(size_type n,const value_type& value); allocator_type get_allocator()const; @@ -245,7 +244,8 @@ types of containers. size_type size()const; size_type max_size()const; - void resize(size_type n,const value_type& x=value_type()); + void resize(size_type n); + void resize(size_type n,const value_type& x); // access: @@ -254,20 +254,32 @@ types of containers. // modifiers: + template<typename... Args> + std::pair<iterator,bool> emplace_front(Args&&... args); std::pair<iterator,bool> push_front(const value_type& x); + std::pair<iterator,bool> push_front(value_type&& x); void pop_front(); + + template<typename... Args> + std::pair<iterator,bool> emplace_back(Args&&... args); std::pair<iterator,bool> push_back(const value_type& x); + std::pair<iterator,bool> push_back(value_type&& x); void pop_back(); + template<typename... Args> + std::pair<iterator,bool> emplace(iterator position,Args&&... args); std::pair<iterator,bool> insert(iterator position,const value_type& x); + std::pair<iterator,bool> insert(iterator position,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); + void insert(iterator position,std::initializer_list<value_type> list); iterator erase(iterator position); iterator erase(iterator first,iterator last); bool replace(iterator position,const value_type& x); + bool replace(iterator position,value_type&& x); template<typename Modifier> bool modify(iterator position,Modifier mod); template<typename Modifier,typename Rollback> bool modify(iterator position,Modifier mod,Rollback back); @@ -419,17 +431,22 @@ objects to which*this
andx
belong, respectively.
Returns:*this
.
index class name& operator=(std::initializer_list<value_type> list);
+ ++Effects: +++where+a=list; +a
is themulti_index_container
+object to which*this
belongs.
+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 tovalue_type
. -first
andlast
are not iterators into any -index of themulti_index_container
to which this index belongs. -last
is reachable fromfirst
.
Effects:clear(); @@ -437,6 +454,15 @@ index of themulti_index_container
to which this index belongs.void assign(std::initializer_list<value_type> list);
+ ++Effects: ++++assign(list.begin(),list.end()); +void assign(size_type n,const value_type& value);
@@ -461,56 +487,113 @@ const_iterator iterator_to(const value_type& x)const;Capacity operations
-void resize(size_type n,const value_type& x=value_type());
+void resize(size_type n);
+void resize(size_type n,const value_type& x);-Effects: -+Requires (first version):-if(n>size())insert(end(),n-size(),x); -else if(n<size()){ - iterator it=begin(); - std::advance(it,n); - erase(it,end()); -} -value_type
isDefaultInsertable
+intomulti_index_container
.
+Requires (second version):value_type
isCopyInsertable
+intomulti_index_container
.
+Effects: Ifsize()<n
, tries to appendn-size()
default-inserted +elements (first version) or copies ofx
(second version) at the end of +the index. Ifn<size()
, erases the lastsize()-n
elements.
Note: If an expansion is requested, the size of the index is not guaranteed to ben
after this operation (other indices may ban insertions.)Modifiers
-std::pair<iterator,bool> push_front(const value_type& x);
+template<typename... Args>
+std::pair<iterator,bool> emplace_front(Args&&... args);-Effects: Inserts- -x
at the beginning of the sequence if -no other index of themulti_index_container
bans the insertion.
+Effects: +Returns: The return value is a pair+emplace(begin(),std::forward<Args>(args)...); +p
.p.second
istrue
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);
+ +std::pair<iterator,bool> push_front(const value_type& x);
+std::pair<iterator,bool> push_front(value_type&& x);
-Effects: Inserts-x
at the end of the sequence if -no other index of themulti_index_container
bans the insertion.
+Effects: +Returns: The return value is a pair+insert(begin(),x); // lvalue ref version +insert(begin(),std::move(x)); // rvalue ref version +p
.p.second
istrue
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);
+template<typename... Args>
+std::pair<iterator,bool> emplace_back(Args&&... args);-Requires:+ +position
is a valid iterator of the index.
+Effects: ++Returns: The return value is a pair+emplace(end(),std::forward<Args>(args)...); +p
.p.second
+istrue
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.
+std::pair<iterator,bool> push_back(const value_type& x);
+std::pair<iterator,bool> push_back(value_type&& x);
+ ++Effects: ++ ++Returns: The return value is a pair+insert(end(),x); // lvalue ref version +insert(end(),std::move(x)); // rvalue ref version +p
.p.second
+istrue
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.
+template<typename... Args>
+ +
+ std::pair<iterator,bool> emplace(iterator position,Args&&... args);+Requires:+ +value_type
isEmplaceConstructible
+intomulti_index_container
fromargs
.
+Effects: Inserts avalue_type
object constructed with +std::forward<Args>(args)...
beforeposition
if insertion +is allowed by all other indices of themulti_index_container
.
+Returns: The return value is a pairp
.p.second
+istrue
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);
+std::pair<iterator,bool> insert(iterator position,value_type&& x);
+ ++Requires (first version):value_type
isCopyInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
+Requires (second version):value_type
isMoveInsertable
+intomulti_index_container
. +position
is a valid iterator of the index.
Effects: Insertsx
beforeposition
if insertion is allowed by all other indices of themulti_index_container
.
Returns: The return value is a pairp
.p.second
@@ -525,7 +608,6 @@ Note that more than one element can be causing insertion not to be allowed.
void insert(iterator position,size_type n,const value_type& x);
-Requires:position
is a valid iterator of the index.
Effects:@@ -569,9 +568,8 @@ container: Elements offor(size_type i=0;i<n;++i)insert(position,x); @@ -537,22 +619,31 @@ 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 tovalue_type
. +InputIterator
is an input iterator. +value_type
is +EmplaceConstructible
into +multi_index_container
from*first
.first
andlast
are not iterators into any index of themulti_index_container
to which this index belongs.last
is reachable fromfirst
.
Effects: -+For each element of [-while(first!=last)insert(position,*first++); -first
,last
), in this +order, inserts it beforeposition
if insertion is allowed by all +other indices of themulti_index_container
.
Complexity:O(m*I(n+m))
, wherem
is the number of elements in [first
,last
).
Exception safety: Basic.void insert(iterator position,std::initializer_list<value_type> list);
+ ++Effects: ++++insert(position,list.begin(),list.end()); +iterator erase(iterator position);
@@ -578,11 +669,14 @@ the number of elements in [-first
,last
).
Exception safety:nothrow
.
bool replace(iterator position,const value_type& x);
+bool replace(iterator position,const value_type& x);
+bool replace(iterator position,value_type&& x);
-Requires:position
is a valid dereferenceable iterator -of the index.
+Requires (first version):value_type
isCopyAssignable
. +position
is a valid dereferenceable iterator of the index.
+Requires (second version):value_type
isMoveAssignable
. +position
is a valid dereferenceable iterator of the index.
Effects: Assigns the valuex
to the element pointed to byposition
into themulti_index_container
to which the index belongs if replacing is allowed by all other indices of the @@ -601,9 +695,8 @@ 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 +Requires:mod
is a unary function object +accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index.
Effects: Callsmod(e)
wheree
is the element @@ -626,9 +719,8 @@ the element pointed to byposition
is erased. bool modify(iterator position,Modifier mod,Rollback back);-Requires:Modifier
andRollback
are models of - -Unary Function
accepting arguments of type +Requires:mod
andback
are unary function +objects accepting arguments of typevalue_type&
.position
is a valid dereferenceable iterator of the index. The sequence of operationsmod(e)
,back(e)
, wheree
is the element @@ -761,11 +853,10 @@ is the number of elements erased.
void merge(index class name& x);
-Requires:-std::less<value_type>
is a - -Strict Weak Ordering
overvalue_type
. +Requires:std::less<value_type>
induces a +strict weak ordering overvalue_type
. Both the index andx
are sorted according to -std::less<value_type>
.
+std::less<value_type>
.
Effects: Attempts to insert every element ofx
into the corresponding position of the index (according to the order). Elements successfully inserted are erased fromx
. The resulting sequence @@ -782,12 +873,11 @@ references is preserved.
otherwise, basic.
template <typename Compare> void merge(index class name& x,Compare comp);
+template <typename Compare> void merge(index class name& x,Compare comp);
-Requires:Compare
is a - -Strict Weak Ordering
overvalue_type
. +Requires:Compare
induces a +strict weak ordering overvalue_type
. Both the index andx
are sorted according tocomp
.
Effects: Attempts to insert every element ofx
into the corresponding position of the index (according tocomp
). @@ -808,24 +898,22 @@ otherwise, basic.
void sort();
-Requires:-std::less<value_type>
is a - -Strict Weak Ordering
overvalue_type
.
+Requires:std::less<value_type>
induces a +strict weark ordering overvalue_type
.
Effects: Sorts the index according to -std::less<value_type>
. The sorting is stable, i.e. +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. +std::less<value_type>
does not throw; otherwise, basic.template <typename Compare> void sort(Compare comp);
+template <typename Compare> void sort(Compare comp);
-Requires:Compare
is a - -Strict Weak Ordering
overvalue_type
.
+Requires:Compare
induces a +strict weak ordering overvalue_type
.
Effects: Sorts the index according tocomp
. The sorting is stable, i.e. equivalent elements preserve their relative position.
Postconditions: Validity of iterators and references is preserved.
@@ -955,9 +1043,9 @@ Random access indices
-Revised July 21st 2009
+Revised July 8th 2013
-© Copyright 2003-2009 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/doc/release_notes.html b/doc/release_notes.html index 2936208..22ed2ca 100644 --- a/doc/release_notes.html +++ b/doc/release_notes.html @@ -27,10 +27,10 @@ Acknowledgements
-Contents
+
+- Boost 1.55 release
- Boost 1.54 release
- Boost 1.49 release
- Boost 1.48 release
@@ -48,6 +48,39 @@ Acknowledgements- Boost 1.33 release
Boost 1.55 release
+ ++
+
+- Boost.MultiIndex has been brought to a higher level of compliance + with C++11. +
++
+ Refer to the compiler specifics section for limitations + on pre-C++11 compilers. +- +
multi_index_container
is now efficiently movable.- Initializer lists supported.
+- Emplace functions provided.
+- Non-copyable elements (such as
+std::unique_ptr<T>
) supported. This includes + insertion of a range [first
,last
) where the iterators point to a type that is + convertible to that of the element: no copy construction happens in the process. +- Random access indices provide
+shrink_to_fit()
.- The following classes are deprecated: + +
+- Maintenance fixes.
+Boost 1.54 release
@@ -371,7 +404,7 @@ Acknowledgements
-Revised February 21st 2013
+Revised July 9st 2013
© Copyright 2003-2013 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/tutorial/indices.html b/doc/tutorial/indices.html index c71bb91..44e2535 100644 --- a/doc/tutorial/indices.html +++ b/doc/tutorial/indices.html @@ -222,9 +222,8 @@ 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 anstd::size_t
value for any given +indices: a hasher is just a unary function object +returning anstd::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 @@ -561,7 +560,7 @@ container: std::vector<boost::reference_wrapper<const int> > v; BOOST_FOREACH(const int& i,c)v.push_back(boost::cref(i)); -// this compiles OK, as reference_wrappers are assignable +// this compiles OK, as reference_wrappers are swappable std::random_shuffle(v.begin(),v.end());v
arereference_wrapper
s (from Boost.Ref) to the actual elements in the multi-index container. These objects still do not allow modification -of the referenced entities, but they are -Assignable
, -which is the only requirementstd::random_suffle
imposes. Once +of the referenced entities, but they are swappable, +which is the only requirementstd::random_shuffle
imposes. Once we have our desired rearrange stored in the view, we can transfer it to the container with @@ -718,9 +716,9 @@ Key extraction
-Revised October 15th 2007
+Revised July 7th 2013
-© Copyright 2003-2007 Joaquín M López Muñoz. +
© Copyright 2003-2013 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 diff --git a/include/boost/multi_index/detail/do_not_copy_elements_tag.hpp b/include/boost/multi_index/detail/do_not_copy_elements_tag.hpp new file mode 100644 index 0000000..a7b3f18 --- /dev/null +++ b/include/boost/multi_index/detail/do_not_copy_elements_tag.hpp @@ -0,0 +1,34 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * 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_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Used to mark a special ctor variant that copies the internal objects of + * a container but not its elements. + */ + +struct do_not_copy_elements_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/include/boost/multi_index/detail/index_base.hpp b/include/boost/multi_index/detail/index_base.hpp index 9b73a4b..a43214a 100644 --- a/include/boost/multi_index/detail/index_base.hpp +++ b/include/boost/multi_index/detail/index_base.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2008 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -14,11 +14,15 @@ #endif #include
/* keep it first to prevent nasty warns in MSVC */ -#include +#include #include +#include +#include #include #include +#include #include +#include #include #include #include @@ -42,6 +46,10 @@ namespace detail{ * cannot be called directly from the index classes.) */ +struct lvalue_tag{}; +struct rvalue_tag{}; +struct emplaced_tag{}; + template class index_base { @@ -74,27 +82,61 @@ protected: #endif private: - typedef typename call_traits ::param_type value_param_type; + typedef Value value_type; protected: explicit index_base(const ctor_args_list&,const Allocator&){} + index_base( + const index_base &, + do_not_copy_elements_tag) + {} + void copy_( const index_base &,const copy_map_type&) {} - node_type* insert_(value_param_type v,node_type* x) + node_type* insert_(const value_type& v,node_type* x,lvalue_tag) { boost::detail::allocator::construct(&x->value(),v); return x; } - node_type* insert_(value_param_type v,node_type*,node_type* x) + node_type* insert_(const value_type& v,node_type* x,rvalue_tag) + { + /* This shoud have used a modified, T&&-compatible version of + * boost::detail::allocator::construct, but + * is too old and venerable to mess + * with; besides, it is a general internal utility and the imperfect + * perfect forwarding emulation of Boost.Move might break other libs. + */ + + new (&x->value()) value_type(boost::move(const_cast (v))); + return x; + } + + node_type* insert_(const value_type&,node_type* x,emplaced_tag) + { + return x; + } + + node_type* insert_(const value_type& v,node_type*,node_type* x,lvalue_tag) { boost::detail::allocator::construct(&x->value(),v); return x; } + node_type* insert_(const value_type& v,node_type*,node_type* x,rvalue_tag) + { + new (&x->value()) value_type(boost::move(const_cast (v))); + return x; + } + + node_type* insert_(const value_type&,node_type*,node_type* x,emplaced_tag) + { + return x; + } + void erase_(node_type* x) { boost::detail::allocator::destroy(&x->value()); @@ -109,12 +151,20 @@ protected: void swap_(index_base &){} - bool replace_(value_param_type v,node_type* x) + void swap_elements_(index_base &){} + + bool replace_(const value_type& v,node_type* x,lvalue_tag) { x->value()=v; return true; } + bool replace_(const value_type& v,node_type* x,rvalue_tag) + { + x->value()=boost::move(const_cast (v)); + return true; + } + bool modify_(node_type*){return true;} bool modify_rollback_(node_type*){return true;} @@ -146,11 +196,39 @@ protected: std::size_t final_size_()const{return final().size_();} std::size_t final_max_size_()const{return final().max_size_();} - std::pair final_insert_(value_param_type x) + std::pair final_insert_(const value_type& x) {return final().insert_(x);} + std::pair final_insert_rv_(const value_type& x) + {return final().insert_rv_(x);} + template + std::pair final_insert_ref_(T& t) + {return final().insert_ref_(t);} + + template + std::pair final_emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + std::pair final_insert_( - value_param_type x,final_node_type* position) + const value_type& x,final_node_type* position) {return final().insert_(x,position);} + std::pair final_insert_rv_( + const value_type& x,final_node_type* position) + {return final().insert_rv_(x,position);} + template + std::pair final_insert_ref_( + T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + + template + std::pair final_emplace_hint_( + final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_hint_( + position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } void final_erase_(final_node_type* x){final().erase_(x);} @@ -159,9 +237,13 @@ protected: void final_clear_(){final().clear_();} void final_swap_(final_type& x){final().swap_(x);} + bool final_replace_( - value_param_type k,final_node_type* x) + const value_type& k,final_node_type* x) {return final().replace_(k,x);} + bool final_replace_rv_( + const value_type& k,final_node_type* x) + {return final().replace_rv_(k,x);} template bool final_modify_(Modifier& mod,final_node_type* x) diff --git a/include/boost/multi_index/detail/rnd_index_ptr_array.hpp b/include/boost/multi_index/detail/rnd_index_ptr_array.hpp index c0a2d67..c1d9873 100644 --- a/include/boost/multi_index/detail/rnd_index_ptr_array.hpp +++ b/include/boost/multi_index/detail/rnd_index_ptr_array.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2008 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -74,12 +74,12 @@ public: void reserve(std::size_t c) { - if(c>capacity_){ - auto_space spc1(spc.get_allocator(),c+1); - node_impl_type::transfer(begin(),end()+1,spc1.data()); - spc.swap(spc1); - capacity_=c; - } + if(c>capacity_)set_capacity(c); + } + + void shrink_to_fit() + { + if(capacity_>size_)set_capacity(size_); } pointer begin()const{return ptrs();} @@ -124,6 +124,14 @@ private: { return spc.data(); } + + void set_capacity(std::size_t c) + { + auto_space spc1(spc.get_allocator(),c+1); + node_impl_type::transfer(begin(),end()+1,spc1.data()); + spc.swap(spc1); + capacity_=c; + } }; template diff --git a/include/boost/multi_index/detail/scope_guard.hpp b/include/boost/multi_index/detail/scope_guard.hpp index 5640c8f..c64429e 100644 --- a/include/boost/multi_index/detail/scope_guard.hpp +++ b/include/boost/multi_index/detail/scope_guard.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2011 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -14,6 +14,7 @@ #endif #include +#include namespace boost{ diff --git a/include/boost/multi_index/detail/vartempl_support.hpp b/include/boost/multi_index/detail/vartempl_support.hpp new file mode 100644 index 0000000..f6db6bf --- /dev/null +++ b/include/boost/multi_index/detail/vartempl_support.hpp @@ -0,0 +1,247 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * 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_DETAIL_VARTEMPL_SUPPORT_HPP +#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP + +#if defined(_MSC_VER)&&(_MSC_VER>=1200) +#pragma once +#endif + +/* Utilities for emulation of variadic template functions. Variadic packs are + * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: + * + * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK + * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK + * - std::forward (args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK + * + * Forwarding emulated with Boost.Move. A template functions foo_imp + * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS + * arguments: variable number of arguments is emulated by providing a set of + * overloads foo forwarding to foo_impl with + * + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) + * + * which fill the extra args with boost::multi_index::detail::noarg's. + * boost::multi_index::detail::vartempl_placement_new works the opposite + * way: it acceps a full a pointer x to Value and a + * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to + * new(x) Value(args) where args is the argument pack after discarding + * noarg's. + * + * Emulation decays to the real thing when the compiler supports variadic + * templates and move semantics natively. + */ + +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) +#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 +#endif + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) + +#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ +BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) + +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_ARG,~) + +#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ +boost::forward (BOOST_PP_CAT(t,n)) + +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) + +namespace boost{namespace multi_index{namespace detail{ +struct noarg{}; +}}} + +/* call vartempl function without args */ + +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) + +#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ +template + +#define BOOST_MULTI_INDEX_TEMPLATE_0(n) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_AND( \ + n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ + (ret)(name_from)(name_to)) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ + z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ + (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ +template< \ + typename Value \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n,typename T) \ +> \ +Value* name( \ + Value* x \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ +{ \ + return new(x) Value( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ +} + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ + name) + +BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) + +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +/* native variadic templates support */ + +#include + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward (args)... +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +template ret name_from(Args&&... args) \ +{ \ + return name_to(std::forward (args)...); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +template ret name_from( \ + extra_arg_type extra_arg_name,Args&&... args) \ +{ \ + return name_to(extra_arg_name,std::forward (args)...); \ +} + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +Value* vartempl_placement_new(Value*x,Args&&... args) +{ + return new(x) Value(std::forward (args)...); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/include/boost/multi_index/hashed_index.hpp b/include/boost/multi_index/hashed_index.hpp index 9d53bb8..ef02eb1 100644 --- a/include/boost/multi_index/hashed_index.hpp +++ b/include/boost/multi_index/hashed_index.hpp @@ -21,33 +21,43 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&hashed_index::check_invariant_); \ + detail::make_obj_guard(x,&hashed_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT #endif @@ -191,6 +201,12 @@ private: typedef typename call_traits< key_type>::param_type key_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/destroy/copy @@ -205,6 +221,15 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + hashed_index & operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + allocator_type get_allocator()const { return this->final().get_allocator(); @@ -248,14 +273,27 @@ public: /* modifiers */ - std::pair insert(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; std::pair p=this->final_insert_(x); return std::pair (make_iterator(p.first),p.second); } - iterator insert(iterator position,value_param_type x) + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair (make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -265,14 +303,30 @@ public: return make_iterator(p.first); } + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast (position.get_node())); + return make_iterator(p.first); + } + template void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - iterator hint=end(); - for(;first!=last;++first)hint=insert(hint,*first); + for(;first!=last;++first)this->final_insert_ref_(*first); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -325,7 +379,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -335,6 +389,16 @@ public: x,static_cast (position.get_node())); } + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast (position.get_node())); + } + template bool modify(iterator position,Modifier mod) { @@ -410,6 +474,7 @@ public: void swap(hashed_index & x) { BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } @@ -634,6 +699,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: */ } + hashed_index( + const hashed_index & x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),0), + mlf(1.0f), + first_bucket(buckets.size()) + { + calculate_max_load(); + } + ~hashed_index() { /* the container is guaranteed to be empty by now */ @@ -689,8 +773,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - - node_type* insert_(value_param_type v,node_type* x) + + template + node_type* insert_(value_param_type v,node_type* x,Variant variant) { reserve(size()+1); @@ -698,7 +783,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: node_impl_pointer pos=buckets.at(buc); if(!link_point(v,pos,Category()))return node_type::from_impl(pos); - node_type* res=static_cast (super::insert_(v,x)); + node_type* res=static_cast (super::insert_(v,x,variant)); if(res==x){ link(x,pos); if(first_bucket>buc)first_bucket=buc; @@ -706,7 +791,9 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template + node_type* insert_( + value_param_type v,node_type* position,node_type* x,Variant variant) { reserve(size()+1); @@ -714,7 +801,8 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: node_impl_pointer pos=buckets.at(buc); if(!link_point(v,pos,Category()))return node_type::from_impl(pos); - node_type* res=static_cast (super::insert_(v,position,x)); + node_type* res= + static_cast (super::insert_(v,position,x,variant)); if(res==x){ link(x,pos); if(first_bucket>buc)first_bucket=buc; @@ -776,10 +864,26 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_( + hashed_index & x) + { + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + std::swap(first_bucket,x.first_bucket); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) { if(eq_(key(v),key(x->value()))){ - return super::replace_(v,x); + return super::replace_(v,x,variant); } node_impl_pointer y=prev(x); @@ -788,7 +892,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: BOOST_TRY{ std::size_t buc=find_bucket(v); node_impl_pointer pos=buckets.at(buc); - if(link_point(v,pos,Category())&&super::replace_(v,x)){ + if(link_point(v,pos,Category())&&super::replace_(v,x,variant)){ link(x,pos); if(first_bucket>buc){ first_bucket=buc; @@ -1157,6 +1261,29 @@ private: } #endif + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair (make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_hint_( + static_cast (position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + key_from_value key; hasher hash_; key_equal eq_; @@ -1257,5 +1384,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF #endif diff --git a/include/boost/multi_index/ordered_index.hpp b/include/boost/multi_index/ordered_index.hpp index e248a8b..3dedbc1 100644 --- a/include/boost/multi_index/ordered_index.hpp +++ b/include/boost/multi_index/ordered_index.hpp @@ -47,11 +47,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -61,12 +63,17 @@ #include #include #include +#include #include #include #include #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #include @@ -75,11 +82,14 @@ #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&ordered_index::check_invariant_); \ + detail::make_obj_guard(x,&ordered_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT #endif @@ -217,6 +227,12 @@ private: typedef typename call_traits< key_type>::param_type key_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/copy/destroy @@ -231,6 +247,15 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + ordered_index & operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + allocator_type get_allocator()const { return this->final().get_allocator(); @@ -269,14 +294,27 @@ public: /* modifiers */ - std::pair insert(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; std::pair p=this->final_insert_(x); return std::pair (make_iterator(p.first),p.second); } - iterator insert(iterator position,value_param_type x) + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair (make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -286,14 +324,35 @@ public: return make_iterator(p.first); } + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast (position.get_node())); + return make_iterator(p.first); + } + template void insert(InputIterator first,InputIterator last) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - iterator hint=end(); - for(;first!=last;++first)hint=insert(hint,*first); + node_type* hint=header(); /* end() */ + for(;first!=last;++first){ + hint=this->final_insert_ref_( + *first,static_cast (hint)).first; + node_type::increment(hint); + } } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + iterator erase(iterator position) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -330,7 +389,7 @@ public: return first; } - bool replace(iterator position,value_param_type x) + bool replace(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); @@ -340,6 +399,16 @@ public: x,static_cast (position.get_node())); } + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast (position.get_node())); + } + template bool modify(iterator position,Modifier mod) { @@ -409,6 +478,7 @@ public: void swap(ordered_index & x) { BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); this->final_swap_(x.final()); } @@ -551,10 +621,25 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: comp_(x.comp_) { /* Copy ctor just takes the key and compare objects from x. The rest is - * done in subsequent call to copy_(). + * done in a subsequent call to copy_(). */ } + ordered_index( + const ordered_index & x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp_(x.comp_) + { + empty_initialize(); + } + ~ordered_index() { /* the container is guaranteed to be empty by now */ @@ -623,28 +708,31 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::copy_(x,map); } - node_type* insert_(value_param_type v,node_type* x) + template + node_type* insert_(value_param_type v,node_type* x,Variant variant) { link_info inf; if(!link_point(key(v),inf,Category())){ return node_type::from_impl(inf.pos); } - node_type* res=static_cast (super::insert_(v,x)); + node_type* res=static_cast (super::insert_(v,x,variant)); if(res==x){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); } return res; } - node_type* insert_(value_param_type v,node_type* position,node_type* x) + template + node_type* insert_( + value_param_type v,node_type* position,node_type* x,Variant variant) { link_info inf; if(!hinted_link_point(key(v),position,inf,Category())){ return node_type::from_impl(inf.pos); } - node_type* res=static_cast (super::insert_(v,position,x)); + node_type* res=static_cast (super::insert_(v,position,x,variant)); if(res==x){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); } @@ -689,10 +777,21 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: super::swap_(x); } - bool replace_(value_param_type v,node_type* x) + void swap_elements_( + ordered_index & x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) { if(in_place(v,x,Category())){ - return super::replace_(v,x); + return super::replace_(v,x,variant); } node_type* next=x; @@ -703,7 +802,7 @@ BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: BOOST_TRY{ link_info inf; - if(link_point(key(v),inf,Category())&&super::replace_(v,x)){ + if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){ node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); return true; } @@ -1085,6 +1184,29 @@ private: } #endif + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair (make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_hint_( + static_cast (position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + template std::pair range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const @@ -1402,5 +1524,6 @@ inline boost::mpl::true_* boost_foreach_is_noncopyable( } #undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF #endif diff --git a/include/boost/multi_index/random_access_index.hpp b/include/boost/multi_index/random_access_index.hpp index c45913a..2460187 100644 --- a/include/boost/multi_index/random_access_index.hpp +++ b/include/boost/multi_index/random_access_index.hpp @@ -1,4 +1,4 @@ -/* Copyright 2003-2011 Joaquin M Lopez Munoz. +/* Copyright 2003-2013 Joaquin M Lopez Munoz. * 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) @@ -20,10 +20,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include #include @@ -32,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -41,17 +45,24 @@ #include #include +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) #include #include #endif #if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(*this,&random_access_index::check_invariant_); \ + detail::make_obj_guard(x,&random_access_index::check_invariant_); \ BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) #else +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) #define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT #endif @@ -176,6 +187,12 @@ private: typedef typename call_traits< value_type>::param_type value_param_type; + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + public: /* construct/copy/destroy @@ -190,12 +207,28 @@ public: return *this; } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + random_access_index & operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + template void assign(InputIterator first,InputIterator last) { assign_iter(first,last,mpl::not_ >()); } +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + void assign(size_type n,value_param_type value) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; @@ -241,12 +274,32 @@ public: size_type size()const{return this->final_size_();} size_type max_size()const{return this->final_max_size_();} size_type capacity()const{return ptrs.capacity();} - void reserve(size_type n){ptrs.reserve(n);} - void resize(size_type n,value_param_type x=value_type()) + void reserve(size_type n) { BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(n>size())insert(end(),n-size(),x); + ptrs.reserve(n); + } + + void shrink_to_fit() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + ptrs.shrink_to_fit(); + } + + void resize(size_type n) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(n>size()) + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + else if(n size())for(size_type m=n-size();m--;)this->final_insert_(x); else if(n push_front(value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_front,emplace_front_impl) + + std::pair push_front(const value_type& x) {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} void pop_front(){erase(begin());} - std::pair push_back(value_param_type x) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} void pop_back(){erase(--end());} - std::pair insert(iterator position,value_param_type x) + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_type& x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); @@ -290,6 +357,18 @@ public: return std::pair (make_iterator(p.first),p.second); } + std::pair insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair (make_iterator(p.first),p.second); + } + void insert(iterator position,size_type n,value_param_type x) { BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); @@ -315,6 +394,13 @@ public: insert_iter(position,first,last,mpl::not_