forked from boostorg/unordered
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 392029c246 | |||
| 8b4c480d47 | |||
| 70ca44b503 | |||
| 795d9f0aa7 | |||
| ec97640b1b | |||
| d3ca85bdbd | |||
| fe2a6c521b | |||
| 958738c7af | |||
| 3fb7d15f5b | |||
| 2b212d7c49 | |||
| aa0e8eedd2 | |||
| f962857e68 | |||
| 02bf8f288e | |||
| 144d8963a3 | |||
| f709c16d70 |
+8
-5
@@ -8,11 +8,6 @@ path-constant admonishment_location : ../../../../doc/src/images ;
|
||||
|
||||
xml unordered : unordered.qbk ;
|
||||
boostbook standalone : unordered :
|
||||
<xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>boost.libraries=../../../libraries.htm
|
||||
<xsl:param>navig.graphics=1
|
||||
|
||||
<xsl:param>chunk.first.sections=1
|
||||
<xsl:param>chunk.section.depth=2
|
||||
<xsl:param>generate.section.toc.level=2
|
||||
@@ -23,7 +18,15 @@ boostbook standalone : unordered :
|
||||
<xsl:param>boost.compact.function=0
|
||||
<xsl:param>boost.compact.enum=0
|
||||
|
||||
# HTML Options:
|
||||
|
||||
<format>html:<xsl:param>boost.root=../../../..
|
||||
<format>html:<xsl:param>img.src.path=../../../../doc/html/
|
||||
<format>xhtml:<xsl:param>boost.root=../../../..
|
||||
<format>xhtml:<xsl:param>img.src.path=../../../../doc/html/
|
||||
|
||||
# PDF Options:
|
||||
|
||||
# TOC Generation: this is needed for FOP-0.9 and later:
|
||||
<xsl:param>fop1.extensions=0
|
||||
<format>pdf:<xsl:param>xep.extensions=1
|
||||
|
||||
@@ -102,5 +102,31 @@ First official release.
|
||||
|
||||
* Buckets are allocated lazily which means that constructing an empty container
|
||||
will not allocate any memory.
|
||||
|
||||
[h2 Boost 1.42.0]
|
||||
|
||||
* Support instantiating the containers with incomplete value types.
|
||||
* Reduced the number of warnings (mostly in tests).
|
||||
* Improved codegear compatibility.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3693 Ticket 3693]:
|
||||
Add `erase_return_void` as a temporary workaround for the current
|
||||
`erase` which can be inefficient because it has to find the next
|
||||
element to return an iterator.
|
||||
* Add templated find overload for compatible keys.
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3773 Ticket 3773]:
|
||||
Add missing `std` qualifier to `ptrdiff_t`.
|
||||
* Some code formatting changes to fit almost all lines into 80 characters.
|
||||
|
||||
[h2 Boost 1.43.0]
|
||||
|
||||
* [@http://svn.boost.org/trac/boost/ticket/3966 Ticket 3966]:
|
||||
`erase_return_void` is now `quick_erase`, which is the
|
||||
[@http://home.roadrunner.com/~hinnant/issue_review/lwg-active.html#579
|
||||
current forerunner for resolving the slow erase by iterator], although
|
||||
there's a strong possibility that this may change in the future. The old
|
||||
method name remains for backwards compatibility but is considered deprecated
|
||||
and will be removed in a future release.
|
||||
* Use Boost.Exception.
|
||||
* Stop using deprecated `BOOST_HAS_*` macros.
|
||||
|
||||
[endsect]
|
||||
|
||||
+376
@@ -459,6 +459,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase">
|
||||
<parameter name="k">
|
||||
@@ -494,6 +503,51 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="clear">
|
||||
<type>void</type>
|
||||
<description>
|
||||
@@ -544,11 +598,51 @@ 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>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
<notes><para>
|
||||
The templated overloads are a non-standard extensions which
|
||||
allows you to use a compatible hash function and equality
|
||||
predicate for a key of a different type in order to avoid
|
||||
an expensive type cast. In general, its use is not encouraged.
|
||||
</para></notes>
|
||||
</overloaded-method>
|
||||
<method name="count" cv="const">
|
||||
<parameter name="k">
|
||||
@@ -1252,6 +1346,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase">
|
||||
<parameter name="k">
|
||||
@@ -1287,6 +1390,51 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="clear">
|
||||
<type>void</type>
|
||||
<description>
|
||||
@@ -1337,11 +1485,51 @@ 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>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
<notes><para>
|
||||
The templated overloads are a non-standard extensions which
|
||||
allows you to use a compatible hash function and equality
|
||||
predicate for a key of a different type in order to avoid
|
||||
an expensive type cast. In general, its use is not encouraged.
|
||||
</para></notes>
|
||||
</overloaded-method>
|
||||
<method name="count" cv="const">
|
||||
<parameter name="k">
|
||||
@@ -2059,6 +2247,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase">
|
||||
<parameter name="k">
|
||||
@@ -2094,6 +2291,51 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="clear">
|
||||
<type>void</type>
|
||||
<description>
|
||||
@@ -2144,11 +2386,51 @@ 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>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
<notes><para>
|
||||
The templated overloads are a non-standard extensions which
|
||||
allows you to use a compatible hash function and equality
|
||||
predicate for a key of a different type in order to avoid
|
||||
an expensive type cast. In general, its use is not encouraged.
|
||||
</para></notes>
|
||||
</overloaded-method>
|
||||
<method name="count" cv="const">
|
||||
<parameter name="k">
|
||||
@@ -2901,6 +3183,15 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
When the number of elements is a lot smaller than the number of buckets
|
||||
this function can be very inefficient as it has to search through empty
|
||||
buckets for the next element, in order to return the iterator.
|
||||
The method <methodname>quick_erase</methodname> is faster, but has yet
|
||||
to be standardized.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase">
|
||||
<parameter name="k">
|
||||
@@ -2936,6 +3227,51 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
<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="quick_erase">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is faster than <methodname>erase</methodname> as
|
||||
it doesn't have to find the next element in the container -
|
||||
a potentially costly operation.
|
||||
</para>
|
||||
<para>
|
||||
As it hasn't been standardized, it's likely that this may
|
||||
change in the future.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="erase_return_void">
|
||||
<parameter name="position">
|
||||
<paramtype>const_iterator</paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Erase the element pointed to by <code>position</code>.</para>
|
||||
</description>
|
||||
<throws>
|
||||
<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>
|
||||
<notes>
|
||||
<para>
|
||||
This method is now deprecated, use
|
||||
<methodname>quick_return</methodname> instead. Although be
|
||||
warned that as that isn't standardized yet, it could also
|
||||
change.
|
||||
</para>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="clear">
|
||||
<type>void</type>
|
||||
<description>
|
||||
@@ -2986,11 +3322,51 @@ 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>const_iterator</type>
|
||||
</signature>
|
||||
<signature>
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>iterator</type>
|
||||
</signature>
|
||||
<signature cv="const">
|
||||
<template>
|
||||
<template-type-parameter name="CompatibleKey"/>
|
||||
<template-type-parameter name="CompatibleHash"/>
|
||||
<template-type-parameter name="CompatiblePredicate"/>
|
||||
</template>
|
||||
<parameter name="k">
|
||||
<paramtype>CompatibleKey const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="hash">
|
||||
<paramtype>CompatibleHash const&</paramtype>
|
||||
</parameter>
|
||||
<parameter name="eq">
|
||||
<paramtype>CompatiblePredicate const&</paramtype>
|
||||
</parameter>
|
||||
<type>const_iterator</type>
|
||||
</signature>
|
||||
<returns>
|
||||
<para>An iterator pointing to an element with key equivalent to <code>k</code>, or <code>b.end()</code> if no such element exists.</para>
|
||||
</returns>
|
||||
<notes><para>
|
||||
The templated overloads are a non-standard extensions which
|
||||
allows you to use a compatible hash function and equality
|
||||
predicate for a key of a different type in order to avoid
|
||||
an expensive type cast. In general, its use is not encouraged.
|
||||
</para></notes>
|
||||
</overloaded-method>
|
||||
<method name="count" cv="const">
|
||||
<parameter name="k">
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
[license
|
||||
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]
|
||||
[@http://www.boost.org/LICENSE_1_0.txt])
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
+6
-3
@@ -55,11 +55,14 @@ namespace hash
|
||||
|
||||
// For 128 bit machines:
|
||||
// const std::size_t fnv_prime = 309485009821345068724781401u;
|
||||
// const std::size_t fnv_offset_basis = 275519064689413815358837431229664493455u;
|
||||
// const std::size_t fnv_offset_basis =
|
||||
// 275519064689413815358837431229664493455u;
|
||||
|
||||
// For 256 bit machines:
|
||||
// const std::size_t fnv_prime = 374144419156711147060143317175368453031918731002211u;
|
||||
// const std::size_t fnv_offset_basis = 100029257958052580907070968620625704837092796014241193945225284501741471925557u;
|
||||
// const std::size_t fnv_prime =
|
||||
// 374144419156711147060143317175368453031918731002211u;
|
||||
// const std::size_t fnv_offset_basis =
|
||||
// 100029257958052580907070968620625704837092796014241193945225284501741471925557u;
|
||||
|
||||
typedef basic_fnv_1<fnv_prime, fnv_offset_basis> fnv_1;
|
||||
typedef basic_fnv_1a<fnv_prime, fnv_offset_basis> fnv_1a;
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// Set up the sentinel (node_ptr cast)
|
||||
bucket_ptr sentinel = constructor.get() +
|
||||
static_cast<ptrdiff_t>(this->bucket_count_);
|
||||
static_cast<std::ptrdiff_t>(this->bucket_count_);
|
||||
sentinel->next_ = sentinel;
|
||||
|
||||
// Only release the buckets once everything is successfully
|
||||
|
||||
@@ -12,12 +12,107 @@
|
||||
|
||||
namespace boost { namespace unordered_detail {
|
||||
|
||||
template <class T>
|
||||
class hash_equivalent_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::table table;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_equivalent_table(std::size_t n,
|
||||
hasher const& hf, key_equal const& eq, value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x,
|
||||
value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x,
|
||||
value_allocator const& a, move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_equivalent_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
iterator_base emplace_impl(node_constructor& a);
|
||||
void emplace_impl_no_rehash(node_constructor& a);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_equivalent_table const&) const;
|
||||
|
||||
inline node_ptr add_node(node_constructor& a,
|
||||
bucket_ptr bucket, node_ptr pos);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template <class... Args>
|
||||
iterator_base emplace(Args&&... args);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
iterator_base emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
#endif
|
||||
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, forward_traversal_tag);
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, boost::incrementable_traversal_tag);
|
||||
template <class I>
|
||||
void insert_range(I i, I j);
|
||||
};
|
||||
|
||||
template <class H, class P, class A>
|
||||
struct multiset : public types<
|
||||
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
H, P, A,
|
||||
set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||
grouped>
|
||||
{
|
||||
typedef hash_equivalent_table<multiset<H, P, A> > impl;
|
||||
typedef hash_table<multiset<H, P, A> > table;
|
||||
};
|
||||
|
||||
template <class K, class H, class P, class A>
|
||||
struct multimap : public types<
|
||||
K, BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
H, P, A,
|
||||
map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||
grouped>
|
||||
{
|
||||
typedef hash_equivalent_table<multimap<K, H, P, A> > impl;
|
||||
typedef hash_table<multimap<K, H, P, A> > table;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Equality
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
bool hash_equivalent_table<H, P, A, K>
|
||||
::equals(hash_equivalent_table<H, P, A, K> const& other) const
|
||||
template <class T>
|
||||
bool hash_equivalent_table<T>
|
||||
::equals(hash_equivalent_table<T> const& other) const
|
||||
{
|
||||
if(this->size_ != other.size_) return false;
|
||||
if(!this->size_) return true;
|
||||
@@ -51,9 +146,9 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// A convenience method for adding nodes.
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, K>::node_ptr
|
||||
hash_equivalent_table<H, P, A, K>
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::node_ptr
|
||||
hash_equivalent_table<T>
|
||||
::add_node(node_constructor& a, bucket_ptr bucket, node_ptr pos)
|
||||
{
|
||||
node_ptr n = a.release();
|
||||
@@ -72,10 +167,10 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Insert methods
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME
|
||||
hash_equivalent_table<H, P, A, K>::iterator_base
|
||||
hash_equivalent_table<H, P, A, K>::emplace_impl(node_constructor& a)
|
||||
hash_equivalent_table<T>::iterator_base
|
||||
hash_equivalent_table<T>::emplace_impl(node_constructor& a)
|
||||
{
|
||||
key_type const& k = this->get_key(a.value());
|
||||
std::size_t hash_value = this->hash_function()(k);
|
||||
@@ -96,8 +191,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
inline void hash_equivalent_table<H, P, A, K>
|
||||
template <class T>
|
||||
inline void hash_equivalent_table<T>
|
||||
::emplace_impl_no_rehash(node_constructor& a)
|
||||
{
|
||||
key_type const& k = this->get_key(a.value());
|
||||
@@ -112,10 +207,10 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class... Args>
|
||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, K>::iterator_base
|
||||
hash_equivalent_table<H, P, A, K>
|
||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::iterator_base
|
||||
hash_equivalent_table<T>
|
||||
::emplace(Args&&... args)
|
||||
{
|
||||
// Create the node before rehashing in case it throws an
|
||||
@@ -129,10 +224,10 @@ namespace boost { namespace unordered_detail {
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||
template <class H, class P, class A, class K> \
|
||||
template <class T> \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<H, P, A, K>::iterator_base \
|
||||
hash_equivalent_table<H, P, A, K> \
|
||||
BOOST_DEDUCED_TYPENAME hash_equivalent_table<T>::iterator_base \
|
||||
hash_equivalent_table<T> \
|
||||
::emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
node_constructor a(*this); \
|
||||
@@ -151,9 +246,9 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class I>
|
||||
inline void hash_equivalent_table<H, P, A, K>
|
||||
inline void hash_equivalent_table<T>
|
||||
::insert_for_range(I i, I j, forward_traversal_tag)
|
||||
{
|
||||
if(i == j) return;
|
||||
@@ -182,9 +277,9 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class I>
|
||||
inline void hash_equivalent_table<H, P, A, K>
|
||||
inline void hash_equivalent_table<T>
|
||||
::insert_for_range(I i, I j, boost::incrementable_traversal_tag)
|
||||
{
|
||||
node_constructor a(*this);
|
||||
@@ -196,9 +291,9 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class I>
|
||||
void hash_equivalent_table<H, P, A, K>::insert_range(I i, I j)
|
||||
void hash_equivalent_table<T>::insert_range(I i, I j)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_traversal<I>::type
|
||||
iterator_traversal_tag;
|
||||
|
||||
@@ -28,128 +28,120 @@ namespace unordered_detail {
|
||||
template <class T> no_key(T const&) {}
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct set_extractor
|
||||
{
|
||||
template <class ValueType>
|
||||
struct apply
|
||||
typedef ValueType value_type;
|
||||
typedef ValueType key_type;
|
||||
|
||||
static key_type const& extract(key_type const& v)
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
typedef ValueType key_type;
|
||||
return v;
|
||||
}
|
||||
|
||||
static key_type const& extract(key_type const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
static no_key extract()
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#else
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&, Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool compare_mapped(value_type const&, value_type const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
struct map_extractor
|
||||
{
|
||||
template <class ValueType>
|
||||
struct apply
|
||||
static no_key extract()
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
remove_const<BOOST_DEDUCED_TYPENAME ValueType::first_type>::type
|
||||
key_type;
|
||||
|
||||
static key_type const& extract(value_type const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
static key_type const& extract(key_type const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class Second>
|
||||
static key_type const& extract(std::pair<key_type, Second> const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
template <class Second>
|
||||
static key_type const& extract(
|
||||
std::pair<key_type const, Second> const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
return no_key();
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
template <class Arg1, class... Args>
|
||||
static key_type const& extract(key_type const& k,
|
||||
Arg1 const&, Args const&...)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
template <class Arg1>
|
||||
static key_type const& extract(key_type const& k, Arg1 const&)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
static no_key extract()
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg, class Arg1>
|
||||
static no_key extract(Arg const&, Arg1 const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&, Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool compare_mapped(value_type const& x, value_type const& y)
|
||||
{
|
||||
return x.second == y.second;
|
||||
}
|
||||
};
|
||||
static bool compare_mapped(value_type const&, value_type const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Key, class ValueType>
|
||||
struct map_extractor
|
||||
{
|
||||
typedef ValueType value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::remove_const<Key>::type key_type;
|
||||
|
||||
static key_type const& extract(value_type const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
static key_type const& extract(key_type const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template <class Second>
|
||||
static key_type const& extract(std::pair<key_type, Second> const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
template <class Second>
|
||||
static key_type const& extract(
|
||||
std::pair<key_type const, Second> const& v)
|
||||
{
|
||||
return v.first;
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
template <class Arg1, class... Args>
|
||||
static key_type const& extract(key_type const& k,
|
||||
Arg1 const&, Args const&...)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
static no_key extract(Args const&...)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#else
|
||||
template <class Arg1>
|
||||
static key_type const& extract(key_type const& k, Arg1 const&)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
|
||||
static no_key extract()
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg>
|
||||
static no_key extract(Arg const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
|
||||
template <class Arg, class Arg1>
|
||||
static no_key extract(Arg const&, Arg1 const&)
|
||||
{
|
||||
return no_key();
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool compare_mapped(value_type const& x, value_type const& y)
|
||||
{
|
||||
return x.second == y.second;
|
||||
}
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#define BOOST_UNORDERED_DETAIL_FWD_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/compressed_pair.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
@@ -30,9 +29,9 @@
|
||||
// P = Predicate
|
||||
// A = Value Allocator
|
||||
// G = Grouped/Ungrouped
|
||||
// K = Key Extractor
|
||||
// E = Key Extractor
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
# if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
// STLport doesn't have std::forward.
|
||||
# else
|
||||
@@ -65,9 +64,13 @@ namespace boost { namespace unordered_detail {
|
||||
static const std::size_t default_bucket_count = 11;
|
||||
struct move_tag {};
|
||||
|
||||
template <class T> class hash_unique_table;
|
||||
template <class T> class hash_equivalent_table;
|
||||
template <class Alloc, class Grouped>
|
||||
class hash_node_constructor;
|
||||
template <class ValueType>
|
||||
struct set_extractor;
|
||||
template <class Key, class ValueType>
|
||||
struct map_extractor;
|
||||
struct no_key;
|
||||
|
||||
@@ -75,9 +78,7 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#if BOOST_MSVC >= 1400
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#endif
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
@@ -106,13 +107,6 @@ namespace boost { namespace unordered_detail {
|
||||
node_ptr next_;
|
||||
|
||||
hash_bucket() : next_() {}
|
||||
|
||||
// Only copy construct when allocating.
|
||||
hash_bucket(hash_bucket const& x)
|
||||
: next_()
|
||||
{
|
||||
BOOST_ASSERT(!x.next_);
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
@@ -187,6 +181,8 @@ namespace boost { namespace unordered_detail {
|
||||
value_type& value() {
|
||||
return *(ValueType*) this;
|
||||
}
|
||||
private:
|
||||
value_base& operator=(value_base const&);
|
||||
};
|
||||
|
||||
// Node
|
||||
@@ -203,6 +199,8 @@ namespace boost { namespace unordered_detail {
|
||||
static value_type& get_value(node_ptr p) {
|
||||
return static_cast<hash_node&>(*p).value();
|
||||
}
|
||||
private:
|
||||
hash_node& operator=(hash_node const&);
|
||||
};
|
||||
|
||||
// Iterator Base
|
||||
@@ -214,9 +212,9 @@ namespace boost { namespace unordered_detail {
|
||||
typedef A value_allocator;
|
||||
typedef hash_bucket<A> bucket;
|
||||
typedef hash_node<A, G> node;
|
||||
typedef BOOST_DEDUCED_TYPENAME node::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME node::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||
|
||||
bucket_ptr bucket_;
|
||||
node_ptr node_;
|
||||
@@ -274,9 +272,10 @@ namespace boost { namespace unordered_detail {
|
||||
typedef BOOST_DEDUCED_TYPENAME A::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME iterator_base::node node;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_allocator bucket_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME node::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME node::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_allocator
|
||||
bucket_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME bucket::node_ptr node_ptr;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME rebind_wrap<value_allocator, node>::type
|
||||
node_allocator;
|
||||
@@ -430,33 +429,28 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
};
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
class hash_table :
|
||||
public hash_buckets<A, G>,
|
||||
public hash_buffered_functions<H, P>
|
||||
template <class T>
|
||||
class hash_table : public T::buckets, public T::buffered_functions
|
||||
{
|
||||
hash_table(hash_table const&);
|
||||
public:
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A value_allocator;
|
||||
typedef K key_extractor;
|
||||
typedef hash_buffered_functions<H, P> base;
|
||||
typedef hash_buckets<A, G> buckets;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME value_allocator::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME key_extractor::BOOST_NESTED_TEMPLATE
|
||||
apply<value_type> extractor;
|
||||
typedef BOOST_DEDUCED_TYPENAME extractor::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::buffered_functions base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::buckets buckets;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
||||
typedef hash_node_constructor<A, G> node_constructor;
|
||||
typedef std::pair<iterator_base, iterator_base> iterator_pair;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_allocator node_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_pair iterator_pair;
|
||||
|
||||
// Members
|
||||
|
||||
@@ -475,6 +469,9 @@ namespace boost { namespace unordered_detail {
|
||||
return extractor::extract(node::get_value(n));
|
||||
}
|
||||
bool equal(key_type const& k, value_type const& v) const;
|
||||
template <class Key, class Pred>
|
||||
node_ptr find_iterator(bucket_ptr bucket, Key const& k,
|
||||
Pred const&) const;
|
||||
node_ptr find_iterator(bucket_ptr bucket, key_type const& k) const;
|
||||
node_ptr find_iterator(key_type const& k) const;
|
||||
node_ptr* find_for_erase(bucket_ptr bucket, key_type const& k) const;
|
||||
@@ -532,6 +529,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
std::size_t count(key_type const& k) const;
|
||||
iterator_base find(key_type const& k) const;
|
||||
template <class Key, class Hash, class Pred>
|
||||
iterator_base find(Key const& k, Hash const& h, Pred const& eq) const;
|
||||
value_type& at(key_type const& k) const;
|
||||
iterator_pair equal_range(key_type const& k) const;
|
||||
|
||||
@@ -541,7 +540,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
void clear();
|
||||
std::size_t erase_key(key_type const& k);
|
||||
iterator_base erase(iterator_base r);
|
||||
iterator_base erase_return_iterator(iterator_base r);
|
||||
void erase(iterator_base r);
|
||||
std::size_t erase_group(node_ptr* it, bucket_ptr bucket);
|
||||
iterator_base erase_range(iterator_base r1, iterator_base r2);
|
||||
|
||||
@@ -569,178 +569,9 @@ namespace boost { namespace unordered_detail {
|
||||
node_constructor&, std::size_t);
|
||||
};
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
class hash_unique_table :
|
||||
public hash_table<H, P, A, ungrouped, K>
|
||||
|
||||
{
|
||||
public:
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A value_allocator;
|
||||
typedef K key_extractor;
|
||||
|
||||
typedef hash_table<H, P, A, ungrouped, K> table;
|
||||
typedef hash_node_constructor<A, ungrouped> node_constructor;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME table::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::extractor extractor;
|
||||
|
||||
typedef std::pair<iterator_base, bool> emplace_return;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_unique_table(std::size_t n, hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_unique_table(hash_unique_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_unique_table(hash_unique_table const& x, value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_unique_table(hash_unique_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_unique_table(hash_unique_table& x, value_allocator const& a,
|
||||
move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_unique_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
emplace_return emplace_impl_with_node(node_constructor& a);
|
||||
value_type& operator[](key_type const& k);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_unique_table const&) const;
|
||||
|
||||
node_ptr add_node(node_constructor& a, bucket_ptr bucket);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template<class... Args>
|
||||
emplace_return emplace(Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(key_type const& k, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(no_key, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_empty_impl(Args&&... args);
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(key_type const& k, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(no_key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_empty_impl( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
|
||||
#endif
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception
|
||||
// safety strong otherwise
|
||||
template <class InputIt>
|
||||
void insert_range(InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(key_type const&, InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(no_key, InputIt i, InputIt j);
|
||||
};
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
class hash_equivalent_table :
|
||||
public hash_table<H, P, A, grouped, K>
|
||||
|
||||
{
|
||||
public:
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A value_allocator;
|
||||
typedef K key_extractor;
|
||||
|
||||
typedef hash_table<H, P, A, grouped, K> table;
|
||||
typedef hash_node_constructor<A, grouped> node_constructor;
|
||||
typedef hash_iterator_base<A, grouped> iterator_base;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME table::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::extractor extractor;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_equivalent_table(std::size_t n,
|
||||
hasher const& hf, key_equal const& eq, value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_equivalent_table(hash_equivalent_table const& x,
|
||||
value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_equivalent_table(hash_equivalent_table& x,
|
||||
value_allocator const& a, move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_equivalent_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
iterator_base emplace_impl(node_constructor& a);
|
||||
void emplace_impl_no_rehash(node_constructor& a);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_equivalent_table const&) const;
|
||||
|
||||
inline node_ptr add_node(node_constructor& a,
|
||||
bucket_ptr bucket, node_ptr pos);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template <class... Args>
|
||||
iterator_base emplace(Args&&... args);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
iterator_base emplace(BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
#endif
|
||||
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, forward_traversal_tag);
|
||||
template <class I>
|
||||
void insert_for_range(I i, I j, boost::incrementable_traversal_tag);
|
||||
template <class I>
|
||||
void insert_range(I i, I j);
|
||||
};
|
||||
|
||||
// Iterator Access
|
||||
|
||||
#if !defined(__clang__)
|
||||
class iterator_access
|
||||
{
|
||||
public:
|
||||
@@ -751,6 +582,28 @@ namespace boost { namespace unordered_detail {
|
||||
return it.base_;
|
||||
}
|
||||
};
|
||||
#else
|
||||
class iterator_access
|
||||
{
|
||||
public:
|
||||
// Note: we access Iterator::base here, rather than in the function
|
||||
// signature to work around a bug in the friend support of an
|
||||
// early version of clang.
|
||||
|
||||
template <class Iterator>
|
||||
struct base
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Iterator::base type;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
static BOOST_DEDUCED_TYPENAME base<Iterator>::type const&
|
||||
get(Iterator const& it)
|
||||
{
|
||||
return it.base_;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Iterators
|
||||
|
||||
@@ -969,6 +822,35 @@ namespace boost { namespace unordered_detail {
|
||||
return base_ != x.base_;
|
||||
}
|
||||
};
|
||||
|
||||
// types
|
||||
|
||||
template <class K, class V, class H, class P, class A, class E, class G>
|
||||
struct types
|
||||
{
|
||||
public:
|
||||
typedef K key_type;
|
||||
typedef V value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A value_allocator;
|
||||
typedef E extractor;
|
||||
typedef G group_type;
|
||||
|
||||
typedef hash_node_constructor<value_allocator, group_type>
|
||||
node_constructor;
|
||||
typedef hash_buckets<value_allocator, group_type> buckets;
|
||||
typedef hash_buffered_functions<hasher, key_equal> buffered_functions;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket bucket;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME buckets::node_allocator node_allocator;
|
||||
|
||||
typedef std::pair<iterator_base, iterator_base> iterator_pair;
|
||||
};
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <algorithm>
|
||||
#include <boost/config/no_tr1/cmath.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <boost/unordered/detail/buckets.hpp>
|
||||
|
||||
@@ -21,17 +22,34 @@ namespace boost { namespace unordered_detail {
|
||||
// Helper methods
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline bool hash_table<H, P, A, G, K>::equal(
|
||||
template <class T>
|
||||
inline bool hash_table<T>::equal(
|
||||
key_type const& k, value_type const& v) const
|
||||
{
|
||||
return this->key_eq()(k, get_key(v));
|
||||
}
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::node_ptr
|
||||
hash_table<H, P, A, G, K>::find_iterator(
|
||||
template <class T>
|
||||
template <class Key, class Pred>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||
hash_table<T>::find_iterator(bucket_ptr bucket, Key const& k,
|
||||
Pred const& eq) const
|
||||
{
|
||||
node_ptr it = bucket->next_;
|
||||
while (BOOST_UNORDERED_BORLAND_BOOL(it) &&
|
||||
!eq(k, get_key(node::get_value(it))))
|
||||
{
|
||||
it = node::next_group(it);
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||
hash_table<T>::find_iterator(
|
||||
bucket_ptr bucket, key_type const& k) const
|
||||
{
|
||||
node_ptr it = bucket->next_;
|
||||
@@ -46,17 +64,17 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// strong exception safety, no side effects
|
||||
// pre: this->buckets_
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::node_ptr
|
||||
hash_table<H, P, A, G, K>::find_iterator(key_type const& k) const
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr
|
||||
hash_table<T>::find_iterator(key_type const& k) const
|
||||
{
|
||||
return find_iterator(this->get_bucket(this->bucket_index(k)), k);
|
||||
}
|
||||
|
||||
// strong exception safety, no side effects
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::node_ptr*
|
||||
hash_table<H, P, A, G, K>::find_for_erase(
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME T::node_ptr*
|
||||
hash_table<T>::find_for_erase(
|
||||
bucket_ptr bucket, key_type const& k) const
|
||||
{
|
||||
node_ptr* it = &bucket->next_;
|
||||
@@ -73,8 +91,8 @@ namespace boost { namespace unordered_detail {
|
||||
// Load methods
|
||||
|
||||
// no throw
|
||||
template <class H, class P, class A, class G, class K>
|
||||
std::size_t hash_table<H, P, A, G, K>::max_size() const
|
||||
template <class T>
|
||||
std::size_t hash_table<T>::max_size() const
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
@@ -84,8 +102,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
// strong safety
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline std::size_t hash_table<H, P, A, G, K>::bucket_index(
|
||||
template <class T>
|
||||
inline std::size_t hash_table<T>::bucket_index(
|
||||
key_type const& k) const
|
||||
{
|
||||
// hash_function can throw:
|
||||
@@ -94,8 +112,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
|
||||
// no throw
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline std::size_t hash_table<H, P, A, G, K>::calculate_max_load()
|
||||
template <class T>
|
||||
inline std::size_t hash_table<T>::calculate_max_load()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
@@ -104,8 +122,8 @@ namespace boost { namespace unordered_detail {
|
||||
return double_to_size_t(ceil((double) mlf_ * this->bucket_count_));
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>::max_load_factor(float z)
|
||||
template <class T>
|
||||
void hash_table<T>::max_load_factor(float z)
|
||||
{
|
||||
BOOST_ASSERT(z > 0);
|
||||
mlf_ = (std::max)(z, minimum_max_load_factor);
|
||||
@@ -113,8 +131,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
// no throw
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline std::size_t hash_table<H, P, A, G, K>::min_buckets_for_size(
|
||||
template <class T>
|
||||
inline std::size_t hash_table<T>::min_buckets_for_size(
|
||||
std::size_t size) const
|
||||
{
|
||||
BOOST_ASSERT(this->mlf_ != 0);
|
||||
@@ -135,8 +153,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// init_buckets
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::init_buckets()
|
||||
template <class T>
|
||||
inline void hash_table<T>::init_buckets()
|
||||
{
|
||||
if (this->size_) {
|
||||
this->cached_begin_bucket_ = this->buckets_;
|
||||
@@ -153,8 +171,8 @@ namespace boost { namespace unordered_detail {
|
||||
//
|
||||
// no throw
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::recompute_begin_bucket(bucket_ptr b)
|
||||
template <class T>
|
||||
inline void hash_table<T>::recompute_begin_bucket(bucket_ptr b)
|
||||
{
|
||||
BOOST_ASSERT(!(b < this->cached_begin_bucket_));
|
||||
|
||||
@@ -174,8 +192,8 @@ namespace boost { namespace unordered_detail {
|
||||
//
|
||||
// no throw
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::recompute_begin_bucket(
|
||||
template <class T>
|
||||
inline void hash_table<T>::recompute_begin_bucket(
|
||||
bucket_ptr b1, bucket_ptr b2)
|
||||
{
|
||||
BOOST_ASSERT(!(b1 < this->cached_begin_bucket_) && !(b2 < b1));
|
||||
@@ -186,8 +204,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
// no throw
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline float hash_table<H, P, A, G, K>::load_factor() const
|
||||
template <class T>
|
||||
inline float hash_table<T>::load_factor() const
|
||||
{
|
||||
BOOST_ASSERT(this->bucket_count_ != 0);
|
||||
return static_cast<float>(this->size_)
|
||||
@@ -197,8 +215,8 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Constructors
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
hash_table<H, P, A, G, K>::hash_table(std::size_t num_buckets,
|
||||
template <class T>
|
||||
hash_table<T>::hash_table(std::size_t num_buckets,
|
||||
hasher const& hf, key_equal const& eq, node_allocator const& a)
|
||||
: buckets(a, next_prime(num_buckets)),
|
||||
base(hf, eq),
|
||||
@@ -211,8 +229,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// Copy Construct with allocator
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
hash_table<H, P, A, G, K>::hash_table(hash_table const& x,
|
||||
template <class T>
|
||||
hash_table<T>::hash_table(hash_table const& x,
|
||||
node_allocator const& a)
|
||||
: buckets(a, x.min_buckets_for_size(x.size_)),
|
||||
base(x),
|
||||
@@ -229,8 +247,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// Move Construct
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
hash_table<H, P, A, G, K>::hash_table(hash_table& x, move_tag)
|
||||
template <class T>
|
||||
hash_table<T>::hash_table(hash_table& x, move_tag)
|
||||
: buckets(x.node_alloc(), x.bucket_count_),
|
||||
base(x),
|
||||
size_(0),
|
||||
@@ -241,8 +259,8 @@ namespace boost { namespace unordered_detail {
|
||||
this->partial_swap(x);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
hash_table<H, P, A, G, K>::hash_table(hash_table& x,
|
||||
template <class T>
|
||||
hash_table<T>::hash_table(hash_table& x,
|
||||
node_allocator const& a, move_tag)
|
||||
: buckets(a, x.bucket_count_),
|
||||
base(x),
|
||||
@@ -261,8 +279,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
hash_table<H, P, A, G, K>& hash_table<H, P, A, G, K>::operator=(
|
||||
template <class T>
|
||||
hash_table<T>& hash_table<T>::operator=(
|
||||
hash_table const& x)
|
||||
{
|
||||
hash_table tmp(x, this->node_alloc());
|
||||
@@ -280,8 +298,8 @@ namespace boost { namespace unordered_detail {
|
||||
// Can throw if hash or predicate object's copy constructor throws
|
||||
// or if allocators are unequal.
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::partial_swap(hash_table& x)
|
||||
template <class T>
|
||||
inline void hash_table<T>::partial_swap(hash_table& x)
|
||||
{
|
||||
this->buckets::swap(x); // No throw
|
||||
std::swap(this->size_, x.size_);
|
||||
@@ -290,15 +308,15 @@ namespace boost { namespace unordered_detail {
|
||||
std::swap(this->max_load_, x.max_load_);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::fast_swap(hash_table& x)
|
||||
template <class T>
|
||||
inline void hash_table<T>::fast_swap(hash_table& x)
|
||||
{
|
||||
// These can throw, but they only affect the function objects
|
||||
// that aren't in use so it is strongly exception safe, via.
|
||||
// double buffering.
|
||||
{
|
||||
set_hash_functions<H, P> op1(*this, x);
|
||||
set_hash_functions<H, P> op2(x, *this);
|
||||
set_hash_functions<hasher, key_equal> op1(*this, x);
|
||||
set_hash_functions<hasher, key_equal> op2(x, *this);
|
||||
op1.commit();
|
||||
op2.commit();
|
||||
}
|
||||
@@ -309,8 +327,8 @@ namespace boost { namespace unordered_detail {
|
||||
std::swap(this->max_load_, x.max_load_);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::slow_swap(hash_table& x)
|
||||
template <class T>
|
||||
inline void hash_table<T>::slow_swap(hash_table& x)
|
||||
{
|
||||
if(this == &x) return;
|
||||
|
||||
@@ -318,8 +336,8 @@ namespace boost { namespace unordered_detail {
|
||||
// These can throw, but they only affect the function objects
|
||||
// that aren't in use so it is strongly exception safe, via.
|
||||
// double buffering.
|
||||
set_hash_functions<H, P> op1(*this, x);
|
||||
set_hash_functions<H, P> op2(x, *this);
|
||||
set_hash_functions<hasher, key_equal> op1(*this, x);
|
||||
set_hash_functions<hasher, key_equal> op2(x, *this);
|
||||
|
||||
// Create new buckets in separate hash_buckets objects
|
||||
// which will clean up if anything throws an exception.
|
||||
@@ -345,8 +363,8 @@ namespace boost { namespace unordered_detail {
|
||||
if(x.buckets_) x.init_buckets();
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>::swap(hash_table& x)
|
||||
template <class T>
|
||||
void hash_table<T>::swap(hash_table& x)
|
||||
{
|
||||
if(this->node_alloc() == x.node_alloc()) {
|
||||
if(this != &x) this->fast_swap(x);
|
||||
@@ -364,13 +382,13 @@ namespace boost { namespace unordered_detail {
|
||||
// Can throw if hash or predicate object's copy constructor throws
|
||||
// or if allocators are unequal.
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>::move(hash_table& x)
|
||||
template <class T>
|
||||
void hash_table<T>::move(hash_table& x)
|
||||
{
|
||||
// This can throw, but it only affects the function objects
|
||||
// that aren't in use so it is strongly exception safe, via.
|
||||
// double buffering.
|
||||
set_hash_functions<H, P> new_func_this(*this, x);
|
||||
set_hash_functions<hasher, key_equal> new_func_this(*this, x);
|
||||
|
||||
if(this->node_alloc() == x.node_alloc()) {
|
||||
this->buckets::move(x); // no throw
|
||||
@@ -402,8 +420,8 @@ namespace boost { namespace unordered_detail {
|
||||
// Reserve & Rehash
|
||||
|
||||
// basic exception safety
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::create_for_insert(std::size_t size)
|
||||
template <class T>
|
||||
inline void hash_table<T>::create_for_insert(std::size_t size)
|
||||
{
|
||||
this->bucket_count_ = (std::max)(this->bucket_count_,
|
||||
this->min_buckets_for_size(size));
|
||||
@@ -412,8 +430,8 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
// basic exception safety
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline bool hash_table<H, P, A, G, K>::reserve_for_insert(std::size_t size)
|
||||
template <class T>
|
||||
inline bool hash_table<T>::reserve_for_insert(std::size_t size)
|
||||
{
|
||||
if(size >= max_load_) {
|
||||
std::size_t num_buckets
|
||||
@@ -431,8 +449,8 @@ namespace boost { namespace unordered_detail {
|
||||
// if hash function throws, basic exception safety
|
||||
// strong otherwise.
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline void hash_table<H, P, A, G, K>::rehash(std::size_t min_buckets)
|
||||
template <class T>
|
||||
inline void hash_table<T>::rehash(std::size_t min_buckets)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
@@ -451,8 +469,8 @@ namespace boost { namespace unordered_detail {
|
||||
// if hash function throws, basic exception safety
|
||||
// strong otherwise
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>
|
||||
template <class T>
|
||||
void hash_table<T>
|
||||
::rehash_impl(std::size_t num_buckets)
|
||||
{
|
||||
hasher const& hf = this->hash_function();
|
||||
@@ -500,8 +518,8 @@ namespace boost { namespace unordered_detail {
|
||||
// basic excpetion safety. If an exception is thrown this will
|
||||
// leave dst partially filled.
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>
|
||||
template <class T>
|
||||
void hash_table<T>
|
||||
::copy_buckets_to(buckets& dst) const
|
||||
{
|
||||
BOOST_ASSERT(this->buckets_ && !dst.buckets_);
|
||||
@@ -509,7 +527,7 @@ namespace boost { namespace unordered_detail {
|
||||
hasher const& hf = this->hash_function();
|
||||
bucket_ptr end = this->get_bucket(this->bucket_count_);
|
||||
|
||||
hash_node_constructor<A, G> a(dst);
|
||||
node_constructor a(dst);
|
||||
dst.create_buckets();
|
||||
|
||||
// no throw:
|
||||
@@ -544,8 +562,8 @@ namespace boost { namespace unordered_detail {
|
||||
//
|
||||
// strong exception safety, no side effects
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
std::size_t hash_table<H, P, A, G, K>::count(key_type const& k) const
|
||||
template <class T>
|
||||
std::size_t hash_table<T>::count(key_type const& k) const
|
||||
{
|
||||
if(!this->size_) return 0;
|
||||
node_ptr it = find_iterator(k); // throws, strong
|
||||
@@ -555,9 +573,9 @@ namespace boost { namespace unordered_detail {
|
||||
// find
|
||||
//
|
||||
// strong exception safety, no side effects
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::iterator_base
|
||||
hash_table<H, P, A, G, K>::find(key_type const& k) const
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||
hash_table<T>::find(key_type const& k) const
|
||||
{
|
||||
if(!this->size_) return this->end();
|
||||
|
||||
@@ -570,28 +588,44 @@ namespace boost { namespace unordered_detail {
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME A::value_type&
|
||||
hash_table<H, P, A, G, K>::at(key_type const& k) const
|
||||
template <class T>
|
||||
template <class Key, class Hash, class Pred>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_base hash_table<T>::find(Key const& k,
|
||||
Hash const& h, Pred const& eq) const
|
||||
{
|
||||
if(!this->size_) return this->end();
|
||||
|
||||
bucket_ptr bucket = this->get_bucket(h(k) % this->bucket_count_);
|
||||
node_ptr it = find_iterator(bucket, k, eq);
|
||||
|
||||
if (BOOST_UNORDERED_BORLAND_BOOL(it))
|
||||
return iterator_base(bucket, it);
|
||||
else
|
||||
return this->end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::value_type&
|
||||
hash_table<T>::at(key_type const& k) const
|
||||
{
|
||||
if(!this->size_)
|
||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||
boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
|
||||
|
||||
bucket_ptr bucket = this->get_bucket(this->bucket_index(k));
|
||||
node_ptr it = find_iterator(bucket, k);
|
||||
|
||||
if (BOOST_UNORDERED_BORLAND_BOOL(it))
|
||||
return node::get_value(it);
|
||||
else
|
||||
throw std::out_of_range("Unable to find key in unordered_map.");
|
||||
if (!it)
|
||||
boost::throw_exception(std::out_of_range("Unable to find key in unordered_map."));
|
||||
|
||||
return node::get_value(it);
|
||||
}
|
||||
|
||||
// equal_range
|
||||
//
|
||||
// strong exception safety, no side effects
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::iterator_pair
|
||||
hash_table<H, P, A, G, K>::equal_range(key_type const& k) const
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_pair
|
||||
hash_table<T>::equal_range(key_type const& k) const
|
||||
{
|
||||
if(!this->size_)
|
||||
return iterator_pair(this->end(), this->end());
|
||||
@@ -612,8 +646,8 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Erase methods
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
void hash_table<H, P, A, G, K>::clear()
|
||||
template <class T>
|
||||
void hash_table<T>::clear()
|
||||
{
|
||||
if(!this->size_) return;
|
||||
|
||||
@@ -626,8 +660,8 @@ namespace boost { namespace unordered_detail {
|
||||
this->cached_begin_bucket_ = end;
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
inline std::size_t hash_table<H, P, A, G, K>::erase_group(
|
||||
template <class T>
|
||||
inline std::size_t hash_table<T>::erase_group(
|
||||
node_ptr* it, bucket_ptr bucket)
|
||||
{
|
||||
node_ptr pos = *it;
|
||||
@@ -639,8 +673,8 @@ namespace boost { namespace unordered_detail {
|
||||
return count;
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
std::size_t hash_table<H, P, A, G, K>::erase_key(key_type const& k)
|
||||
template <class T>
|
||||
std::size_t hash_table<T>::erase_key(key_type const& k)
|
||||
{
|
||||
if(!this->size_) return 0;
|
||||
|
||||
@@ -652,10 +686,20 @@ namespace boost { namespace unordered_detail {
|
||||
return *it ? this->erase_group(it, bucket) : 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void hash_table<T>::erase(iterator_base r)
|
||||
{
|
||||
BOOST_ASSERT(r.node_);
|
||||
--this->size_;
|
||||
node::unlink_node(*r.bucket_, r.node_);
|
||||
this->delete_node(r.node_);
|
||||
// r has been invalidated but its bucket is still valid
|
||||
this->recompute_begin_bucket(r.bucket_);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::iterator_base
|
||||
hash_table<H, P, A, G, K>::erase(iterator_base r)
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||
hash_table<T>::erase_return_iterator(iterator_base r)
|
||||
{
|
||||
BOOST_ASSERT(r.node_);
|
||||
iterator_base next = r;
|
||||
@@ -668,9 +712,9 @@ namespace boost { namespace unordered_detail {
|
||||
return next;
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::iterator_base
|
||||
hash_table<H, P, A, G, K>::erase_range(
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME T::iterator_base
|
||||
hash_table<T>::erase_range(
|
||||
iterator_base r1, iterator_base r2)
|
||||
{
|
||||
if(r1 != r2)
|
||||
@@ -713,9 +757,9 @@ namespace boost { namespace unordered_detail {
|
||||
return r2;
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class G, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<H, P, A, G, K>::iterator_base
|
||||
hash_table<H, P, A, G, K>::emplace_empty_impl_with_node(
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME hash_table<T>::iterator_base
|
||||
hash_table<T>::emplace_empty_impl_with_node(
|
||||
node_constructor& a, std::size_t size)
|
||||
{
|
||||
key_type const& k = get_key(a.value());
|
||||
|
||||
@@ -12,12 +12,125 @@
|
||||
|
||||
namespace boost { namespace unordered_detail {
|
||||
|
||||
template <class T>
|
||||
class hash_unique_table : public T::table
|
||||
{
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_allocator value_allocator;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::table table;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_constructor node_constructor;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node node;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::node_ptr node_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::bucket_ptr bucket_ptr;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::extractor extractor;
|
||||
|
||||
typedef std::pair<iterator_base, bool> emplace_return;
|
||||
|
||||
// Constructors
|
||||
|
||||
hash_unique_table(std::size_t n, hasher const& hf, key_equal const& eq,
|
||||
value_allocator const& a)
|
||||
: table(n, hf, eq, a) {}
|
||||
hash_unique_table(hash_unique_table const& x)
|
||||
: table(x, x.node_alloc()) {}
|
||||
hash_unique_table(hash_unique_table const& x, value_allocator const& a)
|
||||
: table(x, a) {}
|
||||
hash_unique_table(hash_unique_table& x, move_tag m)
|
||||
: table(x, m) {}
|
||||
hash_unique_table(hash_unique_table& x, value_allocator const& a,
|
||||
move_tag m)
|
||||
: table(x, a, m) {}
|
||||
~hash_unique_table() {}
|
||||
|
||||
// Insert methods
|
||||
|
||||
emplace_return emplace_impl_with_node(node_constructor& a);
|
||||
value_type& operator[](key_type const& k);
|
||||
|
||||
// equals
|
||||
|
||||
bool equals(hash_unique_table const&) const;
|
||||
|
||||
node_ptr add_node(node_constructor& a, bucket_ptr bucket);
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template<class... Args>
|
||||
emplace_return emplace(Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(key_type const& k, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_impl(no_key, Args&&... args);
|
||||
template<class... Args>
|
||||
emplace_return emplace_empty_impl(Args&&... args);
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(key_type const& k, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_impl(no_key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n)); \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, n)> \
|
||||
emplace_return emplace_empty_impl( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, n));
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
BOOST_UNORDERED_INSERT_IMPL, _)
|
||||
|
||||
#undef BOOST_UNORDERED_INSERT_IMPL
|
||||
|
||||
#endif
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception
|
||||
// safety strong otherwise
|
||||
template <class InputIt>
|
||||
void insert_range(InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(key_type const&, InputIt i, InputIt j);
|
||||
template <class InputIt>
|
||||
void insert_range_impl(no_key, InputIt i, InputIt j);
|
||||
};
|
||||
|
||||
template <class H, class P, class A>
|
||||
struct set : public types<
|
||||
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
H, P, A,
|
||||
set_extractor<BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||
ungrouped>
|
||||
{
|
||||
typedef hash_unique_table<set<H, P, A> > impl;
|
||||
typedef hash_table<set<H, P, A> > table;
|
||||
};
|
||||
|
||||
template <class K, class H, class P, class A>
|
||||
struct map : public types<
|
||||
K, BOOST_DEDUCED_TYPENAME A::value_type,
|
||||
H, P, A,
|
||||
map_extractor<K, BOOST_DEDUCED_TYPENAME A::value_type>,
|
||||
ungrouped>
|
||||
{
|
||||
typedef hash_unique_table<map<K, H, P, A> > impl;
|
||||
typedef hash_table<map<K, H, P, A> > table;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Equality
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
bool hash_unique_table<H, P, A, K>
|
||||
::equals(hash_unique_table<H, P, A, K> const& other) const
|
||||
template <class T>
|
||||
bool hash_unique_table<T>
|
||||
::equals(hash_unique_table<T> const& other) const
|
||||
{
|
||||
if(this->size_ != other.size_) return false;
|
||||
if(!this->size_) return true;
|
||||
@@ -43,9 +156,9 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// A convenience method for adding nodes.
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::node_ptr
|
||||
hash_unique_table<H, P, A, K>::add_node(node_constructor& a,
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::node_ptr
|
||||
hash_unique_table<T>::add_node(node_constructor& a,
|
||||
bucket_ptr bucket)
|
||||
{
|
||||
node_ptr n = a.release();
|
||||
@@ -61,9 +174,9 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::value_type&
|
||||
hash_unique_table<H, P, A, K>::operator[](key_type const& k)
|
||||
template <class T>
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::value_type&
|
||||
hash_unique_table<T>::operator[](key_type const& k)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME value_type::second_type mapped_type;
|
||||
|
||||
@@ -100,9 +213,9 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace_impl_with_node(node_constructor& a)
|
||||
template <class T>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace_impl_with_node(node_constructor& a)
|
||||
{
|
||||
// No side effects in this initial code
|
||||
key_type const& k = this->get_key(a.value());
|
||||
@@ -129,10 +242,10 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
#if defined(BOOST_UNORDERED_STD_FORWARD)
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template<class... Args>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace_impl(key_type const& k,
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace_impl(key_type const& k,
|
||||
Args&&... args)
|
||||
{
|
||||
// No side effects in this initial code
|
||||
@@ -166,10 +279,10 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template<class... Args>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace_impl(no_key, Args&&... args)
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace_impl(no_key, Args&&... args)
|
||||
{
|
||||
// Construct the node regardless - in order to get the key.
|
||||
// It will be discarded if it isn't used
|
||||
@@ -178,10 +291,10 @@ namespace boost { namespace unordered_detail {
|
||||
return emplace_impl_with_node(a);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template<class... Args>
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace_empty_impl(Args&&... args)
|
||||
inline BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace_empty_impl(Args&&... args)
|
||||
{
|
||||
node_constructor a(*this);
|
||||
a.construct(std::forward<Args>(args)...);
|
||||
@@ -191,11 +304,11 @@ namespace boost { namespace unordered_detail {
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||
template <class H, class P, class A, class K> \
|
||||
template <class T> \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||
inline BOOST_DEDUCED_TYPENAME \
|
||||
hash_unique_table<H, P, A, K>::emplace_return \
|
||||
hash_unique_table<H, P, A, K>::emplace_impl( \
|
||||
hash_unique_table<T>::emplace_return \
|
||||
hash_unique_table<T>::emplace_impl( \
|
||||
key_type const& k, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
@@ -218,11 +331,11 @@ namespace boost { namespace unordered_detail {
|
||||
} \
|
||||
} \
|
||||
\
|
||||
template <class H, class P, class A, class K> \
|
||||
template <class T> \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||
inline BOOST_DEDUCED_TYPENAME \
|
||||
hash_unique_table<H, P, A, K>::emplace_return \
|
||||
hash_unique_table<H, P, A, K>:: \
|
||||
hash_unique_table<T>::emplace_return \
|
||||
hash_unique_table<T>:: \
|
||||
emplace_impl(no_key, \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
@@ -231,17 +344,17 @@ namespace boost { namespace unordered_detail {
|
||||
return emplace_impl_with_node(a); \
|
||||
} \
|
||||
\
|
||||
template <class H, class P, class A, class K> \
|
||||
template <class T> \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||
inline BOOST_DEDUCED_TYPENAME \
|
||||
hash_unique_table<H, P, A, K>::emplace_return \
|
||||
hash_unique_table<H, P, A, K>:: \
|
||||
hash_unique_table<T>::emplace_return \
|
||||
hash_unique_table<T>:: \
|
||||
emplace_empty_impl( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
node_constructor a(*this); \
|
||||
a.construct(BOOST_UNORDERED_CALL_PARAMS(z, num_params)); \
|
||||
return emplace_return(this->emplace_empty_impl_with_node(a, 1), true); \
|
||||
return emplace_return(this->emplace_empty_impl_with_node(a, 1), true); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
@@ -259,10 +372,10 @@ namespace boost { namespace unordered_detail {
|
||||
// if hash function throws, basic exception safety
|
||||
// strong otherwise
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template<class... Args>
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace(Args&&... args)
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace(Args&&... args)
|
||||
{
|
||||
return this->size_ ?
|
||||
emplace_impl(
|
||||
@@ -273,10 +386,10 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
#else
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class Arg0>
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return
|
||||
hash_unique_table<H, P, A, K>::emplace(Arg0 const& arg0)
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return
|
||||
hash_unique_table<T>::emplace(Arg0 const& arg0)
|
||||
{
|
||||
return this->size_ ?
|
||||
emplace_impl(extractor::extract(arg0), arg0) :
|
||||
@@ -284,10 +397,10 @@ namespace boost { namespace unordered_detail {
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_INSERT_IMPL(z, num_params, _) \
|
||||
template <class H, class P, class A, class K> \
|
||||
template <class T> \
|
||||
template <BOOST_UNORDERED_TEMPLATE_ARGS(z, num_params)> \
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<H, P, A, K>::emplace_return \
|
||||
hash_unique_table<H, P, A, K>::emplace( \
|
||||
BOOST_DEDUCED_TYPENAME hash_unique_table<T>::emplace_return \
|
||||
hash_unique_table<T>::emplace( \
|
||||
BOOST_UNORDERED_FUNCTION_PARAMS(z, num_params)) \
|
||||
{ \
|
||||
return this->size_ ? \
|
||||
@@ -307,9 +420,9 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Insert range methods
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class InputIt>
|
||||
inline void hash_unique_table<H, P, A, K>::insert_range_impl(
|
||||
inline void hash_unique_table<T>::insert_range_impl(
|
||||
key_type const&, InputIt i, InputIt j)
|
||||
{
|
||||
node_constructor a(*this);
|
||||
@@ -323,8 +436,8 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
do {
|
||||
// No side effects in this initial code
|
||||
// Note: can't use get_key as '*i' might not be value_type - it could
|
||||
// be a pair with first_types as key_type without const or a
|
||||
// Note: can't use get_key as '*i' might not be value_type - it
|
||||
// could be a pair with first_types as key_type without const or a
|
||||
// different second_type.
|
||||
key_type const& k = extractor::extract(*i);
|
||||
std::size_t hash_value = this->hash_function()(k);
|
||||
@@ -352,9 +465,9 @@ namespace boost { namespace unordered_detail {
|
||||
} while(++i != j);
|
||||
}
|
||||
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class InputIt>
|
||||
inline void hash_unique_table<H, P, A, K>::insert_range_impl(
|
||||
inline void hash_unique_table<T>::insert_range_impl(
|
||||
no_key, InputIt i, InputIt j)
|
||||
{
|
||||
node_constructor a(*this);
|
||||
@@ -375,9 +488,9 @@ namespace boost { namespace unordered_detail {
|
||||
|
||||
// if hash function throws, or inserting > 1 element, basic exception safety
|
||||
// strong otherwise
|
||||
template <class H, class P, class A, class K>
|
||||
template <class T>
|
||||
template <class InputIt>
|
||||
void hash_unique_table<H, P, A, K>::insert_range(InputIt i, InputIt j)
|
||||
void hash_unique_table<T>::insert_range(InputIt i, InputIt j)
|
||||
{
|
||||
if(i != j)
|
||||
return insert_range_impl(extractor::extract(*i), i, j);
|
||||
|
||||
@@ -32,12 +32,6 @@ namespace boost { namespace unordered_detail {
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// primes
|
||||
|
||||
template<class T> struct prime_list_template
|
||||
{
|
||||
static std::size_t const value[];
|
||||
static std::ptrdiff_t const length;
|
||||
};
|
||||
|
||||
#define BOOST_UNORDERED_PRIMES \
|
||||
(5ul)(11ul)(17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
|
||||
(97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
|
||||
@@ -47,14 +41,28 @@ namespace boost { namespace unordered_detail {
|
||||
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
|
||||
(1610612741ul)(3221225473ul)(4294967291ul)
|
||||
|
||||
template<class T> struct prime_list_template
|
||||
{
|
||||
static std::size_t const value[];
|
||||
|
||||
#if !defined(SUNPRO_CC)
|
||||
static std::ptrdiff_t const length;
|
||||
#else
|
||||
static std::ptrdiff_t const length
|
||||
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T>
|
||||
std::size_t const prime_list_template<T>::value[] = {
|
||||
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)
|
||||
};
|
||||
|
||||
#if !defined(SUNPRO_CC)
|
||||
template<class T>
|
||||
std::ptrdiff_t const prime_list_template<T>::length
|
||||
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
|
||||
#endif
|
||||
|
||||
#undef BOOST_UNORDERED_PRIMES
|
||||
|
||||
@@ -288,6 +296,9 @@ namespace boost { namespace unordered_detail {
|
||||
{
|
||||
if (node_) {
|
||||
if (value_constructed_) {
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { hash_node<Alloc, Grouped> x; };
|
||||
#endif
|
||||
boost::unordered_detail::destroy(&node_->value());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
@@ -38,16 +38,16 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||
template <class K, class T, class H, class P, class A>
|
||||
class unordered_map
|
||||
{
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef K key_type;
|
||||
typedef std::pair<const K, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
private:
|
||||
@@ -58,10 +58,11 @@ namespace boost
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
|
||||
typedef boost::unordered_detail::hash_unique_table<Hash, Pred,
|
||||
value_allocator, boost::unordered_detail::map_extractor> table;
|
||||
typedef boost::unordered_detail::map<K, H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||
|
||||
public:
|
||||
|
||||
@@ -96,7 +97,7 @@ namespace boost
|
||||
|
||||
table table_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
||||
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
@@ -158,7 +159,7 @@ namespace boost
|
||||
|
||||
~unordered_map() {}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_map(unordered_map&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -176,7 +177,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
unordered_map(boost::unordered_detail::move_from<
|
||||
unordered_map<Key, T, Hash, Pred, Alloc>
|
||||
unordered_map<K, T, H, P, A>
|
||||
> other)
|
||||
: table_(other.source.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -283,16 +284,19 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
std::pair<iterator, bool> emplace(value_type const& v = value_type())
|
||||
{
|
||||
return boost::unordered_detail::pair_cast<iterator, bool>(
|
||||
table_.emplace(v));
|
||||
}
|
||||
|
||||
iterator emplace_hint(const_iterator, value_type const& v = value_type())
|
||||
iterator emplace_hint(const_iterator,
|
||||
value_type const& v = value_type())
|
||||
{
|
||||
return iterator(table_.emplace(v).first);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
template < \
|
||||
@@ -352,7 +356,7 @@ namespace boost
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(get(position)));
|
||||
return iterator(table_.erase_return_iterator(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
@@ -365,6 +369,16 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
table_.clear();
|
||||
@@ -414,6 +428,26 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@@ -510,9 +544,9 @@ namespace boost
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
friend bool operator==<Key, T, Hash, Pred, Alloc>(
|
||||
friend bool operator==<K, T, H, P, A>(
|
||||
unordered_map const&, unordered_map const&);
|
||||
friend bool operator!=<Key, T, Hash, Pred, Alloc>(
|
||||
friend bool operator!=<K, T, H, P, A>(
|
||||
unordered_map const&, unordered_map const&);
|
||||
#endif
|
||||
}; // class template unordered_map
|
||||
@@ -521,6 +555,9 @@ namespace boost
|
||||
inline bool operator==(unordered_map<K, T, H, P, A> const& m1,
|
||||
unordered_map<K, T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_map<K,T,H,P,A> x; };
|
||||
#endif
|
||||
return m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -528,6 +565,9 @@ namespace boost
|
||||
inline bool operator!=(unordered_map<K, T, H, P, A> const& m1,
|
||||
unordered_map<K, T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_map<K,T,H,P,A> x; };
|
||||
#endif
|
||||
return !m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -535,32 +575,38 @@ namespace boost
|
||||
inline void swap(unordered_map<K, T, H, P, A> &m1,
|
||||
unordered_map<K, T, H, P, A> &m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_map<K,T,H,P,A> x; };
|
||||
#endif
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Key, class T, class Hash, class Pred, class Alloc>
|
||||
template <class K, class T, class H, class P, class A>
|
||||
class unordered_multimap
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Key key_type;
|
||||
typedef std::pair<const Key, T> value_type;
|
||||
typedef K key_type;
|
||||
typedef std::pair<const K, T> value_type;
|
||||
typedef T mapped_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::unordered_detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
|
||||
typedef boost::unordered_detail::hash_equivalent_table<Hash, Pred,
|
||||
value_allocator, boost::unordered_detail::map_extractor> table;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
||||
typedef boost::unordered_detail::multimap<K, H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||
|
||||
public:
|
||||
|
||||
@@ -595,7 +641,7 @@ namespace boost
|
||||
|
||||
table table_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
||||
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
@@ -658,7 +704,7 @@ namespace boost
|
||||
|
||||
~unordered_multimap() {}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multimap(unordered_multimap&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -676,7 +722,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
unordered_multimap(boost::unordered_detail::move_from<
|
||||
unordered_multimap<Key, T, Hash, Pred, Alloc>
|
||||
unordered_multimap<K, T, H, P, A>
|
||||
> other)
|
||||
: table_(other.source.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -782,6 +828,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
iterator emplace(value_type const& v = value_type())
|
||||
{
|
||||
return iterator(table_.emplace(v));
|
||||
@@ -792,7 +839,7 @@ namespace boost
|
||||
{
|
||||
return iterator(table_.emplace(v));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
template < \
|
||||
@@ -852,7 +899,7 @@ namespace boost
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(get(position)));
|
||||
return iterator(table_.erase_return_iterator(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
@@ -865,6 +912,16 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
table_.clear();
|
||||
@@ -899,6 +956,26 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq)
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@@ -995,9 +1072,9 @@ namespace boost
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
friend bool operator==<Key, T, Hash, Pred, Alloc>(
|
||||
friend bool operator==<K, T, H, P, A>(
|
||||
unordered_multimap const&, unordered_multimap const&);
|
||||
friend bool operator!=<Key, T, Hash, Pred, Alloc>(
|
||||
friend bool operator!=<K, T, H, P, A>(
|
||||
unordered_multimap const&, unordered_multimap const&);
|
||||
#endif
|
||||
}; // class template unordered_multimap
|
||||
@@ -1006,6 +1083,9 @@ namespace boost
|
||||
inline bool operator==(unordered_multimap<K, T, H, P, A> const& m1,
|
||||
unordered_multimap<K, T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multimap<K,T,H,P,A> x; };
|
||||
#endif
|
||||
return m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -1013,6 +1093,9 @@ namespace boost
|
||||
inline bool operator!=(unordered_multimap<K, T, H, P, A> const& m1,
|
||||
unordered_multimap<K, T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multimap<K,T,H,P,A> x; };
|
||||
#endif
|
||||
return !m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -1020,6 +1103,9 @@ namespace boost
|
||||
inline void swap(unordered_multimap<K, T, H, P, A> &m1,
|
||||
unordered_multimap<K, T, H, P, A> &m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multimap<K,T,H,P,A> x; };
|
||||
#endif
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Key,
|
||||
template <class K,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class H = hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_map;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator==(unordered_map<K, T, H, P, A> const&,
|
||||
@@ -33,11 +33,11 @@ namespace boost
|
||||
void swap(unordered_map<K, T, H, P, A>&,
|
||||
unordered_map<K, T, H, P, A>&);
|
||||
|
||||
template <class Key,
|
||||
template <class K,
|
||||
class T,
|
||||
class Hash = hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Alloc = std::allocator<std::pair<const Key, T> > >
|
||||
class H = hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_multimap;
|
||||
template <class K, class T, class H, class P, class A>
|
||||
bool operator==(unordered_multimap<K, T, H, P, A> const&,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/unordered/detail/equivalent.hpp>
|
||||
#include <boost/unordered/detail/unique.hpp>
|
||||
|
||||
#if !defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
#include <boost/unordered/detail/move.hpp>
|
||||
#endif
|
||||
|
||||
@@ -38,16 +38,16 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
template <class T, class H, class P, class A>
|
||||
class unordered_set
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef T key_type;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
private:
|
||||
@@ -58,9 +58,11 @@ namespace boost
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
|
||||
typedef boost::unordered_detail::hash_unique_table<Hash, Pred,
|
||||
value_allocator, boost::unordered_detail::set_extractor> table;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
||||
typedef boost::unordered_detail::set<H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||
|
||||
public:
|
||||
|
||||
@@ -91,7 +93,7 @@ namespace boost
|
||||
|
||||
table table_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
||||
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
@@ -151,7 +153,7 @@ namespace boost
|
||||
|
||||
~unordered_set() {}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_set(unordered_set&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -169,7 +171,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
unordered_set(boost::unordered_detail::move_from<
|
||||
unordered_set<Value, Hash, Pred, Alloc>
|
||||
unordered_set<T, H, P, A>
|
||||
> other)
|
||||
: table_(other.source.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -346,7 +348,7 @@ namespace boost
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(get(position)));
|
||||
return iterator(table_.erase_return_iterator(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
@@ -359,6 +361,16 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
table_.clear();
|
||||
@@ -388,6 +400,15 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@@ -476,9 +497,9 @@ namespace boost
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
friend bool operator==<Value, Hash, Pred, Alloc>(
|
||||
friend bool operator==<T, H, P, A>(
|
||||
unordered_set const&, unordered_set const&);
|
||||
friend bool operator!=<Value, Hash, Pred, Alloc>(
|
||||
friend bool operator!=<T, H, P, A>(
|
||||
unordered_set const&, unordered_set const&);
|
||||
#endif
|
||||
}; // class template unordered_set
|
||||
@@ -487,6 +508,9 @@ namespace boost
|
||||
inline bool operator==(unordered_set<T, H, P, A> const& m1,
|
||||
unordered_set<T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_set<T,H,P,A> x; };
|
||||
#endif
|
||||
return m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -494,6 +518,9 @@ namespace boost
|
||||
inline bool operator!=(unordered_set<T, H, P, A> const& m1,
|
||||
unordered_set<T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_set<T,H,P,A> x; };
|
||||
#endif
|
||||
return !m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -501,31 +528,37 @@ namespace boost
|
||||
inline void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_set<T,H,P,A> x; };
|
||||
#endif
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
template <class T, class H, class P, class A>
|
||||
class unordered_multiset
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Value key_type;
|
||||
typedef Value value_type;
|
||||
typedef Hash hasher;
|
||||
typedef Pred key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
typedef T key_type;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef A allocator_type;
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
private:
|
||||
#endif
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::unordered_detail::rebind_wrap<
|
||||
allocator_type, value_type>::type
|
||||
value_allocator;
|
||||
|
||||
typedef boost::unordered_detail::hash_equivalent_table<Hash, Pred,
|
||||
value_allocator, boost::unordered_detail::set_extractor> table;
|
||||
typedef BOOST_DEDUCED_TYPENAME table::iterator_base iterator_base;
|
||||
typedef boost::unordered_detail::multiset<H, P,
|
||||
value_allocator> types;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::impl table;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME types::iterator_base iterator_base;
|
||||
|
||||
public:
|
||||
|
||||
@@ -556,7 +589,7 @@ namespace boost
|
||||
|
||||
table table_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME table::iterator_base const&
|
||||
BOOST_DEDUCED_TYPENAME types::iterator_base const&
|
||||
get(const_iterator const& it)
|
||||
{
|
||||
return boost::unordered_detail::iterator_access::get(it);
|
||||
@@ -617,7 +650,7 @@ namespace boost
|
||||
|
||||
~unordered_multiset() {}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
unordered_multiset(unordered_multiset&& other)
|
||||
: table_(other.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -635,7 +668,7 @@ namespace boost
|
||||
}
|
||||
#else
|
||||
unordered_multiset(boost::unordered_detail::move_from<
|
||||
unordered_multiset<Value, Hash, Pred, Alloc>
|
||||
unordered_multiset<T, H, P, A>
|
||||
> other)
|
||||
: table_(other.source.table_, boost::unordered_detail::move_tag())
|
||||
{
|
||||
@@ -808,7 +841,7 @@ namespace boost
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
return iterator(table_.erase(get(position)));
|
||||
return iterator(table_.erase_return_iterator(get(position)));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
@@ -821,6 +854,16 @@ namespace boost
|
||||
return iterator(table_.erase_range(get(first), get(last)));
|
||||
}
|
||||
|
||||
void quick_erase(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void erase_return_void(const_iterator position)
|
||||
{
|
||||
table_.erase(get(position));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
table_.clear();
|
||||
@@ -850,6 +893,16 @@ namespace boost
|
||||
return const_iterator(table_.find(k));
|
||||
}
|
||||
|
||||
template <class CompatibleKey, class CompatibleHash,
|
||||
class CompatiblePredicate>
|
||||
const_iterator find(
|
||||
CompatibleKey const& k,
|
||||
CompatibleHash const& hash,
|
||||
CompatiblePredicate const& eq) const
|
||||
{
|
||||
return iterator(table_.find(k, hash, eq));
|
||||
}
|
||||
|
||||
size_type count(const key_type& k) const
|
||||
{
|
||||
return table_.count(k);
|
||||
@@ -938,9 +991,9 @@ namespace boost
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
|
||||
friend bool operator==<Value, Hash, Pred, Alloc>(
|
||||
friend bool operator==<T, H, P, A>(
|
||||
unordered_multiset const&, unordered_multiset const&);
|
||||
friend bool operator!=<Value, Hash, Pred, Alloc>(
|
||||
friend bool operator!=<T, H, P, A>(
|
||||
unordered_multiset const&, unordered_multiset const&);
|
||||
#endif
|
||||
}; // class template unordered_multiset
|
||||
@@ -949,6 +1002,9 @@ namespace boost
|
||||
inline bool operator==(unordered_multiset<T, H, P, A> const& m1,
|
||||
unordered_multiset<T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multiset<T,H,P,A> x; };
|
||||
#endif
|
||||
return m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -956,6 +1012,9 @@ namespace boost
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const& m1,
|
||||
unordered_multiset<T, H, P, A> const& m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multiset<T,H,P,A> x; };
|
||||
#endif
|
||||
return !m1.table_.equals(m2.table_);
|
||||
}
|
||||
|
||||
@@ -963,6 +1022,9 @@ namespace boost
|
||||
inline void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy { unordered_multiset<T,H,P,A> x; };
|
||||
#endif
|
||||
m1.swap(m2);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
|
||||
namespace boost
|
||||
{
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
template <class T,
|
||||
class H = hash<T>,
|
||||
class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_set;
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator==(unordered_set<T, H, P, A> const&,
|
||||
@@ -32,10 +32,10 @@ namespace boost
|
||||
void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2);
|
||||
|
||||
template <class Value,
|
||||
class Hash = hash<Value>,
|
||||
class Pred = std::equal_to<Value>,
|
||||
class Alloc = std::allocator<Value> >
|
||||
template <class T,
|
||||
class H = hash<T>,
|
||||
class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_multiset;
|
||||
template <class T, class H, class P, class A>
|
||||
bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
|
||||
@@ -8,7 +8,18 @@ import testing ;
|
||||
#alias framework : /boost/test//boost_unit_test_framework ;
|
||||
alias framework : ;
|
||||
|
||||
project unordered-test/exception-tests ;
|
||||
project unordered-test/exception-tests
|
||||
: requirements
|
||||
<warnings>all
|
||||
<toolset>intel:<warnings>on
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
#<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
test-suite unordered-exception
|
||||
:
|
||||
|
||||
@@ -3,10 +3,16 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
test::seed_t seed(12847);
|
||||
|
||||
template <class T>
|
||||
@@ -18,7 +24,8 @@ struct self_assign_base : public test::exception_base
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x = x; }
|
||||
void check(T const& x) const { test::check_equivalent_keys(x); }
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
|
||||
{ test::check_equivalent_keys(x); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -40,15 +47,20 @@ struct assign_base : public test::exception_base
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
|
||||
: x_values(count1), y_values(count2),
|
||||
x(x_values.begin(), x_values.end(), 0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(y_values.begin(), y_values.end(), 0, hasher(tag2), key_equal(tag2), allocator_type(tag2)) {}
|
||||
assign_base(unsigned int count1, unsigned int count2, int tag1, int tag2) :
|
||||
x_values(count1),
|
||||
y_values(count2),
|
||||
x(x_values.begin(), x_values.end(), 0, hasher(tag1), key_equal(tag1),
|
||||
allocator_type(tag1)),
|
||||
y(y_values.begin(), y_values.end(), 0, hasher(tag2), key_equal(tag2),
|
||||
allocator_type(tag2))
|
||||
{}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(x); }
|
||||
void run(T& x1) const { x1 = y; }
|
||||
void check(T const& x1) const { test::check_equivalent_keys(x1); }
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x1) const
|
||||
{ test::check_equivalent_keys(x1); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
test::seed_t seed(91274);
|
||||
|
||||
struct objects
|
||||
@@ -22,6 +26,7 @@ struct construct_test1 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x;
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -30,6 +35,7 @@ struct construct_test2 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(300);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,6 +44,7 @@ struct construct_test3 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -46,6 +53,7 @@ struct construct_test4 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(0, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,6 +62,7 @@ struct construct_test5 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(50, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -62,6 +71,7 @@ struct construct_test6 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
T x(allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -79,6 +89,7 @@ struct range_construct_test1 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end());
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -87,6 +98,7 @@ struct range_construct_test2 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,6 +107,7 @@ struct range_construct_test3 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,6 +116,7 @@ struct range_construct_test4 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 100, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -114,7 +128,9 @@ struct range_construct_test5 : public range<T>, objects
|
||||
range_construct_test5() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0, hash, equal_to, allocator);
|
||||
T x(this->values.begin(), this->values.end(), 0,
|
||||
hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -124,14 +140,25 @@ struct input_range_construct_test : public range<T>, objects
|
||||
input_range_construct_test() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
T x(test::input_iterator(this->values.begin()),
|
||||
test::input_iterator(this->values.end()),
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
begin = this->values.begin(), end = this->values.end();
|
||||
T x(test::input_iterator(begin), test::input_iterator(end),
|
||||
0, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
RUN_EXCEPTION_TESTS(
|
||||
(construct_test1)(construct_test2)(construct_test3)(construct_test4)(construct_test5)(construct_test6)
|
||||
(range_construct_test1)(range_construct_test2)(range_construct_test3)(range_construct_test4)(range_construct_test5)
|
||||
(construct_test1)
|
||||
(construct_test2)
|
||||
(construct_test3)
|
||||
(construct_test4)
|
||||
(construct_test5)
|
||||
(construct_test6)
|
||||
(range_construct_test1)
|
||||
(range_construct_test2)
|
||||
(range_construct_test3)
|
||||
(range_construct_test4)
|
||||
(range_construct_test5)
|
||||
(input_range_construct_test),
|
||||
CONTAINER_SEQ)
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
test::seed_t seed(73041);
|
||||
|
||||
template <class T>
|
||||
@@ -15,6 +19,7 @@ struct copy_test1 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -28,6 +33,7 @@ struct copy_test2 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,6 +47,7 @@ struct copy_test3 : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -55,6 +62,7 @@ struct copy_with_allocator_test : public test::exception_base
|
||||
|
||||
void run() const {
|
||||
T y(x, allocator);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
@@ -22,7 +24,7 @@ struct erase_test_base : public test::exception_base
|
||||
return T(values.begin(), values.end());
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
BOOST_TEST(scope.find("hash::") != std::string::npos ||
|
||||
@@ -38,7 +40,8 @@ struct erase_by_key_test1 : public erase_test_base<T>
|
||||
{
|
||||
void run(T& x) const
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
test::random_values<T>::const_iterator iterator;
|
||||
|
||||
for(iterator it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
#include <boost/utility.hpp>
|
||||
#include <cmath>
|
||||
|
||||
@@ -27,7 +28,9 @@ struct insert_test_base : public test::exception_base
|
||||
return T();
|
||||
}
|
||||
|
||||
void check(T const& x, strong_type const& strong) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(
|
||||
T const& x, strong_type const& strong) const
|
||||
{
|
||||
std::string scope(test::scope);
|
||||
|
||||
if(scope.find("hash::operator()") == std::string::npos)
|
||||
@@ -36,7 +39,7 @@ struct insert_test_base : public test::exception_base
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class T>
|
||||
struct emplace_test1 : public insert_test_base<T>
|
||||
@@ -45,7 +48,8 @@ struct emplace_test1 : public insert_test_base<T>
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
x.emplace(*it);
|
||||
@@ -62,7 +66,8 @@ struct insert_test1 : public insert_test_base<T>
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
x.insert(*it);
|
||||
@@ -77,7 +82,8 @@ struct insert_test2 : public insert_test_base<T>
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
x.insert(x.begin(), *it);
|
||||
@@ -92,7 +98,7 @@ struct insert_test3 : public insert_test_base<T>
|
||||
x.insert(this->values.begin(), this->values.end());
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
@@ -104,7 +110,8 @@ struct insert_test4 : public insert_test_base<T>
|
||||
|
||||
void run(T& x, strong_type& strong) const {
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = this->values.begin(), end = this->values.end(); it != end; ++it)
|
||||
it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
x.insert(it, boost::next(it));
|
||||
@@ -141,7 +148,8 @@ struct insert_test_rehash1 : public insert_test_base<T>
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()), end = this->values.end();
|
||||
it = boost::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
@@ -164,7 +172,8 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
int count = 0;
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()), end = this->values.end();
|
||||
it = boost::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
strong.store(x, test::exception::detail::tracker.count_allocations);
|
||||
@@ -180,7 +189,8 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
template <class T>
|
||||
struct insert_test_rehash3 : public insert_test_base<T>
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::size_type mutable rehash_bucket_count, original_bucket_count;
|
||||
BOOST_DEDUCED_TYPENAME T::size_type mutable
|
||||
rehash_bucket_count, original_bucket_count;
|
||||
|
||||
insert_test_rehash3() : insert_test_base<T>(1000) {}
|
||||
|
||||
@@ -195,7 +205,8 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
rehash_bucket_count = static_cast<size_type>(
|
||||
ceil(original_bucket_count * (double) x.max_load_factor())) - 1;
|
||||
|
||||
size_type initial_elements = rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
|
||||
size_type initial_elements =
|
||||
rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
|
||||
|
||||
BOOST_TEST(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
@@ -215,7 +226,7 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
BOOST_TEST(x.bucket_count() != bucket_count);
|
||||
}
|
||||
|
||||
void check(T const& x) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const {
|
||||
if(x.size() < rehash_bucket_count) {
|
||||
//BOOST_TEST(x.bucket_count() == original_bucket_count);
|
||||
}
|
||||
@@ -227,7 +238,7 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4) \
|
||||
(insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
#define ALL_TESTS (emplace_test1)BASIC_TESTS
|
||||
#else
|
||||
#define ALL_TESTS BASIC_TESTS
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
@@ -18,7 +20,9 @@ struct rehash_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
unsigned int n;
|
||||
rehash_test_base(unsigned int count = 100, unsigned int n = 0) : values(count), n(n) {}
|
||||
rehash_test_base(unsigned int count = 100, unsigned int n = 0)
|
||||
: values(count), n(n)
|
||||
{}
|
||||
|
||||
typedef T data_type;
|
||||
typedef test::strong<T> strong_type;
|
||||
@@ -28,7 +32,9 @@ struct rehash_test_base : public test::exception_base
|
||||
return x;
|
||||
}
|
||||
|
||||
void check(T const& x, strong_type const& strong) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x,
|
||||
strong_type const& strong) const
|
||||
{
|
||||
std::string scope(test::scope);
|
||||
|
||||
if(scope.find("hash::operator()") == std::string::npos &&
|
||||
|
||||
@@ -3,10 +3,16 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4512) // assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
test::seed_t seed(9387);
|
||||
|
||||
template <class T>
|
||||
@@ -18,7 +24,7 @@ struct self_swap_base : public test::exception_base
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x.swap(x); }
|
||||
void check(T const& x) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
#if BOOST_UNORDERED_SWAP_METHOD != 2
|
||||
@@ -73,7 +79,7 @@ struct swap_base : public test::exception_base
|
||||
d.x.swap(d.y);
|
||||
} catch (std::runtime_error) {}
|
||||
}
|
||||
void check(data_type const& d) const {
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(data_type const& d) const {
|
||||
std::string scope(test::scope);
|
||||
|
||||
#if BOOST_UNORDERED_SWAP_METHOD != 2
|
||||
|
||||
@@ -58,8 +58,8 @@ namespace test
|
||||
return (std::numeric_limits<size_type>::max)();
|
||||
}
|
||||
|
||||
bool operator==(malloc_allocator const& x) const { return true; }
|
||||
bool operator!=(malloc_allocator const& x) const { return false; }
|
||||
bool operator==(malloc_allocator const&) const { return true; }
|
||||
bool operator!=(malloc_allocator const&) const { return false; }
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
template <class T> void deallocate(T* p, size_type) {
|
||||
|
||||
@@ -39,8 +39,15 @@ namespace test {
|
||||
return !(*this == x);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, object_count const& c) {
|
||||
out<<"[instances: "<<c.instances<<", constructions: "<<c.constructions<<"]";
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
object_count const& c)
|
||||
{
|
||||
out
|
||||
<< "[instances: "
|
||||
<< c.instances
|
||||
<< ", constructions: "
|
||||
<< c.constructions
|
||||
<< "]";
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,12 +21,16 @@ namespace test
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&, derived_type) {
|
||||
bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&,
|
||||
derived_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(std::equal_to<T> const&, std::equal_to<T> const&, derived_type) {
|
||||
bool equivalent_impl(std::equal_to<T> const&, std::equal_to<T> const&,
|
||||
derived_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,44 +12,50 @@
|
||||
#include <boost/preprocessor/seq/elem.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
test_func< type > fixture; \
|
||||
::test::lightweight::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
|
||||
}
|
||||
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
test_func< type > fixture; \
|
||||
::test::lightweight::exception_safety( \
|
||||
fixture, BOOST_STRINGIZE(test_func<type>)); \
|
||||
} \
|
||||
|
||||
# define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
|
||||
|
||||
#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
|
||||
|
||||
#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, (test_seq)(param_seq)) \
|
||||
RUN_TESTS()
|
||||
#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, \
|
||||
(test_seq)(param_seq)) \
|
||||
RUN_TESTS() \
|
||||
|
||||
#define RUN_EXCEPTION_TESTS_OP(r, product) \
|
||||
UNORDERED_EXCEPTION_TEST_CASE( \
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \
|
||||
), \
|
||||
BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_SEQ_ELEM(1, product) \
|
||||
)
|
||||
#define RUN_EXCEPTION_TESTS_OP(r, product) \
|
||||
UNORDERED_EXCEPTION_TEST_CASE( \
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \
|
||||
), \
|
||||
BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_SEQ_ELEM(1, product) \
|
||||
) \
|
||||
|
||||
#define UNORDERED_SCOPE(scope_name) \
|
||||
for(::test::scope_guard unordered_test_guard( \
|
||||
BOOST_STRINGIZE(scope_name)); \
|
||||
!unordered_test_guard.dismissed(); \
|
||||
unordered_test_guard.dismiss())
|
||||
#define UNORDERED_SCOPE(scope_name) \
|
||||
for(::test::scope_guard unordered_test_guard( \
|
||||
BOOST_STRINGIZE(scope_name)); \
|
||||
!unordered_test_guard.dismissed(); \
|
||||
unordered_test_guard.dismiss()) \
|
||||
|
||||
#define UNORDERED_EPOINT(name) \
|
||||
if(::test::exceptions_enabled) { \
|
||||
UNORDERED_EPOINT_IMPL(name); \
|
||||
}
|
||||
#define UNORDERED_EPOINT(name) \
|
||||
if(::test::exceptions_enabled) { \
|
||||
UNORDERED_EPOINT_IMPL(name); \
|
||||
} \
|
||||
|
||||
#define ENABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)
|
||||
#define DISABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
|
||||
#define ENABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT( \
|
||||
ENABLE_EXCEPTIONS_, __LINE__)(true) \
|
||||
|
||||
#define DISABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT( \
|
||||
ENABLE_EXCEPTIONS_, __LINE__)(false) \
|
||||
|
||||
namespace test {
|
||||
static char const* scope = "";
|
||||
@@ -110,25 +116,28 @@ namespace test {
|
||||
template <class T> void test(T const&) const {}
|
||||
};
|
||||
data_type init() const { return data_type(); }
|
||||
void check() const {}
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {}
|
||||
};
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(void (T::*fn)() const, T2 const& obj,
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)() const, T2 const& obj,
|
||||
P1&, P2&)
|
||||
{
|
||||
(obj.*fn)();
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(void (T::*fn)(P1&) const, T2 const& obj,
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&) const, T2 const& obj,
|
||||
P1& p1, P2&)
|
||||
{
|
||||
(obj.*fn)(p1);
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(void (T::*fn)(P1&, P2&) const, T2 const& obj,
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&, P2&) const, T2 const& obj,
|
||||
P1& p1, P2& p2)
|
||||
{
|
||||
(obj.*fn)(p1, p2);
|
||||
@@ -143,6 +152,9 @@ namespace test {
|
||||
class test_runner
|
||||
{
|
||||
Test const& test_;
|
||||
|
||||
test_runner(test_runner const&);
|
||||
test_runner& operator=(test_runner const&);
|
||||
public:
|
||||
test_runner(Test const& t) : test_(t) {}
|
||||
void operator()() const {
|
||||
@@ -153,11 +165,18 @@ namespace test {
|
||||
strong.store(x);
|
||||
try {
|
||||
ENABLE_EXCEPTIONS;
|
||||
call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type, BOOST_DEDUCED_TYPENAME Test::strong_type>(&Test::run, test_, x, strong);
|
||||
call_ignore_extra_parameters<
|
||||
Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type
|
||||
>(&Test::run, test_, x, strong);
|
||||
}
|
||||
catch(...) {
|
||||
call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type const, BOOST_DEDUCED_TYPENAME Test::strong_type const>(&Test::check, test_,
|
||||
constant(x), constant(strong));
|
||||
call_ignore_extra_parameters<
|
||||
Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type const,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type const
|
||||
>(&Test::check, test_, constant(x), constant(strong));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,15 @@ namespace test
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static key_type const& get_key(std::pair<key_type, T> const& x, char = 0)
|
||||
static key_type const& get_key(
|
||||
std::pair<key_type, T> const& x, char = 0)
|
||||
{
|
||||
return x.first;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static key_type const& get_key(std::pair<key_type const, T> const& x, unsigned char = 0)
|
||||
static key_type const& get_key(std::pair<key_type const, T> const& x,
|
||||
unsigned char = 0)
|
||||
{
|
||||
return x.first;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
#include <boost/iterator.hpp>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
@@ -16,31 +17,55 @@ namespace test
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type;
|
||||
|
||||
proxy(value_type const& v) : v_(v) {}
|
||||
explicit proxy(value_type const& v) : v_(v) {}
|
||||
proxy(proxy const& x) : v_(x.v_) {}
|
||||
operator value_type const&() const { return v_; }
|
||||
|
||||
value_type v_;
|
||||
private:
|
||||
proxy& operator=(proxy const&);
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct input_iterator_adaptor
|
||||
: boost::iterator_adaptor<
|
||||
input_iterator_adaptor<Iterator>, Iterator,
|
||||
boost::use_default, std::input_iterator_tag,
|
||||
proxy<Iterator> >
|
||||
: public boost::iterator<
|
||||
std::input_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator>
|
||||
>
|
||||
{
|
||||
typedef boost::iterator_adaptor<
|
||||
input_iterator_adaptor<Iterator>, Iterator,
|
||||
boost::use_default, std::input_iterator_tag,
|
||||
proxy<Iterator> > base;
|
||||
|
||||
explicit input_iterator_adaptor(Iterator it = Iterator())
|
||||
: base(it) {}
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
|
||||
input_iterator_adaptor()
|
||||
: base_() {}
|
||||
explicit input_iterator_adaptor(Iterator& it)
|
||||
: base_(&it) {}
|
||||
proxy<Iterator> operator*() const {
|
||||
return proxy<Iterator>(**base_);
|
||||
}
|
||||
value_type* operator->() const {
|
||||
return &**base_;
|
||||
}
|
||||
input_iterator_adaptor& operator++() {
|
||||
++*base_; return *this;
|
||||
}
|
||||
//input_iterator_adaptor operator++(int) {
|
||||
//}
|
||||
bool operator==(input_iterator_adaptor const& x) const {
|
||||
return *base_ == *x.base_;
|
||||
}
|
||||
bool operator!=(input_iterator_adaptor const& x) const {
|
||||
return *base_ != *x.base_;
|
||||
}
|
||||
private:
|
||||
Iterator* base_;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
input_iterator_adaptor<Iterator> input_iterator(Iterator it)
|
||||
input_iterator_adaptor<Iterator> input_iterator(Iterator& it)
|
||||
{
|
||||
return input_iterator_adaptor<Iterator>(it);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data
|
||||
#endif
|
||||
|
||||
namespace test
|
||||
@@ -29,9 +31,11 @@ namespace test
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
// Boost.Test was reporting memory leaks for std::set on g++-3.3.
|
||||
// So I work around it by using malloc.
|
||||
std::set<key_type, std::less<key_type>, test::malloc_allocator<key_type> > found_;
|
||||
std::set<key_type, std::less<key_type>,
|
||||
test::malloc_allocator<key_type> > found_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator it = x1.begin(), end = x1.end();
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator
|
||||
it = x1.begin(), end = x1.end();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type size = 0;
|
||||
while(it != end) {
|
||||
// First test that the current key has not occured before, required
|
||||
@@ -71,7 +75,8 @@ namespace test
|
||||
// // Check that the keys are in the correct bucket and are
|
||||
// // adjacent in the bucket.
|
||||
// BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key);
|
||||
// BOOST_DEDUCED_TYPENAME X::const_local_iterator lit = x1.begin(bucket), lend = x1.end(bucket);
|
||||
// BOOST_DEDUCED_TYPENAME X::const_local_iterator
|
||||
// lit = x1.begin(bucket), lend = x1.end(bucket);
|
||||
// for(; lit != lend && !eq(get_key<X>(*lit), key); ++lit) continue;
|
||||
// if(lit == lend)
|
||||
// BOOST_ERROR("Unable to find element with a local_iterator");
|
||||
@@ -81,7 +86,8 @@ namespace test
|
||||
// BOOST_ERROR("Element count doesn't match local_iterator.");
|
||||
// for(; lit != lend; ++lit) {
|
||||
// if(eq(get_key<X>(*lit), key)) {
|
||||
// BOOST_ERROR("Non-adjacent element with equivalent key in bucket.");
|
||||
// BOOST_ERROR("Non-adjacent element with equivalent key "
|
||||
// "in bucket.");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
@@ -90,7 +96,8 @@ namespace test
|
||||
// Finally, check that size matches up.
|
||||
if(x1.size() != size)
|
||||
BOOST_ERROR("x1.size() doesn't match actual size.");
|
||||
float load_factor = static_cast<float>(size) / static_cast<float>(x1.bucket_count());
|
||||
float load_factor =
|
||||
static_cast<float>(size) / static_cast<float>(x1.bucket_count());
|
||||
using namespace std;
|
||||
if(fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
||||
|
||||
+42
-8
@@ -17,6 +17,23 @@
|
||||
|
||||
namespace test
|
||||
{
|
||||
template <typename It1, typename It2>
|
||||
bool equal(It1 begin, It1 end, It2 compare)
|
||||
{
|
||||
for(;begin != end; ++begin, ++compare)
|
||||
if(*begin != *compare) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename It1, typename It2, typename Pred>
|
||||
bool equal(It1 begin, It1 end, It2 compare, Pred predicate)
|
||||
{
|
||||
for(;begin != end; ++begin, ++compare)
|
||||
if(!predicate(*begin, *compare)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename T> class list;
|
||||
|
||||
namespace test_detail
|
||||
@@ -77,7 +94,7 @@ namespace test
|
||||
|
||||
node* ptr_;
|
||||
public:
|
||||
list_iterator() : ptr_(0) {};
|
||||
list_iterator() : ptr_(0) {}
|
||||
explicit list_iterator(node* x) : ptr_(x) {}
|
||||
|
||||
T& operator*() const { return ptr_->value_; }
|
||||
@@ -109,12 +126,29 @@ namespace test
|
||||
|
||||
T const& operator*() const { return ptr_->value_; }
|
||||
T const* operator->() const { return &ptr_->value_; }
|
||||
list_const_iterator& operator++() {
|
||||
ptr_ = ptr_->next_; return *this; }
|
||||
list_const_iterator operator++(int) {
|
||||
list_const_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; }
|
||||
bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
|
||||
bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
|
||||
|
||||
list_const_iterator& operator++()
|
||||
{
|
||||
ptr_ = ptr_->next_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list_const_iterator operator++(int)
|
||||
{
|
||||
list_const_iterator tmp = *this;
|
||||
ptr_ = ptr_->next_;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const_iterator y) const
|
||||
{
|
||||
return ptr_ == y.ptr_;
|
||||
}
|
||||
|
||||
bool operator!=(const_iterator y) const
|
||||
{
|
||||
return ptr_ != y.ptr_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -222,7 +256,7 @@ namespace test
|
||||
|
||||
bool operator==(list const& y) const {
|
||||
return size() == y.size() &&
|
||||
std::equal(begin(), end(), y.begin());
|
||||
test::equal(begin(), end(), y.begin());
|
||||
}
|
||||
|
||||
bool operator!=(list const& y) const {
|
||||
|
||||
+17
-9
@@ -62,7 +62,8 @@ namespace test
|
||||
#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
|
||||
template <>
|
||||
struct allocator_memory_type_gen<int> {
|
||||
typedef std::map<memory_area, memory_track, memory_area_compare> type;
|
||||
typedef std::map<memory_area, memory_track, memory_area_compare>
|
||||
type;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -73,7 +74,8 @@ namespace test
|
||||
std::pair<memory_area const, memory_track> >::type
|
||||
allocator_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME allocator_memory_type_gen<allocator_type>::type
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
allocator_memory_type_gen<allocator_type>::type
|
||||
allocated_memory_type;
|
||||
|
||||
allocated_memory_type allocated_memory;
|
||||
@@ -106,7 +108,8 @@ namespace test
|
||||
bool no_constructions_left = (count_constructions == 0);
|
||||
bool allocated_memory_empty = allocated_memory.empty();
|
||||
|
||||
// Clearing the data before the checks terminate the tests.
|
||||
// Clearing the data before the checks terminate the
|
||||
// tests.
|
||||
count_allocations = 0;
|
||||
count_constructions = 0;
|
||||
allocated_memory.clear();
|
||||
@@ -118,7 +121,8 @@ namespace test
|
||||
}
|
||||
}
|
||||
|
||||
void track_allocate(void *ptr, std::size_t n, std::size_t size, int tag)
|
||||
void track_allocate(void *ptr, std::size_t n, std::size_t size,
|
||||
int tag)
|
||||
{
|
||||
if(n == 0) {
|
||||
BOOST_ERROR("Allocating 0 length array.");
|
||||
@@ -132,10 +136,12 @@ namespace test
|
||||
}
|
||||
}
|
||||
|
||||
void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag)
|
||||
void track_deallocate(void* ptr, std::size_t n, std::size_t size,
|
||||
int tag)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME allocated_memory_type::iterator pos
|
||||
= allocated_memory.find(memory_area(ptr, (char*) ptr + n * size));
|
||||
BOOST_DEDUCED_TYPENAME allocated_memory_type::iterator pos =
|
||||
allocated_memory.find(
|
||||
memory_area(ptr, (char*) ptr + n * size));
|
||||
if(pos == allocated_memory.end()) {
|
||||
BOOST_ERROR("Deallocating unknown pointer.");
|
||||
} else {
|
||||
@@ -148,12 +154,14 @@ namespace test
|
||||
if(count_allocations > 0) --count_allocations;
|
||||
}
|
||||
|
||||
void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
void track_construct(void* /*ptr*/, std::size_t /*size*/,
|
||||
int /*tag*/)
|
||||
{
|
||||
++count_constructions;
|
||||
}
|
||||
|
||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/,
|
||||
int /*tag*/)
|
||||
{
|
||||
BOOST_TEST(count_constructions > 0);
|
||||
if(count_constructions > 0) --count_constructions;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
// Copyright 2009 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)
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
// The standard windows mobile headers trigger this warning so I disable it
|
||||
// before doing anything else.
|
||||
#pragma warning(disable:4201) // nonstandard extension used :
|
||||
// nameless struct/union
|
||||
#endif
|
||||
@@ -71,7 +71,9 @@ namespace test
|
||||
type_ == generate_collisions ?
|
||||
generate(int_ptr) % 10 : 1;
|
||||
count; --count) {
|
||||
x.push_back(std::pair<key_type const, mapped_type>(key, generate(mapped_ptr)));
|
||||
x.push_back(
|
||||
std::pair<key_type const, mapped_type>(
|
||||
key, generate(mapped_ptr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace test
|
||||
|
||||
void test(X const& x, unsigned int allocations = 0) const {
|
||||
if(!(x.size() == values_.size() &&
|
||||
std::equal(x.cbegin(), x.cend(), values_.begin(),
|
||||
test::equal(x.cbegin(), x.cend(), values_.begin(),
|
||||
test::equivalent)))
|
||||
BOOST_ERROR("Strong exception safety failure.");
|
||||
if(allocations != allocations_)
|
||||
|
||||
+28
-25
@@ -11,19 +11,20 @@
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#define UNORDERED_AUTO_TEST(x) \
|
||||
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base { \
|
||||
BOOST_PP_CAT(x, _type)() \
|
||||
: ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \
|
||||
{ \
|
||||
::test::test_list::add_test(this); \
|
||||
} \
|
||||
void run(); \
|
||||
}; \
|
||||
BOOST_PP_CAT(x, _type) x; \
|
||||
void BOOST_PP_CAT(x, _type)::run()
|
||||
#define RUN_TESTS() int main(int, char**) \
|
||||
{ ::test::test_list::run_tests(); return boost::report_errors(); }
|
||||
#define UNORDERED_AUTO_TEST(x) \
|
||||
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base { \
|
||||
BOOST_PP_CAT(x, _type)() \
|
||||
: ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \
|
||||
{ \
|
||||
::test::test_list::add_test(this); \
|
||||
} \
|
||||
void run(); \
|
||||
}; \
|
||||
BOOST_PP_CAT(x, _type) x; \
|
||||
void BOOST_PP_CAT(x, _type)::run() \
|
||||
|
||||
#define RUN_TESTS() int main(int, char**) \
|
||||
{ ::test::test_list::run_tests(); return boost::report_errors(); } \
|
||||
|
||||
namespace test {
|
||||
struct registered_test_base {
|
||||
@@ -74,20 +75,22 @@ namespace test {
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
|
||||
// Run test with every combination of the parameters (a sequence of sequences)
|
||||
#define UNORDERED_TEST(name, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name)) parameters)
|
||||
#define UNORDERED_TEST(name, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name)) parameters) \
|
||||
|
||||
#define UNORDERED_TEST_OP(r, product) \
|
||||
UNORDERED_TEST_OP2( \
|
||||
BOOST_PP_SEQ_HEAD(product), \
|
||||
BOOST_PP_SEQ_TAIL(product))
|
||||
#define UNORDERED_TEST_OP(r, product) \
|
||||
UNORDERED_TEST_OP2( \
|
||||
BOOST_PP_SEQ_HEAD(product), \
|
||||
BOOST_PP_SEQ_TAIL(product)) \
|
||||
|
||||
#define UNORDERED_TEST_OP2(name, params) \
|
||||
UNORDERED_AUTO_TEST(BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params)) { \
|
||||
name BOOST_PP_SEQ_TO_TUPLE(params); \
|
||||
}
|
||||
#define UNORDERED_TEST_OP2(name, params) \
|
||||
UNORDERED_AUTO_TEST( \
|
||||
BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params)) \
|
||||
{ \
|
||||
name BOOST_PP_SEQ_TO_TUPLE(params); \
|
||||
} \
|
||||
|
||||
#define UNORDERED_TEST_OP_JOIN(s, state, elem) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))
|
||||
#define UNORDERED_TEST_OP_JOIN(s, state, elem) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem)) \
|
||||
|
||||
#endif
|
||||
|
||||
+45
-24
@@ -27,7 +27,8 @@ namespace test
|
||||
{
|
||||
template <class X>
|
||||
struct equals_to_compare2
|
||||
: public boost::mpl::identity<std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> >
|
||||
: public boost::mpl::identity<
|
||||
std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -50,7 +51,7 @@ namespace test
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
std::equal(values1.begin(), values1.end(), values2.begin(),
|
||||
test::equal(values1.begin(), values1.end(), values2.begin(),
|
||||
test::equivalent));
|
||||
}
|
||||
|
||||
@@ -62,37 +63,55 @@ namespace test
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
std::equal(values1.begin(), values1.end(), values2.begin(), test::equivalent));
|
||||
test::equal(values1.begin(), values1.end(),
|
||||
values2.begin(), test::equivalent));
|
||||
}
|
||||
|
||||
template <class X>
|
||||
struct ordered_set
|
||||
: public boost::mpl::if_<
|
||||
struct ordered_set : public
|
||||
boost::mpl::if_<
|
||||
test::has_unique_keys<X>,
|
||||
std::set<BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>,
|
||||
std::multiset<BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
> {};
|
||||
std::set<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<
|
||||
BOOST_DEDUCED_TYPENAME X::key_equal
|
||||
>::type
|
||||
>,
|
||||
std::multiset<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<
|
||||
BOOST_DEDUCED_TYPENAME X::key_equal
|
||||
>::type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class X>
|
||||
struct ordered_map
|
||||
: public boost::mpl::if_<
|
||||
struct ordered_map : public
|
||||
boost::mpl::if_<
|
||||
test::has_unique_keys<X>,
|
||||
std::map<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>,
|
||||
std::multimap<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
> {};
|
||||
std::map<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<
|
||||
BOOST_DEDUCED_TYPENAME X::key_equal
|
||||
>::type
|
||||
>,
|
||||
std::multimap<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<
|
||||
BOOST_DEDUCED_TYPENAME X::key_equal
|
||||
>::type
|
||||
>
|
||||
> {};
|
||||
|
||||
template <class X>
|
||||
struct ordered_base
|
||||
: public boost::mpl::eval_if<
|
||||
struct ordered_base : public
|
||||
boost::mpl::eval_if<
|
||||
test::is_set<X>,
|
||||
test::ordered_set<X>,
|
||||
test::ordered_map<X> >
|
||||
{
|
||||
};
|
||||
test::ordered_map<X>
|
||||
> {};
|
||||
|
||||
template <class X>
|
||||
class ordered : public ordered_base<X>::type
|
||||
@@ -114,7 +133,8 @@ namespace test
|
||||
compare_range(x, *this);
|
||||
}
|
||||
|
||||
void compare_key(X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val)
|
||||
void compare_key(X const& x,
|
||||
BOOST_DEDUCED_TYPENAME X::value_type const& val)
|
||||
{
|
||||
compare_pairs(
|
||||
x.equal_range(get_key<X>(val)),
|
||||
@@ -132,7 +152,8 @@ namespace test
|
||||
};
|
||||
|
||||
template <class Equals>
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare(Equals const&)
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<Equals>::type create_compare(Equals const&)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
|
||||
return x;
|
||||
|
||||
+50
-15
@@ -46,31 +46,61 @@ namespace minimal
|
||||
class copy_constructible_equality_comparable
|
||||
{
|
||||
public:
|
||||
static copy_constructible_equality_comparable create() { return copy_constructible_equality_comparable(); }
|
||||
copy_constructible_equality_comparable(copy_constructible_equality_comparable const&) {}
|
||||
~copy_constructible_equality_comparable() {}
|
||||
static copy_constructible_equality_comparable create() {
|
||||
return copy_constructible_equality_comparable();
|
||||
}
|
||||
|
||||
copy_constructible_equality_comparable(
|
||||
copy_constructible_equality_comparable const&)
|
||||
{
|
||||
}
|
||||
|
||||
~copy_constructible_equality_comparable()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
copy_constructible_equality_comparable& operator=(copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable& operator=(
|
||||
copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable() {}
|
||||
};
|
||||
|
||||
bool operator==(copy_constructible_equality_comparable, copy_constructible_equality_comparable) {
|
||||
bool operator==(
|
||||
copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(copy_constructible_equality_comparable, copy_constructible_equality_comparable) {
|
||||
bool operator!=(
|
||||
copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
class default_copy_constructible
|
||||
{
|
||||
public:
|
||||
static default_copy_constructible create() { return default_copy_constructible(); }
|
||||
default_copy_constructible() {}
|
||||
default_copy_constructible(default_copy_constructible const&) {}
|
||||
~default_copy_constructible() {}
|
||||
static default_copy_constructible create()
|
||||
{
|
||||
return default_copy_constructible();
|
||||
}
|
||||
|
||||
default_copy_constructible()
|
||||
{
|
||||
}
|
||||
|
||||
default_copy_constructible(default_copy_constructible const&)
|
||||
{
|
||||
}
|
||||
|
||||
~default_copy_constructible()
|
||||
{
|
||||
}
|
||||
private:
|
||||
default_copy_constructible& operator=(default_copy_constructible const&);
|
||||
default_copy_constructible& operator=(
|
||||
default_copy_constructible const&);
|
||||
};
|
||||
|
||||
class assignable
|
||||
@@ -130,7 +160,8 @@ namespace minimal
|
||||
ptr& operator++() { ++ptr_; return *this; }
|
||||
ptr operator++(int) { ptr tmp(*this); ++ptr_; return tmp; }
|
||||
ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
|
||||
friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
|
||||
friend ptr operator+(std::ptrdiff_t s, ptr p)
|
||||
{ return ptr<T>(s + p.ptr_); }
|
||||
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
|
||||
@@ -169,8 +200,10 @@ namespace minimal
|
||||
T const* operator->() const { return ptr_; }
|
||||
const_ptr& operator++() { ++ptr_; return *this; }
|
||||
const_ptr operator++(int) { const_ptr tmp(*this); ++ptr_; return tmp; }
|
||||
const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
|
||||
friend const_ptr operator+(std::ptrdiff_t s, const_ptr p) { return ptr<T>(s + p.ptr_); }
|
||||
const_ptr operator+(std::ptrdiff_t s) const
|
||||
{ return const_ptr(ptr_ + s); }
|
||||
friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
|
||||
{ return ptr<T>(s + p.ptr_); }
|
||||
T const& operator[](int s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
operator bool() const { return !!ptr_; }
|
||||
@@ -272,7 +305,9 @@ namespace boost {
|
||||
namespace test {
|
||||
namespace minimal {
|
||||
#endif
|
||||
std::size_t hash_value(test::minimal::copy_constructible_equality_comparable) {
|
||||
std::size_t hash_value(
|
||||
test::minimal::copy_constructible_equality_comparable)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
|
||||
+33
-7
@@ -190,13 +190,37 @@ namespace test
|
||||
|
||||
template <class U> struct rebind { typedef allocator<U> other; };
|
||||
|
||||
explicit allocator(int t = 0) : tag_(t) { detail::tracker.allocator_ref(); }
|
||||
template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
|
||||
allocator(allocator const& x) : tag_(x.tag_) { detail::tracker.allocator_ref(); }
|
||||
~allocator() { detail::tracker.allocator_unref(); }
|
||||
explicit allocator(int t = 0) : tag_(t)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
template <class Y> allocator(allocator<Y> const& x)
|
||||
: tag_(x.tag_)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
pointer address(reference r) { return pointer(&r); }
|
||||
const_pointer address(const_reference r) { return const_pointer(&r); }
|
||||
allocator(allocator const& x)
|
||||
: tag_(x.tag_)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
~allocator()
|
||||
{
|
||||
detail::tracker.allocator_unref();
|
||||
}
|
||||
|
||||
pointer address(reference r)
|
||||
{
|
||||
return pointer(&r);
|
||||
}
|
||||
|
||||
const_pointer address(const_reference r)
|
||||
{
|
||||
return const_pointer(&r);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n) {
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
@@ -250,7 +274,9 @@ namespace test
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(allocator<T> const& x, allocator<T> const& y, test::derived_type) {
|
||||
bool equivalent_impl(allocator<T> const& x, allocator<T> const& y,
|
||||
test::derived_type)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,13 @@ project unordered-test/unordered
|
||||
: requirements
|
||||
<warnings>all
|
||||
<toolset>intel:<warnings>on
|
||||
<toolset>intel:<cxxflags>-strict-ansi
|
||||
<toolset>msvc:<cxxflags>/W4
|
||||
<toolset>gcc:<cxxflags>"-Wsign-promo -Wunused-parameter -pedantic"
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter"
|
||||
<toolset>gcc:<define>_GLIBCXX_DEBUG
|
||||
#<toolset>darwin:<define>_GLIBCXX_DEBUG
|
||||
<toolset>msvc:<warnings-as-errors>on
|
||||
#<toolset>gcc:<warnings-as-errors>on
|
||||
#<toolset>darwin:<warnings-as-errors>on
|
||||
;
|
||||
|
||||
test-suite unordered
|
||||
@@ -21,6 +25,7 @@ test-suite unordered
|
||||
[ run compile_set.cpp ]
|
||||
[ run compile_map.cpp ]
|
||||
[ run link_test_1.cpp link_test_2.cpp ]
|
||||
[ run incomplete_test.cpp ]
|
||||
[ run simple_tests.cpp ]
|
||||
[ run equivalent_keys_tests.cpp ]
|
||||
[ run constructor_tests.cpp ]
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -18,7 +20,8 @@ namespace assign_tests {
|
||||
test::seed_t seed(96785);
|
||||
|
||||
template <class T>
|
||||
void assign_tests1(T*, test::random_generator generator = test::default_generator)
|
||||
void assign_tests1(T*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
@@ -52,7 +55,8 @@ void assign_tests1(T*, test::random_generator generator = test::default_generato
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void assign_tests2(T*, test::random_generator generator = test::default_generator)
|
||||
void assign_tests2(T*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
|
||||
@@ -85,10 +89,18 @@ void assign_tests2(T*, test::random_generator generator = test::default_generato
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
@@ -118,7 +130,8 @@ UNORDERED_AUTO_TEST(assign_default_initializer_list) {
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
|
||||
!defined(BOOST_NO_INITIALIZER_LISTS)
|
||||
|
||||
UNORDERED_AUTO_TEST(assign_initializer_list)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
#include <string>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -11,6 +13,11 @@
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#endif
|
||||
|
||||
namespace bucket_tests {
|
||||
|
||||
test::seed_t seed(54635);
|
||||
@@ -36,24 +43,40 @@ void tests(X* = 0, test::random_generator generator = test::default_generator)
|
||||
if(bucket < x.max_bucket_count()) {
|
||||
// lit? lend?? I need a new naming scheme.
|
||||
const_local_iterator lit = x.begin(bucket), lend = x.end(bucket);
|
||||
while(lit != lend && test::get_key<X>(*it) != test::get_key<X>(*lit)) ++lit;
|
||||
while(lit != lend
|
||||
&& test::get_key<X>(*it) != test::get_key<X>(*lit))
|
||||
{
|
||||
++lit;
|
||||
}
|
||||
BOOST_TEST(lit != lend);
|
||||
}
|
||||
}
|
||||
|
||||
for(size_type i = 0; i < x.bucket_count(); ++i) {
|
||||
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x.begin(i), x.end(i)));
|
||||
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x.cbegin(i), x.cend(i)));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x.begin(i), x.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x.cbegin(i), x.cend(i))));
|
||||
X const& x_ref = x;
|
||||
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x_ref.begin(i), x_ref.end(i)));
|
||||
BOOST_TEST(x.bucket_size(i) == (size_type) std::distance(x_ref.cbegin(i), x_ref.cend(i)));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x_ref.begin(i), x_ref.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x_ref.cbegin(i), x_ref.cend(i))));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
UNORDERED_TEST(tests, ((test_set)(test_multiset)(test_map)(test_multimap)))
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
// This test creates the containers with members that meet their minimum
|
||||
// requirements. Makes sure everything compiles and is defined correctly.
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
// This test creates the containers with members that meet their minimum
|
||||
// requirements. Makes sure everything compiles and is defined correctly.
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#pragma warning(disable:4610) // class can never be instantiated
|
||||
#pragma warning(disable:4510) // default constructor could not be generated
|
||||
#endif
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
@@ -35,10 +37,15 @@ void container_test(X& r, T const&)
|
||||
typedef BOOST_DEDUCED_TYPENAME X::difference_type difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<iterator>::type iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<const_iterator>::type const_iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<const_iterator>::type const_iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_value<iterator>::type iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_value<const_iterator>::type const_iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<iterator>::type iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_iterator>::type
|
||||
const_iterator_difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::reference reference;
|
||||
@@ -131,6 +138,12 @@ void container_test(X& r, T const&)
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
|
||||
test::check_return_type<allocator_type>::equals(a_const.get_allocator());
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(u);
|
||||
sink(u2);
|
||||
sink(u3);
|
||||
}
|
||||
|
||||
template <class X, class Key>
|
||||
@@ -147,7 +160,8 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
BOOST_MPL_ASSERT((boost::is_same<value_type, std::pair<key_type const, T> >));
|
||||
BOOST_MPL_ASSERT((
|
||||
boost::is_same<value_type, std::pair<key_type const, T> >));
|
||||
|
||||
r.insert(std::pair<Key const, T>(k, v));
|
||||
|
||||
@@ -210,25 +224,57 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<iterator>::type iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<iterator>::type iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<iterator>::type
|
||||
iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<iterator>::type
|
||||
iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type
|
||||
iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<iterator>::type
|
||||
iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<local_iterator>::type local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<local_iterator>::type local_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type
|
||||
local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<local_iterator>::type
|
||||
local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type
|
||||
local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<local_iterator>::type
|
||||
local_iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type const_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<const_iterator>::type const_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<const_iterator>::type const_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type
|
||||
const_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_iterator>::type
|
||||
const_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<const_iterator>::type
|
||||
const_iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type const_local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<const_local_iterator>::type const_local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_local_iterator>::type const_local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<const_local_iterator>::type const_local_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type
|
||||
const_local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_local_iterator>::type
|
||||
const_local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<const_local_iterator>::type
|
||||
const_local_iterator_reference;
|
||||
|
||||
BOOST_MPL_ASSERT((boost::is_same<Key, key_type>));
|
||||
boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
|
||||
@@ -241,16 +287,25 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
test::check_return_type<bool>::convertible(eq(k, k));
|
||||
|
||||
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_category, iterator_category>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_difference, iterator_difference>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_pointer, iterator_pointer>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_reference, iterator_reference>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_category,
|
||||
iterator_category>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_difference,
|
||||
iterator_difference>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_pointer,
|
||||
iterator_pointer>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<local_iterator_reference,
|
||||
iterator_reference>));
|
||||
|
||||
boost::function_requires<boost::InputIteratorConcept<const_local_iterator> >();
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_category, const_iterator_category>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_difference, const_iterator_difference>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_pointer, const_iterator_pointer>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_reference, const_iterator_reference>));
|
||||
boost::function_requires<
|
||||
boost::InputIteratorConcept<const_local_iterator> >();
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_category,
|
||||
const_iterator_category>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_difference,
|
||||
const_iterator_difference>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_pointer,
|
||||
const_iterator_pointer>));
|
||||
BOOST_MPL_ASSERT((boost::is_same<const_local_iterator_reference,
|
||||
const_iterator_reference>));
|
||||
|
||||
X(10, hf, eq);
|
||||
X a(10, hf, eq);
|
||||
@@ -326,4 +381,16 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
test::check_return_type<float>::equals(b.max_load_factor());
|
||||
a.max_load_factor((float) 2.0);
|
||||
a.rehash(100);
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(a);
|
||||
sink(a2);
|
||||
sink(a3);
|
||||
sink(a4);
|
||||
sink(a5);
|
||||
sink(a6);
|
||||
sink(a7);
|
||||
sink(a8);
|
||||
sink(a9);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -20,7 +22,8 @@ namespace constructor_tests {
|
||||
test::seed_t seed(356730);
|
||||
|
||||
template <class T>
|
||||
void constructor_tests1(T*, test::random_generator generator = test::default_generator)
|
||||
void constructor_tests1(T*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
@@ -139,7 +142,6 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
|
||||
|
||||
std::cerr<<"Construct 11\n";
|
||||
{
|
||||
test::random_values<T> v(1000, generator);
|
||||
T x(al);
|
||||
BOOST_TEST(x.empty());
|
||||
BOOST_TEST(test::equivalent(x.hash_function(), hf));
|
||||
@@ -150,7 +152,8 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void constructor_tests2(T*, test::random_generator const& generator = test::default_generator)
|
||||
void constructor_tests2(T*,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
|
||||
@@ -243,8 +246,14 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
|
||||
std::cerr<<"Construct 8 - from input iterator\n";
|
||||
{
|
||||
test::random_values<T> v(100, generator);
|
||||
T x(test::input_iterator(v.begin()), test::input_iterator(v.end()), 0, hf1, eq1);
|
||||
T y(test::input_iterator(x.begin()), test::input_iterator(x.end()), 0, hf2, eq2);
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
v_begin = v.begin(), v_end = v.end();
|
||||
T x(test::input_iterator(v_begin),
|
||||
test::input_iterator(v_end), 0, hf1, eq1);
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator
|
||||
x_begin = x.begin(), x_end = x.end();
|
||||
T y(test::input_iterator(x_begin),
|
||||
test::input_iterator(x_end), 0, hf2, eq2);
|
||||
test::check_container(x, v);
|
||||
test::check_container(y, x);
|
||||
test::check_equivalent_keys(x);
|
||||
@@ -319,11 +328,17 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void map_constructor_test(T* = 0, test::random_generator const& generator = test::default_generator)
|
||||
void map_constructor_test(T* = 0,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"map_constructor_test\n";
|
||||
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME T::key_type, BOOST_DEDUCED_TYPENAME T::mapped_type> > list;
|
||||
typedef test::list<
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME T::key_type,
|
||||
BOOST_DEDUCED_TYPENAME T::mapped_type
|
||||
>
|
||||
> list;
|
||||
test::random_values<T> v(1000, generator);
|
||||
list l(v.begin(), v.end());
|
||||
T x(l.begin(), l.end());
|
||||
@@ -332,10 +347,18 @@ void map_constructor_test(T* = 0, test::random_generator const& generator = test
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
@@ -365,7 +388,8 @@ UNORDERED_AUTO_TEST(test_default_initializer_list) {
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_INITIALIZER_LISTS)
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
|
||||
!defined(BOOST_NO_INITIALIZER_LISTS)
|
||||
|
||||
UNORDERED_AUTO_TEST(test_initializer_list) {
|
||||
std::cerr<<"Initializer List Tests\n";
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -18,7 +20,8 @@ namespace copy_tests
|
||||
{
|
||||
|
||||
template <class T>
|
||||
void copy_construct_tests1(T*, test::random_generator const& generator = test::default_generator)
|
||||
void copy_construct_tests1(T*,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
@@ -63,7 +66,8 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void copy_construct_tests2(T* ptr, test::random_generator const& generator = test::default_generator)
|
||||
void copy_construct_tests2(T* ptr,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
copy_construct_tests1(ptr);
|
||||
|
||||
@@ -117,10 +121,18 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/preprocessor/seq.hpp>
|
||||
@@ -28,37 +30,40 @@ namespace equality_tests
|
||||
}
|
||||
};
|
||||
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
} while(false)
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
} while(false)
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> \
|
||||
set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
} while(false)
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
do { \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
} while(false)
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
|
||||
#define UNORDERED_MAP_INSERT(r, map, item) \
|
||||
@@ -89,57 +94,57 @@ namespace equality_tests
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_key_value_tests)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2));
|
||||
UNORDERED_EQUALITY_SET_TEST((2), ==, (2));
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)));
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
|
||||
UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_collision_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1), !=, (501));
|
||||
(1), !=, (501))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(251), !=, (1)(501));
|
||||
(1)(251), !=, (1)(501))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)));
|
||||
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(501), ==, (1)(501));
|
||||
(1)(501), ==, (1)(501))
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1)(501), ==, (501)(1));
|
||||
(1)(501), ==, (501)(1))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_group_size_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(10)(20)(20), !=, (10)(10)(20));
|
||||
(10)(20)(20), !=, (10)(10)(20))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((10)(1))((20)(1))((20)(1)), !=,
|
||||
((10)(1))((20)(1))((10)(1)));
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((20)(1))((10)(1))((10)(1)), ==,
|
||||
((10)(1))((20)(1))((10)(1)));
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_map_value_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)));
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), ==, ((1)(1)));
|
||||
((1)(1)), ==, ((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)));
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)));
|
||||
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)));
|
||||
((1)(2))((1)(1)), !=, ((1)(1))((1)(2)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_predicate_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1), ==, (1001));
|
||||
(1), ==, (1001))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)));
|
||||
((1)(2))((1001)(1)), ==, ((1001)(2))((1)(1)))
|
||||
}
|
||||
|
||||
// Test that equality still works when the two containers have
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -42,17 +44,20 @@ UNORDERED_AUTO_TEST(set_tests)
|
||||
{986, 25, 986}
|
||||
};
|
||||
|
||||
test_equal_insertion<boost::unordered_set<int> >(values[0], values[0] + 1);
|
||||
test_equal_insertion<boost::unordered_set<int> >(values[1], values[1] + 2);
|
||||
test_equal_insertion<boost::unordered_set<int> >(values[2], values[2] + 2);
|
||||
test_equal_insertion<boost::unordered_set<int> >(values[3], values[3] + 2);
|
||||
test_equal_insertion<boost::unordered_set<int> >(values[4], values[4] + 3);
|
||||
typedef boost::unordered_set<int> set;
|
||||
typedef boost::unordered_multiset<int> multiset;
|
||||
|
||||
test_equal_insertion<boost::unordered_multiset<int> >(values[0], values[0] + 1);
|
||||
test_equal_insertion<boost::unordered_multiset<int> >(values[1], values[1] + 2);
|
||||
test_equal_insertion<boost::unordered_multiset<int> >(values[2], values[2] + 2);
|
||||
test_equal_insertion<boost::unordered_multiset<int> >(values[3], values[3] + 2);
|
||||
test_equal_insertion<boost::unordered_multiset<int> >(values[4], values[4] + 3);
|
||||
test_equal_insertion<set>(values[0], values[0] + 1);
|
||||
test_equal_insertion<set>(values[1], values[1] + 2);
|
||||
test_equal_insertion<set>(values[2], values[2] + 2);
|
||||
test_equal_insertion<set>(values[3], values[3] + 2);
|
||||
test_equal_insertion<set>(values[4], values[4] + 3);
|
||||
|
||||
test_equal_insertion<multiset>(values[0], values[0] + 1);
|
||||
test_equal_insertion<multiset>(values[1], values[1] + 2);
|
||||
test_equal_insertion<multiset>(values[2], values[2] + 2);
|
||||
test_equal_insertion<multiset>(values[3], values[3] + 2);
|
||||
test_equal_insertion<multiset>(values[4], values[4] + 3);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(map_tests)
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
// The code for erasing elements from containers with equivalent keys is very
|
||||
// hairy with several tricky edge cases - so explicitly test each one.
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/list.hpp"
|
||||
@@ -15,6 +17,11 @@
|
||||
#include <boost/next_prior.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#endif
|
||||
|
||||
struct write_pair_type
|
||||
{
|
||||
template <class X1, class X2>
|
||||
@@ -128,7 +135,8 @@ template <class Container>
|
||||
void erase_subrange_tests(Container const& x)
|
||||
{
|
||||
for(std::size_t length = 0; length < x.size(); ++length) {
|
||||
for(std::size_t position = 0; position < x.size() - length; ++position) {
|
||||
for(std::size_t position = 0; position < x.size() - length; ++position)
|
||||
{
|
||||
Container y(x);
|
||||
collide_list init(y.begin(), y.end());
|
||||
if(!general_erase_range_test(y, position, position + length)) {
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -21,14 +23,15 @@ namespace erase_tests
|
||||
test::seed_t seed(85638);
|
||||
|
||||
template <class Container>
|
||||
void erase_tests1(Container*, test::random_generator generator = test::default_generator)
|
||||
void erase_tests1(Container*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"Erase by key.\n";
|
||||
{
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
std::size_t count = x.count(test::get_key<Container>(*it));
|
||||
std::size_t old_size = x.size();
|
||||
@@ -46,9 +49,11 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
|
||||
std::size_t size = x.size();
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*x.begin());
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_DEDUCED_TYPENAME Container::iterator pos = x.erase(x.begin());
|
||||
BOOST_DEDUCED_TYPENAME Container::iterator
|
||||
pos = x.erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(pos == x.begin());
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
@@ -65,7 +70,7 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
using namespace std;
|
||||
int index = rand() % x.size();
|
||||
int index = rand() % (int) x.size();
|
||||
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
prev = pos = x.begin();
|
||||
@@ -75,7 +80,8 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
|
||||
pos = boost::next(prev);
|
||||
}
|
||||
next = boost::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(next == x.erase(pos));
|
||||
--size;
|
||||
@@ -110,6 +116,57 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
|
||||
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(begin()).\n";
|
||||
{
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
x.quick_erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
BOOST_TEST(x.size() == size);
|
||||
}
|
||||
BOOST_TEST(x.empty());
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(random position).\n";
|
||||
{
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
using namespace std;
|
||||
int index = rand() % (int) x.size();
|
||||
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
prev = pos = x.begin();
|
||||
}
|
||||
else {
|
||||
prev = boost::next(x.begin(), index - 1);
|
||||
pos = boost::next(prev);
|
||||
}
|
||||
next = boost::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
x.quick_erase(pos);
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == boost::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
BOOST_TEST(x.size() == size);
|
||||
}
|
||||
BOOST_TEST(x.empty());
|
||||
}
|
||||
|
||||
|
||||
std::cerr<<"clear().\n";
|
||||
{
|
||||
test::random_values<Container> v(500, generator);
|
||||
@@ -122,10 +179,18 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
|
||||
std::cerr<<"\n";
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -33,7 +35,8 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
|
||||
iterator pos = x.find(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator const_pos = x_const.find(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator
|
||||
const_pos = x_const.find(key);
|
||||
BOOST_TEST(pos != x.end() &&
|
||||
x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
BOOST_TEST(const_pos != x_const.end() &&
|
||||
@@ -81,10 +84,69 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
struct compatible_key
|
||||
{
|
||||
test::object o_;
|
||||
|
||||
compatible_key(test::object const& o) : o_(o) {}
|
||||
};
|
||||
|
||||
struct compatible_hash
|
||||
{
|
||||
test::hash hash_;
|
||||
|
||||
std::size_t operator()(compatible_key const& k) const {
|
||||
return hash_(k.o_);
|
||||
}
|
||||
};
|
||||
|
||||
struct compatible_predicate
|
||||
{
|
||||
test::equal_to equal_;
|
||||
|
||||
bool operator()(compatible_key const& k1, compatible_key const& k2) const {
|
||||
return equal_(k1.o_, k2.o_);
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
void find_compatible_keys_test(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
value_iterator;
|
||||
test::random_values<X> v(500, generator);
|
||||
X x(v.begin(), v.end());
|
||||
|
||||
compatible_hash h;
|
||||
compatible_predicate eq;
|
||||
|
||||
for(value_iterator it = v.begin(), end = v.end(); it != end; ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
|
||||
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
|
||||
test::random_values<X> v2(20, generator);
|
||||
|
||||
for(value_iterator it = v2.begin(), end = v2.end(); it != end; ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
|
||||
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
@@ -93,6 +155,10 @@ UNORDERED_TEST(find_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
UNORDERED_TEST(find_compatible_keys_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
|
||||
typedef boost::unordered_map<int, int> int_map;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
|
||||
struct true_type { char x[100]; };
|
||||
@@ -45,7 +47,8 @@ bool call_not_equals(int_multiset& x, int_multiset& y) {
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) {
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*) 0)) == sizeof(true_type));
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*) 0))
|
||||
== sizeof(true_type));
|
||||
}
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
@@ -54,8 +57,7 @@ UNORDERED_AUTO_TEST(use_fwd_declared_trait) {
|
||||
boost::unordered_set<int> x;
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
||||
|
||||
int dummy;
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl(&dummy)) == sizeof(false_type));
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int*) 0)) == sizeof(false_type));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
|
||||
// Copyright 2009 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
namespace x
|
||||
{
|
||||
struct D { boost::unordered_map<D, D> x; };
|
||||
}
|
||||
|
||||
namespace test
|
||||
{
|
||||
// Declare, but don't define some types.
|
||||
|
||||
struct value;
|
||||
struct hash;
|
||||
struct equals;
|
||||
template <class T>
|
||||
struct malloc_allocator;
|
||||
|
||||
// Declare some instances
|
||||
|
||||
typedef boost::unordered_map<value, value, hash, equals,
|
||||
malloc_allocator<std::pair<value const, value> > > map;
|
||||
typedef boost::unordered_multimap<value, value, hash, equals,
|
||||
malloc_allocator<std::pair<value const, value> > > multimap;
|
||||
typedef boost::unordered_set<value, hash, equals,
|
||||
malloc_allocator<value> > set;
|
||||
typedef boost::unordered_multiset<value, hash, equals,
|
||||
malloc_allocator<value> > multiset;
|
||||
|
||||
// Now define the types which are stored as members, as they are needed for
|
||||
// declaring struct members.
|
||||
|
||||
struct hash {
|
||||
template <typename T>
|
||||
std::size_t operator()(T const&) const { return 0; }
|
||||
};
|
||||
|
||||
struct equals {
|
||||
template <typename T>
|
||||
bool operator()(T const&, T const&) const { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "../helpers/allocator.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
// Declare some members of a structs.
|
||||
//
|
||||
// Incomplete hash, equals and allocator aren't here supported at the
|
||||
// moment.
|
||||
|
||||
struct struct1 {
|
||||
boost::unordered_map<struct1, struct1, hash, equals,
|
||||
malloc_allocator<std::pair<struct1 const, struct1> > > x;
|
||||
};
|
||||
struct struct2 {
|
||||
boost::unordered_multimap<struct2, struct2, hash, equals,
|
||||
malloc_allocator<std::pair<struct2 const, struct2> > > x;
|
||||
};
|
||||
struct struct3 {
|
||||
boost::unordered_set<struct3, hash, equals,
|
||||
malloc_allocator<struct3> > x;
|
||||
};
|
||||
struct struct4 {
|
||||
boost::unordered_multiset<struct4, hash, equals,
|
||||
malloc_allocator<struct4> > x;
|
||||
};
|
||||
|
||||
// Now define the value type.
|
||||
|
||||
struct value {};
|
||||
|
||||
// Create some instances.
|
||||
|
||||
test::map m1;
|
||||
test::multimap m2;
|
||||
test::set s1;
|
||||
test::multiset s2;
|
||||
|
||||
test::struct1 c1;
|
||||
test::struct2 c2;
|
||||
test::struct3 c3;
|
||||
test::struct4 c4;
|
||||
|
||||
// Now declare, but don't define, the operators required for comparing
|
||||
// elements.
|
||||
|
||||
std::size_t hash_value(value const&);
|
||||
bool operator==(value const&, value const&);
|
||||
|
||||
std::size_t hash_value(struct1 const&);
|
||||
std::size_t hash_value(struct2 const&);
|
||||
std::size_t hash_value(struct3 const&);
|
||||
std::size_t hash_value(struct4 const&);
|
||||
|
||||
bool operator==(struct1 const&, struct1 const&);
|
||||
bool operator==(struct2 const&, struct2 const&);
|
||||
bool operator==(struct3 const&, struct3 const&);
|
||||
bool operator==(struct4 const&, struct4 const&);
|
||||
|
||||
// And finally use these
|
||||
|
||||
void use_types()
|
||||
{
|
||||
test::value x;
|
||||
m1[x] = x;
|
||||
m2.insert(std::make_pair(x, x));
|
||||
s1.insert(x);
|
||||
s2.insert(x);
|
||||
|
||||
c1.x.insert(std::make_pair(c1, c1));
|
||||
c2.x.insert(std::make_pair(c2, c2));
|
||||
c3.x.insert(c3);
|
||||
c4.x.insert(c4);
|
||||
}
|
||||
|
||||
// And finally define the operators required for comparing elements.
|
||||
|
||||
std::size_t hash_value(value const&) { return 0; }
|
||||
bool operator==(value const&, value const&) { return true; }
|
||||
|
||||
std::size_t hash_value(struct1 const&) { return 0; }
|
||||
std::size_t hash_value(struct2 const&) { return 0; }
|
||||
std::size_t hash_value(struct3 const&) { return 0; }
|
||||
std::size_t hash_value(struct4 const&) { return 0; }
|
||||
|
||||
bool operator==(struct1 const&, struct1 const&) { return true; }
|
||||
bool operator==(struct2 const&, struct2 const&) { return true; }
|
||||
bool operator==(struct3 const&, struct3 const&) { return true; }
|
||||
bool operator==(struct4 const&, struct4 const&) { return true; }
|
||||
}
|
||||
|
||||
int main() {
|
||||
// This could just be a compile test, but I like to be able to run these
|
||||
// things. It's probably irrational, but I find it reassuring.
|
||||
|
||||
test::use_types();
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -46,7 +48,8 @@ UNORDERED_AUTO_TEST(stable_insert_test1) {
|
||||
x.insert(insert_stable::member(1,2));
|
||||
x.insert(insert_stable::member(1,3));
|
||||
|
||||
boost::unordered_multiset<insert_stable::member>::const_iterator it = x.begin(), end = x.end();
|
||||
boost::unordered_multiset<insert_stable::member>::const_iterator
|
||||
it = x.begin(), end = x.end();
|
||||
BOOST_TEST(it != end);
|
||||
if(it != end) { BOOST_TEST(it->tag2_ == 1); ++it; }
|
||||
BOOST_TEST(it != end);
|
||||
@@ -58,9 +61,12 @@ UNORDERED_AUTO_TEST(stable_insert_test1) {
|
||||
|
||||
UNORDERED_AUTO_TEST(stable_insert_test2) {
|
||||
boost::unordered_multimap<insert_stable::member, int> x;
|
||||
typedef boost::unordered_multimap<insert_stable::member, int>::const_iterator iterator;
|
||||
typedef
|
||||
boost::unordered_multimap<insert_stable::member, int>::const_iterator
|
||||
iterator;
|
||||
|
||||
iterator it = x.insert(x.end(), std::make_pair(insert_stable::member(1,1), 1));
|
||||
iterator it
|
||||
= x.insert(x.end(), std::make_pair(insert_stable::member(1,1), 1));
|
||||
it = x.insert(it, std::make_pair(insert_stable::member(1,2), 2));
|
||||
it = x.insert(it, std::make_pair(insert_stable::member(1,3), 3));
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -21,7 +23,8 @@ namespace insert_tests {
|
||||
test::seed_t seed(243432);
|
||||
|
||||
template <class X>
|
||||
void unique_insert_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
void unique_insert_tests1(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef test::ordered<X> ordered;
|
||||
@@ -41,7 +44,8 @@ void unique_insert_tests1(X*, test::random_generator generator = test::default_g
|
||||
float b = x.max_load_factor();
|
||||
|
||||
std::pair<iterator, bool> r1 = x.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool>
|
||||
r2 = tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(r1.second == r2.second);
|
||||
BOOST_TEST(*r1.first == *r2.first);
|
||||
@@ -56,7 +60,8 @@ void unique_insert_tests1(X*, test::random_generator generator = test::default_g
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void equivalent_insert_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
void equivalent_insert_tests1(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"insert(value) tests for containers with equivalent keys.\n";
|
||||
|
||||
@@ -71,7 +76,8 @@ void equivalent_insert_tests1(X*, test::random_generator generator = test::defau
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2
|
||||
= tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
|
||||
@@ -85,7 +91,8 @@ void equivalent_insert_tests1(X*, test::random_generator generator = test::defau
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void insert_tests2(X*, test::random_generator generator = test::default_generator)
|
||||
void insert_tests2(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME test::ordered<X> tracker_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
@@ -99,10 +106,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator r1 = x.insert(x.begin(), *it);
|
||||
@@ -125,10 +133,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(100, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
const_iterator r1 = x.insert(x_const.end(), *it);
|
||||
@@ -151,10 +160,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
pos = x.insert(pos, *it);
|
||||
@@ -176,10 +186,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
x.insert(it, boost::next(it));
|
||||
@@ -211,17 +222,20 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
|
||||
X x;
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
x.insert(test::input_iterator(v.begin()), test::input_iterator(v.end()));
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
|
||||
begin = v.begin(), end = v.end();
|
||||
x.insert(test::input_iterator(begin), test::input_iterator(end));
|
||||
test::check_container(x, v);
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
|
||||
template <class X>
|
||||
void unique_emplace_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
void unique_emplace_tests1(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef test::ordered<X> ordered;
|
||||
@@ -241,7 +255,8 @@ void unique_emplace_tests1(X*, test::random_generator generator = test::default_
|
||||
float b = x.max_load_factor();
|
||||
|
||||
std::pair<iterator, bool> r1 = x.emplace(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool>
|
||||
r2 = tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(r1.second == r2.second);
|
||||
BOOST_TEST(*r1.first == *r2.first);
|
||||
@@ -256,7 +271,8 @@ void unique_emplace_tests1(X*, test::random_generator generator = test::default_
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void equivalent_emplace_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
void equivalent_emplace_tests1(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"emplace(value) tests for containers with equivalent keys.\n";
|
||||
|
||||
@@ -271,7 +287,8 @@ void equivalent_emplace_tests1(X*, test::random_generator generator = test::defa
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator
|
||||
r2 = tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
|
||||
@@ -313,14 +330,21 @@ void map_tests(X*, test::random_generator generator = test::default_generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
// Some tests for when the range's value type doesn't match the container's value type.
|
||||
// Some tests for when the range's value type doesn't match the container's
|
||||
// value type.
|
||||
|
||||
template <class X>
|
||||
void map_insert_range_test1(X*, test::random_generator generator = test::default_generator)
|
||||
void map_insert_range_test1(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"map_insert_range_test1\n";
|
||||
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type> > list;
|
||||
typedef test::list<
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type
|
||||
>
|
||||
> list;
|
||||
test::random_values<X> v(1000, generator);
|
||||
list l(v.begin(), v.end());
|
||||
|
||||
@@ -330,12 +354,17 @@ void map_insert_range_test1(X*, test::random_generator generator = test::default
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void map_insert_range_test2(X*, test::random_generator generator = test::default_generator)
|
||||
void map_insert_range_test2(X*,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
std::cerr<<"map_insert_range_test2\n";
|
||||
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, int> > list;
|
||||
test::random_values<boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, int> > v(1000, generator);
|
||||
typedef test::list<
|
||||
std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, int>
|
||||
> list;
|
||||
test::random_values<
|
||||
boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, int>
|
||||
> v(1000, generator);
|
||||
list l(v.begin(), v.end());
|
||||
|
||||
X x; x.insert(l.begin(), l.end());
|
||||
@@ -343,10 +372,18 @@ void map_insert_range_test2(X*, test::random_generator generator = test::default
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
@@ -366,7 +403,7 @@ UNORDERED_TEST(insert_tests2,
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set)(test_map))
|
||||
((default_generator)(generate_collisions))
|
||||
@@ -393,7 +430,8 @@ UNORDERED_TEST(map_insert_range_test2,
|
||||
((default_generator)(generate_collisions))
|
||||
)
|
||||
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
|
||||
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST) && \
|
||||
!defined(BOOST_NO_INITIALIZER_LISTS)
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
@@ -11,6 +13,15 @@ void foo(boost::unordered_set<int>& x1,
|
||||
boost::unordered_multiset<int>& x3,
|
||||
boost::unordered_multimap<int, int>& x4)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy {
|
||||
boost::unordered_set<int> x1;
|
||||
boost::unordered_map<int, int> x2;
|
||||
boost::unordered_multiset<int> x3;
|
||||
boost::unordered_multimap<int, int> x4;
|
||||
};
|
||||
#endif
|
||||
|
||||
x1.insert(1);
|
||||
x2[2] = 2;
|
||||
x3.insert(3);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -34,7 +36,8 @@ void set_load_factor_tests(X* = 0)
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void insert_test(X*, float mlf, test::random_generator generator = test::default_generator)
|
||||
void insert_test(X*, float mlf,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
X x;
|
||||
x.max_load_factor(mlf);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -44,7 +46,8 @@ namespace move_tests
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_construct_tests1(T* ptr, test::random_generator const& generator = test::default_generator)
|
||||
void move_construct_tests1(T* ptr,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
@@ -64,21 +67,26 @@ namespace move_tests
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_assign_tests1(T*, test::random_generator const& generator = test::default_generator)
|
||||
void move_assign_tests1(T*,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
test::object_count count;
|
||||
T y;
|
||||
y = create(v, count);
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
@@ -98,7 +106,9 @@ namespace move_tests
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 0.5));
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
@@ -108,7 +118,8 @@ namespace move_tests
|
||||
}
|
||||
|
||||
{
|
||||
// TODO: To do this correctly requires the fancy new allocator stuff.
|
||||
// TODO: To do this correctly requires the fancy new allocator
|
||||
// stuff.
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 2.0), al2);
|
||||
BOOST_TEST(count != test::global_object_count);
|
||||
@@ -123,10 +134,11 @@ namespace move_tests
|
||||
{
|
||||
test::random_values<T> v(25, generator);
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#else
|
||||
BOOST_TEST(test::global_object_count.constructions - count.constructions <=
|
||||
BOOST_TEST(
|
||||
test::global_object_count.constructions - count.constructions <=
|
||||
(test::is_map<T>::value ? 50 : 25));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#endif
|
||||
@@ -139,10 +151,18 @@ namespace move_tests
|
||||
}
|
||||
*/ }
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -17,7 +19,8 @@ test::seed_t seed(2974);
|
||||
template <class X>
|
||||
bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
|
||||
{
|
||||
return x.bucket_count() > x.size() / x.max_load_factor() && x.bucket_count() >= n;
|
||||
return x.bucket_count() > x.size() / x.max_load_factor() &&
|
||||
x.bucket_count() >= n;
|
||||
}
|
||||
|
||||
template <class X>
|
||||
@@ -33,7 +36,8 @@ void rehash_empty_test1(X* = 0)
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_empty_test2(X* = 0, test::random_generator generator = test::default_generator)
|
||||
void rehash_empty_test2(X* = 0,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
@@ -51,7 +55,8 @@ void rehash_empty_test2(X* = 0, test::random_generator generator = test::default
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_empty_test3(X* = 0, test::random_generator generator = test::default_generator)
|
||||
void rehash_empty_test3(X* = 0,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
@@ -70,7 +75,8 @@ void rehash_empty_test3(X* = 0, test::random_generator generator = test::default
|
||||
|
||||
|
||||
template <class X>
|
||||
void rehash_test1(X* = 0, test::random_generator generator = test::default_generator)
|
||||
void rehash_test1(X* = 0,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
// This test checks the runtime requirements of containers.
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -70,7 +72,8 @@ void simple_test(X const& a)
|
||||
|
||||
{
|
||||
BOOST_TEST(a.size() ==
|
||||
(BOOST_DEDUCED_TYPENAME X::size_type) std::distance(a.begin(), a.end()));
|
||||
static_cast<BOOST_DEDUCED_TYPENAME X::size_type>(
|
||||
std::distance(a.begin(), a.end())));
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
@@ -60,7 +62,8 @@ void swap_tests1(X*, test::random_generator generator = test::default_generator)
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void swap_tests2(X* ptr = 0, test::random_generator generator = test::default_generator)
|
||||
void swap_tests2(X* ptr = 0,
|
||||
test::random_generator generator = test::default_generator)
|
||||
{
|
||||
swap_tests1(ptr);
|
||||
|
||||
@@ -96,7 +99,8 @@ void swap_tests2(X* ptr = 0, test::random_generator generator = test::default_ge
|
||||
X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2));
|
||||
try {
|
||||
swap_test_impl(x, y);
|
||||
BOOST_ERROR("Using swap method 1, swapping with unequal allocators didn't throw.");
|
||||
BOOST_ERROR("Using swap method 1, "
|
||||
"swapping with unequal allocators didn't throw.");
|
||||
} catch (std::runtime_error) {}
|
||||
}
|
||||
#else
|
||||
@@ -109,18 +113,28 @@ void swap_tests2(X* ptr = 0, test::random_generator generator = test::default_ge
|
||||
|
||||
{
|
||||
test::random_values<X> vx(100, generator), vy(100, generator);
|
||||
X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1), allocator_type(1));
|
||||
X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2), allocator_type(2));
|
||||
X x(vx.begin(), vx.end(), 0, hasher(1), key_equal(1),
|
||||
allocator_type(1));
|
||||
X y(vy.begin(), vy.end(), 0, hasher(2), key_equal(2),
|
||||
allocator_type(2));
|
||||
swap_test_impl(x, y);
|
||||
swap_test_impl(x, y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator<test::object> >* test_multimap;
|
||||
|
||||
UNORDERED_TEST(swap_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
@@ -29,7 +31,7 @@ namespace unnecessary_copy_tests
|
||||
: tag_(x.tag_) { ++copies; }
|
||||
|
||||
count_copies(count_copies const& x) : tag_(x.tag_) { ++copies; }
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
count_copies(count_copies&& x) : tag_(x.tag_) {
|
||||
x.tag_ = -1; ++moves;
|
||||
}
|
||||
@@ -65,25 +67,33 @@ namespace unnecessary_copy_tests
|
||||
}
|
||||
}
|
||||
|
||||
#define COPY_COUNT(n) \
|
||||
if(count_copies::copies != n) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: "<<n<<std::endl; \
|
||||
#define COPY_COUNT(n) \
|
||||
if(count_copies::copies != n) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr \
|
||||
<< "Number of copies: " << count_copies::copies \
|
||||
<< " expecting: " << n << std::endl; \
|
||||
}
|
||||
#define MOVE_COUNT(n) \
|
||||
if(count_copies::moves != n) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr<<"Number of moves: "<<count_copies::moves<<" expecting: "<<n<<std::endl; \
|
||||
#define MOVE_COUNT(n) \
|
||||
if(count_copies::moves != n) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr \
|
||||
<< "Number of moves: " << count_copies::moves \
|
||||
<< " expecting: " <<n << std::endl; \
|
||||
}
|
||||
#define COPY_COUNT_RANGE(a, b) \
|
||||
if(count_copies::copies < a || count_copies::copies > b) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr<<"Number of copies: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
|
||||
#define COPY_COUNT_RANGE(a, b) \
|
||||
if(count_copies::copies < a || count_copies::copies > b) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr \
|
||||
<< "Number of copies: " << count_copies::copies \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
}
|
||||
#define MOVE_COUNT_RANGE(a, b) \
|
||||
if(count_copies::moves < a || count_copies::moves > b) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr<<"Number of moves: "<<count_copies::copies<<" expecting: ["<<a<<", "<<b<<"]"<<std::endl; \
|
||||
#define MOVE_COUNT_RANGE(a, b) \
|
||||
if(count_copies::moves < a || count_copies::moves > b) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr \
|
||||
<< "Number of moves: " << count_copies::copies \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
}
|
||||
|
||||
namespace unnecessary_copy_tests
|
||||
@@ -126,7 +136,7 @@ namespace unnecessary_copy_tests
|
||||
reset();
|
||||
T x;
|
||||
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
COPY_COUNT(1);
|
||||
#else
|
||||
COPY_COUNT(2);
|
||||
@@ -138,7 +148,7 @@ namespace unnecessary_copy_tests
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_move_test(T*)
|
||||
{
|
||||
@@ -189,7 +199,7 @@ namespace unnecessary_copy_tests
|
||||
x.emplace(source<count_copies>());
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
// No move should take place.
|
||||
reset();
|
||||
x.emplace(std::move(a));
|
||||
@@ -261,7 +271,7 @@ namespace unnecessary_copy_tests
|
||||
//x.emplace(a_ref);
|
||||
//COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
|
||||
Reference in New Issue
Block a user