BDE 4.14.0 Production release
|
Provide a metafunction to indicate the use of bslma
allocators.
bslma
useThis component defines a metafunction, bslma::UsesBslmaAllocator
, that may be used to associate a type with the uses-bslma
-allocator trait (i.e., declare that a type uses a bslma
allocator), and also to detect whether a type has been associated with that trait (i.e., to test whether a type uses a bslma
allocator, and follows the bslma
allocator model).
bslma::UsesBslmaAllocator<TYPE>
derives from bsl::true_type
if TYPE
is a complete object type and one or more of the following are true:
bslma::UsesBslmaAllocator<TYPE>
is explicitly specialized to derive from bsl::true_type
.TYPE
has a 'BSLMF_NESTED_TRAIT_DECLARATION(TYPE,
bslma::UsesBslmaAllocator);' declaration.TYPE::allocator_type
that is convertible from bslma::Allocator *
. Note that inheriting from a class that defines allocator_type
will implicitly make UsesBslmaAllocator
true for the derived class. To suppress this behavior, create a nested typedef allocator_type
in the derived class that aliases void
.bslma::Allocator *
is implicitly convertible to TYPE
but other, arbitrary, pointers are NOT implicitly convertible to TYPE
. Note that this use is DEPRECATED and that such an implicit conversion will be discouraged (ideally via a compiler warning).Otherwise, bslma::UsesBslmaAllocator<TYPE>
derives from bsl::false_type
. Note that top-level cv qualifiers are ignored when applying the above tests. If TYPE
is a reference type, then bslma::UsesBslmaAllocator<TYPE>
always derives from bsl::false_type
, even if the reference type is AA.
Types that declare the UsesBslmaAllocator
trait must meet some minimal requirements in order for that type to be usable with code that tests for the UsesBslmaAllocator
trait (e.g., bsl
containers). In addition, types that use allocators must have certain properties with respect to memory allocation, which are not enforced by the compiler (such a type is described as following the bslma
allocator model).
Types declaring the UsesBslmaAllocator
trait must provide a constructor variant that accepts a bslma::Allocator *
as the last argument (typically this is an optional argument). If such a type provides a copy constructor, it must similarly provide a variant that takes a (optional) bslma::Allocator *
as the last argument. If such a type provides a move constructor, it must similarly provide a variant that takes a bslma::Allocator *
as the last argument.
Template types (such as bsl
containers), where the template parameter TYPE
represents some element type encapsulated by the class template, often use the UsesBslmaAllocator
trait to test if TYPE
uses bslma
allocators and, if so, to create TYPE
objects using the constructor variant taking an allocator. In this context, compilation will fail if a type declares the UsesBslmaAllocator
trait, but does not provide the expected constructor variant accepting a bslma::Allocator *
as the last argument.
Types declaring the UsesBslmaAllocator
trait are expected to have certain properties with respect to memory allocation. These properties are not enforced by the compiler, but are necessary to ensure consistent and comprehensible allocation behavior.
bslma
allocator model (i.e., the type will provide the supplied allocator to any data members that themselves accept an allocator).noexcept
exists, then if the allocators match, the behavior of those two move constructors will be identical.bsl::string
that is destroyed within the scope of a method need not be explicitly supplied an allocator, since it is a transient allocation, and bsl::string
will use the default allocator by default.operator==
).This section illustrates intended usage of this component.
Suppose we want to declare two types that make use of a bslma
allocator, and need to associate the UsesBslmaAllocator
trait with those types (so that they behave correctly when inserted into a bsl
container, for example). In this example we will demonstrate two different mechanisms by which a trait may be associated with a type.
First, we define a type UsesAllocatorType1
and use the BSLMF_NESTED_TRAIT_DECLARATION
macro to associate the type with the UsesBslmaAllocator
trait:
Note that the macro declaration must appear within the scope of the class declaration and must have public
access.
Next, we define a type UsesAllocatorType2
and define a specialization of the UsesBslmaAllocator
trait for UsesAllocatorType2
that associates the UsesBslmaAllocator
trait with the type (sometimes referred to as a "C++11-style" trait declaration, because it is more in keeping with the style of trait declarations found in the C++11 Standard). Note that the specialization must be performed in the BloombergLP::bslma
namespace:
Next, we define a type BslAAClass
, which provides a bsl-AA interface based on bsl::allocator
:
Finally, we define a type NonAAClass
, which is derived from BslAAClass
but is not AA itself. Because it inherits allocator_type
, this class explicitly says it is not AA by overiding allocator_type
with void
:
Suppose we want to test whether each of a set of different types uses a bslma
allocator.
First, we define a class that is not AA, for control purposes:
Now, we use the UsesBslmaAllocator
template to test whether this type, and any of the other types in Example 1 use bslma allocators:
Finally, we demonstrate that the trait can be tested at compilation time by testing the trait within the context of a compile-time BSLMF_ASSERT
: