forked from boostorg/unordered
Merge branch 'develop'
This commit is contained in:
32
.travis.yml
32
.travis.yml
@ -11,8 +11,9 @@ language: c++
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libboost-dev
|
||||
- libboost-tools-dev
|
||||
- libxml2-utils
|
||||
- g++-multilib
|
||||
|
||||
matrix:
|
||||
include:
|
||||
@ -20,19 +21,40 @@ matrix:
|
||||
env: BJAM_TOOLSET=gcc
|
||||
- compiler: gcc
|
||||
env: BJAM_TOOLSET=gcc-std11
|
||||
- compiler: clang
|
||||
env: BJAM_TOOLSET=clang
|
||||
#- compiler: gcc
|
||||
# env: BJAM_TOOLSET=gcc-m32
|
||||
- compiler: gcc
|
||||
env: BJAM_TOOLSET=gcc-std11m32
|
||||
#- compiler: clang
|
||||
# env: BJAM_TOOLSET=clang
|
||||
- compiler: clang
|
||||
env: BJAM_TOOLSET=clang-std11
|
||||
- compiler: clang
|
||||
env: BJAM_TOOLSET=clang-m32
|
||||
#- compiler: clang
|
||||
# env: BJAM_TOOLSET=clang-std11m32
|
||||
|
||||
before_script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- touch Jamroot.jam
|
||||
- cd $HOME
|
||||
- |
|
||||
echo "using gcc : : g++-4.8 -Werror --std=c++03 -fsanitize=address ;" > ~/user-config.jam
|
||||
echo "using gcc : std11 : g++-4.8 -Werror --std=c++11 -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using gcc : m32 : g++-4.8 -m32 -Werror -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using gcc : std11m32 : g++-4.8 -m32 -Werror --std=c++11 -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using clang : : clang++ -Werror --std=c++03 -fsanitize=address ;" >> ~/user-config.jam
|
||||
echo "using clang : std11 : clang++ -Werror --std=c++11 -fsanitize=address ;" >> ~/user-config.jam
|
||||
# sanitized=address not available for 32-bit clang on travis.
|
||||
echo "using clang : m32 : clang++ -m32 -Werror --std=c++03 ;" >> ~/user-config.jam
|
||||
echo "using clang : std11m32 : clang++ -m32 -Werror --std=c++11 ;" >> ~/user-config.jam
|
||||
- cat ~/user-config.jam
|
||||
- touch Jamroot.jam
|
||||
- wget -O boost.tar.bz2 https://sourceforge.net/projects/boost/files/boost/snapshots/master/boost_1_62_0.tar.bz2/download
|
||||
- tar -xjf boost.tar.bz2
|
||||
- mv boost_1_62_0 boost
|
||||
- rm -r boost/boost/unordered
|
||||
|
||||
script:
|
||||
- cd test && bjam ${BJAM_TOOLSET} include=${TRAVIS_BUILD_DIR}/include
|
||||
- cd ${TRAVIS_BUILD_DIR}/test
|
||||
- bjam ${BJAM_TOOLSET} include=${HOME}/boost include=${TRAVIS_BUILD_DIR}/include
|
||||
- xmllint --noout ${TRAVIS_BUILD_DIR}/doc/ref.xml
|
||||
|
@ -279,4 +279,19 @@ C++11 support has resulted in some breaking changes:
|
||||
* Stop using return value SFINAE which some older compilers have issues
|
||||
with.
|
||||
|
||||
[h2 Boost 1.63.0]
|
||||
|
||||
* Check hint iterator in `insert`/`emplace_hint`.
|
||||
* Fix some warnings, mostly in the tests.
|
||||
* Manually write out `emplace_args` for small numbers of arguments -
|
||||
should make template error messages a little more bearable.
|
||||
* Remove superfluous use of `boost::forward` in emplace arguments,
|
||||
which fixes emplacing string literals in old versions of Visual C++.
|
||||
* Fix an exception safety issue in assignment. If bucket allocation
|
||||
throws an exception, it can overwrite the hash and equality functions while
|
||||
leaving the existing elements in place. This would mean that the function
|
||||
objects wouldn't match the container elements, so elements might be in the
|
||||
wrong bucket and equivalent elements would be incorrectly handled.
|
||||
* Various reference documentation improvements.
|
||||
|
||||
[endsect]
|
||||
|
45
doc/ref.php
45
doc/ref.php
@ -358,6 +358,21 @@ EOL;
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="operator=">
|
||||
<parameter>
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type><?php echo $name; ?>&</type>
|
||||
<description>
|
||||
<para>Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed.</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para>
|
||||
<code>value_type</code> is <code>CopyInsertable</code> into the container and
|
||||
<code>CopyAssignable</code>.
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="get_allocator" cv="const">
|
||||
<type>allocator_type</type>
|
||||
</method>
|
||||
@ -640,7 +655,35 @@ EOL;
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent <?php echo $key_name; ?>.</para>
|
||||
<para>Inserts a range of elements into the container.
|
||||
<?php if (!$equivalent_keys): ?>
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent <?php echo $key_name; ?>.
|
||||
<?php endif; ?>
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>X</code> from <code>*first</code>.</para>
|
||||
</requires>
|
||||
<throws>
|
||||
<para>When inserting a single element, if an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
</throws>
|
||||
<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>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
<parameter name="il">
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container.
|
||||
<?php if (!$equivalent_keys): ?>
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent <?php echo $key_name; ?>.
|
||||
<?php endif; ?>
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
|
160
doc/ref.xml
160
doc/ref.xml
@ -299,6 +299,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="operator=">
|
||||
<parameter>
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>unordered_set&</type>
|
||||
<description>
|
||||
<para>Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed.</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para>
|
||||
<code>value_type</code> is <code>CopyInsertable</code> into the container and
|
||||
<code>CopyAssignable</code>.
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="get_allocator" cv="const">
|
||||
<type>allocator_type</type>
|
||||
</method>
|
||||
@ -537,7 +552,31 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent value.</para>
|
||||
<para>Inserts a range of elements into the container.
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent value.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>X</code> from <code>*first</code>.</para>
|
||||
</requires>
|
||||
<throws>
|
||||
<para>When inserting a single element, if an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
</throws>
|
||||
<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>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
<parameter name="il">
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container.
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent value.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
@ -1334,6 +1373,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="operator=">
|
||||
<parameter>
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>unordered_multiset&</type>
|
||||
<description>
|
||||
<para>Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed.</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para>
|
||||
<code>value_type</code> is <code>CopyInsertable</code> into the container and
|
||||
<code>CopyAssignable</code>.
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="get_allocator" cv="const">
|
||||
<type>allocator_type</type>
|
||||
</method>
|
||||
@ -1569,7 +1623,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent value.</para>
|
||||
<para>Inserts a range of elements into the container.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>X</code> from <code>*first</code>.</para>
|
||||
</requires>
|
||||
<throws>
|
||||
<para>When inserting a single element, if an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
</throws>
|
||||
<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>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
<parameter name="il">
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
@ -2380,6 +2456,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="operator=">
|
||||
<parameter>
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>unordered_map&</type>
|
||||
<description>
|
||||
<para>Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed.</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para>
|
||||
<code>value_type</code> is <code>CopyInsertable</code> into the container and
|
||||
<code>CopyAssignable</code>.
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="get_allocator" cv="const">
|
||||
<type>allocator_type</type>
|
||||
</method>
|
||||
@ -2618,7 +2709,31 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key.</para>
|
||||
<para>Inserts a range of elements into the container.
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent key.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>X</code> from <code>*first</code>.</para>
|
||||
</requires>
|
||||
<throws>
|
||||
<para>When inserting a single element, if an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
</throws>
|
||||
<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>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
<parameter name="il">
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container.
|
||||
Elements are inserted if and only if there is no element in the container with an equivalent key.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
@ -3462,6 +3577,21 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="operator=">
|
||||
<parameter>
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>unordered_multimap&</type>
|
||||
<description>
|
||||
<para>Assign from values in initializer list. All existing elements are either overwritten by the new elements or destroyed.</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para>
|
||||
<code>value_type</code> is <code>CopyInsertable</code> into the container and
|
||||
<code>CopyAssignable</code>.
|
||||
</para>
|
||||
</requires>
|
||||
</method>
|
||||
<method name="get_allocator" cv="const">
|
||||
<type>allocator_type</type>
|
||||
</method>
|
||||
@ -3697,7 +3827,29 @@ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container. Elements are inserted if and only if there is no element in the container with an equivalent key.</para>
|
||||
<para>Inserts a range of elements into the container.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
<code>X</code> from <code>*first</code>.</para>
|
||||
</requires>
|
||||
<throws>
|
||||
<para>When inserting a single element, if an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
|
||||
</throws>
|
||||
<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>
|
||||
</notes>
|
||||
</method>
|
||||
<method name="insert">
|
||||
<parameter name="il">
|
||||
<paramtype>initializer_list<value_type></paramtype>
|
||||
</parameter>
|
||||
<type>void</type>
|
||||
<description>
|
||||
<para>Inserts a range of elements into the container.
|
||||
</para>
|
||||
</description>
|
||||
<requires>
|
||||
<para><code>value_type</code> is <code>EmplaceConstructible</code> into
|
||||
|
@ -96,26 +96,102 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename... Args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS BOOST_FWD_REF(Args)... args
|
||||
#define BOOST_UNORDERED_EMPLACE_FORWARD boost::forward<Args>(args)...
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS1(a0) a0
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS2(a0, a1) a0, a1
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS3(a0, a1, a2) a0, a1, a2
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename... Args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS BOOST_FWD_REF(Args)... args
|
||||
#define BOOST_UNORDERED_EMPLACE_FORWARD boost::forward<Args>(args)...
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS1 create_emplace_args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS2 create_emplace_args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS3 create_emplace_args
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_TEMPLATE typename Args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS Args const& args
|
||||
#define BOOST_UNORDERED_EMPLACE_FORWARD args
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \
|
||||
typedef BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(Arg, n); \
|
||||
BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \
|
||||
typedef typename boost::add_lvalue_reference<BOOST_PP_CAT(A, n)>::type \
|
||||
BOOST_PP_CAT(Arg, n); \
|
||||
BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
|
||||
|
||||
#endif
|
||||
|
||||
template <typename A0>
|
||||
struct emplace_args1
|
||||
{
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
|
||||
|
||||
emplace_args1(Arg0 b0) : a0(b0) {}
|
||||
};
|
||||
|
||||
template <typename A0>
|
||||
inline emplace_args1<A0> create_emplace_args(
|
||||
BOOST_FWD_REF(A0) b0)
|
||||
{
|
||||
emplace_args1<A0> e(b0);
|
||||
return e;
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
struct emplace_args2
|
||||
{
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 1, _)
|
||||
|
||||
emplace_args2(Arg0 b0, Arg1 b1) : a0(b0), a1(b1) {}
|
||||
};
|
||||
|
||||
template <typename A0, typename A1>
|
||||
inline emplace_args2<A0, A1> create_emplace_args(
|
||||
BOOST_FWD_REF(A0) b0,
|
||||
BOOST_FWD_REF(A1) b1)
|
||||
{
|
||||
emplace_args2<A0, A1> e(b0, b1);
|
||||
return e;
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
struct emplace_args3
|
||||
{
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 0, _)
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 1, _)
|
||||
BOOST_UNORDERED_EARGS_MEMBER(1, 2, _)
|
||||
|
||||
emplace_args3(Arg0 b0, Arg1 b1, Arg2 b2) : a0(b0), a1(b1), a2(b2) {}
|
||||
};
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
inline emplace_args3<A0, A1, A2> create_emplace_args(
|
||||
BOOST_FWD_REF(A0) b0,
|
||||
BOOST_FWD_REF(A1) b1,
|
||||
BOOST_FWD_REF(A2) b2)
|
||||
{
|
||||
emplace_args3<A0, A1, A2> e(b0, b1, b2);
|
||||
return e;
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_FWD_PARAM(z, n, a) \
|
||||
BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(a, n)
|
||||
|
||||
#define BOOST_UNORDERED_CALL_FORWARD(z, i, a) \
|
||||
boost::forward<BOOST_PP_CAT(A,i)>(BOOST_PP_CAT(a,i))
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_INIT(z, n, _) \
|
||||
BOOST_PP_CAT(a, n)(BOOST_PP_CAT(b, n))
|
||||
|
||||
#define BOOST_UNORDERED_EARGS(z, n, _) \
|
||||
template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
|
||||
struct BOOST_PP_CAT(emplace_args, n) \
|
||||
@ -141,33 +217,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return e; \
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS1 create_emplace_args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS2 create_emplace_args
|
||||
#define BOOST_UNORDERED_EMPLACE_ARGS3 create_emplace_args
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \
|
||||
typedef BOOST_FWD_REF(BOOST_PP_CAT(A, n)) BOOST_PP_CAT(Arg, n); \
|
||||
BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_INIT(z, n, _) \
|
||||
BOOST_PP_CAT(a, n)( \
|
||||
boost::forward<BOOST_PP_CAT(A,n)>(BOOST_PP_CAT(b, n)))
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_MEMBER(z, n, _) \
|
||||
typedef typename boost::add_lvalue_reference<BOOST_PP_CAT(A, n)>::type \
|
||||
BOOST_PP_CAT(Arg, n); \
|
||||
BOOST_PP_CAT(Arg, n) BOOST_PP_CAT(a, n);
|
||||
|
||||
#define BOOST_UNORDERED_EARGS_INIT(z, n, _) \
|
||||
BOOST_PP_CAT(a, n)(BOOST_PP_CAT(b, n))
|
||||
|
||||
#endif
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EARGS,
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EARGS,
|
||||
_)
|
||||
|
||||
#undef BOOST_UNORDERED_DEFINE_EMPLACE_ARGS
|
||||
|
@ -583,12 +583,12 @@ namespace boost { namespace unordered { namespace detail {
|
||||
// TODO: Maybe not if std::size_t is smaller than long long.
|
||||
#if !defined(BOOST_NO_LONG_LONG)
|
||||
template <>
|
||||
struct pick_policy<long long> {
|
||||
struct pick_policy<boost::long_long_type> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct pick_policy<unsigned long long> {
|
||||
struct pick_policy<boost::ulong_long_type> {
|
||||
typedef prime_policy<std::size_t> type;
|
||||
};
|
||||
#endif
|
||||
|
@ -321,7 +321,10 @@ namespace boost { namespace unordered { namespace detail {
|
||||
|
||||
// Emplace/Insert
|
||||
|
||||
static inline void add_after_node(
|
||||
// Add node 'n' to the group containing 'pos'.
|
||||
// If 'pos' is the first node in group, add to the end of the group,
|
||||
// otherwise add before 'pos'.
|
||||
static inline void add_to_node_group(
|
||||
node_pointer n,
|
||||
node_pointer pos)
|
||||
{
|
||||
@ -338,7 +341,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
n->hash_ = key_hash;
|
||||
if (pos.node_) {
|
||||
this->add_after_node(n, pos.node_);
|
||||
this->add_to_node_group(n, pos.node_);
|
||||
if (n->next_) {
|
||||
std::size_t next_bucket = this->hash_to_bucket(
|
||||
static_cast<node_pointer>(n->next_)->hash_);
|
||||
@ -375,24 +378,23 @@ namespace boost { namespace unordered { namespace detail {
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
iterator emplace_impl(node_pointer n)
|
||||
inline iterator add_using_hint(
|
||||
node_pointer n,
|
||||
node_pointer hint)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
n->hash_ = hint->hash_;
|
||||
this->add_to_node_group(n, hint);
|
||||
if (n->next_ != hint && n->next_) {
|
||||
std::size_t next_bucket = this->hash_to_bucket(
|
||||
static_cast<node_pointer>(n->next_)->hash_);
|
||||
if (next_bucket != this->hash_to_bucket(n->hash_)) {
|
||||
this->get_bucket(next_bucket)->next_ = n;
|
||||
}
|
||||
}
|
||||
++this->size_;
|
||||
return iterator(n);
|
||||
}
|
||||
|
||||
void emplace_impl_no_rehash(node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
# if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@ -402,6 +404,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return iterator();
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator, boost::unordered::detail::emplace_args1<
|
||||
boost::unordered::detail::please_ignore_this_overload> const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return iterator();
|
||||
}
|
||||
# else
|
||||
iterator emplace(
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
@ -409,6 +418,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return iterator();
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator,
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return iterator();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -420,6 +436,49 @@ namespace boost { namespace unordered { namespace detail {
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace_hint(c_iterator hint, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
return iterator(emplace_hint_impl(hint,
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD)));
|
||||
}
|
||||
|
||||
iterator emplace_impl(node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
iterator emplace_hint_impl(c_iterator hint, node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_using_hint(a.release(), hint.node_);
|
||||
}
|
||||
else {
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->reserve_for_insert(this->size_ + 1);
|
||||
return this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
}
|
||||
|
||||
void emplace_impl_no_rehash(node_pointer n)
|
||||
{
|
||||
node_tmp a(n, this->node_alloc());
|
||||
key_type const& k = this->get_key(a.node_->value());
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator position = this->find_node(key_hash, k);
|
||||
this->add_node(a.release(), key_hash, position);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Insert range methods
|
||||
|
||||
@ -431,7 +490,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
if(i == j) return;
|
||||
|
||||
std::size_t distance = std::distance(i, j);
|
||||
std::size_t distance = static_cast<std::size_t>(std::distance(i, j));
|
||||
if(distance == 1) {
|
||||
emplace_impl(
|
||||
boost::unordered::detail::func::construct_value(
|
||||
|
@ -51,7 +51,7 @@ namespace detail {
|
||||
typedef ValueType value_type;
|
||||
typedef ValueType key_type;
|
||||
|
||||
static key_type const& extract(key_type const& v)
|
||||
static key_type const& extract(value_type const& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2008-2016 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
@ -11,12 +11,46 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
|
||||
// Already defined.
|
||||
#elif defined(BOOST_LIBSTDCXX11)
|
||||
// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70
|
||||
# if BOOST_LIBSTDCXX_VERSION > 40600
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206
|
||||
# if LIBCPP_VERSION >= 3000
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#elif defined(BOOST_MSVC)
|
||||
// Apparently C++11 standard supported in Visual Studio 2012
|
||||
// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl
|
||||
// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully!
|
||||
# if BOOST_MSVC >= 1700
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 0
|
||||
#endif
|
||||
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace unordered
|
||||
{
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
using std::piecewise_construct_t;
|
||||
using std::piecewise_construct;
|
||||
#else
|
||||
struct piecewise_construct_t {};
|
||||
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,7 +584,6 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
// Strong exception safety.
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
new_func_this.commit();
|
||||
mlf_ = x.mlf_;
|
||||
recalculate_max_load();
|
||||
|
||||
@ -597,6 +596,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
clear_buckets();
|
||||
}
|
||||
|
||||
new_func_this.commit();
|
||||
static_cast<table_impl*>(this)->assign_buckets(x);
|
||||
}
|
||||
|
||||
@ -663,11 +663,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
else {
|
||||
set_hash_functions new_func_this(*this, x);
|
||||
new_func_this.commit();
|
||||
mlf_ = x.mlf_;
|
||||
recalculate_max_load();
|
||||
|
||||
if (!size_ && !x.size_) return;
|
||||
if (!size_ && !x.size_) {
|
||||
new_func_this.commit();
|
||||
return;
|
||||
}
|
||||
|
||||
if (x.size_ >= max_load_) {
|
||||
create_buckets(min_buckets_for_size(x.size_));
|
||||
@ -676,6 +678,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
clear_buckets();
|
||||
}
|
||||
|
||||
new_func_this.commit();
|
||||
static_cast<table_impl*>(this)->move_assign_buckets(x);
|
||||
}
|
||||
}
|
||||
|
@ -316,6 +316,14 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return emplace_return(this->begin(), false);
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator,
|
||||
boost::unordered::detail::emplace_args1<
|
||||
boost::unordered::detail::please_ignore_this_overload> const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return this->begin();
|
||||
}
|
||||
# else
|
||||
emplace_return emplace(
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
@ -323,6 +331,13 @@ namespace boost { namespace unordered { namespace detail {
|
||||
BOOST_ASSERT(false);
|
||||
return emplace_return(this->begin(), false);
|
||||
}
|
||||
|
||||
iterator emplace_hint(c_iterator,
|
||||
boost::unordered::detail::please_ignore_this_overload const&)
|
||||
{
|
||||
BOOST_ASSERT(false);
|
||||
return this->begin();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -340,6 +355,21 @@ namespace boost { namespace unordered { namespace detail {
|
||||
#endif
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace_hint(c_iterator hint,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
return emplace_hint_impl(hint,
|
||||
extractor::extract(BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
#else
|
||||
return emplace_hint_impl(hint,
|
||||
extractor::extract(args.a0, args.a1),
|
||||
BOOST_UNORDERED_EMPLACE_FORWARD);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <typename A0>
|
||||
emplace_return emplace(
|
||||
@ -347,8 +377,27 @@ namespace boost { namespace unordered { namespace detail {
|
||||
{
|
||||
return emplace_impl(extractor::extract(args.a0), args);
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(c_iterator hint,
|
||||
boost::unordered::detail::emplace_args1<A0> const& args)
|
||||
{
|
||||
return emplace_hint_impl(hint, extractor::extract(args.a0), args);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace_hint_impl(c_iterator hint, key_type const& k,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
return iterator(hint.node_);
|
||||
}
|
||||
else {
|
||||
return emplace_impl(k, BOOST_UNORDERED_EMPLACE_FORWARD).first;
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
emplace_return emplace_impl(key_type const& k,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
@ -368,11 +417,31 @@ namespace boost { namespace unordered { namespace detail {
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
iterator emplace_hint_impl(c_iterator hint, no_key,
|
||||
BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
this->node_alloc());
|
||||
key_type const& k = this->get_key(b.node_->value());
|
||||
if (hint.node_ && this->key_eq()(k, this->get_key(*hint))) {
|
||||
return iterator(hint.node_);
|
||||
}
|
||||
std::size_t key_hash = this->hash(k);
|
||||
iterator pos = this->find_node(key_hash, k);
|
||||
if (pos.node_) {
|
||||
return pos;
|
||||
}
|
||||
else {
|
||||
return this->resize_and_add_node(b.release(), key_hash);
|
||||
}
|
||||
}
|
||||
|
||||
template <BOOST_UNORDERED_EMPLACE_TEMPLATE>
|
||||
emplace_return emplace_impl(no_key, BOOST_UNORDERED_EMPLACE_ARGS)
|
||||
{
|
||||
// Don't have a key, so construct the node first in order
|
||||
// to be able to lookup the position.
|
||||
node_tmp b(
|
||||
boost::unordered::detail::func::construct_value_generic(
|
||||
this->node_alloc(), BOOST_UNORDERED_EMPLACE_FORWARD),
|
||||
|
@ -128,7 +128,7 @@ namespace boost { namespace unordered { namespace detail {
|
||||
inline std::size_t insert_size(I i, I j, typename
|
||||
boost::unordered::detail::enable_if_forward<I, void*>::type = 0)
|
||||
{
|
||||
return std::distance(i, j);
|
||||
return static_cast<std::size_t>(std::distance(i, j));
|
||||
}
|
||||
|
||||
template <class I>
|
||||
|
@ -240,9 +240,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...).first;
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@ -281,12 +281,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
@ -302,15 +302,15 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
@ -328,17 +328,17 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
@ -360,15 +360,15 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
)).first; \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
@ -724,9 +724,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...);
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@ -765,9 +765,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
);
|
||||
@ -786,11 +786,11 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
@ -812,12 +812,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
@ -844,11 +844,11 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
|
@ -237,9 +237,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...).first;
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@ -278,12 +278,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
@ -299,15 +299,15 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
@ -325,17 +325,17 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
boost::forward<A2>(a2))
|
||||
).first;
|
||||
);
|
||||
}
|
||||
|
||||
#define BOOST_UNORDERED_EMPLACE(z, n, _) \
|
||||
@ -357,15 +357,15 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
)).first; \
|
||||
)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||
@ -707,9 +707,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
return table_.emplace(boost::forward<Args>(args)...);
|
||||
return table_.emplace_hint(hint, boost::forward<Args>(args)...);
|
||||
}
|
||||
#else
|
||||
|
||||
@ -748,9 +748,9 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0>
|
||||
iterator emplace_hint(const_iterator, BOOST_FWD_REF(A0) a0)
|
||||
iterator emplace_hint(const_iterator hint, BOOST_FWD_REF(A0) a0)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0))
|
||||
);
|
||||
@ -769,11 +769,11 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1))
|
||||
@ -795,12 +795,12 @@ namespace unordered
|
||||
}
|
||||
|
||||
template <typename A0, typename A1, typename A2>
|
||||
iterator emplace_hint(const_iterator,
|
||||
iterator emplace_hint(const_iterator hint,
|
||||
BOOST_FWD_REF(A0) a0,
|
||||
BOOST_FWD_REF(A1) a1,
|
||||
BOOST_FWD_REF(A2) a2)
|
||||
{
|
||||
return table_.emplace(
|
||||
return table_.emplace_hint(hint,
|
||||
boost::unordered::detail::create_emplace_args(
|
||||
boost::forward<A0>(a0),
|
||||
boost::forward<A1>(a1),
|
||||
@ -827,11 +827,11 @@ namespace unordered
|
||||
BOOST_PP_ENUM_PARAMS_Z(z, n, typename A) \
|
||||
> \
|
||||
iterator emplace_hint( \
|
||||
const_iterator, \
|
||||
const_iterator hint, \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_FWD_PARAM, a) \
|
||||
) \
|
||||
{ \
|
||||
return table_.emplace( \
|
||||
return table_.emplace_hint(hint, \
|
||||
boost::unordered::detail::create_emplace_args( \
|
||||
BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_CALL_FORWARD, \
|
||||
a) \
|
||||
|
@ -11,9 +11,9 @@ project unordered-test/unordered
|
||||
<toolset>intel:<warnings>on
|
||||
# Would be nice to define -Wundef, but I'm getting warnings from
|
||||
# Boost.Preprocessor on trunk.
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow -Wno-long-long"
|
||||
<toolset>gcc:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
<toolset>darwin:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wconversion -Wfloat-equal -Wshadow"
|
||||
<toolset>clang:<cxxflags>"-pedantic -Wextra -Wno-long-long"
|
||||
<toolset>clang:<cxxflags>"-pedantic -Wstrict-aliasing -fstrict-aliasing -Wextra -Wsign-promo -Wunused-parameter -Wsign-conversion -Wconversion -Wfloat-equal -Wshadow"
|
||||
;
|
||||
|
||||
#alias framework : /boost/test//boost_unit_test_framework ;
|
||||
@ -38,6 +38,7 @@ test-suite unordered
|
||||
[ run unordered/assign_tests.cpp ]
|
||||
[ run unordered/insert_tests.cpp ]
|
||||
[ run unordered/insert_stable_tests.cpp ]
|
||||
[ run unordered/insert_hint_tests.cpp ]
|
||||
[ run unordered/unnecessary_copy_tests.cpp ]
|
||||
[ run unordered/erase_tests.cpp ]
|
||||
[ run unordered/erase_equiv_tests.cpp ]
|
||||
@ -71,6 +72,7 @@ test-suite unordered-exception
|
||||
[ run exception/constructor_exception_tests.cpp framework ]
|
||||
[ run exception/copy_exception_tests.cpp framework ]
|
||||
[ run exception/assign_exception_tests.cpp framework ]
|
||||
[ run exception/move_assign_exception_tests.cpp framework ]
|
||||
[ run exception/insert_exception_tests.cpp framework ]
|
||||
[ run exception/erase_exception_tests.cpp framework ]
|
||||
[ run exception/rehash_exception_tests.cpp framework ]
|
||||
|
@ -17,7 +17,7 @@ template <class T>
|
||||
struct self_assign_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_assign_base(int count = 0) : values(count) {}
|
||||
self_assign_base(std::size_t count = 0) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
@ -111,6 +111,12 @@ struct assign_test4 : assign_values<T>
|
||||
assign_test4() : assign_values<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test4a : assign_values<T>
|
||||
{
|
||||
assign_test4a() : assign_values<T>(10, 100, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test5 : assign_values<T>
|
||||
{
|
||||
@ -136,7 +142,7 @@ struct equivalent_test1 : assign_base<T>
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(self_assign_test1)(self_assign_test2)
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test5)
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test4a)(assign_test5)
|
||||
(equivalent_test1),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include <boost/utility.hpp>
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include <cmath>
|
||||
|
||||
test::seed_t initialize_seed(747373);
|
||||
@ -17,7 +17,7 @@ template <class T>
|
||||
struct insert_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
insert_test_base(unsigned int count = 5) : values(count) {}
|
||||
insert_test_base(unsigned int count = 5) : values(count, test::limited_range) {}
|
||||
|
||||
typedef T data_type;
|
||||
typedef test::strong<T> strong_type;
|
||||
@ -112,7 +112,7 @@ struct insert_test4 : public insert_test_base<T>
|
||||
it != end; ++it)
|
||||
{
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(it, boost::next(it));
|
||||
x.insert(it, test::next(it));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -130,12 +130,13 @@ struct insert_test_rehash1 : public insert_test_base<T>
|
||||
|
||||
T x;
|
||||
x.max_load_factor(0.25);
|
||||
// TODO: This doesn't really work is bucket_count is 0
|
||||
size_type bucket_count = x.bucket_count();
|
||||
size_type initial_elements = static_cast<size_type>(
|
||||
ceil(bucket_count * (double) x.max_load_factor()) - 1);
|
||||
ceil((double) bucket_count * (double) x.max_load_factor()) - 1);
|
||||
BOOST_TEST(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
boost::next(this->values.begin(), initial_elements));
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
BOOST_TEST(bucket_count == x.bucket_count());
|
||||
return x;
|
||||
}
|
||||
@ -146,7 +147,7 @@ struct insert_test_rehash1 : public insert_test_base<T>
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()),
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
@ -170,7 +171,7 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
int count = 0;
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = boost::next(this->values.begin(), x.size()),
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
@ -201,14 +202,14 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
|
||||
original_bucket_count = x.bucket_count();
|
||||
rehash_bucket_count = static_cast<size_type>(
|
||||
ceil(original_bucket_count * (double) x.max_load_factor())) - 1;
|
||||
ceil((double) original_bucket_count * (double) x.max_load_factor())) - 1;
|
||||
|
||||
size_type initial_elements =
|
||||
rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
|
||||
|
||||
BOOST_TEST(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
boost::next(this->values.begin(), initial_elements));
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
BOOST_TEST(original_bucket_count == x.bucket_count());
|
||||
return x;
|
||||
}
|
||||
@ -216,8 +217,8 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
void run(T& x) const {
|
||||
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
|
||||
|
||||
x.insert(boost::next(this->values.begin(), x.size()),
|
||||
boost::next(this->values.begin(), x.size() + 20));
|
||||
x.insert(test::next(this->values.begin(), x.size()),
|
||||
test::next(this->values.begin(), x.size() + 20));
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
|
131
test/exception/move_assign_exception_tests.cpp
Normal file
131
test/exception/move_assign_exception_tests.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
|
||||
// Copyright 2006-2009 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <iostream>
|
||||
#include "./containers.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4512) // move_assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
test::seed_t initialize_seed(12847);
|
||||
|
||||
template <class T>
|
||||
struct move_assign_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> x_values, y_values;
|
||||
T x,y;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
x_values(),
|
||||
y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
{
|
||||
x.max_load_factor(mlf1);
|
||||
y.max_load_factor(mlf2);
|
||||
}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(x); }
|
||||
void run(T& x1) const {
|
||||
test::exceptions_enable disable_exceptions(false);
|
||||
T y1 = y;
|
||||
disable_exceptions.release();
|
||||
x1 = boost::move(y1);
|
||||
}
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x1) const
|
||||
{
|
||||
test::check_equivalent_keys(x1);
|
||||
|
||||
// If the container is empty at the point of the exception, the
|
||||
// internal structure is hidden, this exposes it, at the cost of
|
||||
// messing up the data.
|
||||
if (x_values.size()) {
|
||||
T& x2 = const_cast<T&>(x1);
|
||||
x2.emplace(*x_values.begin());
|
||||
test::check_equivalent_keys(x2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_values : move_assign_base<T>
|
||||
{
|
||||
move_assign_values(unsigned int count1, unsigned int count2,
|
||||
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
move_assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
{
|
||||
this->x_values.fill(count1);
|
||||
this->y_values.fill(count2);
|
||||
this->x.insert(this->x_values.begin(), this->x_values.end());
|
||||
this->y.insert(this->y_values.begin(), this->y_values.end());
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test1 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test2 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test3 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test4 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test4a : move_assign_values<T>
|
||||
{
|
||||
move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test5 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct equivalent_test1 : move_assign_base<T>
|
||||
{
|
||||
equivalent_test1() :
|
||||
move_assign_base<T>(0, 0)
|
||||
{
|
||||
test::random_values<T> x_values2(10);
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
test::random_values<T> y_values2(10);
|
||||
this->y_values.insert(y_values2.begin(), y_values2.end());
|
||||
this->y_values.insert(y_values2.begin(), y_values2.end());
|
||||
this->x.insert(this->x_values.begin(), this->x_values.end());
|
||||
this->y.insert(this->y_values.begin(), this->y_values.end());
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(move_assign_test1)(move_assign_test2)(move_assign_test3)(move_assign_test4)(move_assign_test4a)(move_assign_test5)
|
||||
(equivalent_test1),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
@ -17,7 +17,7 @@ template <class T>
|
||||
struct self_swap_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_swap_base(int count = 0) : values(count) {}
|
||||
self_swap_base(std::size_t count = 0) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
|
@ -42,20 +42,15 @@ namespace test
|
||||
}
|
||||
|
||||
struct equivalent_type {
|
||||
equivalent_type() {}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator()(T1 const& x, T2 const& y) {
|
||||
bool operator()(T1 const& x, T2 const& y) const {
|
||||
return equivalent_impl(x, y, derived);
|
||||
}
|
||||
};
|
||||
|
||||
// This won't be a problem as I'm only using a single compile unit
|
||||
// in each test (this is actually require by the minimal test
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
equivalent_type equivalent;
|
||||
}
|
||||
const equivalent_type equivalent;
|
||||
|
||||
template <class Container>
|
||||
class unordered_equivalence_tester
|
||||
|
@ -111,16 +111,28 @@ namespace test {
|
||||
exceptions_enable(exceptions_enable const&);
|
||||
|
||||
bool old_value_;
|
||||
bool released_;
|
||||
public:
|
||||
exceptions_enable(bool enable)
|
||||
: old_value_(exceptions_enabled)
|
||||
: old_value_(exceptions_enabled), released_(false)
|
||||
{
|
||||
exceptions_enabled = enable;
|
||||
}
|
||||
|
||||
~exceptions_enable()
|
||||
{
|
||||
exceptions_enabled = old_value_;
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -10,11 +10,17 @@
|
||||
|
||||
namespace test
|
||||
{
|
||||
int generate(int const*);
|
||||
char generate(char const*);
|
||||
signed char generate(signed char const*);
|
||||
std::string generate(std::string*);
|
||||
float generate(float const*);
|
||||
typedef enum {
|
||||
default_generator,
|
||||
generate_collisions,
|
||||
limited_range
|
||||
} random_generator;
|
||||
|
||||
int generate(int const*, random_generator);
|
||||
char generate(char const*, random_generator);
|
||||
signed char generate(signed char const*, random_generator);
|
||||
std::string generate(std::string const*, random_generator);
|
||||
float generate(float const*, random_generator);
|
||||
|
||||
struct base_type {} base;
|
||||
struct derived_type : base_type {} derived;
|
||||
|
@ -27,25 +27,32 @@ namespace test
|
||||
}
|
||||
};
|
||||
|
||||
inline int generate(int const*)
|
||||
{
|
||||
std::size_t random_value(std::size_t max) {
|
||||
using namespace std;
|
||||
return rand();
|
||||
return static_cast<std::size_t>(rand()) % max;
|
||||
}
|
||||
|
||||
inline char generate(char const*)
|
||||
inline int generate(int const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
int value = rand();
|
||||
if (g == limited_range) { value = value % 100; }
|
||||
return value;
|
||||
}
|
||||
|
||||
inline char generate(char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<char>((rand() >> 1) % (128-32) + 32);
|
||||
}
|
||||
|
||||
inline signed char generate(signed char const*)
|
||||
inline signed char generate(signed char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<signed char>(rand());
|
||||
}
|
||||
|
||||
inline std::string generate(std::string const*)
|
||||
inline std::string generate(std::string const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
@ -53,17 +60,30 @@ namespace test
|
||||
|
||||
std::string result;
|
||||
|
||||
int length = rand() % 10;
|
||||
for(int i = 0; i < length; ++i)
|
||||
result += generate(char_ptr);
|
||||
if (g == limited_range) {
|
||||
std::size_t length = test::random_value(2) + 2;
|
||||
|
||||
char const* strings[] = { "'vZh(3~ms", "%m", "_Y%U", "N'Y", "4,J_J" };
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result += strings[random_value(sizeof(strings) / sizeof(strings[0]))];
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::size_t length = test::random_value(10) + 1;
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result += generate(char_ptr, g);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float generate(float const*)
|
||||
float generate(float const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
return (float) rand() / (float) RAND_MAX;
|
||||
int x = 0;
|
||||
int value = generate(&x, g);
|
||||
return (float) value / (float) RAND_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,26 @@ namespace test
|
||||
{
|
||||
return get_key_impl<Container>::get_key(x);
|
||||
}
|
||||
|
||||
// test::next
|
||||
//
|
||||
// Increments an iterator by 1 or a given value.
|
||||
// Like boost::next, but simpler and slower.
|
||||
|
||||
template <typename Iterator>
|
||||
Iterator next(Iterator it)
|
||||
{
|
||||
return ++it;
|
||||
}
|
||||
|
||||
template <typename Iterator, typename IntType>
|
||||
Iterator next(Iterator it, IntType x)
|
||||
{
|
||||
for(; x > 0; --x) {
|
||||
++it;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -91,7 +91,7 @@ namespace test
|
||||
|
||||
// Check the load factor.
|
||||
|
||||
float load_factor =
|
||||
float load_factor = size == 0 ? 0 :
|
||||
static_cast<float>(size) / static_cast<float>(x1.bucket_count());
|
||||
using namespace std;
|
||||
if(fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||
|
@ -8,8 +8,6 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
namespace test
|
||||
{
|
||||
@ -22,19 +20,11 @@ namespace test
|
||||
template <class Container>
|
||||
struct has_unique_keys
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = false);
|
||||
};
|
||||
|
||||
template <class V, class H, class P, class A>
|
||||
struct has_unique_keys<boost::unordered_set<V, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
};
|
||||
|
||||
template <class K, class M, class H, class P, class A>
|
||||
struct has_unique_keys<boost::unordered_map<K, M, H, P, A> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||
static char flip(BOOST_DEDUCED_TYPENAME Container::iterator const&);
|
||||
static long flip(std::pair<BOOST_DEDUCED_TYPENAME Container::iterator, bool> const&);
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(long) == sizeof(
|
||||
flip(((Container*) 0)->insert(*(BOOST_DEDUCED_TYPENAME Container::value_type*) 0))
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,6 @@
|
||||
|
||||
namespace test
|
||||
{
|
||||
typedef enum {
|
||||
default_generator,
|
||||
generate_collisions
|
||||
} random_generator;
|
||||
|
||||
template <class X>
|
||||
struct unordered_generator_set
|
||||
{
|
||||
@ -32,16 +27,15 @@ namespace test
|
||||
template <class T>
|
||||
void fill(T& x, std::size_t len) {
|
||||
value_type* value_ptr = 0;
|
||||
int* int_ptr = 0;
|
||||
len += x.size();
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
value_type value = generate(value_ptr);
|
||||
value_type value = generate(value_ptr, type_);
|
||||
|
||||
int count = type_ == generate_collisions ?
|
||||
1 + (generate(int_ptr) % 5) : 1;
|
||||
std::size_t count = type_ == generate_collisions ?
|
||||
random_value(5) + 1 : 1;
|
||||
|
||||
for(int j = 0; j < count; ++j) {
|
||||
for(std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(value);
|
||||
}
|
||||
}
|
||||
@ -63,17 +57,16 @@ namespace test
|
||||
void fill(T& x, std::size_t len) {
|
||||
key_type* key_ptr = 0;
|
||||
mapped_type* mapped_ptr = 0;
|
||||
int* int_ptr = 0;
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
key_type key = generate(key_ptr);
|
||||
key_type key = generate(key_ptr, type_);
|
||||
|
||||
int count = type_ == generate_collisions ?
|
||||
1 + (generate(int_ptr) % 5) : 1;
|
||||
std::size_t count = type_ == generate_collisions ?
|
||||
random_value(5) + 1 : 1;
|
||||
|
||||
for(int j = 0; j < count; ++j) {
|
||||
for(std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(std::pair<key_type const, mapped_type>(
|
||||
key, generate(mapped_ptr)));
|
||||
key, generate(mapped_ptr, type_)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,13 +98,13 @@ namespace test
|
||||
{
|
||||
random_values() {}
|
||||
|
||||
explicit random_values(int count, test::random_generator const& generator =
|
||||
explicit random_values(std::size_t count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
fill(count, generator);
|
||||
}
|
||||
|
||||
void fill(int count, test::random_generator const& generator =
|
||||
void fill(std::size_t count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
test::unordered_generator<X> gen(generator);
|
||||
|
@ -24,7 +24,11 @@
|
||||
void BOOST_PP_CAT(x, _type)::run() \
|
||||
|
||||
#define RUN_TESTS() int main(int, char**) \
|
||||
{ ::test::test_list::run_tests(); return boost::report_errors(); } \
|
||||
{ \
|
||||
::test::write_compiler_info(); \
|
||||
::test::test_list::run_tests(); \
|
||||
return boost::report_errors(); \
|
||||
}
|
||||
|
||||
namespace test {
|
||||
struct registered_test_base {
|
||||
@ -66,6 +70,21 @@ namespace test {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void write_compiler_info() {
|
||||
#if defined(BOOST_GCC_CXX11)
|
||||
char const* cpp11 = "true";
|
||||
#else
|
||||
char const* cpp11 = "false";
|
||||
#endif
|
||||
|
||||
std::cout
|
||||
<< "Compiler: " << BOOST_COMPILER << "\n"
|
||||
<< "Library: " << BOOST_STDLIB << "\n"
|
||||
<< "C++11: " << cpp11 << "\n"
|
||||
<< "\n"
|
||||
<< std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
#include <boost/preprocessor/seq/for_each_product.hpp>
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <map>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include "../objects/fwd.hpp"
|
||||
#include "./metafunctions.hpp"
|
||||
#include "./helpers.hpp"
|
||||
@ -60,38 +59,46 @@ namespace test
|
||||
values2.begin(), test::equivalent));
|
||||
}
|
||||
|
||||
template <typename X>
|
||||
template <typename X,
|
||||
bool is_set = test::is_set<X>::value,
|
||||
bool has_unique_keys = test::has_unique_keys<X>::value>
|
||||
struct ordered_base;
|
||||
|
||||
template <class V, class H, class P, class A>
|
||||
struct ordered_base<boost::unordered_set<V, H, P, A> >
|
||||
template <typename X>
|
||||
struct ordered_base<X, true, true>
|
||||
{
|
||||
typedef std::set<V,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<P>::type>
|
||||
typedef std::set<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class V, class H, class P, class A>
|
||||
struct ordered_base<boost::unordered_multiset<V, H, P, A> >
|
||||
template <typename X>
|
||||
struct ordered_base<X, true, false>
|
||||
{
|
||||
typedef std::multiset<V,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<P>::type>
|
||||
typedef std::multiset<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class K, class M, class H, class P, class A>
|
||||
struct ordered_base<boost::unordered_map<K, M, H, P, A> >
|
||||
template <typename X>
|
||||
struct ordered_base<X, false, true>
|
||||
{
|
||||
typedef std::map<K, M,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<P>::type>
|
||||
typedef std::map<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class K, class M, class H, class P, class A>
|
||||
struct ordered_base<boost::unordered_multimap<K, M, H, P, A> >
|
||||
template <typename X>
|
||||
struct ordered_base<X, false, false>
|
||||
{
|
||||
typedef std::multimap<K, M,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<P>::type>
|
||||
typedef std::multimap<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace exception
|
||||
class hash;
|
||||
class equal_to;
|
||||
template <class T> class allocator;
|
||||
object generate(object const*);
|
||||
object generate(object const*, random_generator);
|
||||
|
||||
struct true_type
|
||||
{
|
||||
@ -101,9 +101,9 @@ namespace exception
|
||||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
|
||||
}
|
||||
|
||||
friend object generate(object const*) {
|
||||
friend object generate(object const*, random_generator g) {
|
||||
int* x = 0;
|
||||
return object(::test::generate(x), ::test::generate(x));
|
||||
return object(::test::generate(x, g), ::test::generate(x, g));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, object const& o)
|
||||
@ -146,14 +146,18 @@ namespace exception
|
||||
UNORDERED_EPOINT("Mock hash function.");
|
||||
}
|
||||
|
||||
int result;
|
||||
switch(tag_) {
|
||||
case 1:
|
||||
return x.tag1_;
|
||||
result = x.tag1_;
|
||||
break;
|
||||
case 2:
|
||||
return x.tag2_;
|
||||
result = x.tag2_;
|
||||
break;
|
||||
default:
|
||||
return x.tag1_ + x.tag2_;
|
||||
result = x.tag1_ + x.tag2_;
|
||||
}
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
friend bool operator==(hash const& x1, hash const& x2) {
|
||||
@ -588,8 +592,9 @@ namespace exception
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
namespace test
|
||||
{
|
||||
test::exception::object generate(test::exception::object const* x) {
|
||||
return test::exception::generate(x);
|
||||
test::exception::object generate(test::exception::object const* x,
|
||||
random_generator g) {
|
||||
return test::exception::generate(x, g);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -25,9 +25,9 @@ namespace test
|
||||
class equal_to;
|
||||
template <class T> class allocator1;
|
||||
template <class T> class allocator2;
|
||||
object generate(object const*);
|
||||
movable generate(movable const*);
|
||||
implicitly_convertible generate(implicitly_convertible const*);
|
||||
object generate(object const*, random_generator);
|
||||
movable generate(movable const*, random_generator);
|
||||
implicitly_convertible generate(implicitly_convertible const*, random_generator);
|
||||
|
||||
inline void ignore_variable(void const*) {}
|
||||
|
||||
@ -58,9 +58,9 @@ namespace test
|
||||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
|
||||
}
|
||||
|
||||
friend object generate(object const*) {
|
||||
friend object generate(object const*, random_generator g) {
|
||||
int* x = 0;
|
||||
return object(generate(x), generate(x));
|
||||
return object(generate(x, g), generate(x, g));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, object const& o)
|
||||
@ -133,9 +133,9 @@ namespace test
|
||||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
|
||||
}
|
||||
|
||||
friend movable generate(movable const*) {
|
||||
friend movable generate(movable const*, random_generator g) {
|
||||
int* x = 0;
|
||||
return movable(generate(x), generate(x));
|
||||
return movable(generate(x, g), generate(x, g));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, movable const& o)
|
||||
@ -163,9 +163,9 @@ namespace test
|
||||
return movable(tag1_, tag2_);
|
||||
}
|
||||
|
||||
friend implicitly_convertible generate(implicitly_convertible const*) {
|
||||
friend implicitly_convertible generate(implicitly_convertible const*, random_generator g) {
|
||||
int* x = 0;
|
||||
return implicitly_convertible(generate(x), generate(x));
|
||||
return implicitly_convertible(generate(x, g), generate(x, g));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, implicitly_convertible const& o)
|
||||
@ -182,29 +182,48 @@ namespace test
|
||||
explicit hash(int t = 0) : type_(t) {}
|
||||
|
||||
std::size_t operator()(object const& x) const {
|
||||
int result;
|
||||
switch(type_) {
|
||||
case 1:
|
||||
return x.tag1_;
|
||||
result = x.tag1_;
|
||||
break;
|
||||
case 2:
|
||||
return x.tag2_;
|
||||
result = x.tag2_;
|
||||
break;
|
||||
default:
|
||||
return x.tag1_ + x.tag2_;
|
||||
result = x.tag1_ + x.tag2_;
|
||||
}
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
std::size_t operator()(movable const& x) const {
|
||||
int result;
|
||||
switch(type_) {
|
||||
case 1:
|
||||
return x.tag1_;
|
||||
result = x.tag1_;
|
||||
break;
|
||||
case 2:
|
||||
return x.tag2_;
|
||||
result = x.tag2_;
|
||||
break;
|
||||
default:
|
||||
return x.tag1_ + x.tag2_;
|
||||
result = x.tag1_ + x.tag2_;
|
||||
}
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
std::size_t operator()(int x) const {
|
||||
return x;
|
||||
int result;
|
||||
switch(type_) {
|
||||
case 1:
|
||||
result = x;
|
||||
break;
|
||||
case 2:
|
||||
result = x * 7;
|
||||
break;
|
||||
default:
|
||||
result = x * 256;
|
||||
}
|
||||
return static_cast<std::size_t>(result);
|
||||
}
|
||||
|
||||
friend bool operator==(hash const& x1, hash const& x2) {
|
||||
|
@ -236,6 +236,7 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
template <typename T>
|
||||
bool is_propagate(T*)
|
||||
@ -256,7 +257,7 @@ UNORDERED_TEST(assign_tests1, (
|
||||
(test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(test_multimap_prop_assign)
|
||||
(test_set_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(assign_tests2, (
|
||||
@ -264,7 +265,7 @@ UNORDERED_TEST(assign_tests2, (
|
||||
(test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(test_multimap_prop_assign)
|
||||
(test_set_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
@ -34,8 +34,10 @@ void tests(X*, test::random_generator generator)
|
||||
|
||||
X x(v.begin(), v.end());
|
||||
|
||||
BOOST_TEST(x.bucket_count() < x.max_bucket_count());
|
||||
std::cerr<<x.bucket_count()<<"<"<<x.max_bucket_count()<<"\n";
|
||||
BOOST_TEST(x.bucket_count() <= x.max_bucket_count());
|
||||
if (!(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
|
||||
it = v.begin(), end = v.end(); it != end; ++it)
|
||||
@ -43,7 +45,7 @@ void tests(X*, test::random_generator generator)
|
||||
size_type bucket = x.bucket(test::get_key<X>(*it));
|
||||
|
||||
BOOST_TEST(bucket < x.bucket_count());
|
||||
if(bucket < x.max_bucket_count()) {
|
||||
if(bucket < x.bucket_count()) {
|
||||
// lit? lend?? I need a new naming scheme.
|
||||
const_local_iterator lit = x.begin(bucket), lend = x.end(bucket);
|
||||
while(lit != lend
|
||||
@ -87,10 +89,11 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(tests,
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -89,8 +89,9 @@ void container_test(X& r, T const&)
|
||||
|
||||
// size_type can represent any non-negative value type of difference_type
|
||||
// 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);
|
||||
size_type max_diff = static_cast<size_type>(
|
||||
(std::numeric_limits<difference_type>::max)());
|
||||
difference_type converted_diff(static_cast<difference_type>(max_diff));
|
||||
BOOST_TEST((std::numeric_limits<difference_type>::max)()
|
||||
== converted_diff);
|
||||
|
||||
@ -476,6 +477,17 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
|
||||
|
||||
a.insert(i, j);
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
std::initializer_list<T> list = {t};
|
||||
a.insert(list);
|
||||
a.insert({t,t,t});
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900)
|
||||
a.insert({});
|
||||
a.insert({t});
|
||||
a.insert({t,t});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
X a10;
|
||||
a10.insert(t);
|
||||
|
@ -418,20 +418,21 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(constructor_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(constructor_tests2,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(map_constructor_test,
|
||||
((test_map_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
@ -198,13 +198,14 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests1, (
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy)
|
||||
(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests2, (
|
||||
@ -212,7 +213,7 @@ UNORDERED_TEST(copy_construct_tests2, (
|
||||
(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy)
|
||||
(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,11 @@ namespace equality_tests
|
||||
return x % 1000 == y % 1000;
|
||||
}
|
||||
|
||||
int operator()(int x) const
|
||||
std::size_t operator()(int x) const
|
||||
{
|
||||
return alt_hash_ ? x % 250 : (x + 5) % 250;
|
||||
return alt_hash_ ?
|
||||
static_cast<std::size_t>(x % 250) :
|
||||
static_cast<std::size_t>((x + 5) % 250);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,10 +13,10 @@
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/list.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
@ -43,19 +43,19 @@ void write_container(Container const& x)
|
||||
// Make everything collide - for testing erase in a single bucket.
|
||||
struct collision_hash
|
||||
{
|
||||
int operator()(int) const { return 0; }
|
||||
std::size_t operator()(int) const { return 0; }
|
||||
};
|
||||
|
||||
// For testing erase in 2 buckets.
|
||||
struct collision2_hash
|
||||
{
|
||||
int operator()(int x) const { return x & 1; }
|
||||
std::size_t operator()(int x) const { return static_cast<std::size_t>(x & 1); }
|
||||
};
|
||||
|
||||
// For testing erase in lots of buckets.
|
||||
struct collision3_hash
|
||||
{
|
||||
int operator()(int x) const { return x; }
|
||||
std::size_t operator()(int x) const { return static_cast<std::size_t>(x); }
|
||||
};
|
||||
|
||||
typedef boost::unordered_multimap<int, int,
|
||||
@ -111,8 +111,8 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
|
||||
|
||||
{
|
||||
collide_map x(init.begin(), init.end());
|
||||
int value = boost::next(x.begin())->second;
|
||||
x.erase(x.begin(), boost::next(x.begin()));
|
||||
int value = test::next(x.begin())->second;
|
||||
x.erase(x.begin(), test::next(x.begin()));
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
|
||||
x.begin()->first == 1 && x.begin()->second == value);
|
||||
test::check_equivalent_keys(x);
|
||||
@ -121,7 +121,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());
|
||||
x.erase(test::next(x.begin()), x.end());
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
|
||||
x.begin()->first == 1 && x.begin()->second == value);
|
||||
test::check_equivalent_keys(x);
|
||||
@ -144,8 +144,9 @@ template <class Container>
|
||||
bool general_erase_range_test(Container& x, std::size_t start, std::size_t end)
|
||||
{
|
||||
collide_list l(x.begin(), x.end());
|
||||
l.erase(boost::next(l.begin(), start), boost::next(l.begin(), end));
|
||||
x.erase(boost::next(x.begin(), start), boost::next(x.begin(), end));
|
||||
|
||||
l.erase(test::next(l.begin(), start), test::next(l.begin(), end));
|
||||
x.erase(test::next(x.begin(), start), test::next(x.begin(), end));
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
return compare(l, x);
|
||||
|
@ -9,15 +9,15 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/next_prior.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include "../helpers/equivalent.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace erase_tests
|
||||
{
|
||||
@ -27,6 +27,9 @@ test::seed_t initialize_seed(85638);
|
||||
template <class Container>
|
||||
void erase_tests1(Container*, test::random_generator generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator c_iterator;
|
||||
|
||||
std::cerr<<"Erase by key.\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
@ -60,8 +63,7 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_DEDUCED_TYPENAME Container::iterator
|
||||
pos = x.erase(x.begin());
|
||||
iterator pos = x.erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(pos == x.begin());
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
@ -81,17 +83,16 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
using namespace std;
|
||||
int index = rand() % (int) x.size();
|
||||
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
|
||||
std::size_t index = test::random_value(x.size());
|
||||
c_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
prev = pos = x.begin();
|
||||
}
|
||||
else {
|
||||
prev = boost::next(x.begin(), index - 1);
|
||||
pos = boost::next(prev);
|
||||
prev = test::next(x.begin(), index - 1);
|
||||
pos = test::next(prev);
|
||||
}
|
||||
next = boost::next(pos);
|
||||
next = test::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
@ -100,7 +101,7 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == boost::next(prev));
|
||||
next == test::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
@ -138,6 +139,45 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"erase(random ranges).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
Container x;
|
||||
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
test::random_values<Container> v(1000, generator);
|
||||
x.insert(v.begin(), v.end());
|
||||
|
||||
// Note that erase only invalidates the erased iterators.
|
||||
std::vector<c_iterator> iterators;
|
||||
for(c_iterator it = x.cbegin(); it != x.cend(); ++it) {
|
||||
iterators.push_back(it);
|
||||
}
|
||||
iterators.push_back(x.cend());
|
||||
|
||||
while(iterators.size() > 1) {
|
||||
std::size_t start = test::random_value(iterators.size());
|
||||
std::size_t length = test::random_value(iterators.size() - start);
|
||||
x.erase(iterators[start], iterators[start + length]);
|
||||
iterators.erase(
|
||||
test::next(iterators.begin(), start),
|
||||
test::next(iterators.begin(), start + length));
|
||||
|
||||
BOOST_TEST(x.size() == iterators.size() - 1);
|
||||
BOOST_DEDUCED_TYPENAME std::vector<c_iterator>::const_iterator
|
||||
i2 = iterators.begin();
|
||||
for(c_iterator i1 = x.cbegin(); i1 != x.cend(); ++i1) {
|
||||
BOOST_TEST(i1 == *i2);
|
||||
++i2;
|
||||
}
|
||||
BOOST_TEST(x.cend() == *i2);
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
BOOST_TEST(x.empty());
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(begin()).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
@ -170,17 +210,16 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
using namespace std;
|
||||
int index = rand() % (int) x.size();
|
||||
std::size_t index = test::random_value(x.size());
|
||||
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
prev = pos = x.begin();
|
||||
}
|
||||
else {
|
||||
prev = boost::next(x.begin(), index - 1);
|
||||
pos = boost::next(prev);
|
||||
prev = test::next(x.begin(), index - 1);
|
||||
pos = test::next(prev);
|
||||
}
|
||||
next = boost::next(pos);
|
||||
next = test::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
@ -189,7 +228,7 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == boost::next(prev));
|
||||
next == test::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
@ -230,10 +269,11 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(erase_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -37,15 +37,15 @@ void find_tests1(X*, test::random_generator generator)
|
||||
tracker.begin(); it1 != tracker.end(); ++it1)
|
||||
{
|
||||
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_TEST(pos != x.end());
|
||||
BOOST_TEST(pos != x.end() &&
|
||||
x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
iterator pos = x.find(key);
|
||||
BOOST_TEST(const_pos != x_const.end());
|
||||
BOOST_TEST(const_pos != x_const.end() &&
|
||||
x_const.key_eq()(key, test::get_key<X>(*const_pos)));
|
||||
BOOST_TEST(pos != x.end());
|
||||
BOOST_TEST(pos != x.end() &&
|
||||
x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
|
||||
BOOST_TEST(x.count(key) == tracker.count(key));
|
||||
|
||||
@ -155,14 +155,15 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(find_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(find_compatible_keys_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
118
test/unordered/insert_hint_tests.cpp
Normal file
118
test/unordered/insert_hint_tests.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
// Copyright 2016 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "../helpers/postfix.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
namespace insert_hint
|
||||
{
|
||||
UNORDERED_AUTO_TEST(insert_hint_empty) {
|
||||
typedef boost::unordered_multiset<int> container;
|
||||
container x;
|
||||
x.insert(x.cbegin(), 10);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST_EQ(x.count(10), 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_empty2) {
|
||||
typedef boost::unordered_multimap<std::string, int> container;
|
||||
container x;
|
||||
x.emplace_hint(x.cbegin(), "hello", 50);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST_EQ(x.count("hello"), 1u);
|
||||
BOOST_TEST_EQ(x.find("hello")->second, 50);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_single) {
|
||||
typedef boost::unordered_multiset<std::string> container;
|
||||
container x;
|
||||
x.insert("equal");
|
||||
x.insert(x.cbegin(), "equal");
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST_EQ(x.count("equal"), 2u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_single2) {
|
||||
typedef boost::unordered_multimap<int, std::string> container;
|
||||
container x;
|
||||
x.emplace(10, "one");
|
||||
x.emplace_hint(x.cbegin(), 10, "two");
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST_EQ(x.count(10), 2u);
|
||||
|
||||
container::iterator it = x.find(10);
|
||||
std::string v0 = (it++)->second;
|
||||
std::string v1 = (it++)->second;
|
||||
|
||||
BOOST_TEST(v0 == "one" || v0 == "two");
|
||||
BOOST_TEST(v1 == "one" || v1 == "two");
|
||||
BOOST_TEST(v0 != v1);
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_multiple) {
|
||||
for (unsigned int size = 0; size < 10; ++size) {
|
||||
for (unsigned int offset = 0; offset <= size; ++offset) {
|
||||
typedef boost::unordered_multiset<std::string> container;
|
||||
container x;
|
||||
|
||||
for (unsigned int i = 0; i < size; ++i) { x.insert("multiple"); }
|
||||
|
||||
BOOST_TEST_EQ(x.size(), size);
|
||||
|
||||
container::const_iterator position = x.cbegin();
|
||||
for (unsigned int i = 0; i < offset; ++i) { ++position; }
|
||||
|
||||
x.insert(position, "multiple");
|
||||
|
||||
BOOST_TEST_EQ(x.size(), size + 1u);
|
||||
BOOST_TEST_EQ(x.count("multiple"), size + 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_unique) {
|
||||
typedef boost::unordered_set<int> container;
|
||||
container x;
|
||||
x.insert(x.cbegin(), 10);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST_EQ(x.count(10), 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_unique_single) {
|
||||
typedef boost::unordered_set<int> container;
|
||||
container x;
|
||||
x.insert(10);
|
||||
|
||||
x.insert(x.cbegin(), 10);
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST_EQ(x.count(10), 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
|
||||
x.insert(x.cbegin(), 20);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST_EQ(x.count(10), 1u);
|
||||
BOOST_TEST_EQ(x.count(20), 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
@ -49,6 +49,8 @@ UNORDERED_AUTO_TEST(stable_insert_test1) {
|
||||
x.insert(insert_stable::member(1,2));
|
||||
x.insert(insert_stable::member(1,3));
|
||||
|
||||
BOOST_TEST(x.count(insert_stable::member(1,4)) == 3);
|
||||
|
||||
boost::unordered_multiset<insert_stable::member>::const_iterator
|
||||
it = x.begin(), end = x.end();
|
||||
BOOST_TEST(it != end);
|
||||
@ -66,10 +68,11 @@ UNORDERED_AUTO_TEST(stable_insert_test2) {
|
||||
boost::unordered_multimap<insert_stable::member, int>::const_iterator
|
||||
iterator;
|
||||
|
||||
iterator it
|
||||
= x.insert(x.end(), std::make_pair(insert_stable::member(1,1), 1));
|
||||
it = x.insert(it, std::make_pair(insert_stable::member(1,2), 2));
|
||||
it = x.insert(it, std::make_pair(insert_stable::member(1,3), 3));
|
||||
iterator it = x.emplace(insert_stable::member(1,1), 1);
|
||||
it = x.emplace(insert_stable::member(1,2), 2);
|
||||
it = x.emplace(insert_stable::member(1,3), 3);
|
||||
|
||||
BOOST_TEST(x.count(insert_stable::member(1,4)) == 3);
|
||||
|
||||
it = x.begin();
|
||||
iterator end = x.end();
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/next_prior.hpp>
|
||||
#include "../objects/test.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
@ -55,7 +54,7 @@ void unique_insert_tests1(X*, test::random_generator generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@ -88,7 +87,7 @@ void equivalent_insert_tests1(X*, test::random_generator generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
@ -124,10 +123,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -153,10 +153,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -182,10 +183,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
BOOST_TEST(*pos == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -205,14 +207,15 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
x.insert(it, boost::next(it));
|
||||
x.insert(it, test::next(it));
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -292,6 +295,42 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"insert various ranges.\n";
|
||||
|
||||
{
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end();)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
next = it;
|
||||
for (std::size_t j = test::random_value(20); j > 0; ++j) {
|
||||
++next;
|
||||
if (next == v.end()) { break; }
|
||||
}
|
||||
|
||||
x.insert(it, next);
|
||||
tracker.insert(it, next);
|
||||
it = next;
|
||||
|
||||
tracker.compare(x); // Slow, but I can't see any other way.
|
||||
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class X>
|
||||
@ -323,10 +362,11 @@ void unique_emplace_tests1(X*, test::random_generator generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -353,10 +393,11 @@ void equivalent_emplace_tests1(X*, test::random_generator generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -382,12 +423,12 @@ void move_emplace_tests(X*, test::random_generator generator)
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
@ -401,17 +442,17 @@ void default_emplace_tests(X*, test::random_generator)
|
||||
x.emplace();
|
||||
BOOST_TEST(x.size() == 1);
|
||||
x.emplace();
|
||||
BOOST_TEST(x.size() == is_unique ? 1: 2);
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 2u));
|
||||
x.emplace();
|
||||
BOOST_TEST(x.size() == is_unique ? 1: 3);
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 3u));
|
||||
|
||||
typename X::value_type y;
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == is_unique ? 1: 3);
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 3u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
|
||||
x.emplace(y);
|
||||
BOOST_TEST(x.size() == is_unique ? 1: 4);
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == is_unique ? 1: 4);
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 4u));
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 4u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
|
||||
x.clear();
|
||||
@ -419,9 +460,9 @@ void default_emplace_tests(X*, test::random_generator)
|
||||
x.emplace(y);
|
||||
BOOST_TEST(x.size() == 1);
|
||||
x.emplace(y);
|
||||
BOOST_TEST(x.size() == is_unique ? 1: 2);
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 2u));
|
||||
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == is_unique ? 1: 2);
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 2u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
}
|
||||
|
||||
@ -445,10 +486,11 @@ void map_tests(X*, test::random_generator generator)
|
||||
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
if(static_cast<double>(x.size()) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@ -518,57 +560,58 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(unique_insert_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(equivalent_insert_tests1,
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(insert_tests2,
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(equivalent_emplace_tests1,
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(move_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)
|
||||
(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(default_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)
|
||||
(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(map_tests,
|
||||
((test_map))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test1,
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test2,
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
@ -579,7 +622,7 @@ struct initialize_from_two_ints
|
||||
|
||||
friend std::size_t hash_value(initialize_from_two_ints const& x)
|
||||
{
|
||||
return x.a + x.b;
|
||||
return static_cast<std::size_t>(x.a + x.b);
|
||||
}
|
||||
|
||||
bool operator==(initialize_from_two_ints const& x) const
|
||||
|
@ -51,7 +51,7 @@ void insert_test(X*, float mlf, test::random_generator generator)
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(),
|
||||
old_bucket_count = x.bucket_count();
|
||||
x.insert(*it);
|
||||
if(static_cast<double>(old_size + 1) < b * static_cast<double>(old_bucket_count))
|
||||
if(static_cast<double>(old_size + 1) <= b * static_cast<double>(old_bucket_count))
|
||||
BOOST_TEST(x.bucket_count() == old_bucket_count);
|
||||
}
|
||||
}
|
||||
@ -78,6 +78,7 @@ boost::unordered_multimap<int, int>* int_multimap_ptr;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(set_load_factor_tests,
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))
|
||||
@ -85,7 +86,7 @@ UNORDERED_TEST(set_load_factor_tests,
|
||||
|
||||
UNORDERED_TEST(load_factor_insert_tests,
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -369,6 +369,7 @@ boost::unordered_multimap<test::object, test::object,
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(move_construct_tests1, (
|
||||
(test_map_std_alloc)
|
||||
@ -376,7 +377,7 @@ boost::unordered_multimap<test::object, test::object,
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
|
||||
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(move_assign_tests1, (
|
||||
(test_map_std_alloc)
|
||||
@ -384,21 +385,21 @@ boost::unordered_multimap<test::object, test::object,
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
|
||||
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(move_construct_tests2, (
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
|
||||
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(move_assign_tests2, (
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)
|
||||
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -24,28 +24,6 @@ namespace noexcept_tests
|
||||
equal_to_possible_exception(equal_to_possible_exception const&) {}
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST(test_noexcept)
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT)
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
#endif
|
||||
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception>
|
||||
>::value));
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int, boost::hash<int>,
|
||||
equal_to_possible_exception>
|
||||
>::value));
|
||||
}
|
||||
|
||||
// Test that the move constructor does actually move without throwing
|
||||
// an exception when it claims to.
|
||||
|
||||
@ -70,8 +48,10 @@ namespace noexcept_tests
|
||||
|
||||
hash_nothrow_move() { test_throw("Constructor"); }
|
||||
hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
|
||||
hash_nothrow_move& operator=(hash_nothrow_move const&)
|
||||
hash_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow_move))
|
||||
{ test_throw("Assign"); return *this; }
|
||||
hash_nothrow_move& operator=(BOOST_RV_REF(hash_nothrow_move))
|
||||
{ test_throw("Move Assign"); return *this; }
|
||||
std::size_t operator()(int x) const
|
||||
{ test_throw("Operator"); return static_cast<base const&>(*this)(x); }
|
||||
};
|
||||
@ -87,26 +67,69 @@ namespace noexcept_tests
|
||||
equal_to_nothrow_move() { test_throw("Constructor"); }
|
||||
equal_to_nothrow_move(equal_to_nothrow_move const&)
|
||||
{ test_throw("Copy"); }
|
||||
equal_to_nothrow_move& operator=(equal_to_nothrow_move const&)
|
||||
equal_to_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(equal_to_nothrow_move))
|
||||
{ test_throw("Assign"); return *this; }
|
||||
equal_to_nothrow_move& operator=(BOOST_RV_REF(equal_to_nothrow_move))
|
||||
{ test_throw("Move Assign"); return *this; }
|
||||
std::size_t operator()(int x, int y) const
|
||||
{ test_throw("Operator"); return static_cast<base const&>(*this)(x, y); }
|
||||
};
|
||||
|
||||
bool have_is_nothrow_move = false;
|
||||
|
||||
UNORDERED_AUTO_TEST(check_is_nothrow_move)
|
||||
{
|
||||
BOOST_TEST(!boost::is_nothrow_move_constructible<hash_possible_exception>::value);
|
||||
have_is_nothrow_move = boost::is_nothrow_move_constructible<hash_nothrow_move>::value;
|
||||
|
||||
// Copied from boost::is_nothrow_move_constructible implementation
|
||||
// to make sure this does actually detect it when expected.
|
||||
//
|
||||
// The type trait is also available when BOOST_IS_NOTHROW_MOVE_CONSTRUCT
|
||||
// is defined (for some versions of Visual C++?) but detects 'throw()',
|
||||
// not noexcept.
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
|
||||
BOOST_TEST(have_is_nothrow_move);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_noexcept)
|
||||
{
|
||||
if (have_is_nothrow_move) {
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
}
|
||||
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception>
|
||||
>::value));
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int, boost::hash<int>,
|
||||
equal_to_possible_exception>
|
||||
>::value));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_no_throw_when_noexcept)
|
||||
{
|
||||
typedef boost::unordered_set<int,
|
||||
hash_nothrow_move, equal_to_nothrow_move> throwing_set;
|
||||
|
||||
if (boost::is_nothrow_move_constructible<throwing_set>::value)
|
||||
if (have_is_nothrow_move)
|
||||
{
|
||||
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
||||
|
||||
throwing_test_exception = false;
|
||||
|
||||
throwing_set x1;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
|
@ -22,7 +22,7 @@ test::seed_t initialize_seed(2974);
|
||||
template <class X>
|
||||
bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
|
||||
{
|
||||
return static_cast<double>(x.bucket_count()) >
|
||||
return static_cast<double>(x.bucket_count()) >=
|
||||
static_cast<double>(x.size()) / x.max_load_factor() &&
|
||||
x.bucket_count() >= n;
|
||||
}
|
||||
@ -139,7 +139,7 @@ void reserve_test1(X*, test::random_generator generator)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf)
|
||||
{
|
||||
for (int i = 1; i < 2000; i += i < 50 ? 1 : 13)
|
||||
for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13)
|
||||
{
|
||||
test::random_values<X> v(i, generator);
|
||||
|
||||
@ -149,9 +149,6 @@ void reserve_test1(X*, test::random_generator generator)
|
||||
X x;
|
||||
x.max_load_factor(random_mlf ?
|
||||
static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f : 1.0f);
|
||||
// For the current standard this should reserve i+1, I've
|
||||
// submitted a defect report and will assume it's a defect
|
||||
// for now.
|
||||
x.reserve(test::has_unique_keys<X>::value ? i : v.size());
|
||||
|
||||
// Insert an element before the range insert, otherwise there are
|
||||
@ -174,7 +171,7 @@ void reserve_test2(X*, test::random_generator generator)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf)
|
||||
{
|
||||
for (int i = 0; i < 2000; i += i < 50 ? 1 : 13)
|
||||
for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13)
|
||||
{
|
||||
test::random_values<X> v(i, generator);
|
||||
|
||||
@ -211,21 +208,22 @@ boost::unordered_multimap<int, int>* int_multimap_ptr;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(rehash_empty_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
)
|
||||
UNORDERED_TEST(rehash_empty_test2,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(rehash_empty_test3,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(rehash_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(reserve_empty_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
@ -235,11 +233,11 @@ UNORDERED_TEST(reserve_empty_test2,
|
||||
)
|
||||
UNORDERED_TEST(reserve_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(reserve_test2,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -206,6 +206,7 @@ bool is_propagate(T*)
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_AUTO_TEST(check_traits)
|
||||
{
|
||||
@ -220,7 +221,7 @@ UNORDERED_TEST(swap_tests1, (
|
||||
(test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap)
|
||||
(test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(test_multimap_no_prop_swap)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(swap_tests2, (
|
||||
@ -228,7 +229,7 @@ UNORDERED_TEST(swap_tests2, (
|
||||
(test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap)
|
||||
(test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(test_multimap_no_prop_swap)
|
||||
)
|
||||
((default_generator)(generate_collisions))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ namespace unnecessary_copy_tests
|
||||
#endif
|
||||
{
|
||||
std::size_t hash_value(unnecessary_copy_tests::count_copies const& x) {
|
||||
return x.tag_;
|
||||
return static_cast<std::size_t>(x.tag_);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user