dune-common  2.2.0
alignment.hh
Go to the documentation of this file.
1 // $Id: alignment.hh 6574 2012-02-29 10:11:31Z sander $
2 #ifndef DUNE_ALIGNMENT_HH
3 #define DUNE_ALIGNMENT_HH
4 #include<cstddef>
5 #if HAVE_TYPE_TRAITS
6 #include<type_traits>
7 #elif HAVE_TR1_TYPE_TRAITS
8 #include<tr1/type_traits>
9 #endif
10 
11 namespace Dune
12 {
13 
25  namespace
26  {
27 
32  template<class T>
33  struct AlignmentStruct
34  {
35  char c;
36  T t;
37  void hack();
38  };
39 
44  template<class T, std::size_t N>
45  struct AlignmentHelper
46  {
47  enum { N2 = sizeof(AlignmentStruct<T>) - sizeof(T) - N };
48  char padding1[N];
49  T t;
50  char padding2[N2];
51  };
52 
53 #define ALIGNMENT_MODULO(a, b) (a % b == 0 ? \
54  static_cast<std::size_t>(b) : \
55  static_cast<std::size_t>(a % b))
56 #define ALIGNMENT_MIN(a, b) (static_cast<std::size_t>(a) < \
57  static_cast<std::size_t>(b) ? \
58  static_cast<std::size_t>(a) : \
59  static_cast<std::size_t>(b))
60 
61  template <class T, std::size_t N>
62  struct AlignmentTester
63  {
64  typedef AlignmentStruct<T> s;
65  typedef AlignmentHelper<T, N> h;
66  typedef AlignmentTester<T, N - 1> next;
67  enum
68  {
69  a1 = ALIGNMENT_MODULO(N , sizeof(T)),
70  a2 = ALIGNMENT_MODULO(h::N2 , sizeof(T)),
71  a3 = ALIGNMENT_MODULO(sizeof(h), sizeof(T)),
72  a = sizeof(h) == sizeof(s) ? ALIGNMENT_MIN(a1, a2) : a3,
73  result = ALIGNMENT_MIN(a, next::result)
74  };
75  };
76 
78  template <class T>
79  struct AlignmentTester<T, 0>
80  {
81  enum
82  {
83  result = ALIGNMENT_MODULO(sizeof(AlignmentStruct<T>), sizeof(T))
84  };
85  };
86  } //end anonymous namespace
87 
96  template <class T>
97  struct AlignmentOf
98  {
99 
100  enum
101  {
103 #ifdef HAVE_TYPE_TRAITS
104  value = std::alignment_of<T>::value
105 #elif HAVE_TR1_TYPETRAITS
106  value = std::tr1::alignment_of<T>::value
107 #else
108  value = AlignmentTester<T, sizeof(AlignmentStruct<T>) - sizeof(T) -1>::result
109 #endif
110  };
111  };
112 
114 }
115 #endif