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