Namespaces
Variants
Views
Actions

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

From cppreference.com
< cpp‎ | memory
m (., @-@ -> @,@)
 
(4 intermediate revisions by 3 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 | {{tt|T}} is not a specialization of {{lc|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 >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
     Args&&... args) noexcept;
+
     Args&&... args ) noexcept;
 
}}
 
}}
{{dcl h | {{tt|T}} is a specialization of {{lc|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 >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
     std::piecewise_construct_t, Tuple1&& x, Tuple2&& y) noexcept;
+
     std::piecewise_construct_t, Tuple1&& x, Tuple2&& y ) noexcept;
 
}}
 
}}
{{dcl | num=3 | since=c++20 |
+
{{dcl|num=3|since=c++20|
 
template< class T, class Alloc >
 
template< class T, class Alloc >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc ) noexcept;
 
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 >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
     U&& u, V&& v) noexcept;
+
     U&& u, V&& v ) noexcept;
 
}}
 
}}
{{dcl | num=5 | since=c++23 |
+
{{dcl|num=5|since=c++23|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
     std::pair<U, V>& pr ) noexcept;
 
     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 >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
     const std::pair<U, V>& pr ) noexcept;
 
     const std::pair<U, V>& pr ) noexcept;
 
}}
 
}}
{{dcl | num=7 | since=c++20 |
+
{{dcl|num=7|since=c++20|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
     std::pair<U, V>&& pr ) noexcept;
 
     std::pair<U, V>&& pr ) noexcept;
 
}}
 
}}
{{dcl | num=8 | since=c++23 |
+
{{dcl|num=8|since=c++23|
 
template< class T, class Alloc, class U, class V >
 
template< class T, class Alloc, class U, class V >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
     const std::pair<U, V>&& pr ) noexcept;
 
     const std::pair<U, V>&& pr ) noexcept;
 
}}
 
}}
{{dcl | num=9 | since=c++20 |
+
{{dcl|num=9|since=c++20|
 
template< class T, class Alloc, class NonPair >
 
template< class T, class Alloc, class NonPair >
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
 
constexpr auto uses_allocator_construction_args( const Alloc& alloc,
Line 55: Line 55:
 
@1@ {{cpp/enable if|{{tt|T}} is not a specialization of {{lc|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 {{c|false}} and {{c|std::is_constructible_v<T, Args...>}} is {{c|true}}, returns {{c|std::forward_as_tuple(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 {{c|true}} and {{c|std::is_constructible_v<T, std::allocator_arg_t, const Alloc&, Args...>}} is {{c|true}}, returns {{c|std::tuple<std::allocator_arg_t, const Alloc&, Args&&...>(std::allocator_arg, alloc, std::forward<Args>(args)...)}}
+
* 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, 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)}}
+
|std::tuple<std::allocator_arg_t, const Alloc&, Args&&...>(std::allocator_arg, alloc,
* Otherwise, the program is ill-formed
+
|                                                          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  
 
@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|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
 
@3@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|std::pair}}}}. Equivalent to
Line 80: Line 86:
 
@4@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|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 86: Line 92:
 
);
 
);
 
}}
 
}}
@5-6@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|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 94: Line 100:
 
);
 
);
 
}}
 
}}
@7-8@ {{cpp/enable if|{{tt|T}} is a specialization of {{lc|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::get<0>(std::move(pr))),
 
     std::forward_as_tuple(std::get<0>(std::move(pr))),
     std::forward_as_tuple(std::get<1>(std::move(pr))));
+
     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 an exposition-only function template
+
@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 >
+
{{source|template<class A, class B>
void /*deduce-as-pair*/( const std::pair<A, 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><!--
 
, {{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
 
-->Let the exposition-only class {{tt|''pair-constructor''}} be defined as
 
{{source|1=
 
{{source|1=
class /*pair-constructor*/ {
+
class /*pair-constructor*/
 +
{
 
     const Alloc& alloc_; // exposition only
 
     const Alloc& alloc_; // exposition only
 
     NonPair&    u_;    // exposition only
 
     NonPair&    u_;    // exposition only
Line 133: Line 141:
 
===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 {{tt|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 {{tt|T}}'s {{tt|first}} data member }}
+
{{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 {{tt|T}}'s {{tt|second}} data member }}
+
{{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 {{tt|T}}'s {{tt|first}} data member }}
+
{{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 {{tt|T}}'s {{tt|second}} data member }}
+
{{par|v|single argument to pass to the constructor of {{tt|T}}'s {{tt|second}} data member}}
{{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|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|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}}.
 
===Example===
 
{{example}}
 
  
 
===Notes===
 
===Notes===
Line 153: Line 158:
  
 
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.
 
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}}
  
 
===Defect reports===
 
===Defect reports===
Line 161: Line 169:
 
===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|de|es|ja|ru|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]