Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_ALIGNMENT_H
Toshihiro Shimizu 890ddd
#define TCG_ALIGNMENT_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "macros.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \file alignment.h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  This file contains C++ utilities about types alignment.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
//    Private  stuff
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// From http://stackoverflow.com/questions/6959261/how-can-i-simulate-alignast
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
union _MaxAlign {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  long l;
Shinya Kitaoka 120a6e
  long long ll;
Shinya Kitaoka 120a6e
  long double ld;
Shinya Kitaoka 120a6e
  double d;
Shinya Kitaoka 120a6e
  void *p;
Shinya Kitaoka 120a6e
  void (*pf)();
Shinya Kitaoka 120a6e
  _MaxAlign *ps;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T, bool>
Toshihiro Shimizu 890ddd
struct _AlignTypeDetail;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
struct _AlignTypeDetail<T, false> {
Shinya Kitaoka 120a6e
  typedef T type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
struct _AlignTypeDetail<T, true> {
Shinya Kitaoka 120a6e
  typedef char type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <size_t alignment, typename U>
Toshihiro Shimizu 890ddd
struct _AlignType {
Shinya Kitaoka 120a6e
  typedef typename _AlignTypeDetail<U, (alignment < sizeof(U))>::type type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
struct _Aligner {
Shinya Kitaoka 120a6e
  char c;
Shinya Kitaoka 120a6e
  T t;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
//    TCG alignment  unions
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <int alignment>
Toshihiro Shimizu 890ddd
union aligner_type {
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, char>::type c;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, short>::type s;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, int>::type i;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, long>::type l;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, long long>::type ll;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, float>::type f;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, double>::type d;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, long double>::type ld;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, void *>::type pc;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, _MaxAlign *>::type ps;
Shinya Kitaoka 120a6e
  typename _AlignType<alignment, void (*)()>::type pf;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
union aligned_buffer {
Michał Janiszewski 5387be
  typedef aligner_type<sizeof(_Aligner<T>) - sizeof(T)> aligner_type_t;
Toshihiro Shimizu 890ddd
Michał Janiszewski 5387be
  aligner_type_t m_aligner;
Shinya Kitaoka 120a6e
  char m_buf[sizeof(T)];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  TCG_STATIC_ASSERT(sizeof(_Aligner<T>) - sizeof(T) ==
Michał Janiszewski 5387be
                    sizeof(_Aligner<aligner_type_t>) - sizeof(aligner_type_t));
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
//    TCG alignment  traits
Toshihiro Shimizu 890ddd
//**************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename T>
Toshihiro Shimizu 890ddd
struct alignment_traits {
Shinya Kitaoka 120a6e
  static const int alignment = sizeof(_Aligner<T>) - sizeof(T);
Toshihiro Shimizu 890ddd
Michał Janiszewski 5387be
  typedef aligner_type<alignment> aligner_type_traits;
Shinya Kitaoka 120a6e
  typedef aligned_buffer<T> buffer_type;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_ALIGNMENT_H