BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_istriviallycopyable.h
Go to the documentation of this file.
1/// @file bslmf_istriviallycopyable.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmf_istriviallycopyable.h -*-C++-*-
8#ifndef INCLUDED_BSLMF_ISTRIVIALLYCOPYABLE
9#define INCLUDED_BSLMF_ISTRIVIALLYCOPYABLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmf_istriviallycopyable bslmf_istriviallycopyable
15/// @brief Provide a meta-function for determining trivially copyable types.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmf
19/// @{
20/// @addtogroup bslmf_istriviallycopyable
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmf_istriviallycopyable-purpose"> Purpose</a>
25/// * <a href="#bslmf_istriviallycopyable-classes"> Classes </a>
26/// * <a href="#bslmf_istriviallycopyable-description"> Description </a>
27/// * <a href="#bslmf_istriviallycopyable-bslmf-istriviallycopyablecheck"> bslmf::IsTriviallyCopyableCheck </a>
28/// * <a href="#bslmf_istriviallycopyable-usage"> Usage </a>
29/// * <a href="#bslmf_istriviallycopyable-example-1-verify-whether-types-are-trivially-copyable"> Example 1: Verify Whether Types are Trivially Copyable </a>
30///
31/// # Purpose {#bslmf_istriviallycopyable-purpose}
32/// Provide a meta-function for determining trivially copyable types.
33///
34/// # Classes {#bslmf_istriviallycopyable-classes}
35///
36/// - bsl::is_trivially_copyable: type-traits meta-function
37/// - bsl::is_trivially_copyable_v: the result value of the meta-function
38///
39/// @see bslmf_integralconstant, bslmf_nestedtraitdeclaration
40///
41/// # Description {#bslmf_istriviallycopyable-description}
42/// This component defines a meta-function,
43/// `bsl::is_trivially_copyable` and a template variable
44/// `bsl::is_trivially_copyable_v`, that represents the result value of the
45/// `bsl::is_trivially_copyable` meta-function, that may be used to query
46/// whether a type is trivially copyable as defined in section 3.9.3 of the
47/// C++11 standard [basic.types].
48///
49/// `bsl::is_trivially_copyable` has the same syntax as the
50/// `is_trivially_copyable` template from the C++11 standard [meta.unary.prop].
51/// However, unlike the template defined in the C++11 standard, which can
52/// determine the correct value for all types without requiring specialization,
53/// `bsl::is_trivially_copyable` can, by default, determine the value for the
54/// following type categories only:
55/// @code
56/// Type Category Is Trivially Copyable
57/// ------------- ---------------------
58/// reference types false
59/// fundamental types true
60/// enumerated types true
61/// pointers true
62/// pointers to members true
63/// @endcode
64/// For all other types, `bsl::is_trivially_copyable` returns `false`, unless
65/// the type is explicitly specified to be trivially copyable. This can be done
66/// in 2 ways:
67///
68/// 1. Define a template specialization for `bsl::is_trivially_copyable` having
69/// the type as the template parameter that inherits directly from
70/// `bsl::true_type`.
71/// 2. Use the `BSLMF_NESTED_TRAIT_DECLARATION` macro to define
72/// `bsl::is_trivially_copyable` as a trait in the class definition of the
73/// type.
74///
75/// Note that the template variable `is_trivially_copyable_v` is defined in the
76/// C++17 standard as an inline variable. If the current compiler supports the
77/// inline variable C++17 compiler feature, `bsl::is_trivially_copyable_v` is
78/// defined as an `inline constexpr bool` variable. Otherwise, if the compiler
79/// supports the variable templates C++14 compiler feature,
80/// `bsl::is_trivially_copyable_v` is defined as a non-inline `constexpr bool`
81/// variable. See `BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES` and
82/// `BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES` macros in
83/// bsls_compilerfeatures component for details.
84///
85/// ## bslmf::IsTriviallyCopyableCheck {#bslmf_istriviallycopyable-bslmf-istriviallycopyablecheck}
86///
87///
88/// In addition to `bsl::is_trivially_copyable`, we provide
89/// `bslmf::IsTriviallyCopyableCheck`, which is never intended to be
90/// specialized, but rather to be used to get the same return value as
91/// `bsl::is_trivially_copyable`, but perform a static assert that the `bsl` and
92/// `std` versions of `is_trivially_copyable` are equivalent.
93///
94/// ## Usage {#bslmf_istriviallycopyable-usage}
95///
96///
97/// In this section we show intended use of this component.
98///
99/// ### Example 1: Verify Whether Types are Trivially Copyable {#bslmf_istriviallycopyable-example-1-verify-whether-types-are-trivially-copyable}
100///
101///
102/// Suppose that we want to assert whether a type is trivially copyable.
103///
104/// First, we define a set of types to evaluate:
105/// @code
106/// typedef int MyFundamentalType;
107/// typedef int& MyFundamentalTypeReference;
108///
109/// class MyTriviallyCopyableType {
110/// };
111///
112/// struct MyNonTriviallyCopyableType {
113/// //...
114/// };
115/// @endcode
116/// Then, since user-defined types cannot be automatically evaluated by
117/// `is_trivially_copyable`, we define a template specialization to specify that
118/// `MyTriviallyCopyableType` is trivially copyable:
119/// @code
120/// namespace bsl {
121///
122/// template <>
123/// struct is_trivially_copyable<MyTriviallyCopyableType> : bsl::true_type {
124/// // This template specialization for 'is_trivially_copyable' indicates
125/// // that 'MyTriviallyCopyableType' is a trivially copyable type.
126/// };
127///
128/// } // close namespace bsl
129/// @endcode
130/// Now, we verify whether each type is trivially copyable using
131/// `bsl::is_trivially_copyable`:
132/// @code
133/// assert(true == bsl::is_trivially_copyable<MyFundamentalType>::value);
134/// assert(false == bsl::is_trivially_copyable<
135/// MyFundamentalTypeReference>::value);
136/// assert(true == bsl::is_trivially_copyable<
137/// MyTriviallyCopyableType>::value);
138/// assert(false == bsl::is_trivially_copyable<
139/// MyNonTriviallyCopyableType>::value);
140/// @endcode
141/// Note that if the current compiler supports the variable templates C++14
142/// feature, then we can re-write the snippet of code above as follows:
143/// @code
144/// #ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
145/// assert(true == bsl::is_trivially_copyable_v<MyFundamentalType>);
146/// assert(false == bsl::is_trivially_copyable_v<MyFundamentalTypeReference>);
147/// assert(true == bsl::is_trivially_copyable_v<MyTriviallyCopyableType>);
148/// assert(false == bsl::is_trivially_copyable_v<MyNonTriviallyCopyableType>);
149/// #endif
150/// @endcode
151/// @}
152/** @} */
153/** @} */
154
155/** @addtogroup bsl
156 * @{
157 */
158/** @addtogroup bslmf
159 * @{
160 */
161/** @addtogroup bslmf_istriviallycopyable
162 * @{
163 */
164
165#include <bslscm_version.h>
166
169#include <bslmf_isenum.h>
170#include <bslmf_isfundamental.h>
172#include <bslmf_ispointer.h>
173#include <bslmf_voidtype.h>
174
176#include <bsls_keyword.h>
177#include <bsls_platform.h>
178
179#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
180#include <bsls_timeinterval.h> // see DRQS 131017375
181#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
182
183#include <stddef.h>
184
185#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
186# include <type_traits>
187#endif // BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
188
189#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
190#include <bsls_nativestd.h>
191#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
192
193#ifdef BSLS_COMPILERFEATURES_SUPPORT_TRAITS_HEADER
194#define BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
195// Early implementations of C++11 type traits did not always provide the
196// necessary compiler intrinsic to detect the 'trivial' traits, so we use an
197// additional component-level feature macro to detect whether native support is
198// truly present. This macro is defined for Visual C++ prior to VC2015 due to
199// wrong results for certain types with the initial implementation of that
200// trait.
201
202#if (defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION < 50000) \
203 || (defined(BSLS_PLATFORM_CMP_MSVC) && BSLS_PLATFORM_CMP_VERSION < 1900)
204# undef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
205#endif
206
207#endif
208
209namespace bsl {
210
211template <class t_TYPE>
212struct is_trivially_copyable;
213
214#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
215/// This template variable represents the result value of the
216/// `bsl::is_trivially_copyable` meta-function.
217template <class t_TYPE>
218BSLS_KEYWORD_INLINE_VARIABLE constexpr bool is_trivially_copyable_v =
219 is_trivially_copyable<t_TYPE>::value;
220#endif
221
222} // close namespace bsl
223
224
225
226namespace bsls { class TimeInterval; }
227
228namespace bslmf {
229
230struct Nil;
231
232 // ==============================
233 // struct IsTriviallyCopyable_Imp
234 // ==============================
235
236/// This `struct` template implements a meta-function to determine whether
237/// the (non-cv-qualified) (template parameter) `t_TYPE` has been explicitly
238/// tagged with the trivially copyable trait. If the flag `t_K_INTRINSIC`
239/// is `true` then the compiler has already determined that `t_TYPE` is
240/// trivially copyable without user intervention, and the check for nested
241/// traits can be optimized away.
242template <class t_TYPE, bool t_K_INTRINSIC = false>
244: DetectNestedTrait<t_TYPE, bsl::is_trivially_copyable>::type {
245};
246
247/// This `struct` template implements a meta-function to determine whether
248/// the (non-cv-qualified) (template parameter) `t_TYPE` is trivially
249/// copyable.
250template <class t_TYPE>
252};
253
254#ifdef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
255/// This `struct` template implements a meta-function to determine whether
256/// the (non-cv-qualified) (template parameter) `t_TYPE` is trivially
257/// copyable.
258template <class t_TYPE>
261 t_TYPE,
262 ::std::is_trivially_copyable<t_TYPE>::value>::type {
263};
264#else
265/// This `struct` template implements a meta-function to determine whether
266/// the (non-cv-qualified) (template parameter) `t_TYPE` is trivially
267/// copyable. Without compiler support, only scalar types are trivial
268/// copyable.
269template <class t_TYPE>
272 t_TYPE,
273 bsl::is_fundamental<t_TYPE>::value || bsl::is_enum<t_TYPE>::value ||
274 bsl::is_pointer<t_TYPE>::value ||
275 bsl::is_member_pointer<t_TYPE>::value>::type {
276};
277
278/// This explicit specialization reports that `void` is not a trivially
279/// copyable type, despite being a fundamental type.
280template <>
283#endif
284
285#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
286template <class NON_CV_TYPE, class = void>
287struct IsTriviallyCopyable_Solaris
289 // The Solaris CC compiler (prior to CC 12.4) will match certain types,
290 // such as abominable function types, as matching a 'cv'-qualified type in
291 // partial specialization, even when that type is not 'cv'-qualified. The
292 // idiom of implementing a partial specialization for 'cv'-qualified traits
293 // in terms of the primary template then becomes infinitely recursive for
294 // those special cases, so we provide a shim implementation class to handle
295 // the delegation. This primary template always derives from 'false_type',
296 // and will be matched for function types, reference types, and 'void',
297 // none of which are trivially copyable. The partial specialization below
298 // handles recursion back to the primary trait for all other types.
299};
300
301template <class NON_CV_TYPE>
302struct IsTriviallyCopyable_Solaris<NON_CV_TYPE, BSLMF_VOIDTYPE(NON_CV_TYPE[])>
303 : bsl::is_trivially_copyable<NON_CV_TYPE>::type {
304};
305#endif
306} // close package namespace
307
308
309namespace bsl {
310 // ============================
311 // struct is_trivially_copyable
312 // ============================
313
314/// This `struct` template implements a meta-function to determine whether
315/// the (template parameter) `t_TYPE` is trivially copyable. This `struct`
316/// derives from `bsl::true_type` if the `t_TYPE` is trivially copyable, and
317/// from `bsl::false_type` otherwise. This meta-function has the same
318/// syntax as the `is_trivially_copyable` meta-function defined in the C++11
319/// standard [meta.unary.prop]; however, this meta-function can
320/// automatically determine the value for the following types only:
321/// reference types, fundamental types, enumerated types, pointers to
322/// members, and types declared to have the `bsl::is_trivially_copyable`
323/// trait using the `BSLMF_NESTED_TRAIT_DECLARATION` macro (the value for
324/// other types defaults to `false`). To support other trivially copyable
325/// types, this template must be specialized to inherit from
326/// `bsl::true_type` for them.
327template <class t_TYPE>
329: BloombergLP::bslmf::IsTriviallyCopyable_Intrinsic<t_TYPE>::type {
330};
331
332/// This partial specialization optimizes away a number of nested template
333/// instantiations to prove that reference types are never trivially
334/// copyable.
335template <class t_TYPE>
337};
338
339#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
340/// This partial specialization optimizes away a number of nested template
341/// instantiations to prove that reference types are never trivially
342/// copyable.
343template <class t_TYPE>
344struct is_trivially_copyable<t_TYPE&&> : false_type {
345};
346#endif
347
348#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
349// Solaris CC compiler will erroneously match a cv-qualified abominable
350// function type with a partial specialization for cv-qualified types, and then
351// infinitely recurse when the cv-qualifier is not stripped when instantiating
352// the base class. As this is only a problem for abominable function types
353// that are never trivially copyable, the following workaround (preserving lazy
354// evaluation of the recursive template instantiation) is ugly, but suffices.
355// Compiler fix verified for the CC 12.4 compiler.
356
357template <class t_TYPE>
358struct is_trivially_copyable<const t_TYPE>
359: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
360 // This partial specialization ensures that const-qualified types have the
361 // same result as their element type.
362};
363
364template <class t_TYPE>
365struct is_trivially_copyable<volatile t_TYPE>
366: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
367 // This partial specialization ensures that volatile-qualified types have
368 // the same result as their element type.
369};
370
371template <class t_TYPE>
372struct is_trivially_copyable<const volatile t_TYPE>
373: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
374 // This partial specialization ensures that const-volatile-qualified types
375 // have the same result as their element type.
376};
377#else
378/// This partial specialization ensures that const-qualified types have the
379/// same result as their element type.
380template <class t_TYPE>
381struct is_trivially_copyable<const t_TYPE>
382: is_trivially_copyable<t_TYPE>::type {
383};
384
385/// This partial specialization ensures that volatile-qualified types have
386/// the same result as their element type.
387template <class t_TYPE>
388struct is_trivially_copyable<volatile t_TYPE>
389: is_trivially_copyable<t_TYPE>::type {
390};
391
392/// This partial specialization ensures that const-volatile-qualified types
393/// have the same result as their element type.
394template <class t_TYPE>
395struct is_trivially_copyable<const volatile t_TYPE>
396: is_trivially_copyable<t_TYPE>::type {
397};
398#endif
399
400/// This partial specialization ensures that array types have the same
401/// result as their element type.
402template <class t_TYPE, size_t t_LEN>
403struct is_trivially_copyable<t_TYPE[t_LEN]>
404: is_trivially_copyable<t_TYPE>::type {
405};
406
407/// This partial specialization ensures that const-qualified array types
408/// have the same result as their element type.
409template <class t_TYPE, size_t t_LEN>
410struct is_trivially_copyable<const t_TYPE[t_LEN]>
411: is_trivially_copyable<t_TYPE>::type {
412};
413
414/// This partial specialization ensures that volatile-qualified array types
415/// have the same result as their element type.
416template <class t_TYPE, size_t t_LEN>
417struct is_trivially_copyable<volatile t_TYPE[t_LEN]>
418: is_trivially_copyable<t_TYPE>::type {
419};
420
421/// This partial specialization ensures that const-volatile-qualified array
422/// types have the same result as their element type.
423template <class t_TYPE, size_t t_LEN>
424struct is_trivially_copyable<const volatile t_TYPE[t_LEN]>
425: is_trivially_copyable<t_TYPE>::type {
426};
427
428#if !defined(BSLS_PLATFORM_CMP_IBM)
429// Last checked with the xlC 12.1 compiler. The IBM xlC compiler has problems
430// correctly handling arrays of unknown bound as template parameters.
431
432/// This partial specialization ensures that array-of-unknown-bound types
433/// have the same result as their element type.
434template <class t_TYPE>
435struct is_trivially_copyable<t_TYPE[]> : is_trivially_copyable<t_TYPE>::type {
436};
437
438/// This partial specialization ensures that const-qualified
439/// array-of-unknown-bound types have the same result as their element type.
440template <class t_TYPE>
441struct is_trivially_copyable<const t_TYPE[]>
442: is_trivially_copyable<t_TYPE>::type {
443};
444
445/// This partial specialization ensures that volatile-qualified
446/// array-of-unknown-bound types have the same result as their element type.
447template <class t_TYPE>
448struct is_trivially_copyable<volatile t_TYPE[]>
449: is_trivially_copyable<t_TYPE>::type {
450};
451
452/// This partial specialization ensures that const-volatile-qualified
453/// array-of-unknown-bound types have the same result as their element type.
454template <class t_TYPE>
455struct is_trivially_copyable<const volatile t_TYPE[]>
456: is_trivially_copyable<t_TYPE>::type {
457};
458#endif
459
460///IMPLEMENTATION NOTE
461///-------------------
462// We specialize 'is_trivially_copyable' for 'bsls::TimeInterval' here because
463// 'bsls' is levelized below 'bslmf'. Previously, 'bsls_timeinterval.h' had
464// forward declared the 'is_trivially_copyable' template and provided a
465// specialization for 'TimeInterval' (see BDE 2.24.0 tag), but the forward
466// declaration caused compilation errors with the Sun CC 5.13 compiler.
467//
468// We specialize 'is_trivially_copyable' for 'bslmf::Nil' here to avoid
469// increasing the dependency envelope of 'bslmf_nil'.
470//
471// Neither of these trait declarations will be needed once we fully migrate to
472// a C++11 definition for 'is_trivially_copyable'.
473
474/// This template specialization for `is_trivially_copyable` indicates that
475/// `TimeInterval` is a trivially copyable type.
476template <>
479
480#ifndef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
481/// This template specialization for `is_trivially_copyable` indicates that
482/// `Nil` is a trivially copyable type.
483template <>
485};
486#endif
487} // close namespace bsl
488
489
490namespace bslmf {
491
492/// This `struct` exists to return the same value as `is_trivially_copyable`
493/// and is intended to never be specialized. The purpose of using it is
494/// to perform the following static assert that the `bsl` and `std` versions
495/// of `is_trivially_copyable` are in sync.
496template <class t_TYPE>
498
499#if defined(BSLS_COMPILERFEATURES_SUPPORT_STATIC_ASSERT) && \
500 defined(BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION)
501 // Note that 'std::is_trivially_copyable' is 'false' on Windows for types
502 // with copy c'tors declared as 'deleted', but 'true' on other platforms.
503
505 std::is_trivially_copyable<t_TYPE>::value,
506 "Types with copy constructors or destructors defined "
507 "or deleted may be declared 'bslmf::IsBitwiseCopyable', "
508 "if the type author is certain that using 'memcpy' on "
509 "the type is safe. Declaring such types"
510 " 'bsl::is_trivially_copyable' is, however, prohibited.");
511#endif
512};
513
514} // close namespace bslmf
515
516
517
518#endif // ! defined(INCLUDED_BSLMF_ISTRIVIALLYCOPYABLE)
519
520// ----------------------------------------------------------------------------
521// Copyright 2019 Bloomberg Finance L.P.
522//
523// Licensed under the Apache License, Version 2.0 (the "License");
524// you may not use this file except in compliance with the License.
525// You may obtain a copy of the License at
526//
527// http://www.apache.org/licenses/LICENSE-2.0
528//
529// Unless required by applicable law or agreed to in writing, software
530// distributed under the License is distributed on an "AS IS" BASIS,
531// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
532// See the License for the specific language governing permissions and
533// limitations under the License.
534// ----------------------------- END-OF-FILE ----------------------------------
535
536/** @} */
537/** @} */
538/** @} */
Definition bsls_timeinterval.h:301
#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
Definition bdlb_printmethods.h:283
Definition bdlbb_blob.h:576
Definition bdlt_iso8601util.h:691
Definition bslmf_istriviallycopyable.h:329
Definition bslmf_detectnestedtrait.h:464
Definition bslmf_istriviallycopyable.h:497
Definition bslmf_istriviallycopyable.h:244
Definition bslmf_istriviallycopyable.h:275
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131