Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/memory/uses allocator construction args"

From cppreference.com
< cpp‎ | memory
(+)
 
m (., @-@ -> @,@)
 
(15 intermediate revisions by 5 users not shown)
Line 2: Line 2:
 
{{cpp/memory/navbar}}
 
{{cpp/memory/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl header | memory}}
+
{{dcl header|memory}}
{{dcl h | T is not a specialization of std::pair }}
+
{{dcl h|{{tt|T}} is not a specialization of {{lc|std::pair}}}}
{{dcl | num=1 | since=c++20 |
+
{{dcl|num=1|since=c++20|
 
template< class T, class Alloc, class... Args >
 
template< class T, class Alloc, class... Args >
auto uses_allocator_construction_args( const Alloc& alloc,
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
                                      Args&&... args) -> /*see below*/;
+
    Args&&... args ) noexcept;
 
}}
 
}}
{{dcl h | T is a specialization of std::pair }}
+
{{dcl h|{{tt|T}} is a specialization of {{lc|std::pair}}}}
{{dcl | num=2 | since=c++20 |
+
{{dcl|num=2|since=c++20|
 
template< class T, class Alloc, class Tuple1, class Tuple2 >
 
template< class T, class Alloc, class Tuple1, class Tuple2 >
auto uses_allocator_construction_args( const Alloc& alloc,
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
                                      std::piecewise_construct_t,
+
    std::piecewise_construct_t, Tuple1&& x, Tuple2&& y ) noexcept;
                                      Tuple1&& x, Tuple2&& y) -> /*see below*/;
+
 
}}
 
}}
{{dcl | num=3 | since=c++20 |
+
{{dcl|num=3|since=c++20|
template< class T >
+
template< class T, class Alloc >
auto uses_allocator_construction_args( const Alloc& alloc ) -> /*see below*/;
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc ) noexcept;
 
}}
 
}}
{{dcl | num=4 | since=c++20 |
+
{{dcl|num=4|since=c++20|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
auto uses_allocator_construction_args( const Alloc& alloc,
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
                                      U&& u, V&& v) -> /*see below*/;
+
    U&& u, V&& v ) noexcept;
 
}}
 
}}
{{dcl | num=5 | since=c++20 |
+
{{dcl|num=5|since=c++23|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
auto uses_allocator_construction_args( const Alloc& alloc,
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
                                      const std::pair<U,V>& pr) -> /*see below*/;
+
    std::pair<U, V>& pr ) noexcept;
 
}}
 
}}
{{dcl | num=6 | since=c++20 |
+
{{dcl|num=6|since=c++20|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
auto uses_allocator_construction_args( const Alloc& alloc,
+
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
                                      std::pair<U,V>&& pr) -> /*see below*/;
+
    const std::pair<U, V>& pr ) noexcept;
 +
}}
 +
{{dcl|num=7|since=c++20|
 +
template< class T, class Alloc, class U, class V >
 +
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 +
    std::pair<U, V>&& pr ) noexcept;
 +
}}
 +
{{dcl|num=8|since=c++23|
 +
template< class T, class Alloc, class U, class V >
 +
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 +
    const std::pair<U, V>&& pr ) noexcept;
 +
}}
 +
{{dcl|num=9|since=c++20|
 +
template< class T, class Alloc, class NonPair >
 +
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 +
    NonPair&& non_pair ) noexcept;
 
}}
 
}}
 
{{dcl end}}
 
{{dcl end}}
Line 39: Line 53:
 
Prepares the argument list needed to create an object of the given type {{tt|T}} by means of {{rlp|uses_allocator|uses-allocator construction}}.
 
Prepares the argument list needed to create an object of the given type {{tt|T}} by means of {{rlp|uses_allocator|uses-allocator construction}}.
  
@1@ {{cpp/enable if|T is not a specialization of std::pair}}. Returns {{lc|std::tuple}} determined as follows:
+
@1@ {{cpp/enable if|{{tt|T}} is not a specialization of {{lc|std::pair}}}}. Returns {{lc|std::tuple}} determined as follows:
@@ * If {{c|std::uses_allocator_v<T, Alloc>}} is false and {{c|is_constructible_v<T, Args...>}} is true, returns {{c|std::forward_as_tuple(std::forward<Args>(args)...)}}
+
<!---->
@@ * Otherwise, if {{c|std::uses_allocator_v<T, Alloc>}} is true and {{c|std::is_constructible_v<T, std::allocator_arg_t, Alloc, Args...>}} is true, returns {{c|std::tuple<std::allocator_arg_t, const Alloc&, Args&&...>(std::allocator_arg, alloc, std::forward<Args>(args)...)}}
+
* If {{c|std::uses_allocator_v<T, Alloc>}} is {{c|false}} and {{c|std::is_constructible_v<T, Args...>}} is {{c|true}}, returns {{c|std::forward_as_tuple(std::forward<Args>(args)...)}}.
@@ * Otherwise, if {{c|std::uses_allocator_v<T, Alloc>}} is true and {{c|std::is_constructible_v<T, Args..., Alloc>}} is true, returns {{c|std::forward_as_tuple(std::forward<Args>(args)..., alloc)}}
+
* Otherwise, if {{c|std::uses_allocator_v<T, Alloc>}} is {{c|true}} and {{c|std::is_constructible_v<T, std::allocator_arg_t, const Alloc&, Args...>}} is {{c|true}}, returns<br>{{c multi
@@ * Otherwise, the program is ill-formed
+
|std::tuple<std::allocator_arg_t, const Alloc&, Args&&...>(std::allocator_arg, alloc,
@2@ {{cpp/enable if|T is a specialization of std::pair}}. For {{c|T {{=}} std::pair<P1, P2>}}, equivalent to  
+
|                                                          std::forward<Args>(args)...)}}.
 +
* Otherwise, if {{c|std::uses_allocator_v<T, Alloc>}} is {{c|true}} and {{c|std::is_constructible_v<T, Args..., const Alloc&>}} is {{c|true}}, returns {{c|std::forward_as_tuple(std::forward<Args>(args)..., alloc)}}.
 +
* Otherwise, the program is ill-formed.
 +
@2@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. For {{tt|T}} that is {{c|std::pair<T1, T2>}}, equivalent to  
 
{{source|1=
 
{{source|1=
return std::make_tuple( std::piecewise_construct,
+
return std::make_tuple(std::piecewise_construct,
     std::apply( [&alloc](auto&&... args1) {
+
     std::apply([&alloc](auto&&... args1)
             return std::uses_allocator_construction_args<T1>( alloc,
+
        {
 +
             return std::uses_allocator_construction_args<T1>(alloc,
 
                       std::forward<decltype(args1)>(args1)...);
 
                       std::forward<decltype(args1)>(args1)...);
         }, std::forward<Tuple1>(x)),
+
         }, std::forward<Tuple1>(x)
     std::apply( [&alloc](auto&&... args2) {
+
    ),
             return std::uses_allocator_construction_args<T2>( alloc,
+
     std::apply([&alloc](auto&&... args2)
                    std::forward<decltype(args2)>(args2)...);
+
        {
         }, std::forward<Tuple2>(y))
+
             return std::uses_allocator_construction_args<T2>(alloc,
     );
+
                      std::forward<decltype(args2)>(args2)...);
 +
         }, std::forward<Tuple2>(y)
 +
     )
 +
);
 
}}
 
}}
@3@ {{cpp/enable if|T is a specialization of std::pair}}. Equivalent to
+
@3@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
 
{{source|1=
 
{{source|1=
 
return std::uses_allocator_construction_args<T>(alloc,
 
return std::uses_allocator_construction_args<T>(alloc,
Line 63: Line 84:
 
);
 
);
 
}}
 
}}
@4@ {{cpp/enable if|T is a specialization of std::pair}}. Equivalent to
+
@4@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
 
{{source|1=
 
{{source|1=
return std::uses_allocator_construction_args<T>( alloc,
+
return std::uses_allocator_construction_args<T>(alloc,
 
     std::piecewise_construct,
 
     std::piecewise_construct,
 
     std::forward_as_tuple(std::forward<U>(u)),
 
     std::forward_as_tuple(std::forward<U>(u)),
Line 71: Line 92:
 
);
 
);
 
}}
 
}}
@5@ {{cpp/enable if|T is a specialization of std::pair}}. Equivalent to
+
@5,6@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
 
{{source|1=
 
{{source|1=
return std::uses_allocator_construction_args<T>( alloc,
+
return std::uses_allocator_construction_args<T>(alloc,
 
     std::piecewise_construct,
 
     std::piecewise_construct,
 
     std::forward_as_tuple(pr.first),
 
     std::forward_as_tuple(pr.first),
Line 79: Line 100:
 
);
 
);
 
}}
 
}}
@6@ {{cpp/enable if|T is a specialization of std::pair}}. Equivalent to
+
@7,8@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
 
{{source|1=
 
{{source|1=
return std::uses_allocator_construction_args<T>( alloc,
+
return std::uses_allocator_construction_args<T>(alloc,
 
     std::piecewise_construct,
 
     std::piecewise_construct,
     std::forward_as_tuple(std::move(pr).first),
+
     std::forward_as_tuple(std::get<0>(std::move(pr))),
     std::forward_as_tuple(std::move(pr).second));
+
     std::forward_as_tuple(std::get<1>(std::move(pr)))
 +
);
 +
}}
 +
@9@ {{cpp/enable_if|{{tt|T}} is a specialization of {{lc|std::pair}}, and given the exposition-only function template
 +
{{source|template<class A, class B>
 +
void /*deduce-as-pair*/(const std::pair<A, B>&);
 +
}}
 +
, {{c|/*deduce-as-pair*/(non_pair)}} is ill-formed when considered as an unevaluated operand}}.<br><!--
 +
-->Let the exposition-only class {{tt|''pair-constructor''}} be defined as
 +
{{source|1=
 +
class /*pair-constructor*/
 +
{
 +
    const Alloc& alloc_; // exposition only
 +
    NonPair&    u_;    // exposition only
 +
 
 +
    constexpr reconstruct(const std::remove_cv<T>& p) const // exposition only
 +
    {
 +
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, p);
 +
    }
 +
 
 +
    constexpr reconstruct(std::remove_cv<T>&& p) const // exposition only
 +
    {
 +
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, std::move(p));
 +
    }
 +
 
 +
public:
 +
    constexpr operator std::remove_cv<T>() const
 +
    {
 +
        return reconstruct(std::forward<NonPair>(u_));
 +
    }
 +
};
 
}}
 
}}
 +
This overload is equivalent to {{c|return std::make_tuple(pair_construction);}}, where {{tt|pair_construction}} is a value of type {{tt|''pair-constructor''}} whose {{tt|''alloc_''}} and {{tt|''u_''}} members are {{tt|alloc}} and {{tt|non_pair}} respectively.
  
 
===Parameters===
 
===Parameters===
 
{{par begin}}
 
{{par begin}}
{{par | alloc | the allocator to use.}}
+
{{par|alloc|the allocator to use}}
{{par | args | the arguments to pass to T's constructor}}
+
{{par|args|the arguments to pass to {{tt|T}}'s constructor}}
{{par | x | tuple of arguments to pass to the constructors of T's .first }}
+
{{par|x|tuple of arguments to pass to the constructors of {{tt|T}}'s {{tt|first}} data member}}
{{par | y | tuple of arguments to pass to the constructors of T's .second }}
+
{{par|y|tuple of arguments to pass to the constructors of {{tt|T}}'s {{tt|second}} data member}}
{{par | u | single argument to pass to the constructor of T's .first }}
+
{{par|u|single argument to pass to the constructor of {{tt|T}}'s {{tt|first}} data member}}
{{par | v | single argument to pass to the constructor of T's .second }}
+
{{par|v|single argument to pass to the constructor of {{tt|T}}'s {{tt|second}} data member}}
{{par | pr | a pair whose .first will be passed to the constructor of T's .first and .second will be passed to the constructor of T's .second}}
+
{{par|pr|a pair whose {{tt|first}} data member will be passed to the constructor of {{tt|T}}'s {{tt|first}} data member and {{tt|second}} data member will be passed to the constructor of {{tt|T}}'s {{tt|second}} data member}}
 +
{{par|non_pair|single argument to convert to a {{lc|std::pair}} for further construction}}
 
{{par end}}
 
{{par end}}
  
 
===Return value===
 
===Return value===
{{lc|std::tuple}} of arguments suitable for passing to the constructor of {{tt|T}}
+
{{lc|std::tuple}} of arguments suitable for passing to the constructor of {{tt|T}}.
 +
 
 +
===Notes===
 +
The overloads {{v|2-9}} provide allocator propagation into {{lc|std::pair}}, which supports neither leading-allocator nor trailing-allocator calling conventions (unlike, e.g. {{lc|std::tuple}}, which uses leading-allocator convention).
 +
 
 +
When used in uses-allocator construction, the conversion function of {{tt|''pair-constructor''}} converts the provided argument to {{lc|std::pair}} at first, and then constructs the result from that {{lc|std::pair}} by uses-allocator construction.
  
 
===Example===
 
===Example===
 
{{example}}
 
{{example}}
  
===Notes===
+
===Defect reports===
The overloads {{v|2-6}} provide allocator propagation into {{lc|std::pair}}, which supports neither leading-allocator nor trailing-allocator calling conventions (unlike, e.g. {{lc|std::tuple}}, which uses leading-allocator convention)
+
{{dr list begin}}
 +
{{dr list item|wg=lwg|dr=3525|std=C++20|before=no overload could handle non-{{tt|pair}} types convertible to {{tt|pair}}|after=reconstructing overload added}}
 +
{{dr list end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/memory/dsc uses_allocator}}
+
{{dsc inc|cpp/memory/dsc uses_allocator}}
{{dsc inc | cpp/memory/dsc make_obj_using_allocator}}
+
{{dsc inc|cpp/memory/dsc make_obj_using_allocator}}
{{dsc inc | cpp/memory/dsc uninitialized_construct_using_allocator}}
+
{{dsc inc|cpp/memory/dsc uninitialized_construct_using_allocator}}
 
{{dsc end}}
 
{{dsc end}}
  
{{langlinks|ja|zh}}
+
{{langlinks|de|es|ja|ru|zh}}

Latest revision as of 06:52, 8 October 2023

 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
Dynamic memory management
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Allocators
Garbage collection support
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)
(C++11)(until C++23)



 
Defined in header <memory>
T is not a specialization of std::pair
template< class T, class Alloc, class... Args >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    Args&&... args ) noexcept;
(1) (since C++20)
T is a specialization of std::pair
template< class T, class Alloc, class Tuple1, class Tuple2 >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    std::piecewise_construct_t, Tuple1&& x, Tuple2&& y ) noexcept;
(2) (since C++20)
template< class T, class Alloc >
constexpr auto uses_allocator_construction_args( const Alloc& alloc ) noexcept;
(3) (since C++20)
template< class T, class Alloc, class U, class V >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    U&& u, V&& v ) noexcept;
(4) (since C++20)
template< class T, class Alloc, class U, class V >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    std::pair<U, V>& pr ) noexcept;
(5) (since C++23)
template< class T, class Alloc, class U, class V >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    const std::pair<U, V>& pr ) noexcept;
(6) (since C++20)
template< class T, class Alloc, class U, class V >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    std::pair<U, V>&& pr ) noexcept;
(7) (since C++20)
template< class T, class Alloc, class U, class V >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    const std::pair<U, V>&& pr ) noexcept;
(8) (since C++23)
template< class T, class Alloc, class NonPair >

constexpr auto uses_allocator_construction_args( const Alloc& alloc,

    NonPair&& non_pair ) noexcept;
(9) (since C++20)

Prepares the argument list needed to create an object of the given type T by means of uses-allocator construction.

1) This overload participates in overload resolution only if T is not a specialization of std::pair. Returns std::tuple determined as follows:
2) This overload participates in overload resolution only if T is a specialization of std::pair. For T that is std::pair<T1, T2>, equivalent to
return std::make_tuple(std::piecewise_construct,
    std::apply([&alloc](auto&&... args1)
        {
            return std::uses_allocator_construction_args<T1>(alloc,
                       std::forward<decltype(args1)>(args1)...);
        }, std::forward<Tuple1>(x)
    ),
    std::apply([&alloc](auto&&... args2)
        {
            return std::uses_allocator_construction_args<T2>(alloc,
                       std::forward<decltype(args2)>(args2)...);
        }, std::forward<Tuple2>(y)
    )
);
3) This overload participates in overload resolution only if T is a specialization of std::pair. Equivalent to
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct, std::tuple<>{}, std::tuple<>{}
);
4) This overload participates in overload resolution only if T is a specialization of std::pair. Equivalent to
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(std::forward<U>(u)),
    std::forward_as_tuple(std::forward<V>(v))
);
5,6) This overload participates in overload resolution only if T is a specialization of std::pair. Equivalent to
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(pr.first),
    std::forward_as_tuple(pr.second)
);
7,8) This overload participates in overload resolution only if T is a specialization of std::pair. Equivalent to
return std::uses_allocator_construction_args<T>(alloc,
    std::piecewise_construct,
    std::forward_as_tuple(std::get<0>(std::move(pr))),
    std::forward_as_tuple(std::get<1>(std::move(pr)))
);
9) This overload participates in overload resolution only if T is a specialization of std::pair, and given the exposition-only function template
template<class A, class B>
void /*deduce-as-pair*/(const std::pair<A, B>&);

, /*deduce-as-pair*/(non_pair) is ill-formed when considered as an unevaluated operand.
Let the exposition-only class pair-constructor be defined as

class /*pair-constructor*/
{
    const Alloc& alloc_; // exposition only
    NonPair&     u_;     // exposition only
 
    constexpr reconstruct(const std::remove_cv<T>& p) const // exposition only
    {
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, p);
    }
 
    constexpr reconstruct(std::remove_cv<T>&& p) const // exposition only
    {
        return std::make_obj_using_allocator<std::remove_cv<T>>(alloc_, std::move(p));
    }
 
public:
    constexpr operator std::remove_cv<T>() const
    {
        return reconstruct(std::forward<NonPair>(u_));
    }
};
This overload is equivalent to return std::make_tuple(pair_construction);, where pair_construction is a value of type pair-constructor whose alloc_ and u_ members are alloc and non_pair respectively.

Contents

[edit] Parameters

alloc - the allocator to use
args - the arguments to pass to T's constructor
x - tuple of arguments to pass to the constructors of T's first data member
y - tuple of arguments to pass to the constructors of T's second data member
u - single argument to pass to the constructor of T's first data member
v - single argument to pass to the constructor of T's second data member
pr - a pair whose first data member will be passed to the constructor of T's first data member and second data member will be passed to the constructor of T's second data member
non_pair - single argument to convert to a std::pair for further construction

[edit] Return value

std::tuple of arguments suitable for passing to the constructor of T.

[edit] Notes

The overloads (2-9) provide allocator propagation into std::pair, which supports neither leading-allocator nor trailing-allocator calling conventions (unlike, e.g. std::tuple, which uses leading-allocator convention).

When used in uses-allocator construction, the conversion function of pair-constructor converts the provided argument to std::pair at first, and then constructs the result from that std::pair by uses-allocator construction.

[edit] Example

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3525 C++20 no overload could handle non-pair types convertible to pair reconstructing overload added

[edit] See also

checks if the specified type supports uses-allocator construction
(class template) [edit]
creates an object of the given type by means of uses-allocator construction
(function template) [edit]
creates an object of the given type at specified memory location by means of uses-allocator construction
(function template) [edit]