dune-common 2.1.1
|
00001 // $Id: alignment.hh 5452 2009-02-26 10:54:14Z mblatt $ 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 } //end anonymous namspace 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