BDE 4.14.0 Production release
|
Provide implementation meta-functions for alignment computation.
TYPE
parameter to alignment VALUE
mapmatch
functionsPRIORITY
param to primitive type mapSIZE
(parameter)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.
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:
The compiler lays this structure out in memory as follows:
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.
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.
This section illustrates the intended use of this component.
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:
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.
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:
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:
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: