BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_isbitwisecopyable

Detailed Description

Outline

Purpose

Provide a meta-function for determining bitwise copyable types.

Classes

See also
bslmf_integralconstant, bslmf_nestedtraitdeclaration

Description

This component defines a meta-function, bslmf::IsBitwiseCopyable and a template variable bslmf::IsBitwiseCopyable_v, that represents the result value of the bslmf::IsBitwiseCopyable meta-function, that may be used to query whether a type is deemed by the author to be trivially copyable, but does NOT have the property bsl::is_trivially_copyable.

bslmf::IsBitwiseCopyable has the same syntax as the is_trivially_copyable template from the C++11 standard [meta.unary.prop], but is used exclusively to identify types deemed by the author to be trivially copyable, but for which bsl::is_trivially_copyable is not true by default. Typically such types might have a destructor, or non-trivial creators, so that copying them via memcpy may be theoretically undefined behavior and cause problems on some future compilers.

Type Category IsBitwiseCopyable by Default
------------- ----------------------------
fundamental types true
enumerated types true
pointers to data true
pointers to functions true
pointers to member data true
pointers to member functions true
reference types false
rvalue reference types false

Types that are bsl::is_trivially_copyable are IsBitwiseCopyable by default – otherwise, the only way a type acquires the IsBitwiseCopyable trait is by explicit specialization or by the BSLMF_NESTED_TRAIT_DECLARATION macro.

Note that the template variable IsBitwiseCopyable_v is defined in the C++17 standard as an inline variable. If the current compiler supports the inline variable C++17 compiler feature, bslmf::IsBitwiseCopyable_v is defined as an inline constexpr bool variable. Otherwise, if the compiler supports the variable templates C++14 compiler feature, bslmf::IsBitwiseCopyable_v is defined as a non-inline constexpr bool variable. See BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES and BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES macros in bsls_compilerfeatures component for details.

Usage

In this section we show intended use of this component.

Example 1: Verify Whether Types are Trivially Copyable

Suppose that we want to assert whether a type is trivially copyable, and/or bitwise copyable.

First, we define a set of types to evaluate:

struct MyTriviallyCopyableType {
// TRAITS
BSLMF_NESTED_TRAIT_DECLARATION(MyTriviallyCopyableType,
};
struct MyNonTriviallyCopyableType {
// Because this 'struct' has constructors declared, the C++11 compiler
// will not automatically declare it 'std::is_trivially_copyable'. But
// since it has no data, we know it can be 'memcpy'ed around so we will
// give it the 'IsBitwiseCopyable' trait.
// TRAITS
BSLMF_NESTED_TRAIT_DECLARATION(MyNonTriviallyCopyableType,
// CREATORS
MyNonTriviallyCopyableType() {}
MyNonTriviallyCopyableType(const MyNonTriviallyCopyableType&) {}
~MyNonTriviallyCopyableType() {}
// Explicitly supply creators that do nothing, to ensure that this
// class has no trivial traits detected with a conforming C++11
// library implementation.
};
class MyNonBitwiseCopyableType {
// This 'class' allocates memory and cannot be copied around with
// 'memcpy', so it should have neither the 'is_trivially_copyable' nor
// the 'IsBitwiseCopyable' traits.
// DATA
char *d_string;
public:
// CREATORS
MyNonBitwiseCopyableType(const char *string)
: d_string(::strdup(string))
{}
MyNonBitwiseCopyableType(const MyNonBitwiseCopyableType& original)
: d_string(::strdup(original.d_string))
{}
~MyNonBitwiseCopyableType()
{
free(d_string);
}
bool operator==(const MyNonBitwiseCopyableType& rhs) const
{
return !::strcmp(d_string, rhs.d_string);
}
};
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
basic_string< char > string
Definition bslstl_string.h:782
Definition bslmf_istriviallycopyable.h:329
Definition bslmf_isbitwisecopyable.h:298

Then, the following 5 types are automatically interpreted by bsl::is_trivially_copyable to be trivially copyable without our having to declare them as such, and therefore, as IsBitwiseCopyable.

typedef int MyFundamentalType;
// fundamental type
typedef int *DataPtrTestType;
// data pointer
typedef void (*FunctionPtrTestType)();
// function ptr
typedef int MyNonBitwiseCopyableType::*DataMemberPtrTestType;
// non-static data member ptr
typedef int (MyNonBitwiseCopyableType::*MethodPtrTestType)();
// non-static function member ptr

The following 2 types are neither trivially nor bitwise copyable:

typedef int& MyFundamentalTypeRef;
// reference (not bitwise copyable)
#if defined(BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES)
typedef int&& MyFundamentalTypeRvalueRef;
// rvalue reference (not bitwise copyable)
#endif

Now, we verify whether each type is trivially copyable using bsl::is_trivially_copyable:

Now, we verify whether each type is bitwise copyable using bslmf::IsBitwiseCopyable:

Finally, note that if the current compiler supports the variable templates C++14 feature, then we can re-write the two snippets of code above as follows:

#ifdef BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES
// trivially copyable:
assert( bsl::is_trivially_copyable_v<MyTriviallyCopyableType>);
assert(!bsl::is_trivially_copyable_v<MyNonTriviallyCopyableType>);
assert(!bsl::is_trivially_copyable_v<MyNonBitwiseCopyableType>);
assert( bsl::is_trivially_copyable_v<MyFundamentalType>);
assert( bsl::is_trivially_copyable_v<DataPtrTestType>);
assert( bsl::is_trivially_copyable_v<FunctionPtrTestType>);
assert( bsl::is_trivially_copyable_v<DataMemberPtrTestType>);
assert( bsl::is_trivially_copyable_v<MethodPtrTestType>);
assert(!bsl::is_trivially_copyable_v<MyFundamentalTypeRef>);
assert(!bsl::is_trivially_copyable_v<MyFundamentalTypeRvalueRef>);
// bitwise copyable:
assert( bslmf::IsBitwiseCopyable_v<MyTriviallyCopyableType>);
assert( bslmf::IsBitwiseCopyable_v<MyNonTriviallyCopyableType>);
assert(!bslmf::IsBitwiseCopyable_v<MyNonBitwiseCopyableType>);
assert( bslmf::IsBitwiseCopyable_v<MyFundamentalType>);
assert( bslmf::IsBitwiseCopyable_v<DataPtrTestType>);
assert( bslmf::IsBitwiseCopyable_v<FunctionPtrTestType>);
assert( bslmf::IsBitwiseCopyable_v<DataMemberPtrTestType>);
assert( bslmf::IsBitwiseCopyable_v<MethodPtrTestType>);
assert(!bslmf::IsBitwiseCopyable_v<MyFundamentalTypeRef>);
assert(!bslmf::IsBitwiseCopyable_v<MyFundamentalTypeRvalueRef>);
#endif