forked from boostorg/unordered
Compare commits
45 Commits
feature/ms
...
feature/cx
Author | SHA1 | Date | |
---|---|---|---|
cdda5247a4 | |||
c58a633d1f | |||
4ac18e67ad | |||
0de4dca1b3 | |||
dd8806c8c0 | |||
7232fe793b | |||
aa32843628 | |||
858503b86a | |||
f7bcf9a3dd | |||
b61c5614eb | |||
96170d56a9 | |||
10b4aaa13e | |||
a56945894a | |||
5f68c0f8dd | |||
db3824c956 | |||
5439279300 | |||
75303f438c | |||
4d4dcbbb67 | |||
6f4e833e43 | |||
854308c9cc | |||
3e05333b63 | |||
3ebdc9730c | |||
f5e6804869 | |||
27b0d5fb53 | |||
355815327c | |||
1a42d1aaa7 | |||
e2f53f8c38 | |||
0fcece193f | |||
bf698adbe5 | |||
49b5d36836 | |||
ac17b00db5 | |||
0fa3942782 | |||
7fe4eb1d15 | |||
7eb6a011c1 | |||
95f5dba6f6 | |||
14e8c2418c | |||
30a05c39da | |||
27f1f6d841 | |||
fdc5cc83ff | |||
dc48210c2a | |||
32c2fde321 | |||
451b74d956 | |||
254e47ca52 | |||
0b40137335 | |||
552224888c |
36
.github/workflows/ci.yml
vendored
36
.github/workflows/ci.yml
vendored
@ -57,10 +57,16 @@ jobs:
|
||||
- { compiler: gcc-9, cxxstd: '03,11,14,17', os: 'ubuntu-22.04', install: 'g++-9' }
|
||||
- { compiler: gcc-10, cxxstd: '03,11,14,17,20', os: 'ubuntu-22.04', install: 'g++-10' }
|
||||
- { compiler: gcc-11, cxxstd: '03,11,14,17,20', os: 'ubuntu-22.04', install: 'g++-11' }
|
||||
- { name: "gcc-12 w/ sanitizers (03,11,14)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '03,11,14', os: 'ubuntu-22.04', ccache_key: "san1" }
|
||||
- { name: "gcc-12 w/ sanitizers (17,20,2b)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '17,20,2b', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "gcc-12 w/ sanitizers (03,11)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '03,11', os: 'ubuntu-22.04', ccache_key: "san1" }
|
||||
- { name: "gcc-12 w/ sanitizers (14)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '14', os: 'ubuntu-22.04', ccache_key: "san1" }
|
||||
- { name: "gcc-12 w/ sanitizers (17)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '17', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "gcc-12 w/ sanitizers (20)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '20', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "gcc-12 w/ sanitizers (2b)", sanitize: yes,
|
||||
compiler: gcc-12, cxxstd: '2b', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: Collect coverage, coverage: yes,
|
||||
compiler: gcc-12, cxxstd: '03,20', os: 'ubuntu-22.04', install: 'g++-12-multilib', address-model: '32,64', ccache_key: "cov" }
|
||||
|
||||
@ -74,21 +80,31 @@ jobs:
|
||||
# clang-12 doesn't work on 'ubuntu-22.04', the linker can't find -lunwind for some reason
|
||||
- { name: "clang-12 w/ sanitizers (03,11,14)", sanitize: yes,
|
||||
compiler: clang-12, cxxstd: '03,11,14', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san1" }
|
||||
- { name: "clang-12 w/ sanitizers (17,20,2b)", sanitize: yes,
|
||||
compiler: clang-12, cxxstd: '17,20,2b', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" }
|
||||
- { compiler: clang-13, cxxstd: '03,11,14,17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' }
|
||||
- { name: "clang-12 w/ sanitizers (17)", sanitize: yes,
|
||||
compiler: clang-12, cxxstd: '17', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" }
|
||||
- { name: "clang-12 w/ sanitizers (20)", sanitize: yes,
|
||||
compiler: clang-12, cxxstd: '20', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" }
|
||||
- { name: "clang-12 w/ sanitizers (2b)", sanitize: yes,
|
||||
compiler: clang-12, cxxstd: '2b', os: 'ubuntu-20.04', stdlib: libc++, install: 'clang-12 libc++-12-dev libc++abi-12-dev', ccache_key: "san2" }
|
||||
- { compiler: 'clang-13', cxxstd: '03,11,14', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' }
|
||||
- { compiler: 'clang-13', cxxstd: '17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-13 libc++-13-dev libc++abi-13-dev' }
|
||||
|
||||
# not using libc++ because of https://github.com/llvm/llvm-project/issues/52771
|
||||
- { name: "clang-14 w/ sanitizers (03,11,14)", sanitize: yes,
|
||||
compiler: clang-14, cxxstd: '03,11,14', os: 'ubuntu-22.04', ccache_key: "san1" }
|
||||
- { name: "clang-14 w/ sanitizers (17,20,2b)", sanitize: yes,
|
||||
compiler: clang-14, cxxstd: '17,20,2b', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "clang-14 w/ sanitizers (17)", sanitize: yes,
|
||||
compiler: clang-14, cxxstd: '17', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "clang-14 w/ sanitizers (20)", sanitize: yes,
|
||||
compiler: clang-14, cxxstd: '20', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
- { name: "clang-14 w/ sanitizers (2b)", sanitize: yes,
|
||||
compiler: clang-14, cxxstd: '2b', os: 'ubuntu-22.04', ccache_key: "san2" }
|
||||
|
||||
- { name: "cfoa tsan (clang-14)", cxxstd: '11,14,17,20,2b', os: 'ubuntu-22.04', compiler: clang-14,
|
||||
targets: 'libs/unordered/test//cfoa_tests', thread-sanitize: yes,
|
||||
stdlib: libc++, install: 'clang-14 libc++-14-dev libc++abi-14-dev', ccache_key: "tsan" }
|
||||
|
||||
- { compiler: clang-15, cxxstd: '03,11,14,17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' }
|
||||
- { compiler: 'clang-15', cxxstd: '03,11,14', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' }
|
||||
- { compiler: 'clang-15', cxxstd: '17,20,2b', os: 'ubuntu-22.04', stdlib: libc++, install: 'clang-15 libc++-15-dev libc++abi-15-dev' }
|
||||
|
||||
# OSX, clang
|
||||
- { compiler: clang, cxxstd: '03,11,14,17,2a', os: 'macos-11' }
|
||||
|
@ -18,6 +18,8 @@ a concurrent container from user code.
|
||||
* Added Boost.Serialization support to all containers and their (non-local) iterator types.
|
||||
* Added support for fancy pointers to open-addressing and concurrent containers.
|
||||
This enables scenarios like the use of Boost.Interprocess allocators to construct containers in shared memory.
|
||||
* Starting with this release, `boost::unordered_[multi]set` and `boost::unordered_[multi]map`
|
||||
only work with C++11 onwards.
|
||||
|
||||
== Release 1.83.0 - Major update
|
||||
|
||||
|
@ -7,116 +7,54 @@
|
||||
|
||||
== Closed-addressing Containers
|
||||
|
||||
`unordered_[multi]set` and `unordered_[multi]map` are intended to provide a conformant
|
||||
implementation of the {cpp}20 standard that will work with {cpp}98 upwards.
|
||||
This wide compatibility does mean some compromises have to be made.
|
||||
With a compiler and library that fully support {cpp}11, the differences should
|
||||
be minor.
|
||||
`boost::unordered_[multi]set` and `boost::unordered_[multi]map` provide a conformant
|
||||
implementation for {cpp}11 (or later) compilers of the latest standard revision of
|
||||
{cpp} unordered associative containers, with very minor deviations as noted.
|
||||
The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^]
|
||||
and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^].
|
||||
|
||||
=== Move Emulation
|
||||
=== Deduction Guides
|
||||
|
||||
Support for move semantics is implemented using Boost.Move. If rvalue
|
||||
references are available it will use them, but if not it uses a close,
|
||||
but imperfect emulation. On such compilers:
|
||||
Deduction guides for
|
||||
https://en.cppreference.com/w/cpp/language/class_template_argument_deduction[class template argument deduction (CTAD)^]
|
||||
are only available on {cpp}17 (or later) compilers.
|
||||
|
||||
* Non-copyable objects can be stored in the containers.
|
||||
They can be constructed in place using `emplace`, or if they support
|
||||
Boost.Move, moved into place.
|
||||
* The containers themselves are not movable.
|
||||
* Argument forwarding is not perfect.
|
||||
=== Piecewise Pair Emplacement
|
||||
|
||||
=== Use of Allocators
|
||||
|
||||
{cpp}11 introduced a new allocator system. It's backwards compatible due to
|
||||
the lax requirements for allocators in the old standard, but might need
|
||||
some changes for allocators which worked with the old versions of the
|
||||
unordered containers.
|
||||
It uses a traits class, `allocator_traits` to handle the allocator
|
||||
adding extra functionality, and making some methods and types optional.
|
||||
During development a stable release of
|
||||
`allocator_traits` wasn't available so an internal partial implementation
|
||||
is always used in this version. Hopefully a future version will use the
|
||||
standard implementation where available.
|
||||
|
||||
The member functions `construct`, `destroy` and `max_size` are now
|
||||
optional, if they're not available a fallback is used.
|
||||
A full implementation of `allocator_traits` requires sophisticated
|
||||
member function detection so that the fallback is used whenever the
|
||||
member function call is not well formed.
|
||||
This requires support for SFINAE expressions, which are available on
|
||||
GCC from version 4.4 and Clang.
|
||||
|
||||
On other compilers, there's just a test to see if the allocator has
|
||||
a member, but no check that it can be called. So rather than using a
|
||||
fallback there will just be a compile error.
|
||||
|
||||
`propagate_on_container_copy_assignment`,
|
||||
`propagate_on_container_move_assignment`,
|
||||
`propagate_on_container_swap` and
|
||||
`select_on_container_copy_construction` are also supported.
|
||||
Due to imperfect move emulation, some assignments might check
|
||||
`propagate_on_container_copy_assignment` on some compilers and
|
||||
`propagate_on_container_move_assignment` on others.
|
||||
|
||||
=== Construction/Destruction Using Allocators
|
||||
|
||||
The following support is required for full use of {cpp}11 style
|
||||
construction/destruction:
|
||||
|
||||
* Variadic templates.
|
||||
* Piecewise construction of `std::pair`.
|
||||
* Either `std::allocator_traits` or expression SFINAE.
|
||||
|
||||
This is detected using Boost.Config. The macro
|
||||
`BOOST_UNORDERED_CXX11_CONSTRUCTION` will be set to 1 if it is found, or 0
|
||||
otherwise.
|
||||
|
||||
When this is the case `allocator_traits::construct` and
|
||||
`allocator_traits::destroy` will always be used, apart from when piecewise
|
||||
constructing a `std::pair` using `boost::tuple` (see <<compliance_pairs,below>>), but that should be easily avoided.
|
||||
|
||||
When support is not available `allocator_traits::construct` and
|
||||
`allocator_traits::destroy` are never called.
|
||||
|
||||
=== Pointer Traits
|
||||
|
||||
`pointer_traits` aren't used. Instead, pointer types are obtained from
|
||||
rebound allocators, this can cause problems if the allocator can't be
|
||||
used with incomplete types. If `const_pointer` is not defined in the
|
||||
allocator, `boost::pointer_to_other<pointer, const value_type>::type`
|
||||
is used to obtain a const pointer.
|
||||
|
||||
=== Pairs
|
||||
|
||||
Since the containers use `std::pair` they're limited to the version
|
||||
from the current standard library. But since {cpp}11 ``std::pair``'s
|
||||
`piecewise_construct` based constructor is very useful, `emplace`
|
||||
emulates it with a `piecewise_construct` in the `boost::unordered`
|
||||
namespace. So for example, the following will work:
|
||||
In accordance with the standard specification,
|
||||
`boost::unordered_[multi]map::emplace` supports piecewise pair construction:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
boost::unordered_multimap<std::string, std::complex> x;
|
||||
|
||||
x.emplace(
|
||||
std::piecewise_construct,
|
||||
std::make_tuple("key"), std::make_tuple(1, 2));
|
||||
----
|
||||
|
||||
Additionally, the same
|
||||
functionality is provided via non-standard `boost::unordered::piecewise_construct`
|
||||
and Boost.Tuple:
|
||||
|
||||
[source,c++]
|
||||
----
|
||||
x.emplace(
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple("key"), boost::make_tuple(1, 2));
|
||||
----
|
||||
|
||||
Older drafts of the standard also supported variadic constructors
|
||||
for `std::pair`, where the first argument would be used for the
|
||||
first part of the pair, and the remaining for the second part.
|
||||
This feature has been retained for backwards compatibility with
|
||||
previous versions of Boost.Unordered: users are encouraged to
|
||||
update their code to use `std::piecewise_construct` and
|
||||
``std::tuple``s instead.
|
||||
|
||||
=== Miscellaneous
|
||||
=== Swap
|
||||
|
||||
When swapping, `Pred` and `Hash` are not currently swapped by calling
|
||||
`swap`, their copy constructors are used. As a consequence when swapping
|
||||
`swap`, their copy constructors are used. As a consequence, when swapping
|
||||
an exception may be thrown from their copy constructor.
|
||||
|
||||
Variadic constructor arguments for `emplace` are only used when both
|
||||
rvalue references and variadic template parameters are available.
|
||||
Otherwise `emplace` can only take up to 10 constructors arguments.
|
||||
|
||||
== Open-addressing Containers
|
||||
|
||||
The C++ standard does not currently provide any open-addressing container
|
||||
@ -129,7 +67,9 @@ radically different from that imposed by the standard (closed addressing).
|
||||
Open-addressing containers provided by Boost.Unordered only work with reasonably
|
||||
compliant C++11 (or later) compilers. Language-level features such as move semantics
|
||||
and variadic template parameters are then not emulated.
|
||||
The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^].
|
||||
The containers are fully https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^]
|
||||
and support https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers^].
|
||||
|
||||
|
||||
The main differences with C++ unordered associative containers are:
|
||||
|
||||
@ -156,7 +96,9 @@ due to their inherent problems in concurrent scenarios (high contention, prone t
|
||||
so, Boost.Unordered concurrent containers are technically not models of
|
||||
https://en.cppreference.com/w/cpp/named_req/Container[Container^], although
|
||||
they meet all the requirements of https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer[AllocatorAware^]
|
||||
containers except those implying iterators.
|
||||
containers (including
|
||||
https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointer^] support)
|
||||
except those implying iterators.
|
||||
|
||||
In a non-concurrent unordered container, iterators serve two main purposes:
|
||||
|
||||
|
@ -1045,13 +1045,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
unlike xref:#concurrent_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -1093,13 +1093,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first four overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// last two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
Invalidates pointers and references to elements if a rehashing is issued.
|
||||
@ -1121,19 +1121,19 @@ template<class K, class M> bool insert_or_assign(K&& k, M&& obj);
|
||||
|
||||
Inserts a new element into the table or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the table as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
|
@ -909,13 +909,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
unlike xref:#unordered_flat_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -954,13 +954,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
unlike xref:#unordered_flat_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -985,19 +985,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
@ -1023,19 +1023,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
`hint` is a suggestion to where the element should be inserted. This implementation ignores it.
|
||||
|
@ -26,12 +26,12 @@ namespace boost {
|
||||
using hasher = Hash;
|
||||
using key_equal = Pred;
|
||||
using allocator_type = Allocator;
|
||||
using pointer = typename boost::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = _implementation-defined_;
|
||||
using difference_type = _implementation-defined_;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
@ -316,6 +316,7 @@ namespace boost {
|
||||
|
||||
|_Allocator_
|
||||
|An allocator whose value type is the same as the container's value type.
|
||||
Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported.
|
||||
|
||||
|===
|
||||
|
||||
@ -332,47 +333,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84.
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
----
|
||||
|
||||
`value_type*` if `allocator_type::pointer` is not defined.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
----
|
||||
|
||||
`boost::pointer_to_other<pointer, value_type>::type` if `allocator_type::const_pointer` is not defined.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ size_type;
|
||||
----
|
||||
|
||||
An unsigned integral type.
|
||||
|
||||
`size_type` can represent any non-negative value of `difference_type`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ difference_type;
|
||||
----
|
||||
|
||||
A signed integral type.
|
||||
|
||||
Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ iterator;
|
||||
@ -424,7 +384,8 @@ A const_local_iterator object can be used to iterate through a single bucket.
|
||||
typedef _implementation-defined_ node_type;
|
||||
----
|
||||
|
||||
See node_handle_map for details.
|
||||
A class for holding extracted container elements, modelling
|
||||
https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle].
|
||||
|
||||
---
|
||||
|
||||
@ -433,7 +394,20 @@ See node_handle_map for details.
|
||||
typedef _implementation-defined_ insert_return_type;
|
||||
----
|
||||
|
||||
Structure returned by inserting node_type.
|
||||
A specialization of an internal class template:
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
template<class Iterator, class NodeType>
|
||||
struct _insert_return_type_ // name is exposition only
|
||||
{
|
||||
Iterator position;
|
||||
bool inserted;
|
||||
NodeType node;
|
||||
};
|
||||
----
|
||||
|
||||
with `Iterator` = `iterator` and `NodeType` = `node_type`.
|
||||
|
||||
---
|
||||
|
||||
@ -513,10 +487,7 @@ The move constructor.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; This is implemented using Boost.Move.
|
||||
Requires:;; `value_type` is move-constructible. +
|
||||
+
|
||||
On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable.
|
||||
So, for example, you can't return the container from a function.
|
||||
Requires:;; `value_type` is move-constructible.
|
||||
|
||||
---
|
||||
|
||||
@ -716,7 +687,6 @@ The move assignment operator.
|
||||
If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances.
|
||||
Requires:;; `value_type` is move constructible.
|
||||
|
||||
---
|
||||
@ -827,11 +797,7 @@ If an insert took place, then the iterator points to the newly inserted element.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -852,11 +818,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p
|
||||
+
|
||||
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -1034,13 +996,13 @@ Notes:;; This function is similiar to xref:#unordered_map_emplace[emplace] excep
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
instead of xref:#unordered_map_emplace[emplace] which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -1050,10 +1012,6 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
The `template<class K, class\... Args>` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type.
|
||||
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics.
|
||||
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
--
|
||||
|
||||
---
|
||||
@ -1083,13 +1041,13 @@ Notes:;; This function is similiar to xref:#unordered_map_emplace_hint[emplace_h
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
instead of xref:#unordered_map_emplace_hint[emplace_hint] which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -1101,10 +1059,6 @@ Can invalidate iterators, but only if the insert causes the load factor to be gr
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
The `template<class K, class\... Args>` overload only participates in overload resolution if `Hash::is_transparent` and `Pred::is_transparent` are valid member typedefs and neither `iterator` nor `const_iterator` are implicitly convertible from `K`. The library assumes that `Hash` is callable with both `K` and `Key` and that `Pred` is transparent. This enables heterogeneous lookup which avoids the cost of instantiating an instance of the `Key` type.
|
||||
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics.
|
||||
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
--
|
||||
|
||||
---
|
||||
@ -1121,19 +1075,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
@ -1161,19 +1115,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
`hint` is a suggestion to where the element should be inserted.
|
||||
@ -1766,9 +1720,7 @@ template<class Key, class T, class Hash, class Pred, class Alloc>
|
||||
Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
@ -1782,9 +1734,7 @@ template<class Key, class T, class Hash, class Pred, class Alloc>
|
||||
Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
=== Swap
|
||||
```c++
|
||||
|
@ -26,12 +26,12 @@ namespace boost {
|
||||
using hasher = Hash;
|
||||
using key_equal = Pred;
|
||||
using allocator_type = Allocator;
|
||||
using pointer = typename boost::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = _implementation-defined_;
|
||||
using difference_type = _implementation-defined_;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
@ -283,6 +283,7 @@ namespace boost {
|
||||
|
||||
|_Allocator_
|
||||
|An allocator whose value type is the same as the container's value type.
|
||||
Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported.
|
||||
|
||||
|===
|
||||
|
||||
@ -299,47 +300,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84.
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
----
|
||||
|
||||
`value_type*` if `allocator_type::pointer` is not defined.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
----
|
||||
|
||||
`boost::pointer_to_other<pointer, value_type>::type` if `allocator_type::const_pointer` is not defined.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ size_type;
|
||||
----
|
||||
|
||||
An unsigned integral type.
|
||||
|
||||
`size_type` can represent any non-negative value of `difference_type`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ difference_type;
|
||||
----
|
||||
|
||||
A signed integral type.
|
||||
|
||||
Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ iterator;
|
||||
@ -471,10 +431,7 @@ The move constructor.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; This is implemented using Boost.Move.
|
||||
Requires:;; `value_type` is move-constructible. +
|
||||
+
|
||||
On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable.
|
||||
So, for example, you can't return the container from a function.
|
||||
Requires:;; `value_type` is move-constructible.
|
||||
|
||||
---
|
||||
|
||||
@ -673,7 +630,6 @@ The move assignment operator.
|
||||
If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances.
|
||||
Requires:;; `value_type` is move constructible.
|
||||
|
||||
---
|
||||
@ -782,11 +738,7 @@ Returns:;; An iterator pointing to the inserted element.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -807,11 +759,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p
|
||||
+
|
||||
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -1493,9 +1441,7 @@ template<class Key, class T, class Hash, class Pred, class Alloc>
|
||||
Return `true` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
@ -1509,9 +1455,7 @@ template<class Key, class T, class Hash, class Pred, class Alloc>
|
||||
Return `false` if `x.size() == y.size()` and for every equivalent key group in `x`, there is a group in `y` for the same key, which is a permutation (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
|
@ -24,12 +24,12 @@ namespace boost {
|
||||
using hasher = Hash;
|
||||
using key_equal = Pred;
|
||||
using allocator_type = Allocator;
|
||||
using pointer = typename boost::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = _implementation-defined_;
|
||||
using difference_type = _implementation-defined_;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
@ -271,6 +271,7 @@ namespace boost {
|
||||
|
||||
|_Allocator_
|
||||
|An allocator whose value type is the same as the container's value type.
|
||||
Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported.
|
||||
|
||||
|===
|
||||
|
||||
@ -287,46 +288,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84.
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
----
|
||||
|
||||
`value_type*` if `allocator_type::pointer` is not defined.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
----
|
||||
|
||||
`boost::pointer_to_other<pointer, value_type>::type` if `allocator_type::const_pointer` is not defined.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ size_type;
|
||||
----
|
||||
|
||||
An unsigned integral type.
|
||||
|
||||
`size_type` can represent any non-negative value of `difference_type`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ difference_type;
|
||||
----
|
||||
|
||||
A signed integral type.
|
||||
|
||||
Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ iterator;
|
||||
@ -458,10 +419,7 @@ The move constructor.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; This is implemented using Boost.Move.
|
||||
Requires:;; `value_type` is move-constructible. +
|
||||
+
|
||||
On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable.
|
||||
So, for example, you can't return the container from a function.
|
||||
Requires:;; `value_type` is move-constructible.
|
||||
|
||||
---
|
||||
|
||||
@ -661,7 +619,6 @@ The move assignment operator.
|
||||
If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances.
|
||||
Requires:;; `value_type` is move constructible.
|
||||
|
||||
---
|
||||
@ -772,11 +729,7 @@ Returns:;; An iterator pointing to the inserted element.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -797,11 +750,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p
|
||||
+
|
||||
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -1424,9 +1373,7 @@ template<class Key, class Hash, class Pred, class Alloc>
|
||||
Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
@ -1440,9 +1387,7 @@ template<class Key, class Hash, class Pred, class Alloc>
|
||||
Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
|
@ -962,13 +962,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
unlike xref:#unordered_node_map_emplace[emplace], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -1007,13 +1007,13 @@ if there is an element with an equivalent key; otherwise, the construction is of
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<Args>(args)...))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<Args>(args)...))
|
||||
```
|
||||
|
||||
unlike xref:#unordered_node_map_emplace_hint[emplace_hint], which simply forwards all arguments to ``value_type``'s constructor.
|
||||
@ -1038,19 +1038,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
[horizontal]
|
||||
@ -1076,19 +1076,19 @@ template<class K, class M>
|
||||
|
||||
Inserts a new element into the container or updates an existing one by assigning to the contained value.
|
||||
|
||||
If there is an element with key `k`, then it is updated by assigning `boost::forward<M>(obj)`.
|
||||
If there is an element with key `k`, then it is updated by assigning `std::forward<M>(obj)`.
|
||||
|
||||
If there is no such element, it is added to the container as:
|
||||
```c++
|
||||
// first two overloads
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<Key>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<Key>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
|
||||
// third overload
|
||||
value_type(std::piecewise_construct,
|
||||
std::forward_as_tuple(boost::forward<K>(k)),
|
||||
std::forward_as_tuple(boost::forward<M>(obj)))
|
||||
std::forward_as_tuple(std::forward<K>(k)),
|
||||
std::forward_as_tuple(std::forward<M>(obj)))
|
||||
```
|
||||
|
||||
`hint` is a suggestion to where the element should be inserted. This implementation ignores it.
|
||||
|
@ -24,12 +24,12 @@ namespace boost {
|
||||
using hasher = Hash;
|
||||
using key_equal = Pred;
|
||||
using allocator_type = Allocator;
|
||||
using pointer = typename boost::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename boost::allocator_traits<Allocator>::const_pointer;
|
||||
using pointer = typename std::allocator_traits<Allocator>::pointer;
|
||||
using const_pointer = typename std::allocator_traits<Allocator>::const_pointer;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = _implementation-defined_;
|
||||
using difference_type = _implementation-defined_;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
|
||||
using iterator = _implementation-defined_;
|
||||
using const_iterator = _implementation-defined_;
|
||||
@ -272,6 +272,7 @@ namespace boost {
|
||||
|
||||
|_Allocator_
|
||||
|An allocator whose value type is the same as the container's value type.
|
||||
Allocators using https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers[fancy pointers] are supported.
|
||||
|
||||
|===
|
||||
|
||||
@ -288,47 +289,6 @@ a Boost.Serialization archive with a version of Boost prior to Boost 1.84.
|
||||
|
||||
=== Typedefs
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::pointer pointer;
|
||||
----
|
||||
|
||||
`value_type*` if `allocator_type::pointer` is not defined.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef typename allocator_type::const_pointer const_pointer;
|
||||
----
|
||||
|
||||
`boost::pointer_to_other<pointer, value_type>::type` if `allocator_type::const_pointer` is not defined.
|
||||
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ size_type;
|
||||
----
|
||||
|
||||
An unsigned integral type.
|
||||
|
||||
`size_type` can represent any non-negative value of `difference_type`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ difference_type;
|
||||
----
|
||||
|
||||
A signed integral type.
|
||||
|
||||
Is identical to the difference type of `iterator` and `const_iterator`.
|
||||
|
||||
---
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
typedef _implementation-defined_ iterator;
|
||||
@ -380,7 +340,8 @@ A const_local_iterator object can be used to iterate through a single bucket.
|
||||
typedef _implementation-defined_ node_type;
|
||||
----
|
||||
|
||||
See node_handle_set for details.
|
||||
A class for holding extracted container elements, modelling
|
||||
https://en.cppreference.com/w/cpp/container/node_handle[NodeHandle].
|
||||
|
||||
---
|
||||
|
||||
@ -389,7 +350,20 @@ See node_handle_set for details.
|
||||
typedef _implementation-defined_ insert_return_type;
|
||||
----
|
||||
|
||||
Structure returned by inserting node_type.
|
||||
A specialization of an internal class template:
|
||||
|
||||
[source,c++,subs=+quotes]
|
||||
----
|
||||
template<class Iterator, class NodeType>
|
||||
struct _insert_return_type_ // name is exposition only
|
||||
{
|
||||
Iterator position;
|
||||
bool inserted;
|
||||
NodeType node;
|
||||
};
|
||||
----
|
||||
|
||||
with `Iterator` = `iterator` and `NodeType` = `node_type`.
|
||||
|
||||
---
|
||||
|
||||
@ -469,10 +443,7 @@ The move constructor.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; This is implemented using Boost.Move.
|
||||
Requires:;; `value_type` is move-constructible. +
|
||||
+
|
||||
On compilers without rvalue reference support the emulation does not support moving without calling `boost::move` if `value_type` is not copyable.
|
||||
So, for example, you can't return the container from a function.
|
||||
Requires:;; `value_type` is move-constructible.
|
||||
|
||||
---
|
||||
|
||||
@ -672,7 +643,6 @@ The move assignment operator.
|
||||
If `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`, the allocator is overwritten, if not the moved elements are created using the existing allocator.
|
||||
|
||||
[horizontal]
|
||||
Notes:;; On compilers without rvalue references, this is emulated using Boost.Move. Note that on some compilers the copy assignment operator may be used in some circumstances.
|
||||
Requires:;; `value_type` is move constructible.
|
||||
|
||||
---
|
||||
@ -785,11 +755,7 @@ If an insert took place, then the iterator points to the newly inserted element.
|
||||
Throws:;; If an exception is thrown by an operation other than a call to `hasher` the function has no effect.
|
||||
Notes:;; Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to `10` arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -810,11 +776,7 @@ Notes:;; The standard is fairly vague on the meaning of the hint. But the only p
|
||||
+
|
||||
Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor. +
|
||||
+
|
||||
Pointers and references to elements are never invalidated. +
|
||||
+
|
||||
If the compiler doesn't support variadic template arguments or rvalue references, this is emulated for up to 10 arguments, with no support for rvalue references or move semantics. +
|
||||
+
|
||||
Since existing `std::pair` implementations don't support `std::piecewise_construct` this emulates it, but using `boost::unordered::piecewise_construct`.
|
||||
Pointers and references to elements are never invalidated.
|
||||
|
||||
---
|
||||
|
||||
@ -1489,9 +1451,7 @@ template<class Key, class Hash, class Pred, class Alloc>
|
||||
Return `true` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
@ -1505,9 +1465,7 @@ template<class Key, class Hash, class Pred, class Alloc>
|
||||
Return `false` if `x.size() == y.size()` and for every element in `x`, there is an element in `y` with the same key, with an equal value (using `operator==` to compare the value types).
|
||||
|
||||
[horizontal]
|
||||
Notes:;; The behavior of this function was changed to match the C++11 standard in Boost 1.48. +
|
||||
+
|
||||
Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
Notes:;; Behavior is undefined if the two containers don't have equivalent equality predicates.
|
||||
|
||||
---
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
@ -65,9 +64,9 @@ namespace boost {
|
||||
using init_type = typename type_policy::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = typename boost::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::type_identity<Pred>::type;
|
||||
using allocator_type = typename boost::type_identity<Allocator>::type;
|
||||
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::unordered::detail::type_identity<Pred>::type;
|
||||
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
@ -757,8 +756,8 @@ namespace boost {
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Hash = boost::hash<std::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<std::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
@ -766,7 +765,7 @@ namespace boost {
|
||||
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> concurrent_flat_map<boost::remove_const_t<Key>, T, Hash, Pred,
|
||||
-> concurrent_flat_map<std::remove_const_t<Key>, T, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
@ -806,23 +805,23 @@ namespace boost {
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> concurrent_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Allocator) -> concurrent_flat_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> concurrent_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
-> concurrent_flat_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
concurrent_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Hash, Allocator) -> concurrent_flat_map<boost::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Hash, Allocator) -> concurrent_flat_map<std::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
@ -60,9 +59,9 @@ namespace boost {
|
||||
using init_type = typename type_policy::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = typename boost::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::type_identity<Pred>::type;
|
||||
using allocator_type = typename boost::type_identity<Allocator>::type;
|
||||
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::unordered::detail::type_identity<Pred>::type;
|
||||
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
|
@ -9,13 +9,13 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
||||
|
||||
#include <boost/unordered/detail/opt_storage.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/noncopyable.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
@ -54,7 +54,7 @@ struct archive_constructed:private noncopyable
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
||||
#endif
|
||||
|
||||
T& get(){return *reinterpret_cast<T*>(&space);}
|
||||
T& get(){return *space.address();}
|
||||
|
||||
#if defined(BOOST_UNORDERED_IGNORE_WSTRICT_ALIASING)
|
||||
#pragma GCC diagnostic pop
|
||||
@ -62,7 +62,7 @@ struct archive_constructed:private noncopyable
|
||||
#endif
|
||||
|
||||
private:
|
||||
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
|
||||
opt_storage<T> space;
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
|
@ -115,7 +115,9 @@ to normal separate chaining implementations.
|
||||
|
||||
#include <boost/unordered/detail/prime_fmod.hpp>
|
||||
#include <boost/unordered/detail/serialize_tracked_address.hpp>
|
||||
#include <boost/unordered/detail/opt_storage.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/bit.hpp>
|
||||
@ -124,10 +126,6 @@ to normal separate chaining implementations.
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
@ -144,19 +142,18 @@ namespace boost {
|
||||
node>::type node_pointer;
|
||||
|
||||
node_pointer next;
|
||||
typename boost::aligned_storage<sizeof(value_type),
|
||||
boost::alignment_of<value_type>::value>::type buf;
|
||||
opt_storage<value_type> buf;
|
||||
|
||||
node() BOOST_NOEXCEPT : next(), buf() {}
|
||||
node() noexcept : next(), buf() {}
|
||||
|
||||
value_type* value_ptr() BOOST_NOEXCEPT
|
||||
value_type* value_ptr() noexcept
|
||||
{
|
||||
return reinterpret_cast<value_type*>(buf.address());
|
||||
return buf.address();
|
||||
}
|
||||
|
||||
value_type& value() BOOST_NOEXCEPT
|
||||
value_type& value() noexcept
|
||||
{
|
||||
return *reinterpret_cast<value_type*>(buf.address());
|
||||
return *buf.address();
|
||||
}
|
||||
};
|
||||
|
||||
@ -170,7 +167,7 @@ namespace boost {
|
||||
|
||||
node_pointer next;
|
||||
|
||||
bucket() BOOST_NOEXCEPT : next() {}
|
||||
bucket() noexcept : next() {}
|
||||
};
|
||||
|
||||
template <class Bucket> struct bucket_group
|
||||
@ -186,7 +183,7 @@ namespace boost {
|
||||
std::size_t bitmask;
|
||||
bucket_group_pointer next, prev;
|
||||
|
||||
bucket_group() BOOST_NOEXCEPT : buckets(), bitmask(0), next(), prev() {}
|
||||
bucket_group() noexcept : buckets(), bitmask(0), next(), prev() {}
|
||||
~bucket_group() {}
|
||||
};
|
||||
|
||||
@ -224,33 +221,28 @@ namespace boost {
|
||||
public:
|
||||
grouped_bucket_iterator() : p(), pbg() {}
|
||||
|
||||
reference operator*() const BOOST_NOEXCEPT { return dereference(); }
|
||||
pointer operator->() const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::to_address(p);
|
||||
}
|
||||
reference operator*() const noexcept { return dereference(); }
|
||||
pointer operator->() const noexcept { return boost::to_address(p); }
|
||||
|
||||
grouped_bucket_iterator& operator++() BOOST_NOEXCEPT
|
||||
grouped_bucket_iterator& operator++() noexcept
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
grouped_bucket_iterator operator++(int) BOOST_NOEXCEPT
|
||||
grouped_bucket_iterator operator++(int) noexcept
|
||||
{
|
||||
grouped_bucket_iterator old = *this;
|
||||
increment();
|
||||
return old;
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
grouped_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
bool operator==(grouped_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return equal(other);
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
grouped_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
bool operator!=(grouped_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return !equal(other);
|
||||
}
|
||||
@ -266,14 +258,14 @@ namespace boost {
|
||||
{
|
||||
}
|
||||
|
||||
Bucket& dereference() const BOOST_NOEXCEPT { return *p; }
|
||||
Bucket& dereference() const noexcept { return *p; }
|
||||
|
||||
bool equal(const grouped_bucket_iterator& x) const BOOST_NOEXCEPT
|
||||
bool equal(const grouped_bucket_iterator& x) const noexcept
|
||||
{
|
||||
return p == x.p;
|
||||
}
|
||||
|
||||
void increment() BOOST_NOEXCEPT
|
||||
void increment() noexcept
|
||||
{
|
||||
std::size_t const offset = static_cast<std::size_t>(p - pbg->buckets);
|
||||
|
||||
@ -290,7 +282,7 @@ namespace boost {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Archive>
|
||||
template <typename Archive>
|
||||
friend void serialization_track(
|
||||
Archive& ar, grouped_bucket_iterator const& x)
|
||||
{
|
||||
@ -301,8 +293,7 @@ namespace boost {
|
||||
|
||||
friend class boost::serialization::access;
|
||||
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar,unsigned int)
|
||||
template <typename Archive> void serialize(Archive& ar, unsigned int)
|
||||
{
|
||||
// requires: not at end() position
|
||||
serialize_tracked_address(ar, p);
|
||||
@ -326,20 +317,17 @@ namespace boost {
|
||||
|
||||
grouped_local_bucket_iterator() : p() {}
|
||||
|
||||
reference operator*() const BOOST_NOEXCEPT { return dereference(); }
|
||||
reference operator*() const noexcept { return dereference(); }
|
||||
|
||||
pointer operator->() const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::to_address(p);
|
||||
}
|
||||
pointer operator->() const noexcept { return boost::to_address(p); }
|
||||
|
||||
grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT
|
||||
grouped_local_bucket_iterator& operator++() noexcept
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT
|
||||
grouped_local_bucket_iterator operator++(int) noexcept
|
||||
{
|
||||
grouped_local_bucket_iterator old = *this;
|
||||
increment();
|
||||
@ -347,13 +335,13 @@ namespace boost {
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
grouped_local_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return equal(other);
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
grouped_local_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return !equal(other);
|
||||
}
|
||||
@ -366,14 +354,14 @@ namespace boost {
|
||||
|
||||
grouped_local_bucket_iterator(node_pointer p_) : p(p_) {}
|
||||
|
||||
value_type& dereference() const BOOST_NOEXCEPT { return p->value(); }
|
||||
value_type& dereference() const noexcept { return p->value(); }
|
||||
|
||||
bool equal(const grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT
|
||||
bool equal(const grouped_local_bucket_iterator& x) const noexcept
|
||||
{
|
||||
return p == x.p;
|
||||
}
|
||||
|
||||
void increment() BOOST_NOEXCEPT { p = p->next; }
|
||||
void increment() noexcept { p = p->next; }
|
||||
|
||||
node_pointer p;
|
||||
};
|
||||
@ -397,20 +385,17 @@ namespace boost {
|
||||
{
|
||||
}
|
||||
|
||||
reference operator*() const BOOST_NOEXCEPT { return dereference(); }
|
||||
reference operator*() const noexcept { return dereference(); }
|
||||
|
||||
pointer operator->() const BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::to_address(p);
|
||||
}
|
||||
pointer operator->() const noexcept { return boost::to_address(p); }
|
||||
|
||||
const_grouped_local_bucket_iterator& operator++() BOOST_NOEXCEPT
|
||||
const_grouped_local_bucket_iterator& operator++() noexcept
|
||||
{
|
||||
increment();
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_grouped_local_bucket_iterator operator++(int) BOOST_NOEXCEPT
|
||||
const_grouped_local_bucket_iterator operator++(int) noexcept
|
||||
{
|
||||
const_grouped_local_bucket_iterator old = *this;
|
||||
increment();
|
||||
@ -418,13 +403,13 @@ namespace boost {
|
||||
}
|
||||
|
||||
bool operator==(
|
||||
const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
const_grouped_local_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return equal(other);
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
const_grouped_local_bucket_iterator const& other) const BOOST_NOEXCEPT
|
||||
const_grouped_local_bucket_iterator const& other) const noexcept
|
||||
{
|
||||
return !equal(other);
|
||||
}
|
||||
@ -435,23 +420,22 @@ namespace boost {
|
||||
|
||||
const_grouped_local_bucket_iterator(node_pointer p_) : p(p_) {}
|
||||
|
||||
value_type& dereference() const BOOST_NOEXCEPT { return p->value(); }
|
||||
value_type& dereference() const noexcept { return p->value(); }
|
||||
|
||||
bool equal(
|
||||
const const_grouped_local_bucket_iterator& x) const BOOST_NOEXCEPT
|
||||
bool equal(const const_grouped_local_bucket_iterator& x) const noexcept
|
||||
{
|
||||
return p == x.p;
|
||||
}
|
||||
|
||||
void increment() BOOST_NOEXCEPT { p = p->next; }
|
||||
void increment() noexcept { p = p->next; }
|
||||
|
||||
node_pointer p;
|
||||
};
|
||||
|
||||
template <class T> struct span
|
||||
{
|
||||
T* begin() const BOOST_NOEXCEPT { return data; }
|
||||
T* end() const BOOST_NOEXCEPT { return data + size; }
|
||||
T* begin() const noexcept { return data; }
|
||||
T* end() const noexcept { return data + size; }
|
||||
|
||||
T* data;
|
||||
std::size_t size;
|
||||
@ -466,8 +450,6 @@ namespace boost {
|
||||
typename boost::allocator_void_pointer<Allocator>::type> >::
|
||||
type>
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(grouped_bucket_array)
|
||||
|
||||
typedef typename boost::allocator_value_type<Allocator>::type
|
||||
allocator_value_type;
|
||||
typedef
|
||||
@ -532,8 +514,7 @@ namespace boost {
|
||||
|
||||
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_(0), size_(0), buckets(), groups()
|
||||
{
|
||||
if (n == 0) {
|
||||
return;
|
||||
@ -582,8 +563,10 @@ namespace boost {
|
||||
|
||||
~grouped_bucket_array() { this->deallocate(); }
|
||||
|
||||
grouped_bucket_array(
|
||||
BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT
|
||||
grouped_bucket_array(grouped_bucket_array const&) = delete;
|
||||
grouped_bucket_array& operator=(grouped_bucket_array const&) = delete;
|
||||
|
||||
grouped_bucket_array(grouped_bucket_array&& other) noexcept
|
||||
: empty_value<node_allocator_type>(
|
||||
empty_init_t(), other.get_node_allocator()),
|
||||
size_index_(other.size_index_),
|
||||
@ -597,8 +580,7 @@ namespace boost {
|
||||
other.groups = group_pointer();
|
||||
}
|
||||
|
||||
grouped_bucket_array& operator=(
|
||||
BOOST_RV_REF(grouped_bucket_array) other) BOOST_NOEXCEPT
|
||||
grouped_bucket_array& operator=(grouped_bucket_array&& other) noexcept
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
this->get_node_allocator() == other.get_node_allocator());
|
||||
@ -622,7 +604,7 @@ namespace boost {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void deallocate() BOOST_NOEXCEPT
|
||||
void deallocate() noexcept
|
||||
{
|
||||
if (buckets) {
|
||||
bucket_allocator_type bucket_alloc = this->get_bucket_allocator();
|
||||
@ -651,7 +633,8 @@ namespace boost {
|
||||
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());
|
||||
boost::core::invoke_swap(
|
||||
get_node_allocator(), other.get_node_allocator());
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,12 +658,9 @@ namespace boost {
|
||||
return this->get_node_allocator();
|
||||
}
|
||||
|
||||
size_type buckets_len() const BOOST_NOEXCEPT { return size_ + 1; }
|
||||
size_type buckets_len() const noexcept { return size_ + 1; }
|
||||
|
||||
size_type groups_len() const BOOST_NOEXCEPT
|
||||
{
|
||||
return size_ / group::N + 1;
|
||||
}
|
||||
size_type groups_len() const noexcept { return size_ / group::N + 1; }
|
||||
|
||||
void reset_allocator(Allocator const& allocator_)
|
||||
{
|
||||
@ -713,7 +693,7 @@ namespace boost {
|
||||
|
||||
local_iterator end(size_type) const { return local_iterator(); }
|
||||
|
||||
size_type capacity() const BOOST_NOEXCEPT { return size_; }
|
||||
size_type capacity() const noexcept { return size_; }
|
||||
|
||||
iterator at(size_type n) const
|
||||
{
|
||||
@ -747,7 +727,7 @@ namespace boost {
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
void append_bucket_group(iterator itb) BOOST_NOEXCEPT
|
||||
void append_bucket_group(iterator itb) noexcept
|
||||
{
|
||||
std::size_t const N = group::N;
|
||||
|
||||
@ -777,7 +757,7 @@ namespace boost {
|
||||
}
|
||||
}
|
||||
|
||||
void insert_node(iterator itb, node_pointer p) BOOST_NOEXCEPT
|
||||
void insert_node(iterator itb, node_pointer p) noexcept
|
||||
{
|
||||
this->append_bucket_group(itb);
|
||||
|
||||
@ -786,7 +766,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
void insert_node_hint(
|
||||
iterator itb, node_pointer p, node_pointer hint) BOOST_NOEXCEPT
|
||||
iterator itb, node_pointer p, node_pointer hint) noexcept
|
||||
{
|
||||
this->append_bucket_group(itb);
|
||||
|
||||
@ -799,7 +779,7 @@ namespace boost {
|
||||
}
|
||||
}
|
||||
|
||||
void extract_node(iterator itb, node_pointer p) BOOST_NOEXCEPT
|
||||
void extract_node(iterator itb, node_pointer p) noexcept
|
||||
{
|
||||
node_pointer* pp = boost::addressof(itb->next);
|
||||
while ((*pp) != p)
|
||||
@ -809,14 +789,14 @@ namespace boost {
|
||||
unlink_bucket(itb);
|
||||
}
|
||||
|
||||
void extract_node_after(iterator itb, node_pointer* pp) BOOST_NOEXCEPT
|
||||
void extract_node_after(iterator itb, node_pointer* pp) noexcept
|
||||
{
|
||||
*pp = (*pp)->next;
|
||||
if (!itb->next)
|
||||
unlink_bucket(itb);
|
||||
}
|
||||
|
||||
void unlink_empty_buckets() BOOST_NOEXCEPT
|
||||
void unlink_empty_buckets() noexcept
|
||||
{
|
||||
std::size_t const N = group::N;
|
||||
|
||||
@ -864,7 +844,7 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FCA_HPP
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/mp11/tuple.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/unordered/detail/archive_constructed.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
@ -28,6 +27,7 @@
|
||||
#include <boost/unordered/detail/foa/rw_spinlock.hpp>
|
||||
#include <boost/unordered/detail/foa/tuple_rotate_right.hpp>
|
||||
#include <boost/unordered/detail/serialization_version.hpp>
|
||||
#include <boost/unordered/detail/static_assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
@ -88,7 +88,7 @@ private:
|
||||
static constexpr std::size_t element_offset=
|
||||
(sizeof(T)+cacheline_size-1)/cacheline_size*cacheline_size;
|
||||
|
||||
BOOST_STATIC_ASSERT(alignof(T)<=cacheline_size);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(alignof(T)<=cacheline_size);
|
||||
|
||||
T* data(std::size_t pos)noexcept
|
||||
{
|
||||
@ -341,7 +341,7 @@ struct concurrent_table_arrays:table_arrays<Value,Group,SizePolicy,Allocator>
|
||||
struct atomic_size_control
|
||||
{
|
||||
static constexpr auto atomic_size_t_size=sizeof(std::atomic<std::size_t>);
|
||||
BOOST_STATIC_ASSERT(atomic_size_t_size<cacheline_size);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(atomic_size_t_size<cacheline_size);
|
||||
|
||||
atomic_size_control(std::size_t ml_,std::size_t size_):
|
||||
pad0_{},ml{ml_},pad1_{},size{size_}{}
|
||||
|
@ -22,13 +22,10 @@
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/predef.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/type_traits/is_nothrow_swappable.hpp>
|
||||
#include <boost/unordered/detail/narrow_cast.hpp>
|
||||
#include <boost/unordered/detail/mulx.hpp>
|
||||
#include <boost/unordered/detail/static_assert.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
#include <boost/unordered/hash_traits.hpp>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
@ -133,10 +130,10 @@
|
||||
#define BOOST_UNORDERED_THREAD_SANITIZER
|
||||
#endif
|
||||
|
||||
#define BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) \
|
||||
static_assert(boost::is_nothrow_swappable<Hash>::value, \
|
||||
"Template parameter Hash is required to be nothrow Swappable."); \
|
||||
static_assert(boost::is_nothrow_swappable<Pred>::value, \
|
||||
#define BOOST_UNORDERED_STATIC_ASSERT_HASH_PRED(Hash, Pred) \
|
||||
static_assert(boost::unordered::detail::is_nothrow_swappable<Hash>::value, \
|
||||
"Template parameter Hash is required to be nothrow Swappable."); \
|
||||
static_assert(boost::unordered::detail::is_nothrow_swappable<Pred>::value, \
|
||||
"Template parameter Pred is required to be nothrow Swappable");
|
||||
|
||||
namespace boost{
|
||||
@ -311,7 +308,7 @@ struct group15
|
||||
|
||||
private:
|
||||
using slot_type=IntegralWrapper<unsigned char>;
|
||||
BOOST_STATIC_ASSERT(sizeof(slot_type)==1);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1);
|
||||
|
||||
static constexpr unsigned char available_=0,
|
||||
sentinel_=1;
|
||||
@ -514,7 +511,7 @@ struct group15
|
||||
|
||||
private:
|
||||
using slot_type=IntegralWrapper<unsigned char>;
|
||||
BOOST_STATIC_ASSERT(sizeof(slot_type)==1);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(sizeof(slot_type)==1);
|
||||
|
||||
static constexpr unsigned char available_=0,
|
||||
sentinel_=1;
|
||||
@ -707,7 +704,7 @@ struct group15
|
||||
|
||||
private:
|
||||
using word_type=IntegralWrapper<uint64_t>;
|
||||
BOOST_STATIC_ASSERT(sizeof(word_type)==8);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(sizeof(word_type)==8);
|
||||
|
||||
static constexpr unsigned char available_=0,
|
||||
sentinel_=1;
|
||||
@ -1054,13 +1051,7 @@ struct table_arrays
|
||||
initialize_groups(
|
||||
arrays.groups(),groups_size,
|
||||
std::integral_constant<
|
||||
bool,
|
||||
#if BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION,<50000)
|
||||
/* std::is_trivially_constructible not provided */
|
||||
boost::has_trivial_constructor<group_type>::value
|
||||
#else
|
||||
std::is_trivially_constructible<group_type>::value
|
||||
#endif
|
||||
bool,std::is_trivially_constructible<group_type>::value
|
||||
>{});
|
||||
arrays.groups()[groups_size-1].set_sentinel();
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_NODE_HANDLE_HPP
|
||||
|
||||
#include <boost/unordered/detail/opt_storage.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
@ -25,14 +27,6 @@ struct insert_return_type
|
||||
NodeType node;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
union opt_storage {
|
||||
BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_;
|
||||
|
||||
opt_storage(){}
|
||||
~opt_storage(){}
|
||||
};
|
||||
|
||||
template <class TypePolicy,class Allocator>
|
||||
struct node_handle_base
|
||||
{
|
||||
|
@ -14,60 +14,8 @@
|
||||
|
||||
#include <boost/predef.h>
|
||||
|
||||
#if defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
|
||||
// Already defined.
|
||||
#elif defined(BOOST_LIBSTDCXX11)
|
||||
// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70
|
||||
#if BOOST_LIBSTDCXX_VERSION > 40600
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#elif BOOST_LIB_STD_CXX
|
||||
// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206
|
||||
#if BOOST_LIB_STD_CXX >= BOOST_VERSION_NUMBER(3, 0, 0)
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#elif defined(BOOST_LIB_STD_DINKUMWARE)
|
||||
// Apparently C++11 standard supported in Visual Studio 2012
|
||||
// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl
|
||||
// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully!
|
||||
// I have no idea when Dinkumware added it, probably a lot
|
||||
// earlier than this check.
|
||||
#if BOOST_LIB_STD_DINKUMWARE >= BOOST_VERSION_NUMBER(6, 10, 0) || \
|
||||
BOOST_COMP_MSVC >= BOOST_VERSION_NUMBER(17, 0, 0)
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Assume that an unknown library does not support piecewise construction.
|
||||
#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 0
|
||||
#endif
|
||||
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
using std::piecewise_construct_t;
|
||||
using std::piecewise_construct;
|
||||
#else
|
||||
struct piecewise_construct_t
|
||||
{
|
||||
};
|
||||
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// BOOST_UNORDERED_EMPLACE_LIMIT = The maximum number of parameters in
|
||||
// emplace (not including things like hints). Don't set it to a lower value, as
|
||||
// that might break something.
|
||||
|
||||
#if !defined BOOST_UNORDERED_EMPLACE_LIMIT
|
||||
#define BOOST_UNORDERED_EMPLACE_LIMIT 10
|
||||
#endif
|
||||
#include <tuple>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Configuration
|
||||
@ -88,63 +36,11 @@ namespace boost {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BOOST_UNORDERED_TUPLE_ARGS
|
||||
//
|
||||
// Maximum number of std::tuple members to support, or 0 if std::tuple
|
||||
// isn't avaiable. More are supported when full C++11 is used.
|
||||
|
||||
// Already defined, so do nothing
|
||||
#if defined(BOOST_UNORDERED_TUPLE_ARGS)
|
||||
|
||||
// Assume if we have C++11 tuple it's properly variadic,
|
||||
// and just use a max number of 10 arguments.
|
||||
#elif !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
#define BOOST_UNORDERED_TUPLE_ARGS 10
|
||||
|
||||
// Visual C++ has a decent enough tuple for piecewise construction,
|
||||
// so use that if available, using _VARIADIC_MAX for the maximum
|
||||
// number of parameters. Note that this comes after the check
|
||||
// for a full C++11 tuple.
|
||||
#elif defined(BOOST_MSVC)
|
||||
#if !BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
#define BOOST_UNORDERED_TUPLE_ARGS 0
|
||||
#elif defined(_VARIADIC_MAX)
|
||||
#define BOOST_UNORDERED_TUPLE_ARGS _VARIADIC_MAX
|
||||
#else
|
||||
#define BOOST_UNORDERED_TUPLE_ARGS 5
|
||||
#endif
|
||||
|
||||
// Assume that we don't have std::tuple
|
||||
#else
|
||||
#define BOOST_UNORDERED_TUPLE_ARGS 0
|
||||
#endif
|
||||
|
||||
#if BOOST_UNORDERED_TUPLE_ARGS
|
||||
#include <tuple>
|
||||
#endif
|
||||
|
||||
// BOOST_UNORDERED_CXX11_CONSTRUCTION
|
||||
//
|
||||
// Use C++11 construction, requires variadic arguments, good construct support
|
||||
// in allocator_traits and piecewise construction of std::pair
|
||||
// Otherwise allocators aren't used for construction/destruction
|
||||
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && BOOST_UNORDERED_TUPLE_ARGS
|
||||
#if BOOST_COMP_SUNPRO && BOOST_LIB_STD_GNU
|
||||
// Sun C++ std::pair piecewise construction doesn't seem to be exception safe.
|
||||
// (At least for Sun C++ 12.5 using libstdc++).
|
||||
#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
|
||||
#elif BOOST_COMP_GNUC && BOOST_COMP_GNUC < BOOST_VERSION_NUMBER(4, 7, 0)
|
||||
// Piecewise construction in GCC 4.6 doesn't work for uncopyable types.
|
||||
#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
|
||||
#elif !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
#define BOOST_UNORDERED_CXX11_CONSTRUCTION 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_UNORDERED_CXX11_CONSTRUCTION)
|
||||
#define BOOST_UNORDERED_CXX11_CONSTRUCTION 0
|
||||
#endif
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
using std::piecewise_construct;
|
||||
using std::piecewise_construct_t;
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,21 +9,21 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP
|
||||
|
||||
#include <boost/unordered/detail/static_assert.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
template<typename To,typename From>
|
||||
BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT
|
||||
constexpr To narrow_cast(From x) noexcept
|
||||
{
|
||||
BOOST_STATIC_ASSERT(boost::is_integral<From>::value);
|
||||
BOOST_STATIC_ASSERT(boost::is_integral<To>::value);
|
||||
BOOST_STATIC_ASSERT(sizeof(From)>=sizeof(To));
|
||||
BOOST_UNORDERED_STATIC_ASSERT(std::is_integral<From>::value);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(std::is_integral<To>::value);
|
||||
BOOST_UNORDERED_STATIC_ASSERT(sizeof(From)>=sizeof(To));
|
||||
|
||||
return static_cast<To>(
|
||||
x
|
||||
@ -32,7 +32,7 @@ BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT
|
||||
/* Avoids VS's "Run-Time Check Failure #1 - A cast to a smaller data type
|
||||
* has caused a loss of data."
|
||||
*/
|
||||
&static_cast<typename boost::make_unsigned<To>::type>(~static_cast<To>(0))
|
||||
&static_cast<typename std::make_unsigned<To>::type>(~static_cast<To>(0))
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
25
include/boost/unordered/detail/opt_storage.hpp
Normal file
25
include/boost/unordered/detail/opt_storage.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
template <class T> union opt_storage
|
||||
{
|
||||
BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS T t_;
|
||||
|
||||
opt_storage() {}
|
||||
~opt_storage() {}
|
||||
|
||||
T* address() noexcept { return std::addressof(t_); }
|
||||
T const* address() const noexcept { return std::addressof(t_); }
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_OPT_STORAGE_HPP
|
@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2022 Joaquin M Lopez Munoz.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 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)
|
||||
@ -7,13 +7,10 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/unordered/detail/narrow_cast.hpp>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
@ -37,21 +34,90 @@ namespace boost {
|
||||
namespace detail {
|
||||
template <class = void> struct prime_fmod_size
|
||||
{
|
||||
// Because we compile for C++03, we don't have access to any inline
|
||||
// initialization for array data members so the definitions must exist
|
||||
// out-of-line. To keep the library header-only, we introduce a dummy
|
||||
// template parameter which permits the definition to be included in
|
||||
// multiple TUs without conflict.
|
||||
//
|
||||
static std::size_t sizes[];
|
||||
static std::size_t const sizes_len;
|
||||
static std::size_t (*positions[])(std::size_t);
|
||||
constexpr static std::size_t const sizes[] = {13ul, 29ul, 53ul, 97ul,
|
||||
193ul, 389ul, 769ul, 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
|
||||
49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul,
|
||||
6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul,
|
||||
201326611ul, 402653189ul, 805306457ul, 1610612741ul, 3221225473ul,
|
||||
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
4294967291ul
|
||||
#else
|
||||
6442450939ull, 12884901893ull, 25769803751ull, 51539607551ull,
|
||||
103079215111ull, 206158430209ull, 412316860441ull, 824633720831ull,
|
||||
1649267441651ull
|
||||
#endif
|
||||
};
|
||||
|
||||
constexpr static std::size_t const sizes_len =
|
||||
sizeof(sizes) / sizeof(sizes[0]);
|
||||
|
||||
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
static boost::uint64_t inv_sizes32[];
|
||||
static std::size_t const inv_sizes32_len;
|
||||
constexpr static boost::uint64_t const inv_sizes32[] = {
|
||||
1418980313362273202ull, 636094623231363849ull, 348051774975651918ull,
|
||||
190172619316593316ull, 95578984837873325ull, 47420935922132524ull,
|
||||
23987963684927896ull, 11955116055547344ull, 5991147799191151ull,
|
||||
2998982941588287ull, 1501077717772769ull, 750081082979285ull,
|
||||
375261795343686ull, 187625172388393ull, 93822606204624ull,
|
||||
46909513691883ull, 23456218233098ull, 11728086747027ull,
|
||||
5864041509391ull, 2932024948977ull, 1466014921160ull, 733007198436ull,
|
||||
366503839517ull, 183251896093ull, 91625960335ull, 45812983922ull,
|
||||
22906489714ull, 11453246088ull, 5726623060ull};
|
||||
|
||||
constexpr static std::size_t const inv_sizes32_len =
|
||||
sizeof(inv_sizes32) / sizeof(inv_sizes32[0]);
|
||||
#endif /* defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T) */
|
||||
|
||||
template <std::size_t SizeIndex, std::size_t Size = sizes[SizeIndex]>
|
||||
static std::size_t position(std::size_t hash)
|
||||
{
|
||||
return hash % Size;
|
||||
}
|
||||
|
||||
constexpr static std::size_t (*positions[])(std::size_t) = {
|
||||
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
position<0, sizes[0]>,
|
||||
position<1, sizes[1]>,
|
||||
position<2, sizes[2]>,
|
||||
position<3, sizes[3]>,
|
||||
position<4, sizes[4]>,
|
||||
position<5, sizes[5]>,
|
||||
position<6, sizes[6]>,
|
||||
position<7, sizes[7]>,
|
||||
position<8, sizes[8]>,
|
||||
position<9, sizes[9]>,
|
||||
position<10, sizes[10]>,
|
||||
position<11, sizes[11]>,
|
||||
position<12, sizes[12]>,
|
||||
position<13, sizes[13]>,
|
||||
position<14, sizes[14]>,
|
||||
position<15, sizes[15]>,
|
||||
position<16, sizes[16]>,
|
||||
position<17, sizes[17]>,
|
||||
position<18, sizes[18]>,
|
||||
position<19, sizes[19]>,
|
||||
position<20, sizes[20]>,
|
||||
position<21, sizes[21]>,
|
||||
position<22, sizes[22]>,
|
||||
position<23, sizes[23]>,
|
||||
position<24, sizes[24]>,
|
||||
position<25, sizes[25]>,
|
||||
position<26, sizes[26]>,
|
||||
position<27, sizes[27]>,
|
||||
position<28, sizes[28]>,
|
||||
position<29, sizes[29]>,
|
||||
#else
|
||||
position<29, sizes[29]>,
|
||||
position<30, sizes[30]>,
|
||||
position<31, sizes[31]>,
|
||||
position<32, sizes[32]>,
|
||||
position<33, sizes[33]>,
|
||||
position<34, sizes[34]>,
|
||||
position<35, sizes[35]>,
|
||||
position<36, sizes[36]>,
|
||||
position<37, sizes[37]>,
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline std::size_t size_index(std::size_t n)
|
||||
{
|
||||
std::size_t i = 0;
|
||||
@ -68,11 +134,6 @@ namespace boost {
|
||||
return sizes[size_index];
|
||||
}
|
||||
|
||||
template <std::size_t Size> static std::size_t modulo(std::size_t hash)
|
||||
{
|
||||
return hash % Size;
|
||||
}
|
||||
|
||||
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
// We emulate the techniques taken from:
|
||||
// Faster Remainder by Direct Computation: Applications to Compilers and
|
||||
@ -118,8 +179,8 @@ namespace boost {
|
||||
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
std::size_t sizes_under_32bit = inv_sizes32_len;
|
||||
if (BOOST_LIKELY(size_index < sizes_under_32bit)) {
|
||||
return fast_modulo(
|
||||
narrow_cast<boost::uint32_t>(hash) + narrow_cast<boost::uint32_t>(hash >> 32),
|
||||
return fast_modulo(narrow_cast<boost::uint32_t>(hash) +
|
||||
narrow_cast<boost::uint32_t>(hash >> 32),
|
||||
inv_sizes32[size_index], boost::uint32_t(sizes[size_index]));
|
||||
} else {
|
||||
return positions[size_index - sizes_under_32bit](hash);
|
||||
@ -130,134 +191,22 @@ namespace boost {
|
||||
}
|
||||
}; // prime_fmod_size
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE \
|
||||
(13ul)(29ul)(53ul)(97ul)(193ul)(389ul)(769ul)(1543ul)(3079ul)(6151ul)( \
|
||||
12289ul)(24593ul)(49157ul)(98317ul)(196613ul)(393241ul)(786433ul)( \
|
||||
1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul)(50331653ul)( \
|
||||
100663319ul)(201326611ul)(402653189ul)(805306457ul)(1610612741ul)( \
|
||||
3221225473ul)
|
||||
// https://en.cppreference.com/w/cpp/language/static#Constant_static_members
|
||||
// If a const non-inline (since C++17) static data member or a constexpr
|
||||
// static data member (since C++11)(until C++17) is odr-used, a definition
|
||||
// at namespace scope is still required, but it cannot have an
|
||||
// initializer.
|
||||
template <class T> constexpr std::size_t prime_fmod_size<T>::sizes[];
|
||||
|
||||
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT \
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE(4294967291ul)
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT \
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE
|
||||
|
||||
// The original sequence here is this:
|
||||
// (6442450939ul)
|
||||
// (12884901893ul)
|
||||
// (25769803751ul)
|
||||
// (51539607551ul)
|
||||
// (103079215111ul)
|
||||
// (206158430209ul)
|
||||
// (412316860441ul)
|
||||
// (824633720831ul)
|
||||
// (1649267441651ul)
|
||||
//
|
||||
// but this causes problems on versions of mingw where the `long` type is 32
|
||||
// bits, even for 64-bit targets. We work around this by replacing the literals
|
||||
// with compile-time arithmetic, using bitshifts to reconstruct the number.
|
||||
//
|
||||
|
||||
// clang-format off
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT \
|
||||
((boost::ulong_long_type(1ul) << 32) + boost::ulong_long_type(2147483643ul)) \
|
||||
((boost::ulong_long_type(3ul) << 32) + boost::ulong_long_type(5ul)) \
|
||||
((boost::ulong_long_type(5ul) << 32) + boost::ulong_long_type(4294967271ul)) \
|
||||
((boost::ulong_long_type(11ul) << 32) + boost::ulong_long_type(4294967295ul)) \
|
||||
((boost::ulong_long_type(24ul) << 32) + boost::ulong_long_type(7ul)) \
|
||||
((boost::ulong_long_type(48ul) << 32) + boost::ulong_long_type(1ul)) \
|
||||
((boost::ulong_long_type(96ul) << 32) + boost::ulong_long_type(25ul)) \
|
||||
((boost::ulong_long_type(191ul) << 32) + boost::ulong_long_type(4294967295ul)) \
|
||||
((boost::ulong_long_type(383ul) << 32) + boost::ulong_long_type(4294967283ul))
|
||||
// clang-format on
|
||||
|
||||
#endif /* BOOST_UNORDERED_FCA_HAS_64B_SIZE_T */
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_SIZES \
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
|
||||
|
||||
template <class T>
|
||||
std::size_t prime_fmod_size<T>::sizes[] = {
|
||||
BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIME_FMOD_SIZES)};
|
||||
|
||||
template <class T>
|
||||
std::size_t const prime_fmod_size<T>::sizes_len = BOOST_PP_SEQ_SIZE(
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES);
|
||||
|
||||
// Similarly here, we have to re-express the integer initialization using
|
||||
// arithmetic such that each literal can fit in a 32-bit value.
|
||||
//
|
||||
#if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
// clang-format off
|
||||
template <class T>
|
||||
boost::uint64_t prime_fmod_size<T>::inv_sizes32[] = {
|
||||
(boost::ulong_long_type(330382099ul) << 32) + boost::ulong_long_type(2973438898ul) /* = 1418980313362273202 */,
|
||||
(boost::ulong_long_type(148102320ul) << 32) + boost::ulong_long_type(2369637129ul) /* = 636094623231363849 */,
|
||||
(boost::ulong_long_type(81037118ul) << 32) + boost::ulong_long_type(3403558990ul) /* = 348051774975651918 */,
|
||||
(boost::ulong_long_type(44278013ul) << 32) + boost::ulong_long_type(1549730468ul) /* = 190172619316593316 */,
|
||||
(boost::ulong_long_type(22253716ul) << 32) + boost::ulong_long_type(2403401389ul) /* = 95578984837873325 */,
|
||||
(boost::ulong_long_type(11041047ul) << 32) + boost::ulong_long_type(143533612ul) /* = 47420935922132524 */,
|
||||
(boost::ulong_long_type(5585133ul) << 32) + boost::ulong_long_type(106117528ul) /* = 23987963684927896 */,
|
||||
(boost::ulong_long_type(2783517ul) << 32) + boost::ulong_long_type(1572687312ul) /* = 11955116055547344 */,
|
||||
(boost::ulong_long_type(1394922ul) << 32) + boost::ulong_long_type(3428720239ul) /* = 5991147799191151 */,
|
||||
(boost::ulong_long_type(698255ul) << 32) + boost::ulong_long_type(552319807ul) /* = 2998982941588287 */,
|
||||
(boost::ulong_long_type(349496ul) << 32) + boost::ulong_long_type(3827689953ul) /* = 1501077717772769 */,
|
||||
(boost::ulong_long_type(174641ul) << 32) + boost::ulong_long_type(3699438549ul) /* = 750081082979285 */,
|
||||
(boost::ulong_long_type(87372ul) << 32) + boost::ulong_long_type(1912757574ul) /* = 375261795343686 */,
|
||||
(boost::ulong_long_type(43684ul) << 32) + boost::ulong_long_type(3821029929ul) /* = 187625172388393 */,
|
||||
(boost::ulong_long_type(21844ul) << 32) + boost::ulong_long_type(3340590800ul) /* = 93822606204624 */,
|
||||
(boost::ulong_long_type(10921ul) << 32) + boost::ulong_long_type(4175852267ul) /* = 46909513691883 */,
|
||||
(boost::ulong_long_type(5461ul) << 32) + boost::ulong_long_type(1401829642ul) /* = 23456218233098 */,
|
||||
(boost::ulong_long_type(2730ul) << 32) + boost::ulong_long_type(2826028947ul) /* = 11728086747027 */,
|
||||
(boost::ulong_long_type(1365ul) << 32) + boost::ulong_long_type(1411150351ul) /* = 5864041509391 */,
|
||||
(boost::ulong_long_type(682ul) << 32) + boost::ulong_long_type(2857253105ul) /* = 2932024948977 */,
|
||||
(boost::ulong_long_type(341ul) << 32) + boost::ulong_long_type(1431073224ul) /* = 1466014921160 */,
|
||||
(boost::ulong_long_type(170ul) << 32) + boost::ulong_long_type(2862758116ul) /* = 733007198436 */,
|
||||
(boost::ulong_long_type(85ul) << 32) + boost::ulong_long_type(1431619357ul) /* = 366503839517 */,
|
||||
(boost::ulong_long_type(42ul) << 32) + boost::ulong_long_type(2863269661ul) /* = 183251896093 */,
|
||||
(boost::ulong_long_type(21ul) << 32) + boost::ulong_long_type(1431647119ul) /* = 91625960335 */,
|
||||
(boost::ulong_long_type(10ul) << 32) + boost::ulong_long_type(2863310962ul) /* = 45812983922 */,
|
||||
(boost::ulong_long_type(5ul) << 32) + boost::ulong_long_type(1431653234ul) /* = 22906489714 */,
|
||||
(boost::ulong_long_type(2ul) << 32) + boost::ulong_long_type(2863311496ul) /* = 11453246088 */,
|
||||
(boost::ulong_long_type(1ul) << 32) + boost::ulong_long_type(1431655764ul) /* = 5726623060 */,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
template <class T>
|
||||
std::size_t const
|
||||
prime_fmod_size<T>::inv_sizes32_len = sizeof(inv_sizes32) /
|
||||
sizeof(inv_sizes32[0]);
|
||||
|
||||
#endif /* defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T) */
|
||||
|
||||
#define BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT(z, _, n) \
|
||||
prime_fmod_size<T>::template modulo<n>,
|
||||
|
||||
template <class T>
|
||||
std::size_t (*prime_fmod_size<T>::positions[])(std::size_t) = {
|
||||
#if !defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T)
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT, ~,
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT)
|
||||
#else
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT, ~,
|
||||
BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT)
|
||||
constexpr boost::uint64_t prime_fmod_size<T>::inv_sizes32[];
|
||||
#endif
|
||||
};
|
||||
|
||||
#undef BOOST_UNORDERED_PRIME_FMOD_POSITIONS_ELEMENT
|
||||
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES
|
||||
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_64BIT
|
||||
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT
|
||||
#undef BOOST_UNORDERED_PRIME_FMOD_SIZES_32BIT_INCOMPLETE
|
||||
template <class T>
|
||||
constexpr std::size_t (*prime_fmod_size<T>::positions[])(std::size_t);
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_PRIME_FMOD_HPP
|
||||
|
@ -11,10 +11,7 @@
|
||||
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/unordered/detail/archive_constructed.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
#include <boost/unordered/detail/serialization_version.hpp>
|
||||
@ -94,7 +91,7 @@ template<typename Set> struct load_or_save_unordered_set<Set,false> /* load */
|
||||
archive_constructed<value_type> value("item",ar,value_version);
|
||||
|
||||
std::pair<iterator,bool> p=adapt_insert_return_type(
|
||||
x.insert(boost::move(value.get())));
|
||||
x.insert(std::move(value.get())));
|
||||
if(!p.second)throw_exception(bad_archive_exception());
|
||||
ar.reset_object_address(
|
||||
boost::addressof(*p.first),boost::addressof(value.get()));
|
||||
@ -110,9 +107,9 @@ template<typename Map> struct load_or_save_unordered_map<Map,true> /* save */
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,const Map& x,unsigned int)const
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename Map::key_type>::type key_type;
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename Map::mapped_type>::type mapped_type;
|
||||
typedef typename Map::const_iterator const_iterator;
|
||||
|
||||
@ -147,9 +144,9 @@ template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
|
||||
template<typename Archive>
|
||||
void operator()(Archive& ar,Map& x,unsigned int)const
|
||||
{
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename Map::key_type>::type key_type;
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename Map::mapped_type>::type mapped_type;
|
||||
typedef typename Map::iterator iterator;
|
||||
|
||||
@ -169,7 +166,7 @@ template<typename Map> struct load_or_save_unordered_map<Map,false> /* load */
|
||||
archive_constructed<mapped_type> mapped("mapped",ar,mapped_version);
|
||||
|
||||
std::pair<iterator,bool> p=adapt_insert_return_type(
|
||||
x.emplace(boost::move(key.get()),boost::move(mapped.get())));
|
||||
x.emplace(std::move(key.get()),std::move(mapped.get())));
|
||||
if(!p.second)throw_exception(bad_archive_exception());
|
||||
ar.reset_object_address(
|
||||
boost::addressof(p.first->first),boost::addressof(key.get()));
|
||||
@ -196,7 +193,7 @@ void serialize_container(Archive& ar,Container& x,unsigned int version)
|
||||
{
|
||||
load_or_save_container<
|
||||
Container,
|
||||
boost::is_same<
|
||||
std::is_same<
|
||||
typename Container::key_type,typename Container::value_type>::value,
|
||||
Archive::is_saving::value>()(ar,x,version);
|
||||
}
|
||||
|
@ -9,12 +9,13 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_SERIALIZE_TRACKED_ADDRESS_HPP
|
||||
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/core/serialization.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/unordered/detail/bad_archive_exception.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
@ -44,7 +45,7 @@ template<typename Archive,typename Ptr>
|
||||
void track_address(Archive& ar,Ptr p)
|
||||
{
|
||||
typedef typename boost::pointer_traits<Ptr> ptr_traits;
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename ptr_traits::element_type>::type element_type;
|
||||
|
||||
if(p){
|
||||
@ -57,10 +58,10 @@ void track_address(Archive& ar,Ptr p)
|
||||
}
|
||||
|
||||
template<typename Archive,typename Ptr>
|
||||
void serialize_tracked_address(Archive& ar,Ptr& p,boost::true_type /* save */)
|
||||
void serialize_tracked_address(Archive& ar,Ptr& p,std::true_type /* save */)
|
||||
{
|
||||
typedef typename boost::pointer_traits<Ptr> ptr_traits;
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename ptr_traits::element_type>::type element_type;
|
||||
typedef serialization_tracker<element_type> tracker;
|
||||
|
||||
@ -73,10 +74,10 @@ void serialize_tracked_address(Archive& ar,Ptr& p,boost::true_type /* save */)
|
||||
}
|
||||
|
||||
template<typename Archive,typename Ptr>
|
||||
void serialize_tracked_address(Archive& ar,Ptr& p,boost::false_type /* load */)
|
||||
void serialize_tracked_address(Archive& ar,Ptr& p,std::false_type /* load */)
|
||||
{
|
||||
typedef typename boost::pointer_traits<Ptr> ptr_traits;
|
||||
typedef typename boost::remove_const<
|
||||
typedef typename std::remove_const<
|
||||
typename ptr_traits::element_type>::type element_type;
|
||||
typedef serialization_tracker<element_type> tracker;
|
||||
|
||||
@ -93,7 +94,7 @@ void serialize_tracked_address(Archive& ar,Ptr& p)
|
||||
{
|
||||
serialize_tracked_address(
|
||||
ar,p,
|
||||
boost::integral_constant<bool,Archive::is_saving::value>());
|
||||
std::integral_constant<bool,Archive::is_saving::value>());
|
||||
}
|
||||
|
||||
} /* namespace detail */
|
||||
|
12
include/boost/unordered/detail/static_assert.hpp
Normal file
12
include/boost/unordered/detail/static_assert.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BOOST_UNORDERED_STATIC_ASSERT(...) \
|
||||
static_assert(__VA_ARGS__, #__VA_ARGS__)
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_STATIC_ASSERT_HPP
|
@ -11,20 +11,13 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <boost/type_traits/type_identity.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)
|
||||
#include <boost/type_traits/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
// BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES)
|
||||
@ -40,19 +33,56 @@
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
|
||||
template <class T> struct type_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename... Ts> struct make_void
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename... Ts> using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
namespace type_traits_detail {
|
||||
using std::swap;
|
||||
|
||||
template <class T, class = void> struct is_nothrow_swappable_helper
|
||||
{
|
||||
constexpr static bool const value = false;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_nothrow_swappable_helper<T,
|
||||
void_t<decltype(swap(std::declval<T&>(), std::declval<T&>()))> >
|
||||
{
|
||||
constexpr static bool const value =
|
||||
noexcept(swap(std::declval<T&>(), std::declval<T&>()));
|
||||
};
|
||||
|
||||
} // namespace type_traits_detail
|
||||
|
||||
template <class T> struct is_nothrow_swappable
|
||||
{
|
||||
constexpr static bool const value =
|
||||
type_traits_detail::is_nothrow_swappable_helper<T>::value;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
struct is_transparent : public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_transparent<T,
|
||||
typename boost::make_void<typename T::is_transparent>::type>
|
||||
: public boost::true_type
|
||||
typename boost::unordered::detail::make_void<typename T::is_transparent>::type>
|
||||
: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
@ -71,8 +101,8 @@ namespace boost {
|
||||
|
||||
static bool const value =
|
||||
are_transparent<Key, hash, key_equal>::value &&
|
||||
!boost::is_convertible<Key, iterator>::value &&
|
||||
!boost::is_convertible<Key, const_iterator>::value;
|
||||
!std::is_convertible<Key, iterator>::value &&
|
||||
!std::is_convertible<Key, const_iterator>::value;
|
||||
};
|
||||
|
||||
#if BOOST_UNORDERED_TEMPLATE_DEDUCTION_GUIDES
|
||||
@ -81,7 +111,7 @@ namespace boost {
|
||||
|
||||
template <class InputIterator>
|
||||
constexpr bool const is_input_iterator_v =
|
||||
!boost::is_integral<InputIterator>::value;
|
||||
!std::is_integral<InputIterator>::value;
|
||||
|
||||
template <class A, class = void> struct is_allocator
|
||||
{
|
||||
@ -90,7 +120,7 @@ namespace boost {
|
||||
|
||||
template <class A>
|
||||
struct is_allocator<A,
|
||||
boost::void_t<typename A::value_type,
|
||||
boost::unordered::detail::void_t<typename A::value_type,
|
||||
decltype(std::declval<A&>().allocate(std::size_t{}))> >
|
||||
{
|
||||
constexpr static bool const value = true;
|
||||
@ -101,7 +131,7 @@ namespace boost {
|
||||
|
||||
template <class H>
|
||||
constexpr bool const is_hash_v =
|
||||
!boost::is_integral<H>::value && !is_allocator_v<H>;
|
||||
!std::is_integral<H>::value && !is_allocator_v<H>;
|
||||
|
||||
template <class P> constexpr bool const is_pred_v = !is_allocator_v<P>;
|
||||
|
||||
@ -116,7 +146,7 @@ namespace boost {
|
||||
typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_TYPE_TRAITS_HPP
|
||||
|
@ -11,8 +11,7 @@
|
||||
#ifndef BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||
#define BOOST_UNORDERED_HASH_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace unordered{
|
||||
@ -20,12 +19,12 @@ namespace unordered{
|
||||
namespace detail{
|
||||
|
||||
template<typename Hash,typename=void>
|
||||
struct hash_is_avalanching_impl: boost::false_type{};
|
||||
struct hash_is_avalanching_impl: std::false_type{};
|
||||
|
||||
template<typename Hash>
|
||||
struct hash_is_avalanching_impl<Hash,
|
||||
typename boost::make_void<typename Hash::is_avalanching>::type>:
|
||||
boost::true_type{};
|
||||
typename boost::unordered::detail::make_void<typename Hash::is_avalanching>::type>:
|
||||
std::true_type{};
|
||||
|
||||
} /* namespace detail */
|
||||
|
||||
|
@ -65,9 +65,9 @@ namespace boost {
|
||||
using init_type = typename map_types::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = typename boost::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::type_identity<KeyEqual>::type;
|
||||
using allocator_type = typename boost::type_identity<Allocator>::type;
|
||||
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::unordered::detail::type_identity<KeyEqual>::type;
|
||||
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
@ -729,8 +729,8 @@ namespace boost {
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Hash = boost::hash<std::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<std::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
@ -738,7 +738,7 @@ namespace boost {
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_flat_map<boost::remove_const_t<Key>, T, Hash, Pred,
|
||||
-> unordered_flat_map<std::remove_const_t<Key>, T, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
@ -775,23 +775,23 @@ namespace boost {
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
-> unordered_flat_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_flat_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Hash, Allocator) -> unordered_flat_map<boost::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Hash, Allocator) -> unordered_flat_map<std::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
|
||||
// Copyright (C) 2008-2011 Daniel James.
|
||||
// Copyright (C) 2022 Christian Mazakas
|
||||
// Copyright (C) 2022-2023 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)
|
||||
|
||||
@ -30,9 +30,8 @@ namespace boost {
|
||||
inline bool operator!=(
|
||||
unordered_map<K, T, H, P, A> const&, unordered_map<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(
|
||||
unordered_map<K, T, H, P, A>& m1, unordered_map<K, T, H, P, A>& m2)
|
||||
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
|
||||
inline void swap(unordered_map<K, T, H, P, A>& m1,
|
||||
unordered_map<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
|
||||
|
||||
template <class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_map<K, T, H, P, A>::size_type erase_if(
|
||||
@ -51,8 +50,7 @@ namespace boost {
|
||||
unordered_multimap<K, T, H, P, A> const&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline void swap(unordered_multimap<K, T, H, P, A>& m1,
|
||||
unordered_multimap<K, T, H, P, A>& m2)
|
||||
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
|
||||
unordered_multimap<K, T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
|
||||
|
||||
template <class K, class T, class H, class P, class A, class Predicate>
|
||||
typename unordered_multimap<K, T, H, P, A>::size_type erase_if(
|
||||
@ -60,13 +58,13 @@ 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;
|
||||
}
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::unordered_map;
|
||||
using boost::unordered::unordered_multimap;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
@ -99,9 +99,9 @@ namespace boost {
|
||||
using init_type = typename map_types::init_type;
|
||||
using size_type = std::size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using hasher = typename boost::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::type_identity<KeyEqual>::type;
|
||||
using allocator_type = typename boost::type_identity<Allocator>::type;
|
||||
using hasher = typename boost::unordered::detail::type_identity<Hash>::type;
|
||||
using key_equal = typename boost::unordered::detail::type_identity<KeyEqual>::type;
|
||||
using allocator_type = typename boost::unordered::detail::type_identity<Allocator>::type;
|
||||
using reference = value_type&;
|
||||
using const_reference = value_type const&;
|
||||
using pointer = typename boost::allocator_pointer<allocator_type>::type;
|
||||
@ -822,8 +822,8 @@ namespace boost {
|
||||
Allocator>;
|
||||
|
||||
template <class Key, class T,
|
||||
class Hash = boost::hash<boost::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<boost::remove_const_t<Key> >,
|
||||
class Hash = boost::hash<std::remove_const_t<Key> >,
|
||||
class Pred = std::equal_to<std::remove_const_t<Key> >,
|
||||
class Allocator = std::allocator<std::pair<const Key, T> >,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_pred_v<Pred> >,
|
||||
@ -831,7 +831,7 @@ namespace boost {
|
||||
unordered_node_map(std::initializer_list<std::pair<Key, T> >,
|
||||
std::size_t = boost::unordered::detail::foa::default_bucket_count,
|
||||
Hash = Hash(), Pred = Pred(), Allocator = Allocator())
|
||||
-> unordered_node_map<boost::remove_const_t<Key>, T, Hash, Pred,
|
||||
-> unordered_node_map<std::remove_const_t<Key>, T, Hash, Pred,
|
||||
Allocator>;
|
||||
|
||||
template <class InputIterator, class Allocator,
|
||||
@ -868,23 +868,23 @@ namespace boost {
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_node_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Allocator) -> unordered_node_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Allocator) -> unordered_node_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_node_map(std::initializer_list<std::pair<Key, T> >, Allocator)
|
||||
-> unordered_node_map<boost::remove_const_t<Key>, T,
|
||||
boost::hash<boost::remove_const_t<Key> >,
|
||||
std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
-> unordered_node_map<std::remove_const_t<Key>, T,
|
||||
boost::hash<std::remove_const_t<Key> >,
|
||||
std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
|
||||
template <class Key, class T, class Hash, class Allocator,
|
||||
class = boost::enable_if_t<detail::is_hash_v<Hash> >,
|
||||
class = boost::enable_if_t<detail::is_allocator_v<Allocator> > >
|
||||
unordered_node_map(std::initializer_list<std::pair<Key, T> >, std::size_t,
|
||||
Hash, Allocator) -> unordered_node_map<boost::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<boost::remove_const_t<Key> >, Allocator>;
|
||||
Hash, Allocator) -> unordered_node_map<std::remove_const_t<Key>, T,
|
||||
Hash, std::equal_to<std::remove_const_t<Key> >, Allocator>;
|
||||
#endif
|
||||
|
||||
} // namespace unordered
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,9 +29,8 @@ namespace boost {
|
||||
inline bool operator!=(
|
||||
unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(
|
||||
unordered_set<T, H, P, A>& m1, unordered_set<T, H, P, A>& m2)
|
||||
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
|
||||
inline void swap(unordered_set<T, H, P, A>& m1,
|
||||
unordered_set<T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
|
||||
|
||||
template <class K, class H, class P, class A, class Predicate>
|
||||
typename unordered_set<K, H, P, A>::size_type erase_if(
|
||||
@ -48,9 +47,8 @@ namespace boost {
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(
|
||||
unordered_multiset<T, H, P, A>& m1, unordered_multiset<T, H, P, A>& m2)
|
||||
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(m1.swap(m2)));
|
||||
inline void swap(unordered_multiset<T, H, P, A>& m1,
|
||||
unordered_multiset<T, H, P, A>& m2) noexcept(noexcept(m1.swap(m2)));
|
||||
|
||||
template <class K, class H, class P, class A, class Predicate>
|
||||
typename unordered_multiset<K, H, P, A>::size_type erase_if(
|
||||
@ -58,13 +56,13 @@ namespace boost {
|
||||
|
||||
template <class N, class T, class A> class node_handle_set;
|
||||
template <class Iter, class NodeType> struct insert_return_type_set;
|
||||
}
|
||||
} // namespace unordered
|
||||
|
||||
using boost::unordered::unordered_set;
|
||||
using boost::unordered::unordered_multiset;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::unordered_multiset;
|
||||
using boost::unordered::unordered_set;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
@ -77,11 +77,6 @@ fca_tests(SOURCES exception/swap_exception_tests.cpp COMPILE_DEFINITIONS BOOST_U
|
||||
fca_tests(SOURCES exception/merge_exception_tests.cpp)
|
||||
fca_tests(SOURCES exception/less_tests.cpp)
|
||||
fca_tests(SOURCES unordered/narrow_cast_tests.cpp)
|
||||
fca_tests(SOURCES unordered/compile_set.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_compile_set)
|
||||
fca_tests(SOURCES unordered/compile_map.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_compile_map)
|
||||
fca_tests(SOURCES unordered/copy_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_copy)
|
||||
fca_tests(SOURCES unordered/move_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_move)
|
||||
fca_tests(SOURCES unordered/assign_tests.cpp COMPILE_DEFINITIONS BOOST_UNORDERED_USE_MOVE NAME bmove_assign)
|
||||
fca_tests(SOURCES quick.cpp)
|
||||
|
||||
fca_tests(TYPE compile-fail NAME insert_node_type_fail_map COMPILE_DEFINITIONS UNORDERED_TEST_MAP SOURCES unordered/insert_node_type_fail.cpp)
|
||||
|
@ -146,12 +146,6 @@ for local test in $(FCA_TESTS)
|
||||
|
||||
run unordered/link_test_1.cpp unordered/link_test_2.cpp : : : : link_test ;
|
||||
|
||||
run unordered/compile_set.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_compile_set ;
|
||||
run unordered/compile_map.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_compile_map ;
|
||||
run unordered/copy_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_copy ;
|
||||
run unordered/move_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_move ;
|
||||
run unordered/assign_tests.cpp : : : <define>BOOST_UNORDERED_USE_MOVE : bmove_assign ;
|
||||
|
||||
run unordered/serialization_tests.cpp
|
||||
: $(BOOST_UNORDERED_TEST_DIR)
|
||||
:
|
||||
@ -198,11 +192,6 @@ alias fca_tests :
|
||||
$(FCA_TESTS)
|
||||
$(FCA_EXCEPTION_TESTS)
|
||||
link_test
|
||||
bmove_compile_set
|
||||
bmove_compile_map
|
||||
bmove_copy
|
||||
bmove_move
|
||||
bmove_assign
|
||||
insert_node_type_fail_map
|
||||
insert_node_type_fail_multimap
|
||||
insert_node_type_fail_set
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include "../helpers/tracker.hpp"
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
@ -292,7 +295,7 @@ struct pair_emplace_type : inserter_base
|
||||
x.emplace(std::piecewise_construct, std::make_tuple(it->first),
|
||||
std::make_tuple(it->second));
|
||||
#else
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
x.emplace(std::piecewise_construct,
|
||||
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
||||
#endif
|
||||
}
|
||||
@ -307,7 +310,7 @@ struct pair_emplace2_type : inserter_base
|
||||
std::make_tuple(it->first),
|
||||
std::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||
#else
|
||||
x.emplace_hint(x.begin(), boost::unordered::piecewise_construct,
|
||||
x.emplace_hint(x.begin(), std::piecewise_construct,
|
||||
boost::make_tuple(it->first),
|
||||
boost::make_tuple(it->second.tag1_, it->second.tag2_));
|
||||
#endif
|
||||
|
@ -44,7 +44,7 @@ template <class T> struct move_assign_base : public test::exception_base
|
||||
test::exceptions_enable disable_exceptions(false);
|
||||
T y1 = y;
|
||||
disable_exceptions.release();
|
||||
x1 = boost::move(y1);
|
||||
x1 = std::move(y1);
|
||||
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_container(x1, y_values);
|
||||
|
@ -6,10 +6,15 @@
|
||||
#if !defined(BOOST_UNORDERED_TEST_TEST_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_TEST_HEADER
|
||||
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
|
||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/type_traits/is_nothrow_swappable.hpp>
|
||||
#include <boost/type_traits/make_void.hpp>
|
||||
|
||||
#define UNORDERED_AUTO_TEST(x) \
|
||||
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base \
|
||||
@ -120,7 +125,7 @@ namespace test {
|
||||
static state instance;
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
} // namespace test
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#define BOOST_UNORDERED_CPLUSPLUS __cplusplus
|
||||
@ -134,12 +139,6 @@ namespace test {
|
||||
<< "Compiler: " << BOOST_COMPILER << "\n" \
|
||||
<< "Library: " << BOOST_STDLIB << "\n" \
|
||||
<< "__cplusplus: " << BOOST_UNORDERED_CPLUSPLUS << "\n\n" \
|
||||
<< "BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT: " \
|
||||
<< BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT << "\n" \
|
||||
<< "BOOST_UNORDERED_EMPLACE_LIMIT: " << BOOST_UNORDERED_EMPLACE_LIMIT \
|
||||
<< "\n" \
|
||||
<< "BOOST_UNORDERED_CXX11_CONSTRUCTION: " \
|
||||
<< BOOST_UNORDERED_CXX11_CONSTRUCTION << "\n\n" \
|
||||
<< std::flush; \
|
||||
}
|
||||
|
||||
@ -190,7 +189,7 @@ namespace test {
|
||||
#define UNORDERED_MULTI_TEST_OP2(name, n, params) \
|
||||
{ \
|
||||
UNORDERED_SUB_TEST(BOOST_PP_STRINGIZE( \
|
||||
BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params))) \
|
||||
BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params))) \
|
||||
{ \
|
||||
for (int i = 0; i < n; ++i) \
|
||||
name BOOST_PP_SEQ_TO_TUPLE(params); \
|
||||
|
@ -182,9 +182,7 @@ namespace test
|
||||
|
||||
~cxx11_allocator_base() { detail::tracker.allocator_unref(); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
cxx11_allocator_base& operator=(cxx11_allocator_base const& x) = default;
|
||||
#endif
|
||||
|
||||
pointer address(reference r) { return pointer(&r); }
|
||||
|
||||
@ -214,21 +212,12 @@ namespace test
|
||||
::operator delete((void*)p);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V>
|
||||
void construct(U* p, V const& v)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(v);
|
||||
}
|
||||
#else
|
||||
template <class U, typename... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
@ -272,9 +261,7 @@ namespace test
|
||||
|
||||
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
cxx11_allocator& operator=(cxx11_allocator const& x) = default;
|
||||
#endif
|
||||
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
@ -319,9 +306,7 @@ namespace test
|
||||
|
||||
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
|
||||
cxx11_allocator& operator=(cxx11_allocator const& x) = default;
|
||||
#endif
|
||||
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
|
@ -501,28 +501,15 @@ namespace test {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class Arg>
|
||||
void construct(U* p, Arg const& t)
|
||||
template <class U, class... Args> void construct(U* p, Args&&... args)
|
||||
{
|
||||
UNORDERED_SCOPE(allocator::construct(U*, Arg))
|
||||
UNORDERED_SCOPE(allocator::construct(U*, Args&&...))
|
||||
{
|
||||
UNORDERED_EPOINT("Mock allocator construct function.")
|
||||
new (p) U(t);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args> void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
UNORDERED_SCOPE(allocator::construct(U*, BOOST_FWD_REF(Args)...))
|
||||
{
|
||||
UNORDERED_EPOINT("Mock allocator construct function.")
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
}
|
||||
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
@ -682,29 +669,16 @@ namespace test {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V>
|
||||
void construct(U* p, V const& v)
|
||||
{
|
||||
UNORDERED_SCOPE(allocator2::construct(U*, V))
|
||||
{
|
||||
UNORDERED_EPOINT("Mock allocator2 construct function.")
|
||||
new (p) U(v);
|
||||
}
|
||||
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
UNORDERED_SCOPE(allocator2::construct(U*, BOOST_FWD_REF(Args)...))
|
||||
UNORDERED_SCOPE(allocator2::construct(U*, Args&&...))
|
||||
{
|
||||
UNORDERED_EPOINT("Mock allocator2 construct function.")
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
test::detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U>
|
||||
void destroy(U* p)
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/pointer_traits.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
@ -165,19 +164,18 @@ namespace test {
|
||||
|
||||
class movable1
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
|
||||
|
||||
public:
|
||||
movable1(constructor_param const&) {}
|
||||
movable1() {}
|
||||
explicit movable1(movable_init) {}
|
||||
movable1(BOOST_RV_REF(movable1)) {}
|
||||
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
|
||||
movable1(movable1 const&) = delete;
|
||||
movable1& operator=(movable1 const&) = delete;
|
||||
movable1(movable1&&) {}
|
||||
movable1& operator=(movable1&&) { return *this; }
|
||||
~movable1() {}
|
||||
void dummy_member() const {}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
class movable2
|
||||
{
|
||||
public:
|
||||
@ -193,9 +191,6 @@ namespace test {
|
||||
movable2(movable2 const&);
|
||||
movable2& operator=(movable2 const&);
|
||||
};
|
||||
#else
|
||||
typedef movable1 movable2;
|
||||
#endif
|
||||
|
||||
template <class T> class hash
|
||||
{
|
||||
@ -461,18 +456,11 @@ namespace test {
|
||||
::operator delete((void*)p.ptr_);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V> void construct(U* p, V const& v)
|
||||
{
|
||||
new ((void*)p) U(v);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
new ((void*)p) U(boost::forward<Args>(args)...);
|
||||
new ((void*)p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U> void destroy(U* p) { p->~U(); }
|
||||
|
||||
@ -535,18 +523,11 @@ namespace test {
|
||||
::operator delete((void*)p.ptr_);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U> void construct(U* p, U const& t)
|
||||
{
|
||||
new (p) U(t);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U> void destroy(U* p) { p->~U(); }
|
||||
|
||||
@ -613,18 +594,11 @@ namespace test {
|
||||
|
||||
void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V> void construct(U* p, V const& v)
|
||||
{
|
||||
new ((void*)p) U(v);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
new ((void*)p) U(boost::forward<Args>(args)...);
|
||||
new ((void*)p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U> void destroy(U* p) { p->~U(); }
|
||||
|
||||
|
@ -96,7 +96,6 @@ namespace test {
|
||||
friend class less;
|
||||
int tag1_, tag2_;
|
||||
|
||||
BOOST_COPYABLE_AND_MOVABLE(movable)
|
||||
public:
|
||||
explicit movable(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
|
||||
|
||||
@ -106,7 +105,7 @@ namespace test {
|
||||
BOOST_TEST(x.tag1_ != -1);
|
||||
}
|
||||
|
||||
movable(BOOST_RV_REF(movable) x)
|
||||
movable(movable&& x)
|
||||
: counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
|
||||
{
|
||||
BOOST_TEST(x.tag1_ != -1);
|
||||
@ -114,7 +113,7 @@ namespace test {
|
||||
x.tag2_ = -1;
|
||||
}
|
||||
|
||||
movable& operator=(BOOST_COPY_ASSIGN_REF(movable) x) // Copy assignment
|
||||
movable& operator=(movable const& x) // Copy assignment
|
||||
{
|
||||
BOOST_TEST(x.tag1_ != -1);
|
||||
tag1_ = x.tag1_;
|
||||
@ -122,7 +121,7 @@ namespace test {
|
||||
return *this;
|
||||
}
|
||||
|
||||
movable& operator=(BOOST_RV_REF(movable) x) // Move assignment
|
||||
movable& operator=(movable&& x) // Move assignment
|
||||
{
|
||||
BOOST_TEST(x.tag1_ != -1);
|
||||
tag1_ = x.tag1_;
|
||||
@ -410,11 +409,10 @@ namespace test {
|
||||
::operator delete((void*)p);
|
||||
}
|
||||
|
||||
#if BOOST_UNORDERED_CXX11_CONSTRUCTION
|
||||
template <typename U, typename... Args> void construct(U* p, Args&&... args)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename U> void destroy(U* p)
|
||||
@ -425,22 +423,6 @@ namespace test {
|
||||
// Work around MSVC buggy unused parameter warning.
|
||||
ignore_variable(&p);
|
||||
}
|
||||
#else
|
||||
private:
|
||||
// I'm going to claim in the documentation that construct/destroy
|
||||
// is never used when C++11 support isn't available, so might as
|
||||
// well check that in the text.
|
||||
// TODO: Or maybe just disallow them for values?
|
||||
template <typename U> void construct(U* p);
|
||||
template <typename U, typename A0> void construct(U* p, A0 const&);
|
||||
template <typename U, typename A0, typename A1>
|
||||
void construct(U* p, A0 const&, A1 const&);
|
||||
template <typename U, typename A0, typename A1, typename A2>
|
||||
void construct(U* p, A0 const&, A1 const&, A2 const&);
|
||||
template <typename U> void destroy(U* p);
|
||||
|
||||
public:
|
||||
#endif
|
||||
|
||||
bool operator==(allocator1 const& x) const { return tag_ == x.tag_; }
|
||||
|
||||
@ -674,20 +656,12 @@ namespace test {
|
||||
::operator delete((void*)p.ptr_);
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V> void construct(U* p, V const& v)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(v);
|
||||
}
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(U), tag_);
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class U> void destroy(U* p)
|
||||
{
|
||||
|
@ -111,12 +111,8 @@ void test_empty_allocator()
|
||||
{
|
||||
typedef empty_allocator<int> allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
|
||||
@ -153,12 +149,8 @@ void test_allocator1()
|
||||
{
|
||||
typedef allocator1<int> allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value));
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
|
||||
@ -213,15 +205,7 @@ void test_allocator2()
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_swap::value);
|
||||
BOOST_TEST(!traits::is_always_equal::value);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
// conditionally compile this assertion as all C++03 emulations of expression
|
||||
// SFINAE are broken one way or another and the benefits of using Core's
|
||||
// `allocator_traits` outweigh the costs of breaking this kind of code (i.e.
|
||||
// inheriting SOCCC via a base)
|
||||
//
|
||||
BOOST_TEST(call_select<allocator>() == 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// allocator 3
|
||||
|
@ -436,8 +436,6 @@ namespace assign_tests {
|
||||
(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;
|
||||
@ -459,9 +457,6 @@ namespace assign_tests {
|
||||
BOOST_TEST(x1.empty());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
UNORDERED_AUTO_TEST (assign_initializer_list) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Initializer List Tests\n";
|
||||
|
||||
@ -482,8 +477,6 @@ namespace assign_tests {
|
||||
BOOST_TEST(x.find(10) == x.end());
|
||||
BOOST_TEST(x.find(-10) != x.end());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/predef.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/type_traits/cv_traits.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
@ -34,22 +35,9 @@ template <class T> void sink(T const&) {}
|
||||
template <class T> T rvalue(T const& v) { return v; }
|
||||
template <class T> T rvalue_default() { return T(); }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
template <class T> T implicit_construct() { return {}; }
|
||||
#else
|
||||
template <class T> int implicit_construct()
|
||||
{
|
||||
T x;
|
||||
sink(x);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT)
|
||||
#define TEST_NOEXCEPT_EXPR(x) BOOST_STATIC_ASSERT((BOOST_NOEXCEPT_EXPR(x)));
|
||||
#else
|
||||
#define TEST_NOEXCEPT_EXPR(x)
|
||||
#endif
|
||||
#define TEST_NOEXCEPT_EXPR(x) BOOST_STATIC_ASSERT((noexcept(x)));
|
||||
|
||||
template <class X, class T> void container_test(X& r, T const&)
|
||||
{
|
||||
@ -143,13 +131,11 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
|
||||
// I don't test the runtime post-conditions here.
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
// It isn't specified in the container requirements that the no argument
|
||||
// constructor is implicit, but it is defined that way in the concrete
|
||||
// container specification.
|
||||
X u_implicit = {};
|
||||
sink(u_implicit);
|
||||
#endif
|
||||
|
||||
X u;
|
||||
BOOST_TEST(u.size() == 0);
|
||||
@ -191,10 +177,10 @@ template <class X, class T> void container_test(X& r, T const&)
|
||||
node_type n1;
|
||||
node_type n2(rvalue_default<node_type>());
|
||||
#if !BOOST_COMP_GNUC || BOOST_COMP_GNUC >= BOOST_VERSION_NUMBER(4, 8, 0)
|
||||
TEST_NOEXCEPT_EXPR(node_type(boost::move(n1)));
|
||||
TEST_NOEXCEPT_EXPR(node_type(std::move(n1)));
|
||||
#endif
|
||||
node_type n3;
|
||||
n3 = boost::move(n2);
|
||||
n3 = std::move(n2);
|
||||
n1.swap(n3);
|
||||
swap(n1, n3);
|
||||
// TODO: noexcept for swap?
|
||||
@ -229,13 +215,11 @@ template <class X> void unordered_destructible_test(X&)
|
||||
|
||||
X x1;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
X x2(rvalue_default<X>());
|
||||
X x3 = rvalue_default<X>();
|
||||
// This can only be done if propagate_on_container_move_assignment::value
|
||||
// is true.
|
||||
// x2 = rvalue_default<X>();
|
||||
#endif
|
||||
// This can only be done if propagate_on_container_move_assignment::value
|
||||
// is true.
|
||||
// x2 = rvalue_default<X>();
|
||||
|
||||
X* ptr = new X();
|
||||
X& a1 = *ptr;
|
||||
@ -350,7 +334,7 @@ template <class X, class Key> void unordered_set_test(X& r, Key const&)
|
||||
|
||||
test::minimal::constructor_param v;
|
||||
Key k_lvalue(v);
|
||||
r.emplace(boost::move(k_lvalue));
|
||||
r.emplace(std::move(k_lvalue));
|
||||
node_type n1 = r.extract(r.begin());
|
||||
test::check_return_type<value_type>::equals_ref(n1.value());
|
||||
#endif
|
||||
@ -462,7 +446,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
r.emplace(std::piecewise_construct, std::make_tuple(k), std::make_tuple(v));
|
||||
#else
|
||||
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
|
||||
r.emplace(std::piecewise_construct, boost::make_tuple(k),
|
||||
boost::make_tuple(v));
|
||||
#endif
|
||||
|
||||
@ -476,7 +460,7 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
r.emplace_hint(r.begin(), std::piecewise_construct, std::make_tuple(k),
|
||||
std::make_tuple(v));
|
||||
#else
|
||||
r.emplace_hint(r.begin(), boost::unordered::piecewise_construct,
|
||||
r.emplace_hint(r.begin(), std::piecewise_construct,
|
||||
boost::make_tuple(k), boost::make_tuple(v));
|
||||
#endif
|
||||
|
||||
@ -493,11 +477,11 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
test::check_return_type<key_type>::equals_ref(n1.key());
|
||||
test::check_return_type<T>::equals_ref(n1.mapped());
|
||||
|
||||
node_type n2 = boost::move(n1);
|
||||
r.insert(boost::move(n2));
|
||||
node_type n2 = std::move(n1);
|
||||
r.insert(std::move(n2));
|
||||
r.insert(r.extract(r.begin()));
|
||||
n2 = r.extract(r.begin());
|
||||
r.insert(r.begin(), boost::move(n2));
|
||||
r.insert(r.begin(), std::move(n2));
|
||||
r.insert(r.end(), r.extract(r.begin()));
|
||||
|
||||
node_type n = r.extract(r.begin());
|
||||
@ -530,11 +514,11 @@ template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
||||
|
||||
// TODO;
|
||||
// boost::function_requires<
|
||||
// boost::MoveConstructibleConcept<insert_return_type>
|
||||
// std::moveConstructibleConcept<insert_return_type>
|
||||
// >();
|
||||
// TODO;
|
||||
// boost::function_requires<
|
||||
// boost::MoveAssignableConcept<insert_return_type>
|
||||
// std::moveAssignableConcept<insert_return_type>
|
||||
// >();
|
||||
boost::function_requires<
|
||||
boost::DefaultConstructibleConcept<insert_return_type> >();
|
||||
@ -738,9 +722,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
a.rehash(100);
|
||||
|
||||
a.merge(a2);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
a.merge(rvalue_default<X>());
|
||||
#endif
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
@ -793,7 +775,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
// X a8a(i, j, m);
|
||||
// sink(a8a);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
std::size_t min_buckets = 10;
|
||||
X({t});
|
||||
X({t}, min_buckets);
|
||||
@ -803,7 +784,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
X({t}, min_buckets, m);
|
||||
X({t}, min_buckets, hf, m);
|
||||
X({t}, min_buckets, hf, eq, m);
|
||||
#endif
|
||||
|
||||
X const b;
|
||||
sink(X(b));
|
||||
@ -826,7 +806,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, t));
|
||||
|
||||
a.insert(i, j);
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
std::initializer_list<T> list = {t};
|
||||
a.insert(list);
|
||||
a.insert({t, t, t});
|
||||
@ -837,7 +816,6 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
a.insert({});
|
||||
a.insert({t});
|
||||
a.insert({t, t});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
X a10;
|
||||
@ -879,12 +857,10 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
typedef typename X::const_iterator const_iterator;
|
||||
typedef typename X::allocator_type allocator_type;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
X x1(rvalue_default<X>());
|
||||
X x2(boost::move(x1));
|
||||
X x2(std::move(x1));
|
||||
x1 = rvalue_default<X>();
|
||||
x2 = boost::move(x1);
|
||||
#endif
|
||||
x2 = std::move(x1);
|
||||
|
||||
X a;
|
||||
allocator_type m = a.get_allocator();
|
||||
@ -922,19 +898,19 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, v));
|
||||
|
||||
T v1(v);
|
||||
a.emplace(boost::move(v1));
|
||||
a.emplace(std::move(v1));
|
||||
T v2(v);
|
||||
a.insert(boost::move(v2));
|
||||
a.insert(std::move(v2));
|
||||
T v3(v);
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, boost::move(v3)));
|
||||
test::check_return_type<iterator>::equals(a.emplace_hint(q, std::move(v3)));
|
||||
T v4(v);
|
||||
test::check_return_type<iterator>::equals(a.insert(q, boost::move(v4)));
|
||||
test::check_return_type<iterator>::equals(a.insert(q, std::move(v4)));
|
||||
|
||||
a.insert(i, j);
|
||||
|
||||
X a10;
|
||||
T v5(v);
|
||||
a10.insert(boost::move(v5));
|
||||
a10.insert(std::move(v5));
|
||||
q = a10.cbegin();
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test::check_return_type<iterator>::convertible(a10.erase(q));
|
||||
|
@ -324,7 +324,6 @@ namespace constructor_tests {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
typedef typename T::value_type value_type;
|
||||
|
||||
std::initializer_list<value_type> list;
|
||||
@ -525,7 +524,6 @@ namespace constructor_tests {
|
||||
test::check_container(x, expected);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -608,7 +606,6 @@ namespace constructor_tests {
|
||||
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;
|
||||
@ -633,7 +630,6 @@ namespace constructor_tests {
|
||||
BOOST_TEST_GT(test::detail::tracker.count_allocations, 0u);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -721,8 +717,6 @@ namespace constructor_tests {
|
||||
(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
|
||||
@ -735,10 +729,6 @@ namespace constructor_tests {
|
||||
BOOST_TEST(x1.empty());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#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};
|
||||
@ -752,8 +742,6 @@ namespace constructor_tests {
|
||||
BOOST_TEST(x1.find(10) != x1.end());
|
||||
BOOST_TEST(x1.find(46) == x1.end());
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace constructor_tests
|
||||
|
||||
RUN_TESTS_QUIET()
|
||||
|
@ -35,8 +35,8 @@ template <typename T> struct test_allocator
|
||||
typedef T value_type;
|
||||
test_allocator() = default;
|
||||
template <typename T2> test_allocator(test_allocator<T2> const&) {}
|
||||
T* allocate(std::size_t n) const { return (T*)malloc(sizeof(T) * n); }
|
||||
void deallocate(T* ptr, std::size_t) const { free(ptr); }
|
||||
T* allocate(std::size_t n) const { return (T*)(::operator new(sizeof(T) * n)); }
|
||||
void deallocate(T* ptr, std::size_t) const { ::operator delete(ptr); }
|
||||
bool operator==(test_allocator const&) const { return true; }
|
||||
bool operator!=(test_allocator const&) const { return false; }
|
||||
};
|
||||
|
@ -6,9 +6,10 @@
|
||||
|
||||
#include "../helpers/unordered.hpp"
|
||||
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include "../helpers/test.hpp"
|
||||
#include "../helpers/count.hpp"
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <string>
|
||||
|
||||
// Test that various emplace methods work with different numbers of
|
||||
@ -386,6 +387,7 @@ namespace emplace_tests {
|
||||
|
||||
template <class X> static void emplace_map(X*)
|
||||
{
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
test::check_instances check_;
|
||||
|
||||
typedef X container;
|
||||
@ -394,7 +396,6 @@ namespace emplace_tests {
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
// 5/8 args + duplicate
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
BOOST_TEST_EQ(check_.constructions(), 1);
|
||||
@ -450,63 +451,135 @@ namespace emplace_tests {
|
||||
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,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::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(), 4);
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
r2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::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(), 6);
|
||||
typedef X container;
|
||||
typedef typename container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
// 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(), 4);
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::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(), 10);
|
||||
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(), 6);
|
||||
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r1.first,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk")));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r2.first,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6)));
|
||||
BOOST_TEST(
|
||||
r1.first == x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::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(), 16);
|
||||
// 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(), 10);
|
||||
|
||||
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(), 16);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef X container;
|
||||
typedef typename container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
|
||||
// 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, boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::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(), 4);
|
||||
|
||||
r2 =
|
||||
x.emplace(std::piecewise_construct, boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::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(), 6);
|
||||
|
||||
// 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,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::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(), 10);
|
||||
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk")));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6)));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::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(), 16);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -540,7 +613,7 @@ namespace emplace_tests {
|
||||
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
i1 = x.emplace(std::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
@ -550,7 +623,7 @@ namespace emplace_tests {
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
emplace_value m1a(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
i2 = x.emplace(std::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
@ -564,7 +637,7 @@ namespace emplace_tests {
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
i1 = x.emplace(std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
@ -574,15 +647,15 @@ namespace emplace_tests {
|
||||
BOOST_TEST_EQ(check_.constructions(), 11);
|
||||
|
||||
emplace_value m2a(15, "jkjk");
|
||||
i2 = x.emplace_hint(i2, boost::unordered::piecewise_construct,
|
||||
i2 = x.emplace_hint(i2, std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk"));
|
||||
emplace_value m2b(275, "xxx", 'm', 6);
|
||||
i3 = x.emplace_hint(i1, boost::unordered::piecewise_construct,
|
||||
i3 = x.emplace_hint(i1, std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6));
|
||||
emplace_value m2c(-10, "blah blah", '\0');
|
||||
i4 = x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
|
||||
i4 = x.emplace_hint(x.end(), std::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(-10, "blah blah", '\0'));
|
||||
BOOST_TEST_EQ(x.size(), 6u);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "../helpers/list.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
#include <iterator>
|
||||
#include "../objects/test.hpp"
|
||||
|
@ -9,11 +9,7 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <string>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
|
||||
#define UNORDERED_LVALUE_QUAL &
|
||||
#else
|
||||
#define UNORDERED_LVALUE_QUAL
|
||||
#endif
|
||||
|
||||
namespace test {
|
||||
struct is_even
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace insert_tests {
|
||||
@ -75,7 +75,7 @@ namespace insert_tests {
|
||||
float b = x.max_load_factor();
|
||||
|
||||
typename X::value_type value = *it;
|
||||
std::pair<iterator, bool> r1 = x.insert(boost::move(value));
|
||||
std::pair<iterator, bool> r1 = x.insert(std::move(value));
|
||||
std::pair<typename ordered::iterator, bool> r2 = tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(r1.second == r2.second);
|
||||
@ -137,7 +137,7 @@ namespace insert_tests {
|
||||
float b = x.max_load_factor();
|
||||
|
||||
typename X::value_type value = *it;
|
||||
typename X::iterator r1 = x.insert(boost::move(value));
|
||||
typename X::iterator r1 = x.insert(std::move(value));
|
||||
typename test::ordered<X>::iterator r2 = tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
@ -258,7 +258,7 @@ namespace insert_tests {
|
||||
float b = x.max_load_factor();
|
||||
|
||||
typename X::value_type value = *it;
|
||||
pos = x.insert(pos, boost::move(value));
|
||||
pos = x.insert(pos, std::move(value));
|
||||
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
|
||||
BOOST_TEST(*pos == *r2);
|
||||
tracker.compare_key(x, *it);
|
||||
@ -484,7 +484,7 @@ namespace insert_tests {
|
||||
float b = x.max_load_factor();
|
||||
|
||||
typename X::value_type value = *it;
|
||||
x.emplace(boost::move(value));
|
||||
x.emplace(std::move(value));
|
||||
tracker.insert(*it);
|
||||
tracker.compare_key(x, *it);
|
||||
|
||||
@ -701,7 +701,7 @@ namespace insert_tests {
|
||||
pointer_constructible(int x_) : x(x_) {}
|
||||
pointer_constructible(pointer_constructible const& p) : x(p.x) {}
|
||||
pointer_constructible(pointer_constructible* const&) : x(-1) {}
|
||||
pointer_constructible(BOOST_RV_REF(pointer_constructible*)) : x(-1) {}
|
||||
pointer_constructible(pointer_constructible*&&) : x(-1) {}
|
||||
};
|
||||
|
||||
struct pointer_constructible_hash
|
||||
@ -1079,8 +1079,6 @@ namespace insert_tests {
|
||||
UNORDERED_TEST(set_tests2, ((test_pc_set)))
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
struct initialize_from_two_ints
|
||||
{
|
||||
int a, b;
|
||||
@ -1201,8 +1199,6 @@ namespace insert_tests {
|
||||
BOOST_TEST_EQ(multimap.size(), 3u);
|
||||
BOOST_TEST_EQ(multimap.count("a"), 2u);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct overloaded_constructor
|
||||
@ -1335,7 +1331,7 @@ namespace insert_tests {
|
||||
#endif
|
||||
|
||||
struct derived_from_piecewise_construct_t
|
||||
: boost::unordered::piecewise_construct_t
|
||||
: std::piecewise_construct_t
|
||||
{
|
||||
};
|
||||
|
||||
@ -1346,9 +1342,9 @@ namespace insert_tests {
|
||||
|
||||
struct convertible_to_piecewise
|
||||
{
|
||||
operator boost::unordered::piecewise_construct_t() const
|
||||
operator std::piecewise_construct_t() const
|
||||
{
|
||||
return boost::unordered::piecewise_construct;
|
||||
return std::piecewise_construct;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1497,7 +1493,11 @@ namespace insert_tests {
|
||||
#define EMULATING_PIECEWISE_CONSTRUCTION 1
|
||||
#include "./insert_tests.cpp"
|
||||
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
#define PIECEWISE_TEST_NAME std_tuple_boost_piecewise_tests
|
||||
#define PIECEWISE_NAMESPACE boost::unordered
|
||||
#define TUPLE_NAMESPACE std
|
||||
#define EMULATING_PIECEWISE_CONSTRUCTION 0
|
||||
#include "./insert_tests.cpp"
|
||||
|
||||
#define PIECEWISE_TEST_NAME boost_tuple_std_piecewise_tests
|
||||
#define PIECEWISE_NAMESPACE std
|
||||
@ -1507,21 +1507,6 @@ namespace insert_tests {
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
#define PIECEWISE_TEST_NAME std_tuple_boost_piecewise_tests
|
||||
#define PIECEWISE_NAMESPACE boost::unordered
|
||||
#define TUPLE_NAMESPACE std
|
||||
#define EMULATING_PIECEWISE_CONSTRUCTION 0
|
||||
#include "./insert_tests.cpp"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
static boost::unordered_flat_set<std::pair<overloaded_constructor,
|
||||
overloaded_constructor> >* test_pair_oc_set;
|
||||
@ -1535,8 +1520,6 @@ namespace insert_tests {
|
||||
#define TUPLE_NAMESPACE std
|
||||
#define EMULATING_PIECEWISE_CONSTRUCTION 0
|
||||
#include "./insert_tests.cpp"
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
RUN_TESTS_QUIET()
|
||||
@ -1549,10 +1532,6 @@ RUN_TESTS_QUIET()
|
||||
template <class X>
|
||||
static void MAP_PIECEWISE_TEST(X*)
|
||||
{
|
||||
#if EMULATING_PIECEWISE_CONSTRUCTION
|
||||
test::detail::disable_construction_tracking _scoped;
|
||||
#endif
|
||||
|
||||
X x;
|
||||
|
||||
x.emplace(PIECEWISE_NAMESPACE::piecewise_construct,
|
||||
@ -1601,10 +1580,6 @@ RUN_TESTS_QUIET()
|
||||
template <class X>
|
||||
static void SET_PIECEWISE_TEST(X*)
|
||||
{
|
||||
#if EMULATING_PIECEWISE_CONSTRUCTION
|
||||
test::detail::disable_construction_tracking _scoped;
|
||||
#endif
|
||||
|
||||
X x;
|
||||
std::pair<overloaded_constructor, overloaded_constructor> check;
|
||||
|
||||
@ -1645,9 +1620,6 @@ RUN_TESTS_QUIET()
|
||||
#ifndef BOOST_UNORDERED_FOA_TESTS
|
||||
UNORDERED_AUTO_TEST (BOOST_PP_CAT(multimap_, PIECEWISE_TEST_NAME)) {
|
||||
{
|
||||
#if EMULATING_PIECEWISE_CONSTRUCTION
|
||||
test::detail::disable_construction_tracking _scoped;
|
||||
#endif
|
||||
boost::unordered_multimap<overloaded_constructor, overloaded_constructor,
|
||||
boost::hash<overloaded_constructor>,
|
||||
std::equal_to<overloaded_constructor>,
|
||||
|
@ -48,13 +48,8 @@ template <typename T> void test_simple_allocator()
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<typename traits::difference_type, std::ptrdiff_t>::value));
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<typename traits::size_type, std::size_t>::value));
|
||||
#endif
|
||||
|
||||
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
|
@ -23,12 +23,7 @@
|
||||
|
||||
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(); }
|
||||
|
||||
@ -73,8 +68,6 @@ namespace move_tests {
|
||||
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)
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
using allocator_type = typename T::allocator_type;
|
||||
@ -86,7 +79,6 @@ namespace move_tests {
|
||||
}
|
||||
#else
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -126,8 +118,7 @@ namespace move_tests {
|
||||
|
||||
T y;
|
||||
y = empty(p);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
using allocator_type = typename T::allocator_type;
|
||||
using value_type =
|
||||
@ -138,7 +129,6 @@ namespace move_tests {
|
||||
}
|
||||
#else
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
@ -200,23 +190,8 @@ namespace move_tests {
|
||||
|
||||
test::random_values<T> v(25, generator);
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#elif defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(
|
||||
test::global_object_count.constructions - count.constructions) <=
|
||||
(test::is_set<T>::value ? 1 : 2) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#else
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(
|
||||
test::global_object_count.constructions - count.constructions) <=
|
||||
(test::is_set<T>::value ? 2 : 4) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#endif
|
||||
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
@ -313,9 +288,8 @@ namespace move_tests {
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
|
||||
y = boost::move(x);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
y = std::move(x);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
{
|
||||
using value_type =
|
||||
@ -327,7 +301,6 @@ namespace move_tests {
|
||||
}
|
||||
#else
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, 0u);
|
||||
#endif
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
@ -357,7 +330,7 @@ namespace move_tests {
|
||||
x.insert(v.begin(), v.end());
|
||||
|
||||
test::object_count count = test::global_object_count;
|
||||
y = boost::move(x);
|
||||
y = std::move(x);
|
||||
if (BOOST_UNORDERED_TEST_MOVING && allocator_type::is_propagate_on_move) {
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
}
|
||||
@ -391,7 +364,7 @@ namespace move_tests {
|
||||
test::object_count count1 = test::global_object_count;
|
||||
|
||||
T y(v1.begin(), v1.end(), 0, hf, eq, al1);
|
||||
y = boost::move(x);
|
||||
y = std::move(x);
|
||||
|
||||
test::object_count count2 = test::global_object_count;
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
// 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 <boost/config.hpp>
|
||||
|
||||
#include "../helpers/postfix.hpp"
|
||||
#include "../helpers/prefix.hpp"
|
||||
#include "../helpers/unordered.hpp"
|
||||
@ -17,6 +19,11 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#if defined(BOOST_GCC) && BOOST_GCC >= 130000
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wself-move"
|
||||
#endif
|
||||
|
||||
template <template <class Key, class T, class Hash = boost::hash<Key>,
|
||||
class Pred = std::equal_to<Key>,
|
||||
class Allocator = std::allocator<std::pair<Key const, T> > >
|
||||
@ -119,12 +126,12 @@ static void failed_insertion_with_hint()
|
||||
|
||||
typename Set<int>::node_type nh = src.extract(10);
|
||||
|
||||
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(dst.insert(dst.find(10), std::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(nh);
|
||||
BOOST_TEST(!nh.empty());
|
||||
BOOST_TEST(nh.value() == 10);
|
||||
|
||||
BOOST_TEST(dst.insert(dst.find(20), boost::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(dst.insert(dst.find(20), std::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(nh);
|
||||
BOOST_TEST(!nh.empty());
|
||||
BOOST_TEST(nh.value() == 10);
|
||||
@ -144,14 +151,14 @@ static void failed_insertion_with_hint()
|
||||
dst.emplace(20, 2);
|
||||
|
||||
typename Map<int, int>::node_type nh = src.extract(10);
|
||||
BOOST_TEST(dst.insert(dst.find(10), boost::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(dst.insert(dst.find(10), std::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(nh);
|
||||
BOOST_TEST(!nh.empty());
|
||||
BOOST_TEST(nh.key() == 10);
|
||||
BOOST_TEST(nh.mapped() == 30);
|
||||
BOOST_TEST(dst[10] == 20);
|
||||
|
||||
BOOST_TEST(dst.insert(dst.find(20), boost::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(dst.insert(dst.find(20), std::move(nh)) == dst.find(10));
|
||||
BOOST_TEST(nh);
|
||||
BOOST_TEST(!nh.empty());
|
||||
BOOST_TEST(nh.key() == 10);
|
||||
@ -195,7 +202,7 @@ template <typename Container> void node_handle_tests_impl(Container& c)
|
||||
BOOST_TEST(!n2.empty());
|
||||
node_handle_compare(n2, value);
|
||||
|
||||
node_type n3 = boost::move(n2);
|
||||
node_type n3 = std::move(n2);
|
||||
BOOST_TEST(n3);
|
||||
BOOST_TEST(!n2);
|
||||
node_handle_compare(n3, value);
|
||||
@ -203,16 +210,16 @@ template <typename Container> void node_handle_tests_impl(Container& c)
|
||||
// Maybe by swapping and observing that the allocator is
|
||||
// swapped rather than moved?
|
||||
|
||||
n1 = boost::move(n3);
|
||||
n1 = std::move(n3);
|
||||
BOOST_TEST(n1);
|
||||
BOOST_TEST(!n3);
|
||||
node_handle_compare(n1, value);
|
||||
|
||||
// Self move-assignment empties the node_handle.
|
||||
n1 = boost::move(n1);
|
||||
n1 = std::move(n1);
|
||||
BOOST_TEST(!n1);
|
||||
|
||||
n3 = boost::move(n3);
|
||||
n3 = std::move(n3);
|
||||
BOOST_TEST(!n3);
|
||||
|
||||
typename Container::value_type value1 = *c.begin();
|
||||
|
@ -57,13 +57,10 @@ namespace noexcept_tests {
|
||||
bool nothrow_swap>
|
||||
class hash_nothrow : boost::hash<int>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow)
|
||||
|
||||
typedef boost::hash<int> base;
|
||||
|
||||
public:
|
||||
hash_nothrow(BOOST_RV_REF(hash_nothrow))
|
||||
BOOST_NOEXCEPT_IF(nothrow_move_construct)
|
||||
hash_nothrow(hash_nothrow&&) noexcept(nothrow_move_construct)
|
||||
{
|
||||
if (!nothrow_move_construct) {
|
||||
test_throw("Move Constructor");
|
||||
@ -72,13 +69,13 @@ namespace noexcept_tests {
|
||||
|
||||
hash_nothrow() { test_throw("Constructor"); }
|
||||
hash_nothrow(hash_nothrow const&) { test_throw("Copy"); }
|
||||
hash_nothrow& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow))
|
||||
hash_nothrow& operator=(hash_nothrow const&)
|
||||
{
|
||||
test_throw("Assign");
|
||||
return *this;
|
||||
}
|
||||
hash_nothrow& operator=(BOOST_RV_REF(hash_nothrow))
|
||||
BOOST_NOEXCEPT_IF(nothrow_move_assign)
|
||||
hash_nothrow& operator=(hash_nothrow&&)
|
||||
noexcept(nothrow_move_assign)
|
||||
{
|
||||
if (!nothrow_move_assign) {
|
||||
test_throw("Move Assign");
|
||||
@ -90,8 +87,7 @@ namespace noexcept_tests {
|
||||
test_throw("Operator");
|
||||
return static_cast<base const&>(*this)(x);
|
||||
}
|
||||
friend void swap(hash_nothrow&, hash_nothrow&)
|
||||
BOOST_NOEXCEPT_IF(nothrow_swap)
|
||||
friend void swap(hash_nothrow&, hash_nothrow&) noexcept(nothrow_swap)
|
||||
{
|
||||
if (!nothrow_swap) {
|
||||
test_throw("Swap");
|
||||
@ -107,13 +103,11 @@ namespace noexcept_tests {
|
||||
bool nothrow_swap>
|
||||
class equal_to_nothrow
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow)
|
||||
|
||||
typedef boost::hash<int> base;
|
||||
|
||||
public:
|
||||
equal_to_nothrow(BOOST_RV_REF(equal_to_nothrow))
|
||||
BOOST_NOEXCEPT_IF(nothrow_move_construct)
|
||||
equal_to_nothrow(equal_to_nothrow&&)
|
||||
noexcept(nothrow_move_construct)
|
||||
{
|
||||
if (!nothrow_move_construct) {
|
||||
test_throw("Move Constructor");
|
||||
@ -122,13 +116,13 @@ namespace noexcept_tests {
|
||||
|
||||
equal_to_nothrow() { test_throw("Constructor"); }
|
||||
equal_to_nothrow(equal_to_nothrow const&) { test_throw("Copy"); }
|
||||
equal_to_nothrow& operator=(BOOST_COPY_ASSIGN_REF(equal_to_nothrow))
|
||||
equal_to_nothrow& operator=(equal_to_nothrow const&)
|
||||
{
|
||||
test_throw("Assign");
|
||||
return *this;
|
||||
}
|
||||
equal_to_nothrow& operator=(BOOST_RV_REF(equal_to_nothrow))
|
||||
BOOST_NOEXCEPT_IF(nothrow_move_assign)
|
||||
equal_to_nothrow& operator=(equal_to_nothrow&&)
|
||||
noexcept(nothrow_move_assign)
|
||||
{
|
||||
if (!nothrow_move_assign) {
|
||||
test_throw("Move Assign");
|
||||
@ -141,7 +135,7 @@ namespace noexcept_tests {
|
||||
return x == y;
|
||||
}
|
||||
friend void swap(equal_to_nothrow&, equal_to_nothrow&)
|
||||
BOOST_NOEXCEPT_IF(nothrow_swap)
|
||||
noexcept(nothrow_swap)
|
||||
{
|
||||
if (!nothrow_swap) {
|
||||
test_throw("Swap");
|
||||
@ -178,18 +172,9 @@ namespace noexcept_tests {
|
||||
boost::is_nothrow_swappable<hash_nothrow_swap>::value;
|
||||
|
||||
// Check that the traits work when expected.
|
||||
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && \
|
||||
!BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
|
||||
BOOST_TEST(have_is_nothrow_move);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_NOEXCEPT) && \
|
||||
!defined(BOOST_NO_CXX11_DECLTYPE) && \
|
||||
!defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
|
||||
!BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
|
||||
BOOST_TEST(have_is_nothrow_swap);
|
||||
#endif
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< "have_is_nothrow_move: " << have_is_nothrow_move << std::endl
|
||||
@ -257,7 +242,7 @@ namespace noexcept_tests {
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
X x2 = boost::move(x1);
|
||||
X x2 = std::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
BOOST_TEST(have_is_nothrow_move);
|
||||
@ -289,7 +274,7 @@ namespace noexcept_tests {
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
x2 = boost::move(x1);
|
||||
x2 = std::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
@ -318,7 +303,7 @@ namespace noexcept_tests {
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
x1 = boost::move(x2);
|
||||
x1 = std::move(x2);
|
||||
BOOST_TEST(x1.size() == 100);
|
||||
BOOST_TEST(have_is_nothrow_move_assign);
|
||||
} catch (test_exception) {
|
||||
@ -367,9 +352,8 @@ namespace noexcept_tests {
|
||||
|
||||
template <class T> class allocator1
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator1)
|
||||
allocator1 operator=(BOOST_COPY_ASSIGN_REF(allocator1));
|
||||
allocator1 operator=(BOOST_RV_REF(allocator1));
|
||||
allocator1 operator=(allocator1 const&);
|
||||
allocator1 operator=(allocator1&&);
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
@ -393,8 +377,7 @@ public:
|
||||
|
||||
template <class T> class allocator2
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(allocator2)
|
||||
allocator2 operator=(BOOST_COPY_ASSIGN_REF(allocator2));
|
||||
allocator2 operator=(allocator2 const&);
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
@ -405,7 +388,7 @@ public:
|
||||
|
||||
template <class U> allocator2(allocator2<U> const&) {}
|
||||
|
||||
allocator2& operator=(BOOST_RV_REF(allocator2)) { return *this; }
|
||||
allocator2& operator=(allocator2&&) { return *this; }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
|
@ -21,12 +21,7 @@
|
||||
|
||||
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(); }
|
||||
|
||||
@ -322,7 +317,7 @@ namespace move_tests {
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
std::size_t const size = x.size();
|
||||
y = boost::move(x);
|
||||
y = std::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())));
|
||||
@ -393,7 +388,7 @@ namespace move_tests {
|
||||
template <class T>
|
||||
static void double_move_construct(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x = boost::move(y);
|
||||
T x = std::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
@ -405,7 +400,7 @@ namespace move_tests {
|
||||
static void double_move_assign(T& y, test::random_values<T> const&)
|
||||
{
|
||||
T x;
|
||||
x = boost::move(y);
|
||||
x = std::move(y);
|
||||
x.clear();
|
||||
BOOST_TEST_EQ(y.size(),
|
||||
static_cast<typename T::size_type>(std::distance(y.begin(), y.end())));
|
||||
@ -461,10 +456,8 @@ namespace move_tests {
|
||||
unsigned num_allocs = test::detail::tracker.count_allocations;
|
||||
(void)num_allocs;
|
||||
|
||||
T x(boost::move(y));
|
||||
T x(std::move(y));
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
|
||||
@ -482,8 +475,6 @@ namespace move_tests {
|
||||
#else
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
@ -503,7 +494,7 @@ namespace move_tests {
|
||||
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);
|
||||
T x(std::move(y), al2);
|
||||
|
||||
#ifdef BOOST_UNORDERED_FOA_TESTS
|
||||
BOOST_TEST(y.empty());
|
||||
@ -530,10 +521,8 @@ namespace move_tests {
|
||||
(void)num_allocs;
|
||||
|
||||
T x(empty(ptr));
|
||||
x = boost::move(y);
|
||||
x = std::move(y);
|
||||
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(y.begin() == y.end());
|
||||
|
||||
@ -551,8 +540,6 @@ namespace move_tests {
|
||||
#else
|
||||
BOOST_TEST_EQ(y.bucket_count(), 0u);
|
||||
BOOST_TEST_EQ(test::detail::tracker.count_allocations, num_allocs);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
fps[i](y, v);
|
||||
@ -577,22 +564,15 @@ namespace move_tests {
|
||||
(void)num_allocs;
|
||||
|
||||
T x(al2);
|
||||
x = boost::move(y);
|
||||
x = std::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());
|
||||
|
@ -64,7 +64,7 @@ void prime_sizes_test()
|
||||
BOOST_TEST(!is_prime(100));
|
||||
BOOST_TEST(!is_prime(49));
|
||||
|
||||
std::size_t* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
|
||||
std::size_t const* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
|
||||
std::size_t sizes_len =
|
||||
boost::unordered::detail::prime_fmod_size<>::sizes_len;
|
||||
|
||||
@ -88,7 +88,7 @@ void prime_sizes_test()
|
||||
// correct amount of them, i.e. one for every entry in sizes[] that fits in 32
|
||||
// bits
|
||||
//
|
||||
boost::uint64_t* inv_sizes32 =
|
||||
boost::uint64_t const* inv_sizes32 =
|
||||
boost::unordered::detail::prime_fmod_size<>::inv_sizes32;
|
||||
|
||||
std::size_t inv_sizes32_len =
|
||||
@ -171,7 +171,7 @@ void get_remainder_test()
|
||||
|
||||
void modulo_test()
|
||||
{
|
||||
std::size_t* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
|
||||
std::size_t const* sizes = boost::unordered::detail::prime_fmod_size<>::sizes;
|
||||
|
||||
std::size_t const sizes_len =
|
||||
boost::unordered::detail::prime_fmod_size<>::sizes_len;
|
||||
|
@ -24,19 +24,19 @@ template <typename T> struct A
|
||||
|
||||
A() : i(++count) {}
|
||||
|
||||
template <class U> A(const A<U>& a) BOOST_NOEXCEPT : i(a.i) {}
|
||||
template <class U> A(const A<U>& a) noexcept : i(a.i) {}
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
total_allocation += n * sizeof(T);
|
||||
++num_allocations;
|
||||
return (T*)std::calloc(n, sizeof(T));
|
||||
return (T*)(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t n) BOOST_NOEXCEPT
|
||||
void deallocate(T* p, std::size_t n) noexcept
|
||||
{
|
||||
total_allocation -= n * sizeof(T);
|
||||
std::free(p);
|
||||
::operator delete(p);
|
||||
}
|
||||
|
||||
bool operator==(A const& a) const { return i == a.i; }
|
||||
|
@ -87,15 +87,11 @@ public:
|
||||
::operator delete((void*)p.operator->());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V> void construct(U* p, V const& v) { new (p) U(v); }
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
// msvc-12.0 and msvc-14.0 seem to eliminate the destructor call as we're only
|
||||
// ever using it with an int with has a trivial destructor so it eliminates
|
||||
@ -171,15 +167,11 @@ public:
|
||||
|
||||
void deallocate(pointer p, size_type) { ::operator delete((void*)p.ptr_); }
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template <class U, class V> void construct(U* p, V const& v) { new (p) U(v); }
|
||||
#else
|
||||
template <class U, class... Args>
|
||||
void construct(U* p, BOOST_FWD_REF(Args)... args)
|
||||
void construct(U* p, Args&&... args)
|
||||
{
|
||||
new (p) U(boost::forward<Args>(args)...);
|
||||
new (p) U(std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
// msvc-12.0 and msvc-14.0 seem to eliminate the destructor call as we're only
|
||||
// ever using it with an int with has a trivial destructor so it eliminates
|
||||
|
@ -27,13 +27,7 @@
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_RANDOM) || BOOST_WORKAROUND(BOOST_MSVC, < 1700)
|
||||
#define BOOST_UNORDERED_TEST_USE_STD_RANDOM_SHUFFLE
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_UNORDERED_TEST_USE_STD_RANDOM_SHUFFLE
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -1845,7 +1845,7 @@ template <class UnorderedSet> void test_set_transparent_extract(UnorderedSet*)
|
||||
BOOST_TEST_EQ(nh.value(), 0);
|
||||
BOOST_TEST_EQ(count, set_size - 3);
|
||||
|
||||
set.insert(boost::move(nh));
|
||||
set.insert(std::move(nh));
|
||||
|
||||
nh = set.extract(1);
|
||||
count = set.count(1);
|
||||
@ -1853,7 +1853,7 @@ template <class UnorderedSet> void test_set_transparent_extract(UnorderedSet*)
|
||||
BOOST_TEST_EQ(nh.value(), 1);
|
||||
BOOST_TEST_EQ(count, 0u);
|
||||
|
||||
set.insert(boost::move(nh));
|
||||
set.insert(std::move(nh));
|
||||
|
||||
nh = set.extract(1337);
|
||||
BOOST_TEST(nh.empty());
|
||||
@ -1897,7 +1897,7 @@ void test_set_non_transparent_extract(UnorderedSet*)
|
||||
BOOST_TEST_EQ(nh.value(), 0);
|
||||
BOOST_TEST_EQ(count, set_size - 3);
|
||||
|
||||
set.insert(boost::move(nh));
|
||||
set.insert(std::move(nh));
|
||||
|
||||
nh = set.extract(1);
|
||||
++key_count;
|
||||
@ -1909,7 +1909,7 @@ void test_set_non_transparent_extract(UnorderedSet*)
|
||||
BOOST_TEST_EQ(nh.value(), 1);
|
||||
BOOST_TEST_EQ(count, 0u);
|
||||
|
||||
set.insert(boost::move(nh));
|
||||
set.insert(std::move(nh));
|
||||
|
||||
nh = set.extract(1337);
|
||||
++key_count;
|
||||
|
@ -12,11 +12,11 @@
|
||||
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace unnecessary_copy_tests {
|
||||
struct count_copies
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(count_copies)
|
||||
public:
|
||||
static int copies;
|
||||
static int moves;
|
||||
@ -56,7 +56,7 @@ namespace unnecessary_copy_tests {
|
||||
trace_op("Copy construct");
|
||||
}
|
||||
|
||||
count_copies(BOOST_RV_REF(count_copies) x) : tag_(x.tag_), id_(++id_count)
|
||||
count_copies(count_copies&& x) : tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
x.tag_ = -1;
|
||||
++moves;
|
||||
@ -64,7 +64,7 @@ namespace unnecessary_copy_tests {
|
||||
}
|
||||
|
||||
count_copies& operator=(
|
||||
BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment
|
||||
count_copies const& p) // Copy assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++copies;
|
||||
@ -72,7 +72,7 @@ namespace unnecessary_copy_tests {
|
||||
return *this;
|
||||
}
|
||||
|
||||
count_copies& operator=(BOOST_RV_REF(count_copies) p) // Move assignment
|
||||
count_copies& operator=(count_copies&& p) // Move assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++moves;
|
||||
@ -189,13 +189,13 @@ namespace unnecessary_copy_tests {
|
||||
T x;
|
||||
typename T::value_type a;
|
||||
reset();
|
||||
x.insert(boost::move(a));
|
||||
x.insert(std::move(a));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(1);
|
||||
|
||||
typename T::value_type a2;
|
||||
reset();
|
||||
x.insert(boost::move(a));
|
||||
x.insert(std::move(a));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT((x.size() == 2 ? 1 : 0));
|
||||
}
|
||||
@ -209,25 +209,17 @@ namespace unnecessary_copy_tests {
|
||||
T x;
|
||||
typename T::value_type a;
|
||||
reset();
|
||||
x.insert(boost::move(a));
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
#else
|
||||
x.insert(std::move(a));
|
||||
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(1);
|
||||
#endif
|
||||
|
||||
typename T::value_type a2;
|
||||
reset();
|
||||
x.insert(boost::move(a));
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT((x.size() == 2 ? 1 : 0));
|
||||
MOVE_COUNT(0);
|
||||
#else
|
||||
x.insert(std::move(a));
|
||||
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT((x.size() == 2 ? 1 : 0));
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::unordered_set<count_copies>* set;
|
||||
@ -254,11 +246,7 @@ namespace unnecessary_copy_tests {
|
||||
reset();
|
||||
T x;
|
||||
x.emplace(source<typename T::value_type>());
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(1);
|
||||
#else
|
||||
COPY_COUNT(2);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_TEST(
|
||||
@ -266,7 +254,6 @@ namespace unnecessary_copy_tests {
|
||||
UNORDERED_TEST(
|
||||
unnecessary_copy_emplace_rvalue_test, ((set)(multiset)(map)(multimap)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template <class T> void unnecessary_copy_emplace_std_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
@ -281,7 +268,6 @@ namespace unnecessary_copy_tests {
|
||||
|
||||
UNORDERED_TEST(
|
||||
unnecessary_copy_emplace_std_move_test, ((set)(multiset)(map)(multimap)))
|
||||
#endif
|
||||
|
||||
template <class T> void unnecessary_copy_emplace_boost_move_test(T*)
|
||||
{
|
||||
@ -290,15 +276,9 @@ namespace unnecessary_copy_tests {
|
||||
typename T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
#else
|
||||
// Since std::pair isn't movable, move only works for sets.
|
||||
COPY_COUNT_RANGE(1, 2);
|
||||
MOVE_COUNT_RANGE(0, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_TEST(
|
||||
@ -311,7 +291,7 @@ namespace unnecessary_copy_tests {
|
||||
typename T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
x.emplace(boost::move(a));
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
}
|
||||
@ -328,14 +308,10 @@ namespace unnecessary_copy_tests {
|
||||
typename T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
#else
|
||||
x.emplace(std::move(a));
|
||||
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_TEST(
|
||||
@ -393,7 +369,7 @@ namespace unnecessary_copy_tests {
|
||||
|
||||
// No move should take place.
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
@ -457,7 +433,7 @@ namespace unnecessary_copy_tests {
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
|
||||
// This is a little odd, Visual C++ 11 seems to move the pair, which
|
||||
// results in one copy (for the const key) and one move (for the
|
||||
// non-const mapped value). Since 'emplace(boost::move(a))' (see below)
|
||||
// non-const mapped value). Since 'emplace(std::move(a))' (see below)
|
||||
// has the normal result, it must be some odd consequence of how
|
||||
// Visual C++ 11 handles calling move for default arguments.
|
||||
COPY_COUNT(3);
|
||||
@ -469,7 +445,7 @@ namespace unnecessary_copy_tests {
|
||||
#endif
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
|
||||
x.emplace(std::piecewise_construct, boost::make_tuple(),
|
||||
boost::make_tuple());
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(0);
|
||||
@ -504,7 +480,7 @@ namespace unnecessary_copy_tests {
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
@ -536,16 +512,14 @@ namespace unnecessary_copy_tests {
|
||||
MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
x.emplace(std::piecewise_construct,
|
||||
boost::make_tuple(boost::ref(b.first)),
|
||||
boost::make_tuple(boost::ref(b.second)));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
#if BOOST_UNORDERED_TUPLE_ARGS
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
x.emplace(std::piecewise_construct,
|
||||
std::make_tuple(std::ref(b.first)), std::make_tuple(std::ref(b.second)));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
@ -559,23 +533,17 @@ namespace unnecessary_copy_tests {
|
||||
|
||||
std::pair<count_copies const, count_copies> move_source;
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
x.emplace(std::piecewise_construct,
|
||||
std::make_tuple(std::move(move_source.first)),
|
||||
std::make_tuple(std::move(move_source.second)));
|
||||
COPY_COUNT(tuple_copy_cost);
|
||||
MOVE_COUNT(tuple_move_cost);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
!(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 6) && \
|
||||
!(defined(BOOST_MSVC) && BOOST_MSVC < 1700)
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
x.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(b.first), std::forward_as_tuple(b.second));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user