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:
Daniel James
2007-12-19 23:09:09 +00:00
parent 56f91ea407
commit 3b4acc6342
13 changed files with 293 additions and 274 deletions

View File

@@ -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 xml unordered : unordered.qbk ;
<implicit-dependency>../libs/unordered/doc//unordered boostbook standalone : unordered :
#<dependency>../libs/functional/hash/doc//hash <xsl:param>boost.root=../../../..
#<implicit-dependency>../libs/functional/hash/doc//hash <xsl:param>boost.libraries=../../../libraries.htm
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
<xsl:param>boost.libraries=../../libs/libraries.htm <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 ;

View File

@@ -7,8 +7,8 @@
The containers are made up of a number of 'buckets', each of which can contain 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 any number of elements. For example, the following diagram shows an [classref
boost::unordered_set unordered_set] with 7 buckets containing 5 elements, `A`, 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 `B`, `C`, `D` and `E` (this is just for illustration, containers will typically
will have more buckets). have more buckets).
[$../../libs/unordered/doc/diagrams/buckets.png] [$../../libs/unordered/doc/diagrams/buckets.png]
@@ -98,8 +98,9 @@ elements into container `x`, you could first call:
[blurb Note: `rehash`'s argument is the number of buckets, not the number of [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 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 + 1 guarantees there is no invalidation; without it, reallocation could occur
factor is equal to the maximum load factor.] 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 [table Methods for Controlling Bucket Size
[[Method] [Description]] [[Method] [Description]]

View File

@@ -8,19 +8,16 @@
[[Associative Containers] [Unordered Associative Containers]] [[Associative Containers] [Unordered Associative Containers]]
[ [
[Parametrised by an ordering relation `Compare`] [Parameterized by an ordering relation `Compare`]
[Parametrised by a function object `Hash` and an equivalence relation [Parameterized by a function object `Hash` and an equivalence relation
`Pred`] `Pred`]
] ]
[ [
[`Compare` exposed by member typedef `key_compare`, accessed by member function `key_comp()`] [Keys can be compared using `key_compare` which is accessed by member function `key_comp()`,
[`Hash` exposed by member typedef `hasher`, accessed by member function `hash_function()`. 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()`,
`Pred` by member typedef `key_equal` and member function `key_eq()`.] 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.]
[
[Member typedef `value_compare` supplies an ordering comparison for member elements, accessed by member function `value_comp()`.]
[No equivalent. No idea why.]
] ]
[ [
[Constructors have optional extra parameters for the comparison object.] [Constructors have optional extra parameters for the comparison object.]
@@ -105,7 +102,7 @@
] ]
[ [
[Insert a single element with a hint] [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] logarithmic otherwise]
[Average case constant, worst case linear (ie. the same as [Average case constant, worst case linear (ie. the same as
a normal insert).] a normal insert).]
@@ -113,7 +110,7 @@
[ [
[Inserting a range of /N/ elements] [Inserting a range of /N/ elements]
[ /N/ log(`size()`+/N/) ] [ /N/ log(`size()`+/N/) ]
[Average case O(/N/), worst case O(/N/ * 'size()')] [Average case O(/N/), worst case O(/N/ * `size()`)]
] ]
[ [
[Erase by key, `k`] [Erase by key, `k`]
@@ -122,7 +119,7 @@
] ]
[ [
[Erase a single element by iterator] [Erase a single element by iterator]
[Amortised constant] [Amortized constant]
[Average case: O(1), Worst case: O(`size()`)] [Average case: O(1), Worst case: O(`size()`)]
] ]
[ [
@@ -138,7 +135,7 @@
[ [
[Find] [Find]
[logarithmic] [logarithmic]
[Average case: O(/N/), Worst case: O(`size()`)] [Average case: O(1), Worst case: O(`size()`)]
] ]
[/ TODO: Average case is probably wrong. ] [/ TODO: Average case is probably wrong. ]
[ [

View File

@@ -16,7 +16,7 @@ is declared as:
class ``[classref boost::unordered_set unordered_set]``; class ``[classref boost::unordered_set unordered_set]``;
The hash function comes first as you might want to change the hash function 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 of the equality predicate you would have to change the hash function to match
it. So, if you wanted to use the it. So, if you wanted to use the
[@http://www.isthe.com/chongo/tech/comp/fnv/ FNV-1 hash] you could write: [@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_functions]
[case_insensitive_dictionary] [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] [@../../libs/unordered/examples/case_insensitive.hpp /libs/unordered/examples/case_insensitive.hpp]
which supports other locales and string types.
[h2 Custom Types] [h2 Custom Types]
Similarly, a custom hash function can be used for custom types: Similarly, a custom hash function can be used for custom types:
struct point { [import src_code/point1.cpp]
int x; [point_example1]
int y;
};
bool operator==(point const& p1, point const& p2) Although, customizing Boost.Hash is probably a better solution:
{
return p1.x == p2.x && p1.y == p2.y;
}
struct point_hash [import src_code/point2.cpp]
: std::unary_function<point, std::size_t> [point_example2]
{
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;
See the Boost.Hash documentation for more detail on how to do this. Remember 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 that it relies on extensions to the draft standard - so it won't work on other

View File

@@ -45,14 +45,14 @@ details). If accepted the containers should also be added to __boost-tr1__.
namespace boost { namespace boost {
template < template <
class Key, class Key,
class Hash = boost::hash<Key>, class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>, class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> > class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_set unordered_set]``; class ``[classref boost::unordered_set unordered_set]``;
template< template<
class Key, class Key,
class Hash = boost::hash<Key>, class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>, class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> > class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_multiset unordered_multiset]``; 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 { namespace boost {
template < template <
class Key, class T, class Key, class Mapped,
class Hash = boost::hash<Key>, class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>, class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> > class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_map unordered_map]``; class ``[classref boost::unordered_map unordered_map]``;
template< template<
class Key, class T, class Key, class Mapped,
class Hash = boost::hash<Key>, class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>, class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> > class Alloc = std::allocator<Key> >
class ``[classref boost::unordered_multimap unordered_multimap]``; class ``[classref boost::unordered_multimap unordered_multimap]``;

View File

@@ -7,7 +7,7 @@
Thomas Wang's article on integer hash functions]] Thomas Wang's article on integer hash functions]]
[def __n2345__ [def __n2345__
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2345.pdf [@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__ [def __n2369__
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2369.pdf [@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2369.pdf
the August 2008 version of the working draft standard]] 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. 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 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: bucket but there are a some serious problems with this:
* The draft standard requires that pointers to elements aren't invalidated, so * 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 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. the main advantages of open addressing.
* Local iterators would be very inefficient and may not be able to * 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] [h2 Active Issues and Proposals]
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html [h3 Removing unused allocator functions]
Removing unused allocator functions]]
This proposal suggests removing the `construct`, `destroy` and `address` In
member functions - all of which Boost.Unordered calls. It's near trivial [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html
to replace the calls with the appropriate code - and will simplify the N2257, removing unused allocator functions],
implementation, as well as make supporting `emplace` easier. Matt Austern suggests removing the `construct`, `destroy` and `address` member
[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2339.htm functions - all of which Boost.Unordered calls. Changing this will simplify the
N2339] opposed this change. 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 [h3 Swapping containers with unequal allocators]
431. 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 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 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 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 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 make this distinction requires concepts. For now I'm sticking with the current
implementation. implementation.
[h3 [@http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#518 [h3 Are insert and erase stable for unordered_multiset and unordered_multimap?]
518. 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. The current proposal is that insert, erase and rehash are stable - so they are here.
[h2 Future Developments] [h2 Future Developments]

View File

@@ -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> <para>A const_local_iterator object can be used to iterate through a single bucket.</para>
</description> </description>
</typedef> </typedef>
<constructor> <constructor specifiers="explicit">
<parameter name="n"> <parameter name="n">
<paramtype>size_type</paramtype> <paramtype>size_type</paramtype>
<default><emphasis>implementation-defined</emphasis></default> <default><emphasis>implementation-defined</emphasis></default>
@@ -263,7 +263,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</description> </description>
<returns> <returns>
<para>The bool component of the return type is true if an insert took place.</para> <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> </returns>
<throws> <throws>
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para> <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> <para>hint is a suggestion to where the element should be inserted.</para>
</description> </description>
<returns> <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> </returns>
<throws> <throws>
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para> <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> <para>The iterator following <code>position</code> before the erasure.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="erase"> <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> <para>The number of elements erased.</para>
</returns> </returns>
<throws> <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> </throws>
</method> </method>
<method name="erase"> <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> <paramtype>const_iterator</paramtype>
</parameter> </parameter>
<type>iterator</type> <type>iterator</type>
<descritpion> <description>
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para> <para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
</descritpion> </description>
<returns> <returns>
<para>The iterator following the erased elements - i.e. <code>last</code>.</para> <para>The iterator following the erased elements - i.e. <code>last</code>.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="clear"> <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"> <parameter name="k">
<paramtype>key_type const&amp;</paramtype> <paramtype>key_type const&amp;</paramtype>
</parameter> </parameter>
<type>std::pair&lt;iterator, iterator&gt;</type> <type>std::pair&lt;const_iterator, const_iterator&gt;</type>
</signature> </signature>
<returns> <returns>
<para>A range containing all elements with key equivalent to <code>k</code>. <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-type-parameter>
</template> </template>
<parameter name="x"> <parameter name="x">
<paramtype>unordered_set&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<parameter name="y"> <parameter name="y">
<paramtype>unordered_set&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<type>void</type> <type>void</type>
<effects> <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> <para>A const_local_iterator object can be used to iterate through a single bucket.</para>
</description> </description>
</typedef> </typedef>
<constructor> <constructor specifiers="explicit">
<parameter name="n"> <parameter name="n">
<paramtype>size_type</paramtype> <paramtype>size_type</paramtype>
<default><emphasis>implementation-defined</emphasis></default> <default><emphasis>implementation-defined</emphasis></default>
@@ -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> <para>The iterator following <code>position</code> before the erasure.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="erase"> <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> <para>The number of elements erased.</para>
</returns> </returns>
<throws> <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> </throws>
</method> </method>
<method name="erase"> <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> <paramtype>const_iterator</paramtype>
</parameter> </parameter>
<type>iterator</type> <type>iterator</type>
<descritpion> <description>
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para> <para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
</descritpion> </description>
<returns> <returns>
<para>The iterator following the erased elements - i.e. <code>last</code>.</para> <para>The iterator following the erased elements - i.e. <code>last</code>.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="clear"> <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"> <parameter name="k">
<paramtype>key_type const&amp;</paramtype> <paramtype>key_type const&amp;</paramtype>
</parameter> </parameter>
<type>std::pair&lt;iterator, iterator&gt;</type> <type>std::pair&lt;const_iterator, const_iterator&gt;</type>
</signature> </signature>
<returns> <returns>
<para>A range containing all elements with key equivalent to <code>k</code>. <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-type-parameter>
</template> </template>
<parameter name="x"> <parameter name="x">
<paramtype>unordered_multiset&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<parameter name="y"> <parameter name="y">
<paramtype>unordered_multiset&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<type>void</type> <type>void</type>
<effects> <effects>
@@ -1187,7 +1187,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<template> <template>
<template-type-parameter name="Key"> <template-type-parameter name="Key">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="T"> <template-type-parameter name="Mapped">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Hash"> <template-type-parameter name="Hash">
<default><type>boost::hash&lt;Value&gt;</type></default> <default><type>boost::hash&lt;Value&gt;</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&lt;Value&gt;</type></default> <default><type>std::equal_to&lt;Value&gt;</type></default>
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Alloc"> <template-type-parameter name="Alloc">
<default><type>std::allocator&lt;std::pair&lt;const Key, T&gt; &gt;</type></default> <default><type>std::allocator&lt;std::pair&lt;const Key, Mapped&gt; &gt;</type></default>
</template-type-parameter> </template-type-parameter>
</template> </template>
<purpose>An unordered associative container that associates unique keys with another value. <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><emphasis>Key</emphasis></entry>
<entry>Key must be Assignable and CopyConstructible.</entry></row> <entry>Key must be Assignable and CopyConstructible.</entry></row>
<row> <row>
<entry><emphasis>T</emphasis></entry> <entry><emphasis>Mapped</emphasis></entry>
<entry>T must be CopyConstructible</entry></row> <entry>Mapped must be CopyConstructible</entry></row>
<row> <row>
<entry><emphasis>Hash</emphasis></entry> <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> <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&lt;Key const, Value&gt;</type> <type>std::pair&lt;Key const, Value&gt;</type>
</typedef> </typedef>
<typedef name="mapped_type"> <typedef name="mapped_type">
<type>T</type> <type>Mapped</type>
</typedef> </typedef>
<typedef name="hasher"> <typedef name="hasher">
<type>Hash</type> <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> <para>A const_local_iterator object can be used to iterate through a single bucket.</para>
</description> </description>
</typedef> </typedef>
<constructor> <constructor specifiers="explicit">
<parameter name="n"> <parameter name="n">
<paramtype>size_type</paramtype> <paramtype>size_type</paramtype>
<default><emphasis>implementation-defined</emphasis></default> <default><emphasis>implementation-defined</emphasis></default>
@@ -1438,7 +1438,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</description> </description>
<returns> <returns>
<para>The bool component of the return type is true if an insert took place.</para> <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> </returns>
<throws> <throws>
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para> <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> <para>hint is a suggestion to where the element should be inserted.</para>
</description> </description>
<returns> <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> </returns>
<throws> <throws>
<para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para> <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> <para>The iterator following <code>position</code> before the erasure.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="erase"> <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> <para>The number of elements erased.</para>
</returns> </returns>
<throws> <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> </throws>
</method> </method>
<method name="erase"> <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> <paramtype>const_iterator</paramtype>
</parameter> </parameter>
<type>iterator</type> <type>iterator</type>
<descritpion> <description>
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para> <para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
</descritpion> </description>
<returns> <returns>
<para>The iterator following the erased elements - i.e. <code>last</code>.</para> <para>The iterator following the erased elements - i.e. <code>last</code>.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="clear"> <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"> <parameter name="k">
<paramtype>key_type const&amp;</paramtype> <paramtype>key_type const&amp;</paramtype>
</parameter> </parameter>
<type>std::pair&lt;iterator, iterator&gt;</type> <type>std::pair&lt;const_iterator, const_iterator&gt;</type>
</signature> </signature>
<returns> <returns>
<para>A range containing all elements with key equivalent to <code>k</code>. <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> </notes>
</method> </method>
<overloaded-method name="at"> <overloaded-method name="at">
<signature><type>T&amp;</type> <signature><type>Mapped&amp;</type>
<parameter name="k"><paramtype>key_type const&amp;</paramtype></parameter></signature> <parameter name="k"><paramtype>key_type const&amp;</paramtype></parameter></signature>
<signature cv="const"><type>T const&amp;</type> <signature cv="const"><type>Mapped const&amp;</type>
<parameter name="k"><paramtype>key_type const&amp;</paramtype></parameter></signature> <parameter name="k"><paramtype>key_type const&amp;</paramtype></parameter></signature>
<returns> <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> <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>
<template-type-parameter name="Key"> <template-type-parameter name="Key">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="T"> <template-type-parameter name="Mapped">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Hash"> <template-type-parameter name="Hash">
</template-type-parameter> </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-type-parameter>
</template> </template>
<parameter name="x"> <parameter name="x">
<paramtype>unordered_map&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<parameter name="y"> <parameter name="y">
<paramtype>unordered_map&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<type>void</type> <type>void</type>
<effects> <effects>
@@ -1811,7 +1811,7 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<template> <template>
<template-type-parameter name="Key"> <template-type-parameter name="Key">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="T"> <template-type-parameter name="Mapped">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Hash"> <template-type-parameter name="Hash">
<default><type>boost::hash&lt;Value&gt;</type></default> <default><type>boost::hash&lt;Value&gt;</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&lt;Value&gt;</type></default> <default><type>std::equal_to&lt;Value&gt;</type></default>
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Alloc"> <template-type-parameter name="Alloc">
<default><type>std::allocator&lt;std::pair&lt;const Key, T&gt; &gt;</type></default> <default><type>std::allocator&lt;std::pair&lt;const Key, Mapped&gt; &gt;</type></default>
</template-type-parameter> </template-type-parameter>
</template> </template>
<purpose>An unordered associative container that associates keys with another value. The same key can be stored multiple times. <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><emphasis>Key</emphasis></entry>
<entry>Key must be Assignable and CopyConstructible.</entry></row> <entry>Key must be Assignable and CopyConstructible.</entry></row>
<row> <row>
<entry><emphasis>T</emphasis></entry> <entry><emphasis>Mapped</emphasis></entry>
<entry>T must be CopyConstructible</entry></row> <entry>Mapped must be CopyConstructible</entry></row>
<row> <row>
<entry><emphasis>Hash</emphasis></entry> <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> <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&lt;Key const, Value&gt;</type> <type>std::pair&lt;Key const, Value&gt;</type>
</typedef> </typedef>
<typedef name="mapped_type"> <typedef name="mapped_type">
<type>T</type> <type>Mapped</type>
</typedef> </typedef>
<typedef name="hasher"> <typedef name="hasher">
<type>Hash</type> <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> <para>A const_local_iterator object can be used to iterate through a single bucket.</para>
</description> </description>
</typedef> </typedef>
<constructor> <constructor specifiers="explicit">
<parameter name="n"> <parameter name="n">
<paramtype>size_type</paramtype> <paramtype>size_type</paramtype>
<default><emphasis>implementation-defined</emphasis></default> <default><emphasis>implementation-defined</emphasis></default>
@@ -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> <para>The iterator following <code>position</code> before the erasure.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="erase"> <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> <para>The number of elements erased.</para>
</returns> </returns>
<throws> <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> </throws>
</method> </method>
<method name="erase"> <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> <paramtype>const_iterator</paramtype>
</parameter> </parameter>
<type>iterator</type> <type>iterator</type>
<descritpion> <description>
<para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para> <para>Erases the elements in the range from <code>first</code> to <code>last</code>.</para>
</descritpion> </description>
<returns> <returns>
<para>The iterator following the erased elements - i.e. <code>last</code>.</para> <para>The iterator following the erased elements - i.e. <code>last</code>.</para>
</returns> </returns>
<throws> <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>
<para>They don't get called by the current implementation Boost.Unordered but other implementations may call them.</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> </throws>
</method> </method>
<method name="clear"> <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"> <parameter name="k">
<paramtype>key_type const&amp;</paramtype> <paramtype>key_type const&amp;</paramtype>
</parameter> </parameter>
<type>std::pair&lt;iterator, iterator&gt;</type> <type>std::pair&lt;const_iterator, const_iterator&gt;</type>
</signature> </signature>
<returns> <returns>
<para>A range containing all elements with key equivalent to <code>k</code>. <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>
<template-type-parameter name="Key"> <template-type-parameter name="Key">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="T"> <template-type-parameter name="Mapped">
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Hash"> <template-type-parameter name="Hash">
</template-type-parameter> </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-type-parameter>
</template> </template>
<parameter name="x"> <parameter name="x">
<paramtype>unordered_multimap&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<parameter name="y"> <parameter name="y">
<paramtype>unordered_multimap&lt;Key, T, Hash, Pred, Alloc&gt;&amp;</paramtype> <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt;&amp;</paramtype>
</parameter> </parameter>
<type>void</type> <type>void</type>
<effects> <effects>

View File

@@ -14,7 +14,7 @@
bool operator()(std::string const& x, bool operator()(std::string const& x,
std::string const& y) const 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 operator()(std::string const& x) const
{ {
std::size_t seed = 0; std::size_t seed = 0;
std::locale locale;
for(std::string::const_iterator it = x.begin(); for(std::string::const_iterator it = x.begin();
it != x.end(); ++it) it != x.end(); ++it)
{ {
boost::hash_combine(seed, std::toupper(*it)); boost::hash_combine(seed, std::toupper(*it, locale));
} }
return seed; return seed;

View File

@@ -27,7 +27,7 @@ namespace hash_examples
template <typename String1, typename String2> template <typename String1, typename String2>
bool operator()(String1 const& x1, String2 const& x2) const bool operator()(String1 const& x1, String2 const& x2) const
{ {
return boost::algorithm::iequals(x1, x2); return boost::algorithm::iequals(x1, x2, locale_);
} }
private: private:
std::locale locale_; std::locale locale_;

View File

@@ -82,17 +82,21 @@ namespace boost {
// no throw // no throw
inline std::size_t next_prime(std::size_t n) { 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::size_t const* bound =
std::lower_bound(prime_list,prime_list + 28, n); std::lower_bound(prime_list,prime_list_end, n);
if(bound == prime_list + 28) if(bound == prime_list_end)
bound--; bound--;
return *bound; return *bound;
} }
// no throw // no throw
inline std::size_t prev_prime(std::size_t n) { 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::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) if(bound != prime_list)
bound--; bound--;
return *bound; return *bound;

View File

@@ -5,19 +5,19 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#if BOOST_UNORDERED_HASH_EQUIVALENT #if BOOST_UNORDERED_HASH_EQUIVALENT
#define HASH_TABLE hash_table_equivalent_keys #define BOOST_UNORDERED_TABLE hash_table_equivalent_keys
#define HASH_TABLE_DATA hash_table_data_equivalent_keys #define BOOST_UNORDERED_TABLE_DATA hash_table_data_equivalent_keys
#define HASH_ITERATOR hash_iterator_equivalent_keys #define BOOST_UNORDERED_ITERATOR hash_iterator_equivalent_keys
#define HASH_CONST_ITERATOR hash_const_iterator_equivalent_keys #define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_equivalent_keys
#define HASH_LOCAL_ITERATOR hash_local_iterator_equivalent_keys #define BOOST_UNORDERED_LOCAL_ITERATOR hash_local_iterator_equivalent_keys
#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys #define BOOST_UNORDERED_CONST_LOCAL_ITERATOR hash_const_local_iterator_equivalent_keys
#else #else
#define HASH_TABLE hash_table_unique_keys #define BOOST_UNORDERED_TABLE hash_table_unique_keys
#define HASH_TABLE_DATA hash_table_data_unique_keys #define BOOST_UNORDERED_TABLE_DATA hash_table_data_unique_keys
#define HASH_ITERATOR hash_iterator_unique_keys #define BOOST_UNORDERED_ITERATOR hash_iterator_unique_keys
#define HASH_CONST_ITERATOR hash_const_iterator_unique_keys #define BOOST_UNORDERED_CONST_ITERATOR hash_const_iterator_unique_keys
#define HASH_LOCAL_ITERATOR hash_local_iterator_unique_keys #define BOOST_UNORDERED_LOCAL_ITERATOR hash_local_iterator_unique_keys
#define HASH_CONST_LOCAL_ITERATOR hash_const_local_iterator_unique_keys #define BOOST_UNORDERED_CONST_LOCAL_ITERATOR hash_const_local_iterator_unique_keys
#endif #endif
namespace boost { namespace boost {
@@ -29,7 +29,7 @@ namespace boost {
// Responsible for managing the hash buckets. // Responsible for managing the hash buckets.
template <typename Alloc> template <typename Alloc>
class HASH_TABLE_DATA class BOOST_UNORDERED_TABLE_DATA
{ {
public: public:
struct node_base; struct node_base;
@@ -298,7 +298,7 @@ namespace boost {
void next_group() 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 // 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), : allocators_(a),
buckets_(), bucket_count_(next_prime(n)), buckets_(), bucket_count_(next_prime(n)),
cached_begin_bucket_(), size_(0) cached_begin_bucket_(), size_(0)
@@ -380,7 +380,7 @@ namespace boost {
buckets_ = constructor.release(); 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_), : allocators_(x.allocators_),
buckets_(), bucket_count_(next_prime(n)), buckets_(), bucket_count_(next_prime(n)),
cached_begin_bucket_(), size_(0) cached_begin_bucket_(), size_(0)
@@ -404,7 +404,7 @@ namespace boost {
} }
// no throw // no throw
~HASH_TABLE_DATA() ~BOOST_UNORDERED_TABLE_DATA()
{ {
if(buckets_) { if(buckets_) {
bucket_ptr begin = cached_begin_bucket_; bucket_ptr begin = cached_begin_bucket_;
@@ -424,13 +424,13 @@ namespace boost {
private: private:
HASH_TABLE_DATA(HASH_TABLE_DATA const&); BOOST_UNORDERED_TABLE_DATA(BOOST_UNORDERED_TABLE_DATA const&);
HASH_TABLE_DATA& operator=(HASH_TABLE_DATA const&); BOOST_UNORDERED_TABLE_DATA& operator=(BOOST_UNORDERED_TABLE_DATA const&);
public: public:
// no throw // no throw
void swap(HASH_TABLE_DATA& other) void swap(BOOST_UNORDERED_TABLE_DATA& other)
{ {
std::swap(buckets_, other.buckets_); std::swap(buckets_, other.buckets_);
std::swap(bucket_count_, other.bucket_count_); std::swap(bucket_count_, other.bucket_count_);
@@ -532,7 +532,7 @@ namespace boost {
// no throw // no throw
#if BOOST_UNORDERED_HASH_EQUIVALENT #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_; link_ptr n = r.local_.node_;
@@ -545,11 +545,11 @@ namespace boost {
// The element is the first in its group, so iterate // The element is the first in its group, so iterate
// throught the groups, checking against the first element. // throught the groups, checking against the first element.
it = &r.bucket_->next_; 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; return it;
} }
#else #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 n = r.local_.node_;
link_ptr* it = &r.bucket_->next_; link_ptr* it = &r.bucket_->next_;
@@ -980,7 +980,7 @@ namespace boost {
#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG) #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
template <> template <>
class HASH_TABLE_DATA<int> class BOOST_UNORDERED_TABLE_DATA<int>
{ {
public: public:
typedef int size_type; typedef int size_type;
@@ -995,10 +995,10 @@ namespace boost {
template <typename ValueType, typename KeyType, template <typename ValueType, typename KeyType,
typename Hash, typename Pred, typename Hash, typename Pred,
typename Alloc> typename Alloc>
class HASH_TABLE class BOOST_UNORDERED_TABLE
: public HASH_TABLE_DATA<Alloc> : 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::node_constructor node_constructor;
typedef typename data::bucket_ptr bucket_ptr; typedef typename data::bucket_ptr bucket_ptr;
@@ -1048,7 +1048,7 @@ namespace boost {
// buffering is used to copy them. func_ points to the currently // buffering is used to copy them. func_ points to the currently
// active function objects. // active function objects.
typedef functions HASH_TABLE::*functions_ptr; typedef functions BOOST_UNORDERED_TABLE::*functions_ptr;
functions func1_; functions func1_;
functions func2_; functions func2_;
@@ -1062,15 +1062,15 @@ namespace boost {
// Constructors // Constructors
// //
// In the constructors, if anything throws an exception, // 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, hasher const& hf, key_equal const& eq,
value_allocator const& a) value_allocator const& a)
: data(n, a), // throws, cleans itself up : data(n, a), // throws, cleans itself up
func1_(hf, eq), // throws " " func1_(hf, eq), // throws " "
func2_(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 mlf_(1.0f) // no throw
{ {
calculate_max_load(); // no throw calculate_max_load(); // no throw
@@ -1110,32 +1110,32 @@ namespace boost {
} }
template <typename I> 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, hasher const& hf, key_equal const& eq,
value_allocator const& a) value_allocator const& a)
: data(initial_size(i, j, n), a), // throws, cleans itself up : data(initial_size(i, j, n), a), // throws, cleans itself up
func1_(hf, eq), // throws " " func1_(hf, eq), // throws " "
func2_(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 mlf_(1.0f) // no throw
{ {
calculate_max_load(); // 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); insert(i, j);
} }
// Copy Construct // 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 : data(x, x.min_buckets_for_size(x.size())), // throws
func1_(x.current_functions()), // throws func1_(x.current_functions()), // throws
func2_(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 mlf_(x.mlf_) // no throw
{ {
calculate_max_load(); // 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. // up.
copy_buckets(x, *this, current_functions()); copy_buckets(x, *this, current_functions());
} }
@@ -1147,7 +1147,7 @@ namespace boost {
// throws the container is left with whatever was successfully // throws the container is left with whatever was successfully
// copied. // copied.
HASH_TABLE& operator=(HASH_TABLE const& x) BOOST_UNORDERED_TABLE& operator=(BOOST_UNORDERED_TABLE const& x)
{ {
if(this != &x) if(this != &x)
{ {
@@ -1191,7 +1191,7 @@ namespace boost {
// but this doesn't seem to be guaranteed. Maybe I // but this doesn't seem to be guaranteed. Maybe I
// could double buffer the allocators). // 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 // This only effects the function objects that aren't in use
// so it is strongly exception safe, via. double buffering. // so it is strongly exception safe, via. double buffering.
@@ -1231,11 +1231,11 @@ namespace boost {
// //
// Strong exception safety (since only usued function objects are // Strong exception safety (since only usued function objects are
// changed). // changed).
functions_ptr copy_functions(HASH_TABLE const& x) functions_ptr copy_functions(BOOST_UNORDERED_TABLE const& x)
{ {
// no throw: // no throw:
functions_ptr ptr = func_ == &HASH_TABLE::func1_ functions_ptr ptr = func_ == &BOOST_UNORDERED_TABLE::func1_
? &HASH_TABLE::func2_ : &HASH_TABLE::func1_; ? &BOOST_UNORDERED_TABLE::func2_ : &BOOST_UNORDERED_TABLE::func1_;
// throws, functions not in use, so strong // throws, functions not in use, so strong
this->*ptr = x.current_functions(); this->*ptr = x.current_functions();
return ptr; return ptr;
@@ -1907,10 +1907,10 @@ namespace boost {
// Iterators // Iterators
template <typename Alloc> class HASH_ITERATOR; template <typename Alloc> class BOOST_UNORDERED_ITERATOR;
template <typename Alloc> class HASH_CONST_ITERATOR; template <typename Alloc> class BOOST_UNORDERED_CONST_ITERATOR;
template <typename Alloc> class HASH_LOCAL_ITERATOR; template <typename Alloc> class BOOST_UNORDERED_LOCAL_ITERATOR;
template <typename Alloc> class HASH_CONST_LOCAL_ITERATOR; template <typename Alloc> class BOOST_UNORDERED_CONST_LOCAL_ITERATOR;
class iterator_access; class iterator_access;
// Local Iterators // Local Iterators
@@ -1918,7 +1918,7 @@ namespace boost {
// all no throw // all no throw
template <typename Alloc> template <typename Alloc>
class HASH_LOCAL_ITERATOR class BOOST_UNORDERED_LOCAL_ITERATOR
: public boost::iterator < : public boost::iterator <
std::forward_iterator_tag, std::forward_iterator_tag,
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type, 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; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base; typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
typedef HASH_CONST_LOCAL_ITERATOR<Alloc> const_local_iterator; 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_; base base_;
public: public:
HASH_LOCAL_ITERATOR() : base_() {} BOOST_UNORDERED_LOCAL_ITERATOR() : base_() {}
explicit HASH_LOCAL_ITERATOR(base x) : base_(x) {} explicit BOOST_UNORDERED_LOCAL_ITERATOR(base x) : base_(x) {}
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type operator*() const
{ return *base_; } { return *base_; }
value_type* operator->() const { return &*base_; } value_type* operator->() const { return &*base_; }
HASH_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; }
HASH_LOCAL_ITERATOR operator++(int) { HASH_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; } BOOST_UNORDERED_LOCAL_ITERATOR operator++(int) { BOOST_UNORDERED_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
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_; } 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_; } bool operator!=(const_local_iterator x) const { return base_ != x.base_; }
}; };
template <typename Alloc> template <typename Alloc>
class HASH_CONST_LOCAL_ITERATOR class BOOST_UNORDERED_CONST_LOCAL_ITERATOR
: public boost::iterator < : public boost::iterator <
std::forward_iterator_tag, std::forward_iterator_tag,
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type, 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; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::local_iterator_base base; typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::local_iterator_base base;
typedef HASH_LOCAL_ITERATOR<Alloc> local_iterator; typedef BOOST_UNORDERED_LOCAL_ITERATOR<Alloc> local_iterator;
friend class HASH_LOCAL_ITERATOR<Alloc>; friend class BOOST_UNORDERED_LOCAL_ITERATOR<Alloc>;
base base_; base base_;
public: public:
HASH_CONST_LOCAL_ITERATOR() : base_() {} BOOST_UNORDERED_CONST_LOCAL_ITERATOR() : base_() {}
explicit HASH_CONST_LOCAL_ITERATOR(base x) : base_(x) {} explicit BOOST_UNORDERED_CONST_LOCAL_ITERATOR(base x) : base_(x) {}
HASH_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {} BOOST_UNORDERED_CONST_LOCAL_ITERATOR(local_iterator x) : base_(x.base_) {}
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
operator*() const { return *base_; } operator*() const { return *base_; }
value_type const* operator->() const { return &*base_; } value_type const* operator->() const { return &*base_; }
HASH_CONST_LOCAL_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_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++(int) { BOOST_UNORDERED_CONST_LOCAL_ITERATOR tmp(base_); base_.increment(); return tmp; }
bool operator==(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_; }
bool operator!=(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 // iterators
@@ -1989,7 +1989,7 @@ namespace boost {
template <typename Alloc> template <typename Alloc>
class HASH_ITERATOR class BOOST_UNORDERED_ITERATOR
: public boost::iterator < : public boost::iterator <
std::forward_iterator_tag, std::forward_iterator_tag,
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type, 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; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base; typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::iterator_base base;
typedef HASH_CONST_ITERATOR<Alloc> const_iterator; typedef BOOST_UNORDERED_CONST_ITERATOR<Alloc> const_iterator;
friend class HASH_CONST_ITERATOR<Alloc>; friend class BOOST_UNORDERED_CONST_ITERATOR<Alloc>;
base base_; base base_;
public: public:
HASH_ITERATOR() : base_() {} BOOST_UNORDERED_ITERATOR() : base_() {}
explicit HASH_ITERATOR(base const& x) : base_(x) {} explicit BOOST_UNORDERED_ITERATOR(base const& x) : base_(x) {}
BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type BOOST_DEDUCED_TYPENAME allocator_reference<Alloc>::type
operator*() const { return *base_; } operator*() const { return *base_; }
value_type* operator->() const { return &*base_; } value_type* operator->() const { return &*base_; }
HASH_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_ITERATOR& operator++() { base_.increment(); return *this; }
HASH_ITERATOR operator++(int) { HASH_ITERATOR tmp(base_); base_.increment(); return tmp; } BOOST_UNORDERED_ITERATOR operator++(int) { BOOST_UNORDERED_ITERATOR tmp(base_); base_.increment(); return tmp; }
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_; } 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_; } bool operator!=(const_iterator const& x) const { return base_ != x.base_; }
}; };
template <typename Alloc> template <typename Alloc>
class HASH_CONST_ITERATOR class BOOST_UNORDERED_CONST_ITERATOR
: public boost::iterator < : public boost::iterator <
std::forward_iterator_tag, std::forward_iterator_tag,
BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type, 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; typedef BOOST_DEDUCED_TYPENAME allocator_value_type<Alloc>::type value_type;
private: private:
typedef BOOST_DEDUCED_TYPENAME HASH_TABLE_DATA<Alloc>::iterator_base base; typedef BOOST_DEDUCED_TYPENAME BOOST_UNORDERED_TABLE_DATA<Alloc>::iterator_base base;
typedef HASH_ITERATOR<Alloc> iterator; typedef BOOST_UNORDERED_ITERATOR<Alloc> iterator;
friend class HASH_ITERATOR<Alloc>; friend class BOOST_UNORDERED_ITERATOR<Alloc>;
friend class iterator_access; friend class iterator_access;
base base_; base base_;
public: public:
HASH_CONST_ITERATOR() : base_() {} BOOST_UNORDERED_CONST_ITERATOR() : base_() {}
explicit HASH_CONST_ITERATOR(base const& x) : base_(x) {} explicit BOOST_UNORDERED_CONST_ITERATOR(base const& x) : base_(x) {}
HASH_CONST_ITERATOR(iterator const& x) : base_(x.base_) {} BOOST_UNORDERED_CONST_ITERATOR(iterator const& x) : base_(x.base_) {}
BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type BOOST_DEDUCED_TYPENAME allocator_const_reference<Alloc>::type
operator*() const { return *base_; } operator*() const { return *base_; }
value_type const* operator->() const { return &*base_; } value_type const* operator->() const { return &*base_; }
HASH_CONST_ITERATOR& operator++() { base_.increment(); return *this; } BOOST_UNORDERED_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++(int) { BOOST_UNORDERED_CONST_ITERATOR tmp(base_); base_.increment(); return tmp; }
bool operator==(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_; }
bool operator!=(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 BOOST_UNORDERED_TABLE
#undef HASH_TABLE_DATA #undef BOOST_UNORDERED_TABLE_DATA
#undef HASH_ITERATOR #undef BOOST_UNORDERED_ITERATOR
#undef HASH_CONST_ITERATOR #undef BOOST_UNORDERED_CONST_ITERATOR
#undef HASH_LOCAL_ITERATOR #undef BOOST_UNORDERED_LOCAL_ITERATOR
#undef HASH_CONST_LOCAL_ITERATOR #undef BOOST_UNORDERED_CONST_LOCAL_ITERATOR

View File

@@ -73,11 +73,7 @@ struct insert_test2 : public insert_test_base<T>
template <class T> template <class T>
struct insert_test3 : public insert_test_base<T> struct insert_test3 : public insert_test_base<T>
{ {
typedef typename insert_test_base<T>::strong_type strong_type; void run(T& x) const {
void run(T& x, strong_type& strong) const {
// I don't think there's any need for this here.
//strong.store(x);
x.insert(this->values.begin(), this->values.end()); 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( RUN_EXCEPTION_TESTS(
(insert_test1)(insert_test2)(insert_test3)(insert_test4) (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) CONTAINER_SEQ)

View File

@@ -217,7 +217,8 @@ namespace minimal
size_type max_size() const { return 1000; } 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;} public: allocator& operator=(allocator const&) { return *this;}
#else #else
private: allocator& operator=(allocator const&); private: allocator& operator=(allocator const&);