BDE 4.39.x 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/// /// This template specialization for `is_trivially_copyable` indicates
123/// /// that `MyTriviallyCopyableType` is a trivially copyable type.
124/// template <>
125/// struct is_trivially_copyable<MyTriviallyCopyableType> : bsl::true_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# undef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
204#endif
205
206#endif
207
208namespace bsl {
209
210template <class t_TYPE>
211struct is_trivially_copyable;
212
213#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
214/// This template variable represents the result value of the
215/// `bsl::is_trivially_copyable` meta-function.
216template <class t_TYPE>
217BSLS_KEYWORD_INLINE_VARIABLE constexpr bool is_trivially_copyable_v =
218 is_trivially_copyable<t_TYPE>::value;
219#endif
220
221} // close namespace bsl
222
223
224
225namespace bsls { class TimeInterval; }
226
227namespace bslmf {
228
229struct Nil;
230
231 // ==============================
232 // struct IsTriviallyCopyable_Imp
233 // ==============================
234
235/// This `struct` template implements a meta-function to determine whether the
236/// (non-cv-qualified) (template parameter) `t_TYPE` has been explicitly tagged
237/// with the trivially copyable trait. If the flag `t_K_INTRINSIC` is `true`
238/// then the compiler has already determined that `t_TYPE` is trivially
239/// copyable without user intervention, and the check for nested traits can be
240/// optimized away.
241template <class t_TYPE, bool t_K_INTRINSIC = false>
243: DetectNestedTrait<t_TYPE, bsl::is_trivially_copyable>::type {
244};
245
246/// This `struct` template implements a meta-function to determine whether the
247/// (non-cv-qualified) (template parameter) `t_TYPE` is trivially copyable.
248template <class t_TYPE>
250};
251
252#ifdef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
253/// This `struct` template implements a meta-function to determine whether the
254/// (non-cv-qualified) (template parameter) `t_TYPE` is trivially copyable.
255template <class t_TYPE>
258 t_TYPE,
259 ::std::is_trivially_copyable<t_TYPE>::value>::type {
260};
261#else
262/// This `struct` template implements a meta-function to determine whether the
263/// (non-cv-qualified) (template parameter) `t_TYPE` is trivially copyable.
264/// Without compiler support, only scalar types are trivial copyable.
265template <class t_TYPE>
268 t_TYPE,
269 bsl::is_fundamental<t_TYPE>::value || bsl::is_enum<t_TYPE>::value ||
270 bsl::is_pointer<t_TYPE>::value ||
271 bsl::is_member_pointer<t_TYPE>::value>::type {
272};
273
274/// This explicit specialization reports that `void` is not a trivially
275/// copyable type, despite being a fundamental type.
276template <>
279#endif
280
281#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
282/// The Solaris CC compiler (prior to CC 12.4) will match certain types,
283/// such as abominable function types, as matching a `cv`-qualified type in
284/// partial specialization, even when that type is not `cv`-qualified. The
285/// idiom of implementing a partial specialization for `cv`-qualified traits
286/// in terms of the primary template then becomes infinitely recursive for
287/// those special cases, so we provide a shim implementation class to handle
288/// the delegation. This primary template always derives from `false_type`,
289/// and will be matched for function types, reference types, and `void`,
290/// none of which are trivially copyable. The partial specialization below
291/// handles recursion back to the primary trait for all other types.
292template <class NON_CV_TYPE, class = void>
293struct IsTriviallyCopyable_Solaris
295};
296
297template <class NON_CV_TYPE>
298struct IsTriviallyCopyable_Solaris<NON_CV_TYPE, BSLMF_VOIDTYPE(NON_CV_TYPE[])>
299 : bsl::is_trivially_copyable<NON_CV_TYPE>::type {
300};
301#endif
302} // close package namespace
303
304
305namespace bsl {
306 // ============================
307 // struct is_trivially_copyable
308 // ============================
309
310/// This `struct` template implements a meta-function to determine whether the
311/// (template parameter) `t_TYPE` is trivially copyable. This `struct` derives
312/// from `bsl::true_type` if the `t_TYPE` is trivially copyable, and from
313/// `bsl::false_type` otherwise. This meta-function has the same syntax as the
314/// `is_trivially_copyable` meta-function defined in the C++11 standard
315/// [meta.unary.prop]; however, this meta-function can automatically determine
316/// the value for the following types only: reference types, fundamental types,
317/// enumerated types, pointers to members, and types declared to have the
318/// `bsl::is_trivially_copyable` trait using the
319/// `BSLMF_NESTED_TRAIT_DECLARATION` macro (the value for other types defaults
320/// to `false`). To support other trivially copyable types, this template must
321/// be specialized to inherit from `bsl::true_type` for them.
322template <class t_TYPE>
324: BloombergLP::bslmf::IsTriviallyCopyable_Intrinsic<t_TYPE>::type {
325};
326
327/// This partial specialization optimizes away a number of nested template
328/// instantiations to prove that reference types are never trivially copyable.
329template <class t_TYPE>
331};
332
333#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
334/// This partial specialization optimizes away a number of nested template
335/// instantiations to prove that reference types are never trivially copyable.
336template <class t_TYPE>
337struct is_trivially_copyable<t_TYPE&&> : false_type {
338};
339#endif
340
341#if defined(BSLS_PLATFORM_CMP_SUN) && BSLS_PLATFORM_CMP_VERSION < 0x5130
342// Solaris CC compiler will erroneously match a cv-qualified abominable
343// function type with a partial specialization for cv-qualified types, and then
344// infinitely recurse when the cv-qualifier is not stripped when instantiating
345// the base class. As this is only a problem for abominable function types
346// that are never trivially copyable, the following workaround (preserving lazy
347// evaluation of the recursive template instantiation) is ugly, but suffices.
348// Compiler fix verified for the CC 12.4 compiler.
349
350/// This partial specialization ensures that const-qualified types have the
351/// same result as their element type.
352template <class t_TYPE>
353struct is_trivially_copyable<const t_TYPE>
354: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
355};
356
357/// This partial specialization ensures that volatile-qualified types have the
358/// same result as their element type.
359template <class t_TYPE>
360struct is_trivially_copyable<volatile t_TYPE>
361: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
362};
363
364/// This partial specialization ensures that const-volatile-qualified types
365/// have the same result as their element type.
366template <class t_TYPE>
367struct is_trivially_copyable<const volatile t_TYPE>
368: BloombergLP::bslmf::IsTriviallyCopyable_Solaris<t_TYPE>::type {
369};
370#else
371/// This partial specialization ensures that const-qualified types have the
372/// same result as their element type.
373template <class t_TYPE>
374struct is_trivially_copyable<const t_TYPE>
375: is_trivially_copyable<t_TYPE>::type {
376};
377
378/// This partial specialization ensures that volatile-qualified types have the
379/// same result as their element type.
380template <class t_TYPE>
381struct is_trivially_copyable<volatile t_TYPE>
382: is_trivially_copyable<t_TYPE>::type {
383};
384
385/// This partial specialization ensures that const-volatile-qualified types
386/// have the same result as their element type.
387template <class t_TYPE>
388struct is_trivially_copyable<const volatile t_TYPE>
389: is_trivially_copyable<t_TYPE>::type {
390};
391#endif
392
393/// This partial specialization ensures that array types have the same result
394/// as their element type.
395template <class t_TYPE, size_t t_LEN>
396struct is_trivially_copyable<t_TYPE[t_LEN]>
397: is_trivially_copyable<t_TYPE>::type {
398};
399
400/// This partial specialization ensures that const-qualified array types have
401/// the same result as their element type.
402template <class t_TYPE, size_t t_LEN>
403struct is_trivially_copyable<const t_TYPE[t_LEN]>
404: is_trivially_copyable<t_TYPE>::type {
405};
406
407/// This partial specialization ensures that volatile-qualified array types
408/// have the same result as their element type.
409template <class t_TYPE, size_t t_LEN>
410struct is_trivially_copyable<volatile t_TYPE[t_LEN]>
411: is_trivially_copyable<t_TYPE>::type {
412};
413
414/// This partial specialization ensures that const-volatile-qualified array
415/// types have the same result as their element type.
416template <class t_TYPE, size_t t_LEN>
417struct is_trivially_copyable<const volatile t_TYPE[t_LEN]>
418: is_trivially_copyable<t_TYPE>::type {
419};
420
421#if !defined(BSLS_PLATFORM_CMP_IBM)
422// Last checked with the xlC 12.1 compiler. The IBM xlC compiler has problems
423// correctly handling arrays of unknown bound as template parameters.
424
425/// This partial specialization ensures that array-of-unknown-bound types have
426/// the same result as their element type.
427template <class t_TYPE>
428struct is_trivially_copyable<t_TYPE[]> : is_trivially_copyable<t_TYPE>::type {
429};
430
431/// This partial specialization ensures that const-qualified
432/// array-of-unknown-bound types have the same result as their element type.
433template <class t_TYPE>
434struct is_trivially_copyable<const t_TYPE[]>
435: is_trivially_copyable<t_TYPE>::type {
436};
437
438/// This partial specialization ensures that volatile-qualified
439/// array-of-unknown-bound types have the same result as their element type.
440template <class t_TYPE>
441struct is_trivially_copyable<volatile t_TYPE[]>
442: is_trivially_copyable<t_TYPE>::type {
443};
444
445/// This partial specialization ensures that const-volatile-qualified
446/// array-of-unknown-bound types have the same result as their element type.
447template <class t_TYPE>
448struct is_trivially_copyable<const volatile t_TYPE[]>
449: is_trivially_copyable<t_TYPE>::type {
450};
451#endif
452
453// IMPLEMENTATION NOTE
454// -------------------
455// We specialize `is_trivially_copyable` for `bsls::TimeInterval` here because
456// `bsls` is levelized below `bslmf`. Previously, `bsls_timeinterval.h` had
457// forward declared the `is_trivially_copyable` template and provided a
458// specialization for `TimeInterval` (see BDE 2.24.0 tag), but the forward
459// declaration caused compilation errors with the Sun CC 5.13 compiler.
460//
461// We specialize `is_trivially_copyable` for `bslmf::Nil` here to avoid
462// increasing the dependency envelope of `bslmf_nil`.
463//
464// Neither of these trait declarations will be needed once we fully migrate to
465// a C++11 definition for `is_trivially_copyable`.
466
467/// This template specialization for `is_trivially_copyable` indicates that
468/// `TimeInterval` is a trivially copyable type.
469template <>
472
473#ifndef BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION
474/// This template specialization for `is_trivially_copyable` indicates that
475/// `Nil` is a trivially copyable type.
476template <>
478};
479#endif
480} // close namespace bsl
481
482
483namespace bslmf {
484
485/// This `struct` exists to return the same value as `is_trivially_copyable`
486/// and is intended to never be specialized. The purpose of using it is
487/// to perform the following static assert that the `bsl` and `std` versions
488/// of `is_trivially_copyable` are in sync.
489template <class t_TYPE>
491
492#if defined(BSLS_COMPILERFEATURES_SUPPORT_STATIC_ASSERT) && \
493 defined(BSLMF_ISTRIVIALLYCOPYABLE_NATIVE_IMPLEMENTATION)
494 // Note that 'std::is_trivially_copyable' is 'false' on Windows for types
495 // with copy c'tors declared as 'deleted', but 'true' on other platforms.
496
498 std::is_trivially_copyable<t_TYPE>::value,
499 "Types with copy constructors or destructors defined "
500 "or deleted may be declared 'bslmf::IsBitwiseCopyable', "
501 "if the type author is certain that using 'memcpy' on "
502 "the type is safe. Declaring such types"
503 " 'bsl::is_trivially_copyable' is, however, prohibited.");
504#endif
505};
506
507} // close namespace bslmf
508
509
510
511#endif // ! defined(INCLUDED_BSLMF_ISTRIVIALLYCOPYABLE)
512
513// ----------------------------------------------------------------------------
514// Copyright 2019 Bloomberg Finance L.P.
515//
516// Licensed under the Apache License, Version 2.0 (the "License");
517// you may not use this file except in compliance with the License.
518// You may obtain a copy of the License at
519//
520// http://www.apache.org/licenses/LICENSE-2.0
521//
522// Unless required by applicable law or agreed to in writing, software
523// distributed under the License is distributed on an "AS IS" BASIS,
524// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
525// See the License for the specific language governing permissions and
526// limitations under the License.
527// ----------------------------- END-OF-FILE ----------------------------------
528
529/** @} */
530/** @} */
531/** @} */
Definition bsls_timeinterval.h:307
#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
Definition bdlat_valuetypefunctions.h:939
Definition bdlbb_blob.h:579
Definition bdlt_iso8601util.h:707
Definition bslmf_istriviallycopyable.h:324
Definition bslmf_detectnestedtrait.h:467
Definition bslmf_istriviallycopyable.h:490
Definition bslmf_istriviallycopyable.h:243
Definition bslmf_istriviallycopyable.h:271
Definition bslmf_nil.h:133