diff --git a/doc/reference/hash_indices.html b/doc/reference/hash_indices.html
index c3aeb83..1e1c838 100644
--- a/doc/reference/hash_indices.html
+++ b/doc/reference/hash_indices.html
@@ -308,6 +308,16 @@ requirements.
void clear()noexcept;
void swap(index class name& x);
+ template<typename Index> void merge(Index&& x);
+ template<typename Index>
+ std::pair<iterator,bool> merge(
+ Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
+ template<typename Index>
+ void merge(
+ Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last);
+
// observers:
key_from_value key_extractor()const;
@@ -474,7 +484,9 @@ local_iterator
const_local_iterator
-These types are forward iterators.
+These types are forward iterators. They depend only on node_type and whether
+the index is unique or not (this implies that, for instance, iterators to elements transferred
+from a unique index to a non-unique one will become invalid).
mod' and back defined in such a way that
key is the internal KeyFromValue object of the index.
+template<typename Index> void merge(Index&& x);
+
++Requires:+ +xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator().
+Effects: +++merge(x,x.begin(),x.end()); +
+template<typename Index> std::pair<iterator,bool> merge(
+ Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
+
+
++Requires:+ +xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator(). +iis a valid dereferenceable iterator ofx.
+Effects: Does nothing if the source and destination containers are the same; +otherwise, transfers the node of the element referred to byiinto the +multi_index_containerto which the destination index belongs if ++
+Note that no element is copied or destroyed in the process.- 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.
+Postconditions: If transfer succeeds, for any index in the source container +having the sameiterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to*i+remain valid and behave as iterators of the destination index.
+Returns: The return value is a pairp.p.second+istrueif and only if transfer took place or the source and destination +containers are the same. Ifp.secondistrue, +p.firstpoints to*i; 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: If the source and destination containers are the same, +constant; otherwise,O(I(n)+D(x.size())).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise strong. +
+template<typename Index> void merge(
+ Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last);
+
+
++Requires:+xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator(). +[first,last) is a valid range ofx.
+Effects: Does nothing if the source and destination containers are the same; +otherwise, for each node in [first,last), in this order, +the node is transferred to themulti_index_containerto which the +destination index belongs if ++
+Note that no element is copied or destroyed in the process.- 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.
+Postconditions: For any index in the source container having the same +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to the transferred elements +remain valid and behave as iterators of the destination index.
+Complexity: If the source and destination containers are the same, +constant; otherwise,O(m*(I(n+m)+D(x.size()))), where +mis the number of elements in [first, +last).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise basic. +
Apart from standard hash_function and key_eq,
@@ -1275,7 +1370,7 @@ Sequenced indices
-
Revised July 29th 2021
+Revised August 16th 2021
© Copyright 2003-2021 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/reference/ord_indices.html b/doc/reference/ord_indices.html index 34600f2..af5b491 100644 --- a/doc/reference/ord_indices.html +++ b/doc/reference/ord_indices.html @@ -42,6 +42,7 @@ Ranked indices
KeyFromValue::result_type.
+iterator
+const_iterator
+
+
+These types depend only on node_type.
+
+
@@ -911,6 +931,89 @@ with mod' and back defined in such a way that
key is the internal KeyFromValue object of the index.
+template<typename Index> void merge(Index&& x);
+
+
+Requires:+ +xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator().
+Effects: +++merge(x,x.begin(),x.end()); +
+template<typename Index> std::pair<iterator,bool> merge(
+ Index&& x,typename std::remove_reference_t<Index>::const_iterator i);
+
+
++Requires:+ +xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator(). +iis a valid dereferenceable iterator ofx.
+Effects: Does nothing if the source and destination containers are the same; +otherwise, transfers the node of the element referred to byiinto the +multi_index_containerto which the destination index belongs if ++
+Note that no element is copied or destroyed in the process.- 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.
+Postconditions: If transfer succeeds, for any index in the source container +having the sameiterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to*i+remain valid and behave as iterators of the destination index.
+Returns: The return value is a pairp.p.second+istrueif and only if transfer took place or the source and destination +containers are the same. Ifp.secondistrue, +p.firstpoints to*i; 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: If the source and destination containers are the same, +constant; otherwise,O(I(n)+D(x.size())).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise strong. +
+template<typename Index> void merge(
+ Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last);
+
+
++Requires:+xis a non-const reference to an index of a +node-compatible +multi_index_container.get_allocator()==x.get_allocator(). +[first,last) is a valid range ofx.
+Effects: Does nothing if the source and destination containers are the same; +otherwise, for each node in [first,last), in this order, +the node is transferred to themulti_index_containerto which the +destination index belongs if ++
+Note that no element is copied or destroyed in the process.- 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.
+Postconditions: For any index in the source container having the same +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to the transferred elements +remain valid and behave as iterators of the destination index.
+Complexity: If the source and destination containers are the same, +constant; otherwise,O(m*(I(n+m)+D(x.size()))), where +mis the number of elements in [first, +last).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise basic. +
Apart from standard key_comp and value_comp,
@@ -1237,7 +1340,7 @@ Ranked indices
-
Revised July 29th 2021
+Revised August 16th 2021
© Copyright 2003-2021 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/reference/rnd_indices.html b/doc/reference/rnd_indices.html index dd6a799..f92a9ae 100644 --- a/doc/reference/rnd_indices.html +++ b/doc/reference/rnd_indices.html @@ -40,6 +40,7 @@ Key extraction
std::list specific list operations at
// list operations:
- void splice(iterator position,index class name& x);
- void splice(iterator position,index class name& x,iterator i);
+ template<typename Index> void splice(const_iterator position,Index&& x);
+ template<typename Index>
+ std::pair<iterator,bool> splice(
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator i);
+ template<typename Index>
void splice(
- iterator position,index class name& x,iterator first,iterator last);
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last);
void remove(const value_type& value);
template<typename Predicate> void remove_if(Predicate pred);
@@ -450,6 +457,15 @@ index specifier. Instantiations are dependent on the following types:
tag.
+iterator
+const_iterator
+
+
+These types depend only on node_type.
+
+
@@ -875,56 +891,116 @@ The syntax and behavior of these operations exactly matches those of sequenced indices, but the associated complexity bounds differ in general.
-void splice(iterator position,index class name& x);
+ template<typename Index> void splice(const_iterator position,Index&& x);
-Requires:-positionis a valid iterator of the index. -&x!=this.
-Effects: Inserts the contents ofxbeforeposition, -in the same order as they were inx. Those elements successfully -inserted are erased fromx.
-Complexity:O(shl(end()-position,x.size()) + x.size()*I(n+x.size()) + x.size()*D(x.size())).
-Exception safety: Basic.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +positionis a valid iterator of the index, and must be exactlyend()+if the source and destination containers are the same.
+Effects: ++splice(position,x,x.begin(),x.end()); +
void splice(iterator position,index class name& x,iterator i);
+
+template<typename Index> std::pair<iterator,bool> splice(
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator i);
+
-Requires:-positionis a valid iterator of the index. -iis a valid dereferenceable iteratorx.
-Effects: Inserts the element pointed to byibefore -position: if insertion is successful, the element is erased from -x. In the special case&x==this, no copy or -deletion is performed, and the operation is always successful. If -position==i, no operation is performed.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this,O(rel(position,i,i+1)); -otherwiseO(shl(end()-position,1) + I(n) + D(n)).
-Exception safety: If&x==this,nothrow; -otherwise, strong.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +Ifget_allocator()!=x.get_allocator(), +value_typemust beCopyInsertableinto the destination +multi_index_container. +positionis a valid iterator of the index. +iis a valid dereferenceable iterator ofx.
+Effects: ++
+Postconditions: If transfer succeeds, for any index in the source container +having the same- (Same container) if the source and destination containers are the same, repositions + the element pointed to by
+ibeforepositionunless both + iterators refer to the same element.- (Transfer splice) else, if
+get_allocator()==x.get_allocator(), + transfers the node of the element referred to byiinto the + destinationmulti_index_containerright beforeposition+ if insertion is allowed by all other indices of themulti_index_container.- (Destructive splice) else, insertion of
+*iis tried before +position; if the operation is successful, the element is erased fromx. +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to*i+remain valid and behave as iterators of the destination index.
+Returns: The return value is a pairp.p.second+istrueif and only if insertion (either through transfer or copy insertion) +took place or the source and destination containers are the same. +Ifp.secondistrue, +p.firstpoints to the inserted element or to*iif the +source and destination containers are the same; 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: If the source and destination containers are the same, +O(rel(position,i',i'+1)), wherei'is the projection +ofiinto the index ofposition; +otherwise,O(shl(end()-position,1) + I(n) + D(x.size())).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise strong.
+Implementation note: The destructive variant of this operation is provided +for reasons of backwards compatibility with previous versions of this library where +allocator equality was not required.
void splice(iterator position,index class name& x,iterator first,iterator last);
+
+template<typename Index> void splice(
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last);
+
-Requires:positionis a valid iterator of the index. -firstandlastare valid iterators ofx. -lastis reachable fromfirst.position-is not in the range [first,last).
-Effects: For each element in the range [first,last), -insertion is tried beforeposition; if the operation is successful, -the element is erased fromx. In the special case -&x==this, no copy or deletion is performed, and insertions are -always successful.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this, -O(rel(position,first,last)); otherwise -O(shl(end()-position,m) + m*I(n+m) + m*D(x.size()))-wheremis the number of elements in [first,last).
-Exception safety: If&x==this,nothrow; -otherwise, basic.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +Ifget_allocator()!=x.get_allocator(), +value_typemust beCopyInsertableinto the destination +multi_index_container. +positionis a valid iterator of the index and does not point to any element in +[first,last). +[first,last) is a valid range ofx.
+Effects: ++
+Postconditions: For any index in the source container having the same +- (Same container) if the source and destination containers are the same, repositions all the elements + of [
+first,last), in this order, beforeposition. +- (Transfer splice) else, if
+get_allocator()==x.get_allocator(), then, for each node in + [first,last), in this order, the node is transferred to the +multi_index_containerright beforeposition+ if insertion is allowed by all other indices of the +multi_index_container.- (Destructive splice) else, for each element in [
+first,last), in this order, + insertion is tried beforeposition; if the operation is successful, the + element is erased fromx. +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to the transferred elements +remain valid and behave as iterators of the destination index.
+Complexity: If&x==this,O(rel(position,first,last)); +else, if the source and destination containers are the same,O(n); +otherwise,O(shl(end()-position,m) + m*(I(n+m) + D(x.size()))), where +mis the number of elements in [first,last).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise basic.
+Implementation note: The destructive variant of this operation is provided +for reasons of backwards compatibility with previous versions of this library where +allocator equality was not required.
void remove(const value_type& value);
@@ -973,20 +1049,22 @@ is the number of elements erased.void merge(index class name& x);
-Requires:std::less<value_type>induces a +Requires: +Eitherget_allocator()==x.get_allocator()orvalue_type+isCopyInsertableinto themulti_index_container. +std::less<value_type>induces a strict weak ordering overvalue_type. Both the index andxare sorted according tostd::less<value_type>.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according to the order). Elements -successfully inserted are erased fromx. The resulting sequence +Effects: Attempts to splice every element ofxinto the +corresponding position of the index (according to the order). The resulting sequence is stable, i.e. equivalent elements of either container preserve their relative position. In the special case&x==this, no operation is performed.
Postconditions: Elements in the index and remaining elements inxare sorted. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
+Validity of iterators and references is preserved, except to elements removed +fromxifget_allocator()!=x.get_allocator().
Complexity: If&x==this, constant; otherwiseO(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
Exception safety: If&x==this,nothrow; @@ -996,19 +1074,20 @@ otherwise, basic.
template <typename Compare> void merge(index class name& x,Compare comp);-Requires:Compareinduces a -strict weak ordering overvalue_type. +Requires: +Eitherget_allocator()==x.get_allocator()orvalue_type+isCopyInsertableinto themulti_index_container. +Compareinduces a strict weak ordering overvalue_type. Both the index andxare sorted according tocomp.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according tocomp). -Elements successfully inserted are erased fromx. The resulting +Effects: Attempts to splice every element ofxinto the +corresponding position of the index (according tocomp). The resulting sequence is stable, i.e. equivalent elements of either container preserve their relative position. In the special case&x==this, no operation is performed.
Postconditions: Elements in the index and remaining elements inxare sorted according tocomp. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
+Validity of iterators and references is preserved, except to elements removed +fromxifget_allocator()!=x.get_allocator().
Complexity: If&x==this, constant; otherwiseO(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
Exception safety: If&x==this,nothrow; @@ -1160,9 +1239,9 @@ Key extraction
-Revised May 9th 2020
+Revised August 16th 2021
-© Copyright 2003-2020 Joaquín M López Muñoz. +
© Copyright 2003-2021 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/rnk_indices.html b/doc/reference/rnk_indices.html index 9904b54..bfa3b44 100644 --- a/doc/reference/rnk_indices.html +++ b/doc/reference/rnk_indices.html @@ -42,6 +42,7 @@ Hashed indices @@ -473,6 +474,15 @@ These types are subject to the same requirements as specified for ordered indices.
+Nested types
+ +iterator+ +
+const_iterator+These types depend only on+node_type. +Rank operations
@@ -637,7 +647,7 @@ Hashed indices
-Revised July 29th 2021
+Revised August 14th 2021
© Copyright 2003-2021 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/reference/seq_indices.html b/doc/reference/seq_indices.html index 385fa1b..80e0f14 100644 --- a/doc/reference/seq_indices.html +++ b/doc/reference/seq_indices.html @@ -40,6 +40,7 @@ Random access indices
@@ -88,7 +116,7 @@ Acknowledgements
- Complexity signature
- Instantiation types
+- Nested types
- Constructors, copy and assignment
- Iterators
- Capacity operations
@@ -299,10 +300,16 @@ most important differences are: // list operations: - void splice(iterator position,index class name& x); - void splice(iterator position,index class name& x,iterator i); + template<typename Index> void splice(const_iterator position,Index&& x); + template<typename Index> + std::pair<iterator,bool> splice( + const_iterator position,Index&& x, + typename std::remove_reference_t<Index>::const_iterator i); + template<typename Index> void splice( - iterator position,index class name& x,iterator first,iterator last); + const_iterator position,Index&& x, + typename std::remove_reference_t<Index>::const_iterator first, + typename std::remove_reference_t<Index>::const_iterator last); void remove(const value_type& value); template<typename Predicate> void remove_if(Predicate pred); @@ -420,6 +427,15 @@ index specifier. Instantiations are dependent on the following types:tag. +Nested types
+ +iterator+ +
+const_iterator+These types depend only on+node_type. +Constructors, copy and assignment
@@ -802,62 +818,122 @@ is rethrown.
Sequenced indices provide the full set of list operations found in -
-std::list; the semantics of these member functions, however, -differ from that ofstd::listin some cases as insertions -might not succeed due to banning by other indices. Similarly, the complexity +std::list, extended in some cases such assplice; +the semantics of these member functions, however, +typically differs from that ofstd::listas insertions +may not succeed due to banning by other indices. Similarly, the complexity of the operations may depend on the other indices belonging to the samemulti_index_container.void splice(iterator position,index class name& x);+template<typename Index> void splice(const_iterator position,Index&& x);-Requires:-positionis a valid iterator of the index. -&x!=this.
-Effects: Inserts the contents ofxbeforeposition, -in the same order as they were inx. Those elements successfully -inserted are erased fromx.
-Complexity:O(x.size()*I(n+x.size()) + x.size()*D(x.size())).
-Exception safety: Basic.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +positionis a valid iterator of the index, and must be exactlyend()+if the source and destination containers are the same.
+Effects: ++splice(position,x,x.begin(),x.end()); +void splice(iterator position,index class name& x,iterator i);++template<typename Index> std::pair<iterator,bool> splice(
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator i); +-Requires:-positionis a valid iterator of the index. -iis a valid dereferenceable iteratorx.
-Effects: Inserts the element pointed to byibefore -position: if insertion is successful, the element is erased from -x. In the special case&x==this, no copy or -deletion is performed, and the operation is always successful. If -position==i, no operation is performed.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this, constant; otherwise -O(I(n) + D(n)).
-Exception safety: If&x==this,nothrow; -otherwise, strong.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +Ifget_allocator()!=x.get_allocator(), +value_typemust beCopyInsertableinto the destination +multi_index_container. +positionis a valid iterator of the index. +iis a valid dereferenceable iterator ofx.
+Effects: ++
+Postconditions: If transfer succeeds, for any index in the source container +having the same- (Same container) if the source and destination containers are the same, repositions + the element pointed to by
+ibeforepositionunless both + iterators refer to the same element.- (Transfer splice) else, if
+get_allocator()==x.get_allocator(), + transfers the node of the element referred to byiinto the + destinationmulti_index_containerright beforeposition+ if insertion is allowed by all other indices of themulti_index_container.- (Destructive splice) else, insertion of
+*iis tried before +position; if the operation is successful, the element is erased fromx. +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to*i+remain valid and behave as iterators of the destination index.
+Returns: The return value is a pairp.p.second+istrueif and only if insertion (either through transfer or copy insertion) +took place or the source and destination containers are the same. +Ifp.secondistrue, +p.firstpoints to the inserted element or to*iif the +source and destination containers are the same; 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: If the source and destination containers are the same, +constant; otherwise,O(I(n)+D(x.size())).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise strong.
+Implementation note: The destructive variant of this operation is provided +for reasons of backwards compatibility with previous versions of this library where +allocator equality was not required.void splice(iterator position,index class name& x,iterator first,iterator last);++template<typename Index> void splice(
+ const_iterator position,Index&& x,
+ typename std::remove_reference_t<Index>::const_iterator first,
+ typename std::remove_reference_t<Index>::const_iterator last); +-Requires:positionis a valid iterator of the index. -firstandlastare valid iterators ofx. -lastis reachable fromfirst.position-is not in the range [first,last).
-Effects: For each element in the range [first,last), -insertion is tried beforeposition; if the operation is successful, -the element is erased fromx. In the special case -&x==this, no copy or deletion is performed, and insertions are -always successful.
-Postconditions: If&x==this, no iterator or reference -is invalidated.
-Complexity: If&x==this, constant; otherwise -O(m*I(n+m) + m*D(x.size()))wheremis the number -of elements in [first,last).
-Exception safety: If&x==this,nothrow; -otherwise, basic.
+Requires:xis a non-const reference to an index of a +node-compatible +multi_index_container. +Ifget_allocator()!=x.get_allocator(), +value_typemust beCopyInsertableinto the destination +multi_index_container. +positionis a valid iterator of the index and does not point to any element in +[first,last). +[first,last) is a valid range ofx.
+Effects: ++
+Postconditions: For any index in the source container having the same +- (Same container) if the source and destination containers are the same, repositions all the elements + of [
+first,last), in this order, beforeposition. +- (Transfer splice) else, if
+get_allocator()==x.get_allocator(), then, for each node in + [first,last), in this order, the node is transferred to the +multi_index_containerright beforeposition+ if insertion is allowed by all other indices of the +multi_index_container.- (Destructive splice) else, for each element in [
+first,last), in this order, + insertion is tried beforeposition; if the operation is successful, the + element is erased fromx. +iterator/const_iteratortypes as the corresponding +index in the destination container, iterators referring to the transferred elements +remain valid and behave as iterators of the destination index.
+Complexity: If&x==this, constant; else, if +the source and destination containers are the same,O(m); +otherwise,O(m*(I(n+m)+D(x.size()))), where +mis the number of elements in [first,last).
+Exception safety: If the source and destination containers are the same, +nothrow; otherwise basic.
+Implementation note: The destructive variant of this operation is provided +for reasons of backwards compatibility with previous versions of this library where +allocator equality was not required.void remove(const value_type& value);@@ -906,20 +982,22 @@ is the number of elements erased.
void merge(index class name& x);-Requires:std::less<value_type>induces a +Requires: +Eitherget_allocator()==x.get_allocator()orvalue_type+isCopyInsertableinto themulti_index_container. +std::less<value_type>induces a strict weak ordering overvalue_type. Both the index andxare sorted according tostd::less<value_type>.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according to the order). Elements -successfully inserted are erased fromx. The resulting sequence +Effects: Attempts to splice every element ofxinto the +corresponding position of the index (according to the order). The resulting sequence is stable, i.e. equivalent elements of either container preserve their relative position. In the special case&x==this, no operation is performed.
Postconditions: Elements in the index and remaining elements inxare sorted. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
+Validity of iterators and references is preserved, except to elements removed +fromxifget_allocator()!=x.get_allocator().
Complexity: If&x==this, constant; otherwiseO(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
Exception safety: If&x==this,nothrow; @@ -929,19 +1007,20 @@ otherwise, basic.
template <typename Compare> void merge(index class name& x,Compare comp);-Requires:Compareinduces a -strict weak ordering overvalue_type. +Requires: +Eitherget_allocator()==x.get_allocator()orvalue_type+isCopyInsertableinto themulti_index_container. +Compareinduces a strict weak ordering overvalue_type. Both the index andxare sorted according tocomp.
-Effects: Attempts to insert every element ofxinto the -corresponding position of the index (according tocomp). -Elements successfully inserted are erased fromx. The resulting +Effects: Attempts to splice every element ofxinto the +corresponding position of the index (according tocomp). The resulting sequence is stable, i.e. equivalent elements of either container preserve their relative position. In the special case&x==this, no operation is performed.
Postconditions: Elements in the index and remaining elements inxare sorted according tocomp. -Validity of iterators to the index and of non-erased elements ofx-references is preserved.
+Validity of iterators and references is preserved, except to elements removed +fromxifget_allocator()!=x.get_allocator().
Complexity: If&x==this, constant; otherwiseO(n + x.size()*I(n+x.size()) + x.size()*D(x.size())).
Exception safety: If&x==this,nothrow; @@ -1095,9 +1174,9 @@ Random access indices
-Revised May 9th 2020
+Revised August 16th 2021
-© Copyright 2003-2020 Joaquín M López Muñoz. +
© Copyright 2003-2021 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 11046c2..ef7ec43 100644 --- a/doc/release_notes.html +++ b/doc/release_notes.html @@ -72,6 +72,34 @@ Acknowledgements
- Added
+containsto key-based indices (issue #35).- Added
+mergeoperations to key-based indices. The functionality goes beyond + the standard specification for (unordered) associative containers in a number of ways, + most notably: ++
+- The source index can be of any type, including non key-based indices.
+- Partial merge is provided: for instance,
+x.merge(y,first,last)+ merges only the elements ofywithin [first,last). +- Previous versions of
+splicefor sequenced and random access indices + were destructive, i.e. elements were copy-inserted into the destination and then erased + from the source. Now,spliceis based on node transfer much asmerge+ in key-based indices, and has been similarly extended to accept source indices of any type: + in fact,splicecan be regarded as a frontend to the same functionality + provided bymergein key-based indices. For reasons of backwards compatibility, + the destructive behavior ofsplicehas been retained in the case that the + source and destination containers have unequal allocators. +- The fact has been documented that index iterator types do only depend on
+node_type, + (except for hashed indices, where uniqueness/non-uniqueness is also a dependency). This has + implications on the validity of iterators to elements transferred bymergeor +splice. This property is a variant of what has been called + SCARY iterators in the C++ standard mailing lists. + SCARYness is currently (August 2021) not mandated for standard containers. +- Iterator SCARYness is now also preserved in safe mode. +
- - Added node extraction and insertion + Added node extraction and insertion following the analogous interface of associative containers as introduced in C++17. This feature has also been extended to non key-based indices, in contrast to C++ standard library sequence containers, which do not provide such functionality. @@ -695,7 +723,7 @@ Acknowledgements
-Revised July 29th 2021
+Revised August 16th 2021
© Copyright 2003-2021 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/tutorial/basics.html b/doc/tutorial/basics.html index 8a5a6fa..8f14652 100644 --- a/doc/tutorial/basics.html +++ b/doc/tutorial/basics.html @@ -62,7 +62,6 @@ Index types
- Projection of iterators
-- Node handling operations
- Complexity and exception safety
project can also be used with
tags.
-
-Using direct node manipulation, elements can be passed between
-multi_index_containers without actually copying them:
-
- --// move an employee to the retiree archive -void move_to_retirement(int ssnumber,employee_set& es,employee_set& archive) -{ - // extract the employee with given SS number to a node handle - employee_set_by_ssn::node_type node=es.get<ssn>().extract(ssnumber); - - if(!node.empty()){ // employee found - // re-insert into archive (note the use of std::move) - archive.insert(std::move(node)); - } -} -
-In the example, the internal node is transferred as-is from es to archive,
-which is more efficient than erasing from the source and recreating in destination.
-node_type is a move-only class used to pass nodes around, and its interface follows
-that of the homonym type
-for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
-and insertion operations for all index types, including sequenced ones (by contrast,
-std::list does not have such features):
-
- --multi_index_container< - int, - indexed_by< - sequenced<>, - ordered_unique<identity<int> > - > -> src; - -multi_index_container< - int, - indexed_by< - sequenced<>, - ordered_non_unique<identity<int>, std::greater<int> > - > -> dst; - -... - -// transfer even numbers from src to dst -for(auto first=src.begin(),last=src.end();first!=last;){ - if(*first%2==0) dst.insert(dst.end(),src.extract(first++)); - else ++first; -} -
-Note that src and dst are of different types,
-yet transfer is possible. Two multi_index_containers are
-node-compatible (that is, they use the same node_type) if
-they have the same element and allocator types and their respective indices match
-one by one without regard to whether they are unique or non-unique or to
-their particular configuration parameters: they are both ordered, or
-both sequenced, etc.
-
@@ -1317,9 +1250,9 @@ Index types
-
Revised May 9th 2020
+Revised August 16th 2021
-© Copyright 2003-2020 Joaquín M López Muñoz. +
© Copyright 2003-2021 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/tutorial/indices.html b/doc/tutorial/indices.html
index b1f13bc..dee316e 100644
--- a/doc/tutorial/indices.html
+++ b/doc/tutorial/indices.html
@@ -55,6 +55,7 @@ Key extraction
iterator_to
-Hashed indices replicate the interface as std::unordered_set and
+Hashed indices replicate the interface of std::unordered_set and
std::unordered_multiset, with only minor differences where required
by the general constraints of multi_index_containers, and provide
additional useful capabilities like in-place updating of elements.
@@ -774,6 +775,113 @@ in scenarios where access via iterators is not suitable or desireable:
+Using direct node manipulation, elements can be passed between
+multi_index_containers without actually copying them:
+
+ ++// move an employee to the retiree archive +void move_to_retirement(int ssnumber,employee_set& es,employee_set& archive) +{ + // assume employee_set has an index on SS number(not shown before) + // extract the employee with given SS number to a node handle + employee_set_by_ssn::node_type node=es.get<ssn>().extract(ssnumber); + + if(!node.empty()){ // employee found + // re-insert into archive (note the use of std::move) + archive.insert(std::move(node)); + } +} +
+In the example, the internal node is transferred as-is from es to archive,
+which is more efficient than erasing from the source and recreating in destination.
+node_type is a move-only class used to pass nodes around, and its interface follows
+that of the homonym type
+for C++ associative containers (set containers version). Boost.MultiIndex provides node extraction
+and insertion operations for all index types, including sequenced ones (by contrast,
+std::list does not have such features):
+
+ ++multi_index_container< + int, + indexed_by< + sequenced<>, + ordered_unique<identity<int> > + > +> src; + +multi_index_container< + int, + indexed_by< + sequenced<>, + ordered_non_unique<identity<int>, std::greater<int> > + > +> dst; + +... + +// transfer even numbers from src to dst +for(auto first=src.begin(),last=src.end();first!=last;){ + if(*first%2==0) dst.insert(dst.end(),src.extract(first++)); + else ++first; +} +
+Note that src and dst are of different types,
+yet transfer is possible. Two multi_index_containers are
+node-compatible (that is, they use the same node_type) if
+they have the same element and allocator types and their respective indices match
+one by one without regard to whether they are unique or non-unique or to
+their particular configuration parameters: they are both ordered, or
+both sequenced, etc.
+
+Alternatively, direct node transfer between two containers can be done without
+keeping intervening node_types thanks to merge (key-based
+indices) and splice (non key-based indices).
+
+ ++// move older employees to retirement +void move_to_retirement_by_age( + int max_age,employee_set& es,employee_set& archive) +{ + // assume employee_set has an index on age (not shown before) + employee_set_by_age& ea=es.get<age>(); + + // archive employees with age>max_age + archive.merge(ea,ea.upper_bound(max_age),ea.end()); +} + +... + +// transfer even numbers from src to dst +for(auto first=src.begin(),last=src.end();first!=last;){ + if(*first%2==0) dst.splice(dst.end(),src,first++); + else ++first; +} +
+There are overloads of merge/splice for transferring a single element,
+a range between two iterators and an entire container: for further details, consult
+for instance the reference for ordered indices and for
+sequenced indices
+(the rest of indices provide one interface or the other).
+Please note that sequenced and random access indices do also have an operation called merge,
+but this follows the specification of std::list::merge, which has a somewhat
+different behavior (source and destination are required to be ordered by the same criterion). This is
+a rather confusing naming issue that Boost.MultiIndex simply inherits from the C++ standard.
+
@@ -821,7 +929,7 @@ Key extraction
-
Revised July 29th 2021
+Revised August 16th 2021
© Copyright 2003-2021 Joaquín M López Muñoz. Distributed under the Boost Software