|
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 *AlignTypes 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: