mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Sync from upstream.
This commit is contained in:
@ -31,47 +31,83 @@ environment:
|
||||
B2_VARIANT: debug,release
|
||||
|
||||
matrix:
|
||||
- FLAVOR: Visual Studio 2015
|
||||
- FLAVOR: VS2015 (32 bit)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
B2_TOOLSET: msvc-14.0
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++14
|
||||
- FLAVOR: VS2015 (64 bit)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
B2_TOOLSET: msvc-14.0
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: VS2017 (32 bit, C++14, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++17
|
||||
- FLAVOR: VS2017 (32 bit, C++17, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: Visual Studio 2017, C++latest
|
||||
- FLAVOR: VS2017 (32 bit, C++latest, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: latest
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++11)
|
||||
- FLAVOR: VS2017 (64 bit, C++14, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: VS2017 (64 bit, C++17, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: VS2017 (64 bit, C++latest, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
B2_CXXSTD: latest
|
||||
B2_TOOLSET: msvc-14.1
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: Cygwin (32 bit, C++11, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++14)
|
||||
- FLAVOR: Cygwin (32 bit, C++14, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (32-bit, C++1z)
|
||||
- FLAVOR: Cygwin (32 bit, C++1z, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
ADDPATH: C:\cygwin\bin;
|
||||
B2_ADDRESS_MODEL: 32
|
||||
B2_CXXSTD: 1z
|
||||
B2_TOOLSET: gcc
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++11)
|
||||
- FLAVOR: Cygwin (64 bit, C++11, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
@ -80,74 +116,83 @@ environment:
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++14)
|
||||
- FLAVOR: Cygwin (64 bit, C++14, Debug)
|
||||
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"
|
||||
B2_VARIANT: release
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: cygwin (64-bit, latest, C++1z)
|
||||
- FLAVOR: Cygwin (64 bit, C++17, Release)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 1z
|
||||
B2_CXXSTD: 17
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: release
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++11
|
||||
- FLAVOR: Cygwin (64 bit, C++2a, Debug)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
ADDPATH: C:\cygwin64\bin;
|
||||
B2_ADDRESS_MODEL: 64
|
||||
B2_CXXSTD: 2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_FLAGS: "include=libs/unordered/test/unordered include=libs/unordered/test/exception"
|
||||
B2_VARIANT: debug
|
||||
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++11)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++14
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++14)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++17
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++17)
|
||||
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
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 32 bit, C++2a
|
||||
- FLAVOR: MinGW-w64 (32 bit, C++2a)
|
||||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
ADDPATH: C:\mingw-w64\i686-8.1.0-posix-dwarf-rt_v6-rev0\mingw32\bin;
|
||||
B2_CXXSTD: 2a
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 32
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++11
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++11)
|
||||
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: 11
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++14
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++14)
|
||||
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: 14
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++17
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++17)
|
||||
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
|
||||
B2_TOOLSET: gcc
|
||||
B2_ADDRESS_MODEL: 64
|
||||
|
||||
- FLAVOR: mingw-w64, 64 bit, C++2a
|
||||
- FLAVOR: MinGW-w64 (64 bit, C++2a)
|
||||
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: 2a
|
||||
|
@ -6,6 +6,10 @@
|
||||
:github-pr-url: https://github.com/boostorg/unordered/pull
|
||||
:cpp: C++
|
||||
|
||||
== Release 1.86.0
|
||||
|
||||
* Added container `pmr` aliases when header `<memory_resource>` is available. The alias `boost::unordered::pmr::[container]` refers to `boost::unordered::[container]` with a `std::pmr::polymorphic_allocator` allocator type.
|
||||
|
||||
== Release 1.85.0
|
||||
|
||||
* Optimized `emplace()` for a `value_type` or `init_type` (if applicable) argument to bypass creating an intermediate object. The argument is already the same type as the would-be intermediate object.
|
||||
|
@ -299,6 +299,17 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename concurrent_flat_map<K, T, H, P, A>::size_type
|
||||
xref:#concurrent_flat_map_erase_if_2[erase_if](concurrent_flat_map<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using concurrent_flat_map =
|
||||
boost::concurrent_flat_map<Key, T, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -254,6 +254,16 @@ namespace boost {
|
||||
template<class K, class H, class P, class A, class Predicate>
|
||||
typename concurrent_flat_set<K, H, P, A>::size_type
|
||||
xref:#concurrent_flat_set_erase_if_2[erase_if](concurrent_flat_set<K, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using concurrent_flat_set =
|
||||
boost::concurrent_flat_set<Key, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<Key>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -285,6 +285,17 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_flat_map<K, T, H, P, A>::size_type
|
||||
xref:#unordered_flat_map_erase_if[erase_if](unordered_flat_map<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_flat_map =
|
||||
boost::unordered_flat_map<Key, T, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -238,6 +238,16 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_flat_set<K, T, H, P, A>::size_type
|
||||
xref:#unordered_flat_set_erase_if[erase_if](unordered_flat_set<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_flat_set =
|
||||
boost::unordered_flat_set<Key, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<Key>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -290,6 +290,17 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_map<K, T, H, P, A>::size_type
|
||||
xref:#unordered_map_erase_if[erase_if](unordered_map<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_map =
|
||||
boost::unordered_map<Key, T, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -257,6 +257,17 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_multimap<K, T, H, P, A>::size_type
|
||||
xref:#unordered_multimap_erase_if[erase_if](unordered_multimap<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_multimap =
|
||||
boost::unordered_multimap<Key, T, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -248,6 +248,16 @@ namespace boost {
|
||||
template<class K, class H, class P, class A, class Predicate>
|
||||
typename unordered_multiset<K, H, P, A>::size_type
|
||||
xref:#unordered_multiset_erase_if[erase_if](unordered_multiset<K, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_multiset =
|
||||
boost::unordered_multiset<Key, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<Key>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
`boost::unordered_node_map` — A node-based, open-addressing unordered associative container that associates unique keys with another value.
|
||||
|
||||
`boost::unordered_node_map` uses an open-addressing layout like `boost::unordered_flat_map`, but,
|
||||
being node-based, it provides pointer/iterator stability and node handling functionalities.
|
||||
being node-based, it provides pointer stability and node handling functionalities.
|
||||
Its performance lies between those of `boost::unordered_map` and `boost::unordered_flat_map`.
|
||||
|
||||
As a result of its using open addressing, the interface of `boost::unordered_node_map` deviates in
|
||||
@ -288,6 +288,17 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_node_map<K, T, H, P, A>::size_type
|
||||
xref:#unordered_node_map_erase_if[erase_if](unordered_node_map<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class T,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_node_map =
|
||||
boost::unordered_node_map<Key, T, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T>>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
`boost::unordered_node_set` — A node-based, open-addressing unordered associative container that stores unique values.
|
||||
|
||||
`boost::unordered_node_set` uses an open-addressing layout like `boost::unordered_flat_set`, but,
|
||||
being node-based, it provides pointer/iterator stability and node handling functionalities.
|
||||
being node-based, it provides pointer stability and node handling functionalities.
|
||||
Its performance lies between those of `boost::unordered_set` and `boost::unordered_flat_set`.
|
||||
|
||||
As a result of its using open addressing, the interface of `boost::unordered_node_set` deviates in
|
||||
@ -242,6 +242,16 @@ namespace boost {
|
||||
template<class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_node_set<K, T, H, P, A>::size_type
|
||||
xref:#unordered_node_set_erase_if[erase_if](unordered_node_set<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_node_set =
|
||||
boost::unordered_node_set<Key, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<Key>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -249,6 +249,16 @@ namespace boost {
|
||||
template<class K, class H, class P, class A, class Predicate>
|
||||
typename unordered_set<K, H, P, A>::size_type
|
||||
xref:#unordered_set_erase_if[erase_if](unordered_set<K, H, P, A>& c, Predicate pred);
|
||||
|
||||
// Pmr aliases (C++17 and up)
|
||||
namespace unordered::pmr {
|
||||
template<class Key,
|
||||
class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>>
|
||||
using unordered_set =
|
||||
boost::unordered_set<Key, Hash, Pred,
|
||||
std::pmr::polymorphic_allocator<Key>>;
|
||||
}
|
||||
}
|
||||
-----
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Fast open-addressing concurrent hashmap.
|
||||
*
|
||||
* Copyright 2023 Christian Mazakas.
|
||||
* Copyright 2024 Braden Ganetsky.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
@ -11,11 +12,16 @@
|
||||
#ifndef BOOST_UNORDERED_CONCURRENT_FLAT_MAP_FWD_HPP
|
||||
#define BOOST_UNORDERED_CONCURRENT_FLAT_MAP_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
|
||||
@ -43,6 +49,15 @@ namespace boost {
|
||||
typename concurrent_flat_map<K, T, H, P, A>::size_type erase_if(
|
||||
concurrent_flat_map<K, T, H, P, A>& c, Predicate pred);
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key> >
|
||||
using concurrent_flat_map = boost::unordered::concurrent_flat_map<Key, T,
|
||||
Hash, Pred, std::pmr::polymorphic_allocator<std::pair<Key const, T> > >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::concurrent_flat_map;
|
||||
|
@ -2,6 +2,7 @@
|
||||
*
|
||||
* Copyright 2023 Christian Mazakas.
|
||||
* Copyright 2023 Joaquin M Lopez Munoz.
|
||||
* Copyright 2024 Braden Ganetsky.
|
||||
* 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)
|
||||
@ -12,11 +13,16 @@
|
||||
#ifndef BOOST_UNORDERED_CONCURRENT_FLAT_SET_FWD_HPP
|
||||
#define BOOST_UNORDERED_CONCURRENT_FLAT_SET_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
|
||||
@ -44,6 +50,15 @@ namespace boost {
|
||||
typename concurrent_flat_set<K, H, P, A>::size_type erase_if(
|
||||
concurrent_flat_set<K, H, P, A>& c, Predicate pred);
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key> >
|
||||
using concurrent_flat_set = boost::unordered::concurrent_flat_set<Key,
|
||||
Hash, Pred, std::pmr::polymorphic_allocator<Key> >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::concurrent_flat_set;
|
||||
|
@ -659,12 +659,7 @@ namespace boost {
|
||||
std::swap(buckets, other.buckets);
|
||||
std::swap(groups, other.groups);
|
||||
|
||||
bool b = boost::allocator_propagate_on_container_swap<
|
||||
allocator_type>::type::value;
|
||||
if (b) {
|
||||
boost::core::invoke_swap(
|
||||
get_node_allocator(), other.get_node_allocator());
|
||||
}
|
||||
swap_allocator_if_pocs(other);
|
||||
}
|
||||
|
||||
node_allocator_type const& get_node_allocator() const
|
||||
@ -876,6 +871,27 @@ namespace boost {
|
||||
pbg->prev->next = pbg->next;
|
||||
pbg->prev = pbg->next = group_pointer();
|
||||
}
|
||||
|
||||
void swap_allocator_if_pocs(grouped_bucket_array& other)
|
||||
{
|
||||
using allocator_pocs =
|
||||
typename boost::allocator_propagate_on_container_swap<
|
||||
allocator_type>::type;
|
||||
swap_allocator_if_pocs(
|
||||
other, std::integral_constant<bool, allocator_pocs::value>());
|
||||
}
|
||||
|
||||
void swap_allocator_if_pocs(
|
||||
grouped_bucket_array& other, std::true_type /* propagate */)
|
||||
{
|
||||
boost::core::invoke_swap(
|
||||
get_node_allocator(), other.get_node_allocator());
|
||||
}
|
||||
|
||||
void swap_allocator_if_pocs(
|
||||
grouped_bucket_array&, std::false_type /* don't propagate */)
|
||||
{
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -15,6 +16,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
@ -36,6 +41,16 @@ namespace boost {
|
||||
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)));
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key> >
|
||||
using unordered_flat_map =
|
||||
boost::unordered::unordered_flat_map<Key, T, Hash, KeyEqual,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T> > >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_flat_map;
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -15,6 +16,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
@ -36,6 +41,15 @@ namespace boost {
|
||||
void swap(unordered_flat_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_flat_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)));
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key> >
|
||||
using unordered_flat_set = boost::unordered::unordered_flat_set<Key, Hash,
|
||||
KeyEqual, std::pmr::polymorphic_allocator<Key> >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_flat_set;
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2022-2023 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -16,6 +17,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class K, class T, class H = boost::hash<K>,
|
||||
@ -58,6 +63,20 @@ namespace boost {
|
||||
|
||||
template <class N, class K, class T, class A> class node_handle_map;
|
||||
template <class Iter, class NodeType> struct insert_return_type_map;
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class K, class T, class H = boost::hash<K>,
|
||||
class P = std::equal_to<K> >
|
||||
using unordered_map = boost::unordered::unordered_map<K, T, H, P,
|
||||
std::pmr::polymorphic_allocator<std::pair<const K, T> > >;
|
||||
|
||||
template <class K, class T, class H = boost::hash<K>,
|
||||
class P = std::equal_to<K> >
|
||||
using unordered_multimap = boost::unordered::unordered_multimap<K, T, H,
|
||||
P, std::pmr::polymorphic_allocator<std::pair<const K, T> > >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_map;
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -15,6 +16,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
@ -36,6 +41,16 @@ namespace boost {
|
||||
void swap(unordered_node_map<Key, T, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_node_map<Key, T, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)));
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key> >
|
||||
using unordered_node_map =
|
||||
boost::unordered::unordered_node_map<Key, T, Hash, KeyEqual,
|
||||
std::pmr::polymorphic_allocator<std::pair<const Key, T> > >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_node_map;
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
// Copyright (C) 2023 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -15,6 +16,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
@ -36,6 +41,15 @@ namespace boost {
|
||||
void swap(unordered_node_set<Key, Hash, KeyEqual, Allocator>& lhs,
|
||||
unordered_node_set<Key, Hash, KeyEqual, Allocator>& rhs)
|
||||
noexcept(noexcept(lhs.swap(rhs)));
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class Key, class Hash = boost::hash<Key>,
|
||||
class KeyEqual = std::equal_to<Key> >
|
||||
using unordered_node_set = boost::unordered::unordered_node_set<Key, Hash,
|
||||
KeyEqual, std::pmr::polymorphic_allocator<Key> >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_node_set;
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
@ -16,6 +17,10 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
#include <memory_resource>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class T, class H = boost::hash<T>, class P = std::equal_to<T>,
|
||||
@ -56,6 +61,18 @@ namespace boost {
|
||||
|
||||
template <class N, class T, class A> class node_handle_set;
|
||||
template <class Iter, class NodeType> struct insert_return_type_set;
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
namespace pmr {
|
||||
template <class T, class H = boost::hash<T>, class P = std::equal_to<T> >
|
||||
using unordered_set = boost::unordered::unordered_set<T, H, P,
|
||||
std::pmr::polymorphic_allocator<T> >;
|
||||
|
||||
template <class T, class H = boost::hash<T>, class P = std::equal_to<T> >
|
||||
using unordered_multiset = boost::unordered::unordered_multiset<T, H, P,
|
||||
std::pmr::polymorphic_allocator<T> >;
|
||||
} // namespace pmr
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_multiset;
|
||||
|
@ -122,6 +122,7 @@ local FCA_TESTS =
|
||||
transparent_tests
|
||||
unnecessary_copy_tests
|
||||
fancy_pointer_noleak
|
||||
pmr_allocator_tests
|
||||
;
|
||||
|
||||
for local test in $(FCA_TESTS)
|
||||
@ -229,6 +230,7 @@ local FOA_TESTS =
|
||||
uses_allocator
|
||||
hash_is_avalanching_test
|
||||
fancy_pointer_noleak
|
||||
pmr_allocator_tests
|
||||
;
|
||||
|
||||
for local test in $(FOA_TESTS)
|
||||
@ -338,6 +340,7 @@ local CFOA_TESTS =
|
||||
rw_spinlock_test8
|
||||
reentrancy_check_test
|
||||
explicit_alloc_ctor_tests
|
||||
pmr_allocator_tests
|
||||
;
|
||||
|
||||
for local test in $(CFOA_TESTS)
|
||||
|
@ -8,6 +8,8 @@
|
||||
#define BOOST_UNORDERED_TEST_CFOA_HELPERS_HPP
|
||||
|
||||
#include "../helpers/generators.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include "../helpers/pmr.hpp"
|
||||
#include "../helpers/test.hpp"
|
||||
#include "common_helpers.hpp"
|
||||
|
||||
|
8
test/cfoa/pmr_allocator_tests.cpp
Normal file
8
test/cfoa/pmr_allocator_tests.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// 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)
|
||||
|
||||
#define BOOST_UNORDERED_CFOA_TESTS
|
||||
#include <boost/unordered/concurrent_flat_map.hpp>
|
||||
#include <boost/unordered/concurrent_flat_set.hpp>
|
||||
#include "../unordered/pmr_allocator_tests.cpp"
|
@ -51,6 +51,11 @@ namespace test {
|
||||
static_cast<typename std::iterator_traits<Iterator>::difference_type>(x));
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
using is_map =
|
||||
std::integral_constant<bool, !std::is_same<typename Container::key_type,
|
||||
typename Container::value_type>::value>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
55
test/helpers/pmr.hpp
Normal file
55
test/helpers/pmr.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
// Copyright 2024 Braden Ganetsky.
|
||||
// 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)
|
||||
|
||||
#ifndef BOOST_UNORDERED_TEST_PMR_HEADER
|
||||
#define BOOST_UNORDERED_TEST_PMR_HEADER
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
|
||||
#include <memory_resource>
|
||||
|
||||
namespace test {
|
||||
class counted_new_delete_resource : public std::pmr::memory_resource
|
||||
{
|
||||
public:
|
||||
using std::pmr::memory_resource::memory_resource;
|
||||
~counted_new_delete_resource() override {}
|
||||
|
||||
std::size_t count() const { return _count; }
|
||||
|
||||
private:
|
||||
void* do_allocate(std::size_t bytes, std::size_t alignment) override
|
||||
{
|
||||
_count += bytes;
|
||||
return ::operator new(bytes, std::align_val_t(alignment));
|
||||
}
|
||||
|
||||
void do_deallocate(
|
||||
void* p, std::size_t bytes, std::size_t alignment) override
|
||||
{
|
||||
_count -= bytes;
|
||||
#if __cpp_sized_deallocation
|
||||
::operator delete(p, bytes, std::align_val_t(alignment));
|
||||
#else
|
||||
::operator delete(p, std::align_val_t(alignment));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool do_is_equal(
|
||||
const std::pmr::memory_resource& other) const noexcept override
|
||||
{
|
||||
return this == &other;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t _count = 0;
|
||||
};
|
||||
} // namespace test
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX17_HDR_MEMORY_RESOURCE)
|
||||
|
||||
#endif // !defined(BOOST_UNORDERED_TEST_PMR_HEADER)
|
253
test/unordered/pmr_allocator_tests.cpp
Normal file
253
test/unordered/pmr_allocator_tests.cpp
Normal file
@ -0,0 +1,253 @@
|
||||
//
|
||||
// Copyright 2024 Braden Ganetsky.
|
||||
// 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/helpers.hpp"
|
||||
#include "../helpers/pmr.hpp"
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/unordered.hpp"
|
||||
#include <boost/config/pragma_message.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_NO_CXX17_HDR_MEMORY_RESOURCE
|
||||
|
||||
BOOST_PRAGMA_MESSAGE(
|
||||
"Test skipped because C++17 header <memory_resource> is not available.")
|
||||
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
||||
__MAC_OS_X_VERSION_MIN_REQUIRED < 140000
|
||||
|
||||
BOOST_PRAGMA_MESSAGE(
|
||||
"Test skipped because __MAC_OS_X_VERSION_MIN_REQUIRED < 140000");
|
||||
|
||||
#else
|
||||
|
||||
namespace pmr_allocator_tests {
|
||||
|
||||
using pmr_string = std::basic_string<char, std::char_traits<char>,
|
||||
std::pmr::polymorphic_allocator<char> >;
|
||||
|
||||
#if defined(BOOST_UNORDERED_CFOA_TESTS)
|
||||
static boost::unordered::pmr::concurrent_flat_map<std::string, std::string>*
|
||||
test_string_flat_map;
|
||||
static boost::unordered::pmr::concurrent_flat_map<pmr_string, pmr_string>*
|
||||
test_pmr_string_flat_map;
|
||||
static boost::unordered::pmr::concurrent_flat_set<std::string>*
|
||||
test_string_flat_set;
|
||||
static boost::unordered::pmr::concurrent_flat_set<pmr_string>*
|
||||
test_pmr_string_flat_set;
|
||||
#define PMR_ALLOCATOR_TESTS_ARGS \
|
||||
((test_string_flat_map)(test_pmr_string_flat_map)(test_string_flat_set)(test_pmr_string_flat_set))
|
||||
#elif defined(BOOST_UNORDERED_FOA_TESTS)
|
||||
static boost::unordered::pmr::unordered_flat_map<std::string, std::string>*
|
||||
test_string_flat_map;
|
||||
static boost::unordered::pmr::unordered_flat_map<pmr_string, pmr_string>*
|
||||
test_pmr_string_flat_map;
|
||||
static boost::unordered::pmr::unordered_node_map<std::string, std::string>*
|
||||
test_string_node_map;
|
||||
static boost::unordered::pmr::unordered_node_map<pmr_string, pmr_string>*
|
||||
test_pmr_string_node_map;
|
||||
static boost::unordered::pmr::unordered_flat_set<std::string>*
|
||||
test_string_flat_set;
|
||||
static boost::unordered::pmr::unordered_flat_set<pmr_string>*
|
||||
test_pmr_string_flat_set;
|
||||
static boost::unordered::pmr::unordered_node_set<std::string>*
|
||||
test_string_node_set;
|
||||
static boost::unordered::pmr::unordered_node_set<pmr_string>*
|
||||
test_pmr_string_node_set;
|
||||
#define PMR_ALLOCATOR_TESTS_ARGS \
|
||||
((test_string_flat_map)(test_pmr_string_flat_map)(test_string_node_map)(test_pmr_string_node_map)(test_string_flat_set)(test_pmr_string_flat_set)(test_string_node_set)(test_pmr_string_node_set))
|
||||
#else
|
||||
static boost::unordered::pmr::unordered_map<std::string, std::string>*
|
||||
test_string_map;
|
||||
static boost::unordered::pmr::unordered_map<pmr_string, pmr_string>*
|
||||
test_pmr_string_map;
|
||||
static boost::unordered::pmr::unordered_multimap<std::string, std::string>*
|
||||
test_string_multimap;
|
||||
static boost::unordered::pmr::unordered_multimap<pmr_string, pmr_string>*
|
||||
test_pmr_string_multimap;
|
||||
static boost::unordered::pmr::unordered_set<std::string>* test_string_set;
|
||||
static boost::unordered::pmr::unordered_set<pmr_string>* test_pmr_string_set;
|
||||
static boost::unordered::pmr::unordered_multiset<std::string>*
|
||||
test_string_multiset;
|
||||
static boost::unordered::pmr::unordered_multiset<pmr_string>*
|
||||
test_pmr_string_multiset;
|
||||
#define PMR_ALLOCATOR_TESTS_ARGS \
|
||||
((test_string_map)(test_pmr_string_map)(test_string_multimap)(test_pmr_string_multimap)(test_string_set)(test_pmr_string_set)(test_string_multiset)(test_pmr_string_multiset))
|
||||
#endif
|
||||
|
||||
template <class X>
|
||||
typename std::enable_if<!test::is_map<X>::value, std::size_t>::type
|
||||
emplace_strings(X& x)
|
||||
{
|
||||
std::string_view sv =
|
||||
"this is a string that's longer than the SBO threshold";
|
||||
x.emplace(sv);
|
||||
// Return how many chars were allocated using a pmr allocator
|
||||
return std::is_same<typename X::key_type, pmr_string>::value ? sv.size() + 1
|
||||
: 0;
|
||||
}
|
||||
|
||||
template <class X>
|
||||
typename std::enable_if<test::is_map<X>::value, std::size_t>::type
|
||||
emplace_strings(X& x)
|
||||
{
|
||||
std::string_view key =
|
||||
"this is a string that's longer than the SBO threshold";
|
||||
std::string_view value =
|
||||
"this is another long string that's longer than the SBO threshold";
|
||||
x.emplace(key, value);
|
||||
// Return how many chars were allocated using a pmr allocator
|
||||
return std::is_same<typename X::key_type, pmr_string>::value
|
||||
? key.size() + value.size() + 2
|
||||
: 0;
|
||||
}
|
||||
|
||||
void validate_resource(
|
||||
pmr_string const& str, test::counted_new_delete_resource const& resource)
|
||||
{
|
||||
BOOST_TEST_EQ(str.get_allocator().resource(), &resource);
|
||||
}
|
||||
|
||||
void validate_resource(
|
||||
std::string const&, test::counted_new_delete_resource const&)
|
||||
{
|
||||
// Pass through
|
||||
}
|
||||
|
||||
template <class X>
|
||||
typename std::enable_if<!test::is_map<X>::value>::type validate_resource(
|
||||
X& x, test::counted_new_delete_resource const& resource)
|
||||
{
|
||||
#if defined(BOOST_UNORDERED_CFOA_TESTS)
|
||||
x.cvisit_all(
|
||||
[&resource](auto& element) { validate_resource(element, resource); });
|
||||
#else
|
||||
for (auto& element : x) {
|
||||
validate_resource(element, resource);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X>
|
||||
typename std::enable_if<test::is_map<X>::value>::type validate_resource(
|
||||
X& x, test::counted_new_delete_resource const& resource)
|
||||
{
|
||||
#if defined(BOOST_UNORDERED_CFOA_TESTS)
|
||||
x.cvisit_all([&resource](auto& element) {
|
||||
validate_resource(element.first, resource);
|
||||
validate_resource(element.second, resource);
|
||||
});
|
||||
#else
|
||||
for (auto& element : x) {
|
||||
validate_resource(element.first, resource);
|
||||
validate_resource(element.second, resource);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X> static void pmr_emplace_erase(X*)
|
||||
{
|
||||
using container = X;
|
||||
using allocator_type = typename container::allocator_type;
|
||||
|
||||
test::counted_new_delete_resource resource;
|
||||
|
||||
{
|
||||
allocator_type alloc(&resource);
|
||||
container x(alloc);
|
||||
|
||||
std::size_t num_chars = emplace_strings(x);
|
||||
BOOST_TEST_EQ(x.size(), 1);
|
||||
std::size_t count_after_emplace = resource.count();
|
||||
BOOST_TEST_GT(count_after_emplace,
|
||||
num_chars + sizeof(typename container::value_type));
|
||||
|
||||
validate_resource(x, resource);
|
||||
|
||||
x.clear();
|
||||
BOOST_TEST_LE(resource.count(), count_after_emplace);
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ(resource.count(), 0);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
UNORDERED_TEST(
|
||||
pmr_emplace_erase,
|
||||
PMR_ALLOCATOR_TESTS_ARGS
|
||||
)
|
||||
|
||||
// clang-format on
|
||||
|
||||
enum operation
|
||||
{
|
||||
copy_op,
|
||||
move_op,
|
||||
swap_op,
|
||||
};
|
||||
|
||||
template <class X> void do_operation(X& x1, X& x2, operation op)
|
||||
{
|
||||
switch (op) {
|
||||
case copy_op:
|
||||
x2 = x1;
|
||||
return;
|
||||
case move_op:
|
||||
x2 = std::move(x1);
|
||||
return;
|
||||
case swap_op:
|
||||
x1.swap(x1); // Swapping with non-equal non-pocs allocators is UB
|
||||
return;
|
||||
default:
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
}
|
||||
|
||||
template <class X> static void pmr_no_propagate_on_operation(X*, operation op)
|
||||
{
|
||||
using container = X;
|
||||
using allocator_type = typename container::allocator_type;
|
||||
BOOST_STATIC_ASSERT(
|
||||
!std::allocator_traits<
|
||||
allocator_type>::propagate_on_container_copy_assignment::value);
|
||||
BOOST_STATIC_ASSERT(
|
||||
!std::allocator_traits<
|
||||
allocator_type>::propagate_on_container_move_assignment::value);
|
||||
BOOST_STATIC_ASSERT(!std::allocator_traits<
|
||||
allocator_type>::propagate_on_container_swap::value);
|
||||
|
||||
test::counted_new_delete_resource resource1;
|
||||
test::counted_new_delete_resource resource2;
|
||||
|
||||
allocator_type alloc1(&resource1);
|
||||
allocator_type alloc2(&resource2);
|
||||
|
||||
container x1(alloc1);
|
||||
container x2(alloc2);
|
||||
bool allocators_not_equal = x1.get_allocator() != x2.get_allocator();
|
||||
BOOST_TEST(allocators_not_equal);
|
||||
|
||||
emplace_strings(x1);
|
||||
do_operation(x1, x2, op);
|
||||
allocators_not_equal = x1.get_allocator() != x2.get_allocator();
|
||||
BOOST_TEST(allocators_not_equal);
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
|
||||
UNORDERED_TEST(
|
||||
pmr_no_propagate_on_operation,
|
||||
PMR_ALLOCATOR_TESTS_ARGS
|
||||
((copy_op)(move_op)(swap_op))
|
||||
)
|
||||
|
||||
// clang-format on
|
||||
|
||||
} // namespace pmr_allocator_tests
|
||||
|
||||
#endif
|
||||
|
||||
RUN_TESTS()
|
Reference in New Issue
Block a user