mirror of
https://github.com/boostorg/poly_collection.git
synced 2026-01-19 16:32:14 +00:00
* disallowed fixed_variant with no types
* protected fixed_variant copy/assignment
* documented disallowance of fixed_variant copy/assignment
* worked around spurious C2248 msvc-14.{0|1}
* fixed workaround
1930 lines
80 KiB
Plaintext
1930 lines
80 KiB
Plaintext
[/
|
|
Copyright 2016-2025 Joaquin M Lopez Munoz.
|
|
Distributed under the Boost Software License, Version 1.0.
|
|
(See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt)
|
|
]
|
|
|
|
[def _AllocatorAwareContainer_ [@http://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer [* `AllocatorAwareContainer`]]]
|
|
[def _Callable_ [@http://en.cppreference.com/w/cpp/named_req/Callable [* `Callable`]]]
|
|
[def _Container_ [@http://en.cppreference.com/w/cpp/named_req/Container [* `Container`]]]
|
|
[def _CopyAssignable_ [@http://en.cppreference.com/w/cpp/named_req/CopyAssignable [* `CopyAssignable`]]]
|
|
[def _CopyInsertable_ [@http://en.cppreference.com/w/cpp/named_req/CopyInsertable [* `CopyInsertable`]]]
|
|
[def _DefaultConstructible_ [@http://en.cppreference.com/w/cpp/named_req/DefaultConstructible [* `DefaultConstructible`]]]
|
|
[def _InputIterator_ [@http://en.cppreference.com/w/cpp/named_req/InputIterator [* `InputIterator`]]]
|
|
[def _INVOKE_ [@http://en.cppreference.com/w/cpp/utility/functional/invoke ['[* `INVOKE`]]]]
|
|
[def _MoveAssignable_ [@http://en.cppreference.com/w/cpp/named_req/MoveAssignable [* `MoveAssignable`]]]
|
|
[def _MoveInsertable_ [@http://en.cppreference.com/w/cpp/named_req/MoveInsertable [* `MoveInsertable`]]]
|
|
|
|
[section Reference]
|
|
|
|
[section Polymorphism models]
|
|
|
|
[def _polymorphism_model_ [link poly_collection.reference.polymorphism_models polymorphism model]]
|
|
|
|
The key aspect of dynamic polymorphism is the ability for a value of type `T`
|
|
to internally use another value of a possibily different type `U` for the
|
|
implementation of a given interface. Base/derived polymorphism is the classic
|
|
model of dynamic polymorphism in C++, but not the only possible one.
|
|
|
|
Formally, a /polymorphism model/ is defined by
|
|
|
|
* A family *Interface* of permissible interface types and, for each
|
|
`I` \u2208 *Interface*, the family *Implementation*(`I`) of types satisfying
|
|
`I`.
|
|
* For a given interface type `I`, an operation *subobject*(`x`) that maps each
|
|
value of an implementation type to its internally used value `y` of a possibly
|
|
different implementation type
|
|
[footnote This is a metalinguistic definition not directly expressible in C++.
|
|
There are equivalent formulations that can indeed be realized in C++, but
|
|
they add little to the comprehension of the concepts.].
|
|
|
|
Static polymorphism is the trivial case where *subobject*(`x`) = `x` for all
|
|
`x`. Base/derived polymorphism is characterized by:
|
|
|
|
* *Interface* = { `Base` : `std::is_polymorphic_v<Base>` }.
|
|
* *Implementation*(`Base`) = { `Derived` : `std::is_base_of_v<Base,Derived>` }.
|
|
* *subobject*(`x`) = `static_cast<Derived&>(x)` with `typeid(x)==typeid(Derived)`.
|
|
|
|
A polymorphism model is called /closed/ if, for any `I` \u2208 *Interface*,
|
|
*suboject* ranges over a finite subset ot types of *Implementation*(`I`),
|
|
that is, there is only a finite number of types subojects can belong in.
|
|
A non-closed model is called /open/.
|
|
|
|
[endsect]
|
|
|
|
[section Polymorphic containers]
|
|
|
|
[def _PolymorphicContainer_ [link poly_collection.reference.polymorphic_containers [* `PolymorphicContainer`]]]
|
|
|
|
A /polymorphic container/ is an object that stores objects of some type `T`
|
|
implementing a given interface `I` under an implicitly associated polymorphism
|
|
model. Polymorphic containers satisfy the requirements for _Container_ and
|
|
_AllocatorAwareContainer_ with the following modifications:
|
|
|
|
* Where it occurs, replace the requirement that `T` be _CopyInsertable_,
|
|
_CopyAssignable_, _MoveInsertable_, _MoveAssignable_ or
|
|
_EqualityComparable_, with the following semantic clause: may throw if
|
|
some subobject in the container is not
|
|
_CopyConstructible_ (respectively, _CopyAssignable_, _MoveConstructible_,
|
|
_MoveAssignable_, _EqualityComparable_).
|
|
* Replace [container.requirements.general]/3 with:
|
|
`allocator_type` must have the property that for any type `U`
|
|
implementing `I` and the associated type `A` =
|
|
`std::allocator_traits<allocator_type>::rebind_alloc<U>`, `U` is
|
|
_CopyInsertable_ (respectively _MoveInsertable_) with respect to `A` if and
|
|
only if `U` is _CopyConstructible_ (respectively _MoveConstructible_);
|
|
all subobjects of type `U` stored in these containers shall be constructed
|
|
using the `std::allocator_traits<A>::construct` function and
|
|
destroyed using the `std::allocator_traits<A>::destroy` function;
|
|
these functions (or their equivalents for a rebound allocator) are called
|
|
only for the types of the stored subobjects, not for
|
|
any other type (internal or public) used by the container.
|
|
|
|
[section Polymorphic collections]
|
|
|
|
[def _PolymorphicCollection_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections [* `PolymorphicCollection`]]]
|
|
|
|
/Polymorphic collections/ store their objects of type `value_type` in
|
|
/segments/ dedicated to each of the types of the contained subojects.
|
|
Only objects whose subobjects are of an /acceptable/ type are allowed,
|
|
where a type `U` is said to be acceptable if
|
|
|
|
* it implements the interface associated to the container,
|
|
* it is _MoveConstructible_,
|
|
* it is _MoveAssignable_ or
|
|
[@http://en.cppreference.com/w/cpp/types/is_move_constructible
|
|
`std::is_nothrow_move_constructible<U>::value`] is `true`.
|
|
|
|
The collection is /open/ (resp. /closed/) if its associated polymorphism model
|
|
is open (resp. closed).
|
|
Polymorphic collections conform
|
|
to the requirements of _PolymorphicContainer_ with the following
|
|
modifications and extra guarantees:
|
|
|
|
* The complexity of `empty()` and `size()` is linear on the number of
|
|
segments of the collection.
|
|
* `max_size()` is not provided.
|
|
* `a==b` evaluates to `true` iff for each non-empty segment of subojects
|
|
of type `U` in `a` there is a segment of `U` in `b` with the same size
|
|
and equal elements in the same order, and vice versa.
|
|
* No exceptions are thrown associated to some subobject type not being
|
|
_CopyAssignable_, _MoveConstructible_ or _MoveAssignable_.
|
|
|
|
A type `U` is said to be /registered/ into the collection if a
|
|
(possibly empty) segment for `U` has been created. Registered types
|
|
continue to stay so for the duration of the container except if it is
|
|
moved from, assigned to, or swapped. For closed collections, all
|
|
acceptable types are automatically registered upon construction.
|
|
|
|
Each segment has an associated capacity indicating the maximum size
|
|
that it can attain without reallocation. When the limit
|
|
is exceeded (or explicitly through `reserve`) new storage space is
|
|
allocated with greater capacity and elements are moved.
|
|
|
|
Collection traversal goes through the elements of the first segment,
|
|
then the second, etc. For open collections, the order in which segments
|
|
are visited is unspecified but remains stable until a new segment is created.
|
|
For closed collections, segment order is fixed and determined by
|
|
the specification of the collection type.
|
|
|
|
Besides `iterator` and `const_iterator`, there are iterator types
|
|
`local_base_iterator` and `local_iterator<U>` (and their `const_`
|
|
counterparts) whose objects can be used to iterate over the segment
|
|
for `U` (in the same order followed by global traversal).
|
|
Local base iterators refer to `value_type`, whereas
|
|
(`const_`)`local_iterator<U>` refers to `U`. All local iterators model
|
|
_RandomAccessIterator_. Local base iterators may not be used
|
|
to iterate across segments, and comparing local base iterators
|
|
associated to different segments is undefined behavior. A (const)
|
|
local base iterator to a segment for `U` can be explicitly converted
|
|
to (`const_`)`local_iterator<U>` pointing to the same position,
|
|
and vice versa.
|
|
|
|
Insertion and erasure do not invalidate iterators (global or local)
|
|
except those from the insertion/erasure point to the end of the
|
|
affected segment, if its capacity is not exceeded, or all
|
|
iterators/references to the segment otherwise
|
|
[footnote The global `end()` iterator lies outside any segment, hence
|
|
it always remain valid.].
|
|
|
|
For the description of the remaining requirements of polymorphic collections,
|
|
we use the following notation:
|
|
|
|
* `C` is a polymorphic collection type,
|
|
* `c` is an object of type `C`, `cc` is a possibly `const` object of type `C`,
|
|
* `al` is a value of type `C::allocator_type`,
|
|
* `info` is a value of type `const C::index_type&`,
|
|
* `U` is an acceptable type, `Us...` is a template parameter pack of
|
|
acceptable types,
|
|
* `n` is a value of `size_type`,
|
|
* `x` is a value of a type `T` implementing the interface associated to the
|
|
collection,
|
|
* `args...` is a function parameter pack of types `Args&&...`,
|
|
* `it` is a possibly const global iterator of `c`,
|
|
* `it1` and `it2` are (same-typed) possibly const global iterators of a `C`
|
|
collection other than `c` such that \[`it1`, `it2`) is a valid range.
|
|
* `lbit` is a possibly const local base iterator of `c`,
|
|
* `lbit1` and `lbit2` are (same-typed) possibly const local base iterators of
|
|
a `C` collection other than `c` such that \[`lbit1`, `lbit2`) is a valid range.
|
|
* `lit` is a (`const_`)`local_iterator<U>` of `c`,
|
|
* `lit1` and `lit2` are (same-typed) (`const_`)`local_iterator<U>`s of
|
|
a `C` collection other than `c` such that \[`lit1`, `lit2`) is a valid range,
|
|
* `i1` and `i2` are iterators external to `c` referring to `T` such that
|
|
\[`i1`, `i2`) is a valid range,
|
|
* `j1` and `j2` are iterators external to `c` such that
|
|
\[`j1`, `j2`) is a valid range,
|
|
* `xit1` and `xit2` are (same-typed) possibly const iterators (global or
|
|
local) of `c` such that \[`xit1`, `xit2`) is a valid range.
|
|
|
|
[section Types]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.type_index]
|
|
[def _type_index_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.type_index `type_index`]]
|
|
|
|
`C::type_index`
|
|
|
|
Can be either `std::type_info` or `std::size_t`. We define `index<U>` as follows:
|
|
|
|
* if `type_index` is `std::type_info`: `typeid(U)`,
|
|
* if `type_index` is `std::size_t`: the index number `i` such that `U` is the `i`-th
|
|
element in `Us...`, where `Us...` is the list of acceptable types as specified in the
|
|
associated polymorphism model.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.local_base_iterator]
|
|
[def _local_base_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.local_base_iterator `local_base_iterator`]]
|
|
|
|
`C::local_base_iterator`
|
|
|
|
_RandomAccessIterator_ with same value type, difference type and pointer and
|
|
reference types as `C::iterator`, valid for accessing elements of a given
|
|
segment. Implicily convertible to `C::const_local_base_iterator`, explicitly
|
|
convertible to `C::local_iterator<U>` if the segment it points to is actually
|
|
that for `U`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_local_base_iterator]
|
|
[def _const_local_base_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_local_base_iterator `const_local_base_iterator`]]
|
|
|
|
`C::const_local_base_iterator`
|
|
|
|
_RandomAccessIterator_ with same value type, difference type and pointer and
|
|
reference types as `C::const_iterator`, valid for accessing elements of a given
|
|
segment. Explicitly convertible to `C::const_local_iterator<U>` if the segment
|
|
it points to is actually that for `U`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.local_iterator]
|
|
[def _local_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.local_iterator `local_iterator`]]
|
|
|
|
`C::local_iterator<U>`
|
|
|
|
_RandomAccessIterator_ with value type `U`, reference type `U&`, pointer type
|
|
`U*` and the same difference type as `C::iterator`, valid for accessing elements
|
|
of the segment for `U`. Implicily convertible to `C::const_local_iterator<U>`,
|
|
explicitly convertible to `C::local_base_iterator`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_local_iterator]
|
|
[def _const_local_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_local_iterator `const_local_iterator`]]
|
|
|
|
`C::const_local_iterator<U>`
|
|
|
|
_RandomAccessIterator_ with value type `U`, reference type `const U&`, pointer
|
|
type `const U*` and the same difference type as `C::iterator`, valid for
|
|
accessing elements of the segment for `U`. Explicitly convertible to
|
|
`C::const_local_base_iterator`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_base_segment_info]
|
|
[def _const_base_segment_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_base_segment_info `const_base_segment_info`]]
|
|
|
|
`C::const_base_segment_info`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type with information about a given
|
|
segment of a collection. If `ci` is a possibly `const` object of type
|
|
`C::const_base_segment_info` associated to the segment of `c` for `U`, then
|
|
|
|
* `ci.begin()==c.cbegin(index<U>)`
|
|
* `ci.cbegin()==c.cbegin(index<U>)`
|
|
* `ci.begin<U>()==c.cbegin<U>()`
|
|
* `ci.cbegin<U>()==c.cbegin<U>()`
|
|
* `ci.end()==c.cend(index<U>)`
|
|
* `ci.cend()==c.cend(index<U>)`
|
|
* `ci.end<U>()==c.cend<U>()`
|
|
* `ci.cend<U>()==c.cend<U>()`
|
|
* `ci.type_info()==index<U>`
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.base_segment_info]
|
|
[def _base_segment_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.base_segment_info `base_segment_info`]]
|
|
|
|
`C::base_segment_info`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type publicly derived from
|
|
`C::const_base_segment_info` and exposing its public interface. Additionally,
|
|
if `i` is an object of type `C::base_segment_info` associated to the
|
|
segment of `c` for `U`, then
|
|
|
|
* `i.begin()==c.begin(index<U>)`
|
|
* `i.begin<U>()==c.begin<U>()`
|
|
* `i.end()==c.end(index<U>)`
|
|
* `i.end<U>()==c.end<U>()`
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_segment_info]
|
|
[def _const_segment_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_segment_info `const_segment_info`]]
|
|
|
|
`C::const_segment_info<U>`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type with information about the segment
|
|
for `U`. If `ci` is a possibly `const` object of type `C::const_segment_info<U>`
|
|
associated to the collection `c`, then
|
|
|
|
* `ci.begin()==c.cbegin<U>()`
|
|
* `ci.cbegin()==c.cbegin<U>()`
|
|
* `ci.end()==c.cend<U>()`
|
|
* `ci.cend()==c.cend<U>()`
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.segment_info]
|
|
[def _segment_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.segment_info `segment_info`]]
|
|
|
|
`C::segment_info<U>`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type publicly derived from
|
|
`C::const_segment_info<U>` and exposing its public interface. Additionally,
|
|
if `i` is an object of type `C::segment_info<U>` associated to the collection
|
|
`c`, then
|
|
|
|
* `i.begin()==c.begin<U>()`
|
|
* `i.end()==c.end<U>()`
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.base_segment_info_iterator]
|
|
[def _base_segment_info_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.base_segment_info_iterator `base_segment_info_iterator`]]
|
|
|
|
`C::base_segment_info_iterator`
|
|
|
|
_InputIterator_ with value type and reference type `C::base_segment_info`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_base_segment_info_iterator]
|
|
[def _const_base_segment_info_iterator_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_base_segment_info_iterator `const_base_segment_info_iterator`]]
|
|
|
|
`C::const_base_segment_info_iterator`
|
|
|
|
_InputIterator_ with value type and reference type `C::const_base_segment_info`.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_segment_traversal_info]
|
|
[def _const_segment_traversal_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.const_segment_traversal_info `const_segment_traversal_info`]]
|
|
|
|
`C::const_segment_traversal_info`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type with `const` member
|
|
functions `begin`/`cbegin` and `end`/`cend` returning
|
|
`C::const_base_segment_info_iterator` objects that span over a range
|
|
of `C::const_base_segment_info` objects.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.types.segment_traversal_info]
|
|
[def _segment_traversal_info_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.types.segment_traversal_info `segment_traversal_info`]]
|
|
|
|
`C::segment_traversal_info`
|
|
|
|
_CopyConstructible_ and _CopyAssignable_ type publicly derived
|
|
from with `C::const_segment_traversal_info` and exposing its
|
|
public interface. Additionally, provides non-const member
|
|
functions `begin` and `end` returning
|
|
`C::base_segment_info_iterator` objects that span over an equivalent range
|
|
of `C::base_segment_info` objects.
|
|
|
|
[endsect]
|
|
|
|
[section Construct/copy/destroy]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.construct_copy_destroy.range_construction]
|
|
|
|
`C(j1,j2)`[br]
|
|
`C d(j1,j2)`
|
|
|
|
[*Requires:] `C::allocator_type` is _DefaultConstructible_. \[`j1`, `j2`) can be
|
|
inserted into `C`.[br]
|
|
[*Effects:] Copy constructs the internal allocator from `C::allocator_type()`.
|
|
Internally calls `this->insert(j1,j2)` on construction.
|
|
|
|
`C(j1,j2,al)`[br]
|
|
`C d(j1,j2,al)`
|
|
|
|
[*Requires:] \[`j1`, `j2`) can be inserted into `C`.[br]
|
|
[*Effects:] Copy constructs the internal allocator from `al`.
|
|
Internally calls `this->insert(j1,j2)` on construction.
|
|
|
|
[endsect]
|
|
|
|
[section:type_registration Type registration (open collections only)]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.type_registration.register_types]
|
|
[def _register_types_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.type_registration.register_types `register_types`]]
|
|
|
|
`c.register_types<Us...>()`
|
|
|
|
[*Effects:] Registers (if needed) each of the indicated types in the
|
|
collection.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.type_registration.is_registered]
|
|
[def _is_registered_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.type_registration.is_registered `is_registered`]]
|
|
|
|
`cc.is_registered(info)`[br]
|
|
`cc.is_registered<U>()`
|
|
|
|
[*Returns:] `true` iff the indicated type is registered in the collection.
|
|
|
|
[endsect]
|
|
|
|
[section Iterators]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.begin]
|
|
[def _begin_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.begin `begin`]]
|
|
[def _cbegin_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.begin `cbegin`]]
|
|
|
|
(1) `c.begin(info)`[br]
|
|
(2) `c.begin<U>()`[br]
|
|
(3) `const_cast<const C&>(c).begin(info)`[br]
|
|
(4) `cc.cbegin(info)`[br]
|
|
(5) `const_cast<const C&>(c).begin<U>()`[br]
|
|
(6) `cc.cbegin<U>()`
|
|
|
|
[*Returns:] A `local_base_iterator` (1) or `local_iterator<U>` (2) or
|
|
`const_local_base_iterator` (3,4) or `const_local_iterator<U>` (5,6) to the
|
|
beginning of the segment for the indicated type.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.end]
|
|
[def _end_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.end `end`]]
|
|
[def _cend_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.end `cend`]]
|
|
|
|
(1) `c.end(info)`[br]
|
|
(2) `c.end<U>()`[br]
|
|
(3) `const_cast<const C&>(c).end(info)`[br]
|
|
(4) `cc.cend(info)`[br]
|
|
(5) `const_cast<const C&>(c).end<U>()`[br]
|
|
(6) `cc.cend<U>()`
|
|
|
|
[*Returns:] A `local_base_iterator` (1) or `local_iterator<U>` (2) or
|
|
`const_local_base_iterator` (3,4) or `const_local_iterator<U>` (5,6) to the
|
|
end of the segment for the indicated type.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.segment]
|
|
[def _segment_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.segment `segment`]]
|
|
|
|
(1) `c.segment(info)`[br]
|
|
(2) `c.segment<U>()`[br]
|
|
(3) `const_cast<const C&>(c).segment(info)`[br]
|
|
(4) `const_cast<const C&>(c).segment<U>()`[br]
|
|
|
|
[*Returns:] A `base_segment_info` (1) or `segment_info<U>` (2) or
|
|
`const_base_segment_info` (3) or `const_segment_info<U>` (4) object
|
|
referring to the segment for the indicated type.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.segment_traversal]
|
|
[def _segment_traversal_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.iterators.segment_traversal `segment_traversal`]]
|
|
|
|
(1) `c.segment_traversal()`[br]
|
|
(2) `const_cast<const C&>(c).segment_traversal()`
|
|
|
|
[*Returns:] A `segment_traversal_info` (1) or `const_segment_traversal_info`
|
|
(2) object spanning over a range of segment descriptors for the collection.
|
|
The order in which segments are visited matches that of
|
|
\[`c.begin()`, `c.end()`).
|
|
|
|
[endsect]
|
|
|
|
[section Capacity]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.empty]
|
|
[def _empty_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.empty `empty`]]
|
|
|
|
`cc.empty(info)`[br]
|
|
`cc.empty<U>()`
|
|
|
|
[*Returns:] `true` iff the segment for the indicated type exists and
|
|
is empty.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.size]
|
|
[def _size_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.size `size`]]
|
|
|
|
`cc.size(info)`[br]
|
|
`cc.size<U>()`
|
|
|
|
[*Returns:] The size of the segment for the indicated type.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.max_size]
|
|
[def _max_size_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.max_size `max_size`]]
|
|
|
|
`cc.max_size(info)`[br]
|
|
`cc.max_size<U>()`
|
|
|
|
[*Returns:] The maximum size attainable by the segment for
|
|
the indicated type.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.capacity]
|
|
[def _capacity_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.capacity `capacity`]]
|
|
|
|
`cc.capacity(info)`[br]
|
|
`cc.capacity<U>()`[br]
|
|
|
|
[*Returns:] The maximum size that the segment for the indicated type can
|
|
attain without requiring reallocation.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.reserve]
|
|
[def _reserve_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.reserve `reserve`]]
|
|
|
|
`c.reserve(n)`
|
|
|
|
[*Effects:] Calls `reserve` with `n` for each of the segments of the
|
|
collection.
|
|
|
|
(1) `c.reserve(info,n)`[br]
|
|
(2) `c.reserve<U>(n)`
|
|
|
|
[*Effects:] Throws if the type indicated by `info` is not registered (1)
|
|
or registers `U` if needed (2). If `n` is greater than the current
|
|
capacity of the segment for the indicated type, new storage space is allocated
|
|
with a capacity of at least `n` and elements are moved there.[br]
|
|
[*Complexity:] Linear in the size of the segment if reallocation happens,
|
|
constant otherwise.[br]
|
|
[*Throws:] `std::length_error` if `n` is greater than the return value of
|
|
`max_size` for the segment.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.shrink_to_fit]
|
|
[def _shrink_to_fit_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.capacity.shrink_to_fit `shrink_to_fit`]]
|
|
|
|
`c.shrink_to_fit()`
|
|
|
|
[*Effects:] Calls `shrink_to_fit` for each of the segments of the
|
|
collection.
|
|
|
|
`c.shrink_to_fit(info)`[br]
|
|
`c.shrink_to_fit<U>()`
|
|
|
|
[*Effects:] Non-binding request to reduce memory usage while preserving the
|
|
sequence of elements of the segment for the indicated type. May invalidate
|
|
all iterators and references to the segment.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[endsect]
|
|
|
|
[section Modifiers]
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.emplace]
|
|
[def _emplace_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.emplace `emplace`]]
|
|
[def _emplace_hint_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.emplace `emplace_hint`]]
|
|
|
|
(1) `c.emplace<U>(args...)`[br]
|
|
(2) `c.emplace_hint<U>(it,args...)`
|
|
|
|
[*Requires:] `U` is constructible from `std::forward<Args>(args)...`.[br]
|
|
[*Effects:] Registers `U` (if needed) and inserts a new element with
|
|
a subobject constructed from `std::forward<Args>(args)...`: (1) at the end of
|
|
the segment for `U`; (2) just before the
|
|
position indicated by `it`, if it points to the segment for `U`, or at the
|
|
end of the segment for `U` otherwise.[br]
|
|
[*Returns:] An `iterator` to the newly inserted element.[br]
|
|
[*Complexity:] Amortized constant time plus linear in the distance from the
|
|
insertion position to the end of the segment.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.emplace_pos]
|
|
[def _emplace_pos_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.emplace_pos `emplace_pos`]]
|
|
|
|
(1) `c.emplace_pos<U>(lbit,args...)`[br]
|
|
(2) `c.emplace_pos(lit,args...)`
|
|
|
|
[*Requires:] `U` is constructible from `std::forward<Args>(args)...`.
|
|
(1) `lbit` points to the segment for `U`.[br]
|
|
[*Effects:] Inserts a new element with
|
|
a subobject constructed from `std::forward<Args>(args)...` just before the
|
|
position indicated.[br]
|
|
[*Returns:] A `local_base_iterator` (1) or `local_iterator<U>` (2) to the
|
|
newly inserted element.[br]
|
|
[*Complexity:] Amortized constant time plus linear in the distance from
|
|
the insertion position to the end of the segment.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert]
|
|
[def _insert_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert `insert`]]
|
|
[def _insert_hint_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert `insert`]]
|
|
|
|
(1) `c.insert(x)`[br]
|
|
(2) `c.insert(it,x)`
|
|
|
|
[*Effects:] Let `Q` be the type of the subobject of `x`. If
|
|
`Q` = `T` and `T` is acceptable, registers `T` if needed.
|
|
If `Q` = `T` and `T` is not acceptable, throws.
|
|
If `Q` \u2260 `T` and `Q` is not registered, throws.
|
|
If `x` is not a non-const rvalue expression and `Q` is not _CopyConstructible_, throws.
|
|
Inserts an element with a subobject move constructed or copy constructed
|
|
from the subobject of `x`: (1) at the end of the corresponding segment;
|
|
(2) just before the position indicated by `it`, if it points to the
|
|
corresponding segment, or at the end of the segment otherwise.[br]
|
|
[*Returns:] An `iterator` to the newly inserted element.[br]
|
|
[*Complexity:] Amortized constant time plus linear in the distance
|
|
from the insertion position to the end of the segment.
|
|
|
|
(1) `c.insert(lbit,x)`[br]
|
|
(2) `c.insert(lit,x)`
|
|
|
|
[*Requires:] The type of the subobject of `x` corresponds to the indicated
|
|
segment.[br]
|
|
[*Effects:] Inserts an element with a subobject move constructed or copy
|
|
constructed from the subobject of `x` just before the
|
|
position indicated.[br]
|
|
[*Returns:] A `local_base_iterator` (1) or `local_iterator<U>` (2) to the
|
|
newly inserted element.[br]
|
|
[*Complexity:] Amortized constant time plus linear in the distance
|
|
from the insertion position to the end of the segment.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert_range]
|
|
[def _insert_range_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert_range `insert`]]
|
|
|
|
`c.insert(i1,i2)`
|
|
|
|
[*Effects:] Equivalent to `while(i1!=i2)c.insert(*i1++)`.
|
|
|
|
`c.insert(it1,it2)`[br]
|
|
`c.insert(lbit1,lbit2)`[br]
|
|
`c.insert(lit1,lit2)`
|
|
|
|
[*Effects:] For each of the elements of the range in succession, registers the
|
|
type of its subobject if needed and inserts it into the collection
|
|
[footnote Note that, unlike `c.insert(i1,i2)`, these versions do not throw
|
|
due to type registration problems.].
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert_hint_range]
|
|
[def _insert_hint_range_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.insert_hint_range `insert`]]
|
|
|
|
`c.insert(it,i1,i2)`
|
|
|
|
[*Effects:] If `it==c.end()`, equivalent to `while(i1!=i2)c.insert(it,*i1++)`,
|
|
otherwise inserts each of the elements in \[`i1`, `i2`) in succession with a hint
|
|
pointing to `*it`
|
|
[footnote That is, the hint remains stable even if `it` may become invalid due
|
|
to reallocations.].
|
|
|
|
`c.insert(it,it1,it2)`[br]
|
|
`c.insert(it,lbit1,lbit2)`[br]
|
|
`c.insert(it,lit1,lit2)`
|
|
|
|
[*Effects:] If `it==c.end()`, equivalent to the corresponding hint-less version,
|
|
otherwise for each of the elements in \[`i1`, `i2`) in succession registers the
|
|
type of its subobject if needed and inserts it into the collection with a hint
|
|
pointing to `*it`
|
|
[footnote The two previous notes apply here.].
|
|
|
|
`c.insert(lbit,i1,i2)`
|
|
|
|
[*Requires:] The subojects of elements in \[`i1`, `i2`) are all of the type
|
|
corresponding to the indicated segment.[br]
|
|
[*Effects:] Inserts a range of elements with subobjects copy constructed from
|
|
those in \[`i1`, `i2`) just before `lbit`.[br]
|
|
[*Returns:] A `local_base_iterator` to the beginning of the inserted range.
|
|
|
|
`c.insert(lit,j1,j2)`
|
|
|
|
[*Requires:] For each value `x` in \[`j1`, `j2`) either (a) `x` is of a type
|
|
implementing the interface associated to the collection and the subobject of
|
|
`x` is of type `U` or (b) `U` is constructible from `x`.[br]
|
|
[*Effects:] Inserts a range of elements with subobjects copy
|
|
constructed (a) or constructed (b) from the values in \[`j1`, `j2`)
|
|
just before `lit`.[br]
|
|
[*Returns:] A `local_iterator<U>` to the beginning of the inserted range.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.erase]
|
|
[def _erase_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.erase `erase`]]
|
|
|
|
`c.erase(xit1)`[br]
|
|
`c.erase(xit1,xit2)`
|
|
|
|
[*Effects:] Erases the indicated element(s).[br]
|
|
[*Returns:] A non-const iterator of the same category as `xit` pointing
|
|
to the position just after the erased element(s).[br]
|
|
[*Complexity:] Linear on the number of elements erased plus the distance
|
|
from the last one to the end of its segment.
|
|
|
|
[#poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.clear]
|
|
[def _clear_ [link poly_collection.reference.polymorphic_containers.polymorphic_collections.modifiers.clear `clear`]]
|
|
|
|
`c.clear()`
|
|
|
|
[*Effects:] Erases all the elements of the container.[br]
|
|
[*Complexity:] Linear.
|
|
|
|
`c.clear(info)`[br]
|
|
`c.clear<U>()`
|
|
|
|
[*Effects:] Erases all the elements of the segment for the indicated type.[br]
|
|
[*Complexity:] Linear in the size of the segment.[br]
|
|
[*Throws:] If the indicated type is not registered.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[import poly_collection_synopsis.qbk] [/ template poly_collection_synopsis]
|
|
[import closed_poly_collection_synopsis.qbk] [/ template closed_poly_collection_synopsis]
|
|
|
|
[section Header `"boost/poly_collection/exception.hpp"` synopsis]
|
|
|
|
All the collections in Boost.PolyCollection use the following exceptions
|
|
(and only these) to signal various run-time problems with contained types:
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
struct ``[link poly_collection.reference.header_boost_poly_collection_exc.class_unregistered_type unregistered_type]``;
|
|
struct ``[link poly_collection.reference.header_boost_poly_collection_exc.class_not_copy_constructible not_copy_constructible]``;
|
|
struct ``[link poly_collection.reference.header_boost_poly_collection_exc.class_not_equality_comparable not_equality_comparable]``;
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
[section Class `unregistered_type`]
|
|
|
|
struct unregistered_type:std::logic_error
|
|
{
|
|
unregistered_type(const std::type_info& info);
|
|
|
|
const std::type_info* pinfo;
|
|
};
|
|
|
|
`unregistered_type` is thrown when an operation is requested on a type which
|
|
does not yet have an associated segment.
|
|
|
|
`unregistered_type(const std::type_info& info);`
|
|
|
|
[*Effects:] Constructs an `unregistered_type` object with the specified type
|
|
information.
|
|
|
|
[endsect]
|
|
|
|
[section Class `not_copy_constructible`]
|
|
|
|
struct not_copy_constructible:std::logic_error
|
|
{
|
|
not_copy_constructible(const std::type_info& info);
|
|
|
|
const std::type_info* pinfo;
|
|
};
|
|
|
|
`not_copy_constructible` is thrown when a copy operation is tried that
|
|
involves a non-_CopyConstructible_ type.
|
|
|
|
`not_copy_constructible(const std::type_info& info);`
|
|
|
|
[*Effects:] Constructs a `not_copy_constructible` object with the specified
|
|
type information.
|
|
|
|
[endsect]
|
|
|
|
[section Class `not_equality_comparable`]
|
|
|
|
struct not_equality_comparable:std::logic_error
|
|
{
|
|
not_equality_comparable(const std::type_info& info);
|
|
|
|
const std::type_info* pinfo;
|
|
};
|
|
|
|
`not_equality_comparable` is thrown when comparing two collections
|
|
for (in)equality involves a non-_EqualityComparable_ type.
|
|
|
|
`not_equality_comparable(const std::type_info& info);`
|
|
|
|
[*Effects:] Constructs a `not_equality_comparable` object with the specified
|
|
type information.
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/base_collection_fwd.hpp"` synopsis]
|
|
|
|
[def _base_collection_ [link poly_collection.reference.header_boost_poly_collection_ba0.class_template_base_collection `base_collection`]]
|
|
|
|
#include <memory>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
template<typename Base,typename Allocator=std::allocator<Base>>
|
|
class _base_collection_;
|
|
|
|
template<typename Base,typename Allocator>
|
|
bool operator==(
|
|
const base_collection<Base,Allocator>& x,
|
|
const base_collection<Base,Allocator>& y);
|
|
|
|
template<typename Base,typename Allocator>
|
|
bool operator!=(
|
|
const base_collection<Base,Allocator>& x,
|
|
const base_collection<Base,Allocator>& y);
|
|
|
|
template<typename Base,typename Allocator>
|
|
void swap(
|
|
base_collection<Base,Allocator>& x,base_collection<Base,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
using poly_collection::base_collection;
|
|
|
|
} /* namespace boost */
|
|
|
|
Forward declares the class template _base_collection_
|
|
and specifies its default template arguments. Forward declares associated free
|
|
functions and brings `boost::poly_collection::base_collection` to the `boost`
|
|
namespace.
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/base_collection.hpp"` synopsis]
|
|
|
|
#include <boost/poly_collection/base_collection_fwd.hpp>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
template<typename Base,typename Allocator>
|
|
class _base_collection_;
|
|
|
|
template<typename Base,typename Allocator>
|
|
bool operator==(
|
|
const base_collection<Base,Allocator>& x,
|
|
const base_collection<Base,Allocator>& y);
|
|
|
|
template<typename Base,typename Allocator>
|
|
bool operator!=(
|
|
const base_collection<Base,Allocator>& x,
|
|
const base_collection<Base,Allocator>& y);
|
|
|
|
template<typename Base,typename Allocator>
|
|
void swap(
|
|
base_collection<Base,Allocator>& x,base_collection<Base,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
[section Class template `base_collection`]
|
|
|
|
`base_collection<Base,Allocator>` is an open _PolymorphicCollection_ associated to
|
|
the classic base/derived _polymorphism_model_:
|
|
|
|
* *Interface* = { `Base` : `std::is_polymorphic_v<Base>` }.
|
|
* *Implementation*(`Base`) = { `Derived` : `std::is_base_of_v<Base,Derived>` }.
|
|
* *subobject*(`x`) = `static_cast<Derived&>(x)` with `typeid(x)==typeid(Derived)`.
|
|
|
|
[poly_collection_synopsis `base_collection`..`template<typename Base,typename Allocator>`..`Base`..`std::type_info`]
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/function_collection_fwd.hpp"` synopsis]
|
|
|
|
[def _function_collection_ [link poly_collection.reference.header_boost_poly_collection_fu0.class_template_function_collecti `function_collection`]]
|
|
[def _function_collection_value_type_ [link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti `function_collection_value_type`]]
|
|
|
|
#include <memory>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
template<typename Signature>
|
|
using _function_collection_value_type_=``/implementation-defined/``;
|
|
|
|
template<
|
|
typename Signature,
|
|
typename Allocator=std::allocator<function_collection_value_type<Signature>>
|
|
>
|
|
class _function_collection_;
|
|
|
|
template<typename Signature,typename Allocator>
|
|
bool operator==(
|
|
const function_collection<Signature,Allocator>& x,
|
|
const function_collection<Signature,Allocator>& y);
|
|
|
|
template<typename Signature,typename Allocator>
|
|
bool operator!=(
|
|
const function_collection<Signature,Allocator>& x,
|
|
const function_collection<Signature,Allocator>& y);
|
|
|
|
template<typename Signature,typename Allocator>
|
|
void swap(
|
|
function_collection<Signature,Allocator>& x,
|
|
function_collection<Signature,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
using poly_collection::function_collection;
|
|
|
|
} /* namespace boost */
|
|
|
|
Defines the alias template _function_collection_value_type_ (the actual type
|
|
it refers to, though, is merely forward declared).
|
|
Forward declares the class template _function_collection_
|
|
and specifies its default template arguments. Forward declares associated free
|
|
functions and brings `boost::poly_collection::function_collection` to the
|
|
`boost` namespace.
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/function_collection.hpp"` synopsis]
|
|
|
|
#include <boost/poly_collection/function_collection_fwd.hpp>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
// defines the type ``_function_collection_value_type_`` refers to
|
|
|
|
template<typename Signature,typename Allocator>
|
|
class _function_collection_;
|
|
|
|
template<typename Signature,typename Allocator>
|
|
bool operator==(
|
|
const function_collection<Signature,Allocator>& x,
|
|
const function_collection<Signature,Allocator>& y);
|
|
|
|
template<typename Signature,typename Allocator>
|
|
bool operator!=(
|
|
const function_collection<Signature,Allocator>& x,
|
|
const function_collection<Signature,Allocator>& y);
|
|
|
|
template<typename Signature,typename Allocator>
|
|
void swap(
|
|
function_collection<Signature,Allocator>& x,
|
|
function_collection<Signature,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
[section Alias template `function_collection_value_type`]
|
|
|
|
`function_collection_value_type<Signature>` is the `value_type` of
|
|
`boost::function_collection<Signature,Allocator>`, where `Signature` must be a type
|
|
of the form `R(Args...)`. `function_collection_value_type<Signature>` wraps a
|
|
reference to an object modeling _Callable_ for the given `Signature`. The
|
|
interface provided partially replicates that of _std::function_ and adds some
|
|
extra facilities.
|
|
|
|
In what follows, the name [' `function_collection_value_type_impl`]
|
|
is used just for explanatory purposes in place of the actual
|
|
class template name, which is implementation defined.
|
|
|
|
template<typename Signature>
|
|
using function_collection_value_type=
|
|
``/function_collection_value_type_impl/``<Signature>;
|
|
|
|
template<typename Signature>
|
|
class ``/function_collection_value_type_impl/``;
|
|
|
|
template<typename R,typename... Args>
|
|
class ``/function_collection_value_type_impl/``<R(Args...)>
|
|
{
|
|
public:
|
|
explicit ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_bool operator bool]``()const noexcept;
|
|
|
|
R ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_call operator()]``(Args... args)const;
|
|
|
|
const std::type_info& ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.target_type target_type]``()const noexcept;
|
|
template<typename T> T* ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.target target]``()noexcept;
|
|
template<typename T> const T* ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.target target]``()const noexcept;
|
|
|
|
operator ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_std_function std::function<R(Args...)>]``()const noexcept;
|
|
|
|
void* ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.data data]``()noexcept;
|
|
const void* ``[link poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.data data]``()const noexcept;
|
|
};
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_bool]
|
|
|
|
`explicit operator bool()const noexcept;`
|
|
|
|
[*Returns:] `true`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_call]
|
|
|
|
`R operator()(Args... args)const;`
|
|
|
|
[*Effects:] `_INVOKE_(f,std::forward<Args>(args)...,R)`, where f is the wrapped
|
|
callable object.[br]
|
|
[*Returns:] Nothing if `R` is `void`, otherwise the return value of
|
|
`_INVOKE_(f,std::forward<Args>(args)...,R)`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.target_type]
|
|
|
|
`const std::type_info& target_type()const noexcept;`
|
|
|
|
[*Returns:] `typeid(T)` where `T` is the type of the wrapped callable object.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.target]
|
|
|
|
`template<typename T> T* target()noexcept;`[br]
|
|
`template<typename T> const T* target()const noexcept;`
|
|
|
|
[*Returns:] If `target_type()==typeid(T)` a pointer to the wrapped callable
|
|
object, otherwise `nullptr`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.operator_std_function]
|
|
|
|
`operator std::function<R(Args...)>()const noexcept;`
|
|
|
|
[*Returns:] A `std::function<R(Args...)>` object holding a reference to the
|
|
wrapped callable object.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_fu0.alias_template_function_collecti.data]
|
|
|
|
`void* data()noexcept;`[br]
|
|
`const void* data()const noexcept;`
|
|
|
|
[*Returns:] The address of the wrapped callable object.
|
|
|
|
[endsect]
|
|
|
|
[section Class template `function_collection`]
|
|
|
|
`function_collection<Signature,Allocator>` is an open _PolymorphicCollection_ associated to
|
|
a dynamic _polymorphism_model_ based on call signature compatibility:
|
|
|
|
* *Interface* = { `Signature` : `Signature` = `R(Args...)` }.
|
|
* *Implementation*(`Signature`) = { `Callable` : `std::is_invocable_r_v<R,Callable,Args...>` }.
|
|
* *subobject*(`x`) =
|
|
* `x.target<T>()` with `typeid(T)==x.target_type()`, if `x` is an instantiation of _function_collection_value_type_,
|
|
* `x`, otherwise.
|
|
|
|
[poly_collection_synopsis `function_collection`..`template<typename Signature,typename Allocator>`..`_function_collection_value_type_<Signature>`..`std::type_info`]
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/any_collection_fwd.hpp"` synopsis]
|
|
|
|
[def _any_collection_ [link poly_collection.reference.header_boost_poly_collection_an0.class_template_any_collection `any_collection`]]
|
|
[def _any_collection_value_type_ [link poly_collection.reference.header_boost_poly_collection_an0.alias_template_any_collection_va `any_collection_value_type`]]
|
|
|
|
#include <memory>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
template<typename Concept>
|
|
using _any_collection_value_type_=``/implementation-defined/``;
|
|
|
|
template<
|
|
typename Concept,
|
|
typename Allocator=std::allocator<any_collection_value_type<Concept>>
|
|
>
|
|
class _any_collection_;
|
|
|
|
template<typename Concept,typename Allocator>
|
|
bool operator==(
|
|
const any_collection<Concept,Allocator>& x,
|
|
const any_collection<Concept,Allocator>& y);
|
|
|
|
template<typename Concept,typename Allocator>
|
|
bool operator!=(
|
|
const any_collection<Concept,Allocator>& x,
|
|
const any_collection<Concept,Allocator>& y);
|
|
|
|
template<typename Concept,typename Allocator>
|
|
void swap(
|
|
any_collection<Concept,Allocator>& x,any_collection<Concept,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
using poly_collection::any_collection;
|
|
|
|
} /* namespace boost */
|
|
|
|
Defines the alias template _any_collection_value_type_ (the actual type
|
|
it refers to, though, is merely forward declared).
|
|
Forward declares the class template _any_collection_
|
|
and specifies its default template arguments. Forward declares associated free
|
|
functions and brings `boost::poly_collection::any_collection` to the
|
|
`boost` namespace.
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/any_collection.hpp"` synopsis]
|
|
|
|
#include <boost/poly_collection/any_collection_fwd.hpp>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
// defines the type ``_any_collection_value_type_`` refers to
|
|
|
|
template<typename Concept,typename Allocator>
|
|
class _any_collection_;
|
|
|
|
template<typename Concept,typename Allocator>
|
|
bool operator==(
|
|
const any_collection<Concept,Allocator>& x,
|
|
const any_collection<Concept,Allocator>& y);
|
|
|
|
template<typename Concept,typename Allocator>
|
|
bool operator!=(
|
|
const any_collection<Concept,Allocator>& x,
|
|
const any_collection<Concept,Allocator>& y);
|
|
|
|
template<typename Concept,typename Allocator>
|
|
void swap(
|
|
any_collection<Concept,Allocator>& x,any_collection<Concept,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
[section Alias template `any_collection_value_type`]
|
|
|
|
`any_collection_value_type<Concept>` is the `value_type` of
|
|
`boost::any_collection<Concept,Allocator>`, where `Concept` is defined according to
|
|
the [@boost:/doc/html/boost_typeerasure/conceptdef.html requisites]
|
|
of _Boost.TypeErasure_ using
|
|
[@boost:/doc/html/boost/type_erasure/_self.html `_self`]
|
|
as its [@boost:/doc/html/boost/type_erasure/placeholder.html placeholder].
|
|
The alias template definition has the form
|
|
|
|
template<typename Concept>
|
|
using any_collection_value_type=
|
|
boost::type_erasure::``[@boost:/doc/html/boost/type_erasure/any.html any]``<Concept2,boost::type_erasure::_self&>;
|
|
|
|
with `boost::type_erasure::`[@boost:/doc/html/boost/type_erasure/is_subconcept.html `is_subconcept`]`<Concept,Concept2>::value==true`.
|
|
The exact definition of `Concept2` is implementation defined.
|
|
|
|
[endsect]
|
|
|
|
[section Class template `any_collection`]
|
|
|
|
`any_collection<Concept,Allocator>` is an open _PolymorphicCollection_ associated to
|
|
a dynamic _polymorphism_model_ based on _duck_typing_ as implemented by
|
|
_Boost.TypeErasure_:
|
|
|
|
* *Interface* = { `Concept` :
|
|
as [@boost:/doc/html/boost_typeerasure/conceptdef.html specified] by _Boost.TypeErasure_,
|
|
using the [@boost:/doc/html/boost/type_erasure/_self.html `_self`]
|
|
[@boost:/doc/html/boost/type_erasure/placeholder.html placeholder] }.
|
|
* *Implementation*(`Concept`) = { `Concrete` : `Concrete` satisfies `Concept` }.
|
|
* *subobject*(`x`) =
|
|
* `boost::type_erasure::`[@boost:/doc/html/boost/type_erasure/any_cast.html `any_cast`]`<T&>(x)`
|
|
with `typeid(T)==boost::type_erasure::`[@boost:/doc/html/boost/type_erasure/typeid_of.html `typeid_of`]`(x)`,
|
|
if `x` is an instantiation of `boost::type_erasure::`[@boost:/doc/html/boost/type_erasure/any.html `any`]
|
|
including [@boost:/doc/html/boost/type_erasure/typeid_.html `typeid_`]`<>`,
|
|
* `x`, otherwise.
|
|
|
|
[poly_collection_synopsis `any_collection`..`template<typename Concept,typename Allocator>`..`_any_collection_value_type_<Concept>`..`std::type_info`]
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/variant_collection_fwd.hpp"` synopsis]
|
|
|
|
[def _variant_collection_ [link poly_collection.reference.header_boost_poly_collection_va0.class_template_variant_collectio `variant_collection`]]
|
|
[def _variant_collection_value_type_ [link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio `variant_collection_value_type`]]
|
|
|
|
#include <boost/mp11/list.hpp>
|
|
#include <memory>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
template<typename TypeList>
|
|
using _variant_collection_value_type_=``/implementation-defined/``;
|
|
|
|
template<
|
|
typename TypeList,
|
|
typename Allocator=std::allocator<variant_collection_value_type<TypeList>>
|
|
>
|
|
class _variant_collection_;
|
|
|
|
template<typename... Ts>
|
|
using variant_collection_of=variant_collection<mp11::mp_list<Ts...>>;
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
bool operator==(
|
|
const variant_collection<TypeList,Allocator>& x,
|
|
const variant_collection<TypeList,Allocator>& y);
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
bool operator!=(
|
|
const variant_collection<TypeList,Allocator>& x,
|
|
const variant_collection<TypeList,Allocator>& y);
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
void swap(
|
|
variant_collection<TypeList,Allocator>& x,variant_collection<TypeList,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
using poly_collection::variant_collection;
|
|
using poly_collection::variant_collection_of;
|
|
|
|
} /* namespace boost */
|
|
|
|
Defines the alias template _variant_collection_value_type_ (the actual type
|
|
it refers to, though, is merely forward declared).
|
|
Forward declares the class template _variant_collection_
|
|
and specifies its default template arguments.
|
|
Defines the alias template `variant_collection_of`. Forward declares associated
|
|
free functions and brings `boost::poly_collection::variant_collection`
|
|
and `poly_collection::variant_collection_of` to the `boost` namespace.
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/variant_collection.hpp"` synopsis]
|
|
|
|
#include <boost/poly_collection/variant_collection_fwd.hpp>
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
// defines the type ``_variant_collection_value_type_`` refers to
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
class _variant_collection_;
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
bool operator==(
|
|
const variant_collection<TypeList,Allocator>& x,
|
|
const variant_collection<TypeList,Allocator>& y);
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
bool operator!=(
|
|
const variant_collection<TypeList,Allocator>& x,
|
|
const variant_collection<TypeList,Allocator>& y);
|
|
|
|
template<typename TypeList,typename Allocator>
|
|
void swap(
|
|
variant_collection<TypeList,Allocator>& x,variant_collection<TypeList,Allocator>& y);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
[section Alias template `variant_collection_value_type`]
|
|
|
|
`variant_collection_value_type<TypeList>` is the `value_type` of
|
|
`boost::variant_collection<TypeList,Allocator>`, where `TypeList`
|
|
is a [@boost:/libs/mp11/doc/html/mp11.html#definitions Boost.Mp11 list]
|
|
of different types `Ts...`.
|
|
`variant_collection_value_type<TypeList>` behaves similarly to
|
|
_std::variant_`<Ts...>`, with some intentional limitations such as the impossibility
|
|
of changing the type of the underlying alternative.
|
|
|
|
In what follows, the name [' `variant_collection_value_type_impl`] is used
|
|
just for explanatory purposes in place of the actual class template name,
|
|
which is implementation defined.
|
|
|
|
template<typename TypeList>
|
|
using variant_collection_value_type=
|
|
mp11::mp_rename<TypeList,``/variant_collection_value_type_impl/``>;
|
|
|
|
template<typename... Ts>
|
|
class ``/variant_collection_value_type_impl/``
|
|
{
|
|
public:
|
|
// copy and assigmnent are disallowed
|
|
|
|
std::size_t ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.index index]``()const noexcept;
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.valueless_by_exception valueless_by_exception]``()const noexcept;
|
|
};
|
|
|
|
struct bad_variant_access:std::exception
|
|
{
|
|
bad_variant_access()noexcept{}
|
|
const char* what()const noexcept;
|
|
};
|
|
|
|
template<typename V> struct variant_size; // not defined
|
|
template<typename... Ts>
|
|
struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_size variant_size]``<``/variant_collection_value_type_impl/``<Ts...>>;
|
|
template<typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_size variant_size]``<const V>;
|
|
|
|
template<typename V>
|
|
constexpr std::size_t variant_size_v=variant_size<V>::value;
|
|
|
|
template<std::size_t I,typename T> struct variant_alternative; // not defined
|
|
template<std::size_t I,typename... Ts>
|
|
struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,``/variant_collection_value_type_impl/``<Ts...>>;
|
|
template<std::size_t I,typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,const T>;
|
|
template<std::size_t I,typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,V&>;
|
|
template<std::size_t I,typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,const V&>;
|
|
template<std::size_t I,typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,V&&>;
|
|
template<std::size_t I,typename V> struct ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative variant_alternative]``<I,const V&&>;
|
|
|
|
template<std::size_t I,typename V>
|
|
using variant_alternative_t=typename variant_alternative<I,V>::type;
|
|
|
|
template<typename T,typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.holds_alternative holds_alternative]``(const ``/variant_collection_value_type_impl/``<Ts...>& x)noexcept;
|
|
|
|
template<std::size_t I,typename V>
|
|
variant_alternative_t<I,V&&> ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_by_index get]``(V&& x);
|
|
|
|
template<typename T,typename V>
|
|
variant_alternative_t<mp11::mp_find<std::decay_t<V>,T>::value,V&&> ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_by_type get]``(V&& x);
|
|
|
|
template<std::size_t I,typename... Ts>
|
|
variant_alternative_t<I,``/variant_collection_value_type_impl/``<Ts...>>*
|
|
``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_index get_if]``(``/variant_collection_value_type_impl/``<Ts...>* px)noexcept;
|
|
template<std::size_t I,typename... Ts>
|
|
const variant_alternative_t<I,``/variant_collection_value_type_impl/``<Ts...>>*
|
|
``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_index get_if]``(const ``/variant_collection_value_type_impl/``<Ts...>* px)noexcept;
|
|
|
|
template<typename T,typename... Ts>
|
|
T* ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_type get_if]``(``/variant_collection_value_type_impl/``<Ts...>* px)noexcept;
|
|
template<typename T,typename... Ts>
|
|
const T* ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_type get_if]``(const ``/variant_collection_value_type_impl/``<Ts...>* px)noexcept;
|
|
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_eq operator==]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_ne operator!=]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_lt operator<]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_gt operator>]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_le operator=<]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
template<typename... Ts>
|
|
bool ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_ge operator>=]``(
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& x,
|
|
const ``/variant_collection_value_type_impl/``<Ts...>& y);
|
|
|
|
template<typename R=``/see-below/``,typename F,typename... Vs>
|
|
``/see-below/`` ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.visit visit]``(F&& f,Vs&&... xs);
|
|
|
|
template<typename R=``/see-below/``,typename V,typename... Fs>
|
|
``/see-below/`` ``[link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.visit_by_index visit_by_index]``(V&& x,Fs&&... fs);
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.index]
|
|
|
|
`std::size_t index()const noexcept;`
|
|
|
|
[*Returns:] The index number into `Ts...` of the type of the alternative
|
|
contained in the variant.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.valueless_by_exception]
|
|
|
|
`bool valueless_by_exception()const noexcept;`
|
|
|
|
[*Returns:] `false`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_size]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`struct variant_size<`[^ /variant_collection_value_type_impl/]`<Ts...>>;`[br]
|
|
`template<typename V> struct variant_size<const V>;`
|
|
|
|
`variant_size<...>::value` is a `constexpr std::size_t` value with
|
|
the number of alternative types specified for the variant.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.variant_alternative]
|
|
|
|
`template<std::size_t I,typename... Ts>`[br]
|
|
`struct variant_alternative<I,`[^ /variant_collection_value_type_impl/]`<Ts...>>;`[br]
|
|
`template<std::size_t I,typename V> struct variant_alternative<I,const T>;`[br]
|
|
`template<std::size_t I,typename V> struct variant_alternative<I,V&>;`[br]
|
|
`template<std::size_t I,typename V> struct variant_alternative<I,const V&>;`[br]
|
|
`template<std::size_t I,typename V> struct variant_alternative<I,V&&>;`[br]
|
|
`template<std::size_t I,typename V> struct variant_alternative<I,const V&&>;`
|
|
|
|
`variant_alternative<I,V>::type` is the `I`-th alternative type in the variant
|
|
with the same `const` and reference qualification as `V`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.holds_alternative]
|
|
|
|
`template<typename T,typename... Ts>`[br]
|
|
`bool holds_alternative(const `[^ /variant_collection_value_type_impl/]`<Ts...>& x)noexcept;`
|
|
|
|
[*Returns:] `true` iff the type of the alternative contained in the variant is `T`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_by_index]
|
|
|
|
`template<std::size_t I,typename V>`[br]
|
|
`variant_alternative_t<I,V&&> get(V&& x);`
|
|
|
|
[*Effects:] Throws `bad_variant_access` if `x.index()!=I`.[br]
|
|
[*Returns:] A reference to the contained value
|
|
with the same `const` and reference qualification as `x`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_by_type]
|
|
|
|
`template<typename T,typename V>`[br]
|
|
`variant_alternative_t<mp11::mp_find<std::decay_t<V>,T>::value,V&&> get(V&& x);`
|
|
|
|
[*Effects:] Throws `bad_variant_access` if `!holds_alternative<T>(x)`.[br]
|
|
[*Returns:] A reference to the contained value
|
|
with the same `const` and reference qualification as `x`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_index]
|
|
|
|
`template<std::size_t I,typename... Ts>`[br]
|
|
`variant_alternative_t<I,`[^ /variant_collection_value_type_impl/]`<Ts...>>*`[br]
|
|
`get_if(`[^ /variant_collection_value_type_impl/]`<Ts...>* px)noexcept;`[br]
|
|
`template<std::size_t I,typename... Ts>`[br]
|
|
`const variant_alternative_t<I,`[^ /variant_collection_value_type_impl/]`<Ts...>>*`[br]
|
|
`get_if(const `[^ /variant_collection_value_type_impl/]`<Ts...>* px)noexcept;`
|
|
|
|
[*Returns:] `nullptr` if `px` is null or `px->index()!=I`,
|
|
a pointer to the contained value otherwise.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.get_if_by_type]
|
|
|
|
`template<typename T,typename... Ts>`[br]
|
|
`T* get_if(`[^ /variant_collection_value_type_impl/]`<Ts...>* px)noexcept;`[br]
|
|
`template<typename T,typename... Ts>`[br]
|
|
`const T* get_if(const `[^ /variant_collection_value_type_impl/]`<Ts...>* px)noexcept;`
|
|
|
|
[*Returns:] `nullptr` if `px` is null or `!holds_alternative<T>(*px)`,
|
|
a pointer to the contained value otherwise.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_eq]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator==(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()==y.index()&&get<I>(x)==get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_ne]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator!=(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()!=y.index()||get<I>(x)!=get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_lt]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator<(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()<y.index()||x.index()==y.index()&&get<I>(x)<get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_gt]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator>(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()>y.index()||x.index()==y.index()&&get<I>(x)>get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_le]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator<=(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()<y.index()||x.index()==y.index()&&get<I>(x)<=get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.operator_ge]
|
|
|
|
`template<typename... Ts>`[br]
|
|
`bool operator>=(`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& x,`[br]
|
|
[^ \u00a0\u00a0]`const `[^ /variant_collection_value_type_impl/]`<Ts...>& y);`
|
|
|
|
[*Returns:] `x.index()>y.index()||x.index()==y.index()&&get<I>(x)>=get<I>(y)` with `I==x.index()`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.visit]
|
|
|
|
`template<typename R=`[^ /see-below/]`,typename F,typename... Vs>`[br]
|
|
[^ /see-below/]` visit(F&& f,Vs&&... xs);`
|
|
|
|
[*Effects:] Calls the expression `e(Is...)`, defined as
|
|
`std::forward<F>(f)(get<Is>(std::forward<Vs>(xs)...)`, with `Is...` equal to `xs.index()...`.[br]
|
|
[*Returns:]
|
|
|
|
* If `R` is specified as `void`: nothing.
|
|
* If `R` is specified as a type different from `void`: the value `e(Is...)` implicitly
|
|
converted to `R`.
|
|
* If `R` is not specified, `e(Is...)`. In this and the previous case,
|
|
`e(Js...)` must have the same type for all valid index packs `Js...`.
|
|
|
|
[#poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio.visit_by_index]
|
|
|
|
`template<typename R=`[^ /see-below/]`,typename V,typename... Fs>`[br]
|
|
[^ /see-below/]` visit_by_index(V&& x,Fs&&... fs);`
|
|
|
|
[*Requires:] `sizeof...(Fs)` is equal to the number of alternative types in the variant.[br]
|
|
[*Effects:] Calls the expression `e(i)`, defined as
|
|
`std::forward<Fi>(fi)(get<i>(std::forward<V>(x)))`, with `i==x.index()` and
|
|
`Fi` and `fi` denoting the `i`-th element of `Fs...` and `fs...`, respectively.[br]
|
|
[*Returns:]
|
|
|
|
* If `R` is specified as `void`: nothing.
|
|
* If `R` is specified as a type different from `void`: the value `e(i)` implicitly
|
|
converted to `R`.
|
|
* If `R` is not specified, `e(i)`. In this and the previous case,
|
|
`e(j)` must have the same type for all `j` in \[0, `sizeof...(Fs)`).
|
|
|
|
[endsect]
|
|
|
|
[section Class template `variant_collection`]
|
|
|
|
`variant_collection<TypeList,Allocator>` is a closed _PolymorphicCollection_ associated to
|
|
a dynamic _polymorphism_model_ based on the interface of _std::variant_:
|
|
|
|
* *Interface* = { `TypeList` = `L<Ts...>` : `L` is an arbitrary class template, `Ts...` is not empty, and
|
|
each `Ti` in `Ts...` is different, _MoveConstructible_, and _MoveAssignable_ or such that
|
|
[@http://en.cppreference.com/w/cpp/types/is_move_constructible `std::is_nothrow_move_constructible<Ti>::value`] is `true` }.
|
|
* *Implementation*(`L<Ts...>`) = { `Ts...` } \u222a
|
|
{ [link poly_collection.reference.header_boost_poly_collection_va0.alias_template_variant_collectio `variant_collection_value_type`]`<Us...>` : `Us...` \u2286 `Ts...` } \u222a
|
|
{ _std::variant_`<Us...>` : `Us...` \u2286 `Ts...` } \u222a
|
|
{ [@boost:libs/variant2/doc/html/variant2.html#ref_variant `boost::variant2::variant`]`<Us...>` : `Us...` \u2286 `Ts...` }.
|
|
* *subobject*(`x`) =
|
|
* `get<I>(x)` with `I==x.index()`, if the type of `x` is not in `Ts...`,
|
|
* `x`, otherwise.
|
|
|
|
[closed_poly_collection_synopsis `variant_collection`..`template<typename TypeList,typename Allocator>`..`_variant_collection_value_type_<TypeList>`..`std::size_t`]
|
|
|
|
[endsect]
|
|
|
|
[endsect]
|
|
|
|
[section Header `"boost/poly_collection/algorithm.hpp"` synopsis]
|
|
|
|
namespace boost{
|
|
|
|
namespace poly_collection{
|
|
|
|
``['`// total restitution for closed collections:`]``
|
|
|
|
struct all_types;
|
|
|
|
``['`// non-modifying sequence operations:`]``
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
bool all_of(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
bool any_of(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
bool none_of(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Function>
|
|
Function for_each(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Function f);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename Size,typename Function
|
|
>
|
|
Iterator for_each_n(
|
|
PolyCollectionIterator first,Size n,Function f);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename T>
|
|
PolyCollectionIterator find(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,const T& x);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
PolyCollectionIterator find_if(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
PolyCollectionIterator find_if_not(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename ForwardIterator
|
|
>
|
|
PolyCollectionIterator find_end(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename ForwardIterator,typename BinaryPredicate
|
|
>
|
|
PolyCollectionIterator find_end(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename ForwardIterator
|
|
>
|
|
PolyCollectionIterator find_first_of(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename ForwardIterator,typename BinaryPredicate
|
|
>
|
|
PolyCollectionIterator find_first_of(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator>
|
|
PolyCollectionIterator adjacent_find(
|
|
PolyCollectionIterator first,PolyCollectionIterator last);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename BinaryPredicate
|
|
>
|
|
PolyCollectionIterator adjacent_find(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
BinaryPredicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename T>
|
|
std::ptrdiff_t count(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,const T& x);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
std::ptrdiff_t count_if(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename InputIterator
|
|
>
|
|
std::pair<PolyCollectionIterator,InputIterator> mismatch(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename InputIterator,typename BinaryPredicate
|
|
>
|
|
std::pair<PolyCollectionIterator,InputIterator> mismatch(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename InputIterator
|
|
>
|
|
std::pair<PolyCollectionIterator,InputIterator> mismatch(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,InputIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename InputIterator,typename BinaryPredicate
|
|
>
|
|
std::pair<PolyCollectionIterator,InputIterator> mismatch(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,InputIterator last2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename InputIterator
|
|
>
|
|
bool equal(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename InputIterator,typename BinaryPredicate
|
|
>
|
|
bool equal(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename InputIterator
|
|
>
|
|
bool equal(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,InputIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename InputIterator,typename BinaryPredicate
|
|
>
|
|
bool equal(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,InputIterator last2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename ForwardIterator
|
|
>
|
|
bool is_permutation(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename ForwardIterator,typename BinaryPredicate
|
|
>
|
|
bool is_permutation(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename ForwardIterator
|
|
>
|
|
bool is_permutation(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename ForwardIterator,typename BinaryPredicate
|
|
>
|
|
bool is_permutation(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename ForwardIterator
|
|
>
|
|
PolyCollectionIterator search(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename ForwardIterator,typename BinaryPredicate
|
|
>
|
|
PolyCollectionIterator search(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename Size,typename T
|
|
>
|
|
PolyCollectionIterator search_n(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
Size count,const T& x);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename Size,typename T,typename BinaryPredicate
|
|
>
|
|
PolyCollectionIterator search_n(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
Size count,const T& x,BinaryPredicate pred);
|
|
|
|
``['`// modifying sequence operations:`]``
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename OutputIterator
|
|
>
|
|
OutputIterator copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename Size,typename OutputIterator
|
|
>
|
|
OutputIterator copy_n(
|
|
PolyCollectionIterator first,Size count,OutputIterator res);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename Predicate
|
|
>
|
|
OutputIterator copy_if(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,Predicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename OutputIterator
|
|
>
|
|
OutputIterator move(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename UnaryOperation
|
|
>
|
|
OutputIterator transform(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,UnaryOperation op);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename InputIterator,typename OutputIterator,typename BinaryOperation
|
|
>
|
|
OutputIterator transform(
|
|
PolyCollectionIterator first1,PolyCollectionIterator last1,
|
|
InputIterator first2,OutputIterator res,BinaryOperation op);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename T
|
|
>
|
|
OutputIterator replace_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,const T& old_x,const T& new_x);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename Predicate,typename T
|
|
>
|
|
OutputIterator replace_copy_if(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,Predicate pred,const T& new_x);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename T
|
|
>
|
|
OutputIterator remove_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,const T& x);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename Predicate
|
|
>
|
|
OutputIterator remove_copy_if(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,Predicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename OutputIterator
|
|
>
|
|
OutputIterator unique_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator,typename BinaryPredicate
|
|
>
|
|
OutputIterator unique_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,BinaryPredicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename OutputIterator
|
|
>
|
|
OutputIterator rotate_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator middle,
|
|
PolyCollectionIterator last,OutputIterator res);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,typename OutputIterator,
|
|
typename Distance,typename UniformRandomBitGenerator
|
|
>
|
|
OutputIterator sample(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator res,Distance n,UniformRandomBitGenerator&& g);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
bool is_partitioned(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
template<
|
|
typename... Ts,typename PolyCollectionIterator,
|
|
typename OutputIterator1,typename OutputIterator2,typename Predicate
|
|
>
|
|
std::pair<OutputIterator1,OutputIterator2> partition_copy(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,
|
|
OutputIterator1 rest,OutputIterator2 resf,Predicate pred);
|
|
|
|
template<typename... Ts,typename PolyCollectionIterator,typename Predicate>
|
|
PolyCollectionIterator partition_point(
|
|
PolyCollectionIterator first,PolyCollectionIterator last,Predicate pred);
|
|
|
|
} /* namespace poly_collection */
|
|
|
|
} /* namespace boost */
|
|
|
|
The algorithms provided mimic the functionality of their homonyms in
|
|
[@http://en.cppreference.com/w/cpp/algorithm `<algorithm>`] but take advantage
|
|
of the segmented nature of Boost.PolyCollection (global) iterators to
|
|
deliver better performance. Additionally, concrete types can be passed to
|
|
these algorithms for /type restitution/.
|
|
|
|
For the description of the algorithms we use the following notation:
|
|
|
|
* [' `alg`] is the (unqualified) name of any of the algorithms in
|
|
`"boost/poly_collection/algorithm.hpp"` except `for_each_n`, `copy_n` and `rotate_copy`.
|
|
* `first`, `middle` and `last` are (same-typed) possibly const global iterators
|
|
of a collection of Boost.PolyCollection such that \[`first`, `middle`) and
|
|
\[`middle`, `last`) are valid ranges.
|
|
* `args...` is a function parameter pack of types `Args&&...`,
|
|
* `Ts...` is a template parameter pack of acceptable types for the collection,
|
|
plus optionally `all_types` in the case of closed collections.
|
|
* Open collections: `Us...` is defined as `Ts...`.
|
|
* Closed collections: `Us...` is defined as the set of all acceptable types
|
|
in the collection if `all_types` is in `Ts...`, or as `Ts...` otherwise.
|
|
|
|
(1) [' `alg`]`(first,last,args...)`[br]
|
|
(2) `for_each_n(first,args...)`[br]
|
|
(3) `copy_n(first,args...)`[br]
|
|
(4) `rotate_copy(first,middle,last,args...)`
|
|
|
|
[*Requires:] The expression `expr` is well-formed, where `expr` is defined
|
|
as:[br]
|
|
(1) `std::`[' `alg`]`(first,last,args...)`,[br]
|
|
(2) `std::for_each_n(first,args...)`,[br]
|
|
(3) `std::copy_n(first,args...)`,[br]
|
|
(4) `std::rotate_copy(first,middle,last,args...)`.[br]
|
|
[*Effects:] Equivalent to `expr`.[br]
|
|
[*Returns:] `expr`.[br]
|
|
[*Complexity:] That of `expr`.
|
|
|
|
(1) [' `alg`]`<Ts...>(first,last,args...)`[br]
|
|
(2) `for_each_n<Ts...>(first,args...)`[br]
|
|
(3) `copy_n<Ts...>(first,args...)`[br]
|
|
(4) `rotate_copy<Ts...>(first,middle,last,args...)`
|
|
|
|
[*Requires:] The expression `expr` is well-formed, where `expr` is defined
|
|
as:[br]
|
|
(1) `std::`[' `alg`]`(rfirst,rlast,args...)`,[br]
|
|
(2) `std::for_each_n(rfirst,args...)`,[br]
|
|
(3) `std::copy_n(rfirst,args...)`,[br]
|
|
(4) `std::rotate_copy(rfirst,rmiddle,rlast,args...)`,[br]
|
|
and `rfirst`, `rmiddle` and `rlast` are iterator-like objects behaving like
|
|
their `first`, `middle` and `last` counterparts except that they
|
|
dereference to the corresponding subobject (`const`) `U&` if pointing to a
|
|
segment for `U` and `U` is in `Us...`
|
|
[footnote Strictly speaking a proper _ForwardIterator_ cannot behave
|
|
like this as dereferencing must yield /exactly/ a (`const`) `value_type&`
|
|
value, which disallows this type of polymorphism.].[br]
|
|
[*Effects:] Equivalent to `expr`.[br]
|
|
[*Returns:] `expr`.[br]
|
|
[*Complexity:] That of `expr`.[br]
|
|
[*Note:] In the case of closed collections, if `Us...` is not empty and contains all the
|
|
acceptable types of the collection (/total restitution/), then
|
|
the dereference operation of `rfirst`, `rmiddle` and `rlast` to the
|
|
collection's `value_type` is not ever instantiated.
|
|
|
|
[endsect]
|
|
|
|
[endsect] |