diff --git a/doc/unordered/changes.adoc b/doc/unordered/changes.adoc index f8074c2c..f99979c0 100644 --- a/doc/unordered/changes.adoc +++ b/doc/unordered/changes.adoc @@ -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 diff --git a/doc/unordered/compliance.adoc b/doc/unordered/compliance.adoc index 897c7dfb..a299465a 100644 --- a/doc/unordered/compliance.adoc +++ b/doc/unordered/compliance.adoc @@ -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 <>), 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::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 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: diff --git a/doc/unordered/unordered_map.adoc b/doc/unordered/unordered_map.adoc index 121d5389..5b70df80 100644 --- a/doc/unordered/unordered_map.adoc +++ b/doc/unordered/unordered_map.adoc @@ -26,12 +26,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::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::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 +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. --- @@ -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` 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`. -- --- @@ -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` 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`. -- --- @@ -1766,9 +1720,7 @@ template 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 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++ diff --git a/doc/unordered/unordered_multimap.adoc b/doc/unordered/unordered_multimap.adoc index 52b23d9a..6c50b857 100644 --- a/doc/unordered/unordered_multimap.adoc +++ b/doc/unordered/unordered_multimap.adoc @@ -26,12 +26,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::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::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 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 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. --- diff --git a/doc/unordered/unordered_multiset.adoc b/doc/unordered/unordered_multiset.adoc index a1ee1a57..7fd265bc 100644 --- a/doc/unordered/unordered_multiset.adoc +++ b/doc/unordered/unordered_multiset.adoc @@ -24,12 +24,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::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::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 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 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. --- diff --git a/doc/unordered/unordered_set.adoc b/doc/unordered/unordered_set.adoc index 4b50b21f..14b51eb9 100644 --- a/doc/unordered/unordered_set.adoc +++ b/doc/unordered/unordered_set.adoc @@ -24,12 +24,12 @@ namespace boost { using hasher = Hash; using key_equal = Pred; using allocator_type = Allocator; - using pointer = typename boost::allocator_traits::pointer; - using const_pointer = typename boost::allocator_traits::const_pointer; + using pointer = typename std::allocator_traits::pointer; + using const_pointer = typename std::allocator_traits::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::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 +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 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 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. ---