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

Detailed Description

Outline

Purpose

Provide a metafunction to indicate the use of bslma allocators.

Classes

See also
bslalg_typetraitusesblsmaallocator

Description

This 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).

Trait Description

bslma::UsesBslmaAllocator<TYPE> derives from bsl::true_type if TYPE is a complete object type and one or more of the following are true:

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.

Properties of Types Declaring the UsesBslmaAllocator Trait

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).

Compiler-Enforced Requirements of Types Declaring UsesBslmaAllocator

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.

Expected Properties of Types Declaring the UsesBslmaAllocator Trait

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.

Usage

This section illustrates intended usage of this component.

Example 1: Associating the bslma Allocator Trait with a Type

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:

namespace xyz {
class UsesAllocatorType1 {
// ...
public:
// TRAITS
BSLMF_NESTED_TRAIT_DECLARATION(UsesAllocatorType1,
// CREATORS
explicit UsesAllocatorType1(bslma::Allocator *basicAllocator = 0);
// ...
UsesAllocatorType1(const UsesAllocatorType1& original,
bslma::Allocator *basicAllocator = 0);
// ...
};
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bslma_allocator.h:457
Definition bslma_usesbslmaallocator.h:343

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:

class UsesAllocatorType2 {
// ...
public:
// CREATORS
explicit UsesAllocatorType2(bslma::Allocator *basicAllocator = 0);
// ...
UsesAllocatorType2(const UsesAllocatorType2& original,
bslma::Allocator *basicAllocator = 0);
// ...
};
} // close namespace xyz
// TRAITS
namespace BloombergLP {
namespace bslma {
template <>
struct UsesBslmaAllocator<xyz::UsesAllocatorType2> : bsl::true_type
{};
} // close package namespace
} // close enterprise namespace
Definition balxml_encoderoptions.h:68

Next, we define a type BslAAClass, which provides a bsl-AA interface based on bsl::allocator:

namespace xyz {
class BslAAClass {
// ...
public:
// TYPES
typedef bsl::allocator<char> allocator_type;
// CREATORS
explicit BslAAClass(const allocator_type& alloc = allocator_type());
BslAAClass(const BslAAClass& other,
const allocator_type& alloc = allocator_type());
};
Definition bslma_bslallocator.h:580

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:

class NonAAClass : public BslAAClass {
// ...
public:
// TYPES
typedef void allocator_type; // Not an AA class
// CREATORS
NonAAClass();
NonAAClass(const NonAAClass& other);
};
} // close namespace xyz

Example 2: Testing Whether a Type Uses a bslma Allocator

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:

namespace xyz {
class DoesNotUseAnAllocatorType { };
} // close namespace xyz

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: