diff --git a/doc/acknowledgements.html b/doc/acknowledgements.html index 65dbf55..74f014a 100644 --- a/doc/acknowledgements.html +++ b/doc/acknowledgements.html @@ -172,6 +172,13 @@ hashed indices update functions so that they meet some intuitive expectation Grzegorz Jakacki spotted some internal dead code.
++Stephen Kelly has contributed the removal of workaround code for old compilers +no longer supported. +
+Revised June 25th 2008
+Revised October 9th 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/compiler_specifics.html b/doc/compiler_specifics.html index 3a3c2f5..ca35509 100644 --- a/doc/compiler_specifics.html +++ b/doc/compiler_specifics.html @@ -114,25 +114,21 @@ of symbol names.
indexed_by
BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE
tag
BOOST_MULTI_INDEX_LIMIT_TAG_SIZE
composite_key
BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE
// reducing symbol names through type hiding -// type hide the index spexifier list within employee_set_indices +// type hide the index specifier list within employee_set_indices struct employee_set_indices: indexed_by< @@ -372,7 +368,7 @@ Performance
-Revised July 30th 2013
+Revised November 12th 2013
© Copyright 2003-2013 Joaquín M López Muñoz. Distributed under the Boost Software diff --git a/doc/index.html b/doc/index.html index 32363aa..4e89487 100644 --- a/doc/index.html +++ b/doc/index.html @@ -13,8 +13,8 @@
- - +
Boost Multi-index Containers Library
+
@@ -77,17 +77,17 @@ examples of use developed in the documentation:
- - ++
-Revised February 6th 2006
+Revised November 30th 2013
-© Copyright 2003-2006 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 b8e1985..a0407f3 100644 --- a/doc/reference/hash_indices.html +++ b/doc/reference/hash_indices.html @@ -50,6 +50,7 @@ Sequenced indices
Lookup Bucket interface Hash policy +Comparison Serialization @@ -118,6 +119,13 @@ their associated hashed index classes. template<implementation defined> class index class name implementation defined; +// index comparison: + +// OP is any of ==,!= + +template<implementation defined> +bool operator OP(const index class name& x,const index class name& y); + // index specialized algorithms: template<implementation defined> @@ -238,20 +246,20 @@ requirements. index class name& operator=(const index class name& x); index class name& operator=(std::initializer_list<value_type> list); - allocator_type get_allocator()const; + allocator_type get_allocator()const noexcept; // size and capacity: - bool empty()const; - size_type size()const; - size_type max_size()const; + bool empty()const noexcept; + size_type size()const noexcept; + size_type max_size()const noexcept; // iterators: - iterator begin(); - const_iterator begin()const; - iterator end(); - const_iterator end()const; + iterator begin()noexcept; + const_iterator begin()const noexcept; + iterator end()noexcept; + const_iterator end()const noexcept; const_iterator cbegin()const; const_iterator cend()const; @@ -286,7 +294,7 @@ requirements. template<typename Modifier,typename Rollback> bool modify_key(iterator position,Modifier mod,Rollback back); - void clear(); + void clear()noexcept; void swap(index class name& x); // observers: @@ -326,8 +334,8 @@ requirements. // bucket interface: - size_type bucket_count()const; - size_type max_bucket_count()const; + size_type bucket_count()const noexcept; + size_type max_bucket_count()const noexcept; size_type bucket_size(size_type n)const; size_type bucket(const key_type& k)const; @@ -343,12 +351,24 @@ requirements. // hash policy: - float load_factor()const; - float max_load_factor()const; + float load_factor()const noexcept; + float max_load_factor()const noexcept; void max_load_factor(float z); void rehash(size_type n); + void reserve(size_type n); }; +// index comparison: + +template<implementation defined> +bool operator==(const index class name& x,const index class name& y); + +template<implementation defined> +bool operator!=(const index class name& x,const index class name& y) +{ + return !(x==y); +} + // index specialized algorithms: template<implementation defined> @@ -370,21 +390,22 @@ scheme outlined in the section. The complexity signature of hashed indices is:
- copying:
-c(n)=n*log(n)
,- insertion: average case
-i(n)=1
(constant), - worst casei(n)=n
,- hinted insertion: average case
-h(n)=1
(constant), - worst caseh(n)=n
,- deletion: average case
+d(n)=1
(constant), - worst cased(n)=n
,- insertion: average case
+i(n)=1
(amortized constant), + worst casei(n)=ndist
,- hinted insertion: average case
+h(n)=1
(amortized constant), + worst caseh(n)=ndist
,- deletion:
d(n)=1
(constant),- replacement:
- if the new element key is equivalent to the original,
r(n)=1
(constant),- otherwise, average case
+ worst caser(n)=1
(constant), - worst caser(n)=n
,r(n)=ndist
,modifying: average case + worst casem(n)=1
(constant), - worst casem(n)=n
.m(n)=ndist
, +wherendist
is the number of non-equivalent elements out of +the totaln
.Instantiation types
@@ -504,7 +525,7 @@ istrue
if and only if insertion took place. On successful insertio 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, except that rehashing may occur even if the operation fails.
template<typename... Args>
@@ -530,7 +551,7 @@ 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.
+Exception safety: Strong, except that rehashing may occur even if the operation fails.
std::pair<iterator,bool> insert(const value_type& x);
@@ -555,7 +576,7 @@ is true
if and only if insertion took place. On successful insertio
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, except that rehashing may occur even if the operation fails.
iterator insert(iterator position,const value_type& x);
@@ -583,7 +604,7 @@ 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.
+Exception safety: Strong, except that rehashing may occur even if the operation fails.
template<typename InputIterator>
@@ -618,7 +639,7 @@ to which this index belongs if
Effects:
-insert(list.begin(),list.end())
+insert(list.begin(),list.end());
@@ -641,7 +662,7 @@ if no such element exists.
Effects: Deletes the elements with key equivalent to x
.
Returns: Number of elements deleted.
Complexity: Average case, O(1 + m*D(n))
, worst case
-O(n + m*D(n))
, where m
is
+O(ndist + m*D(n))
, where m
is
the number of elements deleted.
Exception safety: Basic.
@@ -870,7 +891,7 @@ In the context of a compatible extension or a compatible key, the expression
Effects: Returns a pointer to an element whose key is equivalent to
x
, or end()
if such an element does not exist.
Complexity: Average case O(1)
(constant), worst case
-O(n)
.
+O(ndist)
.
template<
@@ -888,7 +909,7 @@ iterator find(
Effects: Returns a pointer to an element whose key is equivalent to
x
, or end()
if such an element does not exist.
Complexity: Average case O(1)
(constant), worst case
-O(n)
.
+O(ndist)
.
template<typename CompatibleKey>
@@ -900,7 +921,7 @@ size_type count(const CompatibleKey& x)const;
(hasher
, key_equal
).
Effects: Returns the number of elements with key equivalent to x
.
Complexity: Average case O(count(x))
, worst case
-O(n)
.
+O(count(x)+ndist)
.
template<
@@ -917,7 +938,7 @@ size_type count(
(hasher
, key_equal
).
Effects: Returns the number of elements with key equivalent to x
.
Complexity: Average case O(count(x,hash,eq))
, worst case
-O(n)
.
+O(count(x,hash,eq)+ndist)
.
template<typename CompatibleKey>
@@ -930,8 +951,8 @@ std::pair<iterator,iterator> equal_range(const CompatibleKey& x)const;
Effects: Returns a range containing all elements with keys equivalent
to x
(and only those), or (end()
,end()
)
if no such elements exist.
-Complexity: Average case O(count(x))
, worst case
-O(n)
.
+Complexity: Average case O(1)
(constant), worst case
+O(ndist)
.
template<
@@ -949,8 +970,8 @@ std::pair<iterator,iterator> equal_range(
Effects: Returns a range containing all elements with keys equivalent
to x
(and only those), or (end()
,end()
)
if no such elements exist.
-Complexity: Average case O(count(x,hash,eq))
, worst case
-O(n)
.
+Complexity: Average case O(1)
(constant), worst case
+O(ndist)
.
Bucket interface
@@ -976,11 +997,50 @@ so that size()/bucket_count()
does not exceed the maximum
load factor, and bucket_count()>=n
.
Postconditions: Validity of iterators and references to the
elements contained is preserved.
-Complexity: Average case O(size())
, worst case
-O(size(n)2)
.
+Complexity: O(m)
, where m
is the number of
+non-equivalent elements in the index.
Exception safety: Strong.
+void reserve(size_type n);
+
+
+Effects:
+
+rehash(std::ceil(n/max_load_factor()));
+
+
+
+Comparison
+
+template<implementation defined>
+bool operator==(const index class name& x,const index class name& y);
+
+
+Requires: x.key_extractor()
, x.hash_function()
and
+x.key_eq()
have the same behavior as the corresponding objects in y
.
+For any two elements e1
, e2
in x
or y
,
+if e1==e2
then their keys are equivalent.
+Returns: true
iff x
and y
have the same size
+and for each key k
present in x
the range
+x.equal_range(k)
is equal (considering the ==
operator of value_type
)
+to y.equal_range(k)
under permutations of the elements.
+Complexity: Let k1
,...,km
be the different
+keys present in x
:
+
+ - If, for each
ki
, x.equal_range(ki)
is arranged
+ in the same order as y.equal_range(ki)
, average case is
+ O(x.size())
, worst case O(x.size()2)
.
+
+ - Otherwise, average case is
+
O(Σ(x.count(ki)2))
,
+ worst case O(x.size()2)
.
+
+
+(For unique indices, the formulas above reduce to average case
+O(x.size())
, worst case O(x.size()2)
.)
+
+
Serialization
@@ -1069,7 +1129,7 @@ Sequenced indices
-
Revised July 6th 2013
+Revised November 30th 2013
© Copyright 2003-2013 Joaquín M López Muñoz.
Distributed under the Boost Software
diff --git a/doc/reference/multi_index_container.html b/doc/reference/multi_index_container.html
index e4e294f..f1d0235 100644
--- a/doc/reference/multi_index_container.html
+++ b/doc/reference/multi_index_container.html
@@ -119,7 +119,7 @@ synopsis
typename nth_index<
multi_index_container<Value,IndexSpecifierList,Allocator>,N
>::type&
-get(multi_index_container<Value,IndexSpecifierList,Allocator>& m);
+get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept;
template<
int N,typename Value,typename IndexSpecifierList,typename Allocator
@@ -127,7 +127,7 @@ synopsis
const typename nth_index<
multi_index_container<Value,IndexSpecifierList,Allocator>,N
>::type&
-get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m);
+get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept;
template<
typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
@@ -135,7 +135,7 @@ synopsis
typename index<
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag
>::type&
-get(multi_index_container<Value,IndexSpecifierList,Allocator>& m);
+get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept;
template<
typename Tag,typename Value,typename IndexSpecifierList,typename Allocator
@@ -143,7 +143,7 @@ synopsis
const typename index<
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag
>::type&
-get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m);
+get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept;
// multi_index_container global functions for projection of iterators:
@@ -314,14 +314,14 @@ operators and functions associated with the index (vg. comparison and
multi_index_container<Value,IndexSpecifierList,Allocator>& operator=(
std::initializer_list<Value> list)
- allocator_type get_allocator()const;
+ allocator_type get_allocator()const noexcept;
// retrieval of indices
- template<int N> typename nth_index<N>::type& get();
- template<int N> const typename nth_index<N>::type& get()const;
- template<typename Tag> typename index<Tag>::type& get()
- template<typename Tag> const typename index<Tag>::type& get()const;
+ template<int N> typename nth_index<N>::type& get()noexcept;
+ template<int N> const typename nth_index<N>::type& get()const noexcept;
+ template<typename Tag> typename index<Tag>::type& get()noexcept;
+ template<typename Tag> const typename index<Tag>::type& get()const noexcept;
// projection of iterators
@@ -379,7 +379,7 @@ operators and functions associated with the index (vg. comparison and
typename nth_index<
multi_index_container<Value,IndexSpecifierList,Allocator>,N
>::type&
-get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)
+get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept
{
return m.get<N>();
}
@@ -390,7 +390,7 @@ operators and functions associated with the index (vg. comparison and
const typename nth_index<
multi_index_container<Value,IndexSpecifierList,Allocator>,N
>::type&
-get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)
+get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept
{
return m.get<N>();
}
@@ -401,7 +401,7 @@ operators and functions associated with the index (vg. comparison and
typename index<
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag
>::type&
-get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)
+get(multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept
{
return m.get<Tag>();
}
@@ -412,7 +412,7 @@ operators and functions associated with the index (vg. comparison and
const typename index<
multi_index_container<Value,IndexSpecifierList,Allocator>,Tag
>::type&
-get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)
+get(const multi_index_container<Value,IndexSpecifierList,Allocator>& m)noexcept
{
return m.get<Tag>();
}
@@ -537,7 +537,7 @@ scheme outlined in the
- Non-equal allocator instances are supported: swapping two non-equal
instances must not throw any exception.
-
s
+
- For every type
T
,
the type Allocator::rebind<T>::other::pointer
can be any
kind of random access iterator, provided that it is explicitly constructible from
@@ -804,7 +804,7 @@ number of elements of list
.
of the types of ctor_args_list
do not throw.
-allocator_type get_allocator()const;
+allocator_type get_allocator()const noexcept;
Returns a copy of the allocator_type
object used to construct
@@ -814,27 +814,25 @@ the multi_index_container
.
Index retrieval operations
-template<int N> typename nth_index<N>::type& get();
+template<int N> typename nth_index<N>::type& get()noexcept;
Requires: 0 <= N < I
.
Effects: Returns a reference to the
nth_index<N>::type
index held by *this
.
Complexity: Constant.
-Exception safety: nothrow
.
-template<int N> const typename nth_index<N>::type& get()const;
+template<int N> const typename nth_index<N>::type& get()const noexcept;
Requires: 0 <= N < I
.
Effects: Returns a const
reference to the
nth_index<N>::type
index held by *this
.
Complexity: Constant.
-Exception safety: nothrow
.
-template<typename Tag> typename index<Tag>::type& get()
+template<typename Tag> typename index<Tag>::type& get()noexcept;
Requires: Tag
is such that index<Tag>::type
@@ -843,10 +841,9 @@ is valid.
index<Tag>::type
index held by
*this
.
Complexity: Constant.
-Exception safety: nothrow
.
-template<typename Tag> const typename index<Tag>::type& get()const;
+template<typename Tag> const typename index<Tag>::type& get()const noexcept;
Requires: Tag
is such that index<Tag>::type
@@ -855,7 +852,6 @@ is valid.
index<Tag>::type
index held by
*this
.
Complexity: Constant.
-Exception safety: nothrow
.
Projection operations
@@ -996,7 +992,7 @@ Index reference
-Revised July 3rd 2013
+Revised October 12th 2013
© Copyright 2003-2013 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 de74590..bd21f91 100644
--- a/doc/reference/ord_indices.html
+++ b/doc/reference/ord_indices.html
@@ -243,31 +243,31 @@ do not exactly conform to or are not mandated by the standard requirements.
index class name& operator=(const index class name& x);
index class name& operator=(std::initializer_list<value_type> list);
- allocator_type get_allocator()const;
+ allocator_type get_allocator()const noexcept;
// iterators:
- iterator begin();
- const_iterator begin()const;
- iterator end();
- const_iterator end()const;
- reverse_iterator rbegin();
- const_reverse_iterator rbegin()const;
- reverse_iterator rend();
- const_reverse_iterator rend()const;
- const_iterator cbegin()const;
- const_iterator cend()const;
- const_reverse_iterator crbegin()const;
- const_reverse_iterator crend()const;
+ iterator begin()noexcept;
+ const_iterator begin()const noexcept;
+ iterator end()noexcept;
+ const_iterator end()const noexcept;
+ reverse_iterator rbegin()noexcept;
+ const_reverse_iterator rbegin()const noexcept;
+ reverse_iterator rend()noexcept;
+ const_reverse_iterator rend()const noexcept;
+ const_iterator cbegin()const noexcept;
+ const_iterator cend()const noexcept;
+ const_reverse_iterator crbegin()const noexcept;
+ const_reverse_iterator crend()const noexcept;
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
// capacity:
- bool empty()const;
- size_type size()const;
- size_type max_size()const;
+ bool empty()const noexcept;
+ size_type size()const noexcept;
+ size_type max_size()const noexcept;
// modifiers:
@@ -297,7 +297,7 @@ do not exactly conform to or are not mandated by the standard requirements.
bool modify_key(iterator position,Modifier mod,Rollback back);
void swap(index class name& x);
- void clear();
+ void clear()noexcept;
// observers:
@@ -631,7 +631,7 @@ to which this index belongs if
Effects:
-insert(list.begin(),list.end())
+insert(list.begin(),list.end());
@@ -1103,7 +1103,7 @@ Hashed indices
-Revised July 6th 2013
+Revised October 12th 2013
© Copyright 2003-2013 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 0e2dd7b..7ed5d15 100644
--- a/doc/reference/rnd_indices.html
+++ b/doc/reference/rnd_indices.html
@@ -230,32 +230,32 @@ plus the requirements for std::list
specific list operations at
void assign(std::initializer_list<value_type> list)
void assign(size_type n,const value_type& value);
- allocator_type get_allocator()const;
+ allocator_type get_allocator()const noexcept;
// iterators:
- iterator begin();
- const_iterator begin()const;
- iterator end();
- const_iterator end()const;
- reverse_iterator rbegin();
- const_reverse_iterator rbegin()const;
- reverse_iterator rend();
- const_reverse_iterator rend()const;
- const_iterator cbegin()const;
- const_iterator cend()const;
- const_reverse_iterator crbegin()const;
- const_reverse_iterator crend()const;
+ iterator begin()noexcept;
+ const_iterator begin()const noexcept;
+ iterator end()noexcept;
+ const_iterator end()const noexcept;
+ reverse_iterator rbegin()noexcept;
+ const_reverse_iterator rbegin()const noexcept;
+ reverse_iterator rend()noexcept;
+ const_reverse_iterator rend()const noexcept;
+ const_iterator cbegin()const noexcept;
+ const_iterator cend()const noexcept;
+ const_reverse_iterator crbegin()const noexcept;
+ const_reverse_iterator crend()const noexcept;
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
// capacity:
- bool empty()const;
- size_type size()const;
- size_type max_size()const;
- size_type capacity()const;
+ bool empty()const noexcept;
+ size_type size()const noexcept;
+ size_type max_size()const noexcept;
+ size_type capacity()const noexcept;
void reserve(size_type m);
void shrink_to_fit();
@@ -303,7 +303,7 @@ plus the requirements for std::list
specific list operations at
void swap(index class name& x);
- void clear();
+ void clear()noexcept;
// list operations:
@@ -325,7 +325,7 @@ plus the requirements for std::list
specific list operations at
void sort();
template <typename Compare> void sort(Compare comp);
- void reverse();
+ void reverse()noexcept;
// rearrange operations:
@@ -517,7 +517,7 @@ const_iterator iterator_to(const value_type& x)const;
Capacity operations
-size_type capacity()const;
+size_type capacity()const noexcept;
Returns: The total number of elements c
such that, when
@@ -987,13 +987,12 @@ is stable, i.e. equivalent elements preserve their relative position.
Exception safety: Basic.
-void reverse();
+void reverse()noexcept;
Effects: Reverses the order of the elements in the index.
Postconditions: Validity of iterators and references is preserved.
Complexity: O(n)
.
-Exception safety: nothrow
.
Rearrange operations
@@ -1108,7 +1107,7 @@ Key extraction
-Revised July 14th 2013
+Revised October 12th 2013
© Copyright 2003-2013 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 b9c93b5..4c3c7ed 100644
--- a/doc/reference/seq_indices.html
+++ b/doc/reference/seq_indices.html
@@ -218,31 +218,31 @@ most important differences are:
void assign(std::initializer_list<value_type> list);
void assign(size_type n,const value_type& value);
- allocator_type get_allocator()const;
+ allocator_type get_allocator()const noexcept;
// iterators:
- iterator begin();
- const_iterator begin()const;
- iterator end();
- const_iterator end()const;
- reverse_iterator rbegin();
- const_reverse_iterator rbegin()const;
- reverse_iterator rend();
- const_reverse_iterator rend()const;
- const_iterator cbegin()const;
- const_iterator cend()const;
- const_reverse_iterator crbegin()const;
- const_reverse_iterator crend()const;
+ iterator begin()noexcept;
+ const_iterator begin()const noexcept;
+ iterator end()noexcept;
+ const_iterator end()const noexcept;
+ reverse_iterator rbegin()noexcept;
+ const_reverse_iterator rbegin()const noexcept;
+ reverse_iterator rend()noexcept;
+ const_reverse_iterator rend()const noexcept;
+ const_iterator cbegin()const noexcept;
+ const_iterator cend()const noexcept;
+ const_reverse_iterator crbegin()const noexcept;
+ const_reverse_iterator crend()const noexcept;
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
// capacity:
- bool empty()const;
- size_type size()const;
- size_type max_size()const;
+ bool empty()const noexcept;
+ size_type size()const noexcept;
+ size_type max_size()const noexcept;
void resize(size_type n);
void resize(size_type n,const value_type& x);
@@ -286,7 +286,7 @@ most important differences are:
void swap(index class name& x);
- void clear();
+ void clear()noexcept;
// list operations:
@@ -308,7 +308,7 @@ most important differences are:
void sort();
template <typename Compare> void sort(Compare comp);
- void reverse();
+ void reverse()noexcept;
// rearrange operations:
@@ -922,13 +922,12 @@ is stable, i.e. equivalent elements preserve their relative position.
not throw; otherwise, basic.
-void reverse();
+void reverse()noexcept;
Effects: Reverses the order of the elements in the index.
Postconditions: Validity of iterators and references is preserved.
Complexity: O(n)
.
-Exception safety: nothrow
.
Rearrange operations
@@ -1043,7 +1042,7 @@ Random access indices
-Revised July 8th 2013
+Revised October 12th 2013
© Copyright 2003-2013 Joaquín M López Muñoz.
Distributed under the Boost Software
diff --git a/doc/release_notes.html b/doc/release_notes.html
index 22ed2ca..20914a4 100644
--- a/doc/release_notes.html
+++ b/doc/release_notes.html
@@ -30,6 +30,7 @@ Acknowledgements
Contents
+ - Boost 1.56 release
- Boost 1.55 release
- Boost 1.54 release
- Boost 1.49 release
@@ -48,6 +49,45 @@ Acknowledgements
- Boost 1.33 release
+Boost 1.56 release
+
+
+
+ - The
erase(iterator)
member function of hashed indices
+ used to have poor performance under low load conditions due to the requirement
+ that an iterator to the next element must be returned (see ticket
+ #4264). In accordance with
+ the resolution of LWG
+ issue #579, this problem has been fixed while maintaining the interface of
+ erase
, at the expense of using one more
+ word of memory per element. In fact, C++ complexity requirements on unordered
+ associative containers have been improved for hashed indices so that
+
+ - deletion of a given element is unconditionally constant-time,
+ - worst-case performance is not
O(n)
but O(ndist)
,
+ where ndist
is the number of non-equivalent elements in the index.
+
+
+ Due to the fact that hashed indices rely on a new data structure, the internal representation of
+ their iterators and local iterators have changed, which affects serialization: their corresponding
+ serialization class version has been
+ bumped from 0 to 1. Old archives involving hashed index (local) iterators can be loaded
+ by Boost 1.56 version of Boost.MultiIndex, but not the other way around.
+
+ - Hashed indices now provide
reserve
.
+ - Hashed indices can now be checked for equality and inequality following the
+ (suitably adapted) C++ standard specification in [unord.req].
+ - The public interface of Boost.MultiIndex provide
noexcept
specifications
+ where appropriate (for compliant compilers).
+
+ - Improved performance of failed insertions into a
multi_index_container
.
+ - Much internal code aimed at supporting MSVC++ 7.0 and prior has been removed.
+ Compilation times without this legacy code might be slightly faster.
+
+ - Maintenance fixes.
+
+
+
Boost 1.55 release
@@ -81,6 +121,7 @@ Acknowledgements
Maintenance fixes.
+
Boost 1.54 release
@@ -404,7 +445,7 @@ Acknowledgements
-
Revised July 9st 2013
+Revised November 30th 2013
© Copyright 2003-2013 Joaquín M López Muñoz.
Distributed under the Boost Software
diff --git a/example/basic.cpp b/example/basic.cpp
index af31048..f7c46ce 100644
--- a/example/basic.cpp
+++ b/example/basic.cpp
@@ -1,6 +1,6 @@
/* Boost.MultiIndex basic example.
*
- * 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)
@@ -69,10 +69,7 @@ typedef multi_index_container<
> employee_set;
template
-void print_out_by(
- const MultiIndexContainer& s,
- Tag* =0 /* fixes a MSVC++ 6.0 bug with implicit template function parms */
-)
+void print_out_by(const MultiIndexContainer& s)
{
/* obtain a reference to the index tagged by Tag */
diff --git a/example/composite_keys.cpp b/example/composite_keys.cpp
index 9de947d..e9da2af 100644
--- a/example/composite_keys.cpp
+++ b/example/composite_keys.cpp
@@ -81,19 +81,9 @@ typedef multi_index_container<
file_entry,
indexed_by<
/* primary index sorted by name (inside the same directory) */
- ordered_unique<
- name_key
-#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
- ,composite_key_result_less
-#endif
- >,
+ ordered_unique,
/* secondary index sorted by size (inside the same directory) */
- ordered_non_unique<
- size_key
-#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
- ,composite_key_result_less
-#endif
- >
+ ordered_non_unique
>
> file_system;
diff --git a/include/boost/multi_index/composite_key.hpp b/include/boost/multi_index/composite_key.hpp
index 2c21a6a..cf3349d 100644
--- a/include/boost/multi_index/composite_key.hpp
+++ b/include/boost/multi_index/composite_key.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)
@@ -9,19 +9,17 @@
#ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
#include /* keep it first to prevent nasty warns in MSVC */
#include
#include
-#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -59,12 +57,8 @@
*/
#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE)
-#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
-#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 5
-#else
#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10
#endif
-#endif
/* maximum number of key extractors in a composite key */
@@ -114,17 +108,14 @@ namespace detail{
/* n-th key extractor of a composite key */
-template
+template
struct nth_key_from_value
{
typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple;
- typedef typename prevent_eti<
+ typedef typename mpl::eval_if_c<
+ N::value,
tuples::element,
- typename mpl::eval_if_c<
- N::value,
- tuples::element,
- mpl::identity
- >::type
+ mpl::identity
>::type type;
};
@@ -146,7 +137,7 @@ struct BOOST_PP_CAT(key_,name) \
typedef tuples::null_type type; \
}; \
\
-template \
+template \
struct BOOST_PP_CAT(nth_composite_key_,name) \
{ \
typedef typename nth_key_from_value::type key_from_value; \
@@ -589,16 +580,6 @@ struct composite_key_result
/* composite_key */
-/* NB. Some overloads of operator() have an extra dummy parameter int=0.
- * This disambiguator serves several purposes:
- * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
- * specializations of a previous member function template.
- * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
- * as if they have the same signature.
- * - If remove_const is broken due to lack of PTS, int=0 avoids the
- * declaration of memfuns with identical signature.
- */
-
template<
typename Value,
BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue)
@@ -648,7 +629,7 @@ public:
return result_type(*this,x.get());
}
- result_type operator()(const reference_wrapper& x,int=0)const
+ result_type operator()(const reference_wrapper& x)const
{
return result_type(*this,x.get());
}
@@ -1238,7 +1219,6 @@ public:
* for composite_key_results enabling interoperation with tuples of values.
*/
-#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace std{
template
@@ -1278,34 +1258,6 @@ struct hash >:
};
} /* namespace boost */
-#else
-/* Lacking template partial specialization, std::equal_to, std::less and
- * std::greater will still work for composite_key_results although without
- * tuple interoperability. To achieve the same graceful degrading with
- * boost::hash, we define the appropriate hash_value overload.
- */
-
-namespace boost{
-
-#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
-namespace multi_index{
-#endif
-
-template
-inline std::size_t hash_value(
- const boost::multi_index::composite_key_result& x)
-{
- boost::multi_index::composite_key_result_hash<
- boost::multi_index::composite_key_result > h;
- return h(x);
-}
-
-#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
-} /* namespace multi_index */
-#endif
-
-} /* namespace boost */
-#endif
#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER
#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER
diff --git a/include/boost/multi_index/detail/access_specifier.hpp b/include/boost/multi_index/detail/access_specifier.hpp
index 84c2f7d..f3346e8 100644
--- a/include/boost/multi_index/detail/access_specifier.hpp
+++ b/include/boost/multi_index/detail/access_specifier.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -42,8 +42,7 @@
* official Sun Studio 12.
*/
-#if BOOST_WORKAROUND(__GNUC__, <3)||\
- BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
+#if BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\
BOOST_WORKAROUND(BOOST_MSVC,==1310)||\
BOOST_WORKAROUND(BOOST_MSVC,==1400)||\
BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
diff --git a/include/boost/multi_index/detail/adl_swap.hpp b/include/boost/multi_index/detail/adl_swap.hpp
index e78235d..02b0644 100644
--- a/include/boost/multi_index/detail/adl_swap.hpp
+++ b/include/boost/multi_index/detail/adl_swap.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/archive_constructed.hpp b/include/boost/multi_index/detail/archive_constructed.hpp
index ee00dfa..0cf7991 100644
--- a/include/boost/multi_index/detail/archive_constructed.hpp
+++ b/include/boost/multi_index/detail/archive_constructed.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/auto_space.hpp b/include/boost/multi_index/detail/auto_space.hpp
index 00e5470..9d78c3a 100644
--- a/include/boost/multi_index/detail/auto_space.hpp
+++ b/include/boost/multi_index/detail/auto_space.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
@@ -46,11 +45,8 @@ namespace detail{
template >
struct auto_space:private noncopyable
{
- typedef typename prevent_eti<
- Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,T
- >::type
+ typedef typename boost::detail::allocator::rebind_to<
+ Allocator,T
>::type::pointer pointer;
explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1):
diff --git a/include/boost/multi_index/detail/base_type.hpp b/include/boost/multi_index/detail/base_type.hpp
index d25332e..8c9b62b 100644
--- a/include/boost/multi_index/detail/base_type.hpp
+++ b/include/boost/multi_index/detail/base_type.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -20,7 +20,6 @@
#include
#include
#include
-#include
#include
namespace boost{
@@ -33,17 +32,6 @@ namespace detail{
* a index list.
*/
-#if BOOST_WORKAROUND(BOOST_MSVC,<1310)
-struct index_applier
-{
- template
- struct apply:
- msvc_index_specifier::
- template result_index_class
- {
- };
-};
-#else
struct index_applier
{
template
@@ -54,7 +42,6 @@ struct index_applier
BOOST_NESTED_TEMPLATE index_class::type type;
};
};
-#endif
template
struct nth_layer
diff --git a/include/boost/multi_index/detail/bidir_node_iterator.hpp b/include/boost/multi_index/detail/bidir_node_iterator.hpp
index 2155255..9bb0470 100644
--- a/include/boost/multi_index/detail/bidir_node_iterator.hpp
+++ b/include/boost/multi_index/detail/bidir_node_iterator.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/bucket_array.hpp b/include/boost/multi_index/detail/bucket_array.hpp
index a6772ad..14220c9 100644
--- a/include/boost/multi_index/detail/bucket_array.hpp
+++ b/include/boost/multi_index/detail/bucket_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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,8 +17,11 @@
#include
#include
#include
-#include
#include
+#include
+#include
+#include
+#include
#include
#include
@@ -36,115 +39,143 @@ namespace detail{
/* bucket structure for use by hashed indices */
+#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \
+(53ul)(97ul)(193ul)(389ul)(769ul) \
+(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \
+(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
+(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
+(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
+(1610612741ul)(3221225473ul)
+
+#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
+#define BOOST_MULTI_INDEX_BA_SIZES \
+BOOST_MULTI_INDEX_BA_SIZES_32BIT \
+(4294967291ul)
+#else
+ /* obtained with aid from
+ * http://javaboutique.internet.com/prime_numb/
+ * http://www.rsok.com/~jrm/next_ten_primes.html
+ * and verified with
+ * http://www.alpertron.com.ar/ECM.HTM
+ */
+
+#define BOOST_MULTI_INDEX_BA_SIZES \
+BOOST_MULTI_INDEX_BA_SIZES_32BIT \
+(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \
+(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \
+(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \
+(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \
+(422212465066001ul)(844424930131963ul)(1688849860263953ul) \
+(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \
+(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \
+(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \
+(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \
+(13835058055282163729ul)(18446744073709551557ul)
+#endif
+
+template /* templatized to have in-header static var defs */
class bucket_array_base:private noncopyable
{
protected:
- inline static std::size_t next_prime(std::size_t n)
+ static const std::size_t sizes[];
+
+ static std::size_t size_index(std::size_t n)
{
- static const std::size_t prime_list[]={
- 53ul, 97ul, 193ul, 389ul, 769ul,
- 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
- 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
- 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
- 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
- 1610612741ul, 3221225473ul,
-
-#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */
- 4294967291ul
-#else
- /* obtained with aid from
- * http://javaboutique.internet.com/prime_numb/
- * http://www.rsok.com/~jrm/next_ten_primes.html
- * and verified with
- * http://www.alpertron.com.ar/ECM.HTM
- */
-
- 6442450939ul, 12884901893ul, 25769803751ul, 51539607551ul,
- 103079215111ul, 206158430209ul, 412316860441ul, 824633720831ul,
- 1649267441651ul, 3298534883309ul, 6597069766657ul, 13194139533299ul,
- 26388279066623ul, 52776558133303ul, 105553116266489ul, 211106232532969ul,
- 422212465066001ul, 844424930131963ul, 1688849860263953ul,
- 3377699720527861ul, 6755399441055731ul, 13510798882111483ul,
- 27021597764222939ul, 54043195528445957ul, 108086391056891903ul,
- 216172782113783843ul, 432345564227567621ul, 864691128455135207ul,
- 1729382256910270481ul, 3458764513820540933ul, 6917529027641081903ul,
- 13835058055282163729ul, 18446744073709551557ul
-#endif
-
- };
- static const std::size_t prime_list_size=
- sizeof(prime_list)/sizeof(prime_list[0]);
-
- std::size_t const *bound=
- std::lower_bound(prime_list,prime_list+prime_list_size,n);
- if(bound==prime_list+prime_list_size)bound--;
- return *bound;
+ const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n);
+ if(bound==sizes+sizes_length)bound--;
+ return bound-sizes;
}
+
+#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \
+ case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES);
+
+ static std::size_t position(std::size_t hash,std::size_t size_index_)
+ {
+ /* Accelerate hash%sizes[size_index_] by replacing with a switch on
+ * hash%Ci expressions, each Ci a compile-time constant, which the
+ * compiler can implement without using integer division.
+ */
+
+ switch(size_index_){
+ default: /* never used */
+ BOOST_PP_REPEAT(
+ BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES),
+ BOOST_MULTI_INDEX_BA_POSITION_CASE,~)
+ }
+ }
+
+private:
+ static const std::size_t sizes_length;
};
+template
+const std::size_t bucket_array_base<_>::sizes[]={
+ BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES)
+};
+
+template
+const std::size_t bucket_array_base<_>::sizes_length=
+ sizeof(bucket_array_base<_>::sizes)/
+ sizeof(bucket_array_base<_>::sizes[0]);
+
+#undef BOOST_MULTI_INDEX_BA_POSITION_CASE
+#undef BOOST_MULTI_INDEX_BA_SIZES
+#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT
+
template
-class bucket_array:public bucket_array_base
+class bucket_array:bucket_array_base<>
{
- typedef typename prevent_eti<
- Allocator,
- hashed_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- Allocator,
- char
- >::type
- >
- >::type node_impl_type;
+ typedef bucket_array_base<> super;
+ typedef hashed_index_base_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ Allocator,
+ char
+ >::type
+ > base_node_impl_type;
public:
- typedef typename node_impl_type::pointer pointer;
+ typedef typename base_node_impl_type::base_pointer base_pointer;
+ typedef typename base_node_impl_type::pointer pointer;
- bucket_array(const Allocator& al,pointer end_,std::size_t size):
- size_(bucket_array_base::next_prime(size)),
- spc(al,size_+1)
+ bucket_array(const Allocator& al,pointer end_,std::size_t size_):
+ size_index_(super::size_index(size_)),
+ spc(al,super::sizes[size_index_]+1)
{
- clear();
- end()->next()=end_;
- end_->next()=end();
+ clear(end_);
}
std::size_t size()const
{
- return size_;
+ return super::sizes[size_index_];
}
std::size_t position(std::size_t hash)const
{
- return hash%size_;
+ return super::position(hash,size_index_);
}
- pointer begin()const{return buckets();}
- pointer end()const{return buckets()+size_;}
- pointer at(std::size_t n)const{return buckets()+n;}
+ base_pointer begin()const{return buckets();}
+ base_pointer end()const{return buckets()+size();}
+ base_pointer at(std::size_t n)const{return buckets()+n;}
- std::size_t first_nonempty(std::size_t n)const
+ void clear(pointer end_)
{
- for(;;++n){
- pointer x=at(n);
- if(x->next()!=x)return n;
- }
- }
-
- void clear()
- {
- for(pointer x=begin(),y=end();x!=y;++x)x->next()=x;
- }
+ for(base_pointer x=begin(),y=end();x!=y;++x)x->next()=pointer(0);
+ end()->next()=end_->next()=end_;
+ end_->prior()=end();
+ }
void swap(bucket_array& x)
{
- std::swap(size_,x.size_);
+ std::swap(size_index_,x.size_index_);
spc.swap(x.spc);
}
private:
- std::size_t size_;
- auto_space spc;
+ std::size_t size_index_;
+ auto_space spc;
- pointer buckets()const
+ base_pointer buckets()const
{
return spc.data();
}
diff --git a/include/boost/multi_index/detail/converter.hpp b/include/boost/multi_index/detail/converter.hpp
index a46cff6..3e04a3e 100644
--- a/include/boost/multi_index/detail/converter.hpp
+++ b/include/boost/multi_index/detail/converter.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/copy_map.hpp b/include/boost/multi_index/detail/copy_map.hpp
index 4279a8d..a0b6cad 100644
--- a/include/boost/multi_index/detail/copy_map.hpp
+++ b/include/boost/multi_index/detail/copy_map.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -110,20 +109,18 @@ public:
}
private:
- typedef typename prevent_eti<
- Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,Node>::type
- >::type allocator_type;
- typedef typename allocator_type::pointer allocator_pointer;
+ typedef typename boost::detail::allocator::rebind_to<
+ Allocator,Node
+ >::type allocator_type;
+ typedef typename allocator_type::pointer allocator_pointer;
- allocator_type al_;
- std::size_t size_;
- auto_space,Allocator> spc;
- std::size_t n;
- Node* header_org_;
- Node* header_cpy_;
- bool released;
+ allocator_type al_;
+ std::size_t size_;
+ auto_space,Allocator> spc;
+ std::size_t n;
+ Node* header_org_;
+ Node* header_cpy_;
+ bool released;
void deallocate(Node* node)
{
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
index a7b3f18..f0fa730 100644
--- a/include/boost/multi_index/detail/do_not_copy_elements_tag.hpp
+++ b/include/boost/multi_index/detail/do_not_copy_elements_tag.hpp
@@ -9,7 +9,7 @@
#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)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/duplicates_iterator.hpp b/include/boost/multi_index/detail/duplicates_iterator.hpp
index 027dabd..cbebf26 100644
--- a/include/boost/multi_index/detail/duplicates_iterator.hpp
+++ b/include/boost/multi_index/detail/duplicates_iterator.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/has_tag.hpp b/include/boost/multi_index/detail/has_tag.hpp
index 83b28cc..217b611 100644
--- a/include/boost/multi_index/detail/has_tag.hpp
+++ b/include/boost/multi_index/detail/has_tag.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/hash_index_args.hpp b/include/boost/multi_index/detail/hash_index_args.hpp
index 4972f9b..81902f5 100644
--- a/include/boost/multi_index/detail/hash_index_args.hpp
+++ b/include/boost/multi_index/detail/hash_index_args.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/hash_index_iterator.hpp b/include/boost/multi_index/detail/hash_index_iterator.hpp
index 352c1d8..fb1a967 100644
--- a/include/boost/multi_index/detail/hash_index_iterator.hpp
+++ b/include/boost/multi_index/detail/hash_index_iterator.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -19,6 +19,7 @@
#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
#include
#include
+#include
#endif
namespace boost{
@@ -30,10 +31,13 @@ namespace detail{
/* Iterator class for hashed indices.
*/
-template
+struct hashed_index_global_iterator_tag{};
+struct hashed_index_local_iterator_tag{};
+
+template
class hashed_index_iterator:
public forward_iterator_helper<
- hashed_index_iterator,
+ hashed_index_iterator,
typename Node::value_type,
std::ptrdiff_t,
const typename Node::value_type*,
@@ -41,9 +45,7 @@ class hashed_index_iterator:
{
public:
hashed_index_iterator(){}
- hashed_index_iterator(Node* node_,BucketArray* buckets_):
- node(node_),buckets(buckets_)
- {}
+ hashed_index_iterator(Node* node_):node(node_){}
const typename Node::value_type& operator*()const
{
@@ -52,7 +54,7 @@ public:
hashed_index_iterator& operator++()
{
- Node::increment(node,buckets->begin(),buckets->end());
+ this->increment(Category());
return *this;
}
@@ -70,16 +72,42 @@ public:
{
node_base_type* bnode=node;
ar<
- void load(Archive& ar,const unsigned int)
+ void load(Archive& ar,const unsigned int version)
+ {
+ load(ar,version,Category());
+ }
+
+ template
+ void load(
+ Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
{
node_base_type* bnode;
ar>>serialization::make_nvp("pointer",bnode);
node=static_cast(bnode);
- ar>>serialization::make_nvp("pointer",buckets);
+ if(version<1){
+ BucketArray* throw_away; /* consume unused ptr */
+ ar>>serialization::make_nvp("pointer",throw_away);
+ }
+ }
+
+ template
+ void load(
+ Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
+ {
+ node_base_type* bnode;
+ ar>>serialization::make_nvp("pointer",bnode);
+ node=static_cast(bnode);
+ if(version<1){
+ BucketArray* buckets;
+ ar>>serialization::make_nvp("pointer",buckets);
+ if(buckets&&node&&node->impl()==buckets->end()->next()->next()){
+ /* end local_iterators used to point to end node, now they are null */
+ node=0;
+ }
+ }
}
#endif
@@ -90,14 +118,24 @@ public:
Node* get_node()const{return node;}
private:
- Node* node;
- BucketArray* buckets;
+
+ void increment(hashed_index_global_iterator_tag)
+ {
+ Node::increment(node);
+ }
+
+ void increment(hashed_index_local_iterator_tag)
+ {
+ Node::increment_local(node);
+ }
+
+ Node* node;
};
-template
+template
bool operator==(
- const hashed_index_iterator& x,
- const hashed_index_iterator& y)
+ const hashed_index_iterator& x,
+ const hashed_index_iterator& y)
{
return x.get_node()==y.get_node();
}
@@ -106,6 +144,22 @@ bool operator==(
} /* namespace multi_index */
+#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
+/* class version = 1 : hashed_index_iterator does no longer serialize a bucket
+ * array pointer.
+ */
+
+namespace serialization {
+template
+struct version<
+ boost::multi_index::detail::hashed_index_iterator
+>
+{
+ BOOST_STATIC_CONSTANT(int,value=1);
+};
+} /* namespace serialization */
+#endif
+
} /* namespace boost */
#endif
diff --git a/include/boost/multi_index/detail/hash_index_node.hpp b/include/boost/multi_index/detail/hash_index_node.hpp
index edb2c10..11290e1 100644
--- a/include/boost/multi_index/detail/hash_index_node.hpp
+++ b/include/boost/multi_index/detail/hash_index_node.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)
@@ -9,14 +9,12 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
#include /* keep it first to prevent nasty warns in MSVC */
#include
-#include
-#include
namespace boost{
@@ -24,104 +22,632 @@ namespace multi_index{
namespace detail{
-/* singly-linked node for use by hashed_index */
+/* Certain C++ requirements on unordered associative containers (see LWG issue
+ * #579) imply a data structure where nodes are linked in a single list, which
+ * in its turn forces implementors to add additional overhed per node to
+ * associate each with its corresponding bucket. Others resort to storing hash
+ * values, we use an alternative structure providing unconditional O(1)
+ * manipulation, even in situations of unfair hash distribution, plus some
+ * lookup speedups. For unique indices we maintain a doubly linked list of
+ * nodes except that the first node N of a bucket is back-linked to its bucket
+ * node, and this bucket node forward links to the node preceding N.
+ *
+ * +---+ +---+ +---+ +---+
+ * | +-->| +--> | +-->| +-->
+ * ... | B0| | B1| ... | B1| | B2| ...
+ * <--+ | +-+ | <--+ | +-+ |
+ * +---+ | +---+ +---+ | +---+
+ * ^ | ^ |
+ * | | | |
+ * +-+ | +-+ |
+ * | | | |
+ * + v + v
+ * --+---+---+---+-- --+---+---+---+--
+ * ... | | B1| | ... | | B2| | ...
+ * --+---+---+---+-- --+---+---+---+--
+ *
+ * The fist and last nodes of buckets can be checked with
+ *
+ * first node of a bucket: Npn != N
+ * last node of a bucket: Nnp != N
+ *
+ * (n and p short for ->next(), ->prior()). Pure insert and erase (without
+ * lookup) can be unconditionally done in O(1).
+ * For non-unique indices we add the following additional complexity: when
+ * there is a group of 3 or more equivalent elements, they are linked as
+ * follows:
+ *
+ * +-----------------------+
+ * v |
+ * +---+ +---+ +---+ | +---+
+ * | +-->| | | +-+ | |
+ * | F | | S | ... | P | | L |
+ * | | +-+ | | |<--+ |
+ * +---+ | +---+ +---+ +---+
+ * | ^
+ * +-----------------------+
+ *
+ * F, S, P and L are the first, second, penultimate and last node in the
+ * group, respectively (S and P can coincide if the group has size 3.) This
+ * arrangement is used to skip equivalent elements in O(1) when doing lookup,
+ * while preserving O(1) insert/erase. The following invariants identify
+ * special positions (some of the operations have to be carefully implemented
+ * as Xpp is not valid if Xp points to a bucket):
+ *
+ * first node of a bucket: Npnn == N
+ * last node of a bucket: Nnpn == N
+ * first node of a group: Nnp != N && Nnppn == N
+ * second node of a group: Npn != N && Nppnn == N
+ * n-1 node of a group: Nnp != N && Nnnpp == N
+ * last node of a group: Npn != N && Npnnp == N
+ *
+ * The memory overhead is one pointer per bucket plus two pointers per node,
+ * probably unbeatable. The resulting structure is bidirectonally traversable,
+ * though currently we are just providing forward iteration.
+ */
template
-struct hashed_index_node_impl
+struct hashed_index_node_impl;
+
+/* half-header (only next() pointer) to use for the bucket array */
+
+template
+struct hashed_index_base_node_impl
{
- typedef typename prevent_eti<
+ typedef typename
+ boost::detail::allocator::rebind_to<
+ Allocator,hashed_index_base_node_impl
+ >::type::pointer base_pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
+ Allocator,hashed_index_base_node_impl
+ >::type::const_pointer const_base_pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,hashed_index_node_impl
- >::type
- >::type::pointer pointer;
- typedef typename prevent_eti<
+ hashed_index_node_impl
+ >::type::pointer pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,hashed_index_node_impl
- >::type
- >::type::const_pointer const_pointer;
+ hashed_index_node_impl
+ >::type::const_pointer const_pointer;
pointer& next(){return next_;}
pointer next()const{return next_;}
- /* algorithmic stuff */
-
- static void increment(pointer& x,pointer bbegin,pointer bend)
- {
- std::less_equal leq;
-
- x=x->next();
- if(leq(bbegin,x)&&leq(x,bend)){ /* bucket node */
- do{
- ++x;
- }while(x->next()==x);
- x=x->next();
- }
- }
-
- static void link(pointer x,pointer pos)
- {
- x->next()=pos->next();
- pos->next()=x;
- };
-
- static void unlink(pointer x)
- {
- pointer y=x->next();
- while(y->next()!=x){y=y->next();}
- y->next()=x->next();
- }
-
- static pointer prev(pointer x)
- {
- pointer y=x->next();
- while(y->next()!=x){y=y->next();}
- return y;
- }
-
- static void unlink_next(pointer x)
- {
- x->next()=x->next()->next();
- }
-
private:
pointer next_;
};
-template
-struct hashed_index_node_trampoline:
- prevent_eti<
- Super,
- hashed_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type
+/* full header (next() and prior()) for the nodes */
+
+template
+struct hashed_index_node_impl:hashed_index_base_node_impl
{
- typedef typename prevent_eti<
- Super,
- hashed_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type impl_type;
+private:
+ typedef hashed_index_base_node_impl super;
+
+public:
+ typedef typename super::base_pointer base_pointer;
+ typedef typename super::const_base_pointer const_base_pointer;
+ typedef typename super::pointer pointer;
+ typedef typename super::const_pointer const_pointer;
+
+ base_pointer& prior(){return prior_;}
+ base_pointer prior()const{return prior_;}
+
+ static pointer pointer_from(base_pointer x)
+ {
+ return static_cast(static_cast(&*x));
+ }
+
+ static base_pointer base_pointer_from(pointer x)
+ {
+ return static_cast(&*x);
+ }
+
+private:
+ base_pointer prior_;
+};
+
+/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple
+ * way to make a pointer-manipulation function undoable is to templatize
+ * its internal pointer assignments with a functor that, besides doing the
+ * assignment, keeps track of the original pointer values and can later undo
+ * the operations in reverse order.
+ */
+
+struct default_assigner
+{
+ template void operator()(T& x,const T& val){x=val;}
+};
+
+template
+struct unlink_undo_assigner
+{
+ typedef typename Node::base_pointer base_pointer;
+ typedef typename Node::pointer pointer;
+
+ unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){}
+
+ void operator()(pointer& x,pointer val)
+ {
+ pointer_tracks[pointer_track_count].x=&x;
+ pointer_tracks[pointer_track_count++].val=x;
+ x=val;
+ }
+
+ void operator()(base_pointer& x,base_pointer val)
+ {
+ base_pointer_tracks[base_pointer_track_count].x=&x;
+ base_pointer_tracks[base_pointer_track_count++].val=x;
+ x=val;
+ }
+
+ void operator()() /* undo op */
+ {
+ /* in the absence of aliasing, restitution order is immaterial */
+
+ while(pointer_track_count--){
+ *(pointer_tracks[pointer_track_count].x)=
+ pointer_tracks[pointer_track_count].val;
+ }
+ while(base_pointer_track_count--){
+ *(base_pointer_tracks[base_pointer_track_count].x)=
+ base_pointer_tracks[base_pointer_track_count].val;
+ }
+ }
+
+ struct pointer_track {pointer* x; pointer val;};
+ struct base_pointer_track{base_pointer* x; base_pointer val;};
+
+ /* We know the maximum number of pointer and base pointer assignments that
+ * the two unlink versions do, so we can statically reserve the needed
+ * storage.
+ */
+
+ pointer_track pointer_tracks[3];
+ int pointer_track_count;
+ base_pointer_track base_pointer_tracks[2];
+ int base_pointer_track_count;
+};
+
+/* algorithmic stuff for unique and non-unique variants */
+
+struct hashed_unique_tag{};
+struct hashed_non_unique_tag{};
+
+template
+struct hashed_index_node_alg;
+
+template
+struct hashed_index_node_alg
+{
+ typedef typename Node::base_pointer base_pointer;
+ typedef typename Node::const_base_pointer const_base_pointer;
+ typedef typename Node::pointer pointer;
+ typedef typename Node::const_pointer const_pointer;
+
+ static bool is_first_of_bucket(pointer x)
+ {
+ return x->prior()->next()!=x;
+ }
+
+ static pointer after(pointer x)
+ {
+ return x->next();
+ }
+
+ static pointer after_local(pointer x)
+ {
+ return is_last_of_bucket(x)?pointer(0):after(x);
+ }
+
+ static pointer next_to_inspect(pointer x)
+ {
+ pointer y=x->next();
+ if(y->prior()==base_pointer_from(x))return y;
+ else return pointer(0); /* x last of bucket, bucket finished */
+ }
+
+ static void link(pointer x,base_pointer buc,pointer end)
+ {
+ if(buc->next()==pointer(0)){ /* empty bucket */
+ x->next()=end->next();
+ x->next()->prior()->next()=x;
+ x->prior()=buc;
+ buc->next()=end;
+ end->next()=x;
+ }
+ else{
+ x->next()=buc->next()->next();
+ x->next()->prior()=base_pointer_from(x);
+ x->prior()=buc;
+ buc->next()->next()=x;
+ }
+ };
+
+ static void unlink(pointer x)
+ {
+ default_assigner assign;
+ unlink(x,assign);
+ }
+
+ typedef unlink_undo_assigner unlink_undo;
+
+ template
+ static void unlink(pointer x,Assigner& assign)
+ {
+ if(is_first_of_bucket(x)){
+ if(is_last_of_bucket(x)){
+ assign(x->prior()->next()->next(),x->next());
+ assign(x->next()->prior()->next(),x->prior()->next());
+ assign(x->prior()->next(),pointer(0));
+ }
+ else{
+ assign(x->prior()->next()->next(),x->next());
+ assign(x->next()->prior(),x->prior());
+ }
+ }
+ else if(is_last_of_bucket(x)){
+ assign(x->prior()->next(),x->next());
+ assign(x->next()->prior()->next(),pointer_from(x->prior()));
+ }
+ else{
+ assign(x->prior()->next(),x->next());
+ assign(x->next()->prior(),x->prior());
+ }
+ }
+
+private:
+ static pointer pointer_from(base_pointer x)
+ {
+ return Node::pointer_from(x);
+ }
+
+ static base_pointer base_pointer_from(pointer x)
+ {
+ return Node::base_pointer_from(x);
+ }
+
+ static bool is_last_of_bucket(pointer x)
+ {
+ return x->next()->prior()!=base_pointer_from(x);
+ }
+};
+
+template
+struct hashed_index_node_alg
+{
+ typedef typename Node::base_pointer base_pointer;
+ typedef typename Node::const_base_pointer const_base_pointer;
+ typedef typename Node::pointer pointer;
+ typedef typename Node::const_pointer const_pointer;
+
+ static bool is_first_of_bucket(pointer x)
+ {
+ return x->prior()->next()->next()==x;
+ }
+
+ static bool is_first_of_group(pointer x)
+ {
+ return
+ x->next()->prior()!=base_pointer_from(x)&&
+ !is_first_of_bucket(x->next())&&
+ pointer_from(x->next()->prior())->prior()->next()==base_pointer_from(x);
+ }
+
+ static pointer after(pointer x)
+ {
+ if(is_last_but_one_of_group(x)){
+ return pointer_from(x->next()->next()->prior());
+ }
+ else{
+ return x->next();
+ }
+ }
+
+ static pointer after_local(pointer x)
+ {
+ return is_last_of_bucket(x)?pointer(0):after(x);
+ }
+
+ static pointer next_to_inspect(pointer x)
+ {
+ pointer y=x->next();
+ if(y->prior()==base_pointer_from(x))return y;
+ pointer z=y->prior()->next();
+ if(z==x|| /* x last of bucket */
+ z->prior()->next()!=z) /* group(x) last of bucket */
+ return pointer(0); /* bucket finished */
+ else return z;
+ }
+
+ static void link(pointer x,base_pointer buc,pointer end)
+ {
+ if(buc->next()==pointer(0)){ /* empty bucket */
+ x->next()=end->next();
+ x->next()->prior()->next()=x;
+ x->prior()=buc;
+ buc->next()=end;
+ end->next()=x;
+ }
+ else{
+ x->next()=buc->next()->next();
+ x->next()->prior()=base_pointer_from(x);
+ x->prior()=buc;
+ buc->next()->next()=x;
+ }
+ };
+
+ static void link(pointer x,pointer first,pointer last)
+ {
+ x->prior()=first->prior();
+ x->next()=first;
+ if(is_first_of_bucket(first)){
+ x->prior()->next()->next()=x;
+ }
+ else{
+ x->prior()->next()=x;
+ }
+
+ if(first==last){
+ last->prior()=base_pointer_from(x);
+ }
+ else if(first->next()==last){
+ first->prior()=base_pointer_from(last);
+ first->next()=x;
+ }
+ else{
+ pointer second=first->next(),
+ lastbutone=pointer_from(last->prior());
+ second->prior()=base_pointer_from(first);
+ first->prior()=base_pointer_from(last);
+ lastbutone->next()=x;
+ }
+ }
+
+ static void link_range(
+ pointer first,pointer last,base_pointer buc,pointer cend)
+ {
+ if(buc->next()==pointer(0)){ /* empty bucket */
+ last->next()=cend->next();
+ last->next()->prior()->next()=last;
+ first->prior()=buc;
+ buc->next()=cend;
+ cend->next()=first;
+ }
+ else{
+ last->next()=buc->next()->next();
+ last->next()->prior()=base_pointer_from(last);
+ first->prior()=buc;
+ buc->next()->next()=first;
+ }
+ }
+
+ static void unlink(pointer x)
+ {
+ default_assigner assign;
+ unlink(x,assign);
+ }
+
+ typedef unlink_undo_assigner unlink_undo;
+
+ template
+ static void unlink(pointer x,Assigner& assign)
+ {
+ if(x->prior()->next()==x){
+ if(x->next()->prior()==base_pointer_from(x)){
+ left_unlink(x,assign);
+ right_unlink(x,assign);
+ }
+ else if(x->next()->prior()->next()==x){ /* last of bucket */
+ left_unlink(x,assign);
+ right_unlink_last_of_bucket(x,assign);
+ }
+ else if(x->next()->next()==x){ /* first of group size==3 */
+ left_unlink(x,assign);
+ assign(x->next()->next(),pointer_from(x->next()->prior()));
+ right_unlink(x,assign);
+ }
+ else if(
+ x->next()->next()->prior()==
+ base_pointer_from(x->next())){ /* first of group size>3 */
+ left_unlink(x,assign);
+ right_unlink_first_of_group_gt_3(x,assign);
+ }
+ else{ /* n-1 of group size>3 */
+ unlink_last_but_one_of_group_gt_3(x,assign);
+ }
+ }
+ else if(x->prior()->next()->next()==x){ /* first of bucket */
+ if(x->next()->prior()==base_pointer_from(x)){
+ left_unlink_first_of_bucket(x,assign);
+ right_unlink(x,assign);
+ }
+ else if(x->next()->prior()->next()==x){ /* last of bucket */
+ left_unlink_first_of_bucket(x,assign);
+ assign(x->next()->prior()->next(),x->prior()->next());
+ assign(x->prior()->next(),pointer(0));
+ }
+ else{ /* first of group */
+ left_unlink_first_of_bucket(x,assign);
+ right_unlink_first_of_group(x,assign);
+ }
+ }
+ else if(x->prior()->next()->next()->prior()==
+ base_pointer_from(x)){ /* last of group */
+ if(x->next()->prior()==base_pointer_from(x)){
+ left_unlink_last_of_group(x,assign);
+ right_unlink(x,assign);
+ }
+ else{ /* last of bucket */
+ left_unlink_last_of_group(x,assign);
+ right_unlink_last_of_bucket(x,assign);
+ }
+ }
+ else{ /* second of group */
+ unlink_second_of_group(x,assign);
+ }
+ }
+
+private:
+ static pointer pointer_from(base_pointer x)
+ {
+ return Node::pointer_from(x);
+ }
+
+ static base_pointer base_pointer_from(pointer x)
+ {
+ return Node::base_pointer_from(x);
+ }
+
+ static bool is_last_of_bucket(pointer x)
+ {
+ return x->next()->prior()->next()==x;
+ }
+
+ static bool is_last_but_one_of_group(pointer x)
+ {
+ return
+ x->next()->prior()!=base_pointer_from(x)&&
+ !is_last_of_bucket(x->next())&&
+ pointer_from(x->next()->next()->prior())->prior()==base_pointer_from(x);
+ }
+
+ template
+ static void left_unlink(pointer x,Assigner& assign)
+ {
+ assign(x->prior()->next(),x->next());
+ }
+
+ template
+ static void right_unlink(pointer x,Assigner& assign)
+ {
+ assign(x->next()->prior(),x->prior());
+ }
+
+ template
+ static void left_unlink_first_of_bucket(pointer x,Assigner& assign)
+ {
+ assign(x->prior()->next()->next(),x->next());
+ }
+
+ template
+ static void right_unlink_last_of_bucket(pointer x,Assigner& assign)
+ {
+ assign(x->next()->prior()->next(),pointer_from(x->prior()));
+ }
+
+ template
+ static void right_unlink_first_of_group(pointer x,Assigner& assign)
+ {
+ pointer second=x->next(),
+ last=pointer_from(second->prior()),
+ lastbutone=pointer_from(last->prior());
+ if(second==lastbutone){
+ assign(second->next(),last);
+ assign(second->prior(),x->prior());
+ }
+ else{
+ assign(lastbutone->next(),second);
+ assign(second->next()->prior(),base_pointer_from(last));
+ assign(second->prior(),x->prior());
+ }
+ }
+
+ template
+ static void right_unlink_first_of_group_gt_3(pointer x,Assigner& assign)
+ {
+ pointer second=x->next(),
+ last=pointer_from(second->prior()),
+ lastbutone=pointer_from(last->prior());
+ assign(lastbutone->next(),second);
+ assign(second->next()->prior(),base_pointer_from(last));
+ assign(second->prior(),x->prior());
+ }
+
+ template
+ static void left_unlink_last_of_group(pointer x,Assigner& assign)
+ {
+ pointer lastbutone=pointer_from(x->prior()),
+ first=lastbutone->next(),
+ second=first->next();
+ if(lastbutone==second){
+ assign(lastbutone->prior(),base_pointer_from(first));
+ assign(lastbutone->next(),x->next());
+ }
+ else{
+ assign(second->prior(),base_pointer_from(lastbutone));
+ assign(lastbutone->prior()->next(),first);
+ assign(lastbutone->next(),x->next());
+ }
+ }
+
+ template
+ static void unlink_last_but_one_of_group_gt_3(pointer x,Assigner& assign)
+ {
+ pointer first=x->next(),
+ second=first->next(),
+ last=pointer_from(second->prior());
+ assign(last->prior(),x->prior());
+ assign(x->prior()->next(),first);
+ }
+
+ template
+ static void unlink_second_of_group(pointer x,Assigner& assign)
+ {
+ pointer last=pointer_from(x->prior()),
+ lastbutone=pointer_from(last->prior()),
+ first=lastbutone->next();
+ if(lastbutone==x){
+ assign(first->next(),last);
+ assign(last->prior(),base_pointer_from(first));
+ }
+ else{
+ assign(first->next(),x->next());
+ assign(x->next()->prior(),base_pointer_from(last));
+ }
+ }
};
template
-struct hashed_index_node:Super,hashed_index_node_trampoline
+struct hashed_index_node_trampoline:
+ hashed_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type
+ >
+{
+ typedef typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type impl_allocator_type;
+ typedef hashed_index_node_impl impl_type;
+};
+
+template
+struct hashed_index_node:
+ Super,hashed_index_node_trampoline
{
private:
typedef hashed_index_node_trampoline trampoline;
public:
- typedef typename trampoline::impl_type impl_type;
- typedef typename trampoline::pointer impl_pointer;
- typedef typename trampoline::const_pointer const_impl_pointer;
+ typedef typename trampoline::impl_type impl_type;
+ typedef hashed_index_node_alg<
+ impl_type,Category> node_alg;
+ typedef typename trampoline::base_pointer impl_base_pointer;
+ typedef typename trampoline::const_base_pointer const_impl_base_pointer;
+ typedef typename trampoline::pointer impl_pointer;
+ typedef typename trampoline::const_pointer const_impl_pointer;
+
+ impl_pointer& next(){return trampoline::next();}
+ impl_pointer next()const{return trampoline::next();}
+ impl_base_pointer& prior(){return trampoline::prior();}
+ impl_base_pointer prior()const{return trampoline::prior();}
impl_pointer impl()
{
@@ -147,12 +673,16 @@ public:
static_cast(&*x));
}
- static void increment(
- hashed_index_node*& x,impl_pointer bbegin,impl_pointer bend)
+ /* interoperability with hashed_index_iterator */
+
+ static void increment(hashed_index_node*& x)
{
- impl_pointer xi=x->impl();
- trampoline::increment(xi,bbegin,bend);
- x=from_impl(xi);
+ x=from_impl(node_alg::after(x->impl()));
+ }
+
+ static void increment_local(hashed_index_node*& x)
+ {
+ x=from_impl(node_alg::after_local(x->impl()));
}
};
diff --git a/include/boost/multi_index/detail/header_holder.hpp b/include/boost/multi_index/detail/header_holder.hpp
index 8716e83..ca8a9b2 100644
--- a/include/boost/multi_index/detail/header_holder.hpp
+++ b/include/boost/multi_index/detail/header_holder.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/index_base.hpp b/include/boost/multi_index/detail/index_base.hpp
index a43214a..74a52f8 100644
--- a/include/boost/multi_index/detail/index_base.hpp
+++ b/include/boost/multi_index/detail/index_base.hpp
@@ -9,12 +9,13 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
#include /* keep it first to prevent nasty warns in MSVC */
#include
+#include
#include
#include
#include
@@ -61,9 +62,10 @@ protected:
Value,IndexSpecifierList,Allocator> final_type;
typedef tuples::null_type ctor_args_list;
typedef typename
- boost::detail::allocator::rebind_to<
- Allocator,
- typename Allocator::value_type>::type final_allocator_type;
+ boost::detail::allocator::rebind_to<
+ Allocator,
+ typename Allocator::value_type
+ >::type final_allocator_type;
typedef mpl::vector0<> index_type_list;
typedef mpl::vector0<> iterator_type_list;
typedef mpl::vector0<> const_iterator_type_list;
@@ -96,43 +98,60 @@ protected:
const index_base&,const copy_map_type&)
{}
- node_type* insert_(const value_type& v,node_type* x,lvalue_tag)
+ final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag)
{
- boost::detail::allocator::construct(&x->value(),v);
+ x=final().allocate_node();
+ BOOST_TRY{
+ boost::detail::allocator::construct(&x->value(),v);
+ }
+ BOOST_CATCH(...){
+ final().deallocate_node(x);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
return x;
}
- node_type* insert_(const value_type& v,node_type* x,rvalue_tag)
+ final_node_type* insert_(const value_type& v,final_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.
- */
+ x=final().allocate_node();
+ BOOST_TRY{
+ /* 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)));
+ new (&x->value()) value_type(boost::move(const_cast(v)));
+ }
+ BOOST_CATCH(...){
+ final().deallocate_node(x);
+ BOOST_RETHROW;
+ }
+ BOOST_CATCH_END
return x;
}
- node_type* insert_(const value_type&,node_type* x,emplaced_tag)
+ final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag)
{
return x;
}
- node_type* insert_(const value_type& v,node_type*,node_type* x,lvalue_tag)
+ final_node_type* insert_(
+ const value_type& v,node_type*,final_node_type*& x,lvalue_tag)
{
- boost::detail::allocator::construct(&x->value(),v);
- return x;
+ return insert_(v,x,lvalue_tag());
}
- node_type* insert_(const value_type& v,node_type*,node_type* x,rvalue_tag)
+ final_node_type* insert_(
+ const value_type& v,node_type*,final_node_type*& x,rvalue_tag)
{
- new (&x->value()) value_type(boost::move(const_cast(v)));
- return x;
+ return insert_(v,x,rvalue_tag());
}
- node_type* insert_(const value_type&,node_type*,node_type* x,emplaced_tag)
+ final_node_type* insert_(
+ const value_type&,node_type*,final_node_type*& x,emplaced_tag)
{
return x;
}
diff --git a/include/boost/multi_index/detail/index_loader.hpp b/include/boost/multi_index/detail/index_loader.hpp
index 001c01b..3f0428c 100644
--- a/include/boost/multi_index/detail/index_loader.hpp
+++ b/include/boost/multi_index/detail/index_loader.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/index_matcher.hpp b/include/boost/multi_index/detail/index_matcher.hpp
index 7e275e1..f3675ac 100644
--- a/include/boost/multi_index/detail/index_matcher.hpp
+++ b/include/boost/multi_index/detail/index_matcher.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/index_node_base.hpp b/include/boost/multi_index/detail/index_node_base.hpp
index ee9f1c6..150eb75 100644
--- a/include/boost/multi_index/detail/index_node_base.hpp
+++ b/include/boost/multi_index/detail/index_node_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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -85,9 +85,7 @@ private:
};
template
-Node* node_from_value(
- const Value* p
- BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
+Node* node_from_value(const Value* p)
{
typedef typename Node::allocator_type allocator_type;
return static_cast(
diff --git a/include/boost/multi_index/detail/index_saver.hpp b/include/boost/multi_index/detail/index_saver.hpp
index d9e6bc7..ae09d4e 100644
--- a/include/boost/multi_index/detail/index_saver.hpp
+++ b/include/boost/multi_index/detail/index_saver.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/invariant_assert.hpp b/include/boost/multi_index/detail/invariant_assert.hpp
index d5fc256..c6c547c 100644
--- a/include/boost/multi_index/detail/invariant_assert.hpp
+++ b/include/boost/multi_index/detail/invariant_assert.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/is_index_list.hpp b/include/boost/multi_index/detail/is_index_list.hpp
index 9ee30ba..f6a2421 100644
--- a/include/boost/multi_index/detail/is_index_list.hpp
+++ b/include/boost/multi_index/detail/is_index_list.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/iter_adaptor.hpp b/include/boost/multi_index/detail/iter_adaptor.hpp
index 0346184..7a03235 100644
--- a/include/boost/multi_index/detail/iter_adaptor.hpp
+++ b/include/boost/multi_index/detail/iter_adaptor.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)
@@ -9,13 +9,12 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
#include /* keep it first to prevent nasty warns in MSVC */
#include
-#include
#include
namespace boost{
@@ -294,12 +293,9 @@ template
struct iter_adaptor_base
{
typedef iter_adaptor_selector<
- typename Base::iterator_category> selector;
- typedef typename prevent_eti<
- selector,
- typename mpl::apply2<
- selector,Derived,Base>::type
- >::type type;
+ typename Base::iterator_category> selector;
+ typedef typename mpl::apply2<
+ selector,Derived,Base>::type type;
};
template
diff --git a/include/boost/multi_index/detail/modify_key_adaptor.hpp b/include/boost/multi_index/detail/modify_key_adaptor.hpp
index 8a93b96..6df89b1 100644
--- a/include/boost/multi_index/detail/modify_key_adaptor.hpp
+++ b/include/boost/multi_index/detail/modify_key_adaptor.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/msvc_index_specifier.hpp b/include/boost/multi_index/detail/msvc_index_specifier.hpp
deleted file mode 100644
index 4766e53..0000000
--- a/include/boost/multi_index/detail/msvc_index_specifier.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/* Copyright 2003-2008 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_MSVC_INDEX_SPECIFIER_HPP
-#define BOOST_MULTI_INDEX_DETAIL_MSVC_INDEX_SPECIFIER_HPP
-
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
-#pragma once
-#endif
-
-#include /* keep it first to prevent nasty warns in MSVC */
-#include
-
-#if BOOST_WORKAROUND(BOOST_MSVC,<1310)
-/* Workaround for a problem in MSVC with dependent template typedefs
- * when accesing index specifiers.
- * Modeled after (thanks, Aleksey!)
- */
-
-#include
-
-namespace boost{
-
-namespace multi_index{
-
-namespace detail{
-
-template
-struct msvc_index_specifier
-{
- template struct fake_index_type:IndexSpecifier{};
- template<> struct fake_index_type
- {
- template
- struct node_class{};
-
- template
- struct index_class{};
- };
-
- template
- struct result_node_class:
- fake_index_type::value>::
- template node_class
- {
- };
-
- template
- struct result_index_class:
- fake_index_type::value>::
- template index_class
- {
- };
-};
-
-} /* namespace multi_index::detail */
-
-} /* namespace multi_index */
-
-} /* namespace boost */
-
-#endif /* workaround */
-
-#endif
diff --git a/include/boost/multi_index/detail/no_duplicate_tags.hpp b/include/boost/multi_index/detail/no_duplicate_tags.hpp
index 9b56e83..ba216ed 100644
--- a/include/boost/multi_index/detail/no_duplicate_tags.hpp
+++ b/include/boost/multi_index/detail/no_duplicate_tags.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP
#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/node_type.hpp b/include/boost/multi_index/detail/node_type.hpp
index 0e87261..7fe85cf 100644
--- a/include/boost/multi_index/detail/node_type.hpp
+++ b/include/boost/multi_index/detail/node_type.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP
#define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -22,7 +22,6 @@
#include
#include
#include
-#include
#include
namespace boost{
@@ -35,17 +34,6 @@ namespace detail{
* index list.
*/
-#if BOOST_WORKAROUND(BOOST_MSVC,<1310)
-struct index_node_applier
-{
- template
- struct apply:
- msvc_index_specifier< mpl::deref::type >::
- template result_node_class
- {
- };
-};
-#else
struct index_node_applier
{
template
@@ -56,7 +44,6 @@ struct index_node_applier
BOOST_NESTED_TEMPLATE node_class::type type;
};
};
-#endif
template
struct multi_index_node_type
diff --git a/include/boost/multi_index/detail/ord_index_args.hpp b/include/boost/multi_index/detail/ord_index_args.hpp
index bb8eb41..3e2641f 100644
--- a/include/boost/multi_index/detail/ord_index_args.hpp
+++ b/include/boost/multi_index/detail/ord_index_args.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP
#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/ord_index_node.hpp b/include/boost/multi_index/detail/ord_index_node.hpp
index edc4329..60727e0 100644
--- a/include/boost/multi_index/detail/ord_index_node.hpp
+++ b/include/boost/multi_index/detail/ord_index_node.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)
@@ -36,14 +36,13 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
#include /* keep it first to prevent nasty warns in MSVC */
#include
#include
-#include
#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES)
#include
@@ -70,22 +69,18 @@ struct ordered_index_node_impl; /* fwd decl. */
template
struct ordered_index_node_std_base
{
- typedef typename prevent_eti<
+ typedef typename
+ boost::detail::allocator::rebind_to<
Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,
- ordered_index_node_impl
- >::type
- >::type::pointer pointer;
- typedef typename prevent_eti<
+ ordered_index_node_impl
+ >::type::pointer pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,
- ordered_index_node_impl
- >::type
- >::type::const_pointer const_pointer;
- typedef ordered_index_color& color_ref;
- typedef pointer& parent_ref;
+ ordered_index_node_impl
+ >::type::const_pointer const_pointer;
+ typedef ordered_index_color& color_ref;
+ typedef pointer& parent_ref;
ordered_index_color& color(){return color_;}
ordered_index_color color()const{return color_;}
@@ -216,12 +211,9 @@ struct ordered_index_node_impl_base:
!(has_uintptr_type::value)||
(alignment_of >::value%2)||
!(is_same<
- typename prevent_eti<
+ typename boost::detail::allocator::rebind_to<
Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,
- ordered_index_node_impl
- >::type
+ ordered_index_node_impl
>::type::pointer,
ordered_index_node_impl*>::value),
ordered_index_node_std_base,
@@ -557,25 +549,19 @@ public:
template
struct ordered_index_node_trampoline:
- prevent_eti<
- Super,
- ordered_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type
+ ordered_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type
+ >
{
- typedef typename prevent_eti<
- Super,
- ordered_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type impl_type;
+ typedef ordered_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type
+ > impl_type;
};
template
diff --git a/include/boost/multi_index/detail/ord_index_ops.hpp b/include/boost/multi_index/detail/ord_index_ops.hpp
index caa71aa..d42f5f1 100644
--- a/include/boost/multi_index/detail/ord_index_ops.hpp
+++ b/include/boost/multi_index/detail/ord_index_ops.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)
@@ -36,7 +36,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP
#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
diff --git a/include/boost/multi_index/detail/prevent_eti.hpp b/include/boost/multi_index/detail/prevent_eti.hpp
deleted file mode 100644
index 56c067a..0000000
--- a/include/boost/multi_index/detail/prevent_eti.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2003-2008 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_PREVENT_ETI_HPP
-#define BOOST_MULTI_INDEX_DETAIL_PREVENT_ETI_HPP
-
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
-#pragma once
-#endif
-
-#include /* keep it first to prevent nasty warns in MSVC */
-#include
-
-#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
-#include
-#include
-#include
-#endif
-
-namespace boost{
-
-namespace multi_index{
-
-namespace detail{
-
-#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
-/* See
- * http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Effective_MPL
- * Item 5.6, Beware of the 'early template instantiation' trap.
- */
-
-template
-struct prevent_eti
-{
- typedef typename mpl::if_<
- mpl::aux::msvc_never_true,
- mpl::integral_c,
- Construct
- >::type type;
-};
-#else
-template
-struct prevent_eti
-{
- typedef Construct type;
-};
-#endif
-
-} /* namespace multi_index::detail */
-
-} /* namespace multi_index */
-
-} /* namespace boost */
-
-#endif
diff --git a/include/boost/multi_index/detail/rnd_index_loader.hpp b/include/boost/multi_index/detail/rnd_index_loader.hpp
index 793c521..4b00345 100644
--- a/include/boost/multi_index/detail/rnd_index_loader.hpp
+++ b/include/boost/multi_index/detail/rnd_index_loader.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP
#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -45,15 +44,12 @@ template
class random_access_index_loader_base:private noncopyable
{
protected:
- typedef typename prevent_eti<
- Allocator,
- random_access_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- Allocator,
- char
- >::type
- >
- >::type node_impl_type;
+ typedef random_access_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ Allocator,
+ char
+ >::type
+ > node_impl_type;
typedef typename node_impl_type::pointer node_impl_pointer;
typedef random_access_index_ptr_array ptr_array;
@@ -86,14 +82,14 @@ protected:
}
}
- void rearrange(node_impl_pointer position,node_impl_pointer x)
+ void rearrange(node_impl_pointer position_,node_impl_pointer x)
{
preprocess(); /* only incur this penalty if rearrange() is ever called */
- if(position==node_impl_pointer(0))position=header;
+ if(position_==node_impl_pointer(0))position_=header;
next(prev(x))=next(x);
prev(next(x))=prev(x);
- prev(x)=position;
- next(x)=next(position);
+ prev(x)=position_;
+ next(x)=next(position_);
next(prev(x))=prev(next(x))=x;
}
@@ -161,9 +157,10 @@ public:
super(al_,ptrs_)
{}
- void rearrange(Node* position,Node *x)
+ void rearrange(Node* position_,Node *x)
{
- super::rearrange(position?position->impl():node_impl_pointer(0),x->impl());
+ super::rearrange(
+ position_?position_->impl():node_impl_pointer(0),x->impl());
}
};
diff --git a/include/boost/multi_index/detail/rnd_index_node.hpp b/include/boost/multi_index/detail/rnd_index_node.hpp
index 43b2526..991f6da 100644
--- a/include/boost/multi_index/detail/rnd_index_node.hpp
+++ b/include/boost/multi_index/detail/rnd_index_node.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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP
#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include
#include
@@ -30,24 +29,18 @@ namespace detail{
template
struct random_access_index_node_impl
{
- typedef typename prevent_eti<
- Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,random_access_index_node_impl
- >::type
- >::type::pointer pointer;
- typedef typename prevent_eti<
- Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,random_access_index_node_impl
- >::type
- >::type::const_pointer const_pointer;
- typedef typename prevent_eti<
- Allocator,
- typename boost::detail::allocator::rebind_to<
- Allocator,pointer
- >::type
- >::type::pointer ptr_pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
+ Allocator,random_access_index_node_impl
+ >::type::pointer pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
+ Allocator,random_access_index_node_impl
+ >::type::const_pointer const_pointer;
+ typedef typename
+ boost::detail::allocator::rebind_to<
+ Allocator,pointer
+ >::type::pointer ptr_pointer;
ptr_pointer& up(){return up_;}
ptr_pointer up()const{return up_;}
@@ -181,25 +174,19 @@ private:
template
struct random_access_index_node_trampoline:
- prevent_eti<
- Super,
- random_access_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type
+ random_access_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type
+ >
{
- typedef typename prevent_eti<
- Super,
- random_access_index_node_impl<
- typename boost::detail::allocator::rebind_to<
- typename Super::allocator_type,
- char
- >::type
- >
- >::type impl_type;
+ typedef random_access_index_node_impl<
+ typename boost::detail::allocator::rebind_to<
+ typename Super::allocator_type,
+ char
+ >::type
+ > impl_type;
};
template
diff --git a/include/boost/multi_index/detail/rnd_index_ops.hpp b/include/boost/multi_index/detail/rnd_index_ops.hpp
index 5bf1ade..6cb030f 100644
--- a/include/boost/multi_index/detail/rnd_index_ops.hpp
+++ b/include/boost/multi_index/detail/rnd_index_ops.hpp
@@ -1,4 +1,4 @@
-/* Copyright 2003-2009 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)
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP
#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -30,8 +30,7 @@ namespace detail{
template
Node* random_access_index_remove(
- random_access_index_ptr_array& ptrs,Predicate pred
- BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
+ random_access_index_ptr_array& ptrs,Predicate pred)
{
typedef typename Node::value_type value_type;
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
@@ -55,8 +54,7 @@ Node* random_access_index_remove(
template
Node* random_access_index_unique(
- random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred
- BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
+ random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred)
{
typedef typename Node::value_type value_type;
typedef typename Node::impl_ptr_pointer impl_ptr_pointer;
@@ -86,8 +84,7 @@ template
void random_access_index_inplace_merge(
const Allocator& al,
random_access_index_ptr_array& ptrs,
- BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp
- BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
+ BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp)
{
typedef typename Node::value_type value_type;
typedef typename Node::impl_pointer impl_pointer;
@@ -151,8 +148,7 @@ template
void random_access_index_sort(
const Allocator& al,
random_access_index_ptr_array& ptrs,
- Compare comp
- BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Node))
+ Compare comp)
{
/* The implementation is extremely simple: an auxiliary
* array of pointers is sorted using stdlib facilities and
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 c1d9873..bae1c85 100644
--- a/include/boost/multi_index/detail/rnd_index_ptr_array.hpp
+++ b/include/boost/multi_index/detail/rnd_index_ptr_array.hpp
@@ -9,7 +9,7 @@
#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP
#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP
-#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#if defined(_MSC_VER)
#pragma once
#endif
@@ -17,7 +17,6 @@
#include
#include
#include
-#include
#include