forked from boostorg/unordered
Merge pull request #148 from boostorg/feature/foa_rc
Add unordered_flat_map, unordered_flat_set
This commit is contained in:
@ -42,7 +42,12 @@ environment:
|
|||||||
|
|
||||||
- FLAVOR: Visual Studio 2017
|
- FLAVOR: Visual Studio 2017
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
B2_CXXSTD: 14,17,latest
|
B2_CXXSTD: 14,17
|
||||||
|
B2_TOOLSET: msvc-14.1
|
||||||
|
|
||||||
|
- FLAVOR: Visual Studio 2017
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
|
B2_CXXSTD: latest
|
||||||
B2_TOOLSET: msvc-14.1
|
B2_TOOLSET: msvc-14.1
|
||||||
|
|
||||||
- FLAVOR: cygwin (32-bit)
|
- FLAVOR: cygwin (32-bit)
|
||||||
@ -63,7 +68,7 @@ environment:
|
|||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
ADDPATH: C:\cygwin64\bin;
|
ADDPATH: C:\cygwin64\bin;
|
||||||
B2_ADDRESS_MODEL: 64
|
B2_ADDRESS_MODEL: 64
|
||||||
B2_CXXSTD: 03,11
|
B2_CXXSTD: 03
|
||||||
B2_TOOLSET: gcc
|
B2_TOOLSET: gcc
|
||||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||||
|
|
||||||
@ -71,14 +76,37 @@ environment:
|
|||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
ADDPATH: C:\cygwin64\bin;
|
ADDPATH: C:\cygwin64\bin;
|
||||||
B2_ADDRESS_MODEL: 64
|
B2_ADDRESS_MODEL: 64
|
||||||
B2_CXXSTD: 14,1z
|
B2_CXXSTD: 11
|
||||||
|
B2_TOOLSET: gcc
|
||||||
|
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||||
|
|
||||||
|
- FLAVOR: cygwin (64-bit, latest)
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
|
ADDPATH: C:\cygwin64\bin;
|
||||||
|
B2_ADDRESS_MODEL: 64
|
||||||
|
B2_CXXSTD: 14
|
||||||
|
B2_TOOLSET: gcc
|
||||||
|
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||||
|
|
||||||
|
- FLAVOR: cygwin (64-bit, latest)
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||||
|
ADDPATH: C:\cygwin64\bin;
|
||||||
|
B2_ADDRESS_MODEL: 64
|
||||||
|
B2_CXXSTD: 1z
|
||||||
B2_TOOLSET: gcc
|
B2_TOOLSET: gcc
|
||||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||||
|
|
||||||
- FLAVOR: mingw-w64, 32 bit
|
- FLAVOR: mingw-w64, 32 bit
|
||||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||||
B2_CXXSTD: 03,11,14,17,2a
|
B2_CXXSTD: 03,11,14
|
||||||
|
B2_TOOLSET: gcc
|
||||||
|
B2_ADDRESS_MODEL: 32
|
||||||
|
|
||||||
|
- FLAVOR: mingw-w64, 32 bit
|
||||||
|
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
|
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||||
|
B2_CXXSTD: 17,2a
|
||||||
B2_TOOLSET: gcc
|
B2_TOOLSET: gcc
|
||||||
B2_ADDRESS_MODEL: 32
|
B2_ADDRESS_MODEL: 32
|
||||||
|
|
||||||
|
1843
include/boost/unordered/detail/foa.hpp
Normal file
1843
include/boost/unordered/detail/foa.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -47,6 +47,7 @@
|
|||||||
#include <boost/type_traits/make_void.hpp>
|
#include <boost/type_traits/make_void.hpp>
|
||||||
#include <boost/type_traits/remove_const.hpp>
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
#include <boost/unordered/detail/fca.hpp>
|
#include <boost/unordered/detail/fca.hpp>
|
||||||
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
#include <boost/unordered/detail/fwd.hpp>
|
#include <boost/unordered/detail/fwd.hpp>
|
||||||
#include <boost/utility/addressof.hpp>
|
#include <boost/utility/addressof.hpp>
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/utility/enable_if.hpp>
|
||||||
@ -618,39 +619,6 @@ namespace boost {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Type checkers used for the transparent member functions added by C++20 and up
|
|
||||||
|
|
||||||
template <class, class = void> struct is_transparent : public false_type
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
struct is_transparent<T,
|
|
||||||
typename boost::make_void<typename T::is_transparent>::type>
|
|
||||||
: public true_type
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class, class A, class B> struct are_transparent
|
|
||||||
{
|
|
||||||
static bool const value =
|
|
||||||
is_transparent<A>::value && is_transparent<B>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class UnorderedMap> struct transparent_non_iterable
|
|
||||||
{
|
|
||||||
typedef typename UnorderedMap::hasher hash;
|
|
||||||
typedef typename UnorderedMap::key_equal key_equal;
|
|
||||||
typedef typename UnorderedMap::iterator iterator;
|
|
||||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
|
||||||
|
|
||||||
static bool const value =
|
|
||||||
are_transparent<Key, hash, key_equal>::value &&
|
|
||||||
!boost::is_convertible<Key, iterator>::value &&
|
|
||||||
!boost::is_convertible<Key, const_iterator>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Explicitly call a destructor
|
// Explicitly call a destructor
|
||||||
|
|
||||||
|
59
include/boost/unordered/detail/type_traits.hpp
Normal file
59
include/boost/unordered/detail/type_traits.hpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
|
#include <boost/type_traits/is_convertible.hpp>
|
||||||
|
#include <boost/type_traits/make_void.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
namespace detail {
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Type checkers used for the transparent member functions added by C++20
|
||||||
|
// and up
|
||||||
|
|
||||||
|
template <class, class = void>
|
||||||
|
struct is_transparent : public boost::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct is_transparent<T,
|
||||||
|
typename boost::make_void<typename T::is_transparent>::type>
|
||||||
|
: public boost::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class, class A, class B> struct are_transparent
|
||||||
|
{
|
||||||
|
static bool const value =
|
||||||
|
is_transparent<A>::value && is_transparent<B>::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class UnorderedMap> struct transparent_non_iterable
|
||||||
|
{
|
||||||
|
typedef typename UnorderedMap::hasher hash;
|
||||||
|
typedef typename UnorderedMap::key_equal key_equal;
|
||||||
|
typedef typename UnorderedMap::iterator iterator;
|
||||||
|
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||||
|
|
||||||
|
static bool const value =
|
||||||
|
are_transparent<Key, hash, key_equal>::value &&
|
||||||
|
!boost::is_convertible<Key, iterator>::value &&
|
||||||
|
!boost::is_convertible<Key, const_iterator>::value;
|
||||||
|
};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
75
include/boost/unordered/detail/xmx.hpp
Normal file
75
include/boost/unordered/detail/xmx.hpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* 32b/64b xmx mix function.
|
||||||
|
*
|
||||||
|
* Copyright 2022 Peter Dimov.
|
||||||
|
* Copyright 2022 Joaquin M Lopez Munoz.
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* See https://www.boost.org/libs/unordered for library home page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_DETAIL_XMX_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_XMX_HPP
|
||||||
|
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace unordered{
|
||||||
|
namespace detail{
|
||||||
|
|
||||||
|
/* Bit mixer for improvement of statistical properties of hash functions.
|
||||||
|
* The implementation is different on 64bit and 32bit architectures:
|
||||||
|
*
|
||||||
|
* - 64bit: same as xmx function in
|
||||||
|
* http://jonkagstrom.com/bit-mixer-construction/index.html
|
||||||
|
* - 32bit: generated by Hash Function Prospector
|
||||||
|
* (https://github.com/skeeto/hash-prospector) and selected as the
|
||||||
|
* best overall performer in benchmarks of Boost.Unordered flat containers.
|
||||||
|
* Score assigned by Hash Prospector: 333.7934929677524
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(SIZE_MAX)
|
||||||
|
#if ((((SIZE_MAX >> 16) >> 16) >> 16) >> 15) != 0
|
||||||
|
#define BOOST_UNORDERED_64B_ARCHITECTURE /* >64 bits assumed as 64 bits */
|
||||||
|
#endif
|
||||||
|
#elif defined(UINTPTR_MAX) /* used as proxy for std::size_t */
|
||||||
|
#if ((((UINTPTR_MAX >> 16) >> 16) >> 16) >> 15) != 0
|
||||||
|
#define BOOST_UNORDERED_64B_ARCHITECTURE
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline std::size_t xmx(std::size_t x)noexcept
|
||||||
|
{
|
||||||
|
#if defined(BOOST_UNORDERED_64B_ARCHITECTURE)
|
||||||
|
|
||||||
|
boost::uint64_t z=(boost::uint64_t)x;
|
||||||
|
|
||||||
|
z^=z>>23;
|
||||||
|
z*=0xff51afd7ed558ccdull;
|
||||||
|
z^=z>>23;
|
||||||
|
|
||||||
|
return (std::size_t)z;
|
||||||
|
|
||||||
|
#else /* 32 bits assumed */
|
||||||
|
|
||||||
|
x^=x>>18;
|
||||||
|
x*=0x56b5aaadu;
|
||||||
|
x^=x>>16;
|
||||||
|
|
||||||
|
return x;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_64B_ARCHITECTURE
|
||||||
|
#undef BOOST_UNORDERED_64B_ARCHITECTURE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} /* namespace detail */
|
||||||
|
} /* namespace unordered */
|
||||||
|
} /* namespace boost */
|
||||||
|
|
||||||
|
#endif
|
44
include/boost/unordered/hash_traits.hpp
Normal file
44
include/boost/unordered/hash_traits.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Hash function characterization.
|
||||||
|
*
|
||||||
|
* Copyright 2022 Joaquin M Lopez Munoz.
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* See https://www.boost.org/libs/unordered for library home page.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||||
|
#define BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||||
|
|
||||||
|
#include <boost/type_traits/make_void.hpp>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace boost{
|
||||||
|
namespace unordered{
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
|
||||||
|
template<typename Hash,typename=void>
|
||||||
|
struct hash_is_avalanching_impl:std::false_type{};
|
||||||
|
|
||||||
|
template<typename Hash>
|
||||||
|
struct hash_is_avalanching_impl<Hash,void_t<typename Hash::is_avalanching>>:
|
||||||
|
std::true_type{};
|
||||||
|
|
||||||
|
} /* namespace detail */
|
||||||
|
|
||||||
|
/* Each trait can be partially specialized by users for concrete hash functions
|
||||||
|
* when actual characterization differs from default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Derived from std::true_type if the type Hash::is_avalanching is present,
|
||||||
|
* derived from std::false_type otherwise.
|
||||||
|
*/
|
||||||
|
template<typename Hash>
|
||||||
|
struct hash_is_avalanching:detail::hash_is_avalanching_impl<Hash>::type{};
|
||||||
|
|
||||||
|
} /* namespace unordered */
|
||||||
|
} /* namespace boost */
|
||||||
|
|
||||||
|
#endif
|
619
include/boost/unordered/unordered_flat_map.hpp
Normal file
619
include/boost/unordered/unordered_flat_map.hpp
Normal file
@ -0,0 +1,619 @@
|
|||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
|
||||||
|
#define BOOST_UNORDERED_UNORDERED_FLAT_MAP_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/unordered/detail/foa.hpp>
|
||||||
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <iterator>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
class unordered_flat_map
|
||||||
|
{
|
||||||
|
struct map_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using raw_key_type = typename std::remove_const<Key>::type;
|
||||||
|
using raw_mapped_type = typename std::remove_const<T>::type;
|
||||||
|
|
||||||
|
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
||||||
|
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
||||||
|
using value_type = std::pair<Key const, T>;
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
||||||
|
{
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static moved_type move(value_type& x)
|
||||||
|
{
|
||||||
|
// TODO: we probably need to launder here
|
||||||
|
return {std::move(const_cast<raw_key_type&>(x.first)),
|
||||||
|
std::move(const_cast<raw_mapped_type&>(x.second))};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
||||||
|
typename boost::allocator_rebind<Allocator,
|
||||||
|
typename map_types::value_type>::type>;
|
||||||
|
|
||||||
|
table_type table_;
|
||||||
|
|
||||||
|
template <class K, class V, class H, class KE, class A, class Pred>
|
||||||
|
typename unordered_flat_map<K, V, H, KE, A>::size_type friend erase_if(
|
||||||
|
unordered_flat_map<K, V, H, KE, A>& set, Pred pred);
|
||||||
|
|
||||||
|
public:
|
||||||
|
using key_type = Key;
|
||||||
|
using mapped_type = T;
|
||||||
|
using value_type = typename map_types::value_type;
|
||||||
|
using init_type = typename map_types::init_type;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using hasher = Hash;
|
||||||
|
using key_equal = KeyEqual;
|
||||||
|
using allocator_type = Allocator;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = value_type const&;
|
||||||
|
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||||
|
using const_pointer =
|
||||||
|
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||||
|
using iterator = typename table_type::iterator;
|
||||||
|
using const_iterator = typename table_type::const_iterator;
|
||||||
|
|
||||||
|
unordered_flat_map() : unordered_flat_map(0) {}
|
||||||
|
|
||||||
|
explicit unordered_flat_map(size_type n, hasher const& h = hasher(),
|
||||||
|
key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: table_(n, h, pred, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(size_type n, allocator_type const& a)
|
||||||
|
: unordered_flat_map(n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(size_type n, hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_map(n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit unordered_flat_map(allocator_type const& a)
|
||||||
|
: unordered_flat_map(0, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
unordered_flat_map(Iterator first, Iterator last, size_type n = 0,
|
||||||
|
hasher const& h = hasher(), key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: unordered_flat_map(n, h, pred, a)
|
||||||
|
{
|
||||||
|
this->insert(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
unordered_flat_map(
|
||||||
|
Iterator first, Iterator last, size_type n, allocator_type const& a)
|
||||||
|
: unordered_flat_map(first, last, n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
unordered_flat_map(Iterator first, Iterator last, size_type n,
|
||||||
|
hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_map(first, last, n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(unordered_flat_map const& other) : table_(other.table_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(
|
||||||
|
unordered_flat_map const& other, allocator_type const& a)
|
||||||
|
: table_(other.table_, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(unordered_flat_map&& other)
|
||||||
|
noexcept(std::is_nothrow_move_constructible<hasher>::value&&
|
||||||
|
std::is_nothrow_move_constructible<key_equal>::value&&
|
||||||
|
std::is_nothrow_move_constructible<allocator_type>::value)
|
||||||
|
: table_(std::move(other.table_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(unordered_flat_map&& other, allocator_type const& al)
|
||||||
|
: table_(std::move(other.table_), al)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(std::initializer_list<value_type> ilist,
|
||||||
|
size_type n = 0, hasher const& h = hasher(),
|
||||||
|
key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: unordered_flat_map(ilist.begin(), ilist.end(), n, h, pred, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(std::initializer_list<value_type> init, size_type n,
|
||||||
|
allocator_type const& a)
|
||||||
|
: unordered_flat_map(init, n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map(std::initializer_list<value_type> init, size_type n,
|
||||||
|
hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_map(init, n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~unordered_flat_map() = default;
|
||||||
|
|
||||||
|
unordered_flat_map& operator=(unordered_flat_map const& other)
|
||||||
|
{
|
||||||
|
table_ = other.table_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_map& operator=(unordered_flat_map&& other) noexcept(
|
||||||
|
noexcept(std::declval<table_type&>() = std::declval<table_type&&>()))
|
||||||
|
{
|
||||||
|
table_ = std::move(other.table_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator_type get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return table_.get_allocator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterators
|
||||||
|
///
|
||||||
|
|
||||||
|
iterator begin() noexcept { return table_.begin(); }
|
||||||
|
const_iterator begin() const noexcept { return table_.begin(); }
|
||||||
|
const_iterator cbegin() const noexcept { return table_.cbegin(); }
|
||||||
|
|
||||||
|
iterator end() noexcept { return table_.end(); }
|
||||||
|
const_iterator end() const noexcept { return table_.end(); }
|
||||||
|
const_iterator cend() const noexcept { return table_.cend(); }
|
||||||
|
|
||||||
|
/// Capacity
|
||||||
|
///
|
||||||
|
|
||||||
|
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
|
||||||
|
{
|
||||||
|
return table_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type size() const noexcept { return table_.size(); }
|
||||||
|
|
||||||
|
size_type max_size() const noexcept { return table_.max_size(); }
|
||||||
|
|
||||||
|
/// Modifiers
|
||||||
|
///
|
||||||
|
|
||||||
|
void clear() noexcept { table_.clear(); }
|
||||||
|
|
||||||
|
template <class Ty>
|
||||||
|
BOOST_FORCEINLINE auto insert(Ty&& value)
|
||||||
|
-> decltype(table_.insert(std::forward<Ty>(value)))
|
||||||
|
{
|
||||||
|
return table_.insert(std::forward<Ty>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> insert(init_type&& value)
|
||||||
|
{
|
||||||
|
return table_.insert(std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Ty>
|
||||||
|
BOOST_FORCEINLINE auto insert(const_iterator, Ty&& value)
|
||||||
|
-> decltype(table_.insert(std::forward<Ty>(value)).first)
|
||||||
|
{
|
||||||
|
return table_.insert(std::forward<Ty>(value)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE iterator insert(const_iterator, init_type&& value)
|
||||||
|
{
|
||||||
|
return table_.insert(std::move(value)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class InputIterator>
|
||||||
|
BOOST_FORCEINLINE void insert(InputIterator first, InputIterator last)
|
||||||
|
{
|
||||||
|
for (auto pos = first; pos != last; ++pos) {
|
||||||
|
table_.emplace(*pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(std::initializer_list<value_type> ilist)
|
||||||
|
{
|
||||||
|
this->insert(ilist.begin(), ilist.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type const& key, M&& obj)
|
||||||
|
{
|
||||||
|
auto iter_bool_pair = table_.try_emplace(key, std::forward<M>(obj));
|
||||||
|
if (iter_bool_pair.second) {
|
||||||
|
return iter_bool_pair;
|
||||||
|
}
|
||||||
|
iter_bool_pair.first->second = std::forward<M>(obj);
|
||||||
|
return iter_bool_pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
std::pair<iterator, bool> insert_or_assign(key_type&& key, M&& obj)
|
||||||
|
{
|
||||||
|
auto iter_bool_pair =
|
||||||
|
table_.try_emplace(std::move(key), std::forward<M>(obj));
|
||||||
|
if (iter_bool_pair.second) {
|
||||||
|
return iter_bool_pair;
|
||||||
|
}
|
||||||
|
iter_bool_pair.first->second = std::forward<M>(obj);
|
||||||
|
return iter_bool_pair;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
iterator insert_or_assign(const_iterator, key_type const& key, M&& obj)
|
||||||
|
{
|
||||||
|
return this->insert_or_assign(key, std::forward<M>(obj)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class M>
|
||||||
|
iterator insert_or_assign(const_iterator, key_type&& key, M&& obj)
|
||||||
|
{
|
||||||
|
return this->insert_or_assign(std::move(key), std::forward<M>(obj))
|
||||||
|
.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.emplace(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE iterator emplace_hint(const_iterator, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.emplace(std::forward<Args>(args)...).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
|
||||||
|
key_type const& key, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(key, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> try_emplace(
|
||||||
|
key_type&& key, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(std::move(key), std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE iterator try_emplace(
|
||||||
|
const_iterator, key_type const& key, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(key, std::forward<Args>(args)...).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE iterator try_emplace(
|
||||||
|
const_iterator, key_type&& key, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(std::move(key), std::forward<Args>(args)...)
|
||||||
|
.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE void erase(iterator pos) { table_.erase(pos); }
|
||||||
|
BOOST_FORCEINLINE void erase(const_iterator pos)
|
||||||
|
{
|
||||||
|
return table_.erase(pos);
|
||||||
|
}
|
||||||
|
iterator erase(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
while (first != last) {
|
||||||
|
this->erase(first++);
|
||||||
|
}
|
||||||
|
return iterator{detail::foa::const_iterator_cast_tag{}, last};
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE size_type erase(key_type const& key)
|
||||||
|
{
|
||||||
|
return table_.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
detail::transparent_non_iterable<K, unordered_flat_map>::value,
|
||||||
|
size_type>::type
|
||||||
|
erase(K const& key)
|
||||||
|
{
|
||||||
|
return table_.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unordered_flat_map& rhs) noexcept(
|
||||||
|
noexcept(std::declval<table_type&>().swap(std::declval<table_type&>())))
|
||||||
|
{
|
||||||
|
table_.swap(rhs.table_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class H2, class P2>
|
||||||
|
void merge(
|
||||||
|
unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&
|
||||||
|
source)
|
||||||
|
{
|
||||||
|
table_.merge(source.table_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class H2, class P2>
|
||||||
|
void merge(
|
||||||
|
unordered_flat_map<key_type, mapped_type, H2, P2, allocator_type>&&
|
||||||
|
source)
|
||||||
|
{
|
||||||
|
table_.merge(std::move(source.table_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lookup
|
||||||
|
///
|
||||||
|
|
||||||
|
mapped_type& at(key_type const& key)
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos != table_.end()) {
|
||||||
|
return pos->second;
|
||||||
|
}
|
||||||
|
// TODO: someday refactor this to conditionally serialize the key and
|
||||||
|
// include it in the error message
|
||||||
|
//
|
||||||
|
boost::throw_exception(
|
||||||
|
std::out_of_range("key was not found in unordered_flat_map"));
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped_type const& at(key_type const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos != table_.end()) {
|
||||||
|
return pos->second;
|
||||||
|
}
|
||||||
|
boost::throw_exception(
|
||||||
|
std::out_of_range("key was not found in unordered_flat_map"));
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped_type& operator[](key_type const& key)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(key).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped_type& operator[](key_type&& key)
|
||||||
|
{
|
||||||
|
return table_.try_emplace(std::move(key)).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type count(key_type const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
return pos != table_.end() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value, size_type>::type
|
||||||
|
count(K const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
return pos != table_.end() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE iterator find(key_type const& key)
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE const_iterator find(key_type const& key) const
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
iterator>::type
|
||||||
|
find(K const& key)
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
const_iterator>::type
|
||||||
|
find(K const& key) const
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(key_type const& key) const
|
||||||
|
{
|
||||||
|
return this->find(key) != this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
bool>::type
|
||||||
|
contains(K const& key) const
|
||||||
|
{
|
||||||
|
return this->find(key) != this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<iterator, iterator> equal_range(key_type const& key)
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<const_iterator, const_iterator> equal_range(
|
||||||
|
key_type const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
std::pair<iterator, iterator> >::type
|
||||||
|
equal_range(K const& key)
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
std::pair<const_iterator, const_iterator> >::type
|
||||||
|
equal_range(K const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hash Policy
|
||||||
|
///
|
||||||
|
|
||||||
|
size_type bucket_count() const noexcept { return table_.capacity(); }
|
||||||
|
|
||||||
|
float load_factor() const noexcept { return table_.load_factor(); }
|
||||||
|
|
||||||
|
float max_load_factor() const noexcept
|
||||||
|
{
|
||||||
|
return table_.max_load_factor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void max_load_factor(float) {}
|
||||||
|
|
||||||
|
void rehash(size_type n) { table_.rehash(n); }
|
||||||
|
|
||||||
|
void reserve(size_type n) { table_.reserve(n); }
|
||||||
|
|
||||||
|
/// Observers
|
||||||
|
///
|
||||||
|
|
||||||
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator==(
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
if (&lhs == &rhs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lhs.size() == rhs.size()) && ([&] {
|
||||||
|
for (auto const& kvp : lhs) {
|
||||||
|
auto pos = rhs.find(kvp.first);
|
||||||
|
if ((pos == rhs.end()) || (*pos != kvp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator!=(
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
|
||||||
|
noexcept(noexcept(lhs.swap(rhs)))
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator,
|
||||||
|
class Pred>
|
||||||
|
typename unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>::size_type
|
||||||
|
erase_if(
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& map, Pred pred)
|
||||||
|
{
|
||||||
|
return erase_if(map.table_, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(pop) /* C4714 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
49
include/boost/unordered/unordered_flat_map_fwd.hpp
Normal file
49
include/boost/unordered/unordered_flat_map_fwd.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED
|
||||||
|
#define BOOST_UNORDERED_FLAT_MAP_FWD_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/functional/hash_fwd.hpp>
|
||||||
|
#include <boost/unordered/detail/fwd.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||||
|
class KeyEqual = std::equal_to<Key>,
|
||||||
|
class Allocator = std::allocator<std::pair<const Key, T> > >
|
||||||
|
class unordered_flat_map;
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator==(
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs);
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator!=(
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator> const& rhs);
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
void swap(unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
unordered_flat_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
|
||||||
|
noexcept(noexcept(lhs.swap(rhs)));
|
||||||
|
} // namespace unordered
|
||||||
|
|
||||||
|
using boost::unordered::unordered_flat_map;
|
||||||
|
|
||||||
|
using boost::unordered::swap;
|
||||||
|
using boost::unordered::operator==;
|
||||||
|
using boost::unordered::operator!=;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
494
include/boost/unordered/unordered_flat_set.hpp
Normal file
494
include/boost/unordered/unordered_flat_set.hpp
Normal file
@ -0,0 +1,494 @@
|
|||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED
|
||||||
|
#define BOOST_UNORDERED_UNORDERED_FLAT_SET_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/unordered/detail/foa.hpp>
|
||||||
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
class unordered_flat_set
|
||||||
|
{
|
||||||
|
struct set_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using init_type = Key;
|
||||||
|
using value_type = Key;
|
||||||
|
static Key const& extract(value_type const& key) { return key; }
|
||||||
|
static Key&& move(value_type& x) { return std::move(x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
||||||
|
typename boost::allocator_rebind<Allocator,
|
||||||
|
typename set_types::value_type>::type>;
|
||||||
|
|
||||||
|
table_type table_;
|
||||||
|
|
||||||
|
template <class K, class H, class KE, class A, class Pred>
|
||||||
|
typename unordered_flat_set<K, H, KE, A>::size_type friend erase_if(
|
||||||
|
unordered_flat_set<K, H, KE, A>& set, Pred pred);
|
||||||
|
|
||||||
|
public:
|
||||||
|
using key_type = Key;
|
||||||
|
using value_type = typename set_types::value_type;
|
||||||
|
using init_type = typename set_types::init_type;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using hasher = Hash;
|
||||||
|
using key_equal = KeyEqual;
|
||||||
|
using allocator_type = Allocator;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = value_type const&;
|
||||||
|
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||||
|
using const_pointer =
|
||||||
|
typename boost::allocator_const_pointer<allocator_type>::type;
|
||||||
|
using iterator = typename table_type::iterator;
|
||||||
|
using const_iterator = typename table_type::const_iterator;
|
||||||
|
|
||||||
|
unordered_flat_set() : unordered_flat_set(0) {}
|
||||||
|
|
||||||
|
explicit unordered_flat_set(size_type n, hasher const& h = hasher(),
|
||||||
|
key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: table_(n, h, pred, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(size_type n, allocator_type const& a)
|
||||||
|
: unordered_flat_set(n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(size_type n, hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_set(n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit unordered_flat_set(allocator_type const& a)
|
||||||
|
: unordered_flat_set(0, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
unordered_flat_set(Iterator first, Iterator last, size_type n = 0,
|
||||||
|
hasher const& h = hasher(), key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: unordered_flat_set(n, h, pred, a)
|
||||||
|
{
|
||||||
|
this->insert(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class InputIt>
|
||||||
|
unordered_flat_set(
|
||||||
|
InputIt first, InputIt last, size_type n, allocator_type const& a)
|
||||||
|
: unordered_flat_set(first, last, n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iterator>
|
||||||
|
unordered_flat_set(Iterator first, Iterator last, size_type n,
|
||||||
|
hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_set(first, last, n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(unordered_flat_set const& other) : table_(other.table_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(
|
||||||
|
unordered_flat_set const& other, allocator_type const& a)
|
||||||
|
: table_(other.table_, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(unordered_flat_set&& other)
|
||||||
|
noexcept(std::is_nothrow_move_constructible<hasher>::value&&
|
||||||
|
std::is_nothrow_move_constructible<key_equal>::value&&
|
||||||
|
std::is_nothrow_move_constructible<allocator_type>::value)
|
||||||
|
: table_(std::move(other.table_))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(unordered_flat_set&& other, allocator_type const& al)
|
||||||
|
: table_(std::move(other.table_), al)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(std::initializer_list<value_type> ilist,
|
||||||
|
size_type n = 0, hasher const& h = hasher(),
|
||||||
|
key_equal const& pred = key_equal(),
|
||||||
|
allocator_type const& a = allocator_type())
|
||||||
|
: unordered_flat_set(ilist.begin(), ilist.end(), n, h, pred, a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(std::initializer_list<value_type> init, size_type n,
|
||||||
|
allocator_type const& a)
|
||||||
|
: unordered_flat_set(init, n, hasher(), key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set(std::initializer_list<value_type> init, size_type n,
|
||||||
|
hasher const& h, allocator_type const& a)
|
||||||
|
: unordered_flat_set(init, n, h, key_equal(), a)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~unordered_flat_set() = default;
|
||||||
|
|
||||||
|
unordered_flat_set& operator=(unordered_flat_set const& other)
|
||||||
|
{
|
||||||
|
table_ = other.table_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unordered_flat_set& operator=(unordered_flat_set&& other) noexcept(
|
||||||
|
noexcept(std::declval<table_type&>() = std::declval<table_type&&>()))
|
||||||
|
{
|
||||||
|
table_ = std::move(other.table_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator_type get_allocator() const noexcept
|
||||||
|
{
|
||||||
|
return table_.get_allocator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterators
|
||||||
|
///
|
||||||
|
|
||||||
|
iterator begin() noexcept { return table_.begin(); }
|
||||||
|
const_iterator begin() const noexcept { return table_.begin(); }
|
||||||
|
const_iterator cbegin() const noexcept { return table_.cbegin(); }
|
||||||
|
|
||||||
|
iterator end() noexcept { return table_.end(); }
|
||||||
|
const_iterator end() const noexcept { return table_.end(); }
|
||||||
|
const_iterator cend() const noexcept { return table_.cend(); }
|
||||||
|
|
||||||
|
/// Capacity
|
||||||
|
///
|
||||||
|
|
||||||
|
BOOST_ATTRIBUTE_NODISCARD bool empty() const noexcept
|
||||||
|
{
|
||||||
|
return table_.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type size() const noexcept { return table_.size(); }
|
||||||
|
|
||||||
|
size_type max_size() const noexcept { return table_.max_size(); }
|
||||||
|
|
||||||
|
/// Modifiers
|
||||||
|
///
|
||||||
|
|
||||||
|
void clear() noexcept { table_.clear(); }
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> insert(
|
||||||
|
value_type const& value)
|
||||||
|
{
|
||||||
|
return table_.insert(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> insert(value_type&& value)
|
||||||
|
{
|
||||||
|
return table_.insert(std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE iterator insert(const_iterator, value_type const& value)
|
||||||
|
{
|
||||||
|
return table_.insert(value).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE iterator insert(const_iterator, value_type&& value)
|
||||||
|
{
|
||||||
|
return table_.insert(std::move(value)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class InputIterator>
|
||||||
|
void insert(InputIterator first, InputIterator last)
|
||||||
|
{
|
||||||
|
for (auto pos = first; pos != last; ++pos) {
|
||||||
|
table_.emplace(*pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(std::initializer_list<value_type> ilist)
|
||||||
|
{
|
||||||
|
this->insert(ilist.begin(), ilist.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE std::pair<iterator, bool> emplace(Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.emplace(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
BOOST_FORCEINLINE iterator emplace_hint(const_iterator, Args&&... args)
|
||||||
|
{
|
||||||
|
return table_.emplace(std::forward<Args>(args)...).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE void erase(const_iterator pos)
|
||||||
|
{
|
||||||
|
return table_.erase(pos);
|
||||||
|
}
|
||||||
|
iterator erase(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
while (first != last) {
|
||||||
|
this->erase(first++);
|
||||||
|
}
|
||||||
|
return iterator{detail::foa::const_iterator_cast_tag{}, last};
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE size_type erase(key_type const& key)
|
||||||
|
{
|
||||||
|
return table_.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
detail::transparent_non_iterable<K, unordered_flat_set>::value,
|
||||||
|
size_type>::type
|
||||||
|
erase(K const& key)
|
||||||
|
{
|
||||||
|
return table_.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unordered_flat_set& rhs) noexcept(
|
||||||
|
noexcept(std::declval<table_type&>().swap(std::declval<table_type&>())))
|
||||||
|
{
|
||||||
|
table_.swap(rhs.table_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class H2, class P2>
|
||||||
|
void merge(unordered_flat_set<key_type, H2, P2, allocator_type>& source)
|
||||||
|
{
|
||||||
|
table_.merge(source.table_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class H2, class P2>
|
||||||
|
void merge(unordered_flat_set<key_type, H2, P2, allocator_type>&& source)
|
||||||
|
{
|
||||||
|
table_.merge(std::move(source.table_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lookup
|
||||||
|
///
|
||||||
|
|
||||||
|
size_type count(key_type const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
return pos != table_.end() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value, size_type>::type
|
||||||
|
count(K const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
return pos != table_.end() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE iterator find(key_type const& key)
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_FORCEINLINE const_iterator find(key_type const& key) const
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
iterator>::type
|
||||||
|
find(K const& key)
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
BOOST_FORCEINLINE typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
const_iterator>::type
|
||||||
|
find(K const& key) const
|
||||||
|
{
|
||||||
|
return table_.find(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(key_type const& key) const
|
||||||
|
{
|
||||||
|
return this->find(key) != this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
boost::unordered::detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
bool>::type
|
||||||
|
contains(K const& key) const
|
||||||
|
{
|
||||||
|
return this->find(key) != this->end();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<iterator, iterator> equal_range(key_type const& key)
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<const_iterator, const_iterator> equal_range(
|
||||||
|
key_type const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
std::pair<iterator, iterator> >::type
|
||||||
|
equal_range(K const& key)
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K>
|
||||||
|
typename std::enable_if<
|
||||||
|
detail::are_transparent<K, hasher, key_equal>::value,
|
||||||
|
std::pair<const_iterator, const_iterator> >::type
|
||||||
|
equal_range(K const& key) const
|
||||||
|
{
|
||||||
|
auto pos = table_.find(key);
|
||||||
|
if (pos == table_.end()) {
|
||||||
|
return {pos, pos};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto next = pos;
|
||||||
|
++next;
|
||||||
|
return {pos, next};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hash Policy
|
||||||
|
///
|
||||||
|
|
||||||
|
size_type bucket_count() const noexcept { return table_.capacity(); }
|
||||||
|
|
||||||
|
float load_factor() const noexcept { return table_.load_factor(); }
|
||||||
|
|
||||||
|
float max_load_factor() const noexcept
|
||||||
|
{
|
||||||
|
return table_.max_load_factor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void max_load_factor(float) {}
|
||||||
|
|
||||||
|
void rehash(size_type n) { table_.rehash(n); }
|
||||||
|
|
||||||
|
void reserve(size_type n) { table_.reserve(n); }
|
||||||
|
|
||||||
|
/// Observers
|
||||||
|
///
|
||||||
|
|
||||||
|
hasher hash_function() const { return table_.hash_function(); }
|
||||||
|
|
||||||
|
key_equal key_eq() const { return table_.key_eq(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator==(
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
if (&lhs == &rhs) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (lhs.size() == rhs.size()) && ([&] {
|
||||||
|
for (auto const& key : lhs) {
|
||||||
|
auto pos = rhs.find(key);
|
||||||
|
if ((pos == rhs.end()) || (key != *pos)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator!=(
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||||
|
noexcept(noexcept(lhs.swap(rhs)))
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator,
|
||||||
|
class Pred>
|
||||||
|
typename unordered_flat_set<Key, Hash, KeyEqual, Allocator>::size_type
|
||||||
|
erase_if(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& set, Pred pred)
|
||||||
|
{
|
||||||
|
return erase_if(set.table_, pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(pop) /* C4714 */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
49
include/boost/unordered/unordered_flat_set_fwd.hpp
Normal file
49
include/boost/unordered/unordered_flat_set_fwd.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED
|
||||||
|
#define BOOST_UNORDERED_FLAT_SET_FWD_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/functional/hash_fwd.hpp>
|
||||||
|
#include <boost/unordered/detail/fwd.hpp>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
template <class Key, class Hash = boost::hash<Key>,
|
||||||
|
class KeyEqual = std::equal_to<Key>,
|
||||||
|
class Allocator = std::allocator<Key> >
|
||||||
|
class unordered_flat_set;
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator==(
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs);
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
bool operator!=(
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator> const& rhs);
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
|
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||||
|
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||||
|
noexcept(noexcept(lhs.swap(rhs)));
|
||||||
|
} // namespace unordered
|
||||||
|
|
||||||
|
using boost::unordered::unordered_flat_set;
|
||||||
|
|
||||||
|
using boost::unordered::swap;
|
||||||
|
using boost::unordered::operator==;
|
||||||
|
using boost::unordered::operator!=;
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif
|
@ -47,6 +47,7 @@ run unordered/equivalent_keys_tests.cpp ;
|
|||||||
run unordered/constructor_tests.cpp ;
|
run unordered/constructor_tests.cpp ;
|
||||||
run unordered/copy_tests.cpp ;
|
run unordered/copy_tests.cpp ;
|
||||||
run unordered/move_tests.cpp ;
|
run unordered/move_tests.cpp ;
|
||||||
|
run unordered/post_move_tests.cpp ;
|
||||||
run unordered/assign_tests.cpp ;
|
run unordered/assign_tests.cpp ;
|
||||||
run unordered/insert_tests.cpp ;
|
run unordered/insert_tests.cpp ;
|
||||||
run unordered/insert_stable_tests.cpp ;
|
run unordered/insert_stable_tests.cpp ;
|
||||||
@ -95,3 +96,55 @@ run exception/swap_exception_tests.cpp : : : <define>BOOST_UNORDERED_SWAP_METHOD
|
|||||||
run exception/merge_exception_tests.cpp ;
|
run exception/merge_exception_tests.cpp ;
|
||||||
|
|
||||||
run quick.cpp ;
|
run quick.cpp ;
|
||||||
|
|
||||||
|
import ../../config/checks/config : requires ;
|
||||||
|
|
||||||
|
CPP11 = [ requires cxx11_constexpr cxx11_noexcept cxx11_decltype cxx11_alignas ] ;
|
||||||
|
|
||||||
|
rule build_foa ( name )
|
||||||
|
{
|
||||||
|
run unordered/$(name).cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_$(name) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
build_foa fwd_set_test ;
|
||||||
|
build_foa fwd_map_test ;
|
||||||
|
build_foa compile_set ;
|
||||||
|
build_foa compile_map ;
|
||||||
|
build_foa noexcept_tests ;
|
||||||
|
run unordered/link_test_1.cpp unordered/link_test_2.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_link_test ;
|
||||||
|
build_foa incomplete_test ;
|
||||||
|
build_foa simple_tests ;
|
||||||
|
build_foa equivalent_keys_tests ;
|
||||||
|
build_foa constructor_tests ;
|
||||||
|
build_foa copy_tests ;
|
||||||
|
build_foa move_tests ;
|
||||||
|
build_foa post_move_tests ;
|
||||||
|
build_foa assign_tests ;
|
||||||
|
build_foa insert_tests ;
|
||||||
|
build_foa insert_hint_tests ;
|
||||||
|
build_foa emplace_tests ;
|
||||||
|
build_foa erase_tests ;
|
||||||
|
build_foa merge_tests ;
|
||||||
|
build_foa find_tests ;
|
||||||
|
build_foa at_tests ;
|
||||||
|
build_foa load_factor_tests ;
|
||||||
|
build_foa rehash_tests ;
|
||||||
|
build_foa equality_tests ;
|
||||||
|
build_foa swap_tests ;
|
||||||
|
run unordered/scoped_allocator.cpp : : : $(CPP11) <toolset>msvc-14.0:<build>no <define>BOOST_UNORDERED_FOA_TESTS : foa_scoped_allocator ;
|
||||||
|
build_foa transparent_tests ;
|
||||||
|
build_foa reserve_tests ;
|
||||||
|
build_foa contains_tests ;
|
||||||
|
build_foa erase_if ;
|
||||||
|
build_foa scary_tests ;
|
||||||
|
build_foa init_type_insert_tests ;
|
||||||
|
|
||||||
|
run exception/constructor_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_constructor_exception_tests ;
|
||||||
|
run exception/copy_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_copy_exception_tests ;
|
||||||
|
run exception/assign_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_assign_exception_tests ;
|
||||||
|
run exception/move_assign_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_move_assign_exception_tests ;
|
||||||
|
run exception/insert_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_insert_exception_tests ;
|
||||||
|
run exception/erase_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_erase_exception_tests ;
|
||||||
|
run exception/rehash_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_rehash_exception_tests ;
|
||||||
|
run exception/swap_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_swap_exception_tests ;
|
||||||
|
run exception/merge_exception_tests.cpp : : : $(CPP11) <define>BOOST_UNORDERED_FOA_TESTS : foa_merge_exception_tests ;
|
||||||
|
@ -1,17 +1,33 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../objects/exception.hpp"
|
#include "../objects/exception.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<test::exception::object,
|
||||||
|
test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator<test::exception::object> >
|
||||||
|
test_set;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_map<test::exception::object,
|
||||||
|
test::exception::object, test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator2<test::exception::object> >
|
||||||
|
test_map;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_set<
|
||||||
|
std::pair<test::exception::object, test::exception::object>,
|
||||||
|
test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator<test::exception::object> >
|
||||||
|
test_pair_set;
|
||||||
|
|
||||||
|
#define CONTAINER_SEQ (test_set)(test_map)
|
||||||
|
#define CONTAINER_PAIR_SEQ (test_pair_set)(test_map)
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<test::exception::object, test::exception::hash,
|
typedef boost::unordered_set<test::exception::object, test::exception::hash,
|
||||||
test::exception::equal_to,
|
test::exception::equal_to,
|
||||||
test::exception::allocator<test::exception::object> >
|
test::exception::allocator<test::exception::object> >
|
||||||
@ -42,3 +58,5 @@ typedef boost::unordered_multiset<
|
|||||||
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
|
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
|
||||||
#define CONTAINER_PAIR_SEQ \
|
#define CONTAINER_PAIR_SEQ \
|
||||||
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)
|
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
#include "./containers.hpp"
|
#include "./containers.hpp"
|
||||||
@ -221,16 +222,41 @@ struct emplace_lvalue_pos_type
|
|||||||
} emplace_lvalue_pos;
|
} emplace_lvalue_pos;
|
||||||
|
|
||||||
// Run the exception tests in various combinations.
|
// Run the exception tests in various combinations.
|
||||||
|
using test::default_generator;
|
||||||
|
using test::limited_range;
|
||||||
|
using test::generate_collisions;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_set* test_set_;
|
||||||
|
test_map* test_map_;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_TEST(insert_exception_test,
|
||||||
|
((test_set_)(test_map_))
|
||||||
|
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
|
||||||
|
(insert_lvalue_pos)(insert_single_item_range)
|
||||||
|
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
|
||||||
|
(emplace_lvalue_pos)
|
||||||
|
)
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
|
||||||
|
UNORDERED_TEST(insert_rehash_exception_test,
|
||||||
|
((test_set_)(test_map_))
|
||||||
|
((insert_lvalue)(insert_lvalue_begin)(insert_lvalue_end)
|
||||||
|
(insert_lvalue_pos)(insert_single_item_range)
|
||||||
|
(emplace_lvalue)(emplace_lvalue_begin)(emplace_lvalue_end)
|
||||||
|
(emplace_lvalue_pos)
|
||||||
|
)
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
#else
|
||||||
test_set* test_set_;
|
test_set* test_set_;
|
||||||
test_multiset* test_multiset_;
|
test_multiset* test_multiset_;
|
||||||
test_map* test_map_;
|
test_map* test_map_;
|
||||||
test_multimap* test_multimap_;
|
test_multimap* test_multimap_;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::limited_range;
|
|
||||||
using test::generate_collisions;
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
UNORDERED_TEST(insert_exception_test,
|
UNORDERED_TEST(insert_exception_test,
|
||||||
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
||||||
@ -252,6 +278,7 @@ UNORDERED_TEST(insert_rehash_exception_test,
|
|||||||
((default_generator)(limited_range)(generate_collisions))
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
)
|
)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
// Repeat insert tests with pairs
|
// Repeat insert tests with pairs
|
||||||
|
|
||||||
@ -259,8 +286,13 @@ struct pair_emplace_type : inserter_base
|
|||||||
{
|
{
|
||||||
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.emplace(std::piecewise_construct, std::make_tuple(it->first),
|
||||||
|
std::make_tuple(it->second));
|
||||||
|
#else
|
||||||
x.emplace(boost::unordered::piecewise_construct,
|
x.emplace(boost::unordered::piecewise_construct,
|
||||||
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} pair_emplace;
|
} pair_emplace;
|
||||||
|
|
||||||
@ -268,12 +300,34 @@ struct pair_emplace2_type : inserter_base
|
|||||||
{
|
{
|
||||||
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
template <typename T, typename Iterator> void operator()(T& x, Iterator it)
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.emplace_hint(x.begin(), std::piecewise_construct,
|
||||||
|
std::make_tuple(it->first),
|
||||||
|
std::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||||
|
#else
|
||||||
x.emplace_hint(x.begin(), boost::unordered::piecewise_construct,
|
x.emplace_hint(x.begin(), boost::unordered::piecewise_construct,
|
||||||
boost::make_tuple(it->first),
|
boost::make_tuple(it->first),
|
||||||
boost::make_tuple(it->second.tag1_, it->second.tag2_));
|
boost::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
} pair_emplace2;
|
} pair_emplace2;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_pair_set* test_pair_set_;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_TEST(insert_exception_test,
|
||||||
|
((test_pair_set_)(test_map_))
|
||||||
|
((pair_emplace)(pair_emplace2))
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
UNORDERED_TEST(insert_rehash_exception_test,
|
||||||
|
((test_pair_set_)(test_map_))
|
||||||
|
((pair_emplace)(pair_emplace2))
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
#else
|
||||||
test_pair_set* test_pair_set_;
|
test_pair_set* test_pair_set_;
|
||||||
test_pair_multiset* test_pair_multiset_;
|
test_pair_multiset* test_pair_multiset_;
|
||||||
|
|
||||||
@ -289,6 +343,7 @@ UNORDERED_TEST(insert_rehash_exception_test,
|
|||||||
((default_generator)(limited_range)(generate_collisions))
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
)
|
)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test inserting using operator[]
|
// Test inserting using operator[]
|
||||||
|
|
||||||
@ -401,6 +456,19 @@ void insert_range_rehash_exception_test(T*, test::random_generator gen)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_TEST(insert_range_exception_test,
|
||||||
|
((test_set_)(test_map_))
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
|
||||||
|
UNORDERED_TEST(insert_range_rehash_exception_test,
|
||||||
|
((test_set_)(test_map_))
|
||||||
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
#else
|
||||||
// clang-format off
|
// clang-format off
|
||||||
UNORDERED_TEST(insert_range_exception_test,
|
UNORDERED_TEST(insert_range_exception_test,
|
||||||
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
|
||||||
@ -412,5 +480,6 @@ UNORDERED_TEST(insert_range_rehash_exception_test,
|
|||||||
((default_generator)(limited_range)(generate_collisions))
|
((default_generator)(limited_range)(generate_collisions))
|
||||||
)
|
)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
// Copyright 2017-2018 Daniel James.
|
// Copyright 2017-2018 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@ -52,6 +53,53 @@ void merge_exception_test(T1 const*, T2 const*, std::size_t count12, int tag12,
|
|||||||
EXCEPTION_LOOP(merge_exception_test(x, y))
|
EXCEPTION_LOOP(merge_exception_test(x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::exception::object, test::exception::hash,
|
||||||
|
test::exception::equal_to,
|
||||||
|
test::exception::allocator<test::exception::object> >* test_set_;
|
||||||
|
boost::unordered_flat_map<test::exception::object, test::exception::object,
|
||||||
|
test::exception::hash, test::exception::equal_to,
|
||||||
|
test::exception::allocator2<test::exception::object> >* test_map_;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
|
||||||
|
((test_set_))
|
||||||
|
((test_set_))
|
||||||
|
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
|
||||||
|
((0x0000)(0x0001)(0x0102))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
)
|
||||||
|
UNORDERED_MULTI_TEST(map_merge, merge_exception_test,
|
||||||
|
((test_map_))
|
||||||
|
((test_map_))
|
||||||
|
((0x0000)(0x6400)(0x0064)(0x0a64)(0x3232))
|
||||||
|
((0x0101)(0x0200)(0x0201))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
((default_generator)(limited_range))
|
||||||
|
)
|
||||||
|
// Run fewer generate_collisions tests, as they're slow.
|
||||||
|
UNORDERED_MULTI_TEST(set_merge_collisions, merge_exception_test,
|
||||||
|
((test_set_))
|
||||||
|
((test_set_))
|
||||||
|
((0x0a0a))
|
||||||
|
((0x0202)(0x0100)(0x0201))
|
||||||
|
((generate_collisions))
|
||||||
|
((generate_collisions))
|
||||||
|
)
|
||||||
|
UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
|
||||||
|
((test_map_))
|
||||||
|
((test_map_))
|
||||||
|
((0x0a0a))
|
||||||
|
((0x0000)(0x0002)(0x0102))
|
||||||
|
((generate_collisions))
|
||||||
|
((generate_collisions))
|
||||||
|
)
|
||||||
|
#else
|
||||||
boost::unordered_set<test::exception::object, test::exception::hash,
|
boost::unordered_set<test::exception::object, test::exception::hash,
|
||||||
test::exception::equal_to,
|
test::exception::equal_to,
|
||||||
test::exception::allocator<test::exception::object> >* test_set_;
|
test::exception::allocator<test::exception::object> >* test_set_;
|
||||||
@ -65,10 +113,6 @@ boost::unordered_multimap<test::exception::object, test::exception::object,
|
|||||||
test::exception::hash, test::exception::equal_to,
|
test::exception::hash, test::exception::equal_to,
|
||||||
test::exception::allocator2<test::exception::object> >* test_multimap_;
|
test::exception::allocator2<test::exception::object> >* test_multimap_;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
|
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
|
||||||
((test_set_)(test_multiset_))
|
((test_set_)(test_multiset_))
|
||||||
@ -104,5 +148,6 @@ UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
|
|||||||
((generate_collisions))
|
((generate_collisions))
|
||||||
)
|
)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
RUN_TESTS_QUIET()
|
RUN_TESTS_QUIET()
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include "./containers.hpp"
|
#include "./containers.hpp"
|
||||||
|
|
||||||
|
#if defined(BOOST_UNORDERED_FOA_TESTS)
|
||||||
|
#define BOOST_UNORDERED_FOA_WEAK_GUARANTEE_SWAP_EXCEPTIONS_TESTS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../helpers/invariants.hpp"
|
#include "../helpers/invariants.hpp"
|
||||||
#include "../helpers/random_values.hpp"
|
#include "../helpers/random_values.hpp"
|
||||||
#include "../helpers/tracker.hpp"
|
#include "../helpers/tracker.hpp"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@ -53,11 +54,22 @@ namespace test {
|
|||||||
if (test::has_unique_keys<X>::value && count != 1)
|
if (test::has_unique_keys<X>::value && count != 1)
|
||||||
BOOST_ERROR("Non-unique key.");
|
BOOST_ERROR("Non-unique key.");
|
||||||
|
|
||||||
|
#if !defined(BOOST_UNORDERED_FOA_WEAK_GUARANTEE_SWAP_EXCEPTIONS_TESTS)
|
||||||
|
// we conditionally compile this check because our FOA implementation only
|
||||||
|
// exhibits the weak guarantee when swapping throws
|
||||||
|
//
|
||||||
|
// in this case, the hasher may be changed before the predicate and the
|
||||||
|
// arrays are swapped in which case, we can can find an element by
|
||||||
|
// iteration but unfortunately, it's in the wrong slot according to the
|
||||||
|
// new hash function so count(key) can wind up returning nothing when
|
||||||
|
// there really is something
|
||||||
if (x1.count(key) != count) {
|
if (x1.count(key) != count) {
|
||||||
BOOST_ERROR("Incorrect output of count.");
|
BOOST_ERROR("Incorrect output of count.");
|
||||||
std::cerr << x1.count(key) << "," << count << "\n";
|
std::cerr << x1.count(key) << "," << count << "\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// Check that the keys are in the correct bucket and are
|
// Check that the keys are in the correct bucket and are
|
||||||
// adjacent in the bucket.
|
// adjacent in the bucket.
|
||||||
typename X::size_type bucket = x1.bucket(key);
|
typename X::size_type bucket = x1.bucket(key);
|
||||||
@ -86,6 +98,7 @@ namespace test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check that size matches up.
|
// Check that size matches up.
|
||||||
@ -104,6 +117,7 @@ namespace test {
|
|||||||
if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||||
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// Check that size in the buckets matches up.
|
// Check that size in the buckets matches up.
|
||||||
|
|
||||||
typename X::size_type bucket_size = 0;
|
typename X::size_type bucket_size = 0;
|
||||||
@ -120,6 +134,7 @@ namespace test {
|
|||||||
BOOST_ERROR("x1.size() doesn't match bucket size.");
|
BOOST_ERROR("x1.size() doesn't match bucket size.");
|
||||||
std::cout << x1.size() << "/" << bucket_size << std::endl;
|
std::cout << x1.size() << "/" << bucket_size << std::endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
test/helpers/unordered.hpp
Normal file
22
test/helpers/unordered.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
// Copyright 2022 Christian Mazakas
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#if !defined(BOOST_UNORDERED_TEST_HELPERS_UNORDERED_HEADER)
|
||||||
|
#define BOOST_UNORDERED_TEST_HELPERS_UNORDERED_HEADER
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#include "prefix.hpp"
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
#include <boost/unordered/unordered_flat_set.hpp>
|
||||||
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
|
#include <boost/unordered/detail/implementation.hpp>
|
||||||
|
#else
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
#endif
|
||||||
|
#include "postfix.hpp"
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#endif
|
@ -11,6 +11,7 @@
|
|||||||
#if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
|
#if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
|
||||||
#define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
|
#define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
|
||||||
|
|
||||||
|
#include <boost/core/addressof.hpp>
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/core/pointer_traits.hpp>
|
#include <boost/core/pointer_traits.hpp>
|
||||||
#include <boost/move/move.hpp>
|
#include <boost/move/move.hpp>
|
||||||
@ -320,7 +321,7 @@ namespace test {
|
|||||||
bool operator!() const { return !ptr_; }
|
bool operator!() const { return !ptr_; }
|
||||||
|
|
||||||
static ptr pointer_to(T& p) {
|
static ptr pointer_to(T& p) {
|
||||||
return ptr(&p);
|
return ptr(boost::addressof(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'm not using the safe bool idiom because the containers should be
|
// I'm not using the safe bool idiom because the containers should be
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -201,6 +197,54 @@ namespace assign_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
template <typename T> bool is_propagate(T*)
|
||||||
|
{
|
||||||
|
return T::allocator_type::is_propagate_on_assign;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::allocator2<test::object> >* test_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||||
|
test_set_prop_assign;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||||
|
test_map_prop_assign;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||||
|
test_set_no_prop_assign;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||||
|
test_map_no_prop_assign;
|
||||||
|
|
||||||
|
UNORDERED_AUTO_TEST (check_traits) {
|
||||||
|
BOOST_TEST(!is_propagate(test_set));
|
||||||
|
BOOST_TEST(is_propagate(test_set_prop_assign));
|
||||||
|
BOOST_TEST(!is_propagate(test_set_no_prop_assign));
|
||||||
|
}
|
||||||
|
|
||||||
|
UNORDERED_TEST(assign_tests1,
|
||||||
|
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_assign)(test_map_prop_assign)(test_set_no_prop_assign)(test_map_no_prop_assign))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(assign_tests2,
|
||||||
|
((test_set)(test_map)(test_set_prop_assign)(test_map_prop_assign)(test_set_no_prop_assign)(test_map_no_prop_assign))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
std::allocator<test::object> >* test_map_std_alloc;
|
std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
@ -241,15 +285,6 @@ namespace assign_tests {
|
|||||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||||
test_multimap_no_prop_assign;
|
test_multimap_no_prop_assign;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
template <typename T> bool is_propagate(T*)
|
|
||||||
{
|
|
||||||
return T::allocator_type::is_propagate_on_assign;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (check_traits) {
|
UNORDERED_AUTO_TEST (check_traits) {
|
||||||
BOOST_TEST(!is_propagate(test_set));
|
BOOST_TEST(!is_propagate(test_set));
|
||||||
BOOST_TEST(is_propagate(test_set_prop_assign));
|
BOOST_TEST(is_propagate(test_set_prop_assign));
|
||||||
@ -271,13 +306,18 @@ namespace assign_tests {
|
|||||||
test_set_no_prop_assign)(test_multiset_no_prop_assign)(
|
test_set_no_prop_assign)(test_multiset_no_prop_assign)(
|
||||||
test_map_no_prop_assign)(test_multimap_no_prop_assign))(
|
test_map_no_prop_assign)(test_multimap_no_prop_assign))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (assign_default_initializer_list) {
|
UNORDERED_AUTO_TEST (assign_default_initializer_list) {
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
||||||
std::initializer_list<std::pair<int const, int> > init;
|
std::initializer_list<std::pair<int const, int> > init;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, int> x1;
|
||||||
|
#else
|
||||||
boost::unordered_map<int, int> x1;
|
boost::unordered_map<int, int> x1;
|
||||||
|
#endif
|
||||||
x1[25] = 3;
|
x1[25] = 3;
|
||||||
x1[16] = 10;
|
x1[16] = 10;
|
||||||
BOOST_TEST(!x1.empty());
|
BOOST_TEST(!x1.empty());
|
||||||
@ -291,7 +331,11 @@ namespace assign_tests {
|
|||||||
UNORDERED_AUTO_TEST (assign_initializer_list) {
|
UNORDERED_AUTO_TEST (assign_initializer_list) {
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> x;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> x;
|
boost::unordered_set<int> x;
|
||||||
|
#endif
|
||||||
x.insert(10);
|
x.insert(10);
|
||||||
x.insert(20);
|
x.insert(20);
|
||||||
x = {1, 2, -10};
|
x = {1, 2, -10};
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2007-2009 Daniel James.
|
// Copyright 2007-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -17,8 +14,13 @@ namespace at_tests {
|
|||||||
UNORDERED_AUTO_TEST (at_tests) {
|
UNORDERED_AUTO_TEST (at_tests) {
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<std::string, int> x;
|
||||||
|
boost::unordered_flat_map<std::string, int> const& x_const(x);
|
||||||
|
#else
|
||||||
boost::unordered_map<std::string, int> x;
|
boost::unordered_map<std::string, int> x;
|
||||||
boost::unordered_map<std::string, int> const& x_const(x);
|
boost::unordered_map<std::string, int> const& x_const(x);
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Check empty container" << std::endl;
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Check empty container" << std::endl;
|
||||||
|
|
||||||
|
@ -1,23 +1,41 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// This test creates the containers with members that meet their minimum
|
// This test creates the containers with members that meet their minimum
|
||||||
// requirements. Makes sure everything compiles and is defined correctly.
|
// requirements. Makes sure everything compiles and is defined correctly.
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/minimal.hpp"
|
#include "../objects/minimal.hpp"
|
||||||
#include "./compile_tests.hpp"
|
#include "./compile_tests.hpp"
|
||||||
|
|
||||||
// Explicit instantiation to catch compile-time errors
|
// Explicit instantiation to catch compile-time errors
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
|
||||||
|
// emulates what was already done for previous tests but without leaking to
|
||||||
|
// the detail namespace
|
||||||
|
//
|
||||||
|
template <typename K, typename T, typename H, typename P, typename A>
|
||||||
|
class instantiate_flat_map
|
||||||
|
{
|
||||||
|
typedef boost::unordered_flat_map<K, T, H, P, A> container;
|
||||||
|
container x;
|
||||||
|
};
|
||||||
|
|
||||||
|
template class instantiate_flat_map<int, int, boost::hash<int>,
|
||||||
|
std::equal_to<int>, test::minimal::allocator<int> >;
|
||||||
|
|
||||||
|
template class instantiate_flat_map<test::minimal::assignable const,
|
||||||
|
test::minimal::default_assignable const,
|
||||||
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<int> >;
|
||||||
|
|
||||||
|
#else
|
||||||
#define INSTANTIATE(type) \
|
#define INSTANTIATE(type) \
|
||||||
template class boost::unordered::detail::instantiate_##type
|
template class boost::unordered::detail::instantiate_##type
|
||||||
|
|
||||||
@ -35,6 +53,7 @@ INSTANTIATE(multimap)<test::minimal::assignable, test::minimal::assignable,
|
|||||||
test::minimal::hash<test::minimal::assignable>,
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<int> >;
|
test::minimal::allocator<int> >;
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test0) {
|
UNORDERED_AUTO_TEST (test0) {
|
||||||
test::minimal::constructor_param x;
|
test::minimal::constructor_param x;
|
||||||
@ -45,6 +64,19 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, int> int_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||||
|
int_map2;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<test::minimal::assignable,
|
||||||
|
test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<value_type> >
|
||||||
|
map;
|
||||||
|
#else
|
||||||
boost::unordered_map<int, int> int_map;
|
boost::unordered_map<int, int> int_map;
|
||||||
|
|
||||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -56,11 +88,13 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<value_type> >
|
test::minimal::allocator<value_type> >
|
||||||
map;
|
map;
|
||||||
|
#endif
|
||||||
|
|
||||||
container_test(int_map, std::pair<int const, int>(0, 0));
|
container_test(int_map, std::pair<int const, int>(0, 0));
|
||||||
container_test(int_map2, std::pair<int const, int>(0, 0));
|
container_test(int_map2, std::pair<int const, int>(0, 0));
|
||||||
container_test(map, value);
|
container_test(map, value);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||||
|
|
||||||
boost::unordered_multimap<int, int> int_multimap;
|
boost::unordered_multimap<int, int> int_multimap;
|
||||||
@ -78,6 +112,7 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
container_test(int_multimap, std::pair<int const, int>(0, 0));
|
container_test(int_multimap, std::pair<int const, int>(0, 0));
|
||||||
container_test(int_multimap2, std::pair<int const, int>(0, 0));
|
container_test(int_multimap2, std::pair<int const, int>(0, 0));
|
||||||
container_test(multimap, value);
|
container_test(multimap, value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (equality_tests) {
|
UNORDERED_AUTO_TEST (equality_tests) {
|
||||||
@ -85,6 +120,22 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
|||||||
test::minimal::copy_constructible_equality_comparable>
|
test::minimal::copy_constructible_equality_comparable>
|
||||||
value_type;
|
value_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, int> int_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||||
|
int_map2;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<
|
||||||
|
test::minimal::copy_constructible_equality_comparable,
|
||||||
|
test::minimal::copy_constructible_equality_comparable,
|
||||||
|
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||||
|
test::minimal::equal_to<
|
||||||
|
test::minimal::copy_constructible_equality_comparable>,
|
||||||
|
test::minimal::allocator<value_type> >
|
||||||
|
map;
|
||||||
|
#else
|
||||||
boost::unordered_map<int, int> int_map;
|
boost::unordered_map<int, int> int_map;
|
||||||
|
|
||||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -98,11 +149,13 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
|||||||
test::minimal::copy_constructible_equality_comparable>,
|
test::minimal::copy_constructible_equality_comparable>,
|
||||||
test::minimal::allocator<value_type> >
|
test::minimal::allocator<value_type> >
|
||||||
map;
|
map;
|
||||||
|
#endif
|
||||||
|
|
||||||
equality_test(int_map);
|
equality_test(int_map);
|
||||||
equality_test(int_map2);
|
equality_test(int_map2);
|
||||||
equality_test(map);
|
equality_test(map);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
boost::unordered_multimap<int, int> int_multimap;
|
boost::unordered_multimap<int, int> int_multimap;
|
||||||
|
|
||||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -121,6 +174,7 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
|||||||
equality_test(int_multimap);
|
equality_test(int_multimap);
|
||||||
equality_test(int_multimap2);
|
equality_test(int_multimap2);
|
||||||
equality_test(multimap);
|
equality_test(multimap);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test1) {
|
UNORDERED_AUTO_TEST (test1) {
|
||||||
@ -131,11 +185,19 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, int> map;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||||
|
map2;
|
||||||
|
#else
|
||||||
boost::unordered_map<int, int> map;
|
boost::unordered_map<int, int> map;
|
||||||
|
|
||||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||||
map2;
|
map2;
|
||||||
|
#endif
|
||||||
|
|
||||||
unordered_unique_test(map, map_value);
|
unordered_unique_test(map, map_value);
|
||||||
unordered_map_test(map, value, value);
|
unordered_map_test(map, value, value);
|
||||||
@ -147,6 +209,7 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
unordered_copyable_test(map2, value, map_value, hash, equal_to);
|
unordered_copyable_test(map2, value, map_value, hash, equal_to);
|
||||||
unordered_map_functions(map2, value, value);
|
unordered_map_functions(map2, value, value);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||||
|
|
||||||
boost::unordered_multimap<int, int> multimap;
|
boost::unordered_multimap<int, int> multimap;
|
||||||
@ -162,6 +225,7 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
unordered_equivalent_test(multimap2, map_value);
|
unordered_equivalent_test(multimap2, map_value);
|
||||||
unordered_map_test(multimap2, value, value);
|
unordered_map_test(multimap2, value, value);
|
||||||
unordered_copyable_test(multimap2, value, map_value, hash, equal_to);
|
unordered_copyable_test(multimap2, value, map_value, hash, equal_to);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test2) {
|
UNORDERED_AUTO_TEST (test2) {
|
||||||
@ -178,28 +242,46 @@ UNORDERED_AUTO_TEST (test2) {
|
|||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::minimal::assignable,
|
||||||
|
test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<map_value_type> >
|
||||||
|
map;
|
||||||
|
#else
|
||||||
boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
|
boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
|
||||||
test::minimal::hash<test::minimal::assignable>,
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<map_value_type> >
|
test::minimal::allocator<map_value_type> >
|
||||||
map;
|
map;
|
||||||
|
#endif
|
||||||
|
|
||||||
unordered_unique_test(map, map_value);
|
unordered_unique_test(map, map_value);
|
||||||
unordered_map_test(map, assignable, assignable);
|
unordered_map_test(map, assignable, assignable);
|
||||||
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
|
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
|
||||||
unordered_map_member_test(map, map_value);
|
unordered_map_member_test(map, map_value);
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::minimal::assignable,
|
||||||
|
test::minimal::default_assignable,
|
||||||
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<map_value_type> >
|
||||||
|
map2;
|
||||||
|
#else
|
||||||
boost::unordered_map<test::minimal::assignable,
|
boost::unordered_map<test::minimal::assignable,
|
||||||
test::minimal::default_assignable,
|
test::minimal::default_assignable,
|
||||||
test::minimal::hash<test::minimal::assignable>,
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<map_value_type> >
|
test::minimal::allocator<map_value_type> >
|
||||||
map2;
|
map2;
|
||||||
|
#endif
|
||||||
|
|
||||||
test::minimal::default_assignable default_assignable;
|
test::minimal::default_assignable default_assignable;
|
||||||
|
|
||||||
unordered_map_functions(map2, assignable, default_assignable);
|
unordered_map_functions(map2, assignable, default_assignable);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||||
|
|
||||||
boost::unordered_multimap<test::minimal::assignable,
|
boost::unordered_multimap<test::minimal::assignable,
|
||||||
@ -212,6 +294,7 @@ UNORDERED_AUTO_TEST (test2) {
|
|||||||
unordered_map_test(multimap, assignable, assignable);
|
unordered_map_test(multimap, assignable, assignable);
|
||||||
unordered_copyable_test(multimap, assignable, map_value, hash, equal_to);
|
unordered_copyable_test(multimap, assignable, map_value, hash, equal_to);
|
||||||
unordered_map_member_test(multimap, map_value);
|
unordered_map_member_test(multimap, map_value);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for ambiguity when using key convertible from iterator
|
// Test for ambiguity when using key convertible from iterator
|
||||||
@ -232,6 +315,11 @@ std::size_t hash_value(lwg2059_key x)
|
|||||||
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (lwg2059) {
|
UNORDERED_AUTO_TEST (lwg2059) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<lwg2059_key, int> x;
|
||||||
|
x.emplace(lwg2059_key(10), 5);
|
||||||
|
x.erase(x.begin());
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
boost::unordered_map<lwg2059_key, int> x;
|
boost::unordered_map<lwg2059_key, int> x;
|
||||||
x.emplace(lwg2059_key(10), 5);
|
x.emplace(lwg2059_key(10), 5);
|
||||||
@ -243,6 +331,7 @@ UNORDERED_AUTO_TEST (lwg2059) {
|
|||||||
x.emplace(lwg2059_key(10), 5);
|
x.emplace(lwg2059_key(10), 5);
|
||||||
x.erase(x.begin());
|
x.erase(x.begin());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// This test creates the containers with members that meet their minimum
|
// This test creates the containers with members that meet their minimum
|
||||||
// requirements. Makes sure everything compiles and is defined correctly.
|
// requirements. Makes sure everything compiles and is defined correctly.
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/minimal.hpp"
|
#include "../objects/minimal.hpp"
|
||||||
@ -18,6 +15,28 @@
|
|||||||
|
|
||||||
// Explicit instantiation to catch compile-time errors
|
// Explicit instantiation to catch compile-time errors
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
|
||||||
|
// emulates what was already done for previous tests but without leaking to
|
||||||
|
// the detail namespace
|
||||||
|
//
|
||||||
|
template <typename T, typename H, typename P, typename A>
|
||||||
|
class instantiate_flat_set
|
||||||
|
{
|
||||||
|
typedef boost::unordered_flat_set<T, H, P, A> container;
|
||||||
|
container x;
|
||||||
|
};
|
||||||
|
|
||||||
|
template class instantiate_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::allocator<int> >;
|
||||||
|
|
||||||
|
template class instantiate_flat_set<test::minimal::assignable const,
|
||||||
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<int> >;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define INSTANTIATE(type) \
|
#define INSTANTIATE(type) \
|
||||||
template class boost::unordered::detail::instantiate_##type
|
template class boost::unordered::detail::instantiate_##type
|
||||||
|
|
||||||
@ -35,6 +54,21 @@ INSTANTIATE(multiset)<test::minimal::assignable,
|
|||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<int> >;
|
test::minimal::allocator<int> >;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UNORDERED_AUTO_TEST (type_traits) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int> set_type;
|
||||||
|
#else
|
||||||
|
typedef boost::unordered_set<int> set_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef set_type::iterator iterator;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(boost::is_same<int const&,
|
||||||
|
std::iterator_traits<iterator>::reference>::value);
|
||||||
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test0) {
|
UNORDERED_AUTO_TEST (test0) {
|
||||||
test::minimal::constructor_param x;
|
test::minimal::constructor_param x;
|
||||||
|
|
||||||
@ -42,6 +76,19 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> int_set;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<int> >
|
||||||
|
int_set2;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::minimal::assignable,
|
||||||
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<test::minimal::assignable> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> int_set;
|
boost::unordered_set<int> int_set;
|
||||||
|
|
||||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -53,11 +100,13 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<test::minimal::assignable> >
|
test::minimal::allocator<test::minimal::assignable> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
container_test(int_set, 0);
|
container_test(int_set, 0);
|
||||||
container_test(int_set2, 0);
|
container_test(int_set2, 0);
|
||||||
container_test(set, assignable);
|
container_test(set, assignable);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
|
|
||||||
boost::unordered_multiset<int> int_multiset;
|
boost::unordered_multiset<int> int_multiset;
|
||||||
@ -75,11 +124,27 @@ UNORDERED_AUTO_TEST (test0) {
|
|||||||
container_test(int_multiset, 0);
|
container_test(int_multiset, 0);
|
||||||
container_test(int_multiset2, 0);
|
container_test(int_multiset2, 0);
|
||||||
container_test(multiset, assignable);
|
container_test(multiset, assignable);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (equality_tests) {
|
UNORDERED_AUTO_TEST (equality_tests) {
|
||||||
typedef test::minimal::copy_constructible_equality_comparable value_type;
|
typedef test::minimal::copy_constructible_equality_comparable value_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> int_set;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<int> >
|
||||||
|
int_set2;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<
|
||||||
|
test::minimal::copy_constructible_equality_comparable,
|
||||||
|
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||||
|
test::minimal::equal_to<
|
||||||
|
test::minimal::copy_constructible_equality_comparable>,
|
||||||
|
test::minimal::allocator<value_type> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> int_set;
|
boost::unordered_set<int> int_set;
|
||||||
|
|
||||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -92,11 +157,13 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
|||||||
test::minimal::copy_constructible_equality_comparable>,
|
test::minimal::copy_constructible_equality_comparable>,
|
||||||
test::minimal::allocator<value_type> >
|
test::minimal::allocator<value_type> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
equality_test(int_set);
|
equality_test(int_set);
|
||||||
equality_test(int_set2);
|
equality_test(int_set2);
|
||||||
equality_test(set);
|
equality_test(set);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
boost::unordered_multiset<int> int_multiset;
|
boost::unordered_multiset<int> int_multiset;
|
||||||
|
|
||||||
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
||||||
@ -114,6 +181,7 @@ UNORDERED_AUTO_TEST (equality_tests) {
|
|||||||
equality_test(int_multiset);
|
equality_test(int_multiset);
|
||||||
equality_test(int_multiset2);
|
equality_test(int_multiset2);
|
||||||
equality_test(multiset);
|
equality_test(multiset);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test1) {
|
UNORDERED_AUTO_TEST (test1) {
|
||||||
@ -122,12 +190,19 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set." << std::endl;
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set." << std::endl;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> set;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
|
test::minimal::cxx11_allocator<int> >
|
||||||
|
set2;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> set;
|
boost::unordered_set<int> set;
|
||||||
|
|
||||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
test::minimal::cxx11_allocator<int> >
|
test::minimal::cxx11_allocator<int> >
|
||||||
set2;
|
set2;
|
||||||
|
#endif
|
||||||
|
|
||||||
unordered_unique_test(set, value);
|
unordered_unique_test(set, value);
|
||||||
unordered_set_test(set, value);
|
unordered_set_test(set, value);
|
||||||
@ -137,6 +212,7 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
unordered_set_test(set2, value);
|
unordered_set_test(set2, value);
|
||||||
unordered_copyable_test(set2, value, value, hash, equal_to);
|
unordered_copyable_test(set2, value, value, hash, equal_to);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset." << std::endl;
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset." << std::endl;
|
||||||
|
|
||||||
boost::unordered_multiset<int> multiset;
|
boost::unordered_multiset<int> multiset;
|
||||||
@ -152,6 +228,7 @@ UNORDERED_AUTO_TEST (test1) {
|
|||||||
unordered_equivalent_test(multiset2, value);
|
unordered_equivalent_test(multiset2, value);
|
||||||
unordered_set_test(multiset2, value);
|
unordered_set_test(multiset2, value);
|
||||||
unordered_copyable_test(multiset2, value, value, hash, equal_to);
|
unordered_copyable_test(multiset2, value, value, hash, equal_to);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test2) {
|
UNORDERED_AUTO_TEST (test2) {
|
||||||
@ -163,18 +240,26 @@ UNORDERED_AUTO_TEST (test2) {
|
|||||||
test::minimal::equal_to<test::minimal::assignable> equal_to(x);
|
test::minimal::equal_to<test::minimal::assignable> equal_to(x);
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::minimal::assignable,
|
||||||
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
|
test::minimal::allocator<test::minimal::assignable> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<test::minimal::assignable,
|
boost::unordered_set<test::minimal::assignable,
|
||||||
test::minimal::hash<test::minimal::assignable>,
|
test::minimal::hash<test::minimal::assignable>,
|
||||||
test::minimal::equal_to<test::minimal::assignable>,
|
test::minimal::equal_to<test::minimal::assignable>,
|
||||||
test::minimal::allocator<test::minimal::assignable> >
|
test::minimal::allocator<test::minimal::assignable> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
unordered_unique_test(set, assignable);
|
unordered_unique_test(set, assignable);
|
||||||
unordered_set_test(set, assignable);
|
unordered_set_test(set, assignable);
|
||||||
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
|
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
|
||||||
unordered_set_member_test(set, assignable);
|
unordered_set_member_test(set, assignable);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
|
|
||||||
boost::unordered_multiset<test::minimal::assignable,
|
boost::unordered_multiset<test::minimal::assignable,
|
||||||
@ -187,6 +272,7 @@ UNORDERED_AUTO_TEST (test2) {
|
|||||||
unordered_set_test(multiset, assignable);
|
unordered_set_test(multiset, assignable);
|
||||||
unordered_copyable_test(multiset, assignable, assignable, hash, equal_to);
|
unordered_copyable_test(multiset, assignable, assignable, hash, equal_to);
|
||||||
unordered_set_member_test(multiset, assignable);
|
unordered_set_member_test(multiset, assignable);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (movable1_tests) {
|
UNORDERED_AUTO_TEST (movable1_tests) {
|
||||||
@ -197,17 +283,25 @@ UNORDERED_AUTO_TEST (movable1_tests) {
|
|||||||
test::minimal::equal_to<test::minimal::movable1> equal_to(x);
|
test::minimal::equal_to<test::minimal::movable1> equal_to(x);
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::minimal::movable1,
|
||||||
|
test::minimal::hash<test::minimal::movable1>,
|
||||||
|
test::minimal::equal_to<test::minimal::movable1>,
|
||||||
|
test::minimal::allocator<test::minimal::movable1> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<test::minimal::movable1,
|
boost::unordered_set<test::minimal::movable1,
|
||||||
test::minimal::hash<test::minimal::movable1>,
|
test::minimal::hash<test::minimal::movable1>,
|
||||||
test::minimal::equal_to<test::minimal::movable1>,
|
test::minimal::equal_to<test::minimal::movable1>,
|
||||||
test::minimal::allocator<test::minimal::movable1> >
|
test::minimal::allocator<test::minimal::movable1> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
// unordered_unique_test(set, movable1);
|
// unordered_unique_test(set, movable1);
|
||||||
unordered_set_test(set, movable1);
|
unordered_set_test(set, movable1);
|
||||||
unordered_movable_test(set, movable1, movable1, hash, equal_to);
|
unordered_movable_test(set, movable1, movable1, hash, equal_to);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
|
|
||||||
boost::unordered_multiset<test::minimal::movable1,
|
boost::unordered_multiset<test::minimal::movable1,
|
||||||
@ -219,6 +313,7 @@ UNORDERED_AUTO_TEST (movable1_tests) {
|
|||||||
// unordered_equivalent_test(multiset, movable1);
|
// unordered_equivalent_test(multiset, movable1);
|
||||||
unordered_set_test(multiset, movable1);
|
unordered_set_test(multiset, movable1);
|
||||||
unordered_movable_test(multiset, movable1, movable1, hash, equal_to);
|
unordered_movable_test(multiset, movable1, movable1, hash, equal_to);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (movable2_tests) {
|
UNORDERED_AUTO_TEST (movable2_tests) {
|
||||||
@ -229,17 +324,25 @@ UNORDERED_AUTO_TEST (movable2_tests) {
|
|||||||
test::minimal::equal_to<test::minimal::movable2> equal_to(x);
|
test::minimal::equal_to<test::minimal::movable2> equal_to(x);
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::minimal::movable2,
|
||||||
|
test::minimal::hash<test::minimal::movable2>,
|
||||||
|
test::minimal::equal_to<test::minimal::movable2>,
|
||||||
|
test::minimal::allocator<test::minimal::movable2> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<test::minimal::movable2,
|
boost::unordered_set<test::minimal::movable2,
|
||||||
test::minimal::hash<test::minimal::movable2>,
|
test::minimal::hash<test::minimal::movable2>,
|
||||||
test::minimal::equal_to<test::minimal::movable2>,
|
test::minimal::equal_to<test::minimal::movable2>,
|
||||||
test::minimal::allocator<test::minimal::movable2> >
|
test::minimal::allocator<test::minimal::movable2> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
// unordered_unique_test(set, movable2);
|
// unordered_unique_test(set, movable2);
|
||||||
unordered_set_test(set, movable2);
|
unordered_set_test(set, movable2);
|
||||||
unordered_movable_test(set, movable2, movable2, hash, equal_to);
|
unordered_movable_test(set, movable2, movable2, hash, equal_to);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
|
|
||||||
boost::unordered_multiset<test::minimal::movable2,
|
boost::unordered_multiset<test::minimal::movable2,
|
||||||
@ -251,6 +354,7 @@ UNORDERED_AUTO_TEST (movable2_tests) {
|
|||||||
// unordered_equivalent_test(multiset, movable2);
|
// unordered_equivalent_test(multiset, movable2);
|
||||||
unordered_set_test(multiset, movable2);
|
unordered_set_test(multiset, movable2);
|
||||||
unordered_movable_test(multiset, movable2, movable2, hash, equal_to);
|
unordered_movable_test(multiset, movable2, movable2, hash, equal_to);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (destructible_tests) {
|
UNORDERED_AUTO_TEST (destructible_tests) {
|
||||||
@ -261,14 +365,21 @@ UNORDERED_AUTO_TEST (destructible_tests) {
|
|||||||
test::minimal::equal_to<test::minimal::destructible> equal_to(x);
|
test::minimal::equal_to<test::minimal::destructible> equal_to(x);
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::minimal::destructible,
|
||||||
|
test::minimal::hash<test::minimal::destructible>,
|
||||||
|
test::minimal::equal_to<test::minimal::destructible> >
|
||||||
|
set;
|
||||||
|
#else
|
||||||
boost::unordered_set<test::minimal::destructible,
|
boost::unordered_set<test::minimal::destructible,
|
||||||
test::minimal::hash<test::minimal::destructible>,
|
test::minimal::hash<test::minimal::destructible>,
|
||||||
test::minimal::equal_to<test::minimal::destructible> >
|
test::minimal::equal_to<test::minimal::destructible> >
|
||||||
set;
|
set;
|
||||||
|
#endif
|
||||||
|
|
||||||
unordered_destructible_test(set);
|
unordered_destructible_test(set);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
|
|
||||||
boost::unordered_multiset<test::minimal::destructible,
|
boost::unordered_multiset<test::minimal::destructible,
|
||||||
@ -277,6 +388,7 @@ UNORDERED_AUTO_TEST (destructible_tests) {
|
|||||||
multiset;
|
multiset;
|
||||||
|
|
||||||
unordered_destructible_test(multiset);
|
unordered_destructible_test(multiset);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for ambiguity when using key convertible from iterator
|
// Test for ambiguity when using key convertible from iterator
|
||||||
@ -297,6 +409,11 @@ std::size_t hash_value(lwg2059_key x)
|
|||||||
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (lwg2059) {
|
UNORDERED_AUTO_TEST (lwg2059) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<lwg2059_key> x;
|
||||||
|
x.emplace(lwg2059_key(10));
|
||||||
|
x.erase(x.begin());
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
boost::unordered_set<lwg2059_key> x;
|
boost::unordered_set<lwg2059_key> x;
|
||||||
x.emplace(lwg2059_key(10));
|
x.emplace(lwg2059_key(10));
|
||||||
@ -308,6 +425,7 @@ UNORDERED_AUTO_TEST (lwg2059) {
|
|||||||
x.emplace(lwg2059_key(10));
|
x.emplace(lwg2059_key(10));
|
||||||
x.erase(x.begin());
|
x.erase(x.begin());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
// Copyright 2005-2009 Daniel James.
|
// Copyright 2005-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
@ -70,9 +71,19 @@ template <class X, class T> void container_test(X& r, T const&)
|
|||||||
typedef typename X::reference reference;
|
typedef typename X::reference reference;
|
||||||
typedef typename X::const_reference const_reference;
|
typedef typename X::const_reference const_reference;
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::node_type node_type;
|
typedef typename X::node_type node_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef typename X::allocator_type allocator_type;
|
typedef typename X::allocator_type allocator_type;
|
||||||
|
typedef typename X::pointer pointer;
|
||||||
|
typedef typename X::const_pointer const_pointer;
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<pointer,
|
||||||
|
typename boost::allocator_pointer<allocator_type>::type>::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<const_pointer,
|
||||||
|
typename boost::allocator_const_pointer<allocator_type>::type>::value));
|
||||||
|
|
||||||
// value_type
|
// value_type
|
||||||
|
|
||||||
@ -97,8 +108,10 @@ template <class X, class T> void container_test(X& r, T const&)
|
|||||||
|
|
||||||
// node_type
|
// node_type
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_STATIC_ASSERT((
|
BOOST_STATIC_ASSERT((
|
||||||
boost::is_same<allocator_type, typename node_type::allocator_type>::value));
|
boost::is_same<allocator_type, typename node_type::allocator_type>::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
// difference_type
|
// difference_type
|
||||||
|
|
||||||
@ -167,6 +180,7 @@ template <class X, class T> void container_test(X& r, T const&)
|
|||||||
sink(X(rvalue(a_const), m));
|
sink(X(rvalue(a_const), m));
|
||||||
X c3(rvalue(a_const), m);
|
X c3(rvalue(a_const), m);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// node_type
|
// node_type
|
||||||
|
|
||||||
implicit_construct<node_type const>();
|
implicit_construct<node_type const>();
|
||||||
@ -193,6 +207,7 @@ template <class X, class T> void container_test(X& r, T const&)
|
|||||||
test::check_return_type<bool>::equals(n_const.empty());
|
test::check_return_type<bool>::equals(n_const.empty());
|
||||||
TEST_NOEXCEPT_EXPR(!n_const);
|
TEST_NOEXCEPT_EXPR(!n_const);
|
||||||
TEST_NOEXCEPT_EXPR(n_const.empty());
|
TEST_NOEXCEPT_EXPR(n_const.empty());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Avoid unused variable warnings:
|
// Avoid unused variable warnings:
|
||||||
|
|
||||||
@ -262,24 +277,30 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
|||||||
|
|
||||||
typedef typename X::iterator iterator;
|
typedef typename X::iterator iterator;
|
||||||
typedef typename X::const_iterator const_iterator;
|
typedef typename X::const_iterator const_iterator;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::local_iterator local_iterator;
|
typedef typename X::local_iterator local_iterator;
|
||||||
typedef typename X::const_local_iterator const_local_iterator;
|
typedef typename X::const_local_iterator const_local_iterator;
|
||||||
|
#endif
|
||||||
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
||||||
typedef typename std::iterator_traits<const_iterator>::pointer
|
typedef typename std::iterator_traits<const_iterator>::pointer
|
||||||
const_iterator_pointer;
|
const_iterator_pointer;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename std::iterator_traits<local_iterator>::pointer
|
typedef typename std::iterator_traits<local_iterator>::pointer
|
||||||
local_iterator_pointer;
|
local_iterator_pointer;
|
||||||
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
||||||
const_local_iterator_pointer;
|
const_local_iterator_pointer;
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, iterator_pointer>::value));
|
(boost::is_same<value_type const*, iterator_pointer>::value));
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, local_iterator_pointer>::value));
|
(boost::is_same<value_type const*, local_iterator_pointer>::value));
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
// pointer_traits<iterator>
|
// pointer_traits<iterator>
|
||||||
|
|
||||||
@ -299,6 +320,8 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
|||||||
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
||||||
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
||||||
|
|
||||||
|
(void) r;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// pointer_traits<local_iterator>
|
// pointer_traits<local_iterator>
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
||||||
@ -330,6 +353,7 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
|||||||
r.emplace(boost::move(k_lvalue));
|
r.emplace(boost::move(k_lvalue));
|
||||||
node_type n1 = r.extract(r.begin());
|
node_type n1 = r.extract(r.begin());
|
||||||
test::check_return_type<value_type>::equals_ref(n1.value());
|
test::check_return_type<value_type>::equals_ref(n1.value());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X, class Key, class T>
|
template <class X, class Key, class T>
|
||||||
@ -345,23 +369,29 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
|
|
||||||
typedef typename X::iterator iterator;
|
typedef typename X::iterator iterator;
|
||||||
typedef typename X::const_iterator const_iterator;
|
typedef typename X::const_iterator const_iterator;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::local_iterator local_iterator;
|
typedef typename X::local_iterator local_iterator;
|
||||||
typedef typename X::const_local_iterator const_local_iterator;
|
typedef typename X::const_local_iterator const_local_iterator;
|
||||||
|
#endif
|
||||||
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
typedef typename std::iterator_traits<iterator>::pointer iterator_pointer;
|
||||||
typedef typename std::iterator_traits<const_iterator>::pointer
|
typedef typename std::iterator_traits<const_iterator>::pointer
|
||||||
const_iterator_pointer;
|
const_iterator_pointer;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename std::iterator_traits<local_iterator>::pointer
|
typedef typename std::iterator_traits<local_iterator>::pointer
|
||||||
local_iterator_pointer;
|
local_iterator_pointer;
|
||||||
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
typedef typename std::iterator_traits<const_local_iterator>::pointer
|
||||||
const_local_iterator_pointer;
|
const_local_iterator_pointer;
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
|
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
(boost::is_same<value_type const*, const_iterator_pointer>::value));
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type*, local_iterator_pointer>::value));
|
(boost::is_same<value_type*, local_iterator_pointer>::value));
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
// pointer_traits<iterator>
|
// pointer_traits<iterator>
|
||||||
|
|
||||||
@ -381,6 +411,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
|
||||||
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
typename boost::pointer_traits<const_iterator>::difference_type>::value));
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// pointer_traits<local_iterator>
|
// pointer_traits<local_iterator>
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
|
||||||
@ -409,6 +440,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
BOOST_STATIC_ASSERT((boost::is_same<T, node_mapped_type>::value));
|
BOOST_STATIC_ASSERT((boost::is_same<T, node_mapped_type>::value));
|
||||||
// Superfluous,but just to make sure.
|
// Superfluous,but just to make sure.
|
||||||
BOOST_STATIC_ASSERT((!boost::is_const<node_key_type>::value));
|
BOOST_STATIC_ASSERT((!boost::is_const<node_key_type>::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Calling functions
|
// Calling functions
|
||||||
|
|
||||||
@ -427,8 +459,12 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
r.emplace(k_lvalue, v_lvalue);
|
r.emplace(k_lvalue, v_lvalue);
|
||||||
r.emplace(rvalue(k), rvalue(v));
|
r.emplace(rvalue(k), rvalue(v));
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
r.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple(v));
|
||||||
|
#else
|
||||||
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
|
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
|
||||||
boost::make_tuple(v));
|
boost::make_tuple(v));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Emplace with hint
|
// Emplace with hint
|
||||||
|
|
||||||
@ -436,9 +472,15 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
r.emplace_hint(r.begin(), k_lvalue, v_lvalue);
|
r.emplace_hint(r.begin(), k_lvalue, v_lvalue);
|
||||||
r.emplace_hint(r.begin(), rvalue(k), rvalue(v));
|
r.emplace_hint(r.begin(), rvalue(k), rvalue(v));
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
r.emplace_hint(r.begin(), std::piecewise_construct, std::make_tuple(k),
|
||||||
|
std::make_tuple(v));
|
||||||
|
#else
|
||||||
r.emplace_hint(r.begin(), boost::unordered::piecewise_construct,
|
r.emplace_hint(r.begin(), boost::unordered::piecewise_construct,
|
||||||
boost::make_tuple(k), boost::make_tuple(v));
|
boost::make_tuple(k), boost::make_tuple(v));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// Extract
|
// Extract
|
||||||
|
|
||||||
test::check_return_type<node_type>::equals(r.extract(r.begin()));
|
test::check_return_type<node_type>::equals(r.extract(r.begin()));
|
||||||
@ -461,6 +503,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
|||||||
node_type n = r.extract(r.begin());
|
node_type n = r.extract(r.begin());
|
||||||
test::check_return_type<node_key_type>::equals_ref(n.key());
|
test::check_return_type<node_key_type>::equals_ref(n.key());
|
||||||
test::check_return_type<node_mapped_type>::equals_ref(n.mapped());
|
test::check_return_type<node_mapped_type>::equals_ref(n.mapped());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X> void equality_test(X& r)
|
template <class X> void equality_test(X& r)
|
||||||
@ -479,6 +522,7 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
|||||||
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
|
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
|
||||||
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
|
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::node_type node_type;
|
typedef typename X::node_type node_type;
|
||||||
typedef typename X::insert_return_type insert_return_type;
|
typedef typename X::insert_return_type insert_return_type;
|
||||||
|
|
||||||
@ -503,6 +547,7 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
|||||||
test::check_return_type<iterator>::equals(insert_return.position);
|
test::check_return_type<iterator>::equals(insert_return.position);
|
||||||
test::check_return_type<node_type>::equals_ref(insert_return.node);
|
test::check_return_type<node_type>::equals_ref(insert_return.node);
|
||||||
boost::swap(insert_return, insert_return2);
|
boost::swap(insert_return, insert_return2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
|
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
|
||||||
@ -554,6 +599,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
|
|
||||||
typedef typename X::iterator iterator;
|
typedef typename X::iterator iterator;
|
||||||
typedef typename X::const_iterator const_iterator;
|
typedef typename X::const_iterator const_iterator;
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::local_iterator local_iterator;
|
typedef typename X::local_iterator local_iterator;
|
||||||
typedef typename X::const_local_iterator const_local_iterator;
|
typedef typename X::const_local_iterator const_local_iterator;
|
||||||
|
|
||||||
@ -590,6 +636,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
const_local_iterator_pointer;
|
const_local_iterator_pointer;
|
||||||
typedef typename std::iterator_traits<const_local_iterator>::reference
|
typedef typename std::iterator_traits<const_local_iterator>::reference
|
||||||
const_local_iterator_reference;
|
const_local_iterator_reference;
|
||||||
|
#endif
|
||||||
typedef typename X::allocator_type allocator_type;
|
typedef typename X::allocator_type allocator_type;
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
|
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
|
||||||
@ -602,6 +649,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
BOOST_STATIC_ASSERT((boost::is_same<Pred, key_equal>::value));
|
BOOST_STATIC_ASSERT((boost::is_same<Pred, key_equal>::value));
|
||||||
test::check_return_type<bool>::convertible(eq(k, k));
|
test::check_return_type<bool>::convertible(eq(k, k));
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
|
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
(boost::is_same<local_iterator_category, iterator_category>::value));
|
(boost::is_same<local_iterator_category, iterator_category>::value));
|
||||||
@ -622,6 +670,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
const_iterator_pointer>::value));
|
const_iterator_pointer>::value));
|
||||||
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_reference,
|
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_reference,
|
||||||
const_iterator_reference>::value));
|
const_iterator_reference>::value));
|
||||||
|
#endif
|
||||||
|
|
||||||
X a;
|
X a;
|
||||||
allocator_type m = a.get_allocator();
|
allocator_type m = a.get_allocator();
|
||||||
@ -667,6 +716,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
|
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
|
||||||
b.equal_range(k));
|
b.equal_range(k));
|
||||||
test::check_return_type<size_type>::equals(b.bucket_count());
|
test::check_return_type<size_type>::equals(b.bucket_count());
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
test::check_return_type<size_type>::equals(b.max_bucket_count());
|
test::check_return_type<size_type>::equals(b.max_bucket_count());
|
||||||
test::check_return_type<size_type>::equals(b.bucket(k));
|
test::check_return_type<size_type>::equals(b.bucket(k));
|
||||||
test::check_return_type<size_type>::equals(b.bucket_size(0));
|
test::check_return_type<size_type>::equals(b.bucket_size(0));
|
||||||
@ -680,6 +730,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
|||||||
test::check_return_type<const_local_iterator>::equals(b.cbegin(0));
|
test::check_return_type<const_local_iterator>::equals(b.cbegin(0));
|
||||||
test::check_return_type<const_local_iterator>::equals(a.cend(0));
|
test::check_return_type<const_local_iterator>::equals(a.cend(0));
|
||||||
test::check_return_type<const_local_iterator>::equals(b.cend(0));
|
test::check_return_type<const_local_iterator>::equals(b.cend(0));
|
||||||
|
#endif
|
||||||
|
|
||||||
test::check_return_type<float>::equals(b.load_factor());
|
test::check_return_type<float>::equals(b.load_factor());
|
||||||
test::check_return_type<float>::equals(b.max_load_factor());
|
test::check_return_type<float>::equals(b.max_load_factor());
|
||||||
@ -792,7 +843,11 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
|||||||
X a10;
|
X a10;
|
||||||
a10.insert(t);
|
a10.insert(t);
|
||||||
q = a10.cbegin();
|
q = a10.cbegin();
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_STATIC_ASSERT(std::is_same<void, decltype(a10.erase(q))>::value);
|
||||||
|
#else
|
||||||
test::check_return_type<iterator>::equals(a10.erase(q));
|
test::check_return_type<iterator>::equals(a10.erase(q));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Avoid unused variable warnings:
|
// Avoid unused variable warnings:
|
||||||
|
|
||||||
@ -807,10 +862,12 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
|||||||
sink(a7a);
|
sink(a7a);
|
||||||
sink(a9a);
|
sink(a9a);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename X::node_type node_type;
|
typedef typename X::node_type node_type;
|
||||||
typedef typename X::allocator_type allocator_type;
|
typedef typename X::allocator_type allocator_type;
|
||||||
node_type const n_const = a.extract(a.begin());
|
node_type const n_const = a.extract(a.begin());
|
||||||
test::check_return_type<allocator_type>::equals(n_const.get_allocator());
|
test::check_return_type<allocator_type>::equals(n_const.get_allocator());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X, class Key, class T, class Hash, class Pred>
|
template <class X, class Key, class T, class Hash, class Pred>
|
||||||
@ -879,7 +936,11 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
|||||||
T v5(v);
|
T v5(v);
|
||||||
a10.insert(boost::move(v5));
|
a10.insert(boost::move(v5));
|
||||||
q = a10.cbegin();
|
q = a10.cbegin();
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_STATIC_ASSERT(std::is_same<void, decltype(a10.erase(q))>::value);
|
||||||
|
#else
|
||||||
test::check_return_type<iterator>::equals(a10.erase(q));
|
test::check_return_type<iterator>::equals(a10.erase(q));
|
||||||
|
#endif
|
||||||
|
|
||||||
// Avoid unused variable warnings:
|
// Avoid unused variable warnings:
|
||||||
|
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2010 Daniel James.
|
// Copyright 2006-2010 Daniel James.
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -497,6 +493,35 @@ namespace constructor_tests {
|
|||||||
test::check_equivalent_keys(x);
|
test::check_equivalent_keys(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::allocator2<test::object> >* test_map;
|
||||||
|
|
||||||
|
UNORDERED_TEST(constructor_tests1,
|
||||||
|
((test_map_std_alloc)(test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(constructor_tests2,
|
||||||
|
((test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(map_constructor_test,
|
||||||
|
((test_map_std_alloc)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(no_alloc_default_construct_test,
|
||||||
|
((test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
std::allocator<test::object> >* test_map_std_alloc;
|
std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
@ -509,10 +534,6 @@ namespace constructor_tests {
|
|||||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(constructor_tests1,
|
UNORDERED_TEST(constructor_tests1,
|
||||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
@ -528,12 +549,17 @@ namespace constructor_tests {
|
|||||||
UNORDERED_TEST(no_alloc_default_construct_test,
|
UNORDERED_TEST(no_alloc_default_construct_test,
|
||||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test_default_initializer_list) {
|
UNORDERED_AUTO_TEST (test_default_initializer_list) {
|
||||||
std::initializer_list<int> init;
|
std::initializer_list<int> init;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> x1 = init;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> x1 = init;
|
boost::unordered_set<int> x1 = init;
|
||||||
|
#endif
|
||||||
BOOST_TEST(x1.empty());
|
BOOST_TEST(x1.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +568,12 @@ namespace constructor_tests {
|
|||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test_initializer_list) {
|
UNORDERED_AUTO_TEST (test_initializer_list) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> x1 = {2, 10, 45, -5};
|
||||||
|
#else
|
||||||
boost::unordered_set<int> x1 = {2, 10, 45, -5};
|
boost::unordered_set<int> x1 = {2, 10, 45, -5};
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_TEST(x1.find(10) != x1.end());
|
BOOST_TEST(x1.find(10) != x1.end());
|
||||||
BOOST_TEST(x1.find(46) == x1.end());
|
BOOST_TEST(x1.find(46) == x1.end());
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
// Copyright 2021 Christian Mazakas.
|
// Copyright 2021-2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
@ -129,6 +124,20 @@ template <class UnorderedMap> void test_map_non_transparent_contains()
|
|||||||
|
|
||||||
void test_map()
|
void test_map()
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<key, int, transparent_hasher,
|
||||||
|
transparent_key_equal>
|
||||||
|
transparent_map;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_map<key, int, transparent_hasher, key_equal>
|
||||||
|
non_transparent_map1;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_map<key, int, hasher, transparent_key_equal>
|
||||||
|
non_transparent_map2;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_map<key, int, hasher, key_equal>
|
||||||
|
non_transparent_map3;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<key, int, transparent_hasher,
|
typedef boost::unordered_map<key, int, transparent_hasher,
|
||||||
transparent_key_equal>
|
transparent_key_equal>
|
||||||
transparent_map;
|
transparent_map;
|
||||||
@ -141,6 +150,7 @@ void test_map()
|
|||||||
|
|
||||||
typedef boost::unordered_map<key, int, hasher, key_equal>
|
typedef boost::unordered_map<key, int, hasher, key_equal>
|
||||||
non_transparent_map3;
|
non_transparent_map3;
|
||||||
|
#endif
|
||||||
|
|
||||||
test_map_transparent_contains<transparent_map>();
|
test_map_transparent_contains<transparent_map>();
|
||||||
test_map_non_transparent_contains<non_transparent_map1>();
|
test_map_non_transparent_contains<non_transparent_map1>();
|
||||||
@ -148,6 +158,7 @@ void test_map()
|
|||||||
test_map_non_transparent_contains<non_transparent_map3>();
|
test_map_non_transparent_contains<non_transparent_map3>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
void test_multimap()
|
void test_multimap()
|
||||||
{
|
{
|
||||||
typedef boost::unordered_multimap<key, int, transparent_hasher,
|
typedef boost::unordered_multimap<key, int, transparent_hasher,
|
||||||
@ -168,6 +179,7 @@ void test_multimap()
|
|||||||
test_map_non_transparent_contains<non_transparent_multimap2>();
|
test_map_non_transparent_contains<non_transparent_multimap2>();
|
||||||
test_map_non_transparent_contains<non_transparent_multimap3>();
|
test_map_non_transparent_contains<non_transparent_multimap3>();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class UnorderedSet> void test_set_transparent_contains()
|
template <class UnorderedSet> void test_set_transparent_contains()
|
||||||
{
|
{
|
||||||
@ -231,6 +243,18 @@ template <class UnorderedSet> void test_set_non_transparent_contains()
|
|||||||
|
|
||||||
void test_set()
|
void test_set()
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<key, transparent_hasher,
|
||||||
|
transparent_key_equal>
|
||||||
|
transparent_set;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_set<key, transparent_hasher, key_equal>
|
||||||
|
non_transparent_set1;
|
||||||
|
typedef boost::unordered_flat_set<key, hasher, transparent_key_equal>
|
||||||
|
non_transparent_set2;
|
||||||
|
typedef boost::unordered_flat_set<key, hasher, key_equal>
|
||||||
|
non_transparent_set3;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
|
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
|
||||||
transparent_set;
|
transparent_set;
|
||||||
|
|
||||||
@ -239,6 +263,7 @@ void test_set()
|
|||||||
typedef boost::unordered_set<key, hasher, transparent_key_equal>
|
typedef boost::unordered_set<key, hasher, transparent_key_equal>
|
||||||
non_transparent_set2;
|
non_transparent_set2;
|
||||||
typedef boost::unordered_set<key, hasher, key_equal> non_transparent_set3;
|
typedef boost::unordered_set<key, hasher, key_equal> non_transparent_set3;
|
||||||
|
#endif
|
||||||
|
|
||||||
test_set_transparent_contains<transparent_set>();
|
test_set_transparent_contains<transparent_set>();
|
||||||
test_set_non_transparent_contains<non_transparent_set1>();
|
test_set_non_transparent_contains<non_transparent_set1>();
|
||||||
@ -246,6 +271,7 @@ void test_set()
|
|||||||
test_set_non_transparent_contains<non_transparent_set3>();
|
test_set_non_transparent_contains<non_transparent_set3>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
void test_multiset()
|
void test_multiset()
|
||||||
{
|
{
|
||||||
typedef boost::unordered_multiset<key, transparent_hasher,
|
typedef boost::unordered_multiset<key, transparent_hasher,
|
||||||
@ -264,11 +290,15 @@ void test_multiset()
|
|||||||
test_set_non_transparent_contains<non_transparent_multiset2>();
|
test_set_non_transparent_contains<non_transparent_multiset2>();
|
||||||
test_set_non_transparent_contains<non_transparent_multiset3>();
|
test_set_non_transparent_contains<non_transparent_multiset3>();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (contains_) { // avoid -Wshadow warning with `bool contains`
|
UNORDERED_AUTO_TEST (contains_) { // avoid -Wshadow warning with `bool contains`
|
||||||
test_map();
|
test_map();
|
||||||
test_multimap();
|
|
||||||
test_set();
|
test_set();
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_multimap();
|
||||||
|
test_multiset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -229,6 +225,38 @@ namespace copy_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||||
|
test_set_select_copy;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::cxx11_allocator<test::object, test::select_copy> >*
|
||||||
|
test_map_select_copy;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||||
|
test_set_no_select_copy;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||||
|
test_map_no_select_copy;
|
||||||
|
|
||||||
|
UNORDERED_TEST(copy_construct_tests1,
|
||||||
|
((test_set)(test_map)(test_set_select_copy)(test_map_select_copy)(test_set_no_select_copy)(test_map_no_select_copy))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(copy_construct_tests2,
|
||||||
|
((test_set)(test_map)(test_set_select_copy)(test_map_select_copy)(test_set_no_select_copy)(test_map_no_select_copy))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
test::allocator1<test::object> >* test_set;
|
test::allocator1<test::object> >* test_set;
|
||||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
@ -264,25 +292,14 @@ namespace copy_tests {
|
|||||||
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||||
test_multimap_no_select_copy;
|
test_multimap_no_select_copy;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(copy_construct_tests1,
|
UNORDERED_TEST(copy_construct_tests1,
|
||||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
|
((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))(
|
||||||
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)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(copy_construct_tests2,
|
UNORDERED_TEST(copy_construct_tests2,
|
||||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
|
((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))(
|
||||||
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)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
}
|
#endif
|
||||||
|
} // namespace copy_tests
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2016 Daniel James.
|
// Copyright 2016 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include <boost/functional/hash/hash.hpp>
|
#include <boost/functional/hash/hash.hpp>
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
@ -46,47 +42,56 @@ namespace emplace_tests {
|
|||||||
A8 a8;
|
A8 a8;
|
||||||
A9 a9;
|
A9 a9;
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1) : arg_count(2), a0(b0), a1(b1) {}
|
emplace_value(A0 const& b0, A1 const& b1)
|
||||||
|
: arg_count(2), a0(b0), a1(b1), a2('\0'), a3(-1), a4(-1), a5(-1),
|
||||||
|
a6(-1), a7(-1), a8(-1), a9(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
|
||||||
: arg_count(3), a0(b0), a1(b1), a2(b2)
|
: arg_count(3), a0(b0), a1(b1), a2(b2), a3(-1), a4(-1), a5(-1), a6(-1),
|
||||||
|
a7(-1), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3)
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3)
|
||||||
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3)
|
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3), a4(-1), a5(-1), a6(-1),
|
||||||
|
a7(-1), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(
|
emplace_value(
|
||||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4)
|
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4)
|
||||||
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4)
|
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(-1), a6(-1),
|
||||||
|
a7(-1), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||||
A4 const& b4, A5 const& b5)
|
A4 const& b4, A5 const& b5)
|
||||||
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5)
|
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(-1),
|
||||||
|
a7(-1), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||||
A4 const& b4, A5 const& b5, A6 const& b6)
|
A4 const& b4, A5 const& b5, A6 const& b6)
|
||||||
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6)
|
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||||
|
a7(-1), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||||
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7)
|
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7)
|
||||||
: arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
: arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||||
a7(b7)
|
a7(b7), a8(-1), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||||
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7, A8 const& b8)
|
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7, A8 const& b8)
|
||||||
: arg_count(9), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
: arg_count(9), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||||
a7(b7), a8(b8)
|
a7(b7), a8(b8), a9(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,16 +167,29 @@ namespace emplace_tests {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
emplace_value() = delete;
|
||||||
|
emplace_value(emplace_value const&) = default;
|
||||||
|
emplace_value(emplace_value&&) = default;
|
||||||
|
#else
|
||||||
private:
|
private:
|
||||||
emplace_value();
|
emplace_value();
|
||||||
emplace_value(emplace_value const&);
|
emplace_value(emplace_value const&);
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (emplace_set) {
|
UNORDERED_AUTO_TEST (emplace_set) {
|
||||||
test::check_instances check_;
|
test::check_instances check_;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<emplace_value,
|
||||||
|
boost::hash<emplace_value> >
|
||||||
|
container;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<emplace_value, boost::hash<emplace_value> >
|
typedef boost::unordered_set<emplace_value, boost::hash<emplace_value> >
|
||||||
container;
|
container;
|
||||||
|
#endif
|
||||||
typedef container::iterator iterator;
|
typedef container::iterator iterator;
|
||||||
typedef std::pair<iterator, bool> return_type;
|
typedef std::pair<iterator, bool> return_type;
|
||||||
container x(10);
|
container x(10);
|
||||||
@ -187,7 +205,15 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(*r1.first == v1);
|
BOOST_TEST(*r1.first == v1);
|
||||||
BOOST_TEST(r1.first == x.find(v1));
|
BOOST_TEST(r1.first == x.find(v1));
|
||||||
BOOST_TEST_EQ(check_.instances(), 2);
|
BOOST_TEST_EQ(check_.instances(), 2);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
// 1 from v1
|
||||||
|
// 1 from constructing the value_type() so we can pluck the key
|
||||||
|
// 1 from move-constructing which invokes the counted_object base
|
||||||
|
// constructor
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 3);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 3 args
|
// 3 args
|
||||||
|
|
||||||
@ -198,7 +224,11 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(*r1.first == v2);
|
BOOST_TEST(*r1.first == v2);
|
||||||
BOOST_TEST(r1.first == x.find(v2));
|
BOOST_TEST(r1.first == x.find(v2));
|
||||||
BOOST_TEST_EQ(check_.instances(), 4);
|
BOOST_TEST_EQ(check_.instances(), 4);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 7 args with hint + duplicate
|
// 7 args with hint + duplicate
|
||||||
|
|
||||||
@ -208,7 +238,11 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(*i1 == v3);
|
BOOST_TEST(*i1 == v3);
|
||||||
BOOST_TEST(i1 == x.find(v3));
|
BOOST_TEST(i1 == x.find(v3));
|
||||||
BOOST_TEST_EQ(check_.instances(), 6);
|
BOOST_TEST_EQ(check_.instances(), 6);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||||
|
#endif
|
||||||
|
|
||||||
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
|
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
|
||||||
BOOST_TEST_EQ(x.size(), 3u);
|
BOOST_TEST_EQ(x.size(), 3u);
|
||||||
@ -218,7 +252,11 @@ namespace emplace_tests {
|
|||||||
// whether it can emplace, so there's an extra construction
|
// whether it can emplace, so there's an extra construction
|
||||||
// here.
|
// here.
|
||||||
BOOST_TEST_EQ(check_.instances(), 6);
|
BOOST_TEST_EQ(check_.instances(), 6);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||||
|
#endif
|
||||||
|
|
||||||
// 10 args + hint duplicate
|
// 10 args + hint duplicate
|
||||||
|
|
||||||
@ -230,7 +268,11 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(*r1.first == v4);
|
BOOST_TEST(*r1.first == v4);
|
||||||
BOOST_TEST(r1.first == x.find(v4));
|
BOOST_TEST(r1.first == x.find(v4));
|
||||||
BOOST_TEST_EQ(check_.instances(), 8);
|
BOOST_TEST_EQ(check_.instances(), 8);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 13);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 9);
|
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_TEST(
|
BOOST_TEST(
|
||||||
r1.first == x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
r1.first == x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||||
@ -239,7 +281,11 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(
|
BOOST_TEST(
|
||||||
r1.first == x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
r1.first == x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||||
BOOST_TEST_EQ(check_.instances(), 8);
|
BOOST_TEST_EQ(check_.instances(), 8);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||||
|
#else
|
||||||
BOOST_TEST_EQ(check_.constructions(), 12);
|
BOOST_TEST_EQ(check_.constructions(), 12);
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_TEST_EQ(x.size(), 4u);
|
BOOST_TEST_EQ(x.size(), 4u);
|
||||||
BOOST_TEST(x.count(v1) == 1);
|
BOOST_TEST(x.count(v1) == 1);
|
||||||
@ -248,6 +294,7 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(x.count(v4) == 1);
|
BOOST_TEST(x.count(v4) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (emplace_multiset) {
|
UNORDERED_AUTO_TEST (emplace_multiset) {
|
||||||
test::check_instances check_;
|
test::check_instances check_;
|
||||||
|
|
||||||
@ -325,20 +372,79 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST_EQ(x.count(v2), 2u);
|
BOOST_TEST_EQ(x.count(v2), 2u);
|
||||||
BOOST_TEST_EQ(x.count(v3), 2u);
|
BOOST_TEST_EQ(x.count(v3), 2u);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (emplace_map) {
|
UNORDERED_AUTO_TEST (emplace_map) {
|
||||||
test::check_instances check_;
|
test::check_instances check_;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<emplace_value, emplace_value,
|
||||||
|
boost::hash<emplace_value> >
|
||||||
|
container;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<emplace_value, emplace_value,
|
typedef boost::unordered_map<emplace_value, emplace_value,
|
||||||
boost::hash<emplace_value> >
|
boost::hash<emplace_value> >
|
||||||
container;
|
container;
|
||||||
|
#endif
|
||||||
typedef container::iterator iterator;
|
typedef container::iterator iterator;
|
||||||
typedef std::pair<iterator, bool> return_type;
|
typedef std::pair<iterator, bool> return_type;
|
||||||
container x(10);
|
container x(10);
|
||||||
return_type r1, r2;
|
return_type r1, r2;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
// 5/8 args + duplicate
|
// 5/8 args + duplicate
|
||||||
|
emplace_value k1(5, "", 'b', 4, 5);
|
||||||
|
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||||
|
r1 = x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
|
||||||
|
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||||
|
BOOST_TEST_EQ(x.size(), 1u);
|
||||||
|
BOOST_TEST(r1.second);
|
||||||
|
BOOST_TEST(x.find(k1) == r1.first);
|
||||||
|
BOOST_TEST(x.find(k1)->second == m1);
|
||||||
|
BOOST_TEST_EQ(check_.instances(), 4);
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||||
|
|
||||||
|
r2 = x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
|
||||||
|
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||||
|
BOOST_TEST_EQ(x.size(), 1u);
|
||||||
|
BOOST_TEST(!r2.second);
|
||||||
|
BOOST_TEST(r1.first == r2.first);
|
||||||
|
BOOST_TEST(x.find(k1)->second == m1);
|
||||||
|
BOOST_TEST_EQ(check_.instances(), 4);
|
||||||
|
// constructions could possibly be 5 if the implementation only
|
||||||
|
// constructed the key.
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 8);
|
||||||
|
|
||||||
|
// 9/3 args + duplicates with hints, different mapped value.
|
||||||
|
|
||||||
|
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||||
|
emplace_value m2(3, "aaa", 'm');
|
||||||
|
r1 = x.emplace(std::piecewise_construct,
|
||||||
|
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||||
|
std::make_tuple(3, "aaa", 'm'));
|
||||||
|
BOOST_TEST_EQ(x.size(), 2u);
|
||||||
|
BOOST_TEST(r1.second);
|
||||||
|
BOOST_TEST(r1.first->first.arg_count == 9);
|
||||||
|
BOOST_TEST(r1.first->second.arg_count == 3);
|
||||||
|
BOOST_TEST(x.find(k2) == r1.first);
|
||||||
|
BOOST_TEST(x.find(k2)->second == m2);
|
||||||
|
BOOST_TEST_EQ(check_.instances(), 8);
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 14);
|
||||||
|
|
||||||
|
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
|
||||||
|
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||||
|
std::make_tuple(15, "jkjk")));
|
||||||
|
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
|
||||||
|
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||||
|
std::make_tuple(275, "xxx", 'm', 6)));
|
||||||
|
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
|
||||||
|
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||||
|
std::make_tuple(-10, "blah blah", '\0')));
|
||||||
|
BOOST_TEST_EQ(x.size(), 2u);
|
||||||
|
BOOST_TEST(x.find(k2)->second == m2);
|
||||||
|
BOOST_TEST_EQ(check_.instances(), 8);
|
||||||
|
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||||
|
#else
|
||||||
|
// 5/8 args + duplicate
|
||||||
emplace_value k1(5, "", 'b', 4, 5);
|
emplace_value k1(5, "", 'b', 4, 5);
|
||||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||||
@ -395,8 +501,10 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST(x.find(k2)->second == m2);
|
BOOST_TEST(x.find(k2)->second == m2);
|
||||||
BOOST_TEST_EQ(check_.instances(), 8);
|
BOOST_TEST_EQ(check_.instances(), 8);
|
||||||
BOOST_TEST_EQ(check_.constructions(), 16);
|
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (emplace_multimap) {
|
UNORDERED_AUTO_TEST (emplace_multimap) {
|
||||||
test::check_instances check_;
|
test::check_instances check_;
|
||||||
|
|
||||||
@ -461,11 +569,15 @@ namespace emplace_tests {
|
|||||||
BOOST_TEST_EQ(check_.instances(), 20);
|
BOOST_TEST_EQ(check_.instances(), 20);
|
||||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (try_emplace) {
|
UNORDERED_AUTO_TEST (try_emplace) {
|
||||||
test::check_instances check_;
|
test::check_instances check_;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<int, emplace_value> container;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<int, emplace_value> container;
|
typedef boost::unordered_map<int, emplace_value> container;
|
||||||
|
#endif
|
||||||
typedef container::iterator iterator;
|
typedef container::iterator iterator;
|
||||||
typedef std::pair<iterator, bool> return_type;
|
typedef std::pair<iterator, bool> return_type;
|
||||||
container x(10);
|
container x(10);
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2008-2009 Daniel James.
|
// Copyright 2008-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include <boost/preprocessor/seq.hpp>
|
#include <boost/preprocessor/seq.hpp>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -30,14 +26,27 @@ namespace equality_tests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
using boost_unordered_set =
|
||||||
|
boost::unordered_flat_set<int, mod_compare, mod_compare>;
|
||||||
|
|
||||||
|
using boost_unordered_map =
|
||||||
|
boost::unordered_flat_map<int, int, mod_compare, mod_compare>;
|
||||||
|
|
||||||
|
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
|
||||||
BOOST_TEST(set1 op set2); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||||
|
{ \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
typedef boost::unordered_set<int, mod_compare, mod_compare>
|
||||||
|
boost_unordered_set;
|
||||||
|
|
||||||
|
typedef boost::unordered_map<int, int, mod_compare, mod_compare>
|
||||||
|
boost_unordered_map;
|
||||||
|
|
||||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
|
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
|
||||||
@ -46,17 +55,26 @@ namespace equality_tests {
|
|||||||
BOOST_TEST(set1 op set2); \
|
BOOST_TEST(set1 op set2); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
|
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||||
BOOST_TEST(map1 op map2); \
|
BOOST_TEST(map1 op map2); \
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||||
{ \
|
{ \
|
||||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
|
boost_unordered_set set1, set2; \
|
||||||
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||||
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||||
|
BOOST_TEST(set1 op set2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||||
|
{ \
|
||||||
|
boost_unordered_map map1, map2; \
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||||
BOOST_TEST(map1 op map2); \
|
BOOST_TEST(map1 op map2); \
|
||||||
@ -67,7 +85,11 @@ namespace equality_tests {
|
|||||||
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
|
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (equality_size_tests) {
|
UNORDERED_AUTO_TEST (equality_size_tests) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> x1, x2;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> x1, x2;
|
boost::unordered_set<int> x1, x2;
|
||||||
|
#endif
|
||||||
BOOST_TEST(x1 == x2);
|
BOOST_TEST(x1 == x2);
|
||||||
BOOST_TEST(!(x1 != x2));
|
BOOST_TEST(!(x1 != x2));
|
||||||
|
|
||||||
@ -134,7 +156,7 @@ namespace equality_tests {
|
|||||||
// different hash functions but the same equality predicate.
|
// different hash functions but the same equality predicate.
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (equality_different_hash_test) {
|
UNORDERED_AUTO_TEST (equality_different_hash_test) {
|
||||||
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
|
typedef boost_unordered_set set;
|
||||||
set set1(0, mod_compare(false), mod_compare(false));
|
set set1(0, mod_compare(false), mod_compare(false));
|
||||||
set set2(0, mod_compare(true), mod_compare(true));
|
set set2(0, mod_compare(true), mod_compare(true));
|
||||||
BOOST_TEST(set1 == set2);
|
BOOST_TEST(set1 == set2);
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -38,8 +34,11 @@ void test_equal_insertion(Iterator begin, Iterator end)
|
|||||||
UNORDERED_AUTO_TEST (set_tests) {
|
UNORDERED_AUTO_TEST (set_tests) {
|
||||||
int values[][5] = {{1}, {54, 23}, {-13, 65}, {77, 77}, {986, 25, 986}};
|
int values[][5] = {{1}, {54, 23}, {-13, 65}, {77, 77}, {986, 25, 986}};
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int> set;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int> set;
|
typedef boost::unordered_set<int> set;
|
||||||
typedef boost::unordered_multiset<int> multiset;
|
#endif
|
||||||
|
|
||||||
test_equal_insertion<set>(values[0], values[0] + 1);
|
test_equal_insertion<set>(values[0], values[0] + 1);
|
||||||
test_equal_insertion<set>(values[1], values[1] + 2);
|
test_equal_insertion<set>(values[1], values[1] + 2);
|
||||||
@ -47,6 +46,7 @@ UNORDERED_AUTO_TEST (set_tests) {
|
|||||||
test_equal_insertion<set>(values[3], values[3] + 2);
|
test_equal_insertion<set>(values[3], values[3] + 2);
|
||||||
test_equal_insertion<set>(values[4], values[4] + 3);
|
test_equal_insertion<set>(values[4], values[4] + 3);
|
||||||
|
|
||||||
|
typedef boost::unordered_multiset<int> multiset;
|
||||||
test_equal_insertion<multiset>(values[0], values[0] + 1);
|
test_equal_insertion<multiset>(values[0], values[0] + 1);
|
||||||
test_equal_insertion<multiset>(values[1], values[1] + 2);
|
test_equal_insertion<multiset>(values[1], values[1] + 2);
|
||||||
test_equal_insertion<multiset>(values[2], values[2] + 2);
|
test_equal_insertion<multiset>(values[2], values[2] + 2);
|
||||||
@ -66,12 +66,17 @@ UNORDERED_AUTO_TEST (map_tests) {
|
|||||||
v[2].push_back(std::pair<int const, int>(432, 24));
|
v[2].push_back(std::pair<int const, int>(432, 24));
|
||||||
|
|
||||||
for (int i = 0; i < 5; ++i)
|
for (int i = 0; i < 5; ++i)
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_equal_insertion<boost::unordered_flat_map<int, int> >(
|
||||||
|
v[i].begin(), v[i].end());
|
||||||
|
#else
|
||||||
test_equal_insertion<boost::unordered_map<int, int> >(
|
test_equal_insertion<boost::unordered_map<int, int> >(
|
||||||
v[i].begin(), v[i].end());
|
v[i].begin(), v[i].end());
|
||||||
|
|
||||||
for (int i2 = 0; i2 < 5; ++i2)
|
for (int i2 = 0; i2 < 5; ++i2)
|
||||||
test_equal_insertion<boost::unordered_multimap<int, int> >(
|
test_equal_insertion<boost::unordered_multimap<int, int> >(
|
||||||
v[i2].begin(), v[i2].end());
|
v[i2].begin(), v[i2].end());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -2,12 +2,7 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
@ -23,36 +18,13 @@
|
|||||||
namespace test {
|
namespace test {
|
||||||
struct is_even
|
struct is_even
|
||||||
{
|
{
|
||||||
is_even() {}
|
bool operator()(std::pair<std::string const, int>& key_value)
|
||||||
|
|
||||||
#if BOOST_CXX_VERSION >= 201703L
|
|
||||||
// immovable for C++17
|
|
||||||
is_even(is_even const&) = delete;
|
|
||||||
is_even(is_even&&) = delete;
|
|
||||||
|
|
||||||
is_even& operator=(is_even const&) = delete;
|
|
||||||
is_even& operator=(is_even&&) = delete;
|
|
||||||
#elif BOOST_CXX_VERSION >= 201103L
|
|
||||||
// move-only for C++11
|
|
||||||
is_even(is_even const&) = delete;
|
|
||||||
is_even(is_even&&) = default;
|
|
||||||
|
|
||||||
is_even& operator=(is_even const&) = delete;
|
|
||||||
is_even& operator=(is_even&&) = default;
|
|
||||||
#else
|
|
||||||
// copyable otherwise
|
|
||||||
is_even(is_even const&) {}
|
|
||||||
is_even& operator=(is_even const&) { return *this; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool operator()(
|
|
||||||
std::pair<std::string const, int>& key_value) UNORDERED_LVALUE_QUAL
|
|
||||||
{
|
{
|
||||||
int const v = key_value.second;
|
int const v = key_value.second;
|
||||||
return (v % 2 == 0);
|
return (v % 2 == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
|
bool operator()(int const& value)
|
||||||
{
|
{
|
||||||
int const v = value;
|
int const v = value;
|
||||||
return (v % 2 == 0);
|
return (v % 2 == 0);
|
||||||
@ -61,37 +33,13 @@ namespace test {
|
|||||||
|
|
||||||
struct is_too_large
|
struct is_too_large
|
||||||
{
|
{
|
||||||
is_too_large() {}
|
bool operator()(std::pair<std::string const, int>& key_value)
|
||||||
|
|
||||||
#if BOOST_CXX_VERSION >= 201703L
|
|
||||||
// immovable for C++17
|
|
||||||
is_too_large(is_too_large const&) = delete;
|
|
||||||
is_too_large(is_too_large&&) = delete;
|
|
||||||
|
|
||||||
is_too_large& operator=(is_too_large const&) = delete;
|
|
||||||
is_too_large& operator=(is_too_large&&) = delete;
|
|
||||||
#elif BOOST_CXX_VERSION >= 201103L
|
|
||||||
// move-only for C++11
|
|
||||||
is_too_large(is_too_large const&) = delete;
|
|
||||||
is_too_large(is_too_large&&) = default;
|
|
||||||
|
|
||||||
is_too_large& operator=(is_too_large const&) = delete;
|
|
||||||
is_too_large& operator=(is_too_large&&) = default;
|
|
||||||
#else
|
|
||||||
// copyable otherwise
|
|
||||||
is_too_large(is_too_large const&) {}
|
|
||||||
|
|
||||||
is_too_large& operator=(is_too_large const&) { return *this; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool operator()(
|
|
||||||
std::pair<std::string const, int>& key_value) UNORDERED_LVALUE_QUAL
|
|
||||||
{
|
{
|
||||||
int const v = key_value.second;
|
int const v = key_value.second;
|
||||||
return v >= 1000;
|
return v >= 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
|
bool operator()(int const& value)
|
||||||
{
|
{
|
||||||
int const v = value;
|
int const v = value;
|
||||||
return v >= 1000;
|
return v >= 1000;
|
||||||
@ -159,11 +107,16 @@ template <class UnorderedSet> void test_set_erase_if()
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (unordered_erase_if) {
|
UNORDERED_AUTO_TEST (unordered_erase_if) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_map_erase_if<boost::unordered_flat_map<std::string, int> >();
|
||||||
|
test_set_erase_if<boost::unordered_flat_set<int> >();
|
||||||
|
#else
|
||||||
test_map_erase_if<boost::unordered_map<std::string, int> >();
|
test_map_erase_if<boost::unordered_map<std::string, int> >();
|
||||||
test_map_erase_if<boost::unordered_multimap<std::string, int> >();
|
test_map_erase_if<boost::unordered_multimap<std::string, int> >();
|
||||||
|
|
||||||
test_set_erase_if<boost::unordered_set<int> >();
|
test_set_erase_if<boost::unordered_set<int> >();
|
||||||
test_set_erase_if<boost::unordered_multiset<int> >();
|
test_set_erase_if<boost::unordered_multiset<int> >();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -27,7 +23,9 @@ namespace erase_tests {
|
|||||||
template <class Container>
|
template <class Container>
|
||||||
void erase_tests1(Container*, test::random_generator generator)
|
void erase_tests1(Container*, test::random_generator generator)
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename Container::iterator iterator;
|
typedef typename Container::iterator iterator;
|
||||||
|
#endif
|
||||||
typedef typename Container::const_iterator c_iterator;
|
typedef typename Container::const_iterator c_iterator;
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Erase by key.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Erase by key.\n";
|
||||||
@ -61,9 +59,13 @@ namespace erase_tests {
|
|||||||
while (size > 0 && !x.empty()) {
|
while (size > 0 && !x.empty()) {
|
||||||
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
||||||
std::size_t count = x.count(key);
|
std::size_t count = x.count(key);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.erase(x.begin());
|
||||||
|
#else
|
||||||
iterator pos = x.erase(x.begin());
|
iterator pos = x.erase(x.begin());
|
||||||
--size;
|
|
||||||
BOOST_TEST(pos == x.begin());
|
BOOST_TEST(pos == x.begin());
|
||||||
|
#endif
|
||||||
|
--size;
|
||||||
BOOST_TEST(x.count(key) == count - 1);
|
BOOST_TEST(x.count(key) == count - 1);
|
||||||
BOOST_TEST(x.size() == size);
|
BOOST_TEST(x.size() == size);
|
||||||
if (++iterations % 20 == 0)
|
if (++iterations % 20 == 0)
|
||||||
@ -93,10 +95,15 @@ namespace erase_tests {
|
|||||||
typename Container::key_type key = test::get_key<Container>(*pos);
|
typename Container::key_type key = test::get_key<Container>(*pos);
|
||||||
std::size_t count = x.count(key);
|
std::size_t count = x.count(key);
|
||||||
BOOST_TEST(count > 0);
|
BOOST_TEST(count > 0);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.erase(pos);
|
||||||
|
--size;
|
||||||
|
#else
|
||||||
BOOST_TEST(next == x.erase(pos));
|
BOOST_TEST(next == x.erase(pos));
|
||||||
--size;
|
--size;
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
||||||
|
#endif
|
||||||
BOOST_TEST(x.count(key) == count - 1);
|
BOOST_TEST(x.count(key) == count - 1);
|
||||||
if (x.count(key) != count - 1) {
|
if (x.count(key) != count - 1) {
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << count << " => " << x.count(key)
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << count << " => " << x.count(key)
|
||||||
@ -185,7 +192,11 @@ namespace erase_tests {
|
|||||||
while (size > 0 && !x.empty()) {
|
while (size > 0 && !x.empty()) {
|
||||||
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
typename Container::key_type key = test::get_key<Container>(*x.begin());
|
||||||
std::size_t count = x.count(key);
|
std::size_t count = x.count(key);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.erase(x.begin());
|
||||||
|
#else
|
||||||
x.quick_erase(x.begin());
|
x.quick_erase(x.begin());
|
||||||
|
#endif
|
||||||
--size;
|
--size;
|
||||||
BOOST_TEST(x.count(key) == count - 1);
|
BOOST_TEST(x.count(key) == count - 1);
|
||||||
BOOST_TEST(x.size() == size);
|
BOOST_TEST(x.size() == size);
|
||||||
@ -216,7 +227,11 @@ namespace erase_tests {
|
|||||||
typename Container::key_type key = test::get_key<Container>(*pos);
|
typename Container::key_type key = test::get_key<Container>(*pos);
|
||||||
std::size_t count = x.count(key);
|
std::size_t count = x.count(key);
|
||||||
BOOST_TEST(count > 0);
|
BOOST_TEST(count > 0);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.erase(pos);
|
||||||
|
#else
|
||||||
x.quick_erase(pos);
|
x.quick_erase(pos);
|
||||||
|
#endif
|
||||||
--size;
|
--size;
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
|
||||||
@ -246,6 +261,20 @@ namespace erase_tests {
|
|||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
erase_tests1, ((test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
test::allocator1<test::object> >* test_set;
|
test::allocator1<test::object> >* test_set;
|
||||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
@ -255,13 +284,11 @@ namespace erase_tests {
|
|||||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(
|
UNORDERED_TEST(
|
||||||
erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -133,6 +129,20 @@ namespace find_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator2<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator2<test::object> >* test_map;
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
find_tests1, ((test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
test::allocator2<test::object> >* test_set;
|
test::allocator2<test::object> >* test_set;
|
||||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
@ -142,16 +152,13 @@ namespace find_tests {
|
|||||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(
|
UNORDERED_TEST(
|
||||||
find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
UNORDERED_TEST(find_compatible_keys_test,
|
UNORDERED_TEST(find_compatible_keys_test,
|
||||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,44 @@
|
|||||||
|
|
||||||
// Copyright 2008-2009 Daniel James.
|
// Copyright 2008-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include "../helpers/prefix.hpp"
|
#include "../helpers/prefix.hpp"
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||||
|
#include <boost/unordered/detail/implementation.hpp>
|
||||||
|
#else
|
||||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||||
|
#endif
|
||||||
#include "../helpers/postfix.hpp"
|
#include "../helpers/postfix.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
template <typename T>
|
||||||
|
void call_swap(
|
||||||
|
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||||
|
{
|
||||||
|
swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool call_equals(
|
||||||
|
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||||
|
{
|
||||||
|
return x == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool call_not_equals(
|
||||||
|
boost::unordered_flat_map<T, T>& x, boost::unordered_flat_map<T, T>& y)
|
||||||
|
{
|
||||||
|
return x != y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/unordered/unordered_flat_map.hpp>
|
||||||
|
#else
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
||||||
{
|
{
|
||||||
@ -50,10 +80,15 @@ bool call_not_equals(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
|
#endif
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<int, int> int_map;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<int, int> int_map;
|
typedef boost::unordered_map<int, int> int_map;
|
||||||
typedef boost::unordered_multimap<int, int> int_multimap;
|
typedef boost::unordered_multimap<int, int> int_multimap;
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
|
UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
|
||||||
int_map x, y;
|
int_map x, y;
|
||||||
@ -71,11 +106,13 @@ UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
|
|||||||
BOOST_TEST(call_not_equals(x, y));
|
BOOST_TEST(call_not_equals(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (use_multimap_fwd_declared_function) {
|
UNORDERED_AUTO_TEST (use_multimap_fwd_declared_function) {
|
||||||
int_multimap x, y;
|
int_multimap x, y;
|
||||||
call_swap(x, y);
|
call_swap(x, y);
|
||||||
BOOST_TEST(call_equals(x, y));
|
BOOST_TEST(call_equals(x, y));
|
||||||
BOOST_TEST(!call_not_equals(x, y));
|
BOOST_TEST(!call_not_equals(x, y));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
|
|
||||||
// Copyright 2008-2009 Daniel James.
|
// Copyright 2008-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include "../helpers/prefix.hpp"
|
#include "../helpers/prefix.hpp"
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||||
|
#include <boost/unordered/detail/implementation.hpp>
|
||||||
|
#else
|
||||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||||
|
#endif
|
||||||
#include "../helpers/postfix.hpp"
|
#include "../helpers/postfix.hpp"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@ -20,6 +26,31 @@ struct false_type
|
|||||||
|
|
||||||
false_type is_unordered_set_impl(void*);
|
false_type is_unordered_set_impl(void*);
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
template <class Value, class Hash, class Pred, class Alloc>
|
||||||
|
true_type is_unordered_set_impl(
|
||||||
|
boost::unordered_flat_set<Value, Hash, Pred, Alloc>*);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void call_swap(boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||||
|
{
|
||||||
|
swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool call_equals(
|
||||||
|
boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||||
|
{
|
||||||
|
return x == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool call_not_equals(
|
||||||
|
boost::unordered_flat_set<T>& x, boost::unordered_flat_set<T>& y)
|
||||||
|
{
|
||||||
|
return x != y;
|
||||||
|
}
|
||||||
|
#else
|
||||||
template <class Value, class Hash, class Pred, class Alloc>
|
template <class Value, class Hash, class Pred, class Alloc>
|
||||||
true_type is_unordered_set_impl(
|
true_type is_unordered_set_impl(
|
||||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||||
@ -41,7 +72,9 @@ bool call_not_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
|
|||||||
{
|
{
|
||||||
return x != y;
|
return x != y;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
|
void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
|
||||||
{
|
{
|
||||||
@ -61,20 +94,29 @@ bool call_not_equals(
|
|||||||
{
|
{
|
||||||
return x != y;
|
return x != y;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int> int_set;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int> int_set;
|
typedef boost::unordered_set<int> int_set;
|
||||||
typedef boost::unordered_multiset<int> int_multiset;
|
typedef boost::unordered_multiset<int> int_multiset;
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (use_fwd_declared_trait_without_definition) {
|
UNORDERED_AUTO_TEST (use_fwd_declared_trait_without_definition) {
|
||||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*)0)) == sizeof(true_type));
|
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*)0)) == sizeof(true_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
#include <boost/unordered/unordered_flat_set.hpp>
|
||||||
|
#else
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/unordered_set.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (use_fwd_declared_trait) {
|
UNORDERED_AUTO_TEST (use_fwd_declared_trait) {
|
||||||
boost::unordered_set<int> x;
|
int_set x;
|
||||||
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
|
||||||
|
|
||||||
BOOST_TEST(sizeof(is_unordered_set_impl((int*)0)) == sizeof(false_type));
|
BOOST_TEST(sizeof(is_unordered_set_impl((int*)0)) == sizeof(false_type));
|
||||||
@ -96,11 +138,13 @@ UNORDERED_AUTO_TEST (use_set_fwd_declared_function) {
|
|||||||
BOOST_TEST(call_not_equals(x, y));
|
BOOST_TEST(call_not_equals(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (use_multiset_fwd_declared_function) {
|
UNORDERED_AUTO_TEST (use_multiset_fwd_declared_function) {
|
||||||
int_multiset x, y;
|
int_multiset x, y;
|
||||||
call_swap(x, y);
|
call_swap(x, y);
|
||||||
BOOST_TEST(call_equals(x, y));
|
BOOST_TEST(call_equals(x, y));
|
||||||
BOOST_TEST(!call_not_equals(x, y));
|
BOOST_TEST(!call_not_equals(x, y));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
|
|
||||||
// Copyright 2009 Daniel James.
|
// Copyright 2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace x {
|
namespace x {
|
||||||
struct D
|
struct D
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<D, D> x;
|
||||||
|
#else
|
||||||
boost::unordered_map<D, D> x;
|
boost::unordered_map<D, D> x;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +29,17 @@ namespace incomplete_test {
|
|||||||
|
|
||||||
// Declare some instances
|
// Declare some instances
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<value, value, hash, equals,
|
||||||
|
allocator<std::pair<value const, value> > >
|
||||||
|
map;
|
||||||
|
typedef boost::unordered_flat_map<value, value, hash, equals,
|
||||||
|
allocator<std::pair<value const, value> > >
|
||||||
|
multimap;
|
||||||
|
typedef boost::unordered_flat_set<value, hash, equals, allocator<value> > set;
|
||||||
|
typedef boost::unordered_flat_set<value, hash, equals, allocator<value> >
|
||||||
|
multiset;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<value, value, hash, equals,
|
typedef boost::unordered_map<value, value, hash, equals,
|
||||||
allocator<std::pair<value const, value> > >
|
allocator<std::pair<value const, value> > >
|
||||||
map;
|
map;
|
||||||
@ -38,6 +49,7 @@ namespace incomplete_test {
|
|||||||
typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
|
typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
|
||||||
typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
|
typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
|
||||||
multiset;
|
multiset;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now define the types which are stored as members, as they are needed for
|
// Now define the types which are stored as members, as they are needed for
|
||||||
// declaring struct members.
|
// declaring struct members.
|
||||||
@ -76,7 +88,28 @@ namespace incomplete_test {
|
|||||||
//
|
//
|
||||||
// Incomplete hash, equals and allocator aren't here supported at the
|
// Incomplete hash, equals and allocator aren't here supported at the
|
||||||
// moment.
|
// moment.
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
struct struct1
|
||||||
|
{
|
||||||
|
boost::unordered_flat_map<struct1, struct1, hash, equals,
|
||||||
|
allocator<std::pair<struct1 const, struct1> > >
|
||||||
|
x;
|
||||||
|
};
|
||||||
|
struct struct2
|
||||||
|
{
|
||||||
|
boost::unordered_flat_map<struct2, struct2, hash, equals,
|
||||||
|
allocator<std::pair<struct2 const, struct2> > >
|
||||||
|
x;
|
||||||
|
};
|
||||||
|
struct struct3
|
||||||
|
{
|
||||||
|
boost::unordered_flat_set<struct3, hash, equals, allocator<struct3> > x;
|
||||||
|
};
|
||||||
|
struct struct4
|
||||||
|
{
|
||||||
|
boost::unordered_flat_set<struct4, hash, equals, allocator<struct4> > x;
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct struct1
|
struct struct1
|
||||||
{
|
{
|
||||||
boost::unordered_map<struct1, struct1, hash, equals,
|
boost::unordered_map<struct1, struct1, hash, equals,
|
||||||
@ -97,7 +130,7 @@ namespace incomplete_test {
|
|||||||
{
|
{
|
||||||
boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
|
boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
// Now define the value type.
|
// Now define the value type.
|
||||||
|
|
||||||
struct value
|
struct value
|
||||||
|
244
test/unordered/init_type_insert_tests.cpp
Normal file
244
test/unordered/init_type_insert_tests.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#if !defined(BOOST_UNORDERED_FOA_TESTS)
|
||||||
|
#error "This test is only for the FOA-style conatiners"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../helpers/unordered.hpp"
|
||||||
|
|
||||||
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
|
struct move_only
|
||||||
|
{
|
||||||
|
int x_ = -1;
|
||||||
|
|
||||||
|
move_only() = default;
|
||||||
|
move_only(int x) : x_{x} {}
|
||||||
|
move_only(move_only const&) = delete;
|
||||||
|
move_only(move_only&&) = default;
|
||||||
|
|
||||||
|
friend bool operator==(move_only const& lhs, move_only const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.x_ == rhs.x_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace std{
|
||||||
|
|
||||||
|
template <> struct hash<move_only>
|
||||||
|
{
|
||||||
|
std::size_t operator()(move_only const& mo) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<int>()(mo.x_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
struct raii_tracker
|
||||||
|
{
|
||||||
|
static unsigned move_constructs;
|
||||||
|
static unsigned copy_constructs;
|
||||||
|
|
||||||
|
int x_ = -1;
|
||||||
|
|
||||||
|
static void reset_counts()
|
||||||
|
{
|
||||||
|
move_constructs = 0;
|
||||||
|
copy_constructs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
raii_tracker() {}
|
||||||
|
raii_tracker(int x) : x_{x} {}
|
||||||
|
raii_tracker(raii_tracker const& rhs) : x_{rhs.x_} { ++copy_constructs; }
|
||||||
|
|
||||||
|
raii_tracker(raii_tracker&& rhs) noexcept : x_{rhs.x_}
|
||||||
|
{
|
||||||
|
rhs.x_ = -1;
|
||||||
|
|
||||||
|
++move_constructs;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(raii_tracker const& lhs, raii_tracker const& rhs)
|
||||||
|
{
|
||||||
|
return lhs.x_ == rhs.x_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace std{
|
||||||
|
|
||||||
|
template <> struct hash<raii_tracker>
|
||||||
|
{
|
||||||
|
std::size_t operator()(raii_tracker const& rt) const noexcept
|
||||||
|
{
|
||||||
|
return std::hash<int>()(rt.x_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
unsigned raii_tracker::move_constructs = 0;
|
||||||
|
unsigned raii_tracker::copy_constructs = 0;
|
||||||
|
|
||||||
|
static void test_move_only()
|
||||||
|
{
|
||||||
|
int const v = 128;
|
||||||
|
|
||||||
|
boost::unordered_flat_map<move_only, int, std::hash<move_only> > map;
|
||||||
|
|
||||||
|
using init_type = decltype(map)::init_type;
|
||||||
|
static_assert(
|
||||||
|
std::is_same<decltype(std::make_pair(move_only(1), v)), init_type>::value,
|
||||||
|
"");
|
||||||
|
|
||||||
|
map.insert(std::make_pair(move_only(1), v));
|
||||||
|
map.insert({move_only(2), v});
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(map.size(), 2u);
|
||||||
|
|
||||||
|
map.rehash(1024);
|
||||||
|
BOOST_TEST_GE(map.bucket_count(), 1024u);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_insert_tracking()
|
||||||
|
{
|
||||||
|
raii_tracker::reset_counts();
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||||
|
|
||||||
|
boost::unordered_flat_map<raii_tracker, raii_tracker,
|
||||||
|
std::hash<raii_tracker> >
|
||||||
|
map;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker, raii_tracker> value{1, 2};
|
||||||
|
|
||||||
|
map.insert(value);
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker, raii_tracker> value{2, 3};
|
||||||
|
|
||||||
|
map.insert(std::move(value));
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker const, raii_tracker> value{3, 4};
|
||||||
|
|
||||||
|
map.insert(value);
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker const, raii_tracker> value{4, 5};
|
||||||
|
|
||||||
|
map.insert(std::move(value));
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 3u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map.insert(std::make_pair(5, 6));
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 5u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map.insert({6, 7});
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(map.size(), 6u);
|
||||||
|
|
||||||
|
map.rehash(1024);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u + 2u * map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_insert_hint_tracking()
|
||||||
|
{
|
||||||
|
raii_tracker::reset_counts();
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 0u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||||
|
|
||||||
|
boost::unordered_flat_map<raii_tracker, raii_tracker,
|
||||||
|
std::hash<raii_tracker> >
|
||||||
|
map;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker, raii_tracker> value{1, 2};
|
||||||
|
|
||||||
|
map.insert(map.begin(), value);
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 0u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker, raii_tracker> value{2, 3};
|
||||||
|
|
||||||
|
map.insert(std::move(value));
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 2u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker const, raii_tracker> value{3, 4};
|
||||||
|
|
||||||
|
map.insert(map.begin(), value);
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 4u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::pair<raii_tracker const, raii_tracker> value{4, 5};
|
||||||
|
|
||||||
|
map.insert(map.begin(), std::move(value));
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 3u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map.insert(map.begin(), std::make_pair(5, 6));
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 5u);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
map.insert(map.begin(), {6, 7});
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST_EQ(map.size(), 6u);
|
||||||
|
|
||||||
|
map.rehash(1024);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::copy_constructs, 5u);
|
||||||
|
BOOST_TEST_EQ(raii_tracker::move_constructs, 7u + 2u * map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_move_only();
|
||||||
|
test_insert_tracking();
|
||||||
|
test_insert_hint_tracking();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2016 Daniel James.
|
// Copyright 2016 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../helpers/invariants.hpp"
|
#include "../helpers/invariants.hpp"
|
||||||
@ -17,6 +13,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace insert_hint {
|
namespace insert_hint {
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (insert_hint_empty) {
|
UNORDERED_AUTO_TEST (insert_hint_empty) {
|
||||||
typedef boost::unordered_multiset<int> container;
|
typedef boost::unordered_multiset<int> container;
|
||||||
container x;
|
container x;
|
||||||
@ -90,9 +87,13 @@ namespace insert_hint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
UNORDERED_AUTO_TEST (insert_hint_unique) {
|
UNORDERED_AUTO_TEST (insert_hint_unique) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int> container;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int> container;
|
typedef boost::unordered_set<int> container;
|
||||||
|
#endif
|
||||||
container x;
|
container x;
|
||||||
x.insert(x.cbegin(), 10);
|
x.insert(x.cbegin(), 10);
|
||||||
BOOST_TEST_EQ(x.size(), 1u);
|
BOOST_TEST_EQ(x.size(), 1u);
|
||||||
@ -101,7 +102,11 @@ namespace insert_hint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (insert_hint_unique_single) {
|
UNORDERED_AUTO_TEST (insert_hint_unique_single) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int> container;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int> container;
|
typedef boost::unordered_set<int> container;
|
||||||
|
#endif
|
||||||
container x;
|
container x;
|
||||||
x.insert(10);
|
x.insert(10);
|
||||||
|
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
|
|
||||||
// Copyright 2006-2010 Daniel James.
|
// Copyright 2006-2010 Daniel James.
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#if !defined(PIECEWISE_TEST_NAME)
|
#if !defined(PIECEWISE_TEST_NAME)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -21,6 +17,8 @@
|
|||||||
#include "../helpers/input_iterator.hpp"
|
#include "../helpers/input_iterator.hpp"
|
||||||
#include "../helpers/helpers.hpp"
|
#include "../helpers/helpers.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace insert_tests {
|
namespace insert_tests {
|
||||||
|
|
||||||
test::seed_t initialize_seed(243432);
|
test::seed_t initialize_seed(243432);
|
||||||
@ -678,6 +676,23 @@ namespace insert_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class X> void set_tests(X*, test::random_generator)
|
||||||
|
{
|
||||||
|
// prove that our insert(iterator, iterator) implementation honors
|
||||||
|
// Cpp17EmplaceConstructible
|
||||||
|
//
|
||||||
|
|
||||||
|
X x;
|
||||||
|
std::vector<int> v;
|
||||||
|
v.reserve(1000);
|
||||||
|
for (unsigned i = 0; i < 1000; ++i) {
|
||||||
|
v.push_back(static_cast<int>(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
x.insert(v.begin(), v.end());
|
||||||
|
BOOST_TEST_EQ(x.size(), 1000u);
|
||||||
|
}
|
||||||
|
|
||||||
template <class X>
|
template <class X>
|
||||||
void try_emplace_tests(X*, test::random_generator generator)
|
void try_emplace_tests(X*, test::random_generator generator)
|
||||||
{
|
{
|
||||||
@ -870,6 +885,53 @@ namespace insert_tests {
|
|||||||
test::check_equivalent_keys(x);
|
test::check_equivalent_keys(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::movable, test::hash, test::equal_to,
|
||||||
|
std::allocator<test::movable> >* test_set_std_alloc;
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::movable, test::movable, test::hash,
|
||||||
|
test::equal_to, test::allocator2<test::movable> >* test_map;
|
||||||
|
|
||||||
|
UNORDERED_TEST(unique_insert_tests1,
|
||||||
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
insert_tests2, ((test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(unique_emplace_tests1,
|
||||||
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(move_emplace_tests,
|
||||||
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(default_emplace_tests,
|
||||||
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(map_tests,
|
||||||
|
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
map_tests2, ((test_map))((default_generator)(generate_collisions)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(map_insert_range_test1,
|
||||||
|
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(map_insert_range_test2,
|
||||||
|
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
set_tests, ((test_set_std_alloc)(test_set))((default_generator)))
|
||||||
|
#else
|
||||||
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
||||||
std::allocator<test::movable> >* test_set_std_alloc;
|
std::allocator<test::movable> >* test_set_std_alloc;
|
||||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
@ -884,10 +946,6 @@ namespace insert_tests {
|
|||||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(unique_insert_tests1,
|
UNORDERED_TEST(unique_insert_tests1,
|
||||||
((test_set_std_alloc)(test_set)(test_map))(
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
@ -897,8 +955,8 @@ namespace insert_tests {
|
|||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(insert_tests2,
|
UNORDERED_TEST(insert_tests2,
|
||||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(
|
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
||||||
test_multimap))((default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(unique_emplace_tests1,
|
UNORDERED_TEST(unique_emplace_tests1,
|
||||||
((test_set_std_alloc)(test_set)(test_map))(
|
((test_set_std_alloc)(test_set)(test_map))(
|
||||||
@ -909,13 +967,11 @@ namespace insert_tests {
|
|||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(move_emplace_tests,
|
UNORDERED_TEST(move_emplace_tests,
|
||||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
|
||||||
test_multiset)(test_multimap))(
|
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(default_emplace_tests,
|
UNORDERED_TEST(default_emplace_tests,
|
||||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
|
||||||
test_multiset)(test_multimap))(
|
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
UNORDERED_TEST(map_tests,
|
UNORDERED_TEST(map_tests,
|
||||||
@ -932,6 +988,10 @@ namespace insert_tests {
|
|||||||
((test_multimap_std_alloc)(test_map)(test_multimap))(
|
((test_multimap_std_alloc)(test_map)(test_multimap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(
|
||||||
|
set_tests, ((test_set_std_alloc)(test_set)(test_multiset))((default_generator)))
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||||
|
|
||||||
struct initialize_from_two_ints
|
struct initialize_from_two_ints
|
||||||
@ -950,13 +1010,21 @@ namespace insert_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (insert_initializer_list_set) {
|
UNORDERED_AUTO_TEST (insert_initializer_list_set) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> set;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> set;
|
boost::unordered_set<int> set;
|
||||||
|
#endif
|
||||||
set.insert({1, 2, 3, 1});
|
set.insert({1, 2, 3, 1});
|
||||||
BOOST_TEST_EQ(set.size(), 3u);
|
BOOST_TEST_EQ(set.size(), 3u);
|
||||||
BOOST_TEST(set.find(1) != set.end());
|
BOOST_TEST(set.find(1) != set.end());
|
||||||
BOOST_TEST(set.find(4) == set.end());
|
BOOST_TEST(set.find(4) == set.end());
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<initialize_from_two_ints> set2;
|
||||||
|
#else
|
||||||
boost::unordered_set<initialize_from_two_ints> set2;
|
boost::unordered_set<initialize_from_two_ints> set2;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
|
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
|
||||||
set2.insert({{1, 2}});
|
set2.insert({{1, 2}});
|
||||||
@ -985,6 +1053,7 @@ namespace insert_tests {
|
|||||||
BOOST_TEST(set2.find({8, 7}) == set2.end());
|
BOOST_TEST(set2.find({8, 7}) == set2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (insert_initializer_list_multiset) {
|
UNORDERED_AUTO_TEST (insert_initializer_list_multiset) {
|
||||||
@ -1002,16 +1071,22 @@ namespace insert_tests {
|
|||||||
BOOST_TEST_EQ(multiset.count("c"), 0u);
|
BOOST_TEST_EQ(multiset.count("c"), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (insert_initializer_list_map) {
|
UNORDERED_AUTO_TEST (insert_initializer_list_map) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<std::string, std::string> map;
|
||||||
|
#else
|
||||||
boost::unordered_map<std::string, std::string> map;
|
boost::unordered_map<std::string, std::string> map;
|
||||||
|
#endif
|
||||||
// map.insert({});
|
// map.insert({});
|
||||||
BOOST_TEST(map.empty());
|
BOOST_TEST(map.empty());
|
||||||
map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
|
map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
|
||||||
BOOST_TEST_EQ(map.size(), 2u);
|
BOOST_TEST_EQ(map.size(), 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (insert_initializer_list_multimap) {
|
UNORDERED_AUTO_TEST (insert_initializer_list_multimap) {
|
||||||
boost::unordered_multimap<std::string, std::string> multimap;
|
boost::unordered_multimap<std::string, std::string> multimap;
|
||||||
// multimap.insert({});
|
// multimap.insert({});
|
||||||
@ -1020,6 +1095,7 @@ namespace insert_tests {
|
|||||||
BOOST_TEST_EQ(multimap.size(), 3u);
|
BOOST_TEST_EQ(multimap.size(), 3u);
|
||||||
BOOST_TEST_EQ(multimap.count("a"), 2u);
|
BOOST_TEST_EQ(multimap.count("a"), 2u);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1050,10 +1126,18 @@ namespace insert_tests {
|
|||||||
|
|
||||||
UNORDERED_AUTO_TEST (map_emplace_test) {
|
UNORDERED_AUTO_TEST (map_emplace_test) {
|
||||||
{
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, overloaded_constructor, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::allocator1<std::pair<int const, overloaded_constructor> > >
|
||||||
|
x;
|
||||||
|
#else
|
||||||
|
|
||||||
boost::unordered_map<int, overloaded_constructor, test::hash,
|
boost::unordered_map<int, overloaded_constructor, test::hash,
|
||||||
test::equal_to,
|
test::equal_to,
|
||||||
test::allocator1<std::pair<int const, overloaded_constructor> > >
|
test::allocator1<std::pair<int const, overloaded_constructor> > >
|
||||||
x;
|
x;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
||||||
x.emplace();
|
x.emplace();
|
||||||
@ -1070,6 +1154,7 @@ namespace insert_tests {
|
|||||||
x.find(5) != x.end() && x.find(5)->second == overloaded_constructor());
|
x.find(5) != x.end() && x.find(5)->second == overloaded_constructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
{
|
{
|
||||||
boost::unordered_multimap<int, overloaded_constructor, test::hash,
|
boost::unordered_multimap<int, overloaded_constructor, test::hash,
|
||||||
test::equal_to,
|
test::equal_to,
|
||||||
@ -1086,11 +1171,17 @@ namespace insert_tests {
|
|||||||
BOOST_TEST(
|
BOOST_TEST(
|
||||||
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
|
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (set_emplace_test) {
|
UNORDERED_AUTO_TEST (set_emplace_test) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<overloaded_constructor> x;
|
||||||
|
overloaded_constructor check;
|
||||||
|
#else
|
||||||
boost::unordered_set<overloaded_constructor> x;
|
boost::unordered_set<overloaded_constructor> x;
|
||||||
overloaded_constructor check;
|
overloaded_constructor check;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
|
||||||
x.emplace();
|
x.emplace();
|
||||||
@ -1136,6 +1227,7 @@ namespace insert_tests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (map_emplace_test2) {
|
UNORDERED_AUTO_TEST (map_emplace_test2) {
|
||||||
// Emulating piecewise construction with boost::tuple bypasses the
|
// Emulating piecewise construction with boost::tuple bypasses the
|
||||||
// allocator's construct method, but still uses test destroy method.
|
// allocator's construct method, but still uses test destroy method.
|
||||||
@ -1259,10 +1351,13 @@ namespace insert_tests {
|
|||||||
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
|
||||||
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Use the preprocessor to generate tests using different combinations of
|
// Use the preprocessor to generate tests using different combinations of
|
||||||
// boost/std piecewise_construct_t/tuple.
|
// boost/std piecewise_construct_t/tuple.
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
|
||||||
#define PIECEWISE_TEST_NAME boost_tuple_piecewise_tests
|
#define PIECEWISE_TEST_NAME boost_tuple_piecewise_tests
|
||||||
#define PIECEWISE_NAMESPACE boost::unordered
|
#define PIECEWISE_NAMESPACE boost::unordered
|
||||||
#define TUPLE_NAMESPACE boost
|
#define TUPLE_NAMESPACE boost
|
||||||
@ -1289,6 +1384,8 @@ namespace insert_tests {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||||
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||||
|
|
||||||
@ -1311,12 +1408,21 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
|
#if defined(BOOST_UNORDERED_FOA_TESTS)
|
||||||
|
boost::unordered_flat_map<overloaded_constructor, overloaded_constructor,
|
||||||
|
boost::hash<overloaded_constructor>,
|
||||||
|
std::equal_to<overloaded_constructor>,
|
||||||
|
test::allocator1<
|
||||||
|
std::pair<overloaded_constructor const, overloaded_constructor> > >
|
||||||
|
x;
|
||||||
|
#else
|
||||||
boost::unordered_map<overloaded_constructor, overloaded_constructor,
|
boost::unordered_map<overloaded_constructor, overloaded_constructor,
|
||||||
boost::hash<overloaded_constructor>,
|
boost::hash<overloaded_constructor>,
|
||||||
std::equal_to<overloaded_constructor>,
|
std::equal_to<overloaded_constructor>,
|
||||||
test::allocator1<
|
test::allocator1<
|
||||||
std::pair<overloaded_constructor const, overloaded_constructor> > >
|
std::pair<overloaded_constructor const, overloaded_constructor> > >
|
||||||
x;
|
x;
|
||||||
|
#endif
|
||||||
|
|
||||||
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
||||||
TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple());
|
TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple());
|
||||||
@ -1360,6 +1466,7 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
|||||||
x.find(overloaded_constructor(2, 3))->second ==
|
x.find(overloaded_constructor(2, 3))->second ==
|
||||||
overloaded_constructor(4, 5, 6));
|
overloaded_constructor(4, 5, 6));
|
||||||
}
|
}
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
{
|
{
|
||||||
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
|
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
|
||||||
boost::hash<overloaded_constructor>,
|
boost::hash<overloaded_constructor>,
|
||||||
@ -1393,6 +1500,7 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
|
|||||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||||
overloaded_constructor(10));
|
overloaded_constructor(10));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
|
UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
|
||||||
@ -1400,9 +1508,15 @@ UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
|
|||||||
test::detail::disable_construction_tracking _scoped;
|
test::detail::disable_construction_tracking _scoped;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<
|
||||||
|
std::pair<overloaded_constructor, overloaded_constructor> >
|
||||||
|
x;
|
||||||
|
#else
|
||||||
boost::unordered_set<
|
boost::unordered_set<
|
||||||
std::pair<overloaded_constructor, overloaded_constructor> >
|
std::pair<overloaded_constructor, overloaded_constructor> >
|
||||||
x;
|
x;
|
||||||
|
#endif
|
||||||
std::pair<overloaded_constructor, overloaded_constructor> check;
|
std::pair<overloaded_constructor, overloaded_constructor> check;
|
||||||
|
|
||||||
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void foo(boost::unordered_flat_set<int>&, boost::unordered_flat_map<int, int>&);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::unordered_flat_set<int> x1;
|
||||||
|
boost::unordered_flat_map<int, int> x2;
|
||||||
|
|
||||||
|
foo(x1, x2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
void foo(boost::unordered_set<int>&, boost::unordered_map<int, int>&,
|
void foo(boost::unordered_set<int>&, boost::unordered_map<int, int>&,
|
||||||
boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
|
boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
|
||||||
|
|
||||||
@ -24,3 +33,4 @@ int main()
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void foo(
|
||||||
|
boost::unordered_flat_set<int>& x1, boost::unordered_flat_map<int, int>& x2)
|
||||||
|
{
|
||||||
|
#if BOOST_WORKAROUND(BOOST_CODEGEARC, BOOST_TESTED_AT(0x0613))
|
||||||
|
struct dummy
|
||||||
|
{
|
||||||
|
boost::unordered_flat_set<int> x1;
|
||||||
|
boost::unordered_flat_map<int, int> x2;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
x1.insert(1);
|
||||||
|
x2[2] = 2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
||||||
boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
|
boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
|
||||||
{
|
{
|
||||||
@ -28,3 +40,4 @@ void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
|||||||
x3.insert(3);
|
x3.insert(3);
|
||||||
x4.insert(std::make_pair(4, 5));
|
x4.insert(std::make_pair(4, 5));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
@ -26,7 +22,17 @@ namespace load_factor_tests {
|
|||||||
template <class X> void set_load_factor_tests(X*)
|
template <class X> void set_load_factor_tests(X*)
|
||||||
{
|
{
|
||||||
X x;
|
X x;
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||||
|
BOOST_TEST(x.load_factor() == 0);
|
||||||
|
|
||||||
|
// A valid implementation could fail these tests, but I think they're
|
||||||
|
// reasonable.
|
||||||
|
x.max_load_factor(2.0);
|
||||||
|
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||||
|
x.max_load_factor(0.5);
|
||||||
|
BOOST_TEST(x.max_load_factor() == boost::unordered::detail::foa::mlf);
|
||||||
|
#else
|
||||||
BOOST_TEST(x.max_load_factor() == 1.0);
|
BOOST_TEST(x.max_load_factor() == 1.0);
|
||||||
BOOST_TEST(x.load_factor() == 0);
|
BOOST_TEST(x.load_factor() == 0);
|
||||||
|
|
||||||
@ -36,6 +42,7 @@ namespace load_factor_tests {
|
|||||||
BOOST_TEST(x.max_load_factor() == 2.0);
|
BOOST_TEST(x.max_load_factor() == 2.0);
|
||||||
x.max_load_factor(0.5);
|
x.max_load_factor(0.5);
|
||||||
BOOST_TEST(x.max_load_factor() == 0.5);
|
BOOST_TEST(x.max_load_factor() == 0.5);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X>
|
template <class X>
|
||||||
@ -72,21 +79,32 @@ namespace load_factor_tests {
|
|||||||
insert_test(ptr, std::numeric_limits<float>::infinity(), generator);
|
insert_test(ptr, std::numeric_limits<float>::infinity(), generator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int>* int_set_ptr;
|
||||||
|
boost::unordered_flat_map<int, int>* int_map_ptr;
|
||||||
|
|
||||||
|
UNORDERED_TEST(set_load_factor_tests, ((int_set_ptr)(int_map_ptr)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(load_factor_insert_tests,
|
||||||
|
((int_set_ptr)(int_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_set<int>* int_set_ptr;
|
boost::unordered_set<int>* int_set_ptr;
|
||||||
boost::unordered_multiset<int>* int_multiset_ptr;
|
boost::unordered_multiset<int>* int_multiset_ptr;
|
||||||
boost::unordered_map<int, int>* int_map_ptr;
|
boost::unordered_map<int, int>* int_map_ptr;
|
||||||
boost::unordered_multimap<int, int>* int_multimap_ptr;
|
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,
|
UNORDERED_TEST(set_load_factor_tests,
|
||||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)))
|
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)))
|
||||||
|
|
||||||
UNORDERED_TEST(load_factor_insert_tests,
|
UNORDERED_TEST(load_factor_insert_tests,
|
||||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
|
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2016 Daniel James.
|
// Copyright 2016 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
#include "../helpers/postfix.hpp"
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
|
|
||||||
#include "../helpers/count.hpp"
|
#include "../helpers/count.hpp"
|
||||||
#include "../helpers/helpers.hpp"
|
#include "../helpers/helpers.hpp"
|
||||||
@ -19,8 +17,13 @@
|
|||||||
namespace merge_tests {
|
namespace merge_tests {
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (merge_set) {
|
UNORDERED_AUTO_TEST (merge_set) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> x;
|
||||||
|
boost::unordered_flat_set<int> y;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> x;
|
boost::unordered_set<int> x;
|
||||||
boost::unordered_set<int> y;
|
boost::unordered_set<int> y;
|
||||||
|
#endif
|
||||||
|
|
||||||
x.merge(y);
|
x.merge(y);
|
||||||
BOOST_TEST(x.empty());
|
BOOST_TEST(x.empty());
|
||||||
@ -57,6 +60,7 @@ namespace merge_tests {
|
|||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
UNORDERED_AUTO_TEST (merge_multiset) {
|
UNORDERED_AUTO_TEST (merge_multiset) {
|
||||||
boost::unordered_multiset<int> x;
|
boost::unordered_multiset<int> x;
|
||||||
boost::unordered_multiset<int> y;
|
boost::unordered_multiset<int> y;
|
||||||
@ -134,6 +138,7 @@ namespace merge_tests {
|
|||||||
test::check_equivalent_keys(x);
|
test::check_equivalent_keys(x);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class X1, class X2>
|
template <class X1, class X2>
|
||||||
void merge_empty_test(X1*, X2*, test::random_generator generator)
|
void merge_empty_test(X1*, X2*, test::random_generator generator)
|
||||||
@ -228,6 +233,82 @@ namespace merge_tests {
|
|||||||
test::check_equivalent_keys(x2);
|
test::check_equivalent_keys(x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<test::movable, test::hash, test::equal_to,
|
||||||
|
std::allocator<test::movable> >* test_set_std_alloc;
|
||||||
|
|
||||||
|
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
|
||||||
|
|
||||||
|
boost::unordered_flat_map<test::movable, test::movable, test::hash, test::equal_to,
|
||||||
|
test::allocator2<test::movable> >* test_map;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
UNORDERED_TEST(merge_empty_test,
|
||||||
|
((test_set_std_alloc))
|
||||||
|
((test_set_std_alloc))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_empty_test,
|
||||||
|
((test_map_std_alloc))
|
||||||
|
((test_map_std_alloc))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_empty_test,
|
||||||
|
((test_set))
|
||||||
|
((test_set))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_empty_test,
|
||||||
|
((test_map))
|
||||||
|
((test_map))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(merge_into_empty_test,
|
||||||
|
((test_set_std_alloc))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_empty_test,
|
||||||
|
((test_map_std_alloc))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_empty_test,
|
||||||
|
((test_set))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_empty_test,
|
||||||
|
((test_map))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||||
|
((test_set_std_alloc))
|
||||||
|
((test_set_std_alloc))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||||
|
((test_map_std_alloc))
|
||||||
|
((test_map_std_alloc))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||||
|
((test_set))
|
||||||
|
((test_set))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
UNORDERED_TEST(merge_into_unique_keys_test,
|
||||||
|
((test_map))
|
||||||
|
((test_map))
|
||||||
|
((0)(1)(2))
|
||||||
|
((0)(1)(2))
|
||||||
|
((default_generator)(generate_collisions)))
|
||||||
|
// clang-format on
|
||||||
|
#else
|
||||||
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
||||||
std::allocator<test::movable> >* test_set_std_alloc;
|
std::allocator<test::movable> >* test_set_std_alloc;
|
||||||
boost::unordered_multiset<test::movable, test::hash, test::equal_to,
|
boost::unordered_multiset<test::movable, test::hash, test::equal_to,
|
||||||
@ -248,9 +329,6 @@ namespace merge_tests {
|
|||||||
boost::unordered_multimap<test::movable, test::movable, test::hash,
|
boost::unordered_multimap<test::movable, test::movable, test::hash,
|
||||||
test::equal_to, test::allocator2<test::movable> >* test_multimap;
|
test::equal_to, test::allocator2<test::movable> >* test_multimap;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
UNORDERED_TEST(merge_empty_test,
|
UNORDERED_TEST(merge_empty_test,
|
||||||
((test_set_std_alloc)(test_multiset_std_alloc))
|
((test_set_std_alloc)(test_multiset_std_alloc))
|
||||||
@ -332,6 +410,8 @@ UNORDERED_TEST(merge_into_equiv_keys_test,
|
|||||||
((0)(1)(2))
|
((0)(1)(2))
|
||||||
((default_generator)(generate_collisions)))
|
((default_generator)(generate_collisions)))
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2008-2009 Daniel James.
|
// Copyright 2008-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
@ -71,7 +67,11 @@ namespace move_tests {
|
|||||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 1.0);
|
BOOST_TEST(y.max_load_factor() == 1.0);
|
||||||
|
#endif
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
@ -146,7 +146,11 @@ namespace move_tests {
|
|||||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
|
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
|
||||||
|
#endif
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +166,11 @@ namespace move_tests {
|
|||||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
|
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
|
||||||
|
#endif
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +200,11 @@ namespace move_tests {
|
|||||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
|
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
|
||||||
|
#endif
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,7 +227,11 @@ namespace move_tests {
|
|||||||
BOOST_TEST(y.empty());
|
BOOST_TEST(y.empty());
|
||||||
test::check_container(y, v2);
|
test::check_container(y, v2);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 2.0);
|
BOOST_TEST(y.max_load_factor() == 2.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_HAS_NRVO)
|
#if defined(BOOST_HAS_NRVO)
|
||||||
if (BOOST_UNORDERED_TEST_MOVING
|
if (BOOST_UNORDERED_TEST_MOVING
|
||||||
@ -240,7 +256,11 @@ namespace move_tests {
|
|||||||
#endif
|
#endif
|
||||||
test::check_container(y, v);
|
test::check_container(y, v);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_HAS_NRVO)
|
#if defined(BOOST_HAS_NRVO)
|
||||||
if (BOOST_UNORDERED_TEST_MOVING
|
if (BOOST_UNORDERED_TEST_MOVING
|
||||||
@ -268,7 +288,11 @@ namespace move_tests {
|
|||||||
#endif
|
#endif
|
||||||
test::check_container(y, v);
|
test::check_container(y, v);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (BOOST_UNORDERED_TEST_MOVING
|
if (BOOST_UNORDERED_TEST_MOVING
|
||||||
? (bool)allocator_type::is_propagate_on_move
|
? (bool)allocator_type::is_propagate_on_move
|
||||||
@ -296,7 +320,11 @@ namespace move_tests {
|
|||||||
}
|
}
|
||||||
test::check_container(y, v);
|
test::check_container(y, v);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (BOOST_UNORDERED_TEST_MOVING
|
if (BOOST_UNORDERED_TEST_MOVING
|
||||||
? (bool)allocator_type::is_propagate_on_move
|
? (bool)allocator_type::is_propagate_on_move
|
||||||
@ -332,7 +360,11 @@ namespace move_tests {
|
|||||||
|
|
||||||
test::check_container(y, v2);
|
test::check_container(y, v2);
|
||||||
test::check_equivalent_keys(y);
|
test::check_equivalent_keys(y);
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.max_load_factor() == 0.875);
|
||||||
|
#else
|
||||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (BOOST_UNORDERED_TEST_MOVING
|
if (BOOST_UNORDERED_TEST_MOVING
|
||||||
? (bool)allocator_type::is_propagate_on_move
|
? (bool)allocator_type::is_propagate_on_move
|
||||||
@ -344,519 +376,51 @@ namespace move_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> T const& get_key(T const& t) { return t; }
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
template <class K, class V> K const& get_key(std::pair<K const, V> const& kv)
|
using test::limited_range;
|
||||||
{
|
|
||||||
return kv.first;
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
}
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
template <class T> T const& get_value(T const& t) { return t; }
|
std::allocator<std::pair<test::object const, test::object> > >*
|
||||||
|
test_map_std_alloc;
|
||||||
template <class K, class V> K const& get_value(std::pair<K const, V> const& kv)
|
|
||||||
{
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
return kv.second;
|
test::allocator2<test::object> >* test_set;
|
||||||
}
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
template <class T>
|
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||||
static void insert_range(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
y.insert(v.begin(), v.end());
|
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||||
BOOST_TEST_EQ(y.size(),
|
test_set_prop_move;
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
}
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
template <class T>
|
test::propagate_move> >* test_map_prop_move;
|
||||||
static void insert_single(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
y.insert(*v.begin());
|
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||||
BOOST_TEST_EQ(y.size(),
|
test_set_no_prop_move;
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
}
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
template <class T>
|
test::no_propagate_move> >* test_map_no_prop_move;
|
||||||
static void insert_single_hint(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
UNORDERED_TEST(move_construct_tests1,
|
||||||
y.insert(y.end(), *v.begin());
|
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||||
BOOST_TEST_EQ(y.size(),
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
UNORDERED_TEST(move_assign_tests1,
|
||||||
}
|
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
template <class T> struct insert_or_assign_invoker
|
UNORDERED_TEST(move_construct_tests2,
|
||||||
{
|
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
};
|
UNORDERED_TEST(move_assign_tests2,
|
||||||
|
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
struct insert_or_assign_invoker<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
|
||||||
Allocator>::size_type size_type;
|
|
||||||
|
|
||||||
y.insert_or_assign(get_key(*v.begin()), get_value(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(
|
|
||||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void insert_or_assign(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
insert_or_assign_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct insert_or_assign_hint_invoker
|
|
||||||
{
|
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
struct insert_or_assign_hint_invoker<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
|
||||||
Allocator>::size_type size_type;
|
|
||||||
y.insert_or_assign(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(
|
|
||||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void insert_or_assign_hint(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
insert_or_assign_hint_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct try_emplace_invoker
|
|
||||||
{
|
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
struct try_emplace_invoker<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
|
||||||
Allocator>::size_type size_type;
|
|
||||||
y.try_emplace(get_key(*v.begin()), get_value(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(
|
|
||||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void try_emplace(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
try_emplace_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct try_emplace_hint_invoker
|
|
||||||
{
|
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
struct try_emplace_hint_invoker<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
|
||||||
Allocator>::size_type size_type;
|
|
||||||
y.try_emplace(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(
|
|
||||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void try_emplace_hint(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
try_emplace_hint_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct at_invoker
|
|
||||||
{
|
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
struct at_invoker<boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
BOOST_TRY { y.at(get_key(*v.begin())); }
|
|
||||||
BOOST_CATCH(...) {}
|
|
||||||
BOOST_CATCH_END
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> static void at(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
at_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct index_operator_invoker
|
|
||||||
{
|
|
||||||
void operator()(T&, test::random_values<T> const&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
|
||||||
struct index_operator_invoker<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
|
||||||
{
|
|
||||||
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
|
||||||
test::random_values<
|
|
||||||
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
|
||||||
{
|
|
||||||
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
|
||||||
Allocator>::size_type size_type;
|
|
||||||
y[get_key(*v.begin())] = get_value(*v.begin());
|
|
||||||
BOOST_TEST_EQ(
|
|
||||||
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void index_operator(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
index_operator_invoker<T>()(y, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void clear(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
y.clear();
|
|
||||||
BOOST_TEST(y.empty());
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void capacity(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
(void)y.empty();
|
|
||||||
(void)y.size();
|
|
||||||
(void)y.max_size();
|
|
||||||
(void)y.load_factor();
|
|
||||||
(void)y.max_load_factor();
|
|
||||||
(void)y.hash_function();
|
|
||||||
(void)y.key_eq();
|
|
||||||
(void)y.get_allocator();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void iterators(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void erase_range(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
y.erase(y.begin(), y.end());
|
|
||||||
BOOST_TEST(y.empty());
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void erase_key(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
y.erase(get_key(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void lookup(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
(void)y.count(get_key(*v.begin()));
|
|
||||||
(void)y.find(get_key(*v.begin()));
|
|
||||||
(void)y.contains(get_key(*v.begin()));
|
|
||||||
(void)y.equal_range(get_key(*v.begin()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void reserve(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
y.reserve(1337);
|
|
||||||
BOOST_TEST_GT(y.bucket_count(), 1337u);
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void copy_assignment(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
T x(v.begin(), v.end());
|
|
||||||
y = x;
|
|
||||||
BOOST_TEST_EQ(y.size(), x.size());
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void move_assignment(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
T x(v.begin(), v.end());
|
|
||||||
std::size_t const size = x.size();
|
|
||||||
y = boost::move(x);
|
|
||||||
BOOST_TEST_GE(y.size(), size);
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void equal(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
T x(v.begin(), v.end());
|
|
||||||
(void)(y == x);
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void extract(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
(void)y.extract(get_key(*v.begin()));
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void merge(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
T x(v.begin(), v.end());
|
|
||||||
if (y.get_allocator() == x.get_allocator()) {
|
|
||||||
y.merge(x);
|
|
||||||
}
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class X> bool pred(X const&) { return true; }
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void erase_with_pred(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
erase_if(y, pred<typename T::value_type>);
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void container_swap(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
T x(v.begin(), v.end());
|
|
||||||
if (boost::allocator_propagate_on_container_swap<
|
|
||||||
typename T::allocator_type>::type::value ||
|
|
||||||
x.get_allocator() == y.get_allocator()) {
|
|
||||||
y.swap(x);
|
|
||||||
}
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> static void buckets(T& y, test::random_values<T> const& v)
|
|
||||||
{
|
|
||||||
(void)y.begin(0);
|
|
||||||
(void)y.end(0);
|
|
||||||
(void)y.bucket_count();
|
|
||||||
(void)y.max_bucket_count();
|
|
||||||
(void)y.bucket_size(0);
|
|
||||||
(void)y.bucket(get_key(*v.begin()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void double_move_construct(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
T x = boost::move(y);
|
|
||||||
x.clear();
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
BOOST_TEST_EQ(x.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void double_move_assign(T& y, test::random_values<T> const&)
|
|
||||||
{
|
|
||||||
T x;
|
|
||||||
x = boost::move(y);
|
|
||||||
x.clear();
|
|
||||||
BOOST_TEST_EQ(y.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
|
||||||
BOOST_TEST_EQ(x.size(),
|
|
||||||
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
static void post_move_tests(T* ptr, test::random_generator const& generator)
|
|
||||||
{
|
|
||||||
// clang-format off
|
|
||||||
void (*fps[])(T&, test::random_values<T> const&) = {
|
|
||||||
insert_range<T>,
|
|
||||||
insert_single<T>,
|
|
||||||
insert_single_hint<T>,
|
|
||||||
insert_or_assign<T>,
|
|
||||||
insert_or_assign_hint<T>,
|
|
||||||
try_emplace<T>,
|
|
||||||
try_emplace_hint<T>,
|
|
||||||
at<T>,
|
|
||||||
index_operator<T>,
|
|
||||||
clear<T>,
|
|
||||||
capacity<T>,
|
|
||||||
iterators<T>,
|
|
||||||
erase_range<T>,
|
|
||||||
erase_key<T>,
|
|
||||||
lookup<T>,
|
|
||||||
reserve<T>,
|
|
||||||
copy_assignment<T>,
|
|
||||||
move_assignment<T>,
|
|
||||||
equal<T>,
|
|
||||||
extract<T>,
|
|
||||||
merge<T>,
|
|
||||||
erase_with_pred<T>,
|
|
||||||
container_swap<T>,
|
|
||||||
buckets<T>,
|
|
||||||
double_move_construct<T>,
|
|
||||||
double_move_assign<T>
|
|
||||||
};
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
std::size_t const len = (sizeof(fps) / sizeof(*(fps)));
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < len; ++i) {
|
|
||||||
test::check_instances check_;
|
|
||||||
|
|
||||||
test::random_values<T> const v(1000, generator);
|
|
||||||
test::object_count count;
|
|
||||||
T y(create(v, count));
|
|
||||||
|
|
||||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
|
||||||
(void)num_allocs;
|
|
||||||
|
|
||||||
T x(boost::move(y));
|
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
|
||||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||||
BOOST_TEST(y.empty());
|
|
||||||
BOOST_TEST(y.begin() == y.end());
|
|
||||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
|
||||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fps[i](y, v);
|
|
||||||
|
|
||||||
test::check_container(x, v);
|
|
||||||
test::check_equivalent_keys(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < len; ++i) {
|
|
||||||
typename T::hasher hf(1);
|
|
||||||
typename T::key_equal eq(1);
|
|
||||||
typename T::allocator_type al1(1);
|
|
||||||
typename T::allocator_type al2(2);
|
|
||||||
|
|
||||||
test::check_instances check_;
|
|
||||||
|
|
||||||
test::random_values<T> v(1000, generator);
|
|
||||||
test::object_count count;
|
|
||||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
|
||||||
T x(boost::move(y), al2);
|
|
||||||
|
|
||||||
BOOST_TEST_NOT(y.empty());
|
|
||||||
BOOST_TEST(y.begin() != y.end());
|
|
||||||
|
|
||||||
fps[i](y, v);
|
|
||||||
|
|
||||||
test::check_container(x, v);
|
|
||||||
test::check_equivalent_keys(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < len; ++i) {
|
|
||||||
test::check_instances check_;
|
|
||||||
|
|
||||||
test::random_values<T> v(1000, generator);
|
|
||||||
test::object_count count;
|
|
||||||
T y(create(v, count));
|
|
||||||
|
|
||||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
|
||||||
(void)num_allocs;
|
|
||||||
|
|
||||||
T x(empty(ptr));
|
|
||||||
x = boost::move(y);
|
|
||||||
|
|
||||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
|
||||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||||
BOOST_TEST(y.empty());
|
|
||||||
BOOST_TEST(y.begin() == y.end());
|
|
||||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
|
||||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fps[i](y, v);
|
|
||||||
|
|
||||||
test::check_container(x, v);
|
|
||||||
test::check_equivalent_keys(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < len; ++i) {
|
|
||||||
typename T::hasher hf(1);
|
|
||||||
typename T::key_equal eq(1);
|
|
||||||
typename T::allocator_type al1(1);
|
|
||||||
typename T::allocator_type al2(2);
|
|
||||||
|
|
||||||
test::check_instances check_;
|
|
||||||
|
|
||||||
test::random_values<T> v(1000, generator);
|
|
||||||
test::object_count count;
|
|
||||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
|
||||||
|
|
||||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
|
||||||
(void)num_allocs;
|
|
||||||
|
|
||||||
T x(al2);
|
|
||||||
x = boost::move(y);
|
|
||||||
|
|
||||||
bool b = boost::allocator_propagate_on_container_move_assignment<
|
|
||||||
typename T::allocator_type>::type::value;
|
|
||||||
if (b) {
|
|
||||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
|
||||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||||
BOOST_TEST(y.empty());
|
|
||||||
BOOST_TEST(y.begin() == y.end());
|
|
||||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
|
||||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
|
||||||
#else
|
#else
|
||||||
BOOST_TEST_NOT(y.empty());
|
|
||||||
BOOST_TEST(y.begin() != y.end());
|
|
||||||
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
BOOST_TEST_NOT(y.empty());
|
|
||||||
BOOST_TEST(y.begin() != y.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
fps[i](y, v);
|
|
||||||
|
|
||||||
test::check_container(x, v);
|
|
||||||
test::check_equivalent_keys(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
std::allocator<std::pair<test::object const, test::object> > >*
|
std::allocator<std::pair<test::object const, test::object> > >*
|
||||||
test_map_std_alloc;
|
test_map_std_alloc;
|
||||||
@ -900,10 +464,6 @@ namespace move_tests {
|
|||||||
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
test::no_propagate_move> >* test_multimap_no_prop_move;
|
test::no_propagate_move> >* test_multimap_no_prop_move;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(move_construct_tests1,
|
UNORDERED_TEST(move_construct_tests1,
|
||||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
|
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
|
||||||
test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
|
test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
|
||||||
@ -930,12 +490,7 @@ namespace move_tests {
|
|||||||
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(
|
||||||
test_multimap_no_prop_move))(
|
test_multimap_no_prop_move))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
UNORDERED_TEST(post_move_tests,
|
#endif
|
||||||
((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)(limited_range)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2013 Daniel James.
|
// Copyright 2013 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../helpers/fwd.hpp"
|
#include "../helpers/fwd.hpp"
|
||||||
@ -202,6 +198,12 @@ namespace noexcept_tests {
|
|||||||
|
|
||||||
UNORDERED_AUTO_TEST (test_noexcept) {
|
UNORDERED_AUTO_TEST (test_noexcept) {
|
||||||
if (have_is_nothrow_move) {
|
if (have_is_nothrow_move) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||||
|
boost::unordered_flat_set<int> >::value));
|
||||||
|
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||||
|
boost::unordered_flat_map<int, int> >::value));
|
||||||
|
#else
|
||||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||||
boost::unordered_set<int> >::value));
|
boost::unordered_set<int> >::value));
|
||||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||||
@ -210,19 +212,35 @@ namespace noexcept_tests {
|
|||||||
boost::unordered_map<int, int> >::value));
|
boost::unordered_map<int, int> >::value));
|
||||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||||
boost::unordered_multimap<int, int> >::value));
|
boost::unordered_multimap<int, int> >::value));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(
|
||||||
|
(!boost::is_nothrow_move_constructible<
|
||||||
|
boost::unordered_flat_set<int, hash_possible_exception> >::value));
|
||||||
|
BOOST_TEST(
|
||||||
|
(!boost::is_nothrow_move_constructible<boost::unordered_flat_set<int,
|
||||||
|
boost::hash<int>, equal_to_possible_exception> >::value));
|
||||||
|
#else
|
||||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||||
boost::unordered_set<int, hash_possible_exception> >::value));
|
boost::unordered_set<int, hash_possible_exception> >::value));
|
||||||
BOOST_TEST(
|
BOOST_TEST(
|
||||||
(!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
|
(!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
|
||||||
boost::hash<int>, equal_to_possible_exception> >::value));
|
boost::hash<int>, equal_to_possible_exception> >::value));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test_nothrow_move_when_noexcept) {
|
UNORDERED_AUTO_TEST (test_nothrow_move_when_noexcept) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int, hash_nothrow_move_construct,
|
||||||
|
equal_to_nothrow_move_construct>
|
||||||
|
throwing_set;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int, hash_nothrow_move_construct,
|
typedef boost::unordered_set<int, hash_nothrow_move_construct,
|
||||||
equal_to_nothrow_move_construct>
|
equal_to_nothrow_move_construct>
|
||||||
throwing_set;
|
throwing_set;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (have_is_nothrow_move) {
|
if (have_is_nothrow_move) {
|
||||||
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
||||||
@ -310,8 +328,14 @@ namespace noexcept_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (test_nothrow_swap_when_noexcept) {
|
UNORDERED_AUTO_TEST (test_nothrow_swap_when_noexcept) {
|
||||||
|
#if BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int, hash_nothrow_swap,
|
||||||
|
equal_to_nothrow_swap>
|
||||||
|
throwing_set;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int, hash_nothrow_swap, equal_to_nothrow_swap>
|
typedef boost::unordered_set<int, hash_nothrow_swap, equal_to_nothrow_swap>
|
||||||
throwing_set;
|
throwing_set;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (have_is_nothrow_swap) {
|
if (have_is_nothrow_swap) {
|
||||||
BOOST_TEST(boost::is_nothrow_swappable<throwing_set>::value);
|
BOOST_TEST(boost::is_nothrow_swappable<throwing_set>::value);
|
||||||
@ -410,6 +434,20 @@ UNORDERED_AUTO_TEST (prelim_allocator_checks) {
|
|||||||
allocator2<int> >::type::value);
|
allocator2<int> >::type::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||||
|
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
|
||||||
|
throwing_set_alloc1;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||||
|
noexcept_tests::equal_to_nothrow_move_assign, allocator2<int> >*
|
||||||
|
throwing_set_alloc2;
|
||||||
|
|
||||||
|
UNORDERED_TEST(test_nothrow_move_assign_when_noexcept,
|
||||||
|
((throwing_set_alloc1)(throwing_set_alloc2))((default_generator)))
|
||||||
|
#else
|
||||||
boost::unordered_set<int, noexcept_tests::hash_nothrow_move_assign,
|
boost::unordered_set<int, noexcept_tests::hash_nothrow_move_assign,
|
||||||
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
|
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
|
||||||
throwing_set_alloc1;
|
throwing_set_alloc1;
|
||||||
@ -418,9 +456,8 @@ boost::unordered_set<int, noexcept_tests::hash_nothrow_move_assign,
|
|||||||
noexcept_tests::equal_to_nothrow_move_assign, allocator2<int> >*
|
noexcept_tests::equal_to_nothrow_move_assign, allocator2<int> >*
|
||||||
throwing_set_alloc2;
|
throwing_set_alloc2;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
|
|
||||||
UNORDERED_TEST(test_nothrow_move_assign_when_noexcept,
|
UNORDERED_TEST(test_nothrow_move_assign_when_noexcept,
|
||||||
((throwing_set_alloc1)(throwing_set_alloc2))((default_generator)))
|
((throwing_set_alloc1)(throwing_set_alloc2))((default_generator)))
|
||||||
|
#endif
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
666
test/unordered/post_move_tests.cpp
Normal file
666
test/unordered/post_move_tests.cpp
Normal file
@ -0,0 +1,666 @@
|
|||||||
|
|
||||||
|
// Copyright (C) 2022 Christian Mazakas
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#include "../helpers/unordered.hpp"
|
||||||
|
#include "../helpers/test.hpp"
|
||||||
|
#include "../objects/test.hpp"
|
||||||
|
#include "../objects/cxx11_allocator.hpp"
|
||||||
|
#include "../helpers/random_values.hpp"
|
||||||
|
#include "../helpers/tracker.hpp"
|
||||||
|
#include "../helpers/equivalent.hpp"
|
||||||
|
#include "../helpers/invariants.hpp"
|
||||||
|
|
||||||
|
#include <boost/core/ignore_unused.hpp>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace move_tests {
|
||||||
|
test::seed_t initialize_seed(98624);
|
||||||
|
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||||
|
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#define BOOST_UNORDERED_TEST_MOVING 1
|
||||||
|
#else
|
||||||
|
#define BOOST_UNORDERED_TEST_MOVING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class T> T empty(T*) { return T(); }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T create(test::random_values<T> const& v, test::object_count& count)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
count = test::global_object_count;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T create(test::random_values<T> const& v, test::object_count& count,
|
||||||
|
typename T::hasher hf, typename T::key_equal eq,
|
||||||
|
typename T::allocator_type al, float mlf)
|
||||||
|
{
|
||||||
|
T x(0, hf, eq, al);
|
||||||
|
x.max_load_factor(mlf);
|
||||||
|
x.insert(v.begin(), v.end());
|
||||||
|
count = test::global_object_count;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> T const& get_key(T const& t) { return t; }
|
||||||
|
|
||||||
|
template <class K, class V> K const& get_key(std::pair<K const, V> const& kv)
|
||||||
|
{
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> T const& get_value(T const& t) { return t; }
|
||||||
|
|
||||||
|
template <class K, class V> K const& get_value(std::pair<K const, V> const& kv)
|
||||||
|
{
|
||||||
|
return kv.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void insert_range(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
y.insert(v.begin(), v.end());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void insert_single(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
y.insert(*v.begin());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void insert_single_hint(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
y.insert(y.end(), *v.begin());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct insert_or_assign_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct insert_or_assign_invoker<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||||
|
Allocator>::size_type size_type;
|
||||||
|
|
||||||
|
y.insert_or_assign(get_key(*v.begin()), get_value(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(
|
||||||
|
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void insert_or_assign(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
insert_or_assign_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct insert_or_assign_hint_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct insert_or_assign_hint_invoker<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||||
|
Allocator>::size_type size_type;
|
||||||
|
y.insert_or_assign(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(
|
||||||
|
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void insert_or_assign_hint(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
insert_or_assign_hint_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct try_emplace_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct try_emplace_invoker<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||||
|
Allocator>::size_type size_type;
|
||||||
|
y.try_emplace(get_key(*v.begin()), get_value(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(
|
||||||
|
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void try_emplace(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
try_emplace_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct try_emplace_hint_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct try_emplace_hint_invoker<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||||
|
Allocator>::size_type size_type;
|
||||||
|
y.try_emplace(y.end(), get_key(*v.begin()), get_value(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(
|
||||||
|
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void try_emplace_hint(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
try_emplace_hint_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct at_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct at_invoker<boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
BOOST_TRY { y.at(get_key(*v.begin())); }
|
||||||
|
BOOST_CATCH(...) {}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> static void at(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
at_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> struct index_operator_invoker
|
||||||
|
{
|
||||||
|
void operator()(T&, test::random_values<T> const&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
|
struct index_operator_invoker<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> >
|
||||||
|
{
|
||||||
|
void operator()(boost::unordered_map<Key, T, Hash, KeyEqual, Allocator>& y,
|
||||||
|
test::random_values<
|
||||||
|
boost::unordered_map<Key, T, Hash, KeyEqual, Allocator> > const& v)
|
||||||
|
{
|
||||||
|
typedef typename boost::unordered_map<Key, T, Hash, KeyEqual,
|
||||||
|
Allocator>::size_type size_type;
|
||||||
|
y[get_key(*v.begin())] = get_value(*v.begin());
|
||||||
|
BOOST_TEST_EQ(
|
||||||
|
y.size(), static_cast<size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void index_operator(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
index_operator_invoker<T>()(y, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void clear(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
y.clear();
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void capacity(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
(void)y.empty();
|
||||||
|
(void)y.size();
|
||||||
|
(void)y.max_size();
|
||||||
|
(void)y.load_factor();
|
||||||
|
(void)y.max_load_factor();
|
||||||
|
(void)y.hash_function();
|
||||||
|
(void)y.key_eq();
|
||||||
|
(void)y.get_allocator();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void iterators(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void erase_range(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
y.erase(y.begin(), y.end());
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void erase_key(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
y.erase(get_key(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void lookup(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
(void)y.count(get_key(*v.begin()));
|
||||||
|
(void)y.find(get_key(*v.begin()));
|
||||||
|
(void)y.contains(get_key(*v.begin()));
|
||||||
|
(void)y.equal_range(get_key(*v.begin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void reserve(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
y.reserve(1337);
|
||||||
|
BOOST_TEST_GT(y.bucket_count(), 1337u);
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void copy_assignment(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
y = x;
|
||||||
|
BOOST_TEST_EQ(y.size(), x.size());
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void move_assignment(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
std::size_t const size = x.size();
|
||||||
|
y = boost::move(x);
|
||||||
|
BOOST_TEST_GE(y.size(), size);
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void equal(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
(void)(y == x);
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void extract(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
(void)y.extract(get_key(*v.begin()));
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void merge(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
if (y.get_allocator() == x.get_allocator()) {
|
||||||
|
y.merge(x);
|
||||||
|
}
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class X> bool pred(X const&) { return true; }
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void erase_with_pred(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
erase_if(y, pred<typename T::value_type>);
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void container_swap(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
T x(v.begin(), v.end());
|
||||||
|
if (boost::allocator_propagate_on_container_swap<
|
||||||
|
typename T::allocator_type>::type::value ||
|
||||||
|
x.get_allocator() == y.get_allocator()) {
|
||||||
|
y.swap(x);
|
||||||
|
}
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> static void buckets(T& y, test::random_values<T> const& v)
|
||||||
|
{
|
||||||
|
(void)y.begin(0);
|
||||||
|
(void)y.end(0);
|
||||||
|
(void)y.bucket_count();
|
||||||
|
(void)y.max_bucket_count();
|
||||||
|
(void)y.bucket_size(0);
|
||||||
|
(void)y.bucket(get_key(*v.begin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void double_move_construct(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
T x = boost::move(y);
|
||||||
|
x.clear();
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
BOOST_TEST_EQ(x.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void double_move_assign(T& y, test::random_values<T> const&)
|
||||||
|
{
|
||||||
|
T x;
|
||||||
|
x = boost::move(y);
|
||||||
|
x.clear();
|
||||||
|
BOOST_TEST_EQ(y.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||||
|
BOOST_TEST_EQ(x.size(),
|
||||||
|
static_cast<typename T::size_type>(std::distance(x.begin(), x.end())));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
static void post_move_tests(T* ptr, test::random_generator const& generator)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
void (*fps[])(T&, test::random_values<T> const&) = {
|
||||||
|
insert_range<T>,
|
||||||
|
insert_single<T>,
|
||||||
|
insert_single_hint<T>,
|
||||||
|
insert_or_assign<T>,
|
||||||
|
insert_or_assign_hint<T>,
|
||||||
|
try_emplace<T>,
|
||||||
|
try_emplace_hint<T>,
|
||||||
|
at<T>,
|
||||||
|
index_operator<T>,
|
||||||
|
clear<T>,
|
||||||
|
capacity<T>,
|
||||||
|
iterators<T>,
|
||||||
|
erase_range<T>,
|
||||||
|
erase_key<T>,
|
||||||
|
lookup<T>,
|
||||||
|
reserve<T>,
|
||||||
|
copy_assignment<T>,
|
||||||
|
move_assignment<T>,
|
||||||
|
equal<T>,
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
extract<T>,
|
||||||
|
buckets<T>,
|
||||||
|
#endif
|
||||||
|
merge<T>,
|
||||||
|
erase_with_pred<T>,
|
||||||
|
container_swap<T>,
|
||||||
|
double_move_construct<T>,
|
||||||
|
double_move_assign<T>
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
std::size_t const len = (sizeof(fps) / sizeof(*(fps)));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
|
test::check_instances check_;
|
||||||
|
|
||||||
|
test::random_values<T> const v(1000, generator);
|
||||||
|
test::object_count count;
|
||||||
|
T y(create(v, count));
|
||||||
|
|
||||||
|
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||||
|
(void)num_allocs;
|
||||||
|
|
||||||
|
T x(boost::move(y));
|
||||||
|
|
||||||
|
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||||
|
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST(y.begin() == y.end());
|
||||||
|
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||||
|
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fps[i](y, v);
|
||||||
|
|
||||||
|
test::check_container(x, v);
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
|
typename T::hasher hf(1);
|
||||||
|
typename T::key_equal eq(1);
|
||||||
|
typename T::allocator_type al1(1);
|
||||||
|
typename T::allocator_type al2(2);
|
||||||
|
|
||||||
|
test::check_instances check_;
|
||||||
|
|
||||||
|
test::random_values<T> v(1000, generator);
|
||||||
|
test::object_count count;
|
||||||
|
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||||
|
T x(boost::move(y), al2);
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST(y.begin() == y.end());
|
||||||
|
#else
|
||||||
|
BOOST_TEST_NOT(y.empty());
|
||||||
|
BOOST_TEST(y.begin() != y.end());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fps[i](y, v);
|
||||||
|
|
||||||
|
test::check_container(x, v);
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
|
test::check_instances check_;
|
||||||
|
|
||||||
|
test::random_values<T> v(1000, generator);
|
||||||
|
test::object_count count;
|
||||||
|
T y(create(v, count));
|
||||||
|
|
||||||
|
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||||
|
(void)num_allocs;
|
||||||
|
|
||||||
|
T x(empty(ptr));
|
||||||
|
x = boost::move(y);
|
||||||
|
|
||||||
|
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||||
|
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST(y.begin() == y.end());
|
||||||
|
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||||
|
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fps[i](y, v);
|
||||||
|
|
||||||
|
test::check_container(x, v);
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < len; ++i) {
|
||||||
|
typename T::hasher hf(1);
|
||||||
|
typename T::key_equal eq(1);
|
||||||
|
typename T::allocator_type al1(1);
|
||||||
|
typename T::allocator_type al2(2);
|
||||||
|
|
||||||
|
test::check_instances check_;
|
||||||
|
|
||||||
|
test::random_values<T> v(1000, generator);
|
||||||
|
test::object_count count;
|
||||||
|
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||||
|
|
||||||
|
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||||
|
(void)num_allocs;
|
||||||
|
|
||||||
|
T x(al2);
|
||||||
|
x = boost::move(y);
|
||||||
|
|
||||||
|
bool b = boost::allocator_propagate_on_container_move_assignment<
|
||||||
|
typename T::allocator_type>::type::value;
|
||||||
|
if (b) {
|
||||||
|
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||||
|
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST(y.begin() == y.end());
|
||||||
|
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||||
|
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||||
|
#else
|
||||||
|
BOOST_TEST_NOT(y.empty());
|
||||||
|
BOOST_TEST(y.begin() != y.end());
|
||||||
|
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST(y.empty());
|
||||||
|
BOOST_TEST(y.begin() == y.end());
|
||||||
|
#else
|
||||||
|
BOOST_TEST_NOT(y.empty());
|
||||||
|
BOOST_TEST(y.begin() != y.end());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
fps[i](y, v);
|
||||||
|
|
||||||
|
test::check_container(x, v);
|
||||||
|
test::check_equivalent_keys(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
std::allocator<std::pair<test::object const, test::object> > >*
|
||||||
|
test_map_std_alloc;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator2<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||||
|
test_set_prop_move;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::propagate_move> >* test_map_prop_move;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||||
|
test_set_no_prop_move;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::no_propagate_move> >* test_map_no_prop_move;
|
||||||
|
|
||||||
|
UNORDERED_TEST(post_move_tests,
|
||||||
|
((test_set)(test_map)(test_set_prop_move)(test_map_prop_move)(test_set_no_prop_move)(test_map_no_prop_move))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
std::allocator<std::pair<test::object const, test::object> > >*
|
||||||
|
test_map_std_alloc;
|
||||||
|
|
||||||
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator2<test::object> >* test_set;
|
||||||
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_multiset;
|
||||||
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<std::pair<test::object const, test::object> > >* test_map;
|
||||||
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::allocator2<std::pair<test::object const, test::object> > >*
|
||||||
|
test_multimap;
|
||||||
|
|
||||||
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||||
|
test_set_prop_move;
|
||||||
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||||
|
test_multiset_prop_move;
|
||||||
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::propagate_move> >* test_map_prop_move;
|
||||||
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::propagate_move> >* test_multimap_prop_move;
|
||||||
|
|
||||||
|
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||||
|
test_set_no_prop_move;
|
||||||
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||||
|
test_multiset_no_prop_move;
|
||||||
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::no_propagate_move> >* test_map_no_prop_move;
|
||||||
|
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<std::pair<test::object const, test::object>,
|
||||||
|
test::no_propagate_move> >* test_multimap_no_prop_move;
|
||||||
|
|
||||||
|
UNORDERED_TEST(post_move_tests,
|
||||||
|
((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)(limited_range)))
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
RUN_TESTS()
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include "../helpers/random_values.hpp"
|
#include "../helpers/random_values.hpp"
|
||||||
@ -151,8 +147,13 @@ namespace rehash_tests {
|
|||||||
BOOST_TEST_EQ(x.size(), 0u);
|
BOOST_TEST_EQ(x.size(), 0u);
|
||||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
float const mlf = boost::unordered::detail::foa::mlf;
|
||||||
|
x.max_load_factor(max_load_factors[i]);
|
||||||
|
#else
|
||||||
float const mlf = max_load_factors[i];
|
float const mlf = max_load_factors[i];
|
||||||
x.max_load_factor(mlf);
|
x.max_load_factor(mlf);
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||||
@ -419,6 +420,15 @@ namespace rehash_tests {
|
|||||||
X x;
|
X x;
|
||||||
x.max_load_factor(0.25);
|
x.max_load_factor(0.25);
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
x.reserve(10000);
|
||||||
|
BOOST_TEST(x.bucket_count() >= 10000);
|
||||||
|
|
||||||
|
x.reserve(0);
|
||||||
|
|
||||||
|
x.reserve(10000000);
|
||||||
|
BOOST_TEST(x.bucket_count() >= 10000000);
|
||||||
|
#else
|
||||||
x.reserve(10000);
|
x.reserve(10000);
|
||||||
BOOST_TEST(x.bucket_count() >= 40000);
|
BOOST_TEST(x.bucket_count() >= 40000);
|
||||||
|
|
||||||
@ -426,6 +436,7 @@ namespace rehash_tests {
|
|||||||
|
|
||||||
x.reserve(10000000);
|
x.reserve(10000000);
|
||||||
BOOST_TEST(x.bucket_count() >= 40000000);
|
BOOST_TEST(x.bucket_count() >= 40000000);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X> void reserve_test1(X*, test::random_generator generator)
|
template <class X> void reserve_test1(X*, test::random_generator generator)
|
||||||
@ -486,6 +497,47 @@ namespace rehash_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int>* int_set_ptr;
|
||||||
|
boost::unordered_flat_map<test::movable, test::movable, test::hash,
|
||||||
|
test::equal_to, test::allocator2<test::movable> >* test_map_ptr;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set_tracking;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::allocator1<std::pair<test::object const, test::object> > >*
|
||||||
|
test_map_tracking;
|
||||||
|
|
||||||
|
UNORDERED_TEST(rehash_empty_test1, ((int_set_ptr)(test_map_ptr)))
|
||||||
|
UNORDERED_TEST(rehash_empty_test2,
|
||||||
|
((int_set_ptr)(test_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(rehash_empty_test3,
|
||||||
|
((int_set_ptr)(test_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(
|
||||||
|
rehash_test1, ((int_set_ptr)(test_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(reserve_empty_test1, ((int_set_ptr)(test_map_ptr)))
|
||||||
|
UNORDERED_TEST(reserve_empty_test2, ((int_set_ptr)(test_map_ptr)))
|
||||||
|
UNORDERED_TEST(
|
||||||
|
reserve_test1, ((int_set_ptr)(test_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(
|
||||||
|
reserve_test2, ((int_set_ptr)(test_map_ptr))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(rehash_empty_tracking,
|
||||||
|
((test_set_tracking)(test_map_tracking))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
UNORDERED_TEST(rehash_nonempty_tracking,
|
||||||
|
((test_set_tracking)(test_map_tracking))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_set<int>* int_set_ptr;
|
boost::unordered_set<int>* int_set_ptr;
|
||||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||||
test::allocator2<test::object> >* test_multiset_ptr;
|
test::allocator2<test::object> >* test_multiset_ptr;
|
||||||
@ -505,10 +557,6 @@ namespace rehash_tests {
|
|||||||
test::allocator1<std::pair<test::object const, test::object> > >*
|
test::allocator1<std::pair<test::object const, test::object> > >*
|
||||||
test_multimap_tracking;
|
test_multimap_tracking;
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_TEST(rehash_empty_test1,
|
UNORDERED_TEST(rehash_empty_test1,
|
||||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
|
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
|
||||||
UNORDERED_TEST(rehash_empty_test2,
|
UNORDERED_TEST(rehash_empty_test2,
|
||||||
@ -536,6 +584,7 @@ namespace rehash_tests {
|
|||||||
UNORDERED_TEST(rehash_nonempty_tracking,
|
UNORDERED_TEST(rehash_nonempty_tracking,
|
||||||
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
|
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -2,12 +2,7 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
@ -113,8 +108,8 @@ template <class UnorderedContainer> void reserve_tests()
|
|||||||
s.max_load_factor(0.37f);
|
s.max_load_factor(0.37f);
|
||||||
s.reserve(count);
|
s.reserve(count);
|
||||||
|
|
||||||
std::size_t expected_bucket_count =
|
std::size_t expected_bucket_count = static_cast<std::size_t>(
|
||||||
static_cast<std::size_t>(std::ceil(static_cast<float>(count) / 0.37f));
|
std::ceil(static_cast<float>(count) / s.max_load_factor()));
|
||||||
|
|
||||||
BOOST_TEST_GE(total_allocation, expected_bucket_count * sizeof(void*));
|
BOOST_TEST_GE(total_allocation, expected_bucket_count * sizeof(void*));
|
||||||
BOOST_TEST_GE(s.bucket_count(), expected_bucket_count);
|
BOOST_TEST_GE(s.bucket_count(), expected_bucket_count);
|
||||||
@ -173,6 +168,12 @@ template <class UnorderedContainer> void rehash_tests()
|
|||||||
// note, the test is vulnerable to cases where the next calculated bucket
|
// note, the test is vulnerable to cases where the next calculated bucket
|
||||||
// count can exceed `prev_count + count`
|
// count can exceed `prev_count + count`
|
||||||
//
|
//
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
BOOST_TEST_LT(s.bucket_count(), prev_count + count);
|
||||||
|
BOOST_TEST_LE(total_allocation,
|
||||||
|
(prev_count + count) * sizeof(typename UnorderedContainer::value_type) +
|
||||||
|
((prev_count + count) / 15 + 1) * 16);
|
||||||
|
#else
|
||||||
std::size_t const estimated_bucket_group_size =
|
std::size_t const estimated_bucket_group_size =
|
||||||
3 * sizeof(void*) + sizeof(std::size_t);
|
3 * sizeof(void*) + sizeof(std::size_t);
|
||||||
std::size_t const estimated_bucket_groups =
|
std::size_t const estimated_bucket_groups =
|
||||||
@ -182,6 +183,7 @@ template <class UnorderedContainer> void rehash_tests()
|
|||||||
BOOST_TEST_LE(total_allocation,
|
BOOST_TEST_LE(total_allocation,
|
||||||
(prev_count + count) * sizeof(void*) +
|
(prev_count + count) * sizeof(void*) +
|
||||||
estimated_bucket_group_size * estimated_bucket_groups);
|
estimated_bucket_group_size * estimated_bucket_groups);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_TEST_GT(num_allocations, 0u);
|
BOOST_TEST_GT(num_allocations, 0u);
|
||||||
@ -214,6 +216,28 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
|
|||||||
BOOST_ASSERT(A<int>(b) == a);
|
BOOST_ASSERT(A<int>(b) == a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int*, boost::hash<int*>,
|
||||||
|
std::equal_to<int*>, A<int*> >
|
||||||
|
unordered_set;
|
||||||
|
|
||||||
|
typedef boost::unordered_flat_map<int*, int*, boost::hash<int*>,
|
||||||
|
std::equal_to<int*>, A<std::pair<int const*, int*> > >
|
||||||
|
unordered_map;
|
||||||
|
|
||||||
|
bucket_count_constructor<unordered_set>();
|
||||||
|
bucket_count_constructor<unordered_map>();
|
||||||
|
|
||||||
|
range_bucket_constructor<unordered_set>();
|
||||||
|
range_bucket_constructor<unordered_map>();
|
||||||
|
|
||||||
|
reserve_tests<unordered_set>();
|
||||||
|
reserve_tests<unordered_map>();
|
||||||
|
|
||||||
|
rehash_tests<unordered_set>();
|
||||||
|
rehash_tests<unordered_map>();
|
||||||
|
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
typedef boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||||
A<int> >
|
A<int> >
|
||||||
unordered_set;
|
unordered_set;
|
||||||
@ -249,6 +273,7 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
|
|||||||
rehash_tests<unordered_map>();
|
rehash_tests<unordered_map>();
|
||||||
rehash_tests<unordered_multiset>();
|
rehash_tests<unordered_multiset>();
|
||||||
rehash_tests<unordered_multimap>();
|
rehash_tests<unordered_multimap>();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -2,14 +2,8 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../objects/test.hpp"
|
#include "../objects/test.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -107,8 +101,7 @@ public:
|
|||||||
// ever using it with an int with has a trivial destructor so it eliminates
|
// ever using it with an int with has a trivial destructor so it eliminates
|
||||||
// the code and generates a warning about an unused variable
|
// the code and generates a warning about an unused variable
|
||||||
//
|
//
|
||||||
template <class U>
|
template <class U> void destroy(U* p)
|
||||||
void destroy(U* p)
|
|
||||||
{
|
{
|
||||||
(void)p;
|
(void)p;
|
||||||
p->~U();
|
p->~U();
|
||||||
@ -192,8 +185,7 @@ public:
|
|||||||
// ever using it with an int with has a trivial destructor so it eliminates
|
// ever using it with an int with has a trivial destructor so it eliminates
|
||||||
// the code and generates a warning about an unused variable
|
// the code and generates a warning about an unused variable
|
||||||
//
|
//
|
||||||
template <class U>
|
template <class U> void destroy(U* p)
|
||||||
void destroy(U* p)
|
|
||||||
{
|
{
|
||||||
(void)p;
|
(void)p;
|
||||||
p->~U();
|
p->~U();
|
||||||
@ -226,11 +218,13 @@ template <class C1, class C2> void scary_test()
|
|||||||
|
|
||||||
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
BOOST_TEST_EQ(x.bucket_count(), 0u);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typename C2::local_iterator lbegin(x.begin(0));
|
typename C2::local_iterator lbegin(x.begin(0));
|
||||||
BOOST_TEST(lbegin == x.end(0));
|
BOOST_TEST(lbegin == x.end(0));
|
||||||
|
|
||||||
typename C2::const_local_iterator clbegin(x.cbegin(0));
|
typename C2::const_local_iterator clbegin(x.cbegin(0));
|
||||||
BOOST_TEST(clbegin == x.cend(0));
|
BOOST_TEST(clbegin == x.cend(0));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <
|
template <
|
||||||
@ -316,11 +310,16 @@ void set_scary_test()
|
|||||||
}
|
}
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (scary_tests) {
|
UNORDERED_AUTO_TEST (scary_tests) {
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
map_scary_test<boost::unordered_flat_map>();
|
||||||
|
set_scary_test<boost::unordered_flat_set>();
|
||||||
|
#else
|
||||||
map_scary_test<boost::unordered_map>();
|
map_scary_test<boost::unordered_map>();
|
||||||
map_scary_test<boost::unordered_multimap>();
|
map_scary_test<boost::unordered_multimap>();
|
||||||
|
|
||||||
set_scary_test<boost::unordered_set>();
|
set_scary_test<boost::unordered_set>();
|
||||||
set_scary_test<boost::unordered_multiset>();
|
set_scary_test<boost::unordered_multiset>();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -19,12 +19,7 @@ int main() {}
|
|||||||
// https://github.com/boostorg/unordered/issues/22
|
// https://github.com/boostorg/unordered/issues/22
|
||||||
//
|
//
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
@ -32,10 +27,10 @@ int main() {}
|
|||||||
|
|
||||||
#include <boost/core/ignore_unused.hpp>
|
#include <boost/core/ignore_unused.hpp>
|
||||||
|
|
||||||
|
#include <scoped_allocator>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <scoped_allocator>
|
|
||||||
|
|
||||||
namespace test {
|
namespace test {
|
||||||
template <class T> struct allocator
|
template <class T> struct allocator
|
||||||
@ -70,9 +65,15 @@ typedef std::scoped_allocator_adaptor<test::allocator<pair_type>,
|
|||||||
test::allocator<boost::uint64_t> >
|
test::allocator<boost::uint64_t> >
|
||||||
allocator_type;
|
allocator_type;
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<const boost::uint64_t, vector_type,
|
||||||
|
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
|
||||||
|
map_type;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<const boost::uint64_t, vector_type,
|
typedef boost::unordered_map<const boost::uint64_t, vector_type,
|
||||||
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
|
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
|
||||||
map_type;
|
map_type;
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (scoped_allocator) {
|
UNORDERED_AUTO_TEST (scoped_allocator) {
|
||||||
allocator_type alloc(
|
allocator_type alloc(
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// This test checks the runtime requirements of containers.
|
// This test checks the runtime requirements of containers.
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -93,7 +89,11 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
|||||||
srand(14878);
|
srand(14878);
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_set.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_set<int> set;
|
||||||
|
#else
|
||||||
boost::unordered_set<int> set;
|
boost::unordered_set<int> set;
|
||||||
|
#endif
|
||||||
simple_test(set);
|
simple_test(set);
|
||||||
|
|
||||||
set.insert(1);
|
set.insert(1);
|
||||||
@ -101,6 +101,7 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
|||||||
set.insert(1456);
|
set.insert(1456);
|
||||||
simple_test(set);
|
simple_test(set);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
|
||||||
boost::unordered_multiset<int> multiset;
|
boost::unordered_multiset<int> multiset;
|
||||||
simple_test(multiset);
|
simple_test(multiset);
|
||||||
@ -111,15 +112,21 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
|||||||
multiset.insert(index);
|
multiset.insert(index);
|
||||||
}
|
}
|
||||||
simple_test(multiset);
|
simple_test(multiset);
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_map.\n";
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<int, int> map;
|
||||||
|
#else
|
||||||
boost::unordered_map<int, int> map;
|
boost::unordered_map<int, int> map;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i2 = 0; i2 < 1000; ++i2) {
|
for (int i2 = 0; i2 < 1000; ++i2) {
|
||||||
map.insert(std::pair<const int, int>(rand(), rand()));
|
map.insert(std::pair<const int, int>(rand(), rand()));
|
||||||
}
|
}
|
||||||
simple_test(map);
|
simple_test(map);
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
|
||||||
boost::unordered_multimap<int, int> multimap;
|
boost::unordered_multimap<int, int> multimap;
|
||||||
|
|
||||||
@ -129,6 +136,7 @@ UNORDERED_AUTO_TEST (simple_tests) {
|
|||||||
multimap.insert(std::pair<const int, int>(index, rand()));
|
multimap.insert(std::pair<const int, int>(index, rand()));
|
||||||
}
|
}
|
||||||
simple_test(multimap);
|
simple_test(multimap);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
// Copyright 2006-2009 Daniel James.
|
// Copyright 2006-2009 Daniel James.
|
||||||
|
// Copyright 2022 Christian Mazakas.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -139,6 +135,53 @@ namespace swap_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using test::default_generator;
|
||||||
|
using test::generate_collisions;
|
||||||
|
using test::limited_range;
|
||||||
|
|
||||||
|
template <typename T> bool is_propagate(T*)
|
||||||
|
{
|
||||||
|
return T::allocator_type::is_propagate_on_swap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::allocator1<test::object> >* test_set;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::allocator1<test::object> >* test_map;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||||
|
test_set_prop_swap;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to, test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||||
|
test_map_prop_swap;
|
||||||
|
|
||||||
|
boost::unordered_flat_set<test::object, test::hash, test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||||
|
test_set_no_prop_swap;
|
||||||
|
boost::unordered_flat_map<test::object, test::object, test::hash,
|
||||||
|
test::equal_to,
|
||||||
|
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||||
|
test_map_no_prop_swap;
|
||||||
|
|
||||||
|
UNORDERED_AUTO_TEST (check_traits) {
|
||||||
|
BOOST_TEST(!is_propagate(test_set));
|
||||||
|
BOOST_TEST(is_propagate(test_set_prop_swap));
|
||||||
|
BOOST_TEST(!is_propagate(test_set_no_prop_swap));
|
||||||
|
}
|
||||||
|
|
||||||
|
UNORDERED_TEST(swap_tests1,
|
||||||
|
((test_map_std_alloc)(test_set)(test_map)(test_set_prop_swap)(test_map_prop_swap)(test_set_no_prop_swap)(test_map_no_prop_swap))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
|
||||||
|
UNORDERED_TEST(swap_tests2,
|
||||||
|
((test_set)(test_map)(test_set_prop_swap)(test_map_prop_swap)(test_set_no_prop_swap)(test_map_no_prop_swap))(
|
||||||
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#else
|
||||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||||
std::allocator<test::object> >* test_map_std_alloc;
|
std::allocator<test::object> >* test_map_std_alloc;
|
||||||
|
|
||||||
@ -178,15 +221,6 @@ namespace swap_tests {
|
|||||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||||
test_multimap_no_prop_swap;
|
test_multimap_no_prop_swap;
|
||||||
|
|
||||||
template <typename T> bool is_propagate(T*)
|
|
||||||
{
|
|
||||||
return T::allocator_type::is_propagate_on_swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
using test::default_generator;
|
|
||||||
using test::generate_collisions;
|
|
||||||
using test::limited_range;
|
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (check_traits) {
|
UNORDERED_AUTO_TEST (check_traits) {
|
||||||
BOOST_TEST(!is_propagate(test_set));
|
BOOST_TEST(!is_propagate(test_set));
|
||||||
BOOST_TEST(is_propagate(test_set_prop_swap));
|
BOOST_TEST(is_propagate(test_set_prop_swap));
|
||||||
@ -207,5 +241,6 @@ namespace swap_tests {
|
|||||||
test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(
|
test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(
|
||||||
test_multimap_no_prop_swap))(
|
test_multimap_no_prop_swap))(
|
||||||
(default_generator)(generate_collisions)(limited_range)))
|
(default_generator)(generate_collisions)(limited_range)))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
@ -2,12 +2,7 @@
|
|||||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
// 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)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
// clang-format off
|
#include "../helpers/unordered.hpp"
|
||||||
#include "../helpers/prefix.hpp"
|
|
||||||
#include <boost/unordered_set.hpp>
|
|
||||||
#include <boost/unordered_map.hpp>
|
|
||||||
#include "../helpers/postfix.hpp"
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
#include "../helpers/test.hpp"
|
#include "../helpers/test.hpp"
|
||||||
|
|
||||||
@ -1053,14 +1048,25 @@ template <class UnorderedMap> struct convertible_to_const_iterator
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<int, int, transparent_hasher,
|
||||||
|
transparent_key_equal>
|
||||||
|
transparent_unordered_map;
|
||||||
|
#else
|
||||||
typedef boost::unordered_map<int, int, transparent_hasher,
|
typedef boost::unordered_map<int, int, transparent_hasher,
|
||||||
transparent_key_equal>
|
transparent_key_equal>
|
||||||
transparent_unordered_map;
|
transparent_unordered_map;
|
||||||
|
#endif
|
||||||
|
|
||||||
// test that in the presence of the member function template `erase()`, we still
|
// test that in the presence of the member function template `erase()`, we still
|
||||||
// invoke the correct iterator overloads when the type is implicitly convertible
|
// invoke the correct iterator overloads when the type is implicitly convertible
|
||||||
//
|
//
|
||||||
transparent_unordered_map::iterator map_erase_overload_compile_test()
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void
|
||||||
|
#else
|
||||||
|
transparent_unordered_map::iterator
|
||||||
|
#endif
|
||||||
|
map_erase_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_iterator<transparent_unordered_map> c;
|
convertible_to_iterator<transparent_unordered_map> c;
|
||||||
transparent_unordered_map map;
|
transparent_unordered_map map;
|
||||||
@ -1069,7 +1075,11 @@ transparent_unordered_map::iterator map_erase_overload_compile_test()
|
|||||||
return map.erase(c);
|
return map.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void
|
||||||
|
#else
|
||||||
transparent_unordered_map::const_iterator
|
transparent_unordered_map::const_iterator
|
||||||
|
#endif
|
||||||
map_erase_const_overload_compile_test()
|
map_erase_const_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_const_iterator<transparent_unordered_map> c;
|
convertible_to_const_iterator<transparent_unordered_map> c;
|
||||||
@ -1079,6 +1089,7 @@ map_erase_const_overload_compile_test()
|
|||||||
return map.erase(c);
|
return map.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef boost::unordered_multimap<int, int, transparent_hasher,
|
typedef boost::unordered_multimap<int, int, transparent_hasher,
|
||||||
transparent_key_equal>
|
transparent_key_equal>
|
||||||
transparent_unordered_multimap;
|
transparent_unordered_multimap;
|
||||||
@ -1101,6 +1112,7 @@ multimap_erase_const_overload_compile_test()
|
|||||||
pos = c;
|
pos = c;
|
||||||
return map.erase(c);
|
return map.erase(c);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class UnorderedMap> void test_map_transparent_erase()
|
template <class UnorderedMap> void test_map_transparent_erase()
|
||||||
{
|
{
|
||||||
@ -1197,14 +1209,25 @@ template <class UnorderedMap> void test_map_non_transparent_erase()
|
|||||||
BOOST_TEST_EQ(key::count_, key_count);
|
BOOST_TEST_EQ(key::count_, key_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<int, transparent_hasher,
|
||||||
|
transparent_key_equal>
|
||||||
|
transparent_unordered_set;
|
||||||
|
#else
|
||||||
typedef boost::unordered_set<int, transparent_hasher, transparent_key_equal>
|
typedef boost::unordered_set<int, transparent_hasher, transparent_key_equal>
|
||||||
transparent_unordered_set;
|
transparent_unordered_set;
|
||||||
|
|
||||||
typedef boost::unordered_multiset<int, transparent_hasher,
|
typedef boost::unordered_multiset<int, transparent_hasher,
|
||||||
transparent_key_equal>
|
transparent_key_equal>
|
||||||
transparent_unordered_multiset;
|
transparent_unordered_multiset;
|
||||||
|
#endif
|
||||||
|
|
||||||
transparent_unordered_set::iterator set_erase_overload_compile_test()
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void
|
||||||
|
#else
|
||||||
|
transparent_unordered_set::iterator
|
||||||
|
#endif
|
||||||
|
set_erase_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_iterator<transparent_unordered_set> c;
|
convertible_to_iterator<transparent_unordered_set> c;
|
||||||
transparent_unordered_set set;
|
transparent_unordered_set set;
|
||||||
@ -1213,7 +1236,11 @@ transparent_unordered_set::iterator set_erase_overload_compile_test()
|
|||||||
return set.erase(c);
|
return set.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
void
|
||||||
|
#else
|
||||||
transparent_unordered_set::const_iterator
|
transparent_unordered_set::const_iterator
|
||||||
|
#endif
|
||||||
set_erase_const_overload_compile_test()
|
set_erase_const_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_const_iterator<transparent_unordered_set> c;
|
convertible_to_const_iterator<transparent_unordered_set> c;
|
||||||
@ -1223,6 +1250,7 @@ set_erase_const_overload_compile_test()
|
|||||||
return set.erase(c);
|
return set.erase(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
transparent_unordered_multiset::iterator multiset_erase_overload_compile_test()
|
transparent_unordered_multiset::iterator multiset_erase_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_iterator<transparent_unordered_multiset> c;
|
convertible_to_iterator<transparent_unordered_multiset> c;
|
||||||
@ -1241,6 +1269,7 @@ multiset_erase_const_overload_compile_test()
|
|||||||
pos = c;
|
pos = c;
|
||||||
return set.erase(c);
|
return set.erase(c);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class UnorderedSet> void test_set_transparent_erase()
|
template <class UnorderedSet> void test_set_transparent_erase()
|
||||||
{
|
{
|
||||||
@ -1337,6 +1366,7 @@ template <class UnorderedSet> void test_set_non_transparent_erase()
|
|||||||
BOOST_TEST_EQ(key::count_, key_count);
|
BOOST_TEST_EQ(key::count_, key_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
// test that in the presence of the member function template `extract()`, we
|
// test that in the presence of the member function template `extract()`, we
|
||||||
// still invoke the correct iterator overloads when the type is implicitly
|
// still invoke the correct iterator overloads when the type is implicitly
|
||||||
// convertible
|
// convertible
|
||||||
@ -1359,9 +1389,11 @@ multimap_extract_const_overload_compile_test()
|
|||||||
pos = c;
|
pos = c;
|
||||||
return map.extract(c);
|
return map.extract(c);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class UnorderedMap> void test_map_transparent_extract()
|
template <class UnorderedMap> void test_map_transparent_extract()
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename UnorderedMap::node_type node_type;
|
typedef typename UnorderedMap::node_type node_type;
|
||||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||||
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
||||||
@ -1397,10 +1429,12 @@ template <class UnorderedMap> void test_map_transparent_extract()
|
|||||||
BOOST_TEST(nh.empty());
|
BOOST_TEST(nh.empty());
|
||||||
|
|
||||||
BOOST_TEST_EQ(key::count_, expected_key_count);
|
BOOST_TEST_EQ(key::count_, expected_key_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class UnorderedMap> void test_map_non_transparent_extract()
|
template <class UnorderedMap> void test_map_non_transparent_extract()
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename UnorderedMap::node_type node_type;
|
typedef typename UnorderedMap::node_type node_type;
|
||||||
typedef typename UnorderedMap::const_iterator const_iterator;
|
typedef typename UnorderedMap::const_iterator const_iterator;
|
||||||
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
|
||||||
@ -1441,8 +1475,10 @@ template <class UnorderedMap> void test_map_non_transparent_extract()
|
|||||||
++key_count;
|
++key_count;
|
||||||
BOOST_TEST(nh.empty());
|
BOOST_TEST(nh.empty());
|
||||||
BOOST_TEST_EQ(key::count_, key_count);
|
BOOST_TEST_EQ(key::count_, key_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
transparent_unordered_set::node_type set_extract_overload_compile_test()
|
transparent_unordered_set::node_type set_extract_overload_compile_test()
|
||||||
{
|
{
|
||||||
convertible_to_iterator<transparent_unordered_set> c;
|
convertible_to_iterator<transparent_unordered_set> c;
|
||||||
@ -1480,9 +1516,11 @@ multiset_extract_const_overload_compile_test()
|
|||||||
pos = c;
|
pos = c;
|
||||||
return set.extract(c);
|
return set.extract(c);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <class UnorderedSet> void test_set_transparent_extract()
|
template <class UnorderedSet> void test_set_transparent_extract()
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename UnorderedSet::node_type node_type;
|
typedef typename UnorderedSet::node_type node_type;
|
||||||
|
|
||||||
count_reset();
|
count_reset();
|
||||||
@ -1526,10 +1564,12 @@ template <class UnorderedSet> void test_set_transparent_extract()
|
|||||||
BOOST_TEST_EQ(set.size(), set_size);
|
BOOST_TEST_EQ(set.size(), set_size);
|
||||||
|
|
||||||
BOOST_TEST_EQ(key::count_, expected_key_count);
|
BOOST_TEST_EQ(key::count_, expected_key_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class UnorderedSet> void test_set_non_transparent_extract()
|
template <class UnorderedSet> void test_set_non_transparent_extract()
|
||||||
{
|
{
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
typedef typename UnorderedSet::node_type node_type;
|
typedef typename UnorderedSet::node_type node_type;
|
||||||
|
|
||||||
count_reset();
|
count_reset();
|
||||||
@ -1583,13 +1623,22 @@ template <class UnorderedSet> void test_set_non_transparent_extract()
|
|||||||
BOOST_TEST_EQ(set.size(), set_size);
|
BOOST_TEST_EQ(set.size(), set_size);
|
||||||
|
|
||||||
BOOST_TEST_EQ(key::count_, key_count);
|
BOOST_TEST_EQ(key::count_, key_count);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Key, class T, class Hash, class KeyEqual> struct map_type
|
||||||
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_map<Key, T, Hash, KeyEqual> type;
|
||||||
|
#else
|
||||||
|
typedef boost::unordered_map<Key, T, Hash, KeyEqual> type;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
void test_unordered_map()
|
void test_unordered_map()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
typedef boost::unordered_map<key, int, transparent_hasher,
|
typedef map_type<key, int, transparent_hasher, transparent_key_equal>::type
|
||||||
transparent_key_equal>
|
|
||||||
unordered_map;
|
unordered_map;
|
||||||
|
|
||||||
test_map_transparent_count<unordered_map>();
|
test_map_transparent_count<unordered_map>();
|
||||||
@ -1602,7 +1651,7 @@ void test_unordered_map()
|
|||||||
{
|
{
|
||||||
// non-transparent Hash, non-transparent KeyEqual
|
// non-transparent Hash, non-transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_map<key, int, hasher, key_equal> unordered_map;
|
typedef map_type<key, int, hasher, key_equal>::type unordered_map;
|
||||||
|
|
||||||
test_map_non_transparent_count<unordered_map>();
|
test_map_non_transparent_count<unordered_map>();
|
||||||
test_map_non_transparent_find<unordered_map>();
|
test_map_non_transparent_find<unordered_map>();
|
||||||
@ -1614,7 +1663,7 @@ void test_unordered_map()
|
|||||||
{
|
{
|
||||||
// transparent Hash, non-transparent KeyEqual
|
// transparent Hash, non-transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_map<key, int, transparent_hasher, key_equal>
|
typedef map_type<key, int, transparent_hasher, key_equal>::type
|
||||||
unordered_map;
|
unordered_map;
|
||||||
|
|
||||||
test_map_non_transparent_count<unordered_map>();
|
test_map_non_transparent_count<unordered_map>();
|
||||||
@ -1627,7 +1676,7 @@ void test_unordered_map()
|
|||||||
{
|
{
|
||||||
// non-transparent Hash, transparent KeyEqual
|
// non-transparent Hash, transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_map<key, int, hasher, transparent_key_equal>
|
typedef map_type<key, int, hasher, transparent_key_equal>::type
|
||||||
unordered_map;
|
unordered_map;
|
||||||
|
|
||||||
test_map_non_transparent_count<unordered_map>();
|
test_map_non_transparent_count<unordered_map>();
|
||||||
@ -1638,6 +1687,7 @@ void test_unordered_map()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
void test_unordered_multimap()
|
void test_unordered_multimap()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -1691,11 +1741,21 @@ void test_unordered_multimap()
|
|||||||
test_map_non_transparent_extract<unordered_multimap>();
|
test_map_non_transparent_extract<unordered_multimap>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class Key, class Hash, class KeyEqual> struct set_type
|
||||||
|
{
|
||||||
|
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
typedef boost::unordered_flat_set<Key, Hash, KeyEqual> type;
|
||||||
|
#else
|
||||||
|
typedef boost::unordered_set<Key, Hash, KeyEqual> type;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
void test_unordered_set()
|
void test_unordered_set()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
|
typedef set_type<key, transparent_hasher, transparent_key_equal>::type
|
||||||
unordered_set;
|
unordered_set;
|
||||||
|
|
||||||
test_set_transparent_count<unordered_set>();
|
test_set_transparent_count<unordered_set>();
|
||||||
@ -1708,7 +1768,7 @@ void test_unordered_set()
|
|||||||
{
|
{
|
||||||
// non-transparent Hash, non-transparent KeyEqual
|
// non-transparent Hash, non-transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_set<key, hasher, key_equal> unordered_set;
|
typedef set_type<key, hasher, key_equal>::type unordered_set;
|
||||||
|
|
||||||
test_set_non_transparent_count<unordered_set>();
|
test_set_non_transparent_count<unordered_set>();
|
||||||
test_set_non_transparent_find<unordered_set>();
|
test_set_non_transparent_find<unordered_set>();
|
||||||
@ -1720,8 +1780,7 @@ void test_unordered_set()
|
|||||||
{
|
{
|
||||||
// transparent Hash, non-transparent KeyEqual
|
// transparent Hash, non-transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_set<key, transparent_hasher, key_equal>
|
typedef set_type<key, transparent_hasher, key_equal>::type unordered_set;
|
||||||
unordered_set;
|
|
||||||
|
|
||||||
test_set_non_transparent_count<unordered_set>();
|
test_set_non_transparent_count<unordered_set>();
|
||||||
test_set_non_transparent_find<unordered_set>();
|
test_set_non_transparent_find<unordered_set>();
|
||||||
@ -1733,8 +1792,7 @@ void test_unordered_set()
|
|||||||
{
|
{
|
||||||
// non-transparent Hash, transparent KeyEqual
|
// non-transparent Hash, transparent KeyEqual
|
||||||
//
|
//
|
||||||
typedef boost::unordered_set<key, hasher, transparent_key_equal>
|
typedef set_type<key, hasher, transparent_key_equal>::type unordered_set;
|
||||||
unordered_set;
|
|
||||||
|
|
||||||
test_set_non_transparent_count<unordered_set>();
|
test_set_non_transparent_count<unordered_set>();
|
||||||
test_set_non_transparent_find<unordered_set>();
|
test_set_non_transparent_find<unordered_set>();
|
||||||
@ -1744,6 +1802,7 @@ void test_unordered_set()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
void test_unordered_multiset()
|
void test_unordered_multiset()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -1796,12 +1855,16 @@ void test_unordered_multiset()
|
|||||||
test_set_non_transparent_extract<unordered_set>();
|
test_set_non_transparent_extract<unordered_set>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UNORDERED_AUTO_TEST (transparent_ops) {
|
UNORDERED_AUTO_TEST (transparent_ops) {
|
||||||
test_unordered_map();
|
test_unordered_map();
|
||||||
test_unordered_multimap();
|
|
||||||
test_unordered_set();
|
test_unordered_set();
|
||||||
|
|
||||||
|
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||||
|
test_unordered_multimap();
|
||||||
test_unordered_multiset();
|
test_unordered_multiset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_TESTS()
|
RUN_TESTS()
|
||||||
|
Reference in New Issue
Block a user