BDE 4.14.0 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#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
137#include <bsls_nativestd.h>
138#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
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_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_isswappable.h' header.
152
153template <class TYPE, class = void>
154struct IsSwappable_Impl;
155 // Forward declaration
156
157} // close namespace bslmf_is_swappable_impl_ns
158} // close package namespace
159
160#endif
161
162 // ===================
163 // struct is_swappable
164 // ===================
165
166namespace bsl {
167
168// C++17 alias definition
169#if defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY)
170
171using std::is_swappable;
172using std::is_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// swappable.
181
182template <class TYPE>
183struct is_swappable : bsl::false_type {};
184
185template <class TYPE>
187constexpr bool is_swappable_v = is_swappable<TYPE>::value;
188 // This template variable represents the result value of the
189 // 'bsl::is_swappable' metafunction.
190
191// C++11 implementation
192#elif defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR) \
193 && defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) \
194 && defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
195// We are compiling C++11 or C++14 on a conformant compiler, so we can
196// replicate the is_swappable trait.
197
198template <class TYPE>
199struct is_swappable
200 : BloombergLP::bslmf::bslmf_is_swappable_impl_ns::IsSwappable_Impl<TYPE> {
201 // This 'struct' template implements a metafunction to determine whether
202 // the (template parameter) 'TYPE' is swappable. This 'struct' derives
203 // from 'bsl::true_type' if the 'TYPE' is swappable, and from
204 // 'bsl::false_type' otherwise. This metafunction has the same syntax as
205 // the 'is_swappable' metafunction defined in the C++17 standard
206 // [meta.unary.prop]; on C++03 platforms this metafunction is not
207 // implemented; on C++11 platforms, it is implemented where it is possible
208 // to do so given compiler support, with the notable exception of MSVC.
209};
210
211#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
212template <class TYPE>
214constexpr bool is_swappable_v = is_swappable<TYPE>::value;
215 // This template variable represents the result value of the
216 // 'bsl::is_swappable' metafunction.
217#endif
218
219#endif
220
221} // close namespace bsl
222
223// ============================================================================
224// TEMPLATE IMPLEMENTATIONS
225// ============================================================================
226
227// Template implementation only for C++11 and C++14 non-MSVC
228#if !defined(BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY) && \
229 !defined(BSLS_PLATFORM_CMP_MSVC) && \
230 defined(BSLS_COMPILERFEATURES_SUPPORT_CONSTEXPR) && \
231 defined(BSLS_COMPILERFEATURES_SUPPORT_NOEXCEPT) && \
232 defined(BSLS_COMPILERFEATURES_SUPPORT_DECLTYPE)
233
234namespace bslmf {
235namespace bslmf_is_swappable_impl_ns
236{
237// This test requires that 'using std::swap' be executed, hence the use of a
238// named namespace to prevent that statement from "leaking" outside of the
239// 'bslmf_isswappable.h' header.
240
241using std::swap;
242
243template <class TYPE, class>
244struct IsSwappable_Impl
246 // This 'struct' template implements a metafunction to determine whether
247 // the (template parameter) 'TYPE' is swappable. Note that the partial
248 // specializations below will provide the determination for class types.
249};
250
251template <class TYPE>
252struct IsSwappable_Impl<TYPE,
253 BSLMF_VOIDTYPE(decltype(
254 swap(BloombergLP::bslmf::Util::declval<TYPE&>(),
255 BloombergLP::bslmf::Util::declval<TYPE&>())))>
257 // Partial specialization to determine whether the (template parameter)
258 // 'TYPE' is swappable as defined in the C++17 standard.
259};
260
261} // close namespace bslmf_is_swappable_impl_ns
262} // close package namespace
263
264#endif
265
266#endif // INCLUDED_BSLMF_ISSWAPPABLE
267
268// ----------------------------------------------------------------------------
269// Copyright 2022 Bloomberg Finance L.P.
270//
271// Licensed under the Apache License, Version 2.0 (the "License");
272// you may not use this file except in compliance with the License.
273// You may obtain a copy of the License at
274//
275// http://www.apache.org/licenses/LICENSE-2.0
276//
277// Unless required by applicable law or agreed to in writing, software
278// distributed under the License is distributed on an "AS IS" BASIS,
279// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
280// See the License for the specific language governing permissions and
281// limitations under the License.
282// ----------------------------- END-OF-FILE ----------------------------------
283
284/** @} */
285/** @} */
286/** @} */
#define BSLMF_VOIDTYPE(ARG)
Definition bslmf_voidtype.h:335
#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_integralconstant.h:244
static BSLS_KEYWORD_CONSTEXPR bsl::add_lvalue_reference< t_TYPE >::type declval() BSLS_KEYWORD_NOEXCEPT