Compare commits

..
Author SHA1 Message Date
Beman Dawes ca39084331 Release 1.40.0
[SVN r55802]
2009-08-27 16:24:59 +00:00
Daniel James df1dad5cb6 Merge an unordered documentation change that I missed before.
Merged revisions 54914 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r54914 | danieljames | 2009-07-12 19:03:35 +0100 (Sun, 12 Jul 2009) | 1 line
  
  Add constructors to the methods for controlling bucket size in unordered containers.
........


[SVN r55211]
2009-07-27 20:46:40 +00:00
Daniel James 1bc3ae3d9d Merge unordered changes, including fixes for Boost.TR1.
Merged revisions 55099-55100,55132,55138,55184-55185 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r55099 | danieljames | 2009-07-22 23:37:52 +0100 (Wed, 22 Jul 2009) | 1 line
  
  Fix the insert tests when there is a small number of buckets.
........
  r55100 | danieljames | 2009-07-22 23:38:08 +0100 (Wed, 22 Jul 2009) | 1 line
  
  Adjust the unordered defaults so that emplace takes more parameters and less buckets are created by default.
........
  r55132 | danieljames | 2009-07-23 18:53:59 +0100 (Thu, 23 Jul 2009) | 1 line
  
  Remove the emulation of single argument C++0x std::pair constructor.
........
  r55138 | danieljames | 2009-07-23 23:17:20 +0100 (Thu, 23 Jul 2009) | 1 line
  
  Try to work around an odd Visual C++ 8 bug.
........
  r55184 | danieljames | 2009-07-26 19:59:33 +0100 (Sun, 26 Jul 2009) | 1 line
  
  Some extra changelog notes.
........
  r55185 | danieljames | 2009-07-26 20:00:40 +0100 (Sun, 26 Jul 2009) | 1 line
  
  Update the reference documentation to mention that emplace is now emulated.
........


[SVN r55189]
2009-07-26 20:22:48 +00:00
Troy D. Straszheim 60ecf12779 Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
Daniel James 241316e0d9 Misc. unordered changes. Fixes #3082, #3119.
Merged revisions 53505-53506,53525,53550,53552,53614 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53505 | danieljames | 2009-05-31 16:50:56 +0100 (Sun, 31 May 2009) | 1 line
  
  Disable incorrect Visual C++ 64-bit warnings. Ref #3082.
........
  r53506 | danieljames | 2009-05-31 16:53:09 +0100 (Sun, 31 May 2009) | 1 line
  
  Remove misplaced visual C++ warning pragma.
........
  r53525 | danieljames | 2009-06-01 07:50:37 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Fix tests for when the library has support for initializer lists but the compiler doesn't.
........
  r53550 | danieljames | 2009-06-01 20:17:49 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Get the type of the initializer_list right.
........
  r53552 | danieljames | 2009-06-01 20:22:27 +0100 (Mon, 01 Jun 2009) | 1 line
  
  Fix the unordered_map declaration in the tutorial. Fixes #3119.
........
  r53614 | danieljames | 2009-06-03 23:48:49 +0100 (Wed, 03 Jun 2009) | 1 line
  
  The move tests pass on 64 bit visual c++.
........


[SVN r53687]
2009-06-06 14:05:54 +00:00
Daniel James 9c43533655 A couple more minor unordered changes.
Merged revisions 53312,53367 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53312 | danieljames | 2009-05-27 18:43:22 +0100 (Wed, 27 May 2009) | 1 line
  
  Remove obsolete comment.
........
  r53367 | danieljames | 2009-05-28 23:06:42 +0100 (Thu, 28 May 2009) | 1 line
  
  Remove a couple of old uses of BOOST_NO_INITIALIZER_LISTS.
........


[SVN r53466]
2009-05-30 17:41:05 +00:00
Daniel James ae09b0dd24 Merge latest changes for unordered. Improved compatability and a few tweaks.
Merged revisions 53127,53253,53256,53311,53314,53316-53318 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r53127 | danieljames | 2009-05-20 07:43:38 +0100 (Wed, 20 May 2009) | 1 line
  
  Better configuration for boost.unordered.
........
  r53253 | danieljames | 2009-05-25 20:14:07 +0100 (Mon, 25 May 2009) | 3 lines
  
  Add explicit destructors to the unordered containers. Refs #2908.
  
  Isn't really needed but it doesn't hurt.
........
  r53256 | danieljames | 2009-05-25 20:45:23 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log for explicit destructors.
........
  r53311 | danieljames | 2009-05-27 18:42:01 +0100 (Wed, 27 May 2009) | 1 line
  
  Missing changelog entry.
........
  r53314 | danieljames | 2009-05-27 18:44:09 +0100 (Wed, 27 May 2009) | 1 line
  
  Use lightweight_test for unordered.
........
  r53316 | danieljames | 2009-05-27 19:19:32 +0100 (Wed, 27 May 2009) | 1 line
  
  Some workarounds for old versions of Borland.
........
  r53317 | danieljames | 2009-05-27 19:32:22 +0100 (Wed, 27 May 2009) | 1 line
  
  Fix a change accidentally included in the last commit.
........
  r53318 | danieljames | 2009-05-27 19:32:38 +0100 (Wed, 27 May 2009) | 1 line
  
  Remove an unused function.
........


[SVN r53465]
2009-05-30 17:34:12 +00:00
Daniel James b018f8b173 Second try at merging emplace support.
Note that the previously rolled back commit was [53257], not [52357].

Merged revisions 52393-52394,52397,52884-52885,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52393 | danieljames | 2009-04-14 18:23:37 +0100 (Tue, 14 Apr 2009) | 2 lines
  
  Implement full extract_key for compilers without SFINAE and variadic
  templates.
........
  r52394 | danieljames | 2009-04-14 18:23:51 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Use emplace instead of insert in the backend as it's more appropriate.
........
  r52397 | danieljames | 2009-04-14 18:51:34 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Add stream output to the count test helper for unordered.
........
  r52884 | danieljames | 2009-05-10 22:24:41 +0100 (Sun, 10 May 2009) | 19 lines
  
  Cherrypick some unordered container changes from sandbox. Not including
  anything which depends on the new move library.
  
  ------------------------------------------------------------------------
  r52746 | danieljames | 2009-05-03 11:12:30 +0100 (Sun, 03 May 2009) | 1 line
  
  Merge latest unordered container changes.
  ------------------------------------------------------------------------
  r52747 | danieljames | 2009-05-03 11:15:35 +0100 (Sun, 03 May 2009) | 4 lines
  
  Put the C++0x emplace implementations before the non-C++0x versions.
  
  I'm going to change the non-C++0x to be macro heavy emulations of the
  C++0x versions, so this will put the readable version first.
  ------------------------------------------------------------------------
  r52748 | danieljames | 2009-05-03 11:15:44 +0100 (Sun, 03 May 2009) | 1 line
  
  Refactor the unordered implementation a tad, to make implementing emplace less painful.
  ------------------------------------------------------------------------
........
  r52885 | danieljames | 2009-05-10 22:25:09 +0100 (Sun, 10 May 2009) | 1 line
  
  Merge emplace support for sandbox - but without move support.
........
  r53255 | danieljames | 2009-05-25 20:45:06 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log.
........


[SVN r53328]
2009-05-27 21:31:08 +00:00
Daniel James 0b4241833d Rollback [52357] as it depends on macros that aren't in release.
Rolled back revisions 52393-52394,52397,52884-52885,53127,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk


[SVN r53277]
2009-05-26 09:56:59 +00:00
Daniel James e911a8011b Merge unordered changes:
* Support emplace for all compilers.
 * Better configuration of C++0x features for when the appropriate headers
   aren't available.

Merged revisions 52393-52394,52397,52884-52885,53127,53255 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52393 | danieljames | 2009-04-14 18:23:37 +0100 (Tue, 14 Apr 2009) | 2 lines
  
  Implement full extract_key for compilers without SFINAE and variadic
  templates.
........
  r52394 | danieljames | 2009-04-14 18:23:51 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Use emplace instead of insert in the backend as it's more appropriate.
........
  r52397 | danieljames | 2009-04-14 18:51:34 +0100 (Tue, 14 Apr 2009) | 1 line
  
  Add stream output to the count test helper for unordered.
........
  r52884 | danieljames | 2009-05-10 22:24:41 +0100 (Sun, 10 May 2009) | 19 lines
  
  Cherrypick some unordered container changes from sandbox. Not including
  anything which depends on the new move library.
  
  ------------------------------------------------------------------------
  r52746 | danieljames | 2009-05-03 11:12:30 +0100 (Sun, 03 May 2009) | 1 line
  
  Merge latest unordered container changes.
  ------------------------------------------------------------------------
  r52747 | danieljames | 2009-05-03 11:15:35 +0100 (Sun, 03 May 2009) | 4 lines
  
  Put the C++0x emplace implementations before the non-C++0x versions.
  
  I'm going to change the non-C++0x to be macro heavy emulations of the
  C++0x versions, so this will put the readable version first.
  ------------------------------------------------------------------------
  r52748 | danieljames | 2009-05-03 11:15:44 +0100 (Sun, 03 May 2009) | 1 line
  
  Refactor the unordered implementation a tad, to make implementing emplace less painful.
  ------------------------------------------------------------------------
........
  r52885 | danieljames | 2009-05-10 22:25:09 +0100 (Sun, 10 May 2009) | 1 line
  
  Merge emplace support for sandbox - but without move support.
........
  r53127 | danieljames | 2009-05-20 07:43:38 +0100 (Wed, 20 May 2009) | 1 line
  
  Better configuration for boost.unordered.
........
  r53255 | danieljames | 2009-05-25 20:45:06 +0100 (Mon, 25 May 2009) | 1 line
  
  Unordered change log.
........


[SVN r53257]
2009-05-25 19:57:04 +00:00
Daniel James f02cc7775d Long term fix for the incorrect length of prime list.
Merged revisions 52658,52669,52673,52711 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r52658 | danieljames | 2009-04-29 11:05:17 +0100 (Wed, 29 Apr 2009) | 1 line
  
  Fix the length of the prime number list.
........
  r52669 | danieljames | 2009-04-29 22:43:41 +0100 (Wed, 29 Apr 2009) | 3 lines
  
  Don't test prime_list::length on Visual C++.
  
  Checking the array size doesn't seem to work on it.
........
  r52673 | danieljames | 2009-04-30 06:08:40 +0100 (Thu, 30 Apr 2009) | 1 line
  
  Revert changes to unordered, as the test fails on most compilers.
........
  r52711 | danieljames | 2009-05-01 21:50:32 +0100 (Fri, 01 May 2009) | 5 lines
  
  Use a preprocessor sequence for the primes.
  
  This feels like overkill but it seems to be the most reliable way to ensure
  that the length is correct. I obviously can't be trusted to get it right, and
  the template hack seems to prevent Boost.Range from working.
........


[SVN r53043]
2009-05-16 13:38:37 +00:00
Troy D. Straszheim 4e6b5de196 tuning up cmakefiles for unordered, utility
[SVN r53008]
2009-05-15 00:21:14 +00:00
45 changed files with 1229 additions and 681 deletions
+7 -1
View File
@@ -1,3 +1,9 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#----------------------------------------------------------------------------
# This file was automatically generated from the original CMakeLists.txt file
# Add a variable to hold the headers for the library
@@ -11,7 +17,7 @@ set (lib_headers
boost_library_project(
unordered
# SRCDIRS
# TESTDIRS
TESTDIRS test
HEADERS ${lib_headers}
# DOCDIRS
# DESCRIPTION
+9
View File
@@ -115,6 +115,15 @@ or close to the hint - unless your hint is unreasonably small or large.
[table Methods for Controlling Bucket Size
[[Method] [Description]]
[
[`X(size_type n)`]
[Construct an empty container with at least `n` buckets (`X` is the container type).]
]
[
[`X(InputIterator i, InputIterator j, size_type n)`]
[Construct an empty container with at least `n` buckets and insert elements
from the range \[`i`, `j`) (`X` is the container type).]
]
[
[`float load_factor() const`]
[The average number of elements per bucket.]
+18
View File
@@ -69,5 +69,23 @@ First official release.
* Some other minor internal changes to the implementation, tests and
documentation.
* Avoid an unnecessary copy in `operator[]`.
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]: Fix length of
prime number list.
[h2 Boost 1.40.0]
* [@https://svn.boost.org/trac/boost/ticket/2975 Ticket 2975]:
Store the prime list as a preprocessor sequence - so that it will always get
the length right if it changes again in the future.
* [@https://svn.boost.org/trac/boost/ticket/1978 Ticket 1978]:
Implement `emplace` for all compilers.
* [@https://svn.boost.org/trac/boost/ticket/2908 Ticket 2908],
[@https://svn.boost.org/trac/boost/ticket/3096 Ticket 3096]:
Some workarounds for old versions of borland, including adding explicit
destructors to all containers.
* [@https://svn.boost.org/trac/boost/ticket/3082 Ticket 3082]:
Disable incorrect Visual C++ warnings.
* Better configuration for C++0x features when the headers aren't available.
* Create less buckets by default.
[endsect]
+1 -1
View File
@@ -13,7 +13,7 @@ is declared as:
class Key, class Mapped,
class Hash = ``[classref boost::hash]``<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<Key> >
class Alloc = std::allocator<std::pair<Key const, Mapped> > >
class ``[classref boost::unordered_map unordered_map]``;
The hash function comes first as you might want to change the hash function
+24 -8
View File
@@ -284,7 +284,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<notes>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace_hint">
@@ -313,7 +315,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@@ -1017,7 +1021,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<notes>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace_hint">
@@ -1046,7 +1052,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@@ -1762,7 +1770,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<notes>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace_hint">
@@ -1791,7 +1801,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@@ -2544,7 +2556,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<notes>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="emplace_hint">
@@ -2573,7 +2587,9 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
<para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
<para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
<para>Pointers and references to elements are never invalidated.</para>
<para>Only available on compilers with support for variadic template arguments and rvalue references.</para>
<para>If the compiler doesn't support variadic template arguments or rvalue
references, this is emulated for up to 10 arguments, with no support
for rvalue references or move semantics.</para>
</notes>
</method>
<method name="insert">
@@ -19,4 +19,12 @@
# define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
#endif
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
# if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
// STLport doesn't have std::forward.
# else
# define BOOST_UNORDERED_STD_FORWARD
# endif
#endif
#endif
+54 -16
View File
@@ -12,6 +12,11 @@
#endif
#include <boost/config.hpp>
#include <boost/unordered/detail/config.hpp>
#if !defined(BOOST_UNORDERED_EMPLACE_LIMIT)
#define BOOST_UNORDERED_EMPLACE_LIMIT 10
#endif
#include <cstddef>
#include <boost/config/no_tr1/cmath.hpp>
@@ -28,18 +33,40 @@
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/swap.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/mpl/aux_/config/eti.hpp>
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/not.hpp>
#if !(defined(BOOST_UNORDERED_STD_FORWARD))
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
BOOST_PP_ENUM_PARAMS_Z(z, n, typename Arg)
#define BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, Arg, const& arg)
#define BOOST_UNORDERED_CALL_PARAMS(z, n) \
BOOST_PP_ENUM_PARAMS_Z(z, n, arg)
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data.
#endif
#endif
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
@@ -58,7 +85,7 @@ namespace boost {
namespace unordered_detail {
template <class T> struct type_wrapper {};
static const std::size_t default_initial_bucket_count = 50;
static const std::size_t default_initial_bucket_count = 11;
static const float minimum_max_load_factor = 1e-3f;
inline std::size_t double_to_size_t(double f)
@@ -76,18 +103,25 @@ namespace boost {
static std::ptrdiff_t const length;
};
template<typename T>
std::size_t const prime_list_template<T>::value[] = {
5ul, 11ul, 17ul, 29ul, 37ul, 53ul, 67ul, 79ul,
97ul, 131ul, 193ul, 257ul, 389ul, 521ul, 769ul,
1031ul, 1543ul, 2053ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul };
#define BOOST_UNORDERED_PRIMES \
(5ul)(11ul)(17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
(97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
(1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \
(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
(1610612741ul)(3221225473ul)(4294967291ul)
template<typename T>
std::ptrdiff_t const prime_list_template<T>::length = 40;
std::size_t const prime_list_template<T>::value[] = {
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)
};
template<typename T>
std::ptrdiff_t const prime_list_template<T>::length
= BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
#undef BOOST_UNORDERED_PRIMES
typedef prime_list_template<std::size_t> prime_list;
@@ -306,4 +340,8 @@ namespace boost {
#undef BOOST_UNORDERED_BORLAND_BOOL
#undef BOOST_UNORDERED_MSVC_RESET_PTR
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
#endif // BOOST_UNORDERED_DETAIL_HASH_TABLE_HPP_INCLUDED
+362 -183
View File
@@ -89,7 +89,7 @@ namespace boost {
struct value_base {
typename boost::aligned_storage<
sizeof(value_type),
boost::alignment_of<value_type>::value>::type data_;
::boost::alignment_of<value_type>::value>::type data_;
void* address() { return this; }
};
@@ -181,53 +181,100 @@ namespace boost {
}
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
void construct_preamble()
{
if(!node_) {
node_constructed_ = false;
value_constructed_ = false;
node_ = allocators_.node_alloc_.allocate(1);
allocators_.node_alloc_.construct(node_, node());
node_constructed_ = true;
}
else {
BOOST_ASSERT(node_constructed_ && value_constructed_);
BOOST_UNORDERED_DESTRUCT(&node_->value(), value_type);
value_constructed_ = false;
}
}
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <typename... Args>
void construct(Args&&... args)
{
BOOST_ASSERT(!node_);
node_constructed_ = false;
value_constructed_ = false;
node_ = allocators_.node_alloc_.allocate(1);
allocators_.node_alloc_.construct(node_, node());
node_constructed_ = true;
construct_preamble();
new(node_->address()) value_type(std::forward<Args>(args)...);
value_constructed_ = true;
}
#else
template <typename V>
void construct(V const& v)
{
BOOST_ASSERT(!node_);
node_constructed_ = false;
value_constructed_ = false;
node_ = allocators_.node_alloc_.allocate(1);
allocators_.node_alloc_.construct(node_, node());
node_constructed_ = true;
new(node_->address()) value_type(v);
value_constructed_ = true;
#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
void construct( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
construct_preamble(); \
construct_impl( \
(value_type*) 0, \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
value_constructed_ = true; \
} \
\
template < \
typename T, \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
void construct_impl( \
T*, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
new(node_->address()) value_type( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
}
#define BOOST_UNORDERED_CONSTRUCT_IMPL2(z, n, _) \
template <typename First, typename Second, typename Key, \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
void construct_impl( \
std::pair<First, Second>*, \
Key const& k, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
new(node_->address()) value_type(k, \
Second( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
) \
); \
}
#endif
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_CONSTRUCT_IMPL, _)
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_CONSTRUCT_IMPL2, _)
template <typename First, typename Second, typename T1, typename T2>
void construct_impl(std::pair<First, Second>*,
std::pair<T1, T2> const& arg0)
{
new(node_->address()) value_type(arg0);
}
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
#endif
template <typename K, typename M>
void construct_pair(K const& k, M*)
{
BOOST_ASSERT(!node_);
node_constructed_ = false;
value_constructed_ = false;
node_ = allocators_.node_alloc_.allocate(1);
allocators_.node_alloc_.construct(node_, node());
node_constructed_ = true;
new(node_->address()) value_type(k, M());
construct_preamble();
new(node_->address()) value_type(k, M());
value_constructed_ = true;
}
@@ -1427,8 +1474,29 @@ namespace boost {
}
// key extractors
//
// no throw
//
// 'extract_key' is called with the emplace parameters to return a
// key if available or 'no_key' is one isn't and will need to be
// constructed.
struct no_key {
no_key() {}
template <class T> no_key(T const&) {}
};
// If emplace is called with no arguments then there obviously
// isn't an available key.
static no_key extract_key()
{
return no_key();
}
// Emplace or insert was called with the value type.
static key_type const& extract_key(value_type const& v)
{
return extract(v, (type_wrapper<value_type>*)0);
@@ -1445,40 +1513,67 @@ namespace boost {
{
return v.first;
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
struct no_key {};
template <typename Arg1, typename... Args>
static typename boost::enable_if<
boost::mpl::and_<
boost::mpl::not_<boost::is_same<key_type, value_type> >,
boost::is_same<Arg1, key_type>
>,
key_type>::type const& extract_key(Arg1 const& k, Args const&...)
// For maps, if emplace is called with just a key, then it's the value type
// with the second value default initialised.
template <typename Arg>
static BOOST_DEDUCED_TYPENAME
boost::mpl::if_<boost::is_same<Arg, key_type>, key_type const&, no_key>::type
extract_key(Arg const& k)
{
return k;
}
// For a map, the argument might be a pair with the key as the first
// part and a convertible value as the second part.
template <typename First, typename Second>
static typename boost::enable_if<
boost::mpl::and_<
boost::mpl::not_<boost::is_same<key_type, value_type> >,
boost::is_same<key_type,
typename boost::remove_const<
typename boost::remove_reference<First>::type
>::type>
>,
key_type>::type const& extract_key(std::pair<First, Second> const& v)
static BOOST_DEDUCED_TYPENAME
boost::mpl::if_<
boost::mpl::and_<
boost::mpl::not_<boost::is_same<key_type, value_type> >,
boost::is_same<key_type,
typename boost::remove_const<
typename boost::remove_reference<First>::type
>::type>
>,
key_type const&, no_key
>::type extract_key(std::pair<First, Second> const& v)
{
return v.first;
}
template <typename... Args>
static no_key extract_key(Args const&...)
// For maps if there is more than one argument, the key can be the first argument.
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <typename Arg, typename Arg1, typename... Args>
static BOOST_DEDUCED_TYPENAME
boost::mpl::if_<
boost::mpl::and_<
boost::mpl::not_<boost::is_same<value_type, key_type> >,
boost::is_same<Arg, key_type>
>,
key_type const&, no_key
>::type extract_key(Arg const& k, Arg1 const&, Args const&...)
{
return no_key();
return k;
}
#else
template <typename Arg, typename Arg1>
static BOOST_DEDUCED_TYPENAME
boost::mpl::if_<
boost::mpl::and_<
boost::mpl::not_<boost::is_same<value_type, key_type> >,
boost::is_same<Arg, key_type>
>,
key_type const&, no_key
>::type extract_key(Arg const& k, Arg1 const&)
{
return k;
}
#endif
public:
@@ -1582,72 +1677,78 @@ namespace boost {
#if BOOST_UNORDERED_EQUIVALENT_KEYS
#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL))
// Insert (equivalent key containers)
#if defined(BOOST_UNORDERED_STD_FORWARD)
// Emplace (equivalent key containers)
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
iterator_base insert(value_type const& v)
template <class... Args>
iterator_base emplace(Args&&... args)
{
// Create the node before rehashing in case it throws an
// exception (need strong safety in such a case).
node_constructor a(data_.allocators_);
a.construct(v);
a.construct(std::forward<Args>(args)...);
return insert_impl(a);
return emplace_impl(a);
}
// Insert (equivalent key containers)
// Emplace (equivalent key containers)
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
iterator_base insert_hint(iterator_base const& it, value_type const& v)
template <class... Args>
iterator_base emplace_hint(iterator_base const& it, Args&&... args)
{
// Create the node before rehashing in case it throws an
// exception (need strong safety in such a case).
node_constructor a(data_.allocators_);
a.construct(v);
a.construct(std::forward<Args>(args)...);
return insert_hint_impl(it, a);
return emplace_hint_impl(it, a);
}
#else
// Insert (equivalent key containers)
// (I'm using an overloaded insert for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
template <class... Args>
iterator_base insert(Args&&... args)
{
// Create the node before rehashing in case it throws an
// exception (need strong safety in such a case).
node_constructor a(data_.allocators_);
a.construct(std::forward<Args>(args)...);
return insert_impl(a);
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator_base emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
node_constructor a(data_.allocators_); \
a.construct( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
return emplace_impl(a); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator_base emplace_hint(iterator_base const& it, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
node_constructor a(data_.allocators_); \
a.construct( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
return emplace_hint_impl(it, a); \
}
// Insert (equivalent key containers)
// (I'm using an overloaded insert for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
template <class... Args>
iterator_base insert_hint(iterator_base const& it, Args&&... args)
{
// Create the node before rehashing in case it throws an
// exception (need strong safety in such a case).
node_constructor a(data_.allocators_);
a.construct(std::forward<Args>(args)...);
return insert_hint_impl(it, a);
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_INSERT_IMPL, _)
#undef BOOST_UNORDERED_INSERT_IMPL
#endif
iterator_base insert_impl(node_constructor& a)
iterator_base emplace_impl(node_constructor& a)
{
key_type const& k = extract_key(a.get()->value());
size_type hash_value = hash_function()(k);
@@ -1668,17 +1769,17 @@ namespace boost {
);
}
iterator_base insert_hint_impl(iterator_base const& it, node_constructor& a)
iterator_base emplace_hint_impl(iterator_base const& it, node_constructor& a)
{
// equal can throw, but with no effects
if (it == data_.end() || !equal(extract_key(a.get()->value()), *it)) {
// Use the standard insert if the iterator doesn't point
// Use the standard emplace if the iterator doesn't point
// to a matching key.
return insert_impl(a);
return emplace_impl(a);
}
else {
// Find the first node in the group - so that the node
// will be inserted at the end of the group.
// will be added at the end of the group.
link_ptr start(it.node_);
while(data_.prev_in_group(start)->next_ == start)
@@ -1707,7 +1808,7 @@ namespace boost {
{
size_type distance = unordered_detail::distance(i, j);
if(distance == 1) {
insert(*i);
emplace(*i);
}
else {
// Only require basic exception safety here
@@ -1737,7 +1838,7 @@ namespace boost {
{
// If only inserting 1 element, get the required
// safety since insert is only called once.
for (; i != j; ++i) insert(*i);
for (; i != j; ++i) emplace(*i);
}
public:
@@ -1786,81 +1887,37 @@ namespace boost {
}
}
#if !(defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL))
#if defined(BOOST_UNORDERED_STD_FORWARD)
// Insert (unique keys)
// if hash function throws, basic exception safety
// strong otherwise
std::pair<iterator_base, bool> insert(value_type const& v)
{
// No side effects in this initial code
key_type const& k = extract_key(v);
size_type hash_value = hash_function()(k);
bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
link_ptr pos = find_iterator(bucket, k);
if (BOOST_UNORDERED_BORLAND_BOOL(pos)) {
// Found an existing key, return it (no throw).
return std::pair<iterator_base, bool>(
iterator_base(bucket, pos), false);
} else {
// Doesn't already exist, add to bucket.
// Side effects only in this block.
// Create the node before rehashing in case it throws an
// exception (need strong safety in such a case).
node_constructor a(data_.allocators_);
a.construct(v);
// reserve has basic exception safety if the hash function
// throws, strong otherwise.
if(reserve_for_insert(size() + 1))
bucket = data_.bucket_ptr_from_hash(hash_value);
// Nothing after this point can throw.
link_ptr n = data_.link_node_in_bucket(a, bucket);
return std::pair<iterator_base, bool>(
iterator_base(bucket, n), true);
}
}
// Insert (unique keys)
// if hash function throws, basic exception safety
// strong otherwise
iterator_base insert_hint(iterator_base const& it, value_type const& v)
{
if(it != data_.end() && equal(extract_key(v), *it))
return it;
else
return insert(v).first;
}
#else
// Insert (unique keys)
// (I'm using an overloaded insert for both 'insert' and 'emplace')
//
// TODO:
// For sets: create a local key without creating the node?
// For maps: use the first argument as the key.
// Emplace (unique keys)
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
template<typename... Args>
std::pair<iterator_base, bool> insert(Args&&... args)
std::pair<iterator_base, bool> emplace(Args&&... args)
{
return insert_impl(
return emplace_impl(
extract_key(std::forward<Args>(args)...),
std::forward<Args>(args)...);
}
// Insert (unique keys)
// (I'm using an overloaded emplace for both 'insert' and 'emplace')
// I'm just ignoring hints here for now.
// if hash function throws, basic exception safety
// strong otherwise
template<typename... Args>
std::pair<iterator_base, bool> insert_impl(key_type const& k, Args&&... args)
iterator_base emplace_hint(iterator_base const&, Args&&... args)
{
return emplace_impl(
extract_key(std::forward<Args>(args)...),
std::forward<Args>(args)...).first;
}
template<typename... Args>
std::pair<iterator_base, bool> emplace_impl(key_type const& k, Args&&... args)
{
// No side effects in this initial code
size_type hash_value = hash_function()(k);
@@ -1894,13 +1951,110 @@ namespace boost {
}
template<typename... Args>
std::pair<iterator_base, bool> insert_impl(no_key, Args&&... args)
std::pair<iterator_base, bool> 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
node_constructor a(data_.allocators_);
a.construct(std::forward<Args>(args)...);
return emplace_impl_with_node(a);
}
#else
template <typename Arg0>
std::pair<iterator_base, bool> emplace(Arg0 const& arg0)
{
return emplace_impl(extract_key(arg0), arg0);
}
template <typename Arg0>
iterator_base emplace_hint(iterator_base const& it, Arg0 const& arg0)
{
return emplace_impl(extract_key(arg0), arg0).first;
}
#define BOOST_UNORDERED_INSERT_IMPL(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator_base, bool> emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return emplace_impl( \
extract_key(arg0, arg1), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator_base emplace_hint(iterator_base const& it, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return emplace_impl( \
extract_key(arg0, arg1), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
).first; \
} \
BOOST_UNORDERED_INSERT_IMPL2(z, n, _)
#define BOOST_UNORDERED_INSERT_IMPL2(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator_base, bool> emplace_impl(key_type const& k, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
size_type hash_value = hash_function()(k); \
bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value); \
link_ptr pos = find_iterator(bucket, k); \
\
if (BOOST_UNORDERED_BORLAND_BOOL(pos)) { \
return std::pair<iterator_base, bool>( \
iterator_base(bucket, pos), false); \
} else { \
node_constructor a(data_.allocators_); \
a.construct( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
\
if(reserve_for_insert(size() + 1)) \
bucket = data_.bucket_ptr_from_hash(hash_value); \
\
return std::pair<iterator_base, bool>(iterator_base(bucket, \
data_.link_node_in_bucket(a, bucket)), true); \
} \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator_base, bool> emplace_impl(no_key, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
node_constructor a(data_.allocators_); \
a.construct( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
); \
return emplace_impl_with_node(a); \
}
BOOST_UNORDERED_INSERT_IMPL2(1, 1, _)
BOOST_PP_REPEAT_FROM_TO(2, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_INSERT_IMPL, _)
#undef BOOST_UNORDERED_INSERT_IMPL
#endif
std::pair<iterator_base, bool> emplace_impl_with_node(node_constructor& a)
{
// No side effects in this initial code
key_type const& k = extract_key(a.get()->value());
size_type hash_value = hash_function()(k);
@@ -1924,19 +2078,6 @@ namespace boost {
}
}
// Insert (unique keys)
// (I'm using an overloaded insert for both 'insert' and 'emplace')
// if hash function throws, basic exception safety
// strong otherwise
template<typename... Args>
iterator_base insert_hint(iterator_base const&, Args&&... args)
{
// Life is complicated - just call the normal implementation.
return insert(std::forward<Args>(args)...).first;
}
#endif
// Insert from iterators (unique keys)
template <typename I>
@@ -1963,6 +2104,13 @@ namespace boost {
// strong otherwise
template <typename InputIterator>
void insert_range(InputIterator i, InputIterator j)
{
if(i != j)
return insert_range_impl(extract_key(*i), i, j);
}
template <typename InputIterator>
void insert_range_impl(key_type const&, InputIterator i, InputIterator j)
{
node_constructor a(data_.allocators_);
@@ -1992,6 +2140,36 @@ namespace boost {
}
}
}
template <typename InputIterator>
void insert_range_impl(no_key, InputIterator i, InputIterator j)
{
node_constructor a(data_.allocators_);
for (; i != j; ++i) {
// No side effects in this initial code
a.construct(*i);
key_type const& k = extract_key(a.get()->value());
size_type hash_value = hash_function()(extract_key(k));
bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
link_ptr pos = find_iterator(bucket, k);
if (!BOOST_UNORDERED_BORLAND_BOOL(pos)) {
// Doesn't already exist, add to bucket.
// Side effects only in this block.
// reserve has basic exception safety if the hash function
// throws, strong otherwise.
if(size() + 1 >= max_load_) {
reserve_for_insert(size() + insert_size(i, j));
bucket = data_.bucket_ptr_from_hash(hash_value);
}
// Nothing after this point can throw.
data_.link_node_in_bucket(a, bucket);
}
}
}
#endif
public:
@@ -2078,8 +2256,9 @@ namespace boost {
key_type const& k) const
{
link_ptr it = data_.begin(bucket);
while (BOOST_UNORDERED_BORLAND_BOOL(it) && !equal(k, data::get_value(it)))
while (BOOST_UNORDERED_BORLAND_BOOL(it) && !equal(k, data::get_value(it))) {
it = data::next_group(it);
}
return it;
}
+138 -18
View File
@@ -21,6 +21,10 @@
#include <boost/unordered/detail/move.hpp>
#endif
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
@@ -35,6 +39,9 @@ namespace boost
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_map
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
typedef boost::unordered_detail::hash_types_unique_keys<
std::pair<const Key, T>, Key, Hash, Pred, Alloc
> implementation;
@@ -98,12 +105,23 @@ namespace boost
unordered_map(InputIterator f, InputIterator l,
size_type n,
const hasher &hf = hasher(),
const key_equal &eql = key_equal(),
const allocator_type &a = allocator_type())
const key_equal &eql = key_equal())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_map(InputIterator f, InputIterator l,
size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_map() {}
#if defined(BOOST_HAS_RVALUE_REFS)
unordered_map(unordered_map&& other)
: base(other.base, boost::unordered_detail::move_tag())
@@ -135,7 +153,7 @@ namespace boost
#endif
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_map(std::initializer_list<value_type> list,
size_type n = boost::unordered_detail::default_initial_bucket_count,
const hasher &hf = hasher(),
@@ -219,30 +237,74 @@ namespace boost
// modifiers
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.insert(std::forward<Args>(args)...));
base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
std::pair<iterator, bool> emplace(value_type const& v = value_type())
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator, bool> emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return boost::unordered_detail::pair_cast<iterator, bool>( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
std::pair<iterator, bool> insert(const value_type& obj)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.insert(obj));
base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.insert_hint(get(hint), obj));
return iterator(base.emplace_hint(get(hint), obj));
}
template <class InputIterator>
@@ -411,7 +473,7 @@ namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
friend bool operator==(unordered_map const&, unordered_map const&);
friend bool operator!=(unordered_map const&, unordered_map const&);
#else
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>(unordered_map const&, unordered_map const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>(unordered_map const&, unordered_map const&);
#endif
@@ -441,6 +503,9 @@ namespace boost
template <class Key, class T, class Hash, class Pred, class Alloc>
class unordered_multimap
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
typedef boost::unordered_detail::hash_types_equivalent_keys<
std::pair<const Key, T>, Key, Hash, Pred, Alloc
> implementation;
@@ -504,12 +569,23 @@ namespace boost
unordered_multimap(InputIterator f, InputIterator l,
size_type n,
const hasher &hf = hasher(),
const key_equal &eql = key_equal(),
const allocator_type &a = allocator_type())
const key_equal &eql = key_equal())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_multimap(InputIterator f, InputIterator l,
size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_multimap() {}
#if defined(BOOST_HAS_RVALUE_REFS)
unordered_multimap(unordered_multimap&& other)
: base(other.base, boost::unordered_detail::move_tag())
@@ -541,7 +617,7 @@ namespace boost
#endif
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_multimap(std::initializer_list<value_type> list,
size_type n = boost::unordered_detail::default_initial_bucket_count,
const hasher &hf = hasher(),
@@ -626,28 +702,72 @@ namespace boost
// modifiers
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <class... Args>
iterator emplace(Args&&... args)
{
return iterator(base.insert(std::forward<Args>(args)...));
return iterator(base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
iterator emplace(value_type const& v = value_type())
{
return iterator(base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
iterator insert(const value_type& obj)
{
return iterator(base.insert(obj));
return iterator(base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.insert_hint(get(hint), obj));
return iterator(base.emplace_hint(get(hint), obj));
}
template <class InputIterator>
@@ -801,7 +921,7 @@ namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
friend bool operator==(unordered_multimap const&, unordered_multimap const&);
friend bool operator!=(unordered_multimap const&, unordered_multimap const&);
#else
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Key, T, Hash, Pred, Alloc>(unordered_multimap const&, unordered_multimap const&);
friend bool operator!=<Key, T, Hash, Pred, Alloc>(unordered_multimap const&, unordered_multimap const&);
#endif
+135 -18
View File
@@ -21,6 +21,10 @@
#include <boost/unordered/detail/move.hpp>
#endif
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
#include <initializer_list>
#endif
#if defined(BOOST_MSVC)
#pragma warning(push)
#if BOOST_MSVC >= 1400
@@ -35,6 +39,9 @@ namespace boost
template <class Value, class Hash, class Pred, class Alloc>
class unordered_set
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
typedef boost::unordered_detail::hash_types_unique_keys<
Value, Value, Hash, Pred, Alloc
> implementation;
@@ -96,11 +103,21 @@ namespace boost
template <class InputIterator>
unordered_set(InputIterator f, InputIterator l, size_type n,
const hasher &hf = hasher(),
const key_equal &eql = key_equal(),
const allocator_type &a = allocator_type())
const key_equal &eql = key_equal())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_set(InputIterator f, InputIterator l, size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_set() {}
#if defined(BOOST_HAS_RVALUE_REFS)
unordered_set(unordered_set&& other)
@@ -133,7 +150,7 @@ namespace boost
#endif
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_set(std::initializer_list<value_type> list,
size_type n = boost::unordered_detail::default_initial_bucket_count,
const hasher &hf = hasher(),
@@ -217,31 +234,75 @@ namespace boost
// modifiers
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <class... Args>
std::pair<iterator, bool> emplace(Args&&... args)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.insert(std::forward<Args>(args)...));
base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(
base.insert_hint(get(hint), std::forward<Args>(args)...));
base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
std::pair<iterator, bool> emplace(value_type const& v = value_type())
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
std::pair<iterator, bool> emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return boost::unordered_detail::pair_cast<iterator, bool>( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
std::pair<iterator, bool> insert(const value_type& obj)
{
return boost::unordered_detail::pair_cast<iterator, bool>(
base.insert(obj));
base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.insert_hint(get(hint), obj));
return iterator(base.emplace_hint(get(hint), obj));
}
template <class InputIterator>
@@ -383,7 +444,7 @@ namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
friend bool operator==(unordered_set const&, unordered_set const&);
friend bool operator!=(unordered_set const&, unordered_set const&);
#else
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>(unordered_set const&, unordered_set const&);
friend bool operator!=<Value, Hash, Pred, Alloc>(unordered_set const&, unordered_set const&);
#endif
@@ -413,6 +474,9 @@ namespace boost
template <class Value, class Hash, class Pred, class Alloc>
class unordered_multiset
{
#if BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
public:
#endif
typedef boost::unordered_detail::hash_types_equivalent_keys<
Value, Value, Hash, Pred, Alloc
> implementation;
@@ -474,12 +538,22 @@ namespace boost
template <class InputIterator>
unordered_multiset(InputIterator f, InputIterator l, size_type n,
const hasher &hf = hasher(),
const key_equal &eql = key_equal(),
const allocator_type &a = allocator_type())
const key_equal &eql = key_equal())
: base(f, l, n, hf, eql, allocator_type())
{
}
template <class InputIterator>
unordered_multiset(InputIterator f, InputIterator l, size_type n,
const hasher &hf,
const key_equal &eql,
const allocator_type &a)
: base(f, l, n, hf, eql, a)
{
}
~unordered_multiset() {}
#if defined(BOOST_HAS_RVALUE_REFS)
unordered_multiset(unordered_multiset&& other)
: base(other.base, boost::unordered_detail::move_tag())
@@ -511,7 +585,7 @@ namespace boost
#endif
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
unordered_multiset(std::initializer_list<value_type> list,
size_type n = boost::unordered_detail::default_initial_bucket_count,
const hasher &hf = hasher(),
@@ -595,28 +669,71 @@ namespace boost
// modifiers
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template <class... Args>
iterator emplace(Args&&... args)
{
return iterator(base.insert(std::forward<Args>(args)...));
return iterator(base.emplace(std::forward<Args>(args)...));
}
template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args)
{
return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
return iterator(base.emplace_hint(get(hint), std::forward<Args>(args)...));
}
#else
iterator emplace(value_type const& v = value_type())
{
return iterator(base.emplace(v));
}
iterator emplace_hint(const_iterator hint, value_type const& v = value_type())
{
return iterator(base.emplace_hint(get(hint), v));
}
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace( \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator( \
base.emplace( \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
} \
\
template < \
BOOST_UNORDERED_TEMPLATE_ARGS(z, n) \
> \
iterator emplace_hint(const_iterator hint, \
BOOST_UNORDERED_FUNCTION_PARAMS(z, n) \
) \
{ \
return iterator(base.emplace_hint(get(hint), \
BOOST_UNORDERED_CALL_PARAMS(z, n) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT,
BOOST_UNORDERED_EMPLACE, _)
#undef BOOST_UNORDERED_EMPLACE
#endif
iterator insert(const value_type& obj)
{
return iterator(base.insert(obj));
return iterator(base.emplace(obj));
}
iterator insert(const_iterator hint, const value_type& obj)
{
return iterator(base.insert_hint(get(hint), obj));
return iterator(base.emplace_hint(get(hint), obj));
}
template <class InputIterator>
@@ -758,7 +875,7 @@ namespace boost
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
friend bool operator==(unordered_multiset const&, unordered_multiset const&);
friend bool operator!=(unordered_multiset const&, unordered_multiset const&);
#else
#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x0582)
friend bool operator==<Value, Hash, Pred, Alloc>(unordered_multiset const&, unordered_multiset const&);
friend bool operator!=<Value, Hash, Pred, Alloc>(unordered_multiset const&, unordered_multiset const&);
#endif
+8 -59
View File
@@ -1,3 +1,9 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
boost_additional_test_dependencies(unordered BOOST_DEPENDS test)
# GCC Compilers
@@ -12,64 +18,7 @@ ENDIF( ${CMAKE_CXX_COMPILER} MATCHES "icpc" )
set (swap_compile_flags "${test_compile_flags} -DBOOST_UNORDERED_SWAP_METHOD=2")
#-------------------------------------------------------------------------------
# Unordered Tests
set (unordered_tests
fwd_set_test
fwd_map_test
compile_set
compile_map
link_test_1
link_test_2
simple_tests
equivalent_keys_tests
constructor_tests
copy_tests
move_tests.cpp
assign_tests
insert_tests
insert_stable_tests
unnecessary_copy_tests
erase_tests
erase_equiv_tests
find_tests
at_tests
bucket_tests
load_factor_tests
rehash_tests
equality_tests
)
#-- Create an executable test for each source
foreach(test ${unordered_tests})
boost_test_run(${test} "unordered/${test}.cpp"
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach(test ${unordered_tests})
#-- run the swap test
boost_test_run(swap_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)
#-------------------------------------------------------------------------------
# Exception Tests
set (exception_tests
constructor_exception_tests
copy_exception_tests
assign_exception_tests
insert_exception_tests
erase_exception_tests
rehash_exception_tests
)
#-- Create an executable test for each source
foreach(test ${exception_tests})
boost_test_run(${test} "exception/${test}.cpp"
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach(test ${unordered_tests})
#-- run the swap test
boost_test_run(swap_swap_exception_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)
add_subdirectory(exception)
add_subdirectory(unordered)
+25
View File
@@ -0,0 +1,25 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
foreach(test
constructor_exception_tests
copy_exception_tests
assign_exception_tests
insert_exception_tests
erase_exception_tests
rehash_exception_tests
)
boost_test_run(${test}
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach(test ${unordered_tests})
#-- run the swap test
boost_test_run(swap_exception_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)
+1 -1
View File
@@ -25,7 +25,7 @@ struct erase_test_base : public test::exception_base
void check(T const& x) const {
std::string scope(test::scope);
BOOST_CHECK(scope.find("hash::") != std::string::npos ||
BOOST_TEST(scope.find("hash::") != std::string::npos ||
scope.find("equal_to::") != std::string::npos ||
scope == "operator==(object, object)");
+9 -9
View File
@@ -128,10 +128,10 @@ struct insert_test_rehash1 : public insert_test_base<T>
size_type bucket_count = x.bucket_count();
size_type initial_elements = static_cast<size_type>(
ceil(bucket_count * (double) x.max_load_factor()) - 1);
BOOST_REQUIRE(initial_elements < this->values.size());
BOOST_TEST(initial_elements < this->values.size());
x.insert(this->values.begin(),
boost::next(this->values.begin(), initial_elements));
BOOST_REQUIRE(bucket_count == x.bucket_count());
BOOST_TEST(bucket_count == x.bucket_count());
return x;
}
@@ -150,7 +150,7 @@ struct insert_test_rehash1 : public insert_test_base<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
};
@@ -173,7 +173,7 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
};
@@ -195,12 +195,12 @@ 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;
size_type initial_elements = rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
BOOST_REQUIRE(initial_elements < this->values.size());
BOOST_TEST(initial_elements < this->values.size());
x.insert(this->values.begin(),
boost::next(this->values.begin(), initial_elements));
BOOST_REQUIRE(original_bucket_count == x.bucket_count());
BOOST_TEST(original_bucket_count == x.bucket_count());
return x;
}
@@ -212,12 +212,12 @@ struct insert_test_rehash3 : public insert_test_base<T>
// This isn't actually a failure, but it means the test isn't doing its
// job.
BOOST_REQUIRE(x.bucket_count() != bucket_count);
BOOST_TEST(x.bucket_count() != bucket_count);
}
void check(T const& x) const {
if(x.size() < rehash_bucket_count) {
//BOOST_CHECK(x.bucket_count() == original_bucket_count);
//BOOST_TEST(x.bucket_count() == original_bucket_count);
}
test::check_equivalent_keys(x);
}
+2 -2
View File
@@ -22,7 +22,7 @@ struct self_swap_base : public test::exception_base
std::string scope(test::scope);
#if BOOST_UNORDERED_SWAP_METHOD != 2
BOOST_CHECK(
BOOST_TEST(
scope == "hash::operator(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::operator(equal_to)" ||
@@ -77,7 +77,7 @@ struct swap_base : public test::exception_base
std::string scope(test::scope);
#if BOOST_UNORDERED_SWAP_METHOD != 2
BOOST_CHECK(
BOOST_TEST(
scope == "hash::operator(hash)" ||
scope == "hash::operator=(hash)" ||
scope == "equal_to::operator(equal_to)" ||
+7
View File
@@ -6,6 +6,8 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
#define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
#include <iostream>
namespace test {
struct object_count {
int instances;
@@ -36,6 +38,11 @@ namespace test {
bool operator!=(object_count const& x) const {
return !(*this == x);
}
friend std::ostream& operator<<(std::ostream& out, object_count const& c) {
out<<"[instances: "<<c.instances<<", constructions: "<<c.constructions<<"]";
return out;
}
};
template <class T>
-26
View File
@@ -8,25 +8,10 @@
#include "./test.hpp"
#if defined(BOOST_UNORDERED_FULL_TEST)
# define BOOST_TEST_MAIN
# include <boost/test/exception_safety.hpp>
# include <boost/test/unit_test.hpp>
#endif
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/cat.hpp>
#if defined(BOOST_UNORDERED_FULL_TEST)
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
UNORDERED_AUTO_TEST(name) \
{ \
test_func< type > fixture; \
::test::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
}
# define UNORDERED_EPOINT_IMPL BOOST_ITEST_EPOINT
#else
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
UNORDERED_AUTO_TEST(name) \
{ \
@@ -34,7 +19,6 @@
::test::lightweight::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \
}
# define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
#endif
#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
@@ -178,16 +162,7 @@ namespace test {
}
}
};
#if defined(BOOST_UNORDERED_FULL_TEST)
template <class Test>
void exception_safety(Test const& f, char const* name) {
test_runner<Test> runner(f);
::boost::itest::exception_safety(runner, name);
}
#else
// Quick exception testing based on lightweight test
namespace lightweight {
@@ -237,7 +212,6 @@ namespace test {
} while(!success);
}
}
#endif
}
#endif
+17 -2
View File
@@ -6,19 +6,34 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_INPUT_ITERATOR_HEADER
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
namespace test
{
template <class Iterator>
struct proxy
{
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type;
proxy(value_type const& v) : v_(v) {}
proxy(proxy const& x) : v_(x.v_) {}
operator value_type const&() const { return v_; }
value_type v_;
};
template <class Iterator>
struct input_iterator_adaptor
: boost::iterator_adaptor<
input_iterator_adaptor<Iterator>, Iterator,
boost::use_default, std::input_iterator_tag>
boost::use_default, std::input_iterator_tag,
proxy<Iterator> >
{
typedef boost::iterator_adaptor<
input_iterator_adaptor<Iterator>, Iterator,
boost::use_default, std::input_iterator_tag> base;
boost::use_default, std::input_iterator_tag,
proxy<Iterator> > base;
explicit input_iterator_adaptor(Iterator it = Iterator())
: base(it) {}
+2 -2
View File
@@ -81,7 +81,7 @@ namespace test
T* operator->() const { return &ptr_->value_; }
list_iterator& operator++() {
ptr_ = ptr_->next_; return *this; }
list_iterator& operator++(int) {
list_iterator operator++(int) {
list_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_; }
@@ -108,7 +108,7 @@ namespace test
T const* operator->() const { return &ptr_->value_; }
list_const_iterator& operator++() {
ptr_ = ptr_->next_; return *this; }
list_const_iterator& operator++(int) {
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_; }
+9 -14
View File
@@ -18,11 +18,6 @@ namespace test
{
namespace detail
{
// This annoymous namespace won't cause ODR violations as I won't
// be linking multiple translation units together. I'll probably
// move this into a cpp file before a full release, but for now it's
// the most convenient way.
struct memory_area {
void const* start;
void const* end;
@@ -103,7 +98,7 @@ namespace test
void allocator_unref()
{
BOOST_CHECK(count_allocators > 0);
BOOST_TEST(count_allocators > 0);
if(count_allocators > 0) {
--count_allocators;
if(count_allocators == 0) {
@@ -116,9 +111,9 @@ namespace test
count_constructions = 0;
allocated_memory.clear();
BOOST_CHECK(no_allocations_left);
BOOST_CHECK(no_constructions_left);
BOOST_CHECK(allocated_memory_empty);
BOOST_TEST(no_allocations_left);
BOOST_TEST(no_constructions_left);
BOOST_TEST(allocated_memory_empty);
}
}
}
@@ -144,12 +139,12 @@ namespace test
if(pos == allocated_memory.end()) {
BOOST_ERROR("Deallocating unknown pointer.");
} else {
BOOST_CHECK(pos->first.start == ptr);
BOOST_CHECK(pos->first.end == (char*) ptr + n * size);
BOOST_CHECK(pos->second.tag_ == tag);
BOOST_TEST(pos->first.start == ptr);
BOOST_TEST(pos->first.end == (char*) ptr + n * size);
BOOST_TEST(pos->second.tag_ == tag);
allocated_memory.erase(pos);
}
BOOST_CHECK(count_allocations > 0);
BOOST_TEST(count_allocations > 0);
if(count_allocations > 0) --count_allocations;
}
@@ -160,7 +155,7 @@ namespace test
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
{
BOOST_CHECK(count_constructions > 0);
BOOST_TEST(count_constructions > 0);
if(count_constructions > 0) --count_constructions;
}
};
+3 -12
View File
@@ -6,15 +6,7 @@
#if !defined(BOOST_UNORDERED_TEST_TEST_HEADER)
#define BOOST_UNORDERED_TEST_TEST_HEADER
#if defined(BOOST_UNORDERED_FULL_TEST)
#include <boost/test/test_tools.hpp>
#define UNORDERED_AUTO_TEST(x) BOOST_AUTO_TEST_CASE(x)
#define RUN_TESTS()
#else
#include <boost/test/minimal.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <iostream>
@@ -30,7 +22,8 @@
}; \
BOOST_PP_CAT(x, _type) x; \
void BOOST_PP_CAT(x, _type)::run()
#define RUN_TESTS() int test_main(int, char**) { ::test::test_list::run_tests(); return 0; }
#define RUN_TESTS() int main(int, char**) \
{ ::test::test_list::run_tests(); return boost::report_errors(); }
namespace test {
struct registered_test_base {
@@ -74,8 +67,6 @@ namespace test {
}
}
#endif
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
+2 -2
View File
@@ -49,7 +49,7 @@ namespace test
value_list values2(x2.begin(), x2.end());
values1.sort();
values2.sort();
BOOST_CHECK(values1.size() == values2.size() &&
BOOST_TEST(values1.size() == values2.size() &&
std::equal(values1.begin(), values1.end(), values2.begin(),
test::equivalent));
}
@@ -61,7 +61,7 @@ namespace test
test::list<T> values2(x2.first, x2.second);
values1.sort();
values2.sort();
BOOST_CHECK(values1.size() == values2.size() &&
BOOST_TEST(values1.size() == values2.size() &&
std::equal(values1.begin(), values1.end(), values2.begin(), test::equivalent));
}
+1 -1
View File
@@ -347,7 +347,7 @@ namespace exception
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
UNORDERED_EPOINT("Mock allocator construct function.");
+1 -1
View File
@@ -229,7 +229,7 @@ namespace minimal
void construct(pointer p, T const& t) { new((void*)p.ptr_) T(t); }
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
new((void*)p.ptr_) T(std::forward<Args>(args)...);
}
+1 -1
View File
@@ -218,7 +218,7 @@ namespace test
new(p) T(t);
}
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
#if defined(BOOST_UNORDERED_STD_FORWARD)
template<class... Args> void construct(pointer p, Args&&... args) {
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
new(p) T(std::forward<Args>(args)...);
+43
View File
@@ -0,0 +1,43 @@
#
# Copyright Troy D. Straszheim
#
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
#
#-------------------------------------------------------------------------------
# Unordered Tests
foreach(test
fwd_set_test
fwd_map_test
compile_set
compile_map
simple_tests
equivalent_keys_tests
constructor_tests
copy_tests
move_tests
assign_tests
insert_tests
insert_stable_tests
unnecessary_copy_tests
erase_tests
erase_equiv_tests
find_tests
at_tests
bucket_tests
load_factor_tests
rehash_tests
equality_tests
)
boost_test_run(${test}
COMPILE_FLAGS ${test_compile_flags}
DEPENDS boost_unit_test_framework)
endforeach()
boost_test_run(link_test link_test_1.cpp link_test_2.cpp)
#-- run the swap test
boost_test_run(swap_tests
COMPILE_FLAGS ${swap_compile_flags}
DEPENDS boost_unit_test_framework)
+26 -11
View File
@@ -27,9 +27,9 @@ void assign_tests1(T*, test::random_generator generator = test::default_generato
{
T x;
x = x;
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"assign_tests1.2\n";
@@ -47,7 +47,7 @@ void assign_tests1(T*, test::random_generator generator = test::default_generato
y.max_load_factor(x.max_load_factor() / 20);
y = x;
tracker.compare(y);
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
}
}
@@ -67,8 +67,8 @@ void assign_tests2(T*, test::random_generator generator = test::default_generato
T x1(v.begin(), v.end(), 0, hf1, eq1);
T x2(0, hf2, eq2);
x2 = x1;
BOOST_CHECK(test::equivalent(x2.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x2.key_eq(), eq1));
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
test::check_container(x2, v);
}
@@ -78,9 +78,9 @@ void assign_tests2(T*, test::random_generator generator = test::default_generato
T x1(v1.begin(), v1.end(), 0, hf1, eq1, al1);
T x2(v2.begin(), v2.end(), 0, hf2, eq2, al2);
x2 = x1;
BOOST_CHECK(test::equivalent(x2.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x2.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x2.get_allocator(), al2));
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
BOOST_TEST(test::equivalent(x2.get_allocator(), al2));
test::check_container(x2, v1);
}
}
@@ -103,6 +103,21 @@ UNORDERED_TEST(assign_tests2,
((default_generator)(generate_collisions))
)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(assign_default_initializer_list) {
std::cerr<<"Initializer List Tests\n";
std::initializer_list<std::pair<int const, int> > init;
boost::unordered_map<int, int> x1;
x1[25] = 3;
x1[16] = 10;
BOOST_TEST(!x1.empty());
x1 = init;
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
UNORDERED_AUTO_TEST(assign_initializer_list)
@@ -113,8 +128,8 @@ UNORDERED_AUTO_TEST(assign_initializer_list)
x.insert(10);
x.insert(20);
x = { 1, 2, -10 };
BOOST_CHECK(x.find(10) == x.end());
BOOST_CHECK(x.find(-10) != x.end());
BOOST_TEST(x.find(10) == x.end());
BOOST_TEST(x.find(-10) != x.end());
}
#endif
+2 -2
View File
@@ -16,8 +16,8 @@ UNORDERED_AUTO_TEST(at_tests) {
x["one"] = 1;
x["two"] = 2;
BOOST_CHECK(x.at("one") == 1);
BOOST_CHECK(x.at("two") == 2);
BOOST_TEST(x.at("one") == 1);
BOOST_TEST(x.at("two") == 2);
try {
x.at("three");
+7 -7
View File
@@ -24,7 +24,7 @@ void tests(X* = 0, test::random_generator generator = test::default_generator)
X x(v.begin(), v.end());
BOOST_CHECK(x.bucket_count() < x.max_bucket_count());
BOOST_TEST(x.bucket_count() < x.max_bucket_count());
std::cerr<<x.bucket_count()<<"<"<<x.max_bucket_count()<<"\n";
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
@@ -32,21 +32,21 @@ void tests(X* = 0, test::random_generator generator = test::default_generator)
{
size_type bucket = x.bucket(test::get_key<X>(*it));
BOOST_CHECK(bucket < x.bucket_count());
BOOST_TEST(bucket < x.bucket_count());
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;
BOOST_CHECK(lit != lend);
BOOST_TEST(lit != lend);
}
}
for(size_type i = 0; i < x.bucket_count(); ++i) {
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x.begin(i), x.end(i)));
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x.cbegin(i), x.cend(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)));
X const& x_ref = x;
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x_ref.begin(i), x_ref.end(i)));
BOOST_CHECK(x.bucket_size(i) == (size_type) std::distance(x_ref.cbegin(i), x_ref.cend(i)));
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)));
}
}
+5 -13
View File
@@ -87,10 +87,10 @@ void container_test(X& r, T const&)
// I'm not sure about either of these tests...
size_type max_diff((std::numeric_limits<difference_type>::max)());
difference_type converted_diff(max_diff);
BOOST_CHECK((std::numeric_limits<difference_type>::max)()
BOOST_TEST((std::numeric_limits<difference_type>::max)()
== converted_diff);
BOOST_CHECK(
BOOST_TEST(
static_cast<comparison_type>(
(std::numeric_limits<size_type>::max)()) >
static_cast<comparison_type>(
@@ -98,8 +98,8 @@ void container_test(X& r, T const&)
// I don't test the runtime post-conditions here.
X u;
BOOST_CHECK(u.size() == 0);
BOOST_CHECK(X().size() == 0);
BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0);
X a,b;
@@ -151,14 +151,12 @@ void unordered_map_test(X& r, Key const& k, T const& v)
r.insert(std::pair<Key const, T>(k, v));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
Key k_lvalue(k);
T v_lvalue(v);
r.emplace(k, v);
r.emplace(k_lvalue, v_lvalue);
r.emplace(rvalue(k), rvalue(v));
#endif
}
template <class X>
@@ -175,9 +173,7 @@ void unordered_unique_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
#endif
}
template <class X, class T>
@@ -185,9 +181,7 @@ void unordered_equivalent_test(X& r, T const& t)
{
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<iterator>::equals(r.insert(t));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
test::check_return_type<iterator>::equals(r.emplace(t));
#endif
}
template <class X, class Key, class T>
@@ -289,14 +283,12 @@ void unordered_test(X&, Key& k, T& t, Hash& hf, Pred& eq)
const_iterator q = a.cbegin();
test::check_return_type<iterator>::equals(a.insert(q, t));
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
#endif
a.insert(i, j);
test::check_return_type<size_type>::equals(a.erase(k));
BOOST_CHECK(a.empty());
BOOST_TEST(a.empty());
if(a.empty()) {
a.insert(t);
q = a.cbegin();
+74 -63
View File
@@ -29,42 +29,42 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
std::cerr<<"Construct 1\n";
{
T x(0, hf, eq);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 2\n";
{
T x(100, hf);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 3\n";
{
T x(2000);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 2000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 2000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 4\n";
{
T x;
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@@ -72,10 +72,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(v.begin(), v.end(), 10000, hf, eq);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -84,10 +84,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(10, generator);
T x(v.begin(), v.end(), 10000, hf);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -96,10 +96,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(100, generator);
T x(v.begin(), v.end(), 100);
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -108,9 +108,9 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1, generator);
T x(v.begin(), v.end());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -118,10 +118,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
std::cerr<<"Construct 9\n";
{
T x(0, hf, eq, al);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@@ -129,10 +129,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(v.begin(), v.end(), 10000, hf, eq, al);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -141,10 +141,10 @@ void constructor_tests1(T*, test::random_generator generator = test::default_gen
{
test::random_values<T> v(1000, generator);
T x(al);
BOOST_CHECK(x.empty());
BOOST_CHECK(test::equivalent(x.hash_function(), hf));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
}
@@ -165,21 +165,21 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
std::cerr<<"Construct 1\n";
{
T x(10000, hf1, eq1);
BOOST_CHECK(x.bucket_count() >= 10000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
std::cerr<<"Construct 2\n";
{
T x(100, hf1);
BOOST_CHECK(x.empty());
BOOST_CHECK(x.bucket_count() >= 100);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_equivalent_keys(x);
}
@@ -187,9 +187,9 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
{
test::random_values<T> v(100, generator);
T x(v.begin(), v.end(), 0, hf1, eq1);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq1));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -198,10 +198,10 @@ void constructor_tests2(T*, test::random_generator const& generator = test::defa
{
test::random_values<T> v(5, generator);
T x(v.begin(), v.end(), 1000, hf1);
BOOST_CHECK(x.bucket_count() >= 1000);
BOOST_CHECK(test::equivalent(x.hash_function(), hf1));
BOOST_CHECK(test::equivalent(x.key_eq(), eq));
BOOST_CHECK(test::equivalent(x.get_allocator(), al));
BOOST_TEST(x.bucket_count() >= 1000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
test::check_container(x, v);
test::check_equivalent_keys(x);
}
@@ -288,13 +288,24 @@ UNORDERED_TEST(map_constructor_test,
((test_map)(test_multimap))
)
#if !defined(BOOST_NO_0X_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(test_default_initializer_list) {
std::cerr<<"Initializer List Tests\n";
std::initializer_list<int> init;
boost::unordered_set<int> x1 = init;
BOOST_TEST(x1.empty());
}
#endif
#if !defined(BOOST_NO_INITIALIZER_LISTS)
UNORDERED_AUTO_TEST(test_initializer_list) {
std::cerr<<"Initializer List Tests\n";
boost::unordered_set<int> x1 = { 2, 10, 45, -5 };
BOOST_CHECK(x1.find(10) != x1.end());
BOOST_CHECK(x1.find(46) == x1.end());
BOOST_TEST(x1.find(10) != x1.end());
BOOST_TEST(x1.find(46) == x1.end());
}
#endif
+18 -18
View File
@@ -27,11 +27,11 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d
{
T x;
T y(x);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
@@ -57,7 +57,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator = test::d
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
// This isn't guaranteed:
BOOST_CHECK(y.load_factor() < y.max_load_factor());
BOOST_TEST(y.load_factor() < y.max_load_factor());
test::check_equivalent_keys(y);
}
}
@@ -75,22 +75,22 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
{
T x(10000, hf, eq, al);
T y(x);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
{
T x(1000, hf, eq, al);
T y(x, al2);
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_CHECK(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
@@ -102,7 +102,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
}
{
@@ -113,7 +113,7 @@ void copy_construct_tests2(T* ptr, test::random_generator const& generator = tes
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
}
}
+21 -21
View File
@@ -33,7 +33,7 @@ namespace equality_tests
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_CHECK(set1 op set2); \
BOOST_TEST(set1 op set2); \
} while(false)
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
@@ -41,7 +41,7 @@ namespace equality_tests
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_CHECK(set1 op set2); \
BOOST_TEST(set1 op set2); \
} while(false)
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
@@ -49,7 +49,7 @@ namespace equality_tests
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_CHECK(map1 op map2); \
BOOST_TEST(map1 op map2); \
} while(false)
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
@@ -57,7 +57,7 @@ namespace equality_tests
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_CHECK(map1 op map2); \
BOOST_TEST(map1 op map2); \
} while(false)
#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
@@ -67,24 +67,24 @@ namespace equality_tests
UNORDERED_AUTO_TEST(equality_size_tests)
{
boost::unordered_set<int> x1, x2;
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
BOOST_TEST(x1 == x2);
BOOST_TEST(!(x1 != x2));
x1.insert(1);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
BOOST_TEST(x1 != x2);
BOOST_TEST(!(x1 == x2));
BOOST_TEST(x2 != x1);
BOOST_TEST(!(x2 == x1));
x2.insert(1);
BOOST_CHECK(x1 == x2);
BOOST_CHECK(!(x1 != x2));
BOOST_TEST(x1 == x2);
BOOST_TEST(!(x1 != x2));
x2.insert(2);
BOOST_CHECK(x1 != x2);
BOOST_CHECK(!(x1 == x2));
BOOST_CHECK(x2 != x1);
BOOST_CHECK(!(x2 == x1));
BOOST_TEST(x1 != x2);
BOOST_TEST(!(x1 == x2));
BOOST_TEST(x2 != x1);
BOOST_TEST(!(x2 == x1));
}
UNORDERED_AUTO_TEST(equality_key_value_tests)
@@ -150,15 +150,15 @@ namespace equality_tests
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
set set1(0, mod_compare(false), mod_compare(false));
set set2(0, mod_compare(true), mod_compare(true));
BOOST_CHECK(set1 == set2);
BOOST_TEST(set1 == set2);
set1.insert(1); set2.insert(2);
BOOST_CHECK(set1 != set2);
BOOST_TEST(set1 != set2);
set1.insert(2); set2.insert(1);
BOOST_CHECK(set1 == set2);
BOOST_TEST(set1 == set2);
set1.insert(10); set2.insert(20);
BOOST_CHECK(set1 != set2);
BOOST_TEST(set1 != set2);
set1.insert(20); set2.insert(10);
BOOST_CHECK(set1 == set2);
BOOST_TEST(set1 == set2);
}
}
+6 -6
View File
@@ -67,11 +67,11 @@ UNORDERED_AUTO_TEST(single_item_tests)
collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.begin());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1);
BOOST_TEST(x.count(1) == 1 && x.size() == 1);
x.erase(x.end(), x.end());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1);
BOOST_TEST(x.count(1) == 1 && x.size() == 1);
x.erase(x.begin(), x.end());
BOOST_CHECK(x.count(1) == 0 && x.size() == 0);
BOOST_TEST(x.count(1) == 0 && x.size() == 0);
}
UNORDERED_AUTO_TEST(two_equivalent_item_tests)
@@ -83,14 +83,14 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
{
collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.end());
BOOST_CHECK(x.count(1) == 0 && x.size() == 0);
BOOST_TEST(x.count(1) == 0 && x.size() == 0);
}
{
collide_map x(init.begin(), init.end());
int value = boost::next(x.begin())->second;
x.erase(x.begin(), boost::next(x.begin()));
BOOST_CHECK(x.count(1) == 1 && x.size() == 1 &&
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
x.begin()->first == 1 && x.begin()->second == value);
}
@@ -98,7 +98,7 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
collide_map x(init.begin(), init.end());
int value = x.begin()->second;
x.erase(boost::next(x.begin()), x.end());
BOOST_CHECK(x.count(1) == 1 && x.size() == 1 &&
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
x.begin()->first == 1 && x.begin()->second == value);
}
}
+22 -22
View File
@@ -32,10 +32,10 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
{
std::size_t count = x.count(test::get_key<Container>(*it));
std::size_t old_size = x.size();
BOOST_CHECK(count == x.erase(test::get_key<Container>(*it)));
BOOST_CHECK(x.size() == old_size - count);
BOOST_CHECK(x.count(test::get_key<Container>(*it)) == 0);
BOOST_CHECK(x.find(test::get_key<Container>(*it)) == x.end());
BOOST_TEST(count == x.erase(test::get_key<Container>(*it)));
BOOST_TEST(x.size() == old_size - count);
BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0);
BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end());
}
}
@@ -50,11 +50,11 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
std::size_t count = x.count(key);
BOOST_DEDUCED_TYPENAME Container::iterator pos = x.erase(x.begin());
--size;
BOOST_CHECK(pos == x.begin());
BOOST_CHECK(x.count(key) == count - 1);
BOOST_CHECK(x.size() == size);
BOOST_TEST(pos == x.begin());
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_CHECK(x.empty());
BOOST_TEST(x.empty());
}
std::cerr<<"erase(random position).\n";
@@ -77,15 +77,15 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
next = boost::next(pos);
BOOST_DEDUCED_TYPENAME Container::key_type key = test::get_key<Container>(*pos);
std::size_t count = x.count(key);
BOOST_CHECK(next == x.erase(pos));
BOOST_TEST(next == x.erase(pos));
--size;
if(size > 0)
BOOST_CHECK(index == 0 ? next == x.begin() :
BOOST_TEST(index == 0 ? next == x.begin() :
next == boost::next(prev));
BOOST_CHECK(x.count(key) == count - 1);
BOOST_CHECK(x.size() == size);
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_CHECK(x.empty());
BOOST_TEST(x.empty());
}
std::cerr<<"erase(ranges).\n";
@@ -99,15 +99,15 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
// returns 'the iterator immediately following the erase elements'
// and if nothing is erased, then there's nothing to follow. But I
// think this is the only sensible option...
BOOST_CHECK(x.erase(x.end(), x.end()) == x.end());
BOOST_CHECK(x.erase(x.begin(), x.begin()) == x.begin());
BOOST_CHECK(x.size() == size);
BOOST_TEST(x.erase(x.end(), x.end()) == x.end());
BOOST_TEST(x.erase(x.begin(), x.begin()) == x.begin());
BOOST_TEST(x.size() == size);
BOOST_CHECK(x.erase(x.begin(), x.end()) == x.end());
BOOST_CHECK(x.empty());
BOOST_CHECK(x.begin() == x.end());
BOOST_TEST(x.erase(x.begin(), x.end()) == x.end());
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
BOOST_CHECK(x.erase(x.begin(), x.end()) == x.begin());
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
}
std::cerr<<"clear().\n";
@@ -115,8 +115,8 @@ void erase_tests1(Container*, test::random_generator generator = test::default_g
test::random_values<Container> v(500, generator);
Container x(v.begin(), v.end());
x.clear();
BOOST_CHECK(x.empty());
BOOST_CHECK(x.begin() == x.end());
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
}
std::cerr<<"\n";
+10 -10
View File
@@ -34,12 +34,12 @@ 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_CHECK(pos != x.end() &&
BOOST_TEST(pos != x.end() &&
x.key_eq()(key, test::get_key<X>(*pos)));
BOOST_CHECK(const_pos != x_const.end() &&
BOOST_TEST(const_pos != x_const.end() &&
x_const.key_eq()(key, test::get_key<X>(*const_pos)));
BOOST_CHECK(x.count(key) == tracker.count(key));
BOOST_TEST(x.count(key) == tracker.count(key));
test::compare_pairs(x.equal_range(key),
tracker.equal_range(key),
@@ -56,11 +56,11 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2);
if(tracker.find(test::get_key<X>(key)) == tracker.end())
{
BOOST_CHECK(x.find(key) == x.end());
BOOST_CHECK(x_const.find(key) == x_const.end());
BOOST_CHECK(x.count(key) == 0);
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x_const.find(key) == x_const.end());
BOOST_TEST(x.count(key) == 0);
std::pair<iterator, iterator> range = x.equal_range(key);
BOOST_CHECK(range.first == range.second);
BOOST_TEST(range.first == range.second);
}
}
}
@@ -73,10 +73,10 @@ void find_tests1(X*, test::random_generator generator = test::default_generator)
v2.begin(); it3 != v2.end(); ++it3)
{
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
BOOST_CHECK(x.find(key) == x.end());
BOOST_CHECK(x.count(key) == 0);
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x.count(key) == 0);
std::pair<iterator, iterator> range = x.equal_range(key);
BOOST_CHECK(range.first == range.second);
BOOST_TEST(range.first == range.second);
}
}
}
+8 -8
View File
@@ -42,21 +42,21 @@ UNORDERED_AUTO_TEST(use_map_fwd_declared_function) {
y[2] = 1;
call_swap(x, y);
BOOST_CHECK(y.find(1) != y.end() && y.find(1)->second == 2);
BOOST_CHECK(y.find(2) == y.end());
BOOST_TEST(y.find(1) != y.end() && y.find(1)->second == 2);
BOOST_TEST(y.find(2) == y.end());
BOOST_CHECK(x.find(1) == x.end());
BOOST_CHECK(x.find(2) != x.end() && x.find(2)->second == 1);
BOOST_TEST(x.find(1) == x.end());
BOOST_TEST(x.find(2) != x.end() && x.find(2)->second == 1);
BOOST_CHECK(!call_equals(x, y));
BOOST_CHECK(call_not_equals(x, y));
BOOST_TEST(!call_equals(x, y));
BOOST_TEST(call_not_equals(x, y));
}
UNORDERED_AUTO_TEST(use_multimap_fwd_declared_function) {
int_multimap x, y;
call_swap(x, y);
BOOST_CHECK(call_equals(x, y));
BOOST_CHECK(!call_not_equals(x, y));
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
RUN_TESTS()
+11 -11
View File
@@ -45,17 +45,17 @@ bool call_not_equals(int_multiset& x, int_multiset& y) {
#include "../helpers/test.hpp"
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) {
BOOST_CHECK(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>
UNORDERED_AUTO_TEST(use_fwd_declared_trait) {
boost::unordered_set<int> x;
BOOST_CHECK(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
int dummy;
BOOST_CHECK(sizeof(is_unordered_set_impl(&dummy)) == sizeof(false_type));
BOOST_TEST(sizeof(is_unordered_set_impl(&dummy)) == sizeof(false_type));
}
UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
@@ -64,21 +64,21 @@ UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
y.insert(2);
call_swap(x, y);
BOOST_CHECK(y.find(1) != y.end());
BOOST_CHECK(y.find(2) == y.end());
BOOST_TEST(y.find(1) != y.end());
BOOST_TEST(y.find(2) == y.end());
BOOST_CHECK(x.find(1) == x.end());
BOOST_CHECK(x.find(2) != x.end());
BOOST_TEST(x.find(1) == x.end());
BOOST_TEST(x.find(2) != x.end());
BOOST_CHECK(!call_equals(x, y));
BOOST_CHECK(call_not_equals(x, y));
BOOST_TEST(!call_equals(x, y));
BOOST_TEST(call_not_equals(x, y));
}
UNORDERED_AUTO_TEST(use_multiset_fwd_declared_function) {
int_multiset x, y;
call_swap(x, y);
BOOST_CHECK(call_equals(x, y));
BOOST_CHECK(!call_not_equals(x, y));
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
RUN_TESTS()
+14 -14
View File
@@ -47,13 +47,13 @@ UNORDERED_AUTO_TEST(stable_insert_test1) {
x.insert(insert_stable::member(1,3));
boost::unordered_multiset<insert_stable::member>::const_iterator it = x.begin(), end = x.end();
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 1); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 2); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->tag2_ == 3); ++it; }
BOOST_CHECK(it == end);
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 1); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 2); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 3); ++it; }
BOOST_TEST(it == end);
}
UNORDERED_AUTO_TEST(stable_insert_test2) {
@@ -66,13 +66,13 @@ UNORDERED_AUTO_TEST(stable_insert_test2) {
it = x.begin();
iterator end = x.end();
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 1 && it->second == 1); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 2 && it->second == 2); ++it; }
BOOST_CHECK(it != end);
if(it != end) { BOOST_CHECK(it->first.tag2_ == 3 && it->second == 3); ++it; }
BOOST_CHECK(it == end);
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 1 && it->second == 1); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 2 && it->second == 2); ++it; }
BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 3 && it->second == 3); ++it; }
BOOST_TEST(it == end);
}
RUN_TESTS()
+18 -18
View File
@@ -43,13 +43,13 @@ void unique_insert_tests1(X*, test::random_generator generator = test::default_g
std::pair<iterator, bool> r1 = x.insert(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
BOOST_CHECK(r1.second == r2.second);
BOOST_CHECK(*r1.first == *r2.first);
BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -73,12 +73,12 @@ void equivalent_insert_tests1(X*, test::random_generator generator = test::defau
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -107,11 +107,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
iterator r1 = x.insert(x.begin(), *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -133,11 +133,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
const_iterator r1 = x.insert(x_const.end(), *it);
tracker_iterator r2 = tracker.insert(tracker.end(), *it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -159,11 +159,11 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
pos = x.insert(pos, *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_CHECK(*pos == *r2);
BOOST_TEST(*pos == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -187,7 +187,7 @@ void insert_tests2(X*, test::random_generator generator = test::default_generato
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -243,13 +243,13 @@ void unique_emplace_tests1(X*, test::random_generator generator = test::default_
std::pair<iterator, bool> r1 = x.emplace(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
BOOST_CHECK(r1.second == r2.second);
BOOST_CHECK(*r1.first == *r2.first);
BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -273,12 +273,12 @@ void equivalent_emplace_tests1(X*, test::random_generator generator = test::defa
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
BOOST_CHECK(*r1 == *r2);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
@@ -307,7 +307,7 @@ void map_tests(X*, test::random_generator generator = test::default_generator)
tracker.compare_key(x, *it);
if(x.size() < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
test::check_equivalent_keys(x);
+5 -5
View File
@@ -24,13 +24,13 @@ void set_load_factor_tests(X* = 0)
{
X x;
BOOST_CHECK(x.max_load_factor() == 1.0);
BOOST_CHECK(x.load_factor() == 0);
BOOST_TEST(x.max_load_factor() == 1.0);
BOOST_TEST(x.load_factor() == 0);
// A valid implementation could fail these tests, but I think they're
// reasonable.
x.max_load_factor(2.0); BOOST_CHECK(x.max_load_factor() == 2.0);
x.max_load_factor(0.5); BOOST_CHECK(x.max_load_factor() == 0.5);
x.max_load_factor(2.0); BOOST_TEST(x.max_load_factor() == 2.0);
x.max_load_factor(0.5); BOOST_TEST(x.max_load_factor() == 0.5);
}
template <class X>
@@ -49,7 +49,7 @@ void insert_test(X*, float mlf, test::random_generator generator = test::default
old_bucket_count = x.bucket_count();
x.insert(*it);
if(old_size + 1 < b * old_bucket_count)
BOOST_CHECK(x.bucket_count() == old_bucket_count);
BOOST_TEST(x.bucket_count() == old_bucket_count);
}
}
+24 -24
View File
@@ -52,11 +52,11 @@ namespace move_tests
{
T y(empty(ptr));
BOOST_CHECK(y.empty());
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 1.0);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0);
test::check_equivalent_keys(y);
}
@@ -64,7 +64,7 @@ namespace move_tests
test::random_values<T> v(1000, generator);
test::object_count count;
T y(create(v, count));
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
test::check_equivalent_keys(y);
}
@@ -78,7 +78,7 @@ namespace move_tests
test::object_count count;
T y;
y = create(v, count);
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
test::check_equivalent_keys(y);
}
@@ -98,12 +98,12 @@ namespace move_tests
{
test::random_values<T> v(500, generator);
T y(create(v, count, hf, eq, al, 0.5));
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 0.5); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
test::check_equivalent_keys(y);
}
@@ -111,12 +111,12 @@ namespace move_tests
// 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_CHECK(count != test::global_object_count);
BOOST_TEST(count != test::global_object_count);
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al2));
BOOST_CHECK(y.max_load_factor() == 2.0); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
@@ -124,17 +124,17 @@ 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)
BOOST_CHECK(count == test::global_object_count);
BOOST_TEST(count == test::global_object_count);
#else
BOOST_CHECK(test::global_object_count.constructions - count.constructions <=
BOOST_TEST(test::global_object_count.constructions - count.constructions <=
(test::is_map<T>::value ? 50 : 25));
BOOST_CHECK(count.instances == test::global_object_count.instances);
BOOST_TEST(count.instances == test::global_object_count.instances);
#endif
test::check_container(y, v);
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
BOOST_CHECK(test::equivalent(y.get_allocator(), al));
BOOST_CHECK(y.max_load_factor() == 1.0); // Not necessarily required.
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
}
+6 -6
View File
@@ -26,10 +26,10 @@ void rehash_empty_test1(X* = 0)
X x;
x.rehash(10000);
BOOST_CHECK(postcondition(x, 10000));
BOOST_TEST(postcondition(x, 10000));
x.rehash(0);
BOOST_CHECK(postcondition(x, 0));
BOOST_TEST(postcondition(x, 0));
}
template <class X>
@@ -40,18 +40,18 @@ void rehash_test1(X* = 0, test::random_generator generator = test::default_gener
tracker.insert_range(v.begin(), v.end());
X x(v.begin(), v.end());
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.max_load_factor(0.25);
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.max_load_factor(50.0);
x.rehash(0); BOOST_CHECK(postcondition(x, 0));
x.rehash(0); BOOST_TEST(postcondition(x, 0));
tracker.compare(x);
x.rehash(1000); BOOST_CHECK(postcondition(x, 1000));
x.rehash(1000); BOOST_TEST(postcondition(x, 1000));
tracker.compare(x);
}
+23 -23
View File
@@ -19,67 +19,67 @@ void simple_test(X const& a)
{
X u;
BOOST_CHECK(u.size() == 0);
BOOST_CHECK(X().size() == 0);
BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0);
}
{
BOOST_CHECK(equivalent(X(a)));
BOOST_TEST(equivalent(X(a)));
}
{
X u(a);
BOOST_CHECK(equivalent(u));
BOOST_TEST(equivalent(u));
}
{
X u = a;
BOOST_CHECK(equivalent(u));
BOOST_TEST(equivalent(u));
}
{
X b(a);
BOOST_CHECK(b.begin() == const_cast<X const&>(b).cbegin());
BOOST_CHECK(b.end() == const_cast<X const&>(b).cend());
BOOST_TEST(b.begin() == const_cast<X const&>(b).cbegin());
BOOST_TEST(b.end() == const_cast<X const&>(b).cend());
}
{
X b(a);
X c;
BOOST_CHECK(equivalent(b));
BOOST_CHECK(c.empty());
BOOST_TEST(equivalent(b));
BOOST_TEST(c.empty());
b.swap(c);
BOOST_CHECK(b.empty());
BOOST_CHECK(equivalent(c));
BOOST_TEST(b.empty());
BOOST_TEST(equivalent(c));
b.swap(c);
BOOST_CHECK(c.empty());
BOOST_CHECK(equivalent(b));
BOOST_TEST(c.empty());
BOOST_TEST(equivalent(b));
}
{
X u;
X& r = u;
BOOST_CHECK(&(r = r) == &r);
BOOST_CHECK(r.empty());
BOOST_CHECK(&(r = a) == &r);
BOOST_CHECK(equivalent(r));
BOOST_CHECK(&(r = r) == &r);
BOOST_CHECK(equivalent(r));
BOOST_TEST(&(r = r) == &r);
BOOST_TEST(r.empty());
BOOST_TEST(&(r = a) == &r);
BOOST_TEST(equivalent(r));
BOOST_TEST(&(r = r) == &r);
BOOST_TEST(equivalent(r));
}
{
BOOST_CHECK(a.size() ==
BOOST_TEST(a.size() ==
(BOOST_DEDUCED_TYPENAME X::size_type) std::distance(a.begin(), a.end()));
}
{
BOOST_CHECK(a.empty() == (a.size() == 0));
BOOST_TEST(a.empty() == (a.size() == 0));
}
{
BOOST_CHECK(a.empty() == (a.begin() == a.end()));
BOOST_TEST(a.empty() == (a.begin() == a.end()));
X u;
BOOST_CHECK(u.begin() == u.end());
BOOST_TEST(u.begin() == u.end());
}
}
+42 -22
View File
@@ -68,12 +68,22 @@ 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<<std::endl; \
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<<std::endl; \
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 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
@@ -99,7 +109,6 @@ namespace unnecessary_copy_tests
UNORDERED_TEST(unnecessary_copy_insert_test,
((set)(multiset)(map)(multimap)))
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
template <class T>
void unnecessary_copy_emplace_test(T*)
{
@@ -117,9 +126,19 @@ 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)
COPY_COUNT(1);
#else
COPY_COUNT(2);
#endif
}
UNORDERED_TEST(unnecessary_copy_emplace_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
((set)(multiset)(map)(multimap)))
#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
template <class T>
void unnecessary_copy_emplace_move_test(T*)
{
@@ -131,13 +150,11 @@ namespace unnecessary_copy_tests
COPY_COUNT(1); MOVE_COUNT(1);
}
UNORDERED_TEST(unnecessary_copy_emplace_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
((set)(multiset)(map)(multimap)))
UNORDERED_TEST(unnecessary_copy_emplace_move_test,
((set)(multiset)(map)(multimap)))
#endif
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
{
reset();
@@ -172,10 +189,12 @@ namespace unnecessary_copy_tests
x.emplace(source<count_copies>());
COPY_COUNT(1); MOVE_COUNT(0);
#if defined(BOOST_HAS_RVALUE_REFS)
// No move should take place.
reset();
x.emplace(std::move(a));
COPY_COUNT(0); MOVE_COUNT(0);
#endif
// Just in case a did get moved...
count_copies b;
@@ -192,8 +211,12 @@ namespace unnecessary_copy_tests
// The container will have to create b copy in order to compare with
// the existing element.
//
// Note to self: If copy_count == 0 it's an error not an optimization.
// TODO: Devise a better test.
reset();
x.emplace(b, b);
COPY_COUNT(1); MOVE_COUNT(0);
}
@@ -230,24 +253,22 @@ namespace unnecessary_copy_tests
x.emplace(source<std::pair<count_copies, count_copies> >());
COPY_COUNT(2); MOVE_COUNT(0);
count_copies part;
reset();
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
x.emplace(a_ref);
COPY_COUNT(0); MOVE_COUNT(0);
// TODO: This doesn't work on older versions of gcc.
//count_copies part;
std::pair<count_copies const, count_copies> b;
//reset();
//std::pair<count_copies const&, count_copies const&> a_ref(part, part);
//x.emplace(a_ref);
//COPY_COUNT(0); MOVE_COUNT(0);
#if defined(BOOST_HAS_RVALUE_REFS)
// No move should take place.
// (since a is already in the container)
reset();
x.emplace(std::move(a));
COPY_COUNT(0); MOVE_COUNT(0);
#endif
// Just in case a did get moved
std::pair<count_copies const, count_copies> b;
// This test requires a C++0x std::pair. Which gcc hasn't got yet.
//reset();
//x.emplace(b.first.tag_);
//COPY_COUNT(2); MOVE_COUNT(0);
//
// 2 arguments
@@ -267,10 +288,9 @@ namespace unnecessary_copy_tests
COPY_COUNT(1); MOVE_COUNT(0);
reset();
x.emplace(b.first.tag_, b.second.tag_);
COPY_COUNT(2); MOVE_COUNT(0);
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
COPY_COUNT(2); MOVE_COUNT(0);
}
#endif
}
RUN_TESTS()