BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmf_unwraprefdecay.h
Go to the documentation of this file.
1/// @file bslmf_unwraprefdecay.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_unwraprefdecay.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_UNWRAPREFDECAY
9#define INCLUDED_BSLMF_UNWRAPREFDECAY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_unwraprefdecay bslmf_unwraprefdecay
15/// @brief Provide a meta-function to decay and unwrap reference wrappers.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_unwraprefdecay
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_unwraprefdecay-purpose"> Purpose</a>
25/// * <a href="#bslmf_unwraprefdecay-classes"> Classes </a>
26/// * <a href="#bslmf_unwraprefdecay-canonical-header"> Canonical Header </a>
27/// * <a href="#bslmf_unwraprefdecay-description"> Description </a>
28/// * <a href="#bslmf_unwraprefdecay-usage"> Usage </a>
29/// * <a href="#bslmf_unwraprefdecay-example-1-unwrap-reference-wrapped-argument-types"> Example 1: Unwrap Reference Wrapped Argument Types </a>
30///
31/// # Purpose {#bslmf_unwraprefdecay-purpose}
32/// Provide a meta-function to decay and unwrap reference wrappers.
33///
34/// # Classes {#bslmf_unwraprefdecay-classes}
35///
36/// - bsl::unwrap_ref_decay: standard meta-function to unwrap decayed ref wrapper
37/// - bsl::unwrap_ref_decay_t: alias to the return type of the meta-function
38///
39/// # Canonical Header {#bslmf_unwraprefdecay-canonical-header}
40/// bsl_functional.h, bsl_type_traits.h
41///
42/// @see bslmf_referencewrapper, bslmf_unwrap_reference
43///
44/// # Description {#bslmf_unwraprefdecay-description}
45/// This component defines a meta-function `bsl::unwrap_ref_decay`
46/// that may be used to unwrap a possibly cv-qualified `bsl::reference_wrapper`
47/// (which is an alias of `std::reference_wrapper` if that exists)
48/// specialization or reference thereto of some type `U`, resulting in `U&`. In
49/// case the specified type template argument is not a specialization of
50/// `bsl::reference_wrapper` the result is the type, but decayed (`bsl::decay`).
51///
52/// `bsl::unwrap_ref_decay` meets the requirements of the @ref unwrap_ref_decay
53/// template defined in the C++20 standard [meta.trans.other].
54///
55/// ## Usage {#bslmf_unwraprefdecay-usage}
56///
57///
58/// In this section we show intended use of this component.
59///
60/// ### Example 1: Unwrap Reference Wrapped Argument Types {#bslmf_unwraprefdecay-example-1-unwrap-reference-wrapped-argument-types}
61///
62///
63/// Suppose that we work in a programming environment where function argument
64/// types may be presented as is, or wrapped in a `bsl::reference_wrapper` and
65/// we would like to create a member or local variable while obeying the request
66/// for the reference type that the reference-wrapper represents. As parameters
67/// may be cv-qualified and may be references we need to first decay them (see
68/// `bsl::decay`). When the argument type decays into a reference-wrapper we
69/// want to use a reference to the wrapped type, and simply use the decayed
70/// variations of types that are not wrapped. This is a use case for
71/// `bsl::unwrap_ref_decay`.
72///
73/// First, we create types that may be the bases for reference-wrapped, and
74/// normal type parameters:
75/// @code
76/// typedef bsl::reference_wrapper<int *> WrappedType;
77/// typedef int *NotWrappedType;
78/// @endcode
79/// Next, we create types that represent possible function argument types:
80/// @code
81/// typedef WrappedType WrappedTypeArray[5];
82/// typedef WrappedType *WrappedTypePointer;
83/// typedef const WrappedType ConstWrappedType;
84/// typedef volatile WrappedType VolatileWrappedType;
85/// typedef const volatile WrappedType CvWrappedType;
86/// typedef WrappedType& WrappedTypeRef;
87/// typedef const WrappedType& ConstWrappedTypeRef;
88/// typedef volatile WrappedType& VolatileWrappedTypeRef;
89/// typedef const volatile WrappedType& CvWrappedTypeRef;
90///
91/// typedef NotWrappedType NotWrappedTypeArray[5];
92/// typedef NotWrappedType *NotWrappedTypePointer;
93/// typedef const NotWrappedType ConstNotWrappedType;
94/// typedef volatile NotWrappedType VolatileNotWrappedType;
95/// typedef const volatile NotWrappedType CvNotWrappedType;
96/// typedef NotWrappedType& NotWrappedTypeRef;
97/// typedef const NotWrappedType& ConstNotWrappedTypeRef;
98/// typedef volatile NotWrappedType& VolatileNotWrappedTypeRef;
99/// typedef const volatile NotWrappedType& CvNotWrappedTypeRef;
100/// @endcode
101/// Finally we can verify and demonstrate how all these types turn into a
102/// decayed type, and only those that decay into a reference-wrapper type will
103/// become themselves references. Notice that an array of reference wrappers
104/// decays into a pointer to a wrapper, so it will not turn into a reference.
105/// @code
106/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedTypeArray>::type,
107/// WrappedType *>::value));
108/// assert((true == bsl::is_same<
109/// bsl::unwrap_ref_decay<WrappedTypePointer>::type,
110/// WrappedTypePointer>::value));
111///
112/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedType>::type,
113/// int *&>::value));
114/// assert((true == bsl::is_same<
115/// bsl::unwrap_ref_decay<ConstWrappedType>::type,
116/// int *&>::value));
117/// assert((true == bsl::is_same<
118/// bsl::unwrap_ref_decay<VolatileWrappedType>::type,
119/// int *&>::value));
120/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvWrappedType>::type,
121/// int *&>::value));
122/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<WrappedTypeRef>::type,
123/// int *&>::value));
124/// assert((true == bsl::is_same<
125/// bsl::unwrap_ref_decay<ConstWrappedTypeRef>::type,
126/// int *&>::value));
127/// assert((true == bsl::is_same<
128/// bsl::unwrap_ref_decay<VolatileWrappedTypeRef>::type,
129/// int *&>::value));
130/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvWrappedTypeRef>::type,
131/// int *&>::value));
132///
133/// // Not wrapped types decay
134/// assert((true == bsl::is_same<
135/// bsl::unwrap_ref_decay<NotWrappedTypeArray>::type,
136/// NotWrappedType *>::value));
137/// assert((true == bsl::is_same<
138/// bsl::unwrap_ref_decay<NotWrappedTypePointer>::type,
139/// NotWrappedTypePointer>::value));
140///
141/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<NotWrappedType>::type,
142/// NotWrappedType>::value));
143/// assert((true == bsl::is_same<
144/// bsl::unwrap_ref_decay<ConstNotWrappedType>::type,
145/// NotWrappedType>::value));
146/// assert((true == bsl::is_same<
147/// bsl::unwrap_ref_decay<VolatileNotWrappedType>::type,
148/// NotWrappedType>::value));
149/// assert((true == bsl::is_same<bsl::unwrap_ref_decay<CvNotWrappedType>::type,
150/// NotWrappedType>::value));
151/// assert((true == bsl::is_same<
152/// bsl::unwrap_ref_decay<NotWrappedTypeRef>::type,
153/// NotWrappedType>::value));
154/// assert((true == bsl::is_same<
155/// bsl::unwrap_ref_decay<ConstNotWrappedTypeRef>::type,
156/// NotWrappedType>::value));
157/// assert((true == bsl::is_same<
158/// bsl::unwrap_ref_decay<VolatileNotWrappedTypeRef>::type,
159/// NotWrappedType>::value));
160/// assert((true == bsl::is_same<
161/// bsl::unwrap_ref_decay<CvNotWrappedTypeRef>::type,
162/// NotWrappedType>::value));
163/// @endcode
164/// Note, that (when available) the `bsl::unwrap_ref_decay_t` avoids the
165/// `::type` suffix and `typename` prefix when we want to use the result of the
166/// `bsl::unwrap_ref_decay` meta-function in templates.
167/// @}
168/** @} */
169/** @} */
170
171/** @addtogroup bsl
172 * @{
173 */
174/** @addtogroup bslmf
175 * @{
176 */
177/** @addtogroup bslmf_unwraprefdecay
178 * @{
179 */
180
181#include <bslscm_version.h>
182
183#include <bslmf_decay.h>
186
188#include <bsls_libraryfeatures.h>
189
190#if BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
191 #include <type_traits> // 'std::unwrap_reference', 'std::unwrap_reference_t'
192#endif
193
194 // =======================
195 // struct unwrap_ref_decay
196 // =======================
197
198namespace bsl {
199
200#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
201using std::unwrap_ref_decay;
202using std::unwrap_ref_decay_t;
203#else
204
205/// This `struct` template implements the @ref unwrap_ref_decay meta-function
206/// defined in the C++20 standard [meta.trans.other], providing an alias,
207/// `type`, that returns the result. `type` is `bsl::decay<t_TYPE>::type`
208/// unless `bsl::decay<t_TYPE>::type` is a specialization of
209/// `bsl::reference_wrapper` (which is an alias to `std::reference_wrapper<U>`
210/// when that exists) for a type `U`, in which case `type` shall be `U&`.
211///
212/// See @ref bslmf_unwraprefdecay
213template <class t_TYPE>
214struct unwrap_ref_decay {
215 // TYPES
216
217 /// This `typedef` is an alias to the reference-unwrapped type of the
218 /// decayed `t_TYPE` template parameter.
219 typedef typename bsl::unwrap_reference<
220 typename bsl::decay<t_TYPE>::type>::type type;
221};
222
223#ifdef BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
224/// @ref unwrap_ref_decay_t is an alias to the return type of the
225/// 'bsl::unwrap_ref_decay' meta-function.
226template <class t_TYPE>
227using unwrap_ref_decay_t = typename unwrap_ref_decay<t_TYPE>::type;
228#endif // BSLS_COMPILERFEATURES_SUPPORT_ALIAS_TEMPLATES
229
230#endif // else of BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY
231
232} // close namespace bsl
233
234#endif
235
236// ----------------------------------------------------------------------------
237// Copyright 2024 Bloomberg Finance L.P.
238//
239// Licensed under the Apache License, Version 2.0 (the "License");
240// you may not use this file except in compliance with the License.
241// You may obtain a copy of the License at
242//
243// http://www.apache.org/licenses/LICENSE-2.0
244//
245// Unless required by applicable law or agreed to in writing, software
246// distributed under the License is distributed on an "AS IS" BASIS,
247// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
248// See the License for the specific language governing permissions and
249// limitations under the License.
250// ----------------------------- END-OF-FILE ----------------------------------
251
252/** @} */
253/** @} */
254/** @} */
decay_imp< U, k_ISARRAY, k_ISFUNC >::type type
Definition bslmf_decay.h:167
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlat_valuetypefunctions.h:939