alignment.hh
Go to the documentation of this file.00001
00002 #ifndef DUNE_ALIGNMENT_HH
00003 #define DUNE_ALIGNMENT_HH
00004 #include<cstddef>
00005 #if HAVE_TYPE_TRAITS
00006 #include<type_traits>
00007 #elif HAVE_TR1_TYPE_TRAITS
00008 #include<tr1/type_traits>
00009 #endif
00010
00011 namespace Dune
00012 {
00013
00025 namespace
00026 {
00027
00032 template<class T>
00033 struct AlignmentStruct
00034 {
00035 char c;
00036 T t;
00037 void hack();
00038 };
00039
00044 template<class T, std::size_t N>
00045 struct AlignmentHelper
00046 {
00047 enum { N2 = sizeof(AlignmentStruct<T>) - sizeof(T) - N };
00048 char padding1[N];
00049 T t;
00050 char padding2[N2];
00051 };
00052
00053 #define ALIGNMENT_MODULO(a, b) (a % b == 0 ? \
00054 static_cast<std::size_t>(b) : \
00055 static_cast<std::size_t>(a % b))
00056 #define ALIGNMENT_MIN(a, b) (static_cast<std::size_t>(a) < \
00057 static_cast<std::size_t>(b) ? \
00058 static_cast<std::size_t>(a) : \
00059 static_cast<std::size_t>(b))
00060
00061 template <class T, std::size_t N>
00062 struct AlignmentTester
00063 {
00064 typedef AlignmentStruct<T> s;
00065 typedef AlignmentHelper<T, N> h;
00066 typedef AlignmentTester<T, N - 1> next;
00067 enum
00068 {
00069 a1 = ALIGNMENT_MODULO(N , sizeof(T)),
00070 a2 = ALIGNMENT_MODULO(h::N2 , sizeof(T)),
00071 a3 = ALIGNMENT_MODULO(sizeof(h), sizeof(T)),
00072 a = sizeof(h) == sizeof(s) ? ALIGNMENT_MIN(a1, a2) : a3,
00073 result = ALIGNMENT_MIN(a, next::result)
00074 };
00075 };
00076
00078 template <class T>
00079 struct AlignmentTester<T, 0>
00080 {
00081 enum
00082 {
00083 result = ALIGNMENT_MODULO(sizeof(AlignmentStruct<T>), sizeof(T))
00084 };
00085 };
00086 }
00087
00096 template <class T>
00097 struct AlignmentOf
00098 {
00099
00100 enum
00101 {
00103 #ifdef HAVE_TYPE_TRAITS
00104 value = std::alignment_of<T>::value
00105 #elif HAVE_TR1_TYPETRAITS
00106 value = std::tr1::alignment_of<T>::value
00107 #else
00108 value = AlignmentTester<T, sizeof(AlignmentStruct<T>) - sizeof(T) -1>::result
00109 #endif
00110 };
00111 };
00112
00114 }
00115 #endif