| #pragma once |
| |
| #ifndef TCG_ALIGNMENT_H |
| #define TCG_ALIGNMENT_H |
| |
| #include "macros.h" |
| |
| |
| |
| |
| |
| |
| namespace tcg |
| { |
| |
| |
| |
| |
| |
| |
| |
| union _MaxAlign { |
| int i; |
| long l; |
| long long ll; |
| long double ld; |
| double d; |
| void *p; |
| void (*pf)(); |
| _MaxAlign *ps; |
| }; |
| |
| |
| |
| template <typename T, bool> |
| struct _AlignTypeDetail; |
| |
| template <typename T> |
| struct _AlignTypeDetail<T, false> { |
| typedef T type; |
| }; |
| |
| template <typename T> |
| struct _AlignTypeDetail<T, true> { |
| typedef char type; |
| }; |
| |
| template <size_t alignment, typename U> |
| struct _AlignType { |
| typedef typename _AlignTypeDetail<U, (alignment < sizeof(U))>::type type; |
| }; |
| |
| template <typename T> |
| struct _Aligner { |
| char c; |
| T t; |
| }; |
| |
| |
| |
| |
| |
| template <int alignment> |
| union aligner_type { |
| private: |
| typename _AlignType<alignment, char>::type c; |
| typename _AlignType<alignment, short>::type s; |
| typename _AlignType<alignment, int>::type i; |
| typename _AlignType<alignment, long>::type l; |
| typename _AlignType<alignment, long long>::type ll; |
| typename _AlignType<alignment, float>::type f; |
| typename _AlignType<alignment, double>::type d; |
| typename _AlignType<alignment, long double>::type ld; |
| typename _AlignType<alignment, void *>::type pc; |
| typename _AlignType<alignment, _MaxAlign *>::type ps; |
| typename _AlignType<alignment, void (*)()>::type pf; |
| }; |
| |
| |
| |
| template <typename T> |
| union aligned_buffer { |
| typedef aligner_type<sizeof(_Aligner<T>) - sizeof(T)> aligner_type; |
| |
| aligner_type m_aligner; |
| char m_buf[sizeof(T)]; |
| |
| private: |
| TCG_STATIC_ASSERT(sizeof(_Aligner<T>) - sizeof(T) == |
| sizeof(_Aligner<aligner_type>) - sizeof(aligner_type)); |
| }; |
| |
| |
| |
| |
| |
| template <typename T> |
| struct alignment_traits { |
| static const int alignment = sizeof(_Aligner<T>) - sizeof(T); |
| |
| typedef aligner_type<alignment> aligner_type; |
| typedef aligned_buffer<T> buffer_type; |
| }; |
| |
| } |
| |
| #endif |