BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmf_isnothrowmoveconstructible.h
Go to the documentation of this file.
1/// @file bslmf_isnothrowmoveconstructible.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_isnothrowmoveconstructible.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISNOTHROWMOVECONSTRUCTIBLE
9#define INCLUDED_BSLMF_ISNOTHROWMOVECONSTRUCTIBLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_isnothrowmoveconstructible bslmf_isnothrowmoveconstructible
15/// @brief Provide metafunction to identify no-throw move-constructible types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_isnothrowmoveconstructible
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_isnothrowmoveconstructible-purpose"> Purpose</a>
25/// * <a href="#bslmf_isnothrowmoveconstructible-classes"> Classes </a>
26/// * <a href="#bslmf_isnothrowmoveconstructible-description"> Description </a>
27///
28/// # Purpose {#bslmf_isnothrowmoveconstructible-purpose}
29/// Provide metafunction to identify no-throw move-constructible types.
30///
31/// # Classes {#bslmf_isnothrowmoveconstructible-classes}
32///
33/// - bsl::is_nothrow_move_constructible: type-traits metafunction
34/// - bsl::is_nothrow_move_constructible_v: the metafunction's result value
35///
36/// @see bslmf_integralconstant, bslmf_nestedtraitdeclaration,
37/// bslmf_movableref
38///
39/// # Description {#bslmf_isnothrowmoveconstructible-description}
40/// This component defines a metafunction,
41/// `bsl::is_nothrow_move_constructible`, and a variable template
42/// `bsl::is_nothrow_move_constructible_v` that represents the result value of
43/// the `bsl::is_nothrow_move_constructible` metafunction, which may be used to
44/// query whether a type has a constructor that can be called with a single
45/// rvalue that is known to not throw exceptions. Note that a C++11 compiler
46/// will automatically infer this trait for class types with a move constructor
47/// that is marked as `noexcept`.
48///
49/// `bsl::is_nothrow_move_constructible` meets the requirements of the
50/// `is_nothrow_move_constructible` template defined in the C++11 standard.
51///
52/// Note that the template variable `is_nothrow_move_constructible_v` is defined
53/// in the C++17 standard as an inline variable. If the current compiler
54/// supports the inline variable C++17 compiler feature,
55/// `bsl::is_nothrow_move_constructible_v` is defined as an 'inline constexpr
56/// bool' variable. Otherwise, if the compiler supports the variable templates
57/// C++14 compiler feature, `bsl::is_nothrow_move_constructible_v` is defined as
58/// a non-inline `constexpr bool` variable. See
59/// `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
60/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in the
61/// bsls_compilerfeatures component for details.
62/// @}
63/** @} */
64/** @} */
65
66/** @addtogroup bsl
67 * @{
68 */
69/** @addtogroup bslmf
70 * @{
71 */
72/** @addtogroup bslmf_isnothrowmoveconstructible
73 * @{
74 */
75
76#include <bslscm_version.h>
77
78#include <bslmf_assert.h>
81#include <bslmf_isarray.h>
83#include <bslmf_isconst.h>
84#include <bslmf_isvolatile.h>
85#include <bslmf_voidtype.h>
86
88#include <bsls_keyword.h>
89#include <bsls_platform.h>
90
91#include <stddef.h>
92
93#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
94# include <type_traits>
95#endif // BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
96
97#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
98#include <bsls_nativestd.h>
99#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
100
101namespace bsl {
102
103template <class t_TYPE>
104struct is_nothrow_move_constructible;
105
106} // close namespace bsl
107
108///Implementation Notes
109///--------------------
110// In C++20 certain array types which decay to their element type, such as
111// 'const void*' and 'bool', report as copy constructible through
112// 'std::is_nothrow_move_constructible'. In fact, initialization that attempts
113// such move constructions does not result in a copy of the orginal array but
114// instead initializes only the first element of the new array -- and that is
115// set to the address of the original array, not the original's first element.
116//
117// This behavior has been observed in 'gcc-11' targeting C++20 and should occur
118// with any compiler correctly supporting C++20 aggregate initialization with
119// parenthesis (identified by the feature test macro
120// '__cpp_aggregate_paren_init').
121//
122// An LWG issue (https://wg21.link/lwg####) has been filed to correct this
123// behavior and continue to return 'false' for all array types.
124//
125// The implementation below preemptively implements the expected resolution of
126// that issue on all platforms.
127
128#define STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(t_TYPE) \
129 (bsl::is_array<t_TYPE>::value \
130 ? false \
131 : ::std::is_nothrow_move_constructible<t_TYPE>::value)
132
133
134namespace bslmf {
135
136 // =====================================
137 // struct IsNothrowMoveConstructible_Imp
138 // =====================================
139
140#if defined(BSLS_PLATFORM_CMP_SUN) && \
141 (BSLS_PLATFORM_CMP_VERSION == 0x5150) && \
142 (BSLS_COMPILERFEATURES_CPLUSPLUS == 199711L)
143// Solaris 12.6 compiler in C++03 mode treats as ambiguous partial
144// specializations with `t_TYPE` and with cv-qualified `t_TYPE`.
145#define BSLMF_ISNOTHROWMOVECONSTRUCTIBLE_VOIDTYPE(t_TYPE) \
146 typename bsl::enable_if<!bsl::is_const<t_TYPE>::value && \
147 !bsl::is_volatile<t_TYPE>::value, \
148 BSLMF_VOIDTYPE(int t_TYPE::*)>::type
149#else
150#define BSLMF_ISNOTHROWMOVECONSTRUCTIBLE_VOIDTYPE(t_TYPE) \
151 BSLMF_VOIDTYPE(int t_TYPE::*)
152#endif
153
154#if defined(BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER)
155/// This `struct` template implements a metafunction to determine whether
156/// the (non-cv-qualified) (template parameter) `t_TYPE` has a no-throw move constructor.
157///
158/// \note Note that the partial specializations below will provide
159/// the determination for class types.
160template <class t_TYPE, class = void>
161struct IsNothrowMoveConstructible_Impl
163 STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(t_TYPE)> {
164};
165
166/// This `struct` template implements a metafunction to determine whether
167/// the (non-cv-qualified) (template parameter) `t_TYPE` has a no-throw move
168/// constructor. To maintain consistency between the C++03 and C++11
169/// implementations of this trait, types that use the BDE trait association
170/// techniques are also detected as no-throw move constructible, even if the
171/// `noexcept` operator would draw a different conclusion.
172template <class t_TYPE>
173struct IsNothrowMoveConstructible_Impl<
174 t_TYPE,
177 bool,
178 STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(t_TYPE) ||
179 bslmf::IsBitwiseCopyable<t_TYPE>::value ||
180 DetectNestedTrait<t_TYPE,
181 bsl::is_nothrow_move_constructible>::value> {
182
183 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
184};
185
186template <class t_TYPE>
187struct IsNothrowMoveConstructible_Impl<
188 const t_TYPE,
191 bool,
192 STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(const t_TYPE) ||
193 bslmf::IsBitwiseCopyable<t_TYPE>::value> {
194 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
195};
196
197template <class t_TYPE>
198struct IsNothrowMoveConstructible_Impl<
199 volatile t_TYPE,
202 bool,
203 STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(volatile t_TYPE)> {
204 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
205};
206
207template <class t_TYPE>
208struct IsNothrowMoveConstructible_Impl<
209 const volatile t_TYPE,
212 bool,
213 STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE(const volatile t_TYPE)> {
214 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
215};
216 // Partial specializations to avoid detecting cv-qualified class types with
217 // nested trait declarations as having no-throw constructors that take
218 // cv-qualified rvalues unless those constructors are actually detected as
219 // non-throwing. Note that volatile-qualified scalar types will detect as
220 // no-throw move constructible through the primary template. In addition,
221 // we flag types that specialize 'bslmf::IsBitwiseCopyable' as no-throw
222 // move constructible to maintain consistency between the C++03 and C++11
223 // implementations of this trait.
224
225#undef STD_IS_NOTHROW_MOVE_CONSTRUCTIBLE_VALUE
226#else
227/// This `struct` template implements a metafunction to determine whether
228/// the (non-cv-qualified) (template parameter) `t_TYPE` has a no-throw move
229/// constructor. For C++03, the set of types known to be no-throw move constructible are all trivial types.
230///
231/// \note Note that the partial
232/// specializations below will provide the determination for class types,
233/// and this primary template is equivalent to querying whether `t_TYPE` is
234/// a scalar type.
235template <class t_TYPE, class = void>
239
240/// This `struct` template implements a metafunction to determine whether
241/// the (non-cv-qualified) (template parameter) `t_TYPE` has a no-throw move
242/// constructor. To maintain consistency between the C++03 and C++11
243/// implementations of this trait, types that use the BDE trait association
244/// techniques are also detected as no-throw move constructible, even if the
245/// `noexcept` operator would draw a different conclusion.
246template <class t_TYPE>
248 t_TYPE,
251 bool,
252 bslmf::IsBitwiseCopyable<t_TYPE>::value ||
253 DetectNestedTrait<t_TYPE,
254 bsl::is_nothrow_move_constructible>::value> {
255
256 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
257};
258
259template <class t_TYPE>
261 const t_TYPE,
263: bslmf::IsBitwiseCopyable<t_TYPE>::type {
264 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
265};
266
267template <class t_TYPE>
269 volatile t_TYPE,
271 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
272};
273
274template <class t_TYPE>
276 const volatile t_TYPE,
278 enum { k_CHECK_COMPLETE = sizeof(t_TYPE) }; // Diagnose incomplete types
279};
280 // Partial specializations to avoid detecting cv-qualified class types with
281 // nested trait declarations as having no-throw constructors that take
282 // cv-qualified rvalues unless those constructors are actually detected.
283 // Note that volatile-qualified scalar types will detect as no-throw move
284 // constructible through the primary template. As a practical matter, we
285 // assume that types flagged as trivially copyable have a no-throw copy
286 // constructor, and so are no-throw move constructible too.
287
288#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
289template <class t_TYPE>
290struct IsNothrowMoveConstructible_Impl<t_TYPE&&> : bsl::true_type {
291};
292#endif
293template <class t_TYPE>
296 // Partial specializations to indicate that reference binding from an
297 // identical reference can never throw.
298
299template <class t_TYPE>
302template <class t_TYPE>
304};
305template <class t_TYPE>
307};
308template <class t_TYPE>
309struct IsNothrowMoveConstructible_Impl<const volatile t_TYPE[]>
311};
312template <class t_TYPE, size_t t_LEN>
314};
315template <class t_TYPE, size_t t_LEN>
317};
318template <class t_TYPE, size_t t_LEN>
319struct IsNothrowMoveConstructible_Impl<volatile t_TYPE[t_LEN]>
321};
322template <class t_TYPE, size_t t_LEN>
323struct IsNothrowMoveConstructible_Impl<const volatile t_TYPE[t_LEN]>
325};
326 // These partial specializations ensure that array types are not detected
327 // as move constructible. Note that while array data members of classes
328 // will correctly move each element through move-construction (when
329 // initializing the owning class), the standard defines the type trait in
330 // terms of a variable declaration, where the move construction syntax is
331 // invalid.
332
333#endif
334} // close package namespace
335
336
337namespace bsl {
338
339 // ====================================
340 // struct is_nothrow_move_constructible
341 // ====================================
342
343/// This `struct` template implements a metafunction to determine whether
344/// the (template parameter) `t_TYPE` has a no-throw move constructor. This
345/// `struct` derives from `bsl::true_type` if the `t_TYPE` has a no-throw
346/// move constructor, and from `bsl::false_type` otherwise. This
347/// metafunction has the same syntax as the `is_nothrow_move_constructible`
348/// metafunction defined in the C++11 standard [meta.unary.prop]; on C++03
349/// platforms, however, this metafunction can automatically determine the
350/// value for trivially copyable types (including scalar types), for
351/// reference types, and for class types associating with the
352/// `bsl::is_nothrow_move_constructible` trait using the
353/// `BSLMF_NESTED_TRAIT_DECLARATION` macro. To support other no-throw move
354/// constructible types, this template should be specialized to inherit from `bsl::true_type`.
355///
356/// \note Note that cv-qualified user defined types are rarely
357/// no-throw move constructible unless they are also trivially copyable, so
358/// there are no cv-qualified partial specializations of this trait.
359template <class t_TYPE>
361: BloombergLP::bslmf::IsNothrowMoveConstructible_Impl<t_TYPE>::type {
362};
363
364#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
365/// This template variable represents the result value of the
366/// `bsl::is_nothrow_move_constructible` metafunction.
367template <class t_TYPE>
368BSLS_KEYWORD_INLINE_VARIABLE constexpr bool is_nothrow_move_constructible_v =
370#endif
371
372} // close namespace bsl
373
374#endif
375
376// ----------------------------------------------------------------------------
377// Copyright 2019 Bloomberg Finance L.P.
378//
379// Licensed under the Apache License, Version 2.0 (the "License");
380// you may not use this file except in compliance with the License.
381// You may obtain a copy of the License at
382//
383// http://www.apache.org/licenses/LICENSE-2.0
384//
385// Unless required by applicable law or agreed to in writing, software
386// distributed under the License is distributed on an "AS IS" BASIS,
387// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
388// See the License for the specific language governing permissions and
389// limitations under the License.
390// ----------------------------- END-OF-FILE ----------------------------------
391
392/** @} */
393/** @} */
394/** @} */
#define BSLMF_ISNOTHROWMOVECONSTRUCTIBLE_VOIDTYPE(t_TYPE)
Definition bslmf_isnothrowmoveconstructible.h:150
#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
Definition bdlat_valuetypefunctions.h:939
Definition bdlbb_blob.h:579
Definition bslmf_integralconstant.h:261
Definition bslmf_isnothrowmoveconstructible.h:361
Definition bslmf_isbitwisecopyable.h:298
Definition bslmf_isnothrowmoveconstructible.h:237