Compare commits

..

1 Commits

Author SHA1 Message Date
feedc0de 016d255851 Rework as esp-idf component 2023-11-23 17:17:05 +01:00
62 changed files with 520 additions and 6781 deletions
+5 -40
View File
@@ -42,12 +42,7 @@ environment:
- FLAVOR: Visual Studio 2017
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXSTD: 14,17
B2_TOOLSET: msvc-14.1
- FLAVOR: Visual Studio 2017
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
B2_CXXSTD: latest
B2_CXXSTD: 14,17,latest
B2_TOOLSET: msvc-14.1
- FLAVOR: cygwin (32-bit)
@@ -68,7 +63,7 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
B2_CXXSTD: 03
B2_CXXSTD: 03,11
B2_TOOLSET: gcc
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
@@ -76,51 +71,21 @@ environment:
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
ADDPATH: C:\cygwin64\bin;
B2_ADDRESS_MODEL: 64
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_CXXSTD: 14,1z
B2_TOOLSET: gcc
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
- 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: 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_CXXSTD: 03,11,14,17,2a
B2_TOOLSET: gcc
B2_ADDRESS_MODEL: 32
- FLAVOR: mingw-w64, 64 bit
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
B2_CXXSTD: 03,11,14
B2_TOOLSET: gcc
B2_ADDRESS_MODEL: 64
- FLAVOR: mingw-w64, 64 bit
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
ADDPATH: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin;
B2_CXXSTD: 17,2a
B2_CXXSTD: 03,11,14,17,2a
B2_TOOLSET: gcc
B2_ADDRESS_MODEL: 64
+1 -5
View File
@@ -32,7 +32,6 @@ local linux_pipeline(name, image, environment, packages = "", sources = [], arch
commands:
[
'set -e',
'uname -a',
'wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -',
] +
(if sources != [] then [ ('apt-add-repository "' + source + '"') for source in sources ] else []) +
@@ -64,7 +63,6 @@ local macos_pipeline(name, environment, xcode_version = "12.2", osx_version = "c
environment: environment + { "DEVELOPER_DIR": "/Applications/Xcode-" + xcode_version + ".app/Contents/Developer" },
commands:
[
'uname -a',
'export LIBRARY=' + library,
'./.drone/drone.sh',
]
@@ -91,7 +89,6 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
environment: environment,
commands:
[
'echo $env:DRONE_STAGE_MACHINE',
'cmd /C .drone\\\\drone.bat ' + library,
]
}
@@ -171,9 +168,8 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
),
macos_pipeline(
"MacOS 12.4 Xcode 13.4.1 ASAN",
"MacOS 10.15 Xcode 12.2 ASAN",
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
xcode_version = "13.4.1", osx_version = "monterey",
),
windows_pipeline(
-1
View File
@@ -5,7 +5,6 @@
# https://www.boost.org/LICENSE_1_0.txt
set -ex
export PATH=~/.local/bin:/usr/local/bin:$PATH
DRONE_BUILD_DIR=$(pwd)
+27
View File
@@ -3,6 +3,8 @@
# Distributed under the Boost Software License, Version 1.0.
# https://www.boost.org/LICENSE_1_0.txt
if(NOT DEFINED IDF_TARGET)
cmake_minimum_required(VERSION 3.5...3.20)
project(boost_unordered VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
@@ -32,3 +34,28 @@ if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
else()
FILE(GLOB_RECURSE headers include/*.h include/*.hpp)
idf_component_register(
SRCS
${headers}
INCLUDE_DIRS
include
REQUIRES
boost_assert
boost_config
boost_container_hash
boost_core
boost_move
boost_mp11
boost_predef
boost_preprocessor
boost_throw_exception
boost_tuple
boost_type_traits
)
endif()
+1 -7
View File
@@ -1566,9 +1566,7 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
void rehash(size_type n);
```
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
@@ -1582,10 +1580,6 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
void reserve(size_type n);
```
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
[horizontal]
+1 -7
View File
@@ -1345,9 +1345,7 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
void rehash(size_type n);
```
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
@@ -1361,10 +1359,6 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
void reserve(size_type n);
```
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
[horizontal]
+1 -8
View File
@@ -1306,9 +1306,7 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
void rehash(size_type n);
```
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
@@ -1322,16 +1320,11 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
void reserve(size_type n);
```
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
[horizontal]
Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.
---
=== Equality Comparisons
+1 -8
View File
@@ -1329,9 +1329,7 @@ Effects:;; Changes the container's maximum load factor, using `z` as a hint.
void rehash(size_type n);
```
Changes the number of buckets so that there are at least `n` buckets, and so that the load factor is less than or equal to the maximum load factor. When applicable, this will either grow or shrink the `bucket_count()` associated with the container.
When `size() == 0`, `rehash(0)` will deallocate the underlying buckets array.
Changes the number of buckets so that there at least `n` buckets, and so that the load factor is less than the maximum load factor.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
@@ -1345,16 +1343,11 @@ Throws:;; The function has no effect if an exception is thrown, unless it is thr
void reserve(size_type n);
```
Equivalent to `a.rehash(ceil(n / a.max_load_factor()))`, or `a.rehash(1)` if `n > 0` and `a.max_load_factor() == std::numeric_limits<float>::infinity()`.
Similar to `rehash`, this function can be used to grow or shrink the number of buckets in the container.
Invalidates iterators, and changes the order of elements. Pointers and references to elements are not invalidated.
[horizontal]
Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function.
=== Equality Comparisons
==== operator==
+7 -37
View File
@@ -494,33 +494,11 @@ namespace boost {
group_pointer groups;
public:
static std::size_t bucket_count_for(std::size_t num_buckets)
{
if (num_buckets == 0) {
return 0;
}
return size_policy::size(size_policy::size_index(num_buckets));
}
grouped_bucket_array()
: empty_value<node_allocator_type>(
empty_init_t(), node_allocator_type()),
size_index_(0), size_(0), buckets(), groups()
{
}
grouped_bucket_array(size_type n, const Allocator& al)
: empty_value<node_allocator_type>(empty_init_t(), al),
size_index_(0),
size_(0), buckets(), groups()
size_index_(size_policy::size_index(n)),
size_(size_policy::size(size_index_)), buckets(), groups()
{
if (n == 0) {
return;
}
size_index_ = size_policy::size_index(n);
size_ = size_policy::size(size_index_);
bucket_allocator_type bucket_alloc = this->get_bucket_allocator();
group_allocator_type group_alloc = this->get_group_allocator();
@@ -668,7 +646,7 @@ namespace boost {
size_type bucket_count() const { return size_; }
iterator begin() const { return size_ == 0 ? end() : ++at(size_); }
iterator begin() const { return ++at(size_); }
iterator end() const
{
@@ -682,10 +660,6 @@ namespace boost {
local_iterator begin(size_type n) const
{
if (size_ == 0) {
return this->end(n);
}
return local_iterator(
(buckets + static_cast<difference_type>(n))->next);
}
@@ -696,16 +670,12 @@ namespace boost {
iterator at(size_type n) const
{
if (size_ > 0) {
std::size_t const N = group::N;
std::size_t const N = group::N;
iterator pbg(buckets + static_cast<difference_type>(n),
groups + static_cast<difference_type>(n / N));
iterator pbg(buckets + static_cast<difference_type>(n),
groups + static_cast<difference_type>(n / N));
return pbg;
} else {
return this->end();
}
return pbg;
}
span<Bucket> raw()
File diff suppressed because it is too large Load Diff
@@ -47,7 +47,6 @@
#include <boost/type_traits/make_void.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/unordered/detail/fca.hpp>
#include <boost/unordered/detail/type_traits.hpp>
#include <boost/unordered/detail/fwd.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/utility/enable_if.hpp>
@@ -201,7 +200,7 @@ namespace boost {
template <typename Types> struct table;
static const float minimum_max_load_factor = 1e-3f;
static const std::size_t default_bucket_count = 0;
static const std::size_t default_bucket_count = 11;
struct move_tag
{
@@ -619,6 +618,39 @@ namespace boost {
#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
@@ -2022,14 +2054,12 @@ namespace boost {
std::size_t bucket_size(std::size_t index) const
{
bucket_iterator itb = buckets_.at(index);
node_pointer n = itb->next;
std::size_t count = 0;
if (size_ > 0) {
bucket_iterator itb = buckets_.at(index);
node_pointer n = itb->next;
while (n) {
++count;
n = n->next;
}
while (n) {
++count;
n = n->next;
}
return count;
}
@@ -2039,18 +2069,13 @@ namespace boost {
void recalculate_max_load()
{
using namespace std;
// From 6.3.1/13:
// Only resize when size >= mlf_ * count
std::size_t const bc = buckets_.bucket_count();
// it's important we do the `bc == 0` check here because the `mlf_`
// can be specified to be infinity. The operation `n * INF` is `INF`
// for all `n > 0` but NaN for `n == 0`.
//
max_load_ =
bc == 0 ? 0
: boost::unordered::detail::double_to_size(
static_cast<double>(mlf_) * static_cast<double>(bc));
max_load_ = boost::unordered::detail::double_to_size(
floor(static_cast<double>(mlf_) *
static_cast<double>(buckets_.bucket_count())));
}
void max_load_factor(float z)
@@ -2063,12 +2088,6 @@ namespace boost {
////////////////////////////////////////////////////////////////////////
// Constructors
table()
: functions(hasher(), key_equal()), size_(0), mlf_(1.0f),
max_load_(0)
{
}
table(std::size_t num_buckets, hasher const& hf, key_equal const& eq,
node_allocator_type const& a)
: functions(hf, eq), size_(0), mlf_(1.0f), max_load_(0),
@@ -2340,6 +2359,7 @@ namespace boost {
template <typename UniqueType>
void move_assign(table& x, UniqueType is_unique, false_type)
{
reserve(x.size_);
if (node_alloc() == x.node_alloc()) {
move_assign_equal_alloc(x);
} else {
@@ -2368,9 +2388,7 @@ namespace boost {
{
mlf_ = x.mlf_;
recalculate_max_load();
if (x.size_ > 0) {
this->reserve_for_insert(x.size_);
}
this->reserve_for_insert(x.size_);
this->clear_impl();
}
BOOST_CATCH(...)
@@ -2402,14 +2420,11 @@ namespace boost {
node_pointer find_node_impl(
Key const& x, bucket_iterator itb) const
{
node_pointer p = node_pointer();
if (itb != buckets_.end()) {
key_equal const& pred = this->key_eq();
p = itb->next;
for (; p; p = p->next) {
if (pred(x, extractor::extract(p->value()))) {
break;
}
key_equal const& pred = this->key_eq();
node_pointer p = itb->next;
for (; p; p = p->next) {
if (pred(x, extractor::extract(p->value()))) {
break;
}
}
return p;
@@ -2438,13 +2453,11 @@ namespace boost {
inline iterator transparent_find(
Key const& k, Hash const& h, Pred const& pred) const
{
if (size_ > 0) {
std::size_t const key_hash = h(k);
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
for (node_pointer p = itb->next; p; p = p->next) {
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
return iterator(p, itb);
}
std::size_t const key_hash = h(k);
bucket_iterator itb = buckets_.at(buckets_.position(key_hash));
for (node_pointer p = itb->next; p; p = p->next) {
if (BOOST_LIKELY(pred(k, extractor::extract(p->value())))) {
return iterator(p, itb);
}
}
@@ -2454,13 +2467,11 @@ namespace boost {
template <class Key>
node_pointer* find_prev(Key const& key, bucket_iterator itb)
{
if (size_ > 0) {
key_equal pred = this->key_eq();
for (node_pointer* pp = boost::addressof(itb->next); *pp;
pp = boost::addressof((*pp)->next)) {
if (pred(key, extractor::extract((*pp)->value()))) {
return pp;
}
key_equal pred = this->key_eq();
for (node_pointer* pp = boost::addressof(itb->next); *pp;
pp = boost::addressof((*pp)->next)) {
if (pred(key, extractor::extract((*pp)->value()))) {
return pp;
}
}
typedef node_pointer* node_pointer_pointer;
@@ -2492,17 +2503,6 @@ namespace boost {
new_buckets.insert_node(itnewb, p);
}
static std::size_t min_buckets(std::size_t num_elements, float mlf)
{
std::size_t num_buckets = static_cast<std::size_t>(
std::ceil(static_cast<float>(num_elements) / mlf));
if (num_buckets == 0 && num_elements > 0) { // mlf == inf
num_buckets = 1;
}
return num_buckets;
}
void rehash(std::size_t);
void reserve(std::size_t);
void reserve_for_insert(std::size_t);
@@ -3411,18 +3411,22 @@ namespace boost {
template <typename Types>
inline void table<Types>::rehash(std::size_t num_buckets)
{
num_buckets = (std::max)(
min_buckets(size_, mlf_), buckets_.bucket_count_for(num_buckets));
std::size_t bc = (std::max)(num_buckets,
static_cast<std::size_t>(1.0f + static_cast<float>(size_) / mlf_));
if (num_buckets != this->bucket_count()) {
this->rehash_impl(num_buckets);
if (bc <= buckets_.bucket_count()) {
return;
}
this->rehash_impl(bc);
}
template <class Types>
inline void table<Types>::reserve(std::size_t num_elements)
{
std::size_t num_buckets = min_buckets(num_elements, mlf_);
std::size_t const num_buckets = static_cast<std::size_t>(
std::ceil(static_cast<float>(num_elements) / mlf_));
this->rehash(num_buckets);
}
@@ -1,59 +0,0 @@
// 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
View File
@@ -1,75 +0,0 @@
/* 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
View File
@@ -1,44 +0,0 @@
/* 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
@@ -1,619 +0,0 @@
// 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
@@ -1,49 +0,0 @@
// 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
@@ -1,494 +0,0 @@
// 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
@@ -1,49 +0,0 @@
// 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
+4 -8
View File
@@ -1664,6 +1664,8 @@ namespace boost {
template <class K, class T, class H, class P, class A>
unordered_map<K, T, H, P, A>::unordered_map()
: table_(boost::unordered::detail::default_bucket_count, hasher(),
key_equal(), allocator_type())
{
}
@@ -2067,10 +2069,6 @@ namespace boost {
template <class K, class T, class H, class P, class A>
float unordered_map<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
@@ -2145,6 +2143,8 @@ namespace boost {
template <class K, class T, class H, class P, class A>
unordered_multimap<K, T, H, P, A>::unordered_multimap()
: table_(boost::unordered::detail::default_bucket_count, hasher(),
key_equal(), allocator_type())
{
}
@@ -2506,10 +2506,6 @@ namespace boost {
template <class K, class T, class H, class P, class A>
float unordered_multimap<K, T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
+4 -8
View File
@@ -1266,6 +1266,8 @@ namespace boost {
////////////////////////////////////////////////////////////////////////////
template <class T, class H, class P, class A>
unordered_set<T, H, P, A>::unordered_set()
: table_(boost::unordered::detail::default_bucket_count, hasher(),
key_equal(), allocator_type())
{
}
@@ -1584,10 +1586,6 @@ namespace boost {
template <class T, class H, class P, class A>
float unordered_set<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
@@ -1662,6 +1660,8 @@ namespace boost {
template <class T, class H, class P, class A>
unordered_multiset<T, H, P, A>::unordered_multiset()
: table_(boost::unordered::detail::default_bucket_count, hasher(),
key_equal(), allocator_type())
{
}
@@ -1986,10 +1986,6 @@ namespace boost {
template <class T, class H, class P, class A>
float unordered_multiset<T, H, P, A>::load_factor() const BOOST_NOEXCEPT
{
if (table_.size_ == 0) {
return 0.0f;
}
BOOST_ASSERT(table_.bucket_count() != 0);
return static_cast<float>(table_.size_) /
static_cast<float>(table_.bucket_count());
-53
View File
@@ -47,7 +47,6 @@ run unordered/equivalent_keys_tests.cpp ;
run unordered/constructor_tests.cpp ;
run unordered/copy_tests.cpp ;
run unordered/move_tests.cpp ;
run unordered/post_move_tests.cpp ;
run unordered/assign_tests.cpp ;
run unordered/insert_tests.cpp ;
run unordered/insert_stable_tests.cpp ;
@@ -96,55 +95,3 @@ run exception/swap_exception_tests.cpp : : : <define>BOOST_UNORDERED_SWAP_METHOD
run exception/merge_exception_tests.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 ;
+6 -24
View File
@@ -1,33 +1,17 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// clang-format off
#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"
#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,
test::exception::equal_to,
test::exception::allocator<test::exception::object> >
@@ -58,5 +42,3 @@ typedef boost::unordered_multiset<
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
#define CONTAINER_PAIR_SEQ \
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)
#endif
+6 -75
View File
@@ -1,6 +1,5 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "./containers.hpp"
@@ -96,7 +95,7 @@ void insert_rehash_exception_test(
T*, Inserter insert, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
T x(1);
T x;
rehash_prep(x);
test::random_values<T> v2(5, gen);
@@ -222,41 +221,16 @@ struct emplace_lvalue_pos_type
} emplace_lvalue_pos;
// 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_multiset* test_multiset_;
test_map* test_map_;
test_multimap* test_multimap_;
using test::default_generator;
using test::limited_range;
using test::generate_collisions;
// clang-format off
UNORDERED_TEST(insert_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
@@ -278,7 +252,6 @@ UNORDERED_TEST(insert_rehash_exception_test,
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
#endif
// Repeat insert tests with pairs
@@ -286,13 +259,8 @@ struct pair_emplace_type : inserter_base
{
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,
boost::make_tuple(it->first), boost::make_tuple(it->second));
#endif
}
} pair_emplace;
@@ -300,34 +268,12 @@ struct pair_emplace2_type : inserter_base
{
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,
boost::make_tuple(it->first),
boost::make_tuple(it->second.tag1_, it->second.tag2_));
#endif
}
} 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_multiset* test_pair_multiset_;
@@ -343,7 +289,6 @@ UNORDERED_TEST(insert_rehash_exception_test,
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
#endif
// Test inserting using operator[]
@@ -448,7 +393,7 @@ template <typename T>
void insert_range_rehash_exception_test(T*, test::random_generator gen)
{
for (int i = 0; i < 5; ++i) {
T x(1);
T x;
rehash_prep(x);
test::random_values<T> v2(5, gen);
@@ -456,19 +401,6 @@ 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
UNORDERED_TEST(insert_range_exception_test,
((test_set_)(test_multiset_)(test_map_)(test_multimap_))
@@ -480,6 +412,5 @@ UNORDERED_TEST(insert_range_rehash_exception_test,
((default_generator)(limited_range)(generate_collisions))
)
// clang-format on
#endif
RUN_TESTS()
+4 -49
View File
@@ -1,6 +1,5 @@
// Copyright 2017-2018 Daniel James.
// 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)
@@ -53,53 +52,6 @@ void merge_exception_test(T1 const*, T2 const*, std::size_t count12, int tag12,
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,
test::exception::equal_to,
test::exception::allocator<test::exception::object> >* test_set_;
@@ -113,6 +65,10 @@ boost::unordered_multimap<test::exception::object, test::exception::object,
test::exception::hash, test::exception::equal_to,
test::exception::allocator2<test::exception::object> >* test_multimap_;
using test::default_generator;
using test::generate_collisions;
using test::limited_range;
// clang-format off
UNORDERED_MULTI_TEST(set_merge, merge_exception_test,
((test_set_)(test_multiset_))
@@ -148,6 +104,5 @@ UNORDERED_MULTI_TEST(map_merge_collisions, merge_exception_test,
((generate_collisions))
)
// clang-format on
#endif
RUN_TESTS_QUIET()
-5
View File
@@ -1,15 +1,10 @@
// Copyright 2006-2009 Daniel James.
// 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)
#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/random_values.hpp"
#include "../helpers/tracker.hpp"
-15
View File
@@ -1,6 +1,5 @@
// Copyright 2006-2009 Daniel James.
// 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)
@@ -54,22 +53,11 @@ namespace test {
if (test::has_unique_keys<X>::value && count != 1)
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) {
BOOST_ERROR("Incorrect output of count.");
std::cerr << x1.count(key) << "," << count << "\n";
}
#endif
#ifndef BOOST_UNORDERED_FOA_TESTS
// Check that the keys are in the correct bucket and are
// adjacent in the bucket.
typename X::size_type bucket = x1.bucket(key);
@@ -98,7 +86,6 @@ namespace test {
}
}
}
#endif
};
// Check that size matches up.
@@ -117,7 +104,6 @@ namespace test {
if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
#ifndef BOOST_UNORDERED_FOA_TESTS
// Check that size in the buckets matches up.
typename X::size_type bucket_size = 0;
@@ -134,7 +120,6 @@ namespace test {
BOOST_ERROR("x1.size() doesn't match bucket size.");
std::cout << x1.size() << "/" << bucket_size << std::endl;
}
#endif
}
}
-22
View File
@@ -1,22 +0,0 @@
// 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
+1 -2
View File
@@ -11,7 +11,6 @@
#if !defined(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/pointer_traits.hpp>
#include <boost/move/move.hpp>
@@ -321,7 +320,7 @@ namespace test {
bool operator!() const { return !ptr_; }
static ptr pointer_to(T& p) {
return ptr(boost::addressof(p));
return ptr(&p);
}
// I'm not using the safe bool idiom because the containers should be
+15 -61
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -41,7 +45,6 @@ namespace assign_tests {
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
}
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "assign_tests1.2\n";
@@ -91,7 +94,6 @@ namespace assign_tests {
BOOST_TEST(test::equivalent(x1.key_eq(), eq1));
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
test::check_container(x1, x2);
}
@@ -197,54 +199,6 @@ 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,
std::allocator<test::object> >* test_map_std_alloc;
@@ -285,6 +239,15 @@ namespace assign_tests {
test::cxx11_allocator<test::object, test::no_propagate_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) {
BOOST_TEST(!is_propagate(test_set));
BOOST_TEST(is_propagate(test_set_prop_assign));
@@ -306,18 +269,13 @@ namespace assign_tests {
test_set_no_prop_assign)(test_multiset_no_prop_assign)(
test_map_no_prop_assign)(test_multimap_no_prop_assign))(
(default_generator)(generate_collisions)(limited_range)))
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (assign_default_initializer_list) {
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
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;
#endif
x1[25] = 3;
x1[16] = 10;
BOOST_TEST(!x1.empty());
@@ -331,11 +289,7 @@ namespace assign_tests {
UNORDERED_AUTO_TEST (assign_initializer_list) {
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;
#endif
x.insert(10);
x.insert(20);
x = {1, 2, -10};
+5 -7
View File
@@ -1,10 +1,13 @@
// Copyright 2007-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// clang-format off
#include "../helpers/prefix.hpp"
#include <boost/unordered_map.hpp>
#include "../helpers/postfix.hpp"
// clang-format on
#include "../helpers/test.hpp"
#include <string>
@@ -14,13 +17,8 @@ namespace at_tests {
UNORDERED_AUTO_TEST (at_tests) {
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> const& x_const(x);
#endif
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Check empty container" << std::endl;
+5 -94
View File
@@ -1,41 +1,23 @@
// Copyright 2006-2009 Daniel James.
// 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)
// This test creates the containers with members that meet their minimum
// requirements. Makes sure everything compiles and is defined correctly.
#include "../helpers/unordered.hpp"
// clang-format off
#include "../helpers/prefix.hpp"
#include <boost/unordered_map.hpp>
#include "../helpers/postfix.hpp"
// clang-format on
#include "../helpers/test.hpp"
#include "../objects/minimal.hpp"
#include "./compile_tests.hpp"
// 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) \
template class boost::unordered::detail::instantiate_##type
@@ -53,7 +35,6 @@ INSTANTIATE(multimap)<test::minimal::assignable, test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<int> >;
#endif
UNORDERED_AUTO_TEST (test0) {
test::minimal::constructor_param x;
@@ -64,19 +45,6 @@ UNORDERED_AUTO_TEST (test0) {
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, boost::hash<int>, std::equal_to<int>,
@@ -88,13 +56,11 @@ UNORDERED_AUTO_TEST (test0) {
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<value_type> >
map;
#endif
container_test(int_map, std::pair<int const, int>(0, 0));
container_test(int_map2, std::pair<int const, int>(0, 0));
container_test(map, value);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> int_multimap;
@@ -112,7 +78,6 @@ UNORDERED_AUTO_TEST (test0) {
container_test(int_multimap, std::pair<int const, int>(0, 0));
container_test(int_multimap2, std::pair<int const, int>(0, 0));
container_test(multimap, value);
#endif
}
UNORDERED_AUTO_TEST (equality_tests) {
@@ -120,22 +85,6 @@ UNORDERED_AUTO_TEST (equality_tests) {
test::minimal::copy_constructible_equality_comparable>
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, boost::hash<int>, std::equal_to<int>,
@@ -149,13 +98,11 @@ UNORDERED_AUTO_TEST (equality_tests) {
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
map;
#endif
equality_test(int_map);
equality_test(int_map2);
equality_test(map);
#ifndef BOOST_UNORDERED_FOA_TESTS
boost::unordered_multimap<int, int> int_multimap;
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
@@ -174,7 +121,6 @@ UNORDERED_AUTO_TEST (equality_tests) {
equality_test(int_multimap);
equality_test(int_multimap2);
equality_test(multimap);
#endif
}
UNORDERED_AUTO_TEST (test1) {
@@ -185,19 +131,11 @@ UNORDERED_AUTO_TEST (test1) {
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, boost::hash<int>, std::equal_to<int>,
test::minimal::cxx11_allocator<std::pair<int const, int> > >
map2;
#endif
unordered_unique_test(map, map_value);
unordered_map_test(map, value, value);
@@ -209,7 +147,6 @@ UNORDERED_AUTO_TEST (test1) {
unordered_copyable_test(map2, value, map_value, hash, equal_to);
unordered_map_functions(map2, value, value);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> multimap;
@@ -225,7 +162,6 @@ UNORDERED_AUTO_TEST (test1) {
unordered_equivalent_test(multimap2, map_value);
unordered_map_test(multimap2, value, value);
unordered_copyable_test(multimap2, value, map_value, hash, equal_to);
#endif
}
UNORDERED_AUTO_TEST (test2) {
@@ -242,46 +178,28 @@ UNORDERED_AUTO_TEST (test2) {
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,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> >
map;
#endif
unordered_unique_test(map, map_value);
unordered_map_test(map, assignable, assignable);
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
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,
test::minimal::default_assignable,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> >
map2;
#endif
test::minimal::default_assignable default_assignable;
unordered_map_functions(map2, assignable, default_assignable);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
boost::unordered_multimap<test::minimal::assignable,
@@ -294,7 +212,6 @@ UNORDERED_AUTO_TEST (test2) {
unordered_map_test(multimap, assignable, assignable);
unordered_copyable_test(multimap, assignable, map_value, hash, equal_to);
unordered_map_member_test(multimap, map_value);
#endif
}
// Test for ambiguity when using key convertible from iterator
@@ -315,11 +232,6 @@ std::size_t hash_value(lwg2059_key x)
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
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;
x.emplace(lwg2059_key(10), 5);
@@ -331,7 +243,6 @@ UNORDERED_AUTO_TEST (lwg2059) {
x.emplace(lwg2059_key(10), 5);
x.erase(x.begin());
}
#endif
}
RUN_TESTS()
+9 -127
View File
@@ -1,13 +1,16 @@
// Copyright 2006-2009 Daniel James.
// 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)
// This test creates the containers with members that meet their minimum
// requirements. Makes sure everything compiles and is defined correctly.
#include "../helpers/unordered.hpp"
// clang-format off
#include "../helpers/prefix.hpp"
#include <boost/unordered_set.hpp>
#include "../helpers/postfix.hpp"
// clang-format on
#include "../helpers/test.hpp"
#include "../objects/minimal.hpp"
@@ -15,28 +18,6 @@
// 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) \
template class boost::unordered::detail::instantiate_##type
@@ -54,21 +35,6 @@ INSTANTIATE(multiset)<test::minimal::assignable,
test::minimal::equal_to<test::minimal::assignable>,
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) {
test::minimal::constructor_param x;
@@ -76,19 +42,6 @@ UNORDERED_AUTO_TEST (test0) {
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, boost::hash<int>, std::equal_to<int>,
@@ -100,13 +53,11 @@ UNORDERED_AUTO_TEST (test0) {
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >
set;
#endif
container_test(int_set, 0);
container_test(int_set2, 0);
container_test(set, assignable);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<int> int_multiset;
@@ -124,27 +75,11 @@ UNORDERED_AUTO_TEST (test0) {
container_test(int_multiset, 0);
container_test(int_multiset2, 0);
container_test(multiset, assignable);
#endif
}
UNORDERED_AUTO_TEST (equality_tests) {
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, boost::hash<int>, std::equal_to<int>,
@@ -157,13 +92,11 @@ UNORDERED_AUTO_TEST (equality_tests) {
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
set;
#endif
equality_test(int_set);
equality_test(int_set2);
equality_test(set);
#ifndef BOOST_UNORDERED_FOA_TESTS
boost::unordered_multiset<int> int_multiset;
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
@@ -181,7 +114,6 @@ UNORDERED_AUTO_TEST (equality_tests) {
equality_test(int_multiset);
equality_test(int_multiset2);
equality_test(multiset);
#endif
}
UNORDERED_AUTO_TEST (test1) {
@@ -190,19 +122,12 @@ UNORDERED_AUTO_TEST (test1) {
int value = 0;
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, boost::hash<int>, std::equal_to<int>,
test::minimal::cxx11_allocator<int> >
set2;
#endif
unordered_unique_test(set, value);
unordered_set_test(set, value);
@@ -212,7 +137,6 @@ UNORDERED_AUTO_TEST (test1) {
unordered_set_test(set2, value);
unordered_copyable_test(set2, value, value, hash, equal_to);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset." << std::endl;
boost::unordered_multiset<int> multiset;
@@ -228,7 +152,6 @@ UNORDERED_AUTO_TEST (test1) {
unordered_equivalent_test(multiset2, value);
unordered_set_test(multiset2, value);
unordered_copyable_test(multiset2, value, value, hash, equal_to);
#endif
}
UNORDERED_AUTO_TEST (test2) {
@@ -240,26 +163,18 @@ UNORDERED_AUTO_TEST (test2) {
test::minimal::equal_to<test::minimal::assignable> equal_to(x);
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,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >
set;
#endif
unordered_unique_test(set, assignable);
unordered_set_test(set, assignable);
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
unordered_set_member_test(set, assignable);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<test::minimal::assignable,
@@ -272,7 +187,6 @@ UNORDERED_AUTO_TEST (test2) {
unordered_set_test(multiset, assignable);
unordered_copyable_test(multiset, assignable, assignable, hash, equal_to);
unordered_set_member_test(multiset, assignable);
#endif
}
UNORDERED_AUTO_TEST (movable1_tests) {
@@ -283,25 +197,17 @@ UNORDERED_AUTO_TEST (movable1_tests) {
test::minimal::equal_to<test::minimal::movable1> equal_to(x);
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,
test::minimal::hash<test::minimal::movable1>,
test::minimal::equal_to<test::minimal::movable1>,
test::minimal::allocator<test::minimal::movable1> >
set;
#endif
// unordered_unique_test(set, movable1);
unordered_set_test(set, movable1);
unordered_movable_test(set, movable1, movable1, hash, equal_to);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<test::minimal::movable1,
@@ -313,7 +219,6 @@ UNORDERED_AUTO_TEST (movable1_tests) {
// unordered_equivalent_test(multiset, movable1);
unordered_set_test(multiset, movable1);
unordered_movable_test(multiset, movable1, movable1, hash, equal_to);
#endif
}
UNORDERED_AUTO_TEST (movable2_tests) {
@@ -324,25 +229,17 @@ UNORDERED_AUTO_TEST (movable2_tests) {
test::minimal::equal_to<test::minimal::movable2> equal_to(x);
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,
test::minimal::hash<test::minimal::movable2>,
test::minimal::equal_to<test::minimal::movable2>,
test::minimal::allocator<test::minimal::movable2> >
set;
#endif
// unordered_unique_test(set, movable2);
unordered_set_test(set, movable2);
unordered_movable_test(set, movable2, movable2, hash, equal_to);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<test::minimal::movable2,
@@ -354,7 +251,6 @@ UNORDERED_AUTO_TEST (movable2_tests) {
// unordered_equivalent_test(multiset, movable2);
unordered_set_test(multiset, movable2);
unordered_movable_test(multiset, movable2, movable2, hash, equal_to);
#endif
}
UNORDERED_AUTO_TEST (destructible_tests) {
@@ -365,21 +261,14 @@ UNORDERED_AUTO_TEST (destructible_tests) {
test::minimal::equal_to<test::minimal::destructible> equal_to(x);
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,
test::minimal::hash<test::minimal::destructible>,
test::minimal::equal_to<test::minimal::destructible> >
set;
#endif
unordered_destructible_test(set);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<test::minimal::destructible,
@@ -388,7 +277,6 @@ UNORDERED_AUTO_TEST (destructible_tests) {
multiset;
unordered_destructible_test(multiset);
#endif
}
// Test for ambiguity when using key convertible from iterator
@@ -409,11 +297,6 @@ std::size_t hash_value(lwg2059_key x)
bool operator==(lwg2059_key x, lwg2059_key y) { return x.value == y.value; }
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;
x.emplace(lwg2059_key(10));
@@ -425,7 +308,6 @@ UNORDERED_AUTO_TEST (lwg2059) {
x.emplace(lwg2059_key(10));
x.erase(x.begin());
}
#endif
}
RUN_TESTS()
-61
View File
@@ -1,6 +1,5 @@
// Copyright 2005-2009 Daniel James.
// 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)
@@ -71,19 +70,9 @@ template <class X, class T> void container_test(X& r, T const&)
typedef typename X::reference reference;
typedef typename X::const_reference const_reference;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::node_type node_type;
#endif
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
@@ -108,10 +97,8 @@ template <class X, class T> void container_test(X& r, T const&)
// node_type
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_STATIC_ASSERT((
boost::is_same<allocator_type, typename node_type::allocator_type>::value));
#endif
// difference_type
@@ -180,7 +167,6 @@ template <class X, class T> void container_test(X& r, T const&)
sink(X(rvalue(a_const), m));
X c3(rvalue(a_const), m);
#ifndef BOOST_UNORDERED_FOA_TESTS
// node_type
implicit_construct<node_type const>();
@@ -207,7 +193,6 @@ template <class X, class T> void container_test(X& r, T const&)
test::check_return_type<bool>::equals(n_const.empty());
TEST_NOEXCEPT_EXPR(!n_const);
TEST_NOEXCEPT_EXPR(n_const.empty());
#endif
// Avoid unused variable warnings:
@@ -277,30 +262,24 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
typedef typename X::iterator iterator;
typedef typename X::const_iterator const_iterator;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::local_iterator 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<const_iterator>::pointer
const_iterator_pointer;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename std::iterator_traits<local_iterator>::pointer
local_iterator_pointer;
typedef typename std::iterator_traits<const_local_iterator>::pointer
const_local_iterator_pointer;
#endif
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_iterator_pointer>::value));
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
#endif
// pointer_traits<iterator>
@@ -320,8 +299,6 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
typename boost::pointer_traits<const_iterator>::difference_type>::value));
(void) r;
#ifndef BOOST_UNORDERED_FOA_TESTS
// pointer_traits<local_iterator>
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
@@ -353,7 +330,6 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
r.emplace(boost::move(k_lvalue));
node_type n1 = r.extract(r.begin());
test::check_return_type<value_type>::equals_ref(n1.value());
#endif
}
template <class X, class Key, class T>
@@ -369,29 +345,23 @@ void unordered_map_test(X& r, Key const& k, T const& v)
typedef typename X::iterator iterator;
typedef typename X::const_iterator const_iterator;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::local_iterator 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<const_iterator>::pointer
const_iterator_pointer;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename std::iterator_traits<local_iterator>::pointer
local_iterator_pointer;
typedef typename std::iterator_traits<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 const*, const_iterator_pointer>::value));
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_STATIC_ASSERT(
(boost::is_same<value_type*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, const_local_iterator_pointer>::value));
#endif
// pointer_traits<iterator>
@@ -411,7 +381,6 @@ void unordered_map_test(X& r, Key const& k, T const& v)
BOOST_STATIC_ASSERT((boost::is_same<std::ptrdiff_t,
typename boost::pointer_traits<const_iterator>::difference_type>::value));
#ifndef BOOST_UNORDERED_FOA_TESTS
// pointer_traits<local_iterator>
BOOST_STATIC_ASSERT((boost::is_same<local_iterator,
@@ -440,7 +409,6 @@ void unordered_map_test(X& r, Key const& k, T const& v)
BOOST_STATIC_ASSERT((boost::is_same<T, node_mapped_type>::value));
// Superfluous,but just to make sure.
BOOST_STATIC_ASSERT((!boost::is_const<node_key_type>::value));
#endif
// Calling functions
@@ -459,12 +427,8 @@ void unordered_map_test(X& r, Key const& k, T const& v)
r.emplace(k_lvalue, v_lvalue);
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),
boost::make_tuple(v));
#endif
// Emplace with hint
@@ -472,15 +436,9 @@ 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(), 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,
boost::make_tuple(k), boost::make_tuple(v));
#endif
#ifndef BOOST_UNORDERED_FOA_TESTS
// Extract
test::check_return_type<node_type>::equals(r.extract(r.begin()));
@@ -503,7 +461,6 @@ void unordered_map_test(X& r, Key const& k, T const& v)
node_type n = r.extract(r.begin());
test::check_return_type<node_key_type>::equals_ref(n.key());
test::check_return_type<node_mapped_type>::equals_ref(n.mapped());
#endif
}
template <class X> void equality_test(X& r)
@@ -522,7 +479,6 @@ 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.emplace(t));
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::node_type node_type;
typedef typename X::insert_return_type insert_return_type;
@@ -547,7 +503,6 @@ 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<node_type>::equals_ref(insert_return.node);
boost::swap(insert_return, insert_return2);
#endif
}
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
@@ -599,7 +554,6 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
typedef typename X::iterator iterator;
typedef typename X::const_iterator const_iterator;
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::local_iterator local_iterator;
typedef typename X::const_local_iterator const_local_iterator;
@@ -636,7 +590,6 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
const_local_iterator_pointer;
typedef typename std::iterator_traits<const_local_iterator>::reference
const_local_iterator_reference;
#endif
typedef typename X::allocator_type allocator_type;
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
@@ -649,7 +602,6 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
BOOST_STATIC_ASSERT((boost::is_same<Pred, key_equal>::value));
test::check_return_type<bool>::convertible(eq(k, k));
#ifndef BOOST_UNORDERED_FOA_TESTS
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
BOOST_STATIC_ASSERT(
(boost::is_same<local_iterator_category, iterator_category>::value));
@@ -670,7 +622,6 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
const_iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<const_local_iterator_reference,
const_iterator_reference>::value));
#endif
X a;
allocator_type m = a.get_allocator();
@@ -716,7 +667,6 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
b.equal_range(k));
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.bucket(k));
test::check_return_type<size_type>::equals(b.bucket_size(0));
@@ -730,7 +680,6 @@ 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(a.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.max_load_factor());
@@ -843,11 +792,7 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
X a10;
a10.insert(t);
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));
#endif
// Avoid unused variable warnings:
@@ -862,12 +807,10 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
sink(a7a);
sink(a9a);
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename X::node_type node_type;
typedef typename X::allocator_type allocator_type;
node_type const n_const = a.extract(a.begin());
test::check_return_type<allocator_type>::equals(n_const.get_allocator());
#endif
}
template <class X, class Key, class T, class Hash, class Pred>
@@ -936,11 +879,7 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
T v5(v);
a10.insert(boost::move(v5));
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));
#endif
// Avoid unused variable warnings:
+10 -148
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2010 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -31,7 +35,6 @@ namespace constructor_tests {
T x(0, hf, eq);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
@@ -70,7 +73,6 @@ namespace constructor_tests {
T x;
BOOST_TEST(x.empty());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
@@ -138,7 +140,6 @@ namespace constructor_tests {
T x(0, hf, eq, al);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
@@ -165,7 +166,6 @@ namespace constructor_tests {
T x(al);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
@@ -325,7 +325,6 @@ namespace constructor_tests {
T x(list);
BOOST_TEST(x.empty());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
BOOST_TEST(test::equivalent(x.get_allocator(), al));
@@ -381,104 +380,6 @@ namespace constructor_tests {
#endif
}
template <class T>
void no_alloc_default_construct_test(T*, test::random_generator)
{
UNORDERED_SUB_TEST("Construct 1")
{
T x;
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
UNORDERED_SUB_TEST("Construct 2")
{
{
T x(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
T x(1);
BOOST_TEST_GT(x.bucket_count(), 0u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
}
UNORDERED_SUB_TEST("Construct 3")
{
test::random_values<T> v;
T x(v.begin(), v.end());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
UNORDERED_SUB_TEST("Construct 4")
{
{
test::random_values<T> v;
T x(v.begin(), v.end(), 0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
test::random_values<T> v;
T x(v.begin(), v.end(), 1);
BOOST_TEST_GT(x.bucket_count(), 0u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
}
UNORDERED_SUB_TEST("Construct 5")
{
typename T::allocator_type al;
{
T x(al);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
}
UNORDERED_SUB_TEST("Construct 6")
{
typename T::allocator_type al;
T x(0, al);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_SUB_TEST("Initializer list 1")
{
std::initializer_list<typename T::value_type> list;
T x(list);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
UNORDERED_SUB_TEST("Initializer list 2")
{
{
std::initializer_list<typename T::value_type> list;
T x(list, 0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
std::initializer_list<typename T::value_type> list;
T x(list, 1);
BOOST_TEST_GT(x.bucket_count(), 0u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
}
#endif
}
template <class T>
void map_constructor_test(T*, test::random_generator const& generator)
{
@@ -493,35 +394,6 @@ namespace constructor_tests {
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,
std::allocator<test::object> >* test_map_std_alloc;
@@ -534,6 +406,10 @@ namespace constructor_tests {
boost::unordered_multimap<test::object, test::object, test::hash,
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,
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
@@ -546,20 +422,11 @@ namespace constructor_tests {
((test_map_std_alloc)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(no_alloc_default_construct_test,
((test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
#endif
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST (test_default_initializer_list) {
std::initializer_list<int> init;
#ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<int> x1 = init;
#else
boost::unordered_set<int> x1 = init;
#endif
BOOST_TEST(x1.empty());
}
@@ -568,12 +435,7 @@ namespace constructor_tests {
#if !defined(BOOST_NO_CXX11_HDR_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};
#endif
BOOST_TEST(x1.find(10) != x1.end());
BOOST_TEST(x1.find(46) == x1.end());
}
+8 -38
View File
@@ -1,8 +1,13 @@
// Copyright 2021-2022 Christian Mazakas.
// Copyright 2021 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)
#include "../helpers/unordered.hpp"
// 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"
@@ -124,20 +129,6 @@ template <class UnorderedMap> void test_map_non_transparent_contains()
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,
transparent_key_equal>
transparent_map;
@@ -150,7 +141,6 @@ void test_map()
typedef boost::unordered_map<key, int, hasher, key_equal>
non_transparent_map3;
#endif
test_map_transparent_contains<transparent_map>();
test_map_non_transparent_contains<non_transparent_map1>();
@@ -158,7 +148,6 @@ void test_map()
test_map_non_transparent_contains<non_transparent_map3>();
}
#ifndef BOOST_UNORDERED_FOA_TESTS
void test_multimap()
{
typedef boost::unordered_multimap<key, int, transparent_hasher,
@@ -179,7 +168,6 @@ void test_multimap()
test_map_non_transparent_contains<non_transparent_multimap2>();
test_map_non_transparent_contains<non_transparent_multimap3>();
}
#endif
template <class UnorderedSet> void test_set_transparent_contains()
{
@@ -243,18 +231,6 @@ template <class UnorderedSet> void test_set_non_transparent_contains()
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>
transparent_set;
@@ -263,7 +239,6 @@ void test_set()
typedef boost::unordered_set<key, hasher, transparent_key_equal>
non_transparent_set2;
typedef boost::unordered_set<key, hasher, key_equal> non_transparent_set3;
#endif
test_set_transparent_contains<transparent_set>();
test_set_non_transparent_contains<non_transparent_set1>();
@@ -271,7 +246,6 @@ void test_set()
test_set_non_transparent_contains<non_transparent_set3>();
}
#ifndef BOOST_UNORDERED_FOA_TESTS
void test_multiset()
{
typedef boost::unordered_multiset<key, transparent_hasher,
@@ -290,15 +264,11 @@ void test_multiset()
test_set_non_transparent_contains<non_transparent_multiset2>();
test_set_non_transparent_contains<non_transparent_multiset3>();
}
#endif
UNORDERED_AUTO_TEST (contains_) { // avoid -Wshadow warning with `bool contains`
test_map();
test_set();
#ifndef BOOST_UNORDERED_FOA_TESTS
test_multimap();
test_multiset();
#endif
test_set();
}
RUN_TESTS()
+21 -117
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -39,23 +43,6 @@ namespace copy_tests {
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(test::selected_count(y.get_allocator()) ==
(allocator_type::is_select_on_copy));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
test::check_equivalent_keys(y);
}
{
test::check_instances check_;
T x(0);
T y(x);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(test::selected_count(y.get_allocator()) ==
(allocator_type::is_select_on_copy));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
test::check_equivalent_keys(y);
}
@@ -104,22 +91,6 @@ namespace copy_tests {
typedef typename T::allocator_type allocator_type;
{
test::check_instances check_;
T x(0, hf, eq, al);
T y(x);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(test::selected_count(y.get_allocator()) ==
(allocator_type::is_select_on_copy));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
test::check_equivalent_keys(y);
}
{
test::check_instances check_;
@@ -135,21 +106,6 @@ namespace copy_tests {
test::check_equivalent_keys(y);
}
{
test::check_instances check_;
T x(0, hf, eq, al);
T y(x, al2);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
BOOST_TEST(test::selected_count(y.get_allocator()) == 0);
BOOST_TEST(test::detail::tracker.count_allocations == 0);
test::check_equivalent_keys(y);
}
{
test::check_instances check_;
@@ -164,22 +120,6 @@ namespace copy_tests {
test::check_equivalent_keys(y);
}
{
test::check_instances check_;
test::random_values<T> v;
T x(v.begin(), v.end(), 0, hf, eq, al);
T y(x);
test::unordered_equivalence_tester<T> equivalent(x);
BOOST_TEST(equivalent(y));
test::check_equivalent_keys(y);
BOOST_TEST(test::selected_count(y.get_allocator()) ==
(allocator_type::is_select_on_copy));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
}
{
test::check_instances check_;
@@ -195,21 +135,6 @@ namespace copy_tests {
BOOST_TEST(test::equivalent(y.get_allocator(), al));
}
{
test::check_instances check_;
test::random_values<T> v;
T x(v.begin(), v.end(), 0, hf, eq, al);
T y(x, al2);
test::unordered_equivalence_tester<T> equivalent(x);
BOOST_TEST(equivalent(y));
test::check_equivalent_keys(y);
BOOST_TEST(test::selected_count(y.get_allocator()) == 0);
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(test::detail::tracker.count_allocations == 0);
}
{
test::check_instances check_;
@@ -225,38 +150,6 @@ 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,
test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, test::hash, test::equal_to,
@@ -292,14 +185,25 @@ namespace copy_tests {
test::equal_to, test::cxx11_allocator<test::object, test::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,
((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_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
test_multiset_select_copy)(test_map_select_copy)(
test_multimap_select_copy)(test_set_no_select_copy)(
test_multiset_no_select_copy)(test_map_no_select_copy)(
test_multimap_no_select_copy))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(copy_construct_tests2,
((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_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
test_multiset_select_copy)(test_map_select_copy)(
test_multimap_select_copy)(test_set_no_select_copy)(
test_multiset_no_select_copy)(test_map_no_select_copy)(
test_multimap_no_select_copy))(
(default_generator)(generate_collisions)(limited_range)))
#endif
} // namespace copy_tests
}
RUN_TESTS()
+16 -128
View File
@@ -1,10 +1,14 @@
//
// Copyright 2016 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 <boost/functional/hash/hash.hpp>
#include "../helpers/test.hpp"
@@ -42,56 +46,47 @@ namespace emplace_tests {
A8 a8;
A9 a9;
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) : arg_count(2), a0(b0), a1(b1) {}
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
: arg_count(3), a0(b0), a1(b1), a2(b2), a3(-1), a4(-1), a5(-1), a6(-1),
a7(-1), a8(-1), a9(-1)
: arg_count(3), a0(b0), a1(b1), a2(b2)
{
}
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), a4(-1), a5(-1), a6(-1),
a7(-1), a8(-1), a9(-1)
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3)
{
}
emplace_value(
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), a5(-1), a6(-1),
a7(-1), a8(-1), a9(-1)
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4)
{
}
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A4 const& b4, A5 const& b5)
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(-1),
a7(-1), a8(-1), a9(-1)
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5)
{
}
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
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),
a7(-1), a8(-1), a9(-1)
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6)
{
}
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)
: arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
a7(b7), a8(-1), a9(-1)
a7(b7)
{
}
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)
: arg_count(9), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
a7(b7), a8(b8), a9(-1)
a7(b7), a8(b8)
{
}
@@ -167,29 +162,16 @@ namespace emplace_tests {
return true;
}
#ifdef BOOST_UNORDERED_FOA_TESTS
emplace_value() = delete;
emplace_value(emplace_value const&) = default;
emplace_value(emplace_value&&) = default;
#else
private:
emplace_value();
emplace_value(emplace_value const&);
#endif
};
UNORDERED_AUTO_TEST (emplace_set) {
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> >
container;
#endif
typedef container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
@@ -205,15 +187,7 @@ namespace emplace_tests {
BOOST_TEST(*r1.first == v1);
BOOST_TEST(r1.first == x.find(v1));
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);
#endif
// 3 args
@@ -224,11 +198,7 @@ namespace emplace_tests {
BOOST_TEST(*r1.first == v2);
BOOST_TEST(r1.first == x.find(v2));
BOOST_TEST_EQ(check_.instances(), 4);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST_EQ(check_.constructions(), 6);
#else
BOOST_TEST_EQ(check_.constructions(), 4);
#endif
// 7 args with hint + duplicate
@@ -238,11 +208,7 @@ namespace emplace_tests {
BOOST_TEST(*i1 == v3);
BOOST_TEST(i1 == x.find(v3));
BOOST_TEST_EQ(check_.instances(), 6);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST_EQ(check_.constructions(), 9);
#else
BOOST_TEST_EQ(check_.constructions(), 6);
#endif
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
BOOST_TEST_EQ(x.size(), 3u);
@@ -252,11 +218,7 @@ namespace emplace_tests {
// whether it can emplace, so there's an extra construction
// here.
BOOST_TEST_EQ(check_.instances(), 6);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST_EQ(check_.constructions(), 10);
#else
BOOST_TEST_EQ(check_.constructions(), 7);
#endif
// 10 args + hint duplicate
@@ -268,11 +230,7 @@ namespace emplace_tests {
BOOST_TEST(*r1.first == v4);
BOOST_TEST(r1.first == x.find(v4));
BOOST_TEST_EQ(check_.instances(), 8);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST_EQ(check_.constructions(), 13);
#else
BOOST_TEST_EQ(check_.constructions(), 9);
#endif
BOOST_TEST(
r1.first == x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
@@ -281,11 +239,7 @@ namespace emplace_tests {
BOOST_TEST(
r1.first == x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
BOOST_TEST_EQ(check_.instances(), 8);
#ifdef BOOST_UNORDERED_FOA_TESTS
BOOST_TEST_EQ(check_.constructions(), 16);
#else
BOOST_TEST_EQ(check_.constructions(), 12);
#endif
BOOST_TEST_EQ(x.size(), 4u);
BOOST_TEST(x.count(v1) == 1);
@@ -294,7 +248,6 @@ namespace emplace_tests {
BOOST_TEST(x.count(v4) == 1);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (emplace_multiset) {
test::check_instances check_;
@@ -372,79 +325,20 @@ namespace emplace_tests {
BOOST_TEST_EQ(x.count(v2), 2u);
BOOST_TEST_EQ(x.count(v3), 2u);
}
#endif
UNORDERED_AUTO_TEST (emplace_map) {
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,
boost::hash<emplace_value> >
container;
#endif
typedef container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
return_type r1, r2;
#ifdef BOOST_UNORDERED_FOA_TESTS
// 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 m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 = x.emplace(boost::unordered::piecewise_construct,
@@ -501,10 +395,8 @@ namespace emplace_tests {
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
#endif
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (emplace_multimap) {
test::check_instances check_;
@@ -569,15 +461,11 @@ namespace emplace_tests {
BOOST_TEST_EQ(check_.instances(), 20);
BOOST_TEST_EQ(check_.constructions(), 20);
}
#endif
UNORDERED_AUTO_TEST (try_emplace) {
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;
#endif
typedef container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
+16 -38
View File
@@ -1,10 +1,14 @@
// Copyright 2008-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 <boost/preprocessor/seq.hpp>
#include <list>
@@ -26,27 +30,14 @@ namespace equality_tests {
}
};
#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) \
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
{ \
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_TEST(set1 op set2); \
}
#define UNORDERED_EQUALITY_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) \
{ \
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
@@ -55,26 +46,17 @@ namespace equality_tests {
BOOST_TEST(set1 op set2); \
}
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
{ \
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_TEST(map1 op map2); \
}
#endif
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
{ \
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::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_TEST(map1 op map2); \
@@ -85,11 +67,7 @@ namespace equality_tests {
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
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;
#endif
BOOST_TEST(x1 == x2);
BOOST_TEST(!(x1 != x2));
@@ -156,7 +134,7 @@ namespace equality_tests {
// different hash functions but the same equality predicate.
UNORDERED_AUTO_TEST (equality_different_hash_test) {
typedef boost_unordered_set set;
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
set set1(0, mod_compare(false), mod_compare(false));
set set2(0, mod_compare(true), mod_compare(true));
BOOST_TEST(set1 == set2);
+7 -12
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 <algorithm>
@@ -34,11 +38,8 @@ void test_equal_insertion(Iterator begin, Iterator end)
UNORDERED_AUTO_TEST (set_tests) {
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;
#endif
typedef boost::unordered_multiset<int> multiset;
test_equal_insertion<set>(values[0], values[0] + 1);
test_equal_insertion<set>(values[1], values[1] + 2);
@@ -46,7 +47,6 @@ UNORDERED_AUTO_TEST (set_tests) {
test_equal_insertion<set>(values[3], values[3] + 2);
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[1], values[1] + 2);
test_equal_insertion<multiset>(values[2], values[2] + 2);
@@ -66,17 +66,12 @@ UNORDERED_AUTO_TEST (map_tests) {
v[2].push_back(std::pair<int const, int>(432, 24));
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> >(
v[i].begin(), v[i].end());
for (int i2 = 0; i2 < 5; ++i2)
test_equal_insertion<boost::unordered_multimap<int, int> >(
v[i2].begin(), v[i2].end());
#endif
}
RUN_TESTS()
+57 -10
View File
@@ -2,7 +2,12 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "../helpers/unordered.hpp"
// 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"
@@ -18,13 +23,36 @@
namespace test {
struct is_even
{
bool operator()(std::pair<std::string const, int>& key_value)
is_even() {}
#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;
return (v % 2 == 0);
}
bool operator()(int const& value)
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
{
int const v = value;
return (v % 2 == 0);
@@ -33,13 +61,37 @@ namespace test {
struct is_too_large
{
bool operator()(std::pair<std::string const, int>& key_value)
is_too_large() {}
#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;
return v >= 1000;
}
bool operator()(int const& value)
bool operator()(int const& value) UNORDERED_LVALUE_QUAL
{
int const v = value;
return v >= 1000;
@@ -107,16 +159,11 @@ template <class UnorderedSet> void test_set_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_multimap<std::string, int> >();
test_set_erase_if<boost::unordered_set<int> >();
test_set_erase_if<boost::unordered_multiset<int> >();
#endif
}
RUN_TESTS()
+10 -37
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -23,9 +27,7 @@ namespace erase_tests {
template <class Container>
void erase_tests1(Container*, test::random_generator generator)
{
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename Container::iterator iterator;
#endif
typedef typename Container::const_iterator c_iterator;
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Erase by key.\n";
@@ -59,13 +61,9 @@ namespace erase_tests {
while (size > 0 && !x.empty()) {
typename Container::key_type key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key);
#ifdef BOOST_UNORDERED_FOA_TESTS
x.erase(x.begin());
#else
iterator pos = x.erase(x.begin());
BOOST_TEST(pos == x.begin());
#endif
--size;
BOOST_TEST(pos == x.begin());
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
if (++iterations % 20 == 0)
@@ -95,15 +93,10 @@ namespace erase_tests {
typename Container::key_type key = test::get_key<Container>(*pos);
std::size_t count = x.count(key);
BOOST_TEST(count > 0);
#ifdef BOOST_UNORDERED_FOA_TESTS
x.erase(pos);
--size;
#else
BOOST_TEST(next == x.erase(pos));
--size;
if (size > 0)
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
#endif
BOOST_TEST(x.count(key) == count - 1);
if (x.count(key) != count - 1) {
BOOST_LIGHTWEIGHT_TEST_OSTREAM << count << " => " << x.count(key)
@@ -192,11 +185,7 @@ namespace erase_tests {
while (size > 0 && !x.empty()) {
typename Container::key_type key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key);
#ifdef BOOST_UNORDERED_FOA_TESTS
x.erase(x.begin());
#else
x.quick_erase(x.begin());
#endif
--size;
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
@@ -227,11 +216,7 @@ namespace erase_tests {
typename Container::key_type key = test::get_key<Container>(*pos);
std::size_t count = x.count(key);
BOOST_TEST(count > 0);
#ifdef BOOST_UNORDERED_FOA_TESTS
x.erase(pos);
#else
x.quick_erase(pos);
#endif
--size;
if (size > 0)
BOOST_TEST(index == 0 ? next == x.begin() : next == test::next(prev));
@@ -261,20 +246,6 @@ namespace erase_tests {
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,
test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, test::hash, test::equal_to,
@@ -284,11 +255,13 @@ namespace erase_tests {
boost::unordered_multimap<test::object, test::object, test::hash,
test::equal_to, test::allocator2<test::object> >* test_multimap;
using test::default_generator;
using test::generate_collisions;
using test::limited_range;
UNORDERED_TEST(
erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
#endif
}
RUN_TESTS()
+10 -17
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -129,20 +133,6 @@ 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,
test::allocator2<test::object> >* test_set;
boost::unordered_multiset<test::object, test::hash, test::equal_to,
@@ -152,13 +142,16 @@ namespace find_tests {
boost::unordered_multimap<test::object, test::object, test::hash,
test::equal_to, test::allocator1<test::object> >* test_multimap;
using test::default_generator;
using test::generate_collisions;
using test::limited_range;
UNORDERED_TEST(
find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(find_compatible_keys_test,
((test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
#endif
}
RUN_TESTS()
-37
View File
@@ -1,44 +1,14 @@
// Copyright 2008-2009 Daniel James.
// 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)
// clang-format off
#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>
#endif
#include "../helpers/postfix.hpp"
// 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>
void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
{
@@ -80,15 +50,10 @@ bool call_not_equals(
}
#include <boost/unordered_map.hpp>
#endif
#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_multimap<int, int> int_multimap;
#endif
UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
int_map x, y;
@@ -106,13 +71,11 @@ UNORDERED_AUTO_TEST (use_map_fwd_declared_function) {
BOOST_TEST(call_not_equals(x, y));
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (use_multimap_fwd_declared_function) {
int_multimap x, y;
call_swap(x, y);
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
#endif
RUN_TESTS()
+1 -45
View File
@@ -1,17 +1,11 @@
// Copyright 2008-2009 Daniel James.
// 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)
// clang-format off
#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>
#endif
#include "../helpers/postfix.hpp"
// clang-format on
@@ -26,31 +20,6 @@ struct false_type
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>
true_type is_unordered_set_impl(
boost::unordered_set<Value, Hash, Pred, Alloc>*);
@@ -72,9 +41,7 @@ bool call_not_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
{
return x != y;
}
#endif
#ifndef BOOST_UNORDERED_FOA_TESTS
template <typename T>
void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
{
@@ -94,29 +61,20 @@ bool call_not_equals(
{
return x != y;
}
#endif
#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_multiset<int> int_multiset;
#endif
UNORDERED_AUTO_TEST (use_fwd_declared_trait_without_definition) {
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>
#endif
UNORDERED_AUTO_TEST (use_fwd_declared_trait) {
int_set x;
boost::unordered_set<int> x;
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
BOOST_TEST(sizeof(is_unordered_set_impl((int*)0)) == sizeof(false_type));
@@ -138,13 +96,11 @@ UNORDERED_AUTO_TEST (use_set_fwd_declared_function) {
BOOST_TEST(call_not_equals(x, y));
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (use_multiset_fwd_declared_function) {
int_multiset x, y;
call_swap(x, y);
BOOST_TEST(call_equals(x, y));
BOOST_TEST(!call_not_equals(x, y));
}
#endif
RUN_TESTS()
+8 -41
View File
@@ -1,21 +1,21 @@
// Copyright 2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// clang-format off
#include "../helpers/prefix.hpp"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include "../helpers/postfix.hpp"
// clang-format on
#include <utility>
namespace x {
struct D
{
#ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_map<D, D> x;
#else
boost::unordered_map<D, D> x;
#endif
};
}
@@ -29,17 +29,6 @@ namespace incomplete_test {
// 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,
allocator<std::pair<value const, value> > >
map;
@@ -49,7 +38,6 @@ namespace incomplete_test {
typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
multiset;
#endif
// Now define the types which are stored as members, as they are needed for
// declaring struct members.
@@ -88,28 +76,7 @@ namespace incomplete_test {
//
// Incomplete hash, equals and allocator aren't here supported at the
// 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
{
boost::unordered_map<struct1, struct1, hash, equals,
@@ -130,7 +97,7 @@ namespace incomplete_test {
{
boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
};
#endif
// Now define the value type.
struct value
-244
View File
@@ -1,244 +0,0 @@
// 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();
}
+7 -12
View File
@@ -1,10 +1,14 @@
// Copyright 2016 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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/invariants.hpp"
@@ -13,7 +17,6 @@
#include <set>
namespace insert_hint {
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (insert_hint_empty) {
typedef boost::unordered_multiset<int> container;
container x;
@@ -87,13 +90,9 @@ namespace insert_hint {
}
}
}
#endif
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;
#endif
container x;
x.insert(x.cbegin(), 10);
BOOST_TEST_EQ(x.size(), 1u);
@@ -102,11 +101,7 @@ namespace insert_hint {
}
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;
#endif
container x;
x.insert(10);
+16 -130
View File
@@ -1,12 +1,16 @@
// Copyright 2006-2010 Daniel James.
// 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)
#if !defined(PIECEWISE_TEST_NAME)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -17,8 +21,6 @@
#include "../helpers/input_iterator.hpp"
#include "../helpers/helpers.hpp"
#include <vector>
namespace insert_tests {
test::seed_t initialize_seed(243432);
@@ -676,23 +678,6 @@ 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>
void try_emplace_tests(X*, test::random_generator generator)
{
@@ -885,53 +870,6 @@ namespace insert_tests {
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,
std::allocator<test::movable> >* test_set_std_alloc;
boost::unordered_multimap<test::object, test::object, test::hash,
@@ -946,6 +884,10 @@ namespace insert_tests {
boost::unordered_multimap<test::object, test::object, test::hash,
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,
((test_set_std_alloc)(test_set)(test_map))(
(default_generator)(generate_collisions)(limited_range)))
@@ -955,8 +897,8 @@ namespace insert_tests {
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(insert_tests2,
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(
test_multimap))((default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(unique_emplace_tests1,
((test_set_std_alloc)(test_set)(test_map))(
@@ -967,11 +909,13 @@ namespace insert_tests {
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(move_emplace_tests,
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
test_multiset)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(default_emplace_tests,
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(test_multiset)(test_multimap))(
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
test_multiset)(test_multimap))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(map_tests,
@@ -988,10 +932,6 @@ namespace insert_tests {
((test_multimap_std_alloc)(test_map)(test_multimap))(
(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)
struct initialize_from_two_ints
@@ -1010,21 +950,13 @@ namespace insert_tests {
};
UNORDERED_AUTO_TEST (insert_initializer_list_set) {
#ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<int> set;
#else
boost::unordered_set<int> set;
#endif
set.insert({1, 2, 3, 1});
BOOST_TEST_EQ(set.size(), 3u);
BOOST_TEST(set.find(1) != 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;
#endif
#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))
set2.insert({{1, 2}});
@@ -1053,7 +985,6 @@ namespace insert_tests {
BOOST_TEST(set2.find({8, 7}) == set2.end());
}
#ifndef BOOST_UNORDERED_FOA_TESTS
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
UNORDERED_AUTO_TEST (insert_initializer_list_multiset) {
@@ -1071,22 +1002,16 @@ namespace insert_tests {
BOOST_TEST_EQ(multiset.count("c"), 0u);
}
#endif
#endif
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;
#endif
// map.insert({});
BOOST_TEST(map.empty());
map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
BOOST_TEST_EQ(map.size(), 2u);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (insert_initializer_list_multimap) {
boost::unordered_multimap<std::string, std::string> multimap;
// multimap.insert({});
@@ -1095,7 +1020,6 @@ namespace insert_tests {
BOOST_TEST_EQ(multimap.size(), 3u);
BOOST_TEST_EQ(multimap.count("a"), 2u);
}
#endif
#endif
@@ -1126,18 +1050,10 @@ namespace insert_tests {
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,
test::equal_to,
test::allocator1<std::pair<int const, overloaded_constructor> > >
x;
#endif
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace();
@@ -1154,7 +1070,6 @@ namespace insert_tests {
x.find(5) != x.end() && x.find(5)->second == overloaded_constructor());
}
#ifndef BOOST_UNORDERED_FOA_TESTS
{
boost::unordered_multimap<int, overloaded_constructor, test::hash,
test::equal_to,
@@ -1171,17 +1086,11 @@ namespace insert_tests {
BOOST_TEST(
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
}
#endif
}
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;
overloaded_constructor check;
#endif
#if !BOOST_UNORDERED_SUN_WORKAROUNDS1
x.emplace();
@@ -1227,7 +1136,6 @@ namespace insert_tests {
}
};
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (map_emplace_test2) {
// Emulating piecewise construction with boost::tuple bypasses the
// allocator's construct method, but still uses test destroy method.
@@ -1351,13 +1259,10 @@ namespace insert_tests {
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
}
#endif
// Use the preprocessor to generate tests using different combinations of
// boost/std piecewise_construct_t/tuple.
#ifndef BOOST_UNORDERED_FOA_TESTS
#define PIECEWISE_TEST_NAME boost_tuple_piecewise_tests
#define PIECEWISE_NAMESPACE boost::unordered
#define TUPLE_NAMESPACE boost
@@ -1384,8 +1289,6 @@ namespace insert_tests {
#endif
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
@@ -1408,21 +1311,12 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
#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::hash<overloaded_constructor>,
std::equal_to<overloaded_constructor>,
test::allocator1<
std::pair<overloaded_constructor const, overloaded_constructor> > >
x;
#endif
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
TUPLE_NAMESPACE::make_tuple(), TUPLE_NAMESPACE::make_tuple());
@@ -1466,7 +1360,6 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6));
}
#ifndef BOOST_UNORDERED_FOA_TESTS
{
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
boost::hash<overloaded_constructor>,
@@ -1500,7 +1393,6 @@ UNORDERED_AUTO_TEST (PIECEWISE_TEST_NAME) {
x.find(overloaded_constructor(9, 3, 1))->second ==
overloaded_constructor(10));
}
#endif
}
UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
@@ -1508,15 +1400,9 @@ UNORDERED_AUTO_TEST (BOOST_PP_CAT(PIECEWISE_TEST_NAME, 2)) {
test::detail::disable_construction_tracking _scoped;
#endif
#ifdef BOOST_UNORDERED_FOA_TESTS
boost::unordered_flat_set<
std::pair<overloaded_constructor, overloaded_constructor> >
x;
#else
boost::unordered_set<
std::pair<overloaded_constructor, overloaded_constructor> >
x;
#endif
std::pair<overloaded_constructor, overloaded_constructor> check;
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
+6 -16
View File
@@ -1,24 +1,15 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// clang-format off
#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>&,
boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
@@ -33,4 +24,3 @@ int main()
return 0;
}
#endif
+6 -19
View File
@@ -1,27 +1,15 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// clang-format off
#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,
boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
{
@@ -40,4 +28,3 @@ void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
x3.insert(3);
x4.insert(std::make_pair(4, 5));
}
#endif
+10 -28
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 <boost/limits.hpp>
@@ -22,17 +26,7 @@ namespace load_factor_tests {
template <class X> void set_load_factor_tests(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.load_factor() == 0);
@@ -42,7 +36,6 @@ namespace load_factor_tests {
BOOST_TEST(x.max_load_factor() == 2.0);
x.max_load_factor(0.5);
BOOST_TEST(x.max_load_factor() == 0.5);
#endif
}
template <class X>
@@ -79,32 +72,21 @@ namespace load_factor_tests {
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_multiset<int>* int_multiset_ptr;
boost::unordered_map<int, int>* int_map_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,
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)))
UNORDERED_TEST(load_factor_insert_tests,
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
(default_generator)(generate_collisions)(limited_range)))
#endif
}
RUN_TESTS()
+7 -87
View File
@@ -1,10 +1,12 @@
// Copyright 2016 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
#include "../helpers/postfix.hpp"
#include "../helpers/prefix.hpp"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include "../helpers/count.hpp"
#include "../helpers/helpers.hpp"
@@ -17,13 +19,8 @@
namespace merge_tests {
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> y;
#endif
x.merge(y);
BOOST_TEST(x.empty());
@@ -60,7 +57,6 @@ namespace merge_tests {
test::check_equivalent_keys(y);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
UNORDERED_AUTO_TEST (merge_multiset) {
boost::unordered_multiset<int> x;
boost::unordered_multiset<int> y;
@@ -138,7 +134,6 @@ namespace merge_tests {
test::check_equivalent_keys(x);
test::check_equivalent_keys(y);
}
#endif
template <class X1, class X2>
void merge_empty_test(X1*, X2*, test::random_generator generator)
@@ -233,82 +228,6 @@ namespace merge_tests {
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,
std::allocator<test::movable> >* test_set_std_alloc;
boost::unordered_multiset<test::movable, test::hash, test::equal_to,
@@ -329,6 +248,9 @@ UNORDERED_TEST(merge_into_unique_keys_test,
boost::unordered_multimap<test::movable, test::movable, test::hash,
test::equal_to, test::allocator2<test::movable> >* test_multimap;
using test::default_generator;
using test::generate_collisions;
// clang-format off
UNORDERED_TEST(merge_empty_test,
((test_set_std_alloc)(test_multiset_std_alloc))
@@ -410,8 +332,6 @@ UNORDERED_TEST(merge_into_equiv_keys_test,
((0)(1)(2))
((default_generator)(generate_collisions)))
// clang-format on
#endif
}
RUN_TESTS()
+22 -146
View File
@@ -1,10 +1,14 @@
// Copyright 2008-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 "../objects/test.hpp"
@@ -14,9 +18,6 @@
#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
@@ -67,16 +68,8 @@ namespace move_tests {
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
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);
#endif
test::check_equivalent_keys(y);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
}
{
@@ -94,7 +87,7 @@ namespace move_tests {
}
template <class T>
void move_assign_tests1(T* p, test::random_generator const& generator)
void move_assign_tests1(T*, test::random_generator const& generator)
{
{
test::check_instances check_;
@@ -105,19 +98,6 @@ namespace move_tests {
y = create(v, count);
#if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
BOOST_TEST(count == test::global_object_count);
#endif
test::check_container(y, v);
test::check_equivalent_keys(y);
}
{
test::random_values<T> v;
T y;
y = empty(p);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
test::check_container(y, v);
test::check_equivalent_keys(y);
@@ -146,11 +126,7 @@ namespace move_tests {
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
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.
#endif
test::check_equivalent_keys(y);
}
@@ -166,11 +142,7 @@ namespace move_tests {
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
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.
#endif
test::check_equivalent_keys(y);
}
@@ -200,11 +172,7 @@ namespace move_tests {
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
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.
#endif
test::check_equivalent_keys(y);
}
}
@@ -227,11 +195,7 @@ namespace move_tests {
BOOST_TEST(y.empty());
test::check_container(y, v2);
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);
#endif
#if defined(BOOST_HAS_NRVO)
if (BOOST_UNORDERED_TEST_MOVING
@@ -256,11 +220,7 @@ namespace move_tests {
#endif
test::check_container(y, v);
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);
#endif
#if defined(BOOST_HAS_NRVO)
if (BOOST_UNORDERED_TEST_MOVING
@@ -273,36 +233,6 @@ namespace move_tests {
#endif
}
{
test::random_values<T> v;
T y(0, hf, eq, al1);
T x(0, hf, eq, al2);
x.max_load_factor(0.25);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
y = boost::move(x);
#if defined(BOOST_UNORDERED_USE_MOVE) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
#endif
test::check_container(y, v);
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);
#endif
if (BOOST_UNORDERED_TEST_MOVING
? (bool)allocator_type::is_propagate_on_move
: (bool)allocator_type::is_propagate_on_assign) {
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
} else {
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
}
}
{
test::check_instances check_;
@@ -320,11 +250,7 @@ namespace move_tests {
}
test::check_container(y, v);
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);
#endif
if (BOOST_UNORDERED_TEST_MOVING
? (bool)allocator_type::is_propagate_on_move
@@ -360,11 +286,7 @@ namespace move_tests {
test::check_container(y, v2);
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);
#endif
if (BOOST_UNORDERED_TEST_MOVING
? (bool)allocator_type::is_propagate_on_move
@@ -376,65 +298,17 @@ namespace move_tests {
}
}
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(move_construct_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)))
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)))
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))(
(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))(
(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;
std::allocator<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;
test::allocator1<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;
test::equal_to, test::allocator2<test::object> >* test_multimap;
boost::unordered_set<test::object, test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_move> >*
@@ -443,12 +317,11 @@ namespace move_tests {
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;
test::cxx11_allocator<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;
test::equal_to, test::cxx11_allocator<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> >*
@@ -457,12 +330,16 @@ namespace move_tests {
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;
test::cxx11_allocator<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;
test::cxx11_allocator<test::object, 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,
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
@@ -490,7 +367,6 @@ namespace move_tests {
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()
+32 -174
View File
@@ -1,13 +1,16 @@
// Copyright 2013 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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/fwd.hpp"
#if defined(BOOST_MSVC)
#pragma warning(push)
@@ -198,12 +201,6 @@ namespace noexcept_tests {
UNORDERED_AUTO_TEST (test_noexcept) {
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::unordered_set<int> >::value));
BOOST_TEST((boost::is_nothrow_move_constructible<
@@ -212,35 +209,19 @@ namespace noexcept_tests {
boost::unordered_map<int, int> >::value));
BOOST_TEST((boost::is_nothrow_move_constructible<
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::unordered_set<int, hash_possible_exception> >::value));
BOOST_TEST(
(!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
boost::hash<int>, equal_to_possible_exception> >::value));
#endif
}
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,
equal_to_nothrow_move_construct>
throwing_set;
#endif
if (have_is_nothrow_move) {
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
@@ -266,76 +247,42 @@ namespace noexcept_tests {
throwing_test_exception = false;
}
template <class T>
void test_nothrow_move_assign_when_noexcept(T*, test::random_generator const&)
{
{
if (have_is_nothrow_move_assign) {
BOOST_TEST(boost::is_nothrow_move_assignable<T>::value);
}
UNORDERED_AUTO_TEST (test_nothrow_move_assign_when_noexcept) {
typedef boost::unordered_set<int, hash_nothrow_move_assign,
equal_to_nothrow_move_assign>
throwing_set;
throwing_test_exception = false;
T x1;
T x2;
x1.insert(10);
x1.insert(50);
for (int i = 0; i < 100; ++i) {
x2.insert(i);
}
try {
throwing_test_exception = true;
x2 = boost::move(x1);
BOOST_TEST(x2.size() == 2);
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
BOOST_TEST(have_is_nothrow_move_assign);
} catch (test_exception) {
BOOST_TEST(!have_is_nothrow_move_assign);
}
throwing_test_exception = false;
if (have_is_nothrow_move_assign) {
BOOST_TEST(boost::is_nothrow_move_assignable<throwing_set>::value);
}
{
if (have_is_nothrow_move_assign) {
BOOST_TEST(boost::is_nothrow_move_assignable<T>::value);
}
throwing_test_exception = false;
throwing_test_exception = false;
T x1;
T x2;
x1.insert(10);
x1.insert(50);
for (int i = 0; i < 100; ++i) {
x2.insert(i);
}
try {
throwing_test_exception = true;
x1 = boost::move(x2);
BOOST_TEST(x1.size() == 100);
BOOST_TEST(have_is_nothrow_move_assign);
} catch (test_exception) {
BOOST_TEST(!have_is_nothrow_move_assign);
}
throwing_test_exception = false;
throwing_set x1;
throwing_set x2;
x1.insert(10);
x1.insert(50);
for (int i = 0; i < 100; ++i) {
x2.insert(i);
}
try {
throwing_test_exception = true;
x2 = boost::move(x1);
BOOST_TEST(x2.size() == 2);
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
BOOST_TEST(have_is_nothrow_move_assign);
} catch (test_exception) {
BOOST_TEST(!have_is_nothrow_move_assign);
}
throwing_test_exception = false;
}
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>
throwing_set;
#endif
if (have_is_nothrow_swap) {
BOOST_TEST(boost::is_nothrow_swappable<throwing_set>::value);
@@ -371,93 +318,4 @@ namespace noexcept_tests {
#pragma warning(pop)
#endif
template <class T> class allocator1
{
BOOST_COPYABLE_AND_MOVABLE(allocator1)
allocator1 operator=(BOOST_COPY_ASSIGN_REF(allocator1));
allocator1 operator=(BOOST_RV_REF(allocator1));
public:
typedef T value_type;
allocator1() {}
allocator1(allocator1 const&) {}
template <class U> allocator1(allocator1<U> const&) {}
T* allocate(std::size_t n)
{
noexcept_tests::test_throw("Allocate");
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) { ::operator delete(p); }
friend bool operator==(allocator1 const&, allocator1 const&) { return true; }
friend bool operator!=(allocator1 const&, allocator1 const&) { return false; }
};
template <class T> class allocator2
{
BOOST_COPYABLE_AND_MOVABLE(allocator2)
allocator2 operator=(BOOST_COPY_ASSIGN_REF(allocator2));
public:
typedef T value_type;
typedef boost::true_type propagate_on_container_move_assignment;
allocator2() {}
allocator2(allocator2 const&) {}
template <class U> allocator2(allocator2<U> const&) {}
allocator2& operator=(BOOST_RV_REF(allocator2)) { return *this; }
T* allocate(std::size_t n)
{
noexcept_tests::test_throw("Allocate");
return static_cast<T*>(::operator new(n * sizeof(T)));
}
void deallocate(T* p, std::size_t) { ::operator delete(p); }
friend bool operator==(allocator2 const&, allocator2 const&) { return true; }
friend bool operator!=(allocator2 const&, allocator2 const&) { return false; }
};
UNORDERED_AUTO_TEST (prelim_allocator_checks) {
BOOST_TEST(boost::allocator_is_always_equal<allocator1<int> >::type::value);
BOOST_TEST(!boost::allocator_propagate_on_container_move_assignment<
allocator1<int> >::type::value);
BOOST_TEST(boost::allocator_is_always_equal<allocator2<int> >::type::value);
BOOST_TEST(boost::allocator_propagate_on_container_move_assignment<
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,
noexcept_tests::equal_to_nothrow_move_assign, allocator1<int> >*
throwing_set_alloc1;
boost::unordered_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)))
#endif
RUN_TESTS()
-666
View File
@@ -1,666 +0,0 @@
// 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()
+9 -370
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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/random_values.hpp"
@@ -77,305 +81,6 @@ namespace rehash_tests {
BOOST_TEST(postcondition(x, 0));
}
template <class X> void rehash_empty_tracking(X*, test::random_generator)
{
// valid for all load factors
float const max_load_factors[] = {
0.5f, 1.0f, 1e6f, std::numeric_limits<float>::infinity()};
std::size_t const max_load_factors_len =
sizeof(max_load_factors) / sizeof(*max_load_factors);
for (std::size_t i = 0; i < max_load_factors_len; ++i) {
X x;
BOOST_TEST_EQ(x.size(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
x.max_load_factor(max_load_factors[i]);
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.rehash(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.rehash(1000);
BOOST_TEST_GE(x.bucket_count(), 1000u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.rehash(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.rehash(1000);
BOOST_TEST_GE(x.bucket_count(), 1000u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.rehash(10);
BOOST_TEST_GE(x.bucket_count(), 10u);
BOOST_TEST_LT(x.bucket_count(), 1000u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_GT(x.bucket_count(), 0u);
BOOST_TEST_LT(x.bucket_count(), 1000u);
x.rehash(1000);
BOOST_TEST_GE(x.bucket_count(), 1000u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.rehash(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
}
for (std::size_t i = 0; i < max_load_factors_len; ++i) {
typedef typename X::size_type size_type;
X x;
BOOST_TEST_EQ(x.size(), 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];
x.max_load_factor(mlf);
#endif
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.reserve(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.reserve(1000);
BOOST_TEST_GE(
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.reserve(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_EQ(x.bucket_count(), 0u);
x.reserve(1000);
BOOST_TEST_GE(
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.reserve(10);
BOOST_TEST_GE(
x.bucket_count(), static_cast<size_type>(std::ceil(10 / mlf)));
BOOST_TEST_LT(x.bucket_count(), 1000u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
}
{
BOOST_TEST_GT(x.bucket_count(), 0u);
BOOST_TEST_LT(x.bucket_count(), 1000u);
x.reserve(1000);
BOOST_TEST_GE(
x.bucket_count(), static_cast<size_type>(std::ceil(1000 / mlf)));
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.reserve(0);
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
}
}
}
template <class X>
void rehash_nonempty_tracking(X*, test::random_generator generator)
{
test::random_values<X> const v(1000, generator);
typedef typename X::size_type size_type;
float const max_load_factors[] = {0.5f, 1.0f, 1e2f};
size_type const max_load_factors_len =
sizeof(max_load_factors) / sizeof(*max_load_factors);
for (size_type i = 0; i < max_load_factors_len; ++i) {
float const mlf = max_load_factors[i];
X x(v.begin(), v.end());
BOOST_TEST_GT(x.size(), 0u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
x.max_load_factor(mlf);
size_type bucket_count = x.bucket_count();
{
BOOST_TEST_GT(x.bucket_count(), 0u);
x.rehash(0);
BOOST_TEST_GE(x.bucket_count(),
static_cast<size_type>(
std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
bucket_count = x.bucket_count();
}
{
BOOST_TEST_GT(bucket_count, 0u);
x.rehash(2 * x.bucket_count());
BOOST_TEST_GT(x.bucket_count(), bucket_count);
bucket_count = x.bucket_count();
}
{
float const old_mlf = x.max_load_factor();
BOOST_TEST_GT(bucket_count, 0u);
x.rehash(bucket_count / 4);
BOOST_TEST_LT(x.bucket_count(), bucket_count);
x.max_load_factor(std::numeric_limits<float>::infinity());
x.rehash(0);
BOOST_TEST_GT(x.bucket_count(), 0u);
x.max_load_factor(old_mlf);
}
{
std::size_t const max_load =
static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
static_cast<double>(x.bucket_count()));
while (x.size() < max_load) {
test::random_values<X> const t(max_load, generator);
typename test::random_values<X>::const_iterator pos = t.begin();
typename test::random_values<X>::const_iterator end = t.end();
for (; pos != end; ++pos) {
x.insert(*pos);
if (x.size() == max_load) {
break;
}
}
}
while (x.size() > max_load) {
x.erase(x.begin());
}
BOOST_TEST_EQ(x.size(), max_load);
bucket_count = x.bucket_count();
x.rehash(x.bucket_count());
BOOST_TEST_EQ(x.bucket_count(), bucket_count);
}
}
for (size_type i = 0; i < max_load_factors_len; ++i) {
X x(v.begin(), v.end());
BOOST_TEST_GT(x.size(), 0u);
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
float const mlf = max_load_factors[i];
x.max_load_factor(mlf);
size_type bucket_count = x.bucket_count();
{
BOOST_TEST_GT(x.bucket_count(), 0u);
x.reserve(0);
BOOST_TEST_GE(x.bucket_count(),
static_cast<size_type>(
std::floor(static_cast<float>(x.size()) / x.max_load_factor())));
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
bucket_count = x.bucket_count();
}
{
BOOST_TEST_GT(x.bucket_count(), 0u);
x.reserve(
2 * (static_cast<size_type>(
std::floor(static_cast<float>(x.size()) / x.max_load_factor()) +
std::floor(static_cast<float>(x.size()) * x.max_load_factor()))));
BOOST_TEST_GT(x.bucket_count(), bucket_count);
bucket_count = x.bucket_count();
BOOST_TEST_GT(bucket_count, 1u);
}
{
float const old_mlf = x.max_load_factor();
BOOST_TEST_GT(bucket_count, 4u);
x.reserve(bucket_count / 4);
BOOST_TEST_LT(x.bucket_count(), bucket_count);
x.max_load_factor(std::numeric_limits<float>::infinity());
x.reserve(0);
BOOST_TEST_GT(x.bucket_count(), 0u);
x.max_load_factor(old_mlf);
}
{
std::size_t const max_load =
static_cast<std::size_t>(static_cast<double>(x.max_load_factor()) *
static_cast<double>(x.bucket_count()));
while (x.size() < max_load) {
test::random_values<X> const t(max_load, generator);
typename test::random_values<X>::const_iterator pos = t.begin();
typename test::random_values<X>::const_iterator end = t.end();
for (; pos != end; ++pos) {
x.insert(*pos);
if (x.size() == max_load) {
break;
}
}
}
while (x.size() > max_load) {
x.erase(x.begin());
}
BOOST_TEST_EQ(x.size(), max_load);
bucket_count = x.bucket_count();
x.reserve(x.size());
BOOST_TEST_EQ(x.bucket_count(), bucket_count);
}
}
}
template <class X> void rehash_test1(X*, test::random_generator generator)
{
test::random_values<X> v(1000, generator);
@@ -420,15 +125,6 @@ namespace rehash_tests {
X x;
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);
BOOST_TEST(x.bucket_count() >= 40000);
@@ -436,7 +132,6 @@ namespace rehash_tests {
x.reserve(10000000);
BOOST_TEST(x.bucket_count() >= 40000000);
#endif
}
template <class X> void reserve_test1(X*, test::random_generator generator)
@@ -497,47 +192,6 @@ 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_multiset<test::object, test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset_ptr;
@@ -545,17 +199,9 @@ namespace rehash_tests {
test::allocator2<test::movable> >* test_map_ptr;
boost::unordered_multimap<int, int>* int_multimap_ptr;
boost::unordered_set<test::object, test::hash, test::equal_to,
test::allocator1<test::object> >* test_set_tracking;
boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::allocator1<test::object> >* test_multiset_tracking;
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::allocator1<std::pair<test::object const, test::object> > >*
test_map_tracking;
boost::unordered_multimap<test::object, test::object, test::hash,
test::equal_to,
test::allocator1<std::pair<test::object const, test::object> > >*
test_multimap_tracking;
using test::default_generator;
using test::generate_collisions;
using test::limited_range;
UNORDERED_TEST(rehash_empty_test1,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
@@ -578,13 +224,6 @@ namespace rehash_tests {
UNORDERED_TEST(reserve_test2,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(rehash_empty_tracking,
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
(default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(rehash_nonempty_tracking,
((test_set_tracking)(test_multiset_tracking)(test_map_tracking)(test_multimap_tracking))(
(default_generator)(generate_collisions)(limited_range)))
#endif
}
RUN_TESTS()
+8 -33
View File
@@ -2,7 +2,12 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "../helpers/unordered.hpp"
// 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"
@@ -108,8 +113,8 @@ template <class UnorderedContainer> void reserve_tests()
s.max_load_factor(0.37f);
s.reserve(count);
std::size_t expected_bucket_count = static_cast<std::size_t>(
std::ceil(static_cast<float>(count) / s.max_load_factor()));
std::size_t expected_bucket_count =
static_cast<std::size_t>(std::ceil(static_cast<float>(count) / 0.37f));
BOOST_TEST_GE(total_allocation, expected_bucket_count * sizeof(void*));
BOOST_TEST_GE(s.bucket_count(), expected_bucket_count);
@@ -168,12 +173,6 @@ template <class UnorderedContainer> void rehash_tests()
// note, the test is vulnerable to cases where the next calculated bucket
// 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 =
3 * sizeof(void*) + sizeof(std::size_t);
std::size_t const estimated_bucket_groups =
@@ -183,7 +182,6 @@ template <class UnorderedContainer> void rehash_tests()
BOOST_TEST_LE(total_allocation,
(prev_count + count) * sizeof(void*) +
estimated_bucket_group_size * estimated_bucket_groups);
#endif
}
BOOST_TEST_GT(num_allocations, 0u);
@@ -216,28 +214,6 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
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>,
A<int> >
unordered_set;
@@ -273,7 +249,6 @@ UNORDERED_AUTO_TEST (unordered_set_reserve) {
rehash_tests<unordered_map>();
rehash_tests<unordered_multiset>();
rehash_tests<unordered_multimap>();
#endif
}
RUN_TESTS()
+12 -11
View File
@@ -2,8 +2,14 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// 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/unordered.hpp"
#include "../objects/test.hpp"
#include <memory>
@@ -101,7 +107,8 @@ public:
// ever using it with an int with has a trivial destructor so it eliminates
// the code and generates a warning about an unused variable
//
template <class U> void destroy(U* p)
template <class U>
void destroy(U* p)
{
(void)p;
p->~U();
@@ -185,7 +192,8 @@ public:
// ever using it with an int with has a trivial destructor so it eliminates
// the code and generates a warning about an unused variable
//
template <class U> void destroy(U* p)
template <class U>
void destroy(U* p)
{
(void)p;
p->~U();
@@ -216,15 +224,13 @@ template <class C1, class C2> void scary_test()
typename C2::const_iterator cbegin(x.cbegin());
BOOST_TEST(cbegin == x.cend());
BOOST_TEST_EQ(x.bucket_count(), 0u);
BOOST_ASSERT(x.bucket_count() > 0);
#ifndef BOOST_UNORDERED_FOA_TESTS
typename C2::local_iterator lbegin(x.begin(0));
BOOST_TEST(lbegin == x.end(0));
typename C2::const_local_iterator clbegin(x.cbegin(0));
BOOST_TEST(clbegin == x.cend(0));
#endif
}
template <
@@ -310,16 +316,11 @@ void set_scary_test()
}
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_multimap>();
set_scary_test<boost::unordered_set>();
set_scary_test<boost::unordered_multiset>();
#endif
}
RUN_TESTS()
+7 -8
View File
@@ -19,7 +19,12 @@ int main() {}
// https://github.com/boostorg/unordered/issues/22
//
#include "../helpers/unordered.hpp"
// 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"
@@ -27,10 +32,10 @@ int main() {}
#include <boost/core/ignore_unused.hpp>
#include <scoped_allocator>
#include <string>
#include <utility>
#include <vector>
#include <scoped_allocator>
namespace test {
template <class T> struct allocator
@@ -65,15 +70,9 @@ typedef std::scoped_allocator_adaptor<test::allocator<pair_type>,
test::allocator<boost::uint64_t> >
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,
boost::hash<boost::uint64_t>, std::equal_to<boost::uint64_t>, allocator_type>
map_type;
#endif
UNORDERED_AUTO_TEST (scoped_allocator) {
allocator_type alloc(
+6 -14
View File
@@ -1,12 +1,16 @@
// Copyright 2006-2009 Daniel James.
// 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)
// This test checks the runtime requirements of containers.
#include "../helpers/unordered.hpp"
// 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 <cstdlib>
@@ -89,11 +93,7 @@ UNORDERED_AUTO_TEST (simple_tests) {
srand(14878);
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;
#endif
simple_test(set);
set.insert(1);
@@ -101,7 +101,6 @@ UNORDERED_AUTO_TEST (simple_tests) {
set.insert(1456);
simple_test(set);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multiset.\n";
boost::unordered_multiset<int> multiset;
simple_test(multiset);
@@ -112,21 +111,15 @@ UNORDERED_AUTO_TEST (simple_tests) {
multiset.insert(index);
}
simple_test(multiset);
#endif
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;
#endif
for (int i2 = 0; i2 < 1000; ++i2) {
map.insert(std::pair<const int, int>(rand(), rand()));
}
simple_test(map);
#ifndef BOOST_UNORDERED_FOA_TESTS
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> multimap;
@@ -136,7 +129,6 @@ UNORDERED_AUTO_TEST (simple_tests) {
multimap.insert(std::pair<const int, int>(index, rand()));
}
simple_test(multimap);
#endif
}
RUN_TESTS()
+15 -50
View File
@@ -1,10 +1,14 @@
// Copyright 2006-2009 Daniel James.
// 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)
#include "../helpers/unordered.hpp"
// 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 <boost/config.hpp>
#include <algorithm>
@@ -135,53 +139,6 @@ 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,
std::allocator<test::object> >* test_map_std_alloc;
@@ -221,6 +178,15 @@ namespace swap_tests {
test::cxx11_allocator<test::object, test::no_propagate_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) {
BOOST_TEST(!is_propagate(test_set));
BOOST_TEST(is_propagate(test_set_prop_swap));
@@ -241,6 +207,5 @@ namespace swap_tests {
test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(
test_multimap_no_prop_swap))(
(default_generator)(generate_collisions)(limited_range)))
#endif
}
RUN_TESTS()
+20 -83
View File
@@ -2,7 +2,12 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include "../helpers/unordered.hpp"
// 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"
@@ -1048,25 +1053,14 @@ 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,
transparent_key_equal>
transparent_unordered_map;
#endif
// test that in the presence of the member function template `erase()`, we still
// invoke the correct iterator overloads when the type is implicitly convertible
//
#ifdef BOOST_UNORDERED_FOA_TESTS
void
#else
transparent_unordered_map::iterator
#endif
map_erase_overload_compile_test()
transparent_unordered_map::iterator map_erase_overload_compile_test()
{
convertible_to_iterator<transparent_unordered_map> c;
transparent_unordered_map map;
@@ -1075,11 +1069,7 @@ map_erase_overload_compile_test()
return map.erase(c);
}
#ifdef BOOST_UNORDERED_FOA_TESTS
void
#else
transparent_unordered_map::const_iterator
#endif
map_erase_const_overload_compile_test()
{
convertible_to_const_iterator<transparent_unordered_map> c;
@@ -1089,7 +1079,6 @@ map_erase_const_overload_compile_test()
return map.erase(c);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef boost::unordered_multimap<int, int, transparent_hasher,
transparent_key_equal>
transparent_unordered_multimap;
@@ -1112,7 +1101,6 @@ multimap_erase_const_overload_compile_test()
pos = c;
return map.erase(c);
}
#endif
template <class UnorderedMap> void test_map_transparent_erase()
{
@@ -1209,25 +1197,14 @@ template <class UnorderedMap> void test_map_non_transparent_erase()
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>
transparent_unordered_set;
typedef boost::unordered_multiset<int, transparent_hasher,
transparent_key_equal>
transparent_unordered_multiset;
#endif
#ifdef BOOST_UNORDERED_FOA_TESTS
void
#else
transparent_unordered_set::iterator
#endif
set_erase_overload_compile_test()
transparent_unordered_set::iterator set_erase_overload_compile_test()
{
convertible_to_iterator<transparent_unordered_set> c;
transparent_unordered_set set;
@@ -1236,11 +1213,7 @@ set_erase_overload_compile_test()
return set.erase(c);
}
#ifdef BOOST_UNORDERED_FOA_TESTS
void
#else
transparent_unordered_set::const_iterator
#endif
set_erase_const_overload_compile_test()
{
convertible_to_const_iterator<transparent_unordered_set> c;
@@ -1250,7 +1223,6 @@ set_erase_const_overload_compile_test()
return set.erase(c);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
transparent_unordered_multiset::iterator multiset_erase_overload_compile_test()
{
convertible_to_iterator<transparent_unordered_multiset> c;
@@ -1269,7 +1241,6 @@ multiset_erase_const_overload_compile_test()
pos = c;
return set.erase(c);
}
#endif
template <class UnorderedSet> void test_set_transparent_erase()
{
@@ -1366,7 +1337,6 @@ template <class UnorderedSet> void test_set_non_transparent_erase()
BOOST_TEST_EQ(key::count_, key_count);
}
#ifndef BOOST_UNORDERED_FOA_TESTS
// test that in the presence of the member function template `extract()`, we
// still invoke the correct iterator overloads when the type is implicitly
// convertible
@@ -1389,11 +1359,9 @@ multimap_extract_const_overload_compile_test()
pos = c;
return map.extract(c);
}
#endif
template <class UnorderedMap> void test_map_transparent_extract()
{
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename UnorderedMap::node_type node_type;
typedef typename UnorderedMap::const_iterator const_iterator;
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
@@ -1429,12 +1397,10 @@ template <class UnorderedMap> void test_map_transparent_extract()
BOOST_TEST(nh.empty());
BOOST_TEST_EQ(key::count_, expected_key_count);
#endif
}
template <class UnorderedMap> void test_map_non_transparent_extract()
{
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename UnorderedMap::node_type node_type;
typedef typename UnorderedMap::const_iterator const_iterator;
typedef std::pair<const_iterator, const_iterator> const_iterator_pair;
@@ -1475,10 +1441,8 @@ template <class UnorderedMap> void test_map_non_transparent_extract()
++key_count;
BOOST_TEST(nh.empty());
BOOST_TEST_EQ(key::count_, key_count);
#endif
}
#ifndef BOOST_UNORDERED_FOA_TESTS
transparent_unordered_set::node_type set_extract_overload_compile_test()
{
convertible_to_iterator<transparent_unordered_set> c;
@@ -1516,11 +1480,9 @@ multiset_extract_const_overload_compile_test()
pos = c;
return set.extract(c);
}
#endif
template <class UnorderedSet> void test_set_transparent_extract()
{
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename UnorderedSet::node_type node_type;
count_reset();
@@ -1564,12 +1526,10 @@ template <class UnorderedSet> void test_set_transparent_extract()
BOOST_TEST_EQ(set.size(), set_size);
BOOST_TEST_EQ(key::count_, expected_key_count);
#endif
}
template <class UnorderedSet> void test_set_non_transparent_extract()
{
#ifndef BOOST_UNORDERED_FOA_TESTS
typedef typename UnorderedSet::node_type node_type;
count_reset();
@@ -1623,22 +1583,13 @@ template <class UnorderedSet> void test_set_non_transparent_extract()
BOOST_TEST_EQ(set.size(), set_size);
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()
{
{
typedef map_type<key, int, transparent_hasher, transparent_key_equal>::type
typedef boost::unordered_map<key, int, transparent_hasher,
transparent_key_equal>
unordered_map;
test_map_transparent_count<unordered_map>();
@@ -1651,7 +1602,7 @@ void test_unordered_map()
{
// non-transparent Hash, non-transparent KeyEqual
//
typedef map_type<key, int, hasher, key_equal>::type unordered_map;
typedef boost::unordered_map<key, int, hasher, key_equal> unordered_map;
test_map_non_transparent_count<unordered_map>();
test_map_non_transparent_find<unordered_map>();
@@ -1663,7 +1614,7 @@ void test_unordered_map()
{
// transparent Hash, non-transparent KeyEqual
//
typedef map_type<key, int, transparent_hasher, key_equal>::type
typedef boost::unordered_map<key, int, transparent_hasher, key_equal>
unordered_map;
test_map_non_transparent_count<unordered_map>();
@@ -1676,7 +1627,7 @@ void test_unordered_map()
{
// non-transparent Hash, transparent KeyEqual
//
typedef map_type<key, int, hasher, transparent_key_equal>::type
typedef boost::unordered_map<key, int, hasher, transparent_key_equal>
unordered_map;
test_map_non_transparent_count<unordered_map>();
@@ -1687,7 +1638,6 @@ void test_unordered_map()
}
}
#ifndef BOOST_UNORDERED_FOA_TESTS
void test_unordered_multimap()
{
{
@@ -1741,21 +1691,11 @@ void test_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()
{
{
typedef set_type<key, transparent_hasher, transparent_key_equal>::type
typedef boost::unordered_set<key, transparent_hasher, transparent_key_equal>
unordered_set;
test_set_transparent_count<unordered_set>();
@@ -1768,7 +1708,7 @@ void test_unordered_set()
{
// non-transparent Hash, non-transparent KeyEqual
//
typedef set_type<key, hasher, key_equal>::type unordered_set;
typedef boost::unordered_set<key, hasher, key_equal> unordered_set;
test_set_non_transparent_count<unordered_set>();
test_set_non_transparent_find<unordered_set>();
@@ -1780,7 +1720,8 @@ void test_unordered_set()
{
// transparent Hash, non-transparent KeyEqual
//
typedef set_type<key, transparent_hasher, key_equal>::type unordered_set;
typedef boost::unordered_set<key, transparent_hasher, key_equal>
unordered_set;
test_set_non_transparent_count<unordered_set>();
test_set_non_transparent_find<unordered_set>();
@@ -1792,7 +1733,8 @@ void test_unordered_set()
{
// non-transparent Hash, transparent KeyEqual
//
typedef set_type<key, hasher, transparent_key_equal>::type unordered_set;
typedef boost::unordered_set<key, hasher, transparent_key_equal>
unordered_set;
test_set_non_transparent_count<unordered_set>();
test_set_non_transparent_find<unordered_set>();
@@ -1802,7 +1744,6 @@ void test_unordered_set()
}
}
#ifndef BOOST_UNORDERED_FOA_TESTS
void test_unordered_multiset()
{
{
@@ -1855,16 +1796,12 @@ void test_unordered_multiset()
test_set_non_transparent_extract<unordered_set>();
}
}
#endif
UNORDERED_AUTO_TEST (transparent_ops) {
test_unordered_map();
test_unordered_set();
#ifndef BOOST_UNORDERED_FOA_TESTS
test_unordered_multimap();
test_unordered_set();
test_unordered_multiset();
#endif
}
RUN_TESTS()