Provide implementation meta-functions for alignment computation.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide implementation meta-functions for alignment computation.
-
- Classes:
-
- See also:
- Component bsls_alignmentfromtype, Component bsls_alignmenttotype, Component bsls_alignmentutil
-
- Description:
- This component provides a suite of template meta-functions that can be used to compute (at compile-time) various platform-dependent alignment information. The clients of this component are expected to be
bsls
components such as bsls_alignmentfromtype
, bsls_alignmenttotype
, and bsls_alignmentutil
. Other client code should use one of these bsls
components instead of using this component directly.
-
- Computing Alignment for a Type:
- The compiler alignment for a given type,
T
, can be computed by creating a structure containing a single char
member followed by a T
member: struct X {
char d_c;
T d_t;
};
The compiler lays this structure out in memory as follows: +---+---+-------+
|d_c| P | d_t |
+---+---+-------+
where P
is padding added by the compiler to ensure that d_t
is properly aligned. The alignment for T
is the number of bytes from the start of the structure to the beginning of d_t
, which is also the total size of the structure minus the size of d_t
: Since sizeof
yields a compile-time constant, the alignment can be computed at compile time.
-
- Computing a Type Requiring an Alignment:
- A considerably more difficult compile-time computation supported by this component is that of determining a fundamental type with the same alignment requirements of a given type
T
. This involves computing the alignment for T
, as above, and then performing an alignment-to-type lookup, all at compile time. The general principles of this computation follow.
- We would like to create a template class that is specialized for each fundamental type's alignment. Unfortunately, multiple types will have the same alignment and the compiler would issue a diagnostic if the same specialization was defined more than once. To disambiguate, we create a "priority" class for each fundamental type that arbitrarily ranks that type relative to all of the other fundamental types. Each priority class is derived from the next-lower priority class. A set of overloaded functions are created such that, given two fundamental types with the same alignment, overload resolution will pick the one with the highest priority (i.e., the most-derived priority type). The
sizeof
operator and several template specializations are used to determine the compiler's choice of overloaded match
function. The return value is mapped to a priority, which is, in turn, mapped to an appropriate primitive type.
-
- Usage:
- This section illustrates the intended use of this component.
-
- Example 1: AlignmentImpCalc Template:
- Suppose that we want to write a program that needs to calculate the alignment requirements of both user-defined types and built-in types. Further suppose that the program will run on a platform where the alignment requirement of
int
is 4 bytes.
- First, we define a
struct
, MyStruct
, for which want to determine the alignment requirement: struct MyStruct {
char d_c;
int d_i;
short d_s;
};
Note that int
is the most alignment-demanding type within MyStruct
.
- Now, we use
AlignmentImpCalc
to calculate the alignments of two types, short
and the MyStruct
we just defined: Finally, we observe the values of our alignments, we observe that the size of the 2 objects is a multiple of each object's alignment (which is true for all C++ types), and we observe that the size of MyStruct
is greater than its alignment. assert(2 == SHORT_ALIGNMENT);
assert(4 == MY_STRUCT_ALIGNMENT);
assert(0 == sizeof(short ) % SHORT_ALIGNMENT);
assert(0 == sizeof(MyStruct) % MY_STRUCT_ALIGNMENT);
assert(sizeof(MyStruct) > MY_STRUCT_ALIGNMENT);
-
- Example 2: Types Supporting AlignmentToType:
- Suppose we to be able to determine a fundamental or pointer type that has both its size and alignment requirement equal to the alignment requirement of a specified template parameter type. We can use the
AlignmentImpTag
struct
template, the overloads of AlignmentImpMatch::match
class method, the AiignmentImp_Priority
template class, and the AlignmentImpPrioriityToType
template class to do this calculation.
- First, we define a class template,
ConvertAlignmentToType
, that provides a Type
alias to a fundamental or pointer type that has both its alignment requirement and size equal to the compile-time constant ALIGNMENT
int
parameter of the template. Then, we define two user defined types on which we will use ConvertAlignmentToType
on: struct MyStructA {
short d_s;
double d_d;
int d_i;
};
struct MyStructB {
double d_d[20];
};
Here, we calculate alignments for our 3 types with AlignmentImpCalc
. Now, for each alignment requirement we just calculated, we utilize ConvertAlignmentToType
to determine the fundamental or pointer type having both size and alignment requirement equal to the calculated alignment requirement: typedef ConvertAlignmentToType<INT_ALIGNMENT>::Type IntAlignType;
typedef ConvertAlignmentToType<A_ALIGNMENT >::Type ThisAlignType;
typedef ConvertAlignmentToType<B_ALIGNMENT >::Type ThatAlignType;
Finally, we observe that the alignments of the *AlignType
s are the same as the alignments of the types from which they are derived, and that all the type determined by ConvertAlignmentToType
have sizes equal to their alignment requirements:
Define Documentation
Typedef Documentation