mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 19:37:14 +02:00
Merged revisions 41822-41992,41994-42101 via svnmerge from
https://svn.boost.org/svn/boost/branches/unordered/dev ........ r41822 | danieljames | 2007-12-07 12:51:54 +0000 (Fri, 07 Dec 2007) | 5 lines Change the macros to meet boost guidelines. I should really have done this before the review. At least it'll give them something to say. ........ r41928 | danieljames | 2007-12-09 19:23:27 +0000 (Sun, 09 Dec 2007) | 1 line Add some parameters to standalone documentation build. ........ r41929 | danieljames | 2007-12-09 19:24:07 +0000 (Sun, 09 Dec 2007) | 1 line An extra rehash test for inserting a range. ........ r41930 | danieljames | 2007-12-09 19:24:52 +0000 (Sun, 09 Dec 2007) | 1 line get_for_erase can be static because all the required information is in the iterator. ........ r41931 | danieljames | 2007-12-09 19:31:00 +0000 (Sun, 09 Dec 2007) | 1 line ADL doesn't seem to be working properly on Visual C++ 7.1 when calling swap, so workaround this in the compile tests. ........ r41932 | danieljames | 2007-12-09 19:44:46 +0000 (Sun, 09 Dec 2007) | 1 line Try to make the erase exception requirements a little clearer. ........ r41933 | danieljames | 2007-12-09 19:52:50 +0000 (Sun, 09 Dec 2007) | 1 line Hopefully clearer comparison of accessors for comparison/hash function objects. ........ r41943 | danieljames | 2007-12-10 00:03:53 +0000 (Mon, 10 Dec 2007) | 1 line Fix a typo. ........ r41951 | danieljames | 2007-12-10 11:08:02 +0000 (Mon, 10 Dec 2007) | 1 line Use the locale in the case insensitive comparison, I really should add a test for this. ........ r41994 | danieljames | 2007-12-13 00:26:05 +0000 (Thu, 13 Dec 2007) | 3 lines Hervé Brönnimann's improved explanation of the formula for avoiding invalidating iterators. ........ r41995 | danieljames | 2007-12-13 00:30:46 +0000 (Thu, 13 Dec 2007) | 4 lines Explicity use the classic locale in the case insensitive example. I could make the locale a member, but that would make the example longer. Also, this would be a good place to put a note about the need for constant function objects. ........ r41996 | danieljames | 2007-12-13 00:31:55 +0000 (Thu, 13 Dec 2007) | 1 line Pull the point examples out into test files - fixing a few bugs in the process. ........ r41997 | danieljames | 2007-12-13 00:41:30 +0000 (Thu, 13 Dec 2007) | 3 lines A few reference links for boost::hash, it might be better to link to the first page of the Boost.Hash documentation though. ........ r42092 | danieljames | 2007-12-16 10:07:27 +0000 (Sun, 16 Dec 2007) | 2 lines Fix some typos, and use American spelling. ........ r42093 | danieljames | 2007-12-16 10:11:00 +0000 (Sun, 16 Dec 2007) | 1 line Small documentation tweak. ........ r42096 | danieljames | 2007-12-16 10:17:03 +0000 (Sun, 16 Dec 2007) | 1 line Fix some reference documentation errors. ........ r42097 | danieljames | 2007-12-16 10:28:08 +0000 (Sun, 16 Dec 2007) | 1 line Document the explicit constructors. ........ r42098 | danieljames | 2007-12-16 10:47:13 +0000 (Sun, 16 Dec 2007) | 1 line Try to make the active issues and proposals a little clearer - including more obvious links to the relevant papers. ........ r42099 | danieljames | 2007-12-16 10:52:30 +0000 (Sun, 16 Dec 2007) | 1 line Fix some complexity errors in the comparison table. ........ r42100 | danieljames | 2007-12-16 10:59:45 +0000 (Sun, 16 Dec 2007) | 1 line Use Mapped instead of T in the documentation. ........ r42101 | danieljames | 2007-12-16 11:06:16 +0000 (Sun, 16 Dec 2007) | 1 line Remove hard-coded length of prime numbers. ........ [SVN r42187]
This commit is contained in:
@ -1,15 +1,17 @@
|
||||
project boost/doc ;
|
||||
import boostbook : boostbook ;
|
||||
|
||||
boostbook doc : src/boost.xml
|
||||
:
|
||||
# Copyright 2005 Daniel James.
|
||||
# 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)
|
||||
|
||||
## Build the various generated docs (Doxygen and QuickBook)...
|
||||
using quickbook ;
|
||||
|
||||
<dependency>../libs/unordered/doc//unordered
|
||||
<implicit-dependency>../libs/unordered/doc//unordered
|
||||
#<dependency>../libs/functional/hash/doc//hash
|
||||
#<implicit-dependency>../libs/functional/hash/doc//hash
|
||||
|
||||
<xsl:param>boost.libraries=../../libs/libraries.htm
|
||||
;
|
||||
xml unordered : unordered.qbk ;
|
||||
boostbook standalone : unordered :
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>boost.libraries=../../../libraries.htm
|
||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
||||
<xsl:param>chunk.first.sections=1
|
||||
<xsl:param>chunk.section.depth=2
|
||||
<xsl:param>generate.section.toc.level=2
|
||||
<xsl:param>toc.section.depth=1
|
||||
<xsl:param>toc.max.depth=1 ;
|
||||
|
@ -7,8 +7,8 @@
|
||||
The containers are made up of a number of 'buckets', each of which can contain
|
||||
any number of elements. For example, the following diagram shows an [classref
|
||||
boost::unordered_set unordered_set] with 7 buckets containing 5 elements, `A`,
|
||||
`B`, `C`, `D` and `E` (this is just for illustration, in practise containers
|
||||
will have more buckets).
|
||||
`B`, `C`, `D` and `E` (this is just for illustration, containers will typically
|
||||
have more buckets).
|
||||
|
||||
[$../../libs/unordered/doc/diagrams/buckets.png]
|
||||
|
||||
@ -97,9 +97,10 @@ elements into container `x`, you could first call:
|
||||
x.rehash((x.size() + n) / x.max_load_factor() + 1);
|
||||
|
||||
[blurb Note: `rehash`'s argument is the number of buckets, not the number of
|
||||
elements, which is why the new size is divided by the maximum load factor. The
|
||||
`+ 1` is required because the container is allowed to resize when the load
|
||||
factor is equal to the maximum load factor.]
|
||||
elements, which is why the new size is divided by the maximum load factor. The
|
||||
+ 1 guarantees there is no invalidation; without it, reallocation could occur
|
||||
if the number of bucket exactly divides the target size, since the container is
|
||||
allowed to rehash when the load factor is equal to the maximum load factor.]
|
||||
|
||||
[table Methods for Controlling Bucket Size
|
||||
[[Method] [Description]]
|
||||
|
@ -8,19 +8,16 @@
|
||||
[[Associative Containers] [Unordered Associative Containers]]
|
||||
|
||||
[
|
||||
[Parametrised by an ordering relation `Compare`]
|
||||
[Parametrised by a function object `Hash` and an equivalence relation
|
||||
[Parameterized by an ordering relation `Compare`]
|
||||
[Parameterized by a function object `Hash` and an equivalence relation
|
||||
`Pred`]
|
||||
]
|
||||
[
|
||||
[`Compare` exposed by member typedef `key_compare`, accessed by member function `key_comp()`]
|
||||
[`Hash` exposed by member typedef `hasher`, accessed by member function `hash_function()`.
|
||||
|
||||
`Pred` by member typedef `key_equal` and member function `key_eq()`.]
|
||||
]
|
||||
[
|
||||
[Member typedef `value_compare` supplies an ordering comparison for member elements, accessed by member function `value_comp()`.]
|
||||
[No equivalent. No idea why.]
|
||||
[Keys can be compared using `key_compare` which is accessed by member function `key_comp()`,
|
||||
values can be compared using `value_compare` which is accessed by member function `value_comp()`.]
|
||||
[Keys can be hashed using `hasher` which is accessed by member function `hash_function()`,
|
||||
and checked for equality using `key_equal` which is accessed by member function `key_eq()`.
|
||||
There is no function object for compared or hashing values.]
|
||||
]
|
||||
[
|
||||
[Constructors have optional extra parameters for the comparison object.]
|
||||
@ -105,15 +102,15 @@
|
||||
]
|
||||
[
|
||||
[Insert a single element with a hint]
|
||||
[Amortised constant if t elements inserted right after hint,
|
||||
[Amortized constant if t elements inserted right after hint,
|
||||
logarithmic otherwise]
|
||||
[Average case constant, worst case linear (ie. the same as
|
||||
a normal insert).]
|
||||
]
|
||||
[
|
||||
[Inserting a range of /N/ elements]
|
||||
[/N/ log(`size()`+/N/)]
|
||||
[Average case O(/N/), worst case O(/N/ * 'size()')]
|
||||
[ /N/ log(`size()`+/N/) ]
|
||||
[Average case O(/N/), worst case O(/N/ * `size()`)]
|
||||
]
|
||||
[
|
||||
[Erase by key, `k`]
|
||||
@ -122,7 +119,7 @@
|
||||
]
|
||||
[
|
||||
[Erase a single element by iterator]
|
||||
[Amortised constant]
|
||||
[Amortized constant]
|
||||
[Average case: O(1), Worst case: O(`size()`)]
|
||||
]
|
||||
[
|
||||
@ -138,7 +135,7 @@
|
||||
[
|
||||
[Find]
|
||||
[logarithmic]
|
||||
[Average case: O(/N/), Worst case: O(`size()`)]
|
||||
[Average case: O(1), Worst case: O(`size()`)]
|
||||
]
|
||||
[/ TODO: Average case is probably wrong. ]
|
||||
[
|
||||
|
@ -16,7 +16,7 @@ is declared as:
|
||||
class ``[classref boost::unordered_set unordered_set]``;
|
||||
|
||||
The hash function comes first as you might want to change the hash function
|
||||
but not the equality predicate, while if you were to change the behaviour
|
||||
but not the equality predicate, while if you were to change the behavior
|
||||
of the equality predicate you would have to change the hash function to match
|
||||
it. So, if you wanted to use the
|
||||
[@http://www.isthe.com/chongo/tech/comp/fnv/ FNV-1 hash] you could write:
|
||||
@ -34,59 +34,21 @@ case-insensitive dictionary:
|
||||
[case_insensitive_functions]
|
||||
[case_insensitive_dictionary]
|
||||
|
||||
A more generic version is available at:
|
||||
This is a simplified version of the example at:
|
||||
[@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
|
||||
which supports other locales and string types.
|
||||
|
||||
[h2 Custom Types]
|
||||
|
||||
Similarly, a custom hash function can be used for custom types:
|
||||
|
||||
struct point {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
[import src_code/point1.cpp]
|
||||
[point_example1]
|
||||
|
||||
bool operator==(point const& p1, point const& p2)
|
||||
{
|
||||
return p1.x == p2.x && p1.y == p2.y;
|
||||
}
|
||||
Although, customizing Boost.Hash is probably a better solution:
|
||||
|
||||
struct point_hash
|
||||
: std::unary_function<point, std::size_t>
|
||||
{
|
||||
std::size_t operator()(point const& p) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, p.x);
|
||||
boost::hash_combine(seed, p.y);
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_multiset<point, std::equal_to<point>, point_hash>
|
||||
points;
|
||||
|
||||
Although, customising Boost.Hash is probably a better solution:
|
||||
|
||||
struct point {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
bool operator==(point const& p1, point const& p2)
|
||||
{
|
||||
return p1.x == p2.x && p1.y == p2.y;
|
||||
}
|
||||
|
||||
std::size_t hash_value(point const& x) {
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine(seed, p.x);
|
||||
boost::hash_combine(seed, p.y);
|
||||
return seed;
|
||||
}
|
||||
|
||||
// Now the default functions work.
|
||||
boost::unordered_multiset<point> points;
|
||||
[import src_code/point2.cpp]
|
||||
[point_example2]
|
||||
|
||||
See the Boost.Hash documentation for more detail on how to do this. Remember
|
||||
that it relies on extensions to the draft standard - so it won't work on other
|
||||
|
@ -45,14 +45,14 @@ details). If accepted the containers should also be added to __boost-tr1__.
|
||||
namespace boost {
|
||||
template <
|
||||
class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_set unordered_set]``;
|
||||
|
||||
template<
|
||||
class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_multiset unordered_multiset]``;
|
||||
@ -63,15 +63,15 @@ details). If accepted the containers should also be added to __boost-tr1__.
|
||||
|
||||
namespace boost {
|
||||
template <
|
||||
class Key, class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Key, class Mapped,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_map unordered_map]``;
|
||||
|
||||
template<
|
||||
class Key, class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Key, class Mapped,
|
||||
class Hash = ``[classref boost::hash]``<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<Key> >
|
||||
class ``[classref boost::unordered_multimap unordered_multimap]``;
|
||||
|
@ -7,7 +7,7 @@
|
||||
Thomas Wang's article on integer hash functions]]
|
||||
[def __n2345__
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2345.pdf
|
||||
N2345, 'Placement Instert for Containers']]
|
||||
N2345, 'Placement Insert for Containers']]
|
||||
[def __n2369__
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2369.pdf
|
||||
the August 2008 version of the working draft standard]]
|
||||
@ -28,12 +28,12 @@ By specifying an interface for accessing the buckets of the container the
|
||||
standard pretty much requires that the hash table uses chained addressing.
|
||||
|
||||
It would be conceivable to write a hash table that uses another method. For
|
||||
example, an it could use open addressing, and use the lookup chain to act as a
|
||||
example, it could use open addressing, and use the lookup chain to act as a
|
||||
bucket but there are a some serious problems with this:
|
||||
|
||||
* The draft standard requires that pointers to elements aren't invalidated, so
|
||||
the elements can't be stored in one array, but will need a layer of
|
||||
indirection instead - loosing the efficiency and most of the memory gain,
|
||||
indirection instead - losing the efficiency and most of the memory gain,
|
||||
the main advantages of open addressing.
|
||||
|
||||
* Local iterators would be very inefficient and may not be able to
|
||||
@ -98,33 +98,43 @@ So, this implementation uses a prime number for the hash table size.
|
||||
|
||||
[h2 Active Issues and Proposals]
|
||||
|
||||
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html
|
||||
Removing unused allocator functions]]
|
||||
[h3 Removing unused allocator functions]
|
||||
|
||||
This proposal suggests removing the `construct`, `destroy` and `address`
|
||||
member functions - all of which Boost.Unordered calls. It's near trivial
|
||||
to replace the calls with the appropriate code - and will simplify the
|
||||
implementation, as well as make supporting `emplace` easier.
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2339.htm
|
||||
N2339] opposed this change.
|
||||
In
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html
|
||||
N2257, removing unused allocator functions],
|
||||
Matt Austern suggests removing the `construct`, `destroy` and `address` member
|
||||
functions - all of which Boost.Unordered calls. Changing this will simplify the
|
||||
implementation, as well as make supporting `emplace` easier, but means that the
|
||||
containers won't support allocators which require these methods to be called.
|
||||
Detlef Vollmann opposed this change in
|
||||
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2339.htm N2339].
|
||||
|
||||
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#431
|
||||
431. Swapping containers with unequal allocators]]
|
||||
[h3 Swapping containers with unequal allocators]
|
||||
|
||||
I followed Howard Hinnant's advice and implemented option 3.
|
||||
It isn't clear how to swap containers when their allocators aren't equal.
|
||||
This is
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#431
|
||||
Issue 431: Swapping containers with unequal allocators].
|
||||
Howard Hinnant wrote about this in
|
||||
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1599.html N1599]
|
||||
and suggested swapping both the allocators and the containers' contents.
|
||||
|
||||
There is currently a further issue - if the allocator's swap does throw there's
|
||||
no guarantee what state the allocators will be in. The only solution seems to
|
||||
be to double buffer the allocators. But I'm assuming that it won't throw for now.
|
||||
be to double buffer the allocators. But I'm assuming that it won't throw for
|
||||
now.
|
||||
|
||||
Update: The committee have now decided that `swap` should do a fast swap if the
|
||||
allocator is Swappable and a slow swap using copy construction otherwise. To
|
||||
make this distinction requires concepts. For now I'm sticking with the current
|
||||
implementation.
|
||||
|
||||
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518
|
||||
518. Are insert and erase stable for unordered_multiset and unordered_multimap?]]
|
||||
[h3 Are insert and erase stable for unordered_multiset and unordered_multimap?]
|
||||
|
||||
It is not specified if `unordered_multiset` and `unordered_multimap` preserve the order
|
||||
of elements with equivalent keys (i.e. if they're stable under `insert` and `erase`).
|
||||
This is [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518 issue 581].
|
||||
The current proposal is that insert, erase and rehash are stable - so they are here.
|
||||
|
||||
[h2 Future Developments]
|
||||
|
132
doc/ref.xml
132
doc/ref.xml
@ -128,7 +128,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>A const_local_iterator object can be used to iterate through a single bucket.</para>
|
||||
</description>
|
||||
</typedef>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="n">
|
||||
<paramtype>size_type</paramtype>
|
||||
<default><emphasis>implementation-defined</emphasis></default>
|
||||
@ -149,7 +149,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<code><methodname>size</methodname>() == 0</code>
|
||||
</postconditions>
|
||||
<description>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocatorand a maximum load factor of 1.0.</para>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocator and a maximum load factor of 1.0.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
@ -263,7 +263,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</description>
|
||||
<returns>
|
||||
<para>The bool component of the return type is true if an insert took place.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the elment with equivalent value.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
@ -285,7 +285,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>hint is a suggestion to where the element should be inserted.</para>
|
||||
</description>
|
||||
<returns>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the elment with equivalent value.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
@ -329,8 +329,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The iterator following <code>position</code> before the erasure.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -345,7 +345,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The number of elements erased.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -356,15 +356,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
<descritpion>
|
||||
<description>
|
||||
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
|
||||
</descritpion>
|
||||
</description>
|
||||
<returns>
|
||||
<para>The iterator following the erased elements - i.e. <code>last</code>.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="clear">
|
||||
@ -439,7 +439,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="k">
|
||||
<paramtype>key_type const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::pair<iterator, iterator></type>
|
||||
<type>std::pair<const_iterator, const_iterator></type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>A range containing all elements with key equivalent to <code>k</code>.
|
||||
@ -576,10 +576,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_set<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_set<Value, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="y">
|
||||
<paramtype>unordered_set<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_set<Value, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
@ -708,7 +708,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>A const_local_iterator object can be used to iterate through a single bucket.</para>
|
||||
</description>
|
||||
</typedef>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="n">
|
||||
<paramtype>size_type</paramtype>
|
||||
<default><emphasis>implementation-defined</emphasis></default>
|
||||
@ -729,7 +729,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<code><methodname>size</methodname>() == 0</code>
|
||||
</postconditions>
|
||||
<description>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocatorand a maximum load factor of 1.0.</para>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocator and a maximum load factor of 1.0.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
@ -908,8 +908,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The iterator following <code>position</code> before the erasure.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -924,7 +924,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The number of elements erased.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -935,15 +935,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
<descritpion>
|
||||
<description>
|
||||
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
|
||||
</descritpion>
|
||||
</description>
|
||||
<returns>
|
||||
<para>The iterator following the erased elements - i.e. <code>last</code>.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="clear">
|
||||
@ -1018,7 +1018,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="k">
|
||||
<paramtype>key_type const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::pair<iterator, iterator></type>
|
||||
<type>std::pair<const_iterator, const_iterator></type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>A range containing all elements with key equivalent to <code>k</code>.
|
||||
@ -1155,10 +1155,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_multiset<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_multiset<Value, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="y">
|
||||
<paramtype>unordered_multiset<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_multiset<Value, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
@ -1187,7 +1187,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="T">
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
<default><type>boost::hash<Value></type></default>
|
||||
@ -1196,7 +1196,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<default><type>std::equal_to<Value></type></default>
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
<default><type>std::allocator<std::pair<const Key, T> ></type></default>
|
||||
<default><type>std::allocator<std::pair<const Key, Mapped> ></type></default>
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<purpose>An unordered associative container that associates unique keys with another value.
|
||||
@ -1212,8 +1212,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<entry><emphasis>Key</emphasis></entry>
|
||||
<entry>Key must be Assignable and CopyConstructible.</entry></row>
|
||||
<row>
|
||||
<entry><emphasis>T</emphasis></entry>
|
||||
<entry>T must be CopyConstructible</entry></row>
|
||||
<entry><emphasis>Mapped</emphasis></entry>
|
||||
<entry>Mapped must be CopyConstructible</entry></row>
|
||||
<row>
|
||||
<entry><emphasis>Hash</emphasis></entry>
|
||||
<entry>A unary function object type that acts a hash function for a <code>Key</code>. It takes a single argument of type <code>Key</code> and returns a value of type std::size_t.</entry></row>
|
||||
@ -1235,7 +1235,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<type>std::pair<Key const, Value></type>
|
||||
</typedef>
|
||||
<typedef name="mapped_type">
|
||||
<type>T</type>
|
||||
<type>Mapped</type>
|
||||
</typedef>
|
||||
<typedef name="hasher">
|
||||
<type>Hash</type>
|
||||
@ -1303,7 +1303,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>A const_local_iterator object can be used to iterate through a single bucket.</para>
|
||||
</description>
|
||||
</typedef>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="n">
|
||||
<paramtype>size_type</paramtype>
|
||||
<default><emphasis>implementation-defined</emphasis></default>
|
||||
@ -1324,7 +1324,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<code><methodname>size</methodname>() == 0</code>
|
||||
</postconditions>
|
||||
<description>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocatorand a maximum load factor of 1.0.</para>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocator and a maximum load factor of 1.0.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
@ -1438,7 +1438,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</description>
|
||||
<returns>
|
||||
<para>The bool component of the return type is true if an insert took place.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the elment with equivalent key.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
@ -1460,7 +1460,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>hint is a suggestion to where the element should be inserted.</para>
|
||||
</description>
|
||||
<returns>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the elment with equivalent key.</para>
|
||||
<para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
@ -1504,8 +1504,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The iterator following <code>position</code> before the erasure.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -1520,7 +1520,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The number of elements erased.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -1531,15 +1531,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
<descritpion>
|
||||
<description>
|
||||
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
|
||||
</descritpion>
|
||||
</description>
|
||||
<returns>
|
||||
<para>The iterator following the erased elements - i.e. <code>last</code>.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="clear">
|
||||
@ -1614,7 +1614,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="k">
|
||||
<paramtype>key_type const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::pair<iterator, iterator></type>
|
||||
<type>std::pair<const_iterator, const_iterator></type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>A range containing all elements with key equivalent to <code>k</code>.
|
||||
@ -1642,9 +1642,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</notes>
|
||||
</method>
|
||||
<overloaded-method name="at">
|
||||
<signature><type>T&</type>
|
||||
<signature><type>Mapped&</type>
|
||||
<parameter name="k"><paramtype>key_type const&</paramtype></parameter></signature>
|
||||
<signature cv="const"><type>T const&</type>
|
||||
<signature cv="const"><type>Mapped const&</type>
|
||||
<parameter name="k"><paramtype>key_type const&</paramtype></parameter></signature>
|
||||
<returns>
|
||||
<para>A reference to <code>x.second</code> where <code>x</code> is the (unique) element whose key is equivalent to <code>k</code>.</para>
|
||||
@ -1777,7 +1777,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="T">
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
@ -1787,10 +1787,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_map<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_map<Key, Mapped, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="y">
|
||||
<paramtype>unordered_map<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_map<Key, Mapped, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
@ -1811,7 +1811,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="T">
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
<default><type>boost::hash<Value></type></default>
|
||||
@ -1820,7 +1820,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<default><type>std::equal_to<Value></type></default>
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Alloc">
|
||||
<default><type>std::allocator<std::pair<const Key, T> ></type></default>
|
||||
<default><type>std::allocator<std::pair<const Key, Mapped> ></type></default>
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<purpose>An unordered associative container that associates keys with another value. The same key can be stored multiple times.
|
||||
@ -1836,8 +1836,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<entry><emphasis>Key</emphasis></entry>
|
||||
<entry>Key must be Assignable and CopyConstructible.</entry></row>
|
||||
<row>
|
||||
<entry><emphasis>T</emphasis></entry>
|
||||
<entry>T must be CopyConstructible</entry></row>
|
||||
<entry><emphasis>Mapped</emphasis></entry>
|
||||
<entry>Mapped must be CopyConstructible</entry></row>
|
||||
<row>
|
||||
<entry><emphasis>Hash</emphasis></entry>
|
||||
<entry>A unary function object type that acts a hash function for a <code>Key</code>. It takes a single argument of type <code>Key</code> and returns a value of type std::size_t.</entry></row>
|
||||
@ -1859,7 +1859,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<type>std::pair<Key const, Value></type>
|
||||
</typedef>
|
||||
<typedef name="mapped_type">
|
||||
<type>T</type>
|
||||
<type>Mapped</type>
|
||||
</typedef>
|
||||
<typedef name="hasher">
|
||||
<type>Hash</type>
|
||||
@ -1927,7 +1927,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>A const_local_iterator object can be used to iterate through a single bucket.</para>
|
||||
</description>
|
||||
</typedef>
|
||||
<constructor>
|
||||
<constructor specifiers="explicit">
|
||||
<parameter name="n">
|
||||
<paramtype>size_type</paramtype>
|
||||
<default><emphasis>implementation-defined</emphasis></default>
|
||||
@ -1948,7 +1948,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<code><methodname>size</methodname>() == 0</code>
|
||||
</postconditions>
|
||||
<description>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocatorand a maximum load factor of 1.0.</para>
|
||||
<para>Constructs an empty container with at least n buckets, using hf as the hash function, eq as the key equality predicate, a as the allocator and a maximum load factor of 1.0.</para>
|
||||
</description>
|
||||
</constructor>
|
||||
<constructor>
|
||||
@ -2127,8 +2127,8 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The iterator following <code>position</code> before the erasure.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -2143,7 +2143,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<para>The number of elements erased.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="erase">
|
||||
@ -2154,15 +2154,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
<descritpion>
|
||||
<description>
|
||||
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
|
||||
</descritpion>
|
||||
</description>
|
||||
<returns>
|
||||
<para>The iterator following the erased elements - i.e. <code>last</code>.</para>
|
||||
</returns>
|
||||
<throws>
|
||||
<para>Only throws an exception, if it is thrown by a call to <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</para>
|
||||
<para>Only throws an exception if it is thrown by <code>hasher</code> or <code>key_equal</code>.</para>
|
||||
<para>In this implementation, this overload doesn't call either function object's methods so it is no throw, but this might not be true in other implementations.</para>
|
||||
</throws>
|
||||
</method>
|
||||
<method name="clear">
|
||||
@ -2237,7 +2237,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<parameter name="k">
|
||||
<paramtype>key_type const&</paramtype>
|
||||
</parameter>
|
||||
<type>std::pair<iterator, iterator></type>
|
||||
<type>std::pair<const_iterator, const_iterator></type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>A range containing all elements with key equivalent to <code>k</code>.
|
||||
@ -2366,7 +2366,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<template>
|
||||
<template-type-parameter name="Key">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="T">
|
||||
<template-type-parameter name="Mapped">
|
||||
</template-type-parameter>
|
||||
<template-type-parameter name="Hash">
|
||||
</template-type-parameter>
|
||||
@ -2376,10 +2376,10 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</template-type-parameter>
|
||||
</template>
|
||||
<parameter name="x">
|
||||
<paramtype>unordered_multimap<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_multimap<Key, Mapped, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="y">
|
||||
<paramtype>unordered_multimap<Key, T, Hash, Pred, Alloc>&</paramtype>
|
||||
<paramtype>unordered_multimap<Key, Mapped, Hash, Pred, Alloc>&</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<effects>
|
||||
|
@ -14,7 +14,7 @@
|
||||
bool operator()(std::string const& x,
|
||||
std::string const& y) const
|
||||
{
|
||||
return boost::algorithm::iequals(x, y);
|
||||
return boost::algorithm::iequals(x, y, std::locale());
|
||||
}
|
||||
};
|
||||
|
||||
@ -24,11 +24,12 @@
|
||||
std::size_t operator()(std::string const& x) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
std::locale locale;
|
||||
|
||||
for(std::string::const_iterator it = x.begin();
|
||||
it != x.end(); ++it)
|
||||
{
|
||||
boost::hash_combine(seed, std::toupper(*it));
|
||||
boost::hash_combine(seed, std::toupper(*it, locale));
|
||||
}
|
||||
|
||||
return seed;
|
||||
|
@ -27,7 +27,7 @@ namespace hash_examples
|
||||
template <typename String1, typename String2>
|
||||
bool operator()(String1 const& x1, String2 const& x2) const
|
||||
{
|
||||
return boost::algorithm::iequals(x1, x2);
|
||||
return boost::algorithm::iequals(x1, x2, locale_);
|
||||
}
|
||||
private:
|
||||
std::locale locale_;
|
||||
|
@ -82,17 +82,21 @@ namespace boost {
|
||||
|
||||
// no throw
|
||||
inline std::size_t next_prime(std::size_t n) {
|
||||
std::size_t const* const prime_list_end = prime_list +
|
||||
sizeof(prime_list) / sizeof(*prime_list);
|
||||
std::size_t const* bound =
|
||||
std::lower_bound(prime_list,prime_list + 28, n);
|
||||
if(bound == prime_list + 28)
|
||||
std::lower_bound(prime_list,prime_list_end, n);
|
||||
if(bound == prime_list_end)
|
||||
bound--;
|
||||
return *bound;
|
||||
}
|
||||
|
||||
// no throw
|
||||
inline std::size_t prev_prime(std::size_t n) {
|
||||
std::size_t const* const prime_list_end = prime_list +
|
||||
sizeof(prime_list) / sizeof(*prime_list);
|
||||
std::size_t const* bound =
|
||||
std::upper_bound(prime_list,prime_list + 28, n);
|
||||
std::upper_bound(prime_list,prime_list_end, n);
|
||||
if(bound != prime_list)
|
||||
bound--;
|
||||
return *bound;
|
||||
|
@ -5,19 +5,19 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||
#define HASH_TABLE hash_table_equivalent_keys
|
||||
#define HASH_TABLE_DATA hash_table_data_equivalent_keys
|
||||
#define HASH_ITERATOR hash_iterator_equivalent_keys
|
||||
#define HASH_CONST_ITERATOR hash_const_iterator_equivalent_keys
|
||||
#define HASH_LOCAL_ITERATOR hash_local_iterator_equivalent_keys
|
||||
#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys
|
||||
#define BOOST_UNORDERED_TABLE hash_table_equivalent_keys
|
||||
#define BOOST_UNORDERED_TABLE_DATA hash_table_data_equivalent_keys
|
||||
#define BOOST_UNORDERED_ITERATOR hash_iterator_equivalent_keys
|
||||
#define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_equivalent_keys
|
||||
#define BOOST_UNORDERED_LOCAL_ITERATOR hash_local_iterator_equivalent_keys
|
||||
#define BOOST_UNORDERED_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys
|
||||
#else
|
||||
#define HASH_TABLE hash_table_unique_keys
|
||||
#define HASH_TABLE_DATA hash_table_data_unique_keys
|
||||
#define HASH_ITERATOR hash_iterator_unique_keys
|
||||
#define HASH_CONST_ITERATOR hash_const_iterator_unique_keys
|
||||
#define HASH_LOCAL_ITERATOR hash_local_iterator_unique_keys
|
||||
#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_unique_keys
|
||||
#define BOOST_UNORDERED_TABLE hash_table_unique_keys
|
||||
#define BOOST_UNORDERED_TABLE_DATA hash_table_data_unique_keys
|
||||
#define BOOST_UNORDERED_ITERATOR hash_iterator_unique_keys
|
||||
#define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_unique_keys
|
||||
#define BOOST_UNORDERED_LOCAL_ITERATOR hash_local_iterator_unique_keys
|
||||
#define BOOST_UNORDERED_CONST_LOCAL_ITERATOR hash_const_local_iterator_unique_keys
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
@ -29,7 +29,7 @@ namespace boost {
|
||||
// Responsible for managing the hash buckets.
|
||||
|
||||
template <typename Alloc>
|
||||
class HASH_TABLE_DATA
|
||||
class BOOST_UNORDERED_TABLE_DATA
|
||||
{
|
||||
public:
|
||||
struct node_base;
|
||||
@ -298,7 +298,7 @@ namespace boost {
|
||||
|
||||
void next_group()
|
||||
{
|
||||
node_ = HASH_TABLE_DATA::next_group(node_);
|
||||
node_ = BOOST_UNORDERED_TABLE_DATA::next_group(node_);
|
||||
}
|
||||
};
|
||||
|
||||
@ -357,7 +357,7 @@ namespace boost {
|
||||
|
||||
// Constructors/Deconstructor
|
||||
|
||||
HASH_TABLE_DATA(size_type n, value_allocator const& a)
|
||||
BOOST_UNORDERED_TABLE_DATA(size_type n, value_allocator const& a)
|
||||
: allocators_(a),
|
||||
buckets_(), bucket_count_(next_prime(n)),
|
||||
cached_begin_bucket_(), size_(0)
|
||||
@ -380,7 +380,7 @@ namespace boost {
|
||||
buckets_ = constructor.release();
|
||||
}
|
||||
|
||||
HASH_TABLE_DATA(HASH_TABLE_DATA const& x, size_type n)
|
||||
BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA const& x, size_type n)
|
||||
: allocators_(x.allocators_),
|
||||
buckets_(), bucket_count_(next_prime(n)),
|
||||
cached_begin_bucket_(), size_(0)
|
||||
@ -404,7 +404,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
// no throw
|
||||
~HASH_TABLE_DATA()
|
||||
~BOOST_UNORDERED_TABLE_DATA()
|
||||
{
|
||||
if(buckets_) {
|
||||
bucket_ptr begin = cached_begin_bucket_;
|
||||
@ -424,13 +424,13 @@ namespace boost {
|
||||
|
||||
private:
|
||||
|
||||
HASH_TABLE_DATA(HASH_TABLE_DATA const&);
|
||||
HASH_TABLE_DATA& operator=(HASH_TABLE_DATA const&);
|
||||
BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA const&);
|
||||
BOOST_UNORDERED_TABLE_DATA& operator=(BOOST_UNORDERED_TABLE_DATA const&);
|
||||
|
||||
public:
|
||||
|
||||
// no throw
|
||||
void swap(HASH_TABLE_DATA& other)
|
||||
void swap(BOOST_UNORDERED_TABLE_DATA& other)
|
||||
{
|
||||
std::swap(buckets_, other.buckets_);
|
||||
std::swap(bucket_count_, other.bucket_count_);
|
||||
@ -532,7 +532,7 @@ namespace boost {
|
||||
// no throw
|
||||
|
||||
#if BOOST_UNORDERED_HASH_EQUIVALENT
|
||||
link_ptr* get_for_erase(iterator_base r) const
|
||||
static link_ptr* get_for_erase(iterator_base r)
|
||||
{
|
||||
link_ptr n = r.local_.node_;
|
||||
|
||||
@ -545,11 +545,11 @@ namespace boost {
|
||||
// The element is the first in its group, so iterate
|
||||
// throught the groups, checking against the first element.
|
||||
it = &r.bucket_->next_;
|
||||
while(*it != n) it = &HASH_TABLE_DATA::next_group(*it);
|
||||
while(*it != n) it = &BOOST_UNORDERED_TABLE_DATA::next_group(*it);
|
||||
return it;
|
||||
}
|
||||
#else
|
||||
link_ptr* get_for_erase(iterator_base r) const
|
||||
static link_ptr* get_for_erase(iterator_base r)
|
||||
{
|
||||
link_ptr n = r.local_.node_;
|
||||
link_ptr* it = &r.bucket_->next_;
|
||||
@ -980,7 +980,7 @@ namespace boost {
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
|
||||
template <>
|
||||
class HASH_TABLE_DATA<int>
|
||||
class BOOST_UNORDERED_TABLE_DATA<int>
|
||||
{
|
||||
public:
|
||||
typedef int size_type;
|
||||
@ -995,10 +995,10 @@ namespace boost {
|
||||
template <typename ValueType, typename KeyType,
|
||||
typename Hash, typename Pred,
|
||||
typename Alloc>
|
||||
class HASH_TABLE
|
||||
: public HASH_TABLE_DATA<Alloc>
|
||||
class BOOST_UNORDERED_TABLE
|
||||
: public BOOST_UNORDERED_TABLE_DATA<Alloc>
|
||||
{
|
||||
typedef HASH_TABLE_DATA<Alloc> data;
|
||||
typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;
|
||||
|
||||
typedef typename data::node_constructor node_constructor;
|
||||
typedef typename data::bucket_ptr bucket_ptr;
|
||||
@ -1048,7 +1048,7 @@ namespace boost {
|
||||
// buffering is used to copy them. func_ points to the currently
|
||||
// active function objects.
|
||||
|
||||
typedef functions HASH_TABLE::*functions_ptr;
|
||||
typedef functions BOOST_UNORDERED_TABLE::*functions_ptr;
|
||||
|
||||
functions func1_;
|
||||
functions func2_;
|
||||
@ -1062,15 +1062,15 @@ namespace boost {
|
||||
// Constructors
|
||||
//
|
||||
// In the constructors, if anything throws an exception,
|
||||
// HASH_TABLE_DATA's destructor will clean up.
|
||||
// BOOST_UNORDERED_TABLE_DATA's destructor will clean up.
|
||||
|
||||
HASH_TABLE(size_type n,
|
||||
BOOST_UNORDERED_TABLE(size_type n,
|
||||
hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: data(n, a), // throws, cleans itself up
|
||||
func1_(hf, eq), // throws " "
|
||||
func2_(hf, eq), // throws " "
|
||||
func_(&HASH_TABLE::func1_), // no throw
|
||||
func_(&BOOST_UNORDERED_TABLE::func1_), // no throw
|
||||
mlf_(1.0f) // no throw
|
||||
{
|
||||
calculate_max_load(); // no throw
|
||||
@ -1110,32 +1110,32 @@ namespace boost {
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
HASH_TABLE(I i, I j, size_type n,
|
||||
BOOST_UNORDERED_TABLE(I i, I j, size_type n,
|
||||
hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: data(initial_size(i, j, n), a), // throws, cleans itself up
|
||||
func1_(hf, eq), // throws " "
|
||||
func2_(hf, eq), // throws " "
|
||||
func_(&HASH_TABLE::func1_), // no throw
|
||||
func_(&BOOST_UNORDERED_TABLE::func1_), // no throw
|
||||
mlf_(1.0f) // no throw
|
||||
{
|
||||
calculate_max_load(); // no throw
|
||||
|
||||
// This can throw, but HASH_TABLE_DATA's destructor will clean up.
|
||||
// This can throw, but BOOST_UNORDERED_TABLE_DATA's destructor will clean up.
|
||||
insert(i, j);
|
||||
}
|
||||
// Copy Construct
|
||||
|
||||
HASH_TABLE(HASH_TABLE const& x)
|
||||
BOOST_UNORDERED_TABLE(BOOST_UNORDERED_TABLE const& x)
|
||||
: data(x, x.min_buckets_for_size(x.size())), // throws
|
||||
func1_(x.current_functions()), // throws
|
||||
func2_(x.current_functions()), // throws
|
||||
func_(&HASH_TABLE::func1_), // no throw
|
||||
func_(&BOOST_UNORDERED_TABLE::func1_), // no throw
|
||||
mlf_(x.mlf_) // no throw
|
||||
{
|
||||
calculate_max_load(); // no throw
|
||||
|
||||
// This can throw, but HASH_TABLE_DATA's destructor will clean
|
||||
// This can throw, but BOOST_UNORDERED_TABLE_DATA's destructor will clean
|
||||
// up.
|
||||
copy_buckets(x, *this, current_functions());
|
||||
}
|
||||
@ -1147,7 +1147,7 @@ namespace boost {
|
||||
// throws the container is left with whatever was successfully
|
||||
// copied.
|
||||
|
||||
HASH_TABLE& operator=(HASH_TABLE const& x)
|
||||
BOOST_UNORDERED_TABLE& operator=(BOOST_UNORDERED_TABLE const& x)
|
||||
{
|
||||
if(this != &x)
|
||||
{
|
||||
@ -1191,7 +1191,7 @@ namespace boost {
|
||||
// but this doesn't seem to be guaranteed. Maybe I
|
||||
// could double buffer the allocators).
|
||||
|
||||
void swap(HASH_TABLE& x)
|
||||
void swap(BOOST_UNORDERED_TABLE& x)
|
||||
{
|
||||
// This only effects the function objects that aren't in use
|
||||
// so it is strongly exception safe, via. double buffering.
|
||||
@ -1231,11 +1231,11 @@ namespace boost {
|
||||
//
|
||||
// Strong exception safety (since only usued function objects are
|
||||
// changed).
|
||||
functions_ptr copy_functions(HASH_TABLE const& x)
|
||||
functions_ptr copy_functions(BOOST_UNORDERED_TABLE const& x)
|
||||
{
|
||||
// no throw:
|
||||
functions_ptr ptr = func_ == &HASH_TABLE::func1_
|
||||
? &HASH_TABLE::func2_ : &HASH_TABLE::func1_;
|
||||
functions_ptr ptr = func_ == &BOOST_UNORDERED_TABLE::func1_
|
||||
? &BOOST_UNORDERED_TABLE::func2_ : &BOOST_UNORDERED_TABLE::func1_;
|
||||
// throws, functions not in use, so strong
|
||||
this->*ptr = x.current_functions();
|
||||
return ptr;
|
||||
@ -1907,10 +1907,10 @@ namespace boost {
|
||||
|
||||
// Iterators
|
||||
|
||||
template <typename Alloc> class HASH_ITERATOR;
|
||||
template <typename Alloc> class HASH_CONST_ITERATOR;
|
||||
template <typename Alloc> class HASH_LOCAL_ITERATOR;
|
||||
template <typename Alloc> class HASH_CONST_LOCAL_ITERATOR;
|
||||
template <typename Alloc> class BOOST_UNORDERED_ITERATOR;
|
||||
template <typename Alloc> class BOOST_UNORDERED_CONST_ITERATOR;
|
||||
template <typename Alloc> class BOOST_UNORDERED_LOCAL_ITERATOR;
|
||||
template <typename Alloc> class BOOST_UNORDERED_CONST_LOCAL_ITERATOR;
|
||||
class iterator_access;
|
||||
|
||||
// Local Iterators
|
||||
@ -1918,7 +1918,7 @@ namespace boost {
|
||||
// all no throw
|
||||
|
||||
template <typename Alloc>
|
||||
class HASH_LOCAL_ITERATOR
|
||||
class BOOST_UNORDERED_LOCAL_ITERATOR
|
||||
: public boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
|
||||
@ -1930,28 +1930,28 @@ namespace boost {
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||
|
||||
private:
|
||||
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base;
|
||||
typedef HASH_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
|
||||
typedef BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator;
|
||||
|
||||
friend class HASH_CONST_LOCAL_ITERATOR<Alloc>;
|
||||
friend class BOOST_UNORDERED_CONST_LOCAL_ITERATOR<Alloc>;
|
||||
base base_;
|
||||
|
||||
public:
|
||||
HASH_LOCAL_ITERATOR() : base_() {}
|
||||
explicit HASH_LOCAL_ITERATOR(base x) : base_(x) {}
|
||||
BOOST_UNORDERED_LOCAL_ITERATOR() : base_() {}
|
||||
explicit BOOST_UNORDERED_LOCAL_ITERATOR(base x) : base_(x) {}
|
||||
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
|
||||
{ return *base_; }
|
||||
value_type* operator->() const { return &*base_; }
|
||||
HASH_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
HASH_LOCAL_ITERATOR operator++(int) { HASH_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(HASH_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
||||
BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
||||
bool operator==(const_local_iterator x) const { return base_ == x.base_; }
|
||||
bool operator!=(HASH_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
||||
bool operator!=(BOOST_UNORDERED_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
||||
bool operator!=(const_local_iterator x) const { return base_ != x.base_; }
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
class HASH_CONST_LOCAL_ITERATOR
|
||||
class BOOST_UNORDERED_CONST_LOCAL_ITERATOR
|
||||
: public boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
|
||||
@ -1963,24 +1963,24 @@ namespace boost {
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||
|
||||
private:
|
||||
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base;
|
||||
typedef HASH_LOCAL_ITERATOR<Alloc> local_iterator;
|
||||
friend class HASH_LOCAL_ITERATOR<Alloc>;
|
||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
|
||||
typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator;
|
||||
friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
|
||||
base base_;
|
||||
|
||||
public:
|
||||
HASH_CONST_LOCAL_ITERATOR() : base_() {}
|
||||
explicit HASH_CONST_LOCAL_ITERATOR(base x) : base_(x) {}
|
||||
HASH_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {}
|
||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : base_() {}
|
||||
explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(base x) : base_(x) {}
|
||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {}
|
||||
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
|
||||
operator*() const { return *base_; }
|
||||
value_type const* operator->() const { return &*base_; }
|
||||
HASH_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
HASH_CONST_LOCAL_ITERATOR operator++(int) { HASH_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
BOOST_UNORDERED_CONST_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(local_iterator x) const { return base_ == x.base_; }
|
||||
bool operator==(HASH_CONST_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
||||
bool operator==(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ == x.base_; }
|
||||
bool operator!=(local_iterator x) const { return base_ != x.base_; }
|
||||
bool operator!=(HASH_CONST_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
||||
bool operator!=(BOOST_UNORDERED_CONST_LOCAL_ITERATOR x) const { return base_ != x.base_; }
|
||||
};
|
||||
|
||||
// iterators
|
||||
@ -1989,7 +1989,7 @@ namespace boost {
|
||||
|
||||
|
||||
template <typename Alloc>
|
||||
class HASH_ITERATOR
|
||||
class BOOST_UNORDERED_ITERATOR
|
||||
: public boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
|
||||
@ -2001,28 +2001,28 @@ namespace boost {
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||
|
||||
private:
|
||||
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base;
|
||||
typedef HASH_CONST_ITERATOR<Alloc> const_iterator;
|
||||
friend class HASH_CONST_ITERATOR<Alloc>;
|
||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::iterator_base base;
|
||||
typedef BOOST_UNORDERED_CONST_ITERATOR<Alloc> const_iterator;
|
||||
friend class BOOST_UNORDERED_CONST_ITERATOR<Alloc>;
|
||||
base base_;
|
||||
|
||||
public:
|
||||
|
||||
HASH_ITERATOR() : base_() {}
|
||||
explicit HASH_ITERATOR(base const& x) : base_(x) {}
|
||||
BOOST_UNORDERED_ITERATOR() : base_() {}
|
||||
explicit BOOST_UNORDERED_ITERATOR(base const& x) : base_(x) {}
|
||||
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type
|
||||
operator*() const { return *base_; }
|
||||
value_type* operator->() const { return &*base_; }
|
||||
HASH_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
HASH_ITERATOR operator++(int) { HASH_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(HASH_ITERATOR const& x) const { return base_ == x.base_; }
|
||||
BOOST_UNORDERED_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
BOOST_UNORDERED_ITERATOR operator++(int) { BOOST_UNORDERED_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(BOOST_UNORDERED_ITERATOR const& x) const { return base_ == x.base_; }
|
||||
bool operator==(const_iterator const& x) const { return base_ == x.base_; }
|
||||
bool operator!=(HASH_ITERATOR const& x) const { return base_ != x.base_; }
|
||||
bool operator!=(BOOST_UNORDERED_ITERATOR const& x) const { return base_ != x.base_; }
|
||||
bool operator!=(const_iterator const& x) const { return base_ != x.base_; }
|
||||
};
|
||||
|
||||
template <typename Alloc>
|
||||
class HASH_CONST_ITERATOR
|
||||
class BOOST_UNORDERED_CONST_ITERATOR
|
||||
: public boost::iterator <
|
||||
std::forward_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type,
|
||||
@ -2034,34 +2034,34 @@ namespace boost {
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
|
||||
|
||||
private:
|
||||
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base;
|
||||
typedef HASH_ITERATOR<Alloc> iterator;
|
||||
friend class HASH_ITERATOR<Alloc>;
|
||||
typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::iterator_base base;
|
||||
typedef BOOST_UNORDERED_ITERATOR<Alloc> iterator;
|
||||
friend class BOOST_UNORDERED_ITERATOR<Alloc>;
|
||||
friend class iterator_access;
|
||||
base base_;
|
||||
|
||||
public:
|
||||
|
||||
HASH_CONST_ITERATOR() : base_() {}
|
||||
explicit HASH_CONST_ITERATOR(base const& x) : base_(x) {}
|
||||
HASH_CONST_ITERATOR(iterator const& x) : base_(x.base_) {}
|
||||
BOOST_UNORDERED_CONST_ITERATOR() : base_() {}
|
||||
explicit BOOST_UNORDERED_CONST_ITERATOR(base const& x) : base_(x) {}
|
||||
BOOST_UNORDERED_CONST_ITERATOR(iterator const& x) : base_(x.base_) {}
|
||||
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
|
||||
operator*() const { return *base_; }
|
||||
value_type const* operator->() const { return &*base_; }
|
||||
HASH_CONST_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
HASH_CONST_ITERATOR operator++(int) { HASH_CONST_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
BOOST_UNORDERED_CONST_ITERATOR& operator++() { base_.increment(); return *this; }
|
||||
BOOST_UNORDERED_CONST_ITERATOR operator++(int) { BOOST_UNORDERED_CONST_ITERATOR tmp(base_); base_.increment(); return tmp; }
|
||||
bool operator==(iterator const& x) const { return base_ == x.base_; }
|
||||
bool operator==(HASH_CONST_ITERATOR const& x) const { return base_ == x.base_; }
|
||||
bool operator==(BOOST_UNORDERED_CONST_ITERATOR const& x) const { return base_ == x.base_; }
|
||||
bool operator!=(iterator const& x) const { return base_ != x.base_; }
|
||||
bool operator!=(HASH_CONST_ITERATOR const& x) const { return base_ != x.base_; }
|
||||
bool operator!=(BOOST_UNORDERED_CONST_ITERATOR const& x) const { return base_ != x.base_; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#undef HASH_TABLE
|
||||
#undef HASH_TABLE_DATA
|
||||
#undef HASH_ITERATOR
|
||||
#undef HASH_CONST_ITERATOR
|
||||
#undef HASH_LOCAL_ITERATOR
|
||||
#undef HASH_CONST_LOCAL_ITERATOR
|
||||
#undef BOOST_UNORDERED_TABLE
|
||||
#undef BOOST_UNORDERED_TABLE_DATA
|
||||
#undef BOOST_UNORDERED_ITERATOR
|
||||
#undef BOOST_UNORDERED_CONST_ITERATOR
|
||||
#undef BOOST_UNORDERED_LOCAL_ITERATOR
|
||||
#undef BOOST_UNORDERED_CONST_LOCAL_ITERATOR
|
||||
|
||||
|
@ -73,11 +73,7 @@ struct insert_test2 : public insert_test_base<T>
|
||||
template <class T>
|
||||
struct insert_test3 : public insert_test_base<T>
|
||||
{
|
||||
typedef typename insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
// I don't think there's any need for this here.
|
||||
//strong.store(x);
|
||||
void run(T& x) const {
|
||||
x.insert(this->values.begin(), this->values.end());
|
||||
}
|
||||
|
||||
@ -165,7 +161,52 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash3 : public insert_test_base<T>
|
||||
{
|
||||
typename T::size_type mutable rehash_bucket_count, original_bucket_count;
|
||||
|
||||
insert_test_rehash3() : insert_test_base<T>(1000) {}
|
||||
|
||||
T init() const {
|
||||
typedef typename T::size_type size_type;
|
||||
|
||||
T x;
|
||||
x.max_load_factor(0.25);
|
||||
|
||||
original_bucket_count = x.bucket_count();
|
||||
rehash_bucket_count = static_cast<size_type>(
|
||||
std::ceil(original_bucket_count * x.max_load_factor())) - 1;
|
||||
|
||||
size_type initial_elements = rehash_bucket_count - 5;
|
||||
|
||||
BOOST_REQUIRE(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
boost::next(this->values.begin(), initial_elements));
|
||||
BOOST_REQUIRE(original_bucket_count == x.bucket_count());
|
||||
return x;
|
||||
}
|
||||
|
||||
void run(T& x) const {
|
||||
typename T::size_type bucket_count = x.bucket_count();
|
||||
|
||||
x.insert(boost::next(this->values.begin(), x.size()),
|
||||
boost::next(this->values.begin(), x.size() + 20));
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_REQUIRE(x.bucket_count() != bucket_count);
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
if(x.size() < rehash_bucket_count) {
|
||||
//BOOST_CHECK(x.bucket_count() == original_bucket_count);
|
||||
}
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4)
|
||||
(insert_test_rehash1)(insert_test_rehash2),
|
||||
(insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3),
|
||||
CONTAINER_SEQ)
|
||||
|
@ -217,7 +217,8 @@ namespace minimal
|
||||
|
||||
size_type max_size() const { return 1000; }
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
|
||||
BOOST_WORKAROUND(MSVC, <= 1300)
|
||||
public: allocator& operator=(allocator const&) { return *this;}
|
||||
#else
|
||||
private: allocator& operator=(allocator const&);
|
||||
|
Reference in New Issue
Block a user