BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_isreferencewrapper.h
Go to the documentation of this file.
1/// @file bslmf_isreferencewrapper.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_isreferencewrapper.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISREFERENCEWRAPPER
9#define INCLUDED_BSLMF_ISREFERENCEWRAPPER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_isreferencewrapper bslmf_isreferencewrapper
15/// @brief Provide a trait to detect reference-wrapper specializations.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_isreferencewrapper
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_isreferencewrapper-purpose"> Purpose</a>
25/// * <a href="#bslmf_isreferencewrapper-classes"> Classes </a>
26/// * <a href="#bslmf_isreferencewrapper-description"> Description </a>
27/// * <a href="#bslmf_isreferencewrapper-usage"> Usage </a>
28/// * <a href="#bslmf_isreferencewrapper-example-reference-access"> Example: Reference Access </a>
29///
30/// # Purpose {#bslmf_isreferencewrapper-purpose}
31/// Provide a trait to detect reference-wrapper specializations.
32///
33/// # Classes {#bslmf_isreferencewrapper-classes}
34///
35/// - bslmf::IsReferenceWrapper: metafunction for detecting reference wrappers
36///
37/// @see bslstl_referencewrapper
38///
39/// # Description {#bslmf_isreferencewrapper-description}
40/// This component provides a `struct` template,
41/// `bslmf::IsReferenceWrapper`, that is a boolean metafunction with a single
42/// class template parameter `t_TYPE`. `bslmf::IsReferenceWrapper` derives from
43/// `bsl::false_type` by default. The only intended specialization of
44/// `bslmf::IsReferenceWrapper` is for `bsl::reference_wrapper`. Clients are
45/// not allowed to specialized `bslmf::IsReferenceWrapper` for any other type.
46///
47/// This component exists primarily because there are other type traits provided
48/// by components in the `bslmf` package that require the ability to detect
49/// whether or not a type is a specialization of `bsl::reference_wrapper`,
50/// notably `bsl::invoke_result`. `bsl::reference_wrapper` is defined in the
51/// @ref bslstl_referencewrapper component in the `bslstl` package, and is
52/// available to clients through the @ref bsl_functional component in the
53/// `bsl+bslhdrs` package. These packages are levelized above `bslmf`, and so
54/// this trait permits components in the `bslmf` package (and above) to detect
55/// whether or not a type is a reference wrapper even if they cannot refer to
56/// the `bsl::reference_wrapper` type.
57///
58/// ## Usage {#bslmf_isreferencewrapper-usage}
59///
60///
61/// In this section we show intended use of this component.
62///
63/// ### Example: Reference Access {#bslmf_isreferencewrapper-example-reference-access}
64///
65///
66/// In this example, we suppose that we would like to provide a software
67/// component that treats specializations of `bsl::reference_wrapper` and
68/// true reference qualified types in the same way.
69///
70/// Suppose that we would like to do this by having a utility function that
71/// returns an lvalue reference to an object given either an lvalue-reference
72/// qualified type or a `bsl::reference_wrapper`.
73///
74/// First, we define a utility `struct` that contains the overload of this
75/// utility function for `const` and non-`const` lvalue-reference qualified
76/// types:
77/// @code
78/// struct MyLvalueReferenceUtil {
79/// // CLASS METHODS
80/// template <class t_TYPE>
81/// static t_TYPE& access(t_TYPE& reference)
82/// {
83/// return reference;
84/// }
85///
86/// template <class t_TYPE>
87/// static const t_TYPE& access(const t_TYPE& reference)
88/// {
89/// return reference;
90/// }
91/// @endcode
92/// Then, we define the overload of this utility function for reference
93/// wrappers, taking care to define it such that it does not participate in
94/// overload resolution unless it is passed a reference wrapper:
95/// @code
96/// template <class t_TYPE>
97/// static typename bsl::enable_if<
98/// bslmf::IsReferenceWrapper<t_TYPE>::value,
99/// typename bsl::add_lvalue_reference<typename t_TYPE::type>::type
100/// >::type
101/// access(t_TYPE referenceWrapper)
102/// {
103/// return referenceWrapper.get();
104/// }
105/// };
106/// @endcode
107/// Finally, we can verify that this utility allows us to transparently access
108/// lvalue references:
109/// @code
110/// void example()
111/// {
112/// int x = 1;
113/// assert(1 == MyLvalueReferenceUtil::access(x));
114///
115/// const int y = 2;
116/// assert(2 == MyLvalueReferenceUtil::access(y));
117///
118/// // Note that even though the following invokes 'access' with the
119/// // literal 3, which is a prvalue expression, the call expression is
120/// // an lvalue with type 'const int&'.
121/// assert(3 == MyLvalueReferenceUtil::access(3));
122///
123/// // Further, note that the levelization of the
124/// // 'bslmf_isreferencewrapper' component prohibits showing the
125/// // application of 'MyLvalueReferenceUtil' to a reference wrapper.
126/// // The following commented-out code would be valid given a suitable
127/// // 'bsl::reference_wrapper' type that acts like a reference wrapper
128/// // and specializes the 'bslmf::IsReferenceWrapper' trait accordingly.
129/// //..
130/// // assert(x == MyLvalueReferenceUtil::access(
131/// // bsl::reference_wrapper<int>(x)));
132/// //..
133/// }
134/// @endcode
135/// @}
136/** @} */
137/** @} */
138
139/** @addtogroup bsl
140 * @{
141 */
142/** @addtogroup bslmf
143 * @{
144 */
145/** @addtogroup bslmf_isreferencewrapper
146 * @{
147 */
148
149#include <bslmf_integralconstant.h>
150
151
152namespace bslmf {
153
154 // =========================
155 // struct IsReferenceWrapper
156 // =========================
157
158/// This `struct` template implements a boolean metafunction used to detect
159/// if the specified `t_TYPE` is a reference wrapper. Clients may
160/// specialize this `struct` template to inherit from `bsl::true_type` for
161/// `t_TYPE` types that are specializations of `bsl::reference_wrapper`.
162/// The behavior is undefined if any other specialization of this `struct`
163/// template is defined. Note that this `struct` template
164template <class t_TYPE>
167
168} // close package namespace
169
170
171#endif // INCLUDED_BSLMF_ISREFERENCEWRAPPER
172
173// ----------------------------------------------------------------------------
174// Copyright 2021 Bloomberg Finance L.P.
175//
176// Licensed under the Apache License, Version 2.0 (the "License");
177// you may not use this file except in compliance with the License.
178// You may obtain a copy of the License at
179//
180// http://www.apache.org/licenses/LICENSE-2.0
181//
182// Unless required by applicable law or agreed to in writing, software
183// distributed under the License is distributed on an "AS IS" BASIS,
184// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
185// See the License for the specific language governing permissions and
186// limitations under the License.
187// ----------------------------- END-OF-FILE ----------------------------------
188
189/** @} */
190/** @} */
191/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlbb_blob.h:576
Definition bslmf_integralconstant.h:244
Definition bslmf_isreferencewrapper.h:165