BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_isnothrowswappable.h
Go to the documentation of this file.
1/// @file bslmf_isnothrowswappable.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_isnothrowswappable.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISNOTHROWSWAPPABLE
9#define INCLUDED_BSLMF_ISNOTHROWSWAPPABLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_isnothrowswappable bslmf_isnothrowswappable
15/// @brief Provide metafunction to identify nothrow swappable types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_isnothrowswappable
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_isnothrowswappable-purpose"> Purpose</a>
25/// * <a href="#bslmf_isnothrowswappable-classes"> Classes </a>
26/// * <a href="#bslmf_isnothrowswappable-description"> Description </a>
27/// * <a href="#bslmf_isnothrowswappable-usage"> Usage </a>
28/// * <a href="#bslmf_isnothrowswappable-example-1-verify-class-types"> Example 1: Verify Class Types </a>
29///
30/// # Purpose {#bslmf_isnothrowswappable-purpose}
31/// Provide metafunction to identify nothrow swappable types.
32///
33/// # Classes {#bslmf_isnothrowswappable-classes}
34///
35/// - bsl::is_nothrow_swappable: type-traits metafunction
36/// - bsl::is_nothrow_swappable_v: the metafunction's result value
37///
38/// @see bslmf_integralconstant
39///
40/// # Description {#bslmf_isnothrowswappable-description}
41/// This component defines a metafunction,
42/// `bsl::is_nothrow_swappable`, and a variable template
43/// `bsl::is_nothrow_swappable_v` that represents the result value of the
44/// `bsl::is_nothrow_swappable` metafunction, which may be used to query whether
45/// `swap(x,y);` is well-formed. Note that this is only implemented for C++11
46/// and above.
47///
48/// `bsl::is_nothrow_swappable` meets the requirements of the
49/// `is_nothrow_swappable` template defined in the C++17 standard.
50///
51/// Note that the template variable `is_nothrow_swappable_v` is defined in the
52/// C++17 standard as an inline variable. If the current compiler supports the
53/// inline variable C++17 compiler feature, `bsl::is_nothrow_swappable_v` is
54/// defined as an `inline constexpr bool` variable. Otherwise, if the compiler
55/// supports the variable templates C++14 compiler feature,
56/// `bsl::is_nothrow_swappable_v` is defined as a non-inline `constexpr bool`
57/// variable. See `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
58/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in the
59/// bsls_compilerfeatures component for details.
60///
61/// ## Usage {#bslmf_isnothrowswappable-usage}
62///
63///
64/// In this section we show intended use of this component.
65///
66/// ### Example 1: Verify Class Types {#bslmf_isnothrowswappable-example-1-verify-class-types}
67///
68///
69/// Suppose that we want to assert whether a particular type is nothrow
70/// swappable.
71///
72/// First, we create two `struct`s -- one nothrow swappable and one not.
73/// @code
74/// struct MyType1 {
75/// // trivial so swappable
76/// };
77///
78/// struct MyType2 {
79/// // private assignement, so not swappable
80/// private:
81/// // NOT IMPLEMENTED
82/// MyType2& operator=(const MyType2&);
83/// // Assignment operator made private to prevent swappability.
84/// };
85/// @endcode
86/// Now, we instantiate the `bsl::is_nothrow_swappable` template for each of the
87/// `struct`s and assert the `value` static data member of each instantiation:
88/// @code
89/// assert(true == bsl::is_nothrow_swappable<MyType1>::value);
90/// assert(false == bsl::is_nothrow_swappable<MyType2>::value);
91/// @endcode
92/// Note that if the current compiler supports the variable templates C++14
93/// feature then we can re-write the snippet of code above using the
94/// `bsl::is_nothrow_swappable_v` variable as follows:
95/// @code
96/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
97/// assert(true == bsl::is_nothrow_swappable_v<MyType1>);
98/// assert(false == bsl::is_nothrow_swappable_v<MyType2>);
99/// #endif
100/// @endcode
101/// @}
102/** @} */
103/** @} */
104
105/** @addtogroup bsl
106 * @{
107 */
108/** @addtogroup bslmf
109 * @{
110 */
111/** @addtogroup bslmf_isnothrowswappable
112 * @{
113 */
114
115#include <bslscm_version.h>
116
117#include <bslmf_assert.h>
118#include <bslmf_enableif.h>
119#include <bslmf_if.h>
121#include <bslmf_isswappable.h>
122#include <bslmf_util.h>
123#include <bslmf_voidtype.h>
124
126#include <bsls_keyword.h>
127#include <bsls_platform.h>
128
129#include <stddef.h>
130
131#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
132# include <type_traits>
133#endif // BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
134
135#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
136#include <bsls_nativestd.h>
137#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
138
139
140// Forward declaration for C++11 and C++14 non-MSVC
141#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) && \
142 !defined(BSLS_PLATFORM_CMP_MSVC) && \
143 defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR) && \
144 defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) && \
145 defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
146
147namespace bslmf {
148namespace bslmf_is_nothrow_swappable_impl_ns {
149// This test requires that 'using std::swap' be executed, hence the use of a
150// named namespace to prevent that statement from "leaking" outside of the
151// 'bslmf_isnothrowswappable.h' header.
152
153template <class TYPE, class = void>
154struct IsNoThrowSwappable_Impl;
155 // Forward declaration
156
157} // close namespace bslmf_is_nothrow_swappable_impl_ns
158} // close package namespace
159
160#endif
161
162 // ===========================
163 // struct is_nothrow_swappable
164 // ===========================
165
166namespace bsl {
167
168// C++17 alias definition
169#if defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY)
170
171using std::is_nothrow_swappable;
172using std::is_nothrow_swappable_v;
173
174// Windows non-C++17 definition
175#elif defined(BSLS_PLATFORM_CMP_MSVC)
176// For MSVC before 2019 and all MSVC versions building C++14 (C++14 is the
177// lowest supported by MSVC), a combination of MSVC's name lookup and sfinae
178// peculiarities means we cannot reproduce this behaviour. Under these
179// unfortunate circumstances, it is therefore safest to assume nothing is
180// nothrow swappable.
181
182#define BSLMF_ISNOTHROWSWAPPABLE_ALWAYS_FALSE 1
183
184template <class TYPE>
185struct is_nothrow_swappable : bsl::false_type {};
186
187template <class TYPE>
189constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<TYPE>::value;
190 // This template variable represents the result value of the
191 // 'bsl::is_nothrow_swappable' metafunction.
192
193// C++11 implementation
194#elif defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR) \
195 && defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) \
196 && defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
197// We are compiling C++11 or C++14 on a conformant compiler, so we can
198// replicate the is_swappable trait.
199
200template <class TYPE>
201struct is_nothrow_swappable
202: BloombergLP::bslmf::If<
203 BloombergLP::bslmf::bslmf_is_nothrow_swappable_impl_ns::
204 IsNoThrowSwappable_Impl<TYPE>::isNoexcept(),
205 bsl::true_type,
206 bsl::false_type>::Type {
207 // This 'struct' template implements a metafunction to determine whether
208 // the (template parameter) 'TYPE' is nothrow swappable. This 'struct'
209 // derives from 'bsl::true_type' if the 'TYPE' is nothrow swappable, and
210 // from 'bsl::false_type' otherwise. This metafunction has the same syntax
211 // as the 'is_nothrow_swappable' metafunction defined in the C++17 standard
212 // [meta.unary.prop]; on C++03 platforms this metafunction is not
213 // implemented; on C++11 platforms, it is implemented where it is possible
214 // to do so given compiler support, with the notable exception of MSVC.
215};
216
217#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
218template <class TYPE>
220constexpr bool is_nothrow_swappable_v =
221 is_nothrow_swappable<TYPE>::value;
222 // This template variable represents the result value of the
223 // 'bsl::is_nothrow_swappable' metafunction.
224#endif // BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
225
226#endif
227
228} // close namespace bsl
229
230// ============================================================================
231// TEMPLATE IMPLEMENTATIONS
232// ============================================================================
233
234// Template implementation only for C++11 and C++14 non-MSVC
235#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) && \
236 !defined(BSLS_PLATFORM_CMP_MSVC) && \
237 defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR) && \
238 defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) && \
239 defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
240
241namespace bslmf {
242namespace bslmf_is_nothrow_swappable_impl_ns {
243// This test requires that 'using std::swap' be executed, hence the use of a
244// named namespace to prevent that statement from "leaking" outside of the
245// 'bslmf_isnothrowswappable.h' header.
246
247using std::swap;
248
249template <class TYPE, class BDE_OTHER_TYPE>
250struct IsNoThrowSwappable_Impl {
251 // This 'struct' template implements a 'constexpr' 'evaluate' function to
252 // determine whether the (template parameter) 'TYPE' is nothrow swappable.
253 // The default implementation is for non-swappable types, which are, by
254 // definition, not nothrow swappable. Note that the partial
255 // specializations below will provide the determination for swappable
256 // types.
257
258 // CLASS METHODS
259 static constexpr bool isNoexcept();
260 // 'constexpr' method to determine whether the (template) parameter
261 // 'TYPE' is nothrow swappable.
262};
263
264template <class TYPE>
265struct IsNoThrowSwappable_Impl<
266 TYPE,
267 typename bsl::enable_if<bsl::is_swappable<TYPE>::value, void>::type> {
268 // This 'struct' template implements a 'constexpr' 'evaluate' to determine
269 // whether the (template parameter) 'TYPE' is nothrow swappable. Note that
270 // this partial specialization provides the determination for swappable
271 // types.
272
273 // CLASS METHODS
274 static constexpr bool isNoexcept();
275 // 'constexpr' method to determine whether the (template) parameter
276 // 'TYPE' is nothrow swappable.
277};
278
279
280template <class TYPE, class BDE_OTHER_TYPE>
281constexpr bool
282IsNoThrowSwappable_Impl<TYPE, BDE_OTHER_TYPE>
283::isNoexcept()
284{
285 return false;
286}
287
288template <class TYPE>
289constexpr bool
290IsNoThrowSwappable_Impl<
291 TYPE,
293::isNoexcept()
294{
295 return noexcept(swap(BloombergLP::bslmf::Util::declval<TYPE&>(),
296 BloombergLP::bslmf::Util::declval<TYPE&>()));
297}
298
299} // close namespace bslmf_is_nothrow_swappable_impl_ns
300} // close package namespace
301
302#endif
303
304#endif // INCLUDED_BSLMF_ISNOTHROWSWAPPABLE
305
306// ----------------------------------------------------------------------------
307// Copyright 2022 Bloomberg Finance L.P.
308//
309// Licensed under the Apache License, Version 2.0 (the "License");
310// you may not use this file except in compliance with the License.
311// You may obtain a copy of the License at
312//
313// http://www.apache.org/licenses/LICENSE-2.0
314//
315// Unless required by applicable law or agreed to in writing, software
316// distributed under the License is distributed on an "AS IS" BASIS,
317// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
318// See the License for the specific language governing permissions and
319// limitations under the License.
320// ----------------------------- END-OF-FILE ----------------------------------
321
322/** @} */
323/** @} */
324/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_INLINE_VARIABLE
Definition bsls_keyword.h:623
void swap(OptionValue &a, OptionValue &b)
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
void swap(TYPE &a, TYPE &b)
Definition bslmf_enableif.h:525
Definition bslmf_integralconstant.h:244