tahoma2d/toonz/sources/include/tcg/alignment.h

107 lines
2.6 KiB
C
Raw Normal View History

2016-05-17 03:04:11 +12:00
#pragma once
2016-03-19 06:57:51 +13:00
#ifndef TCG_ALIGNMENT_H
#define TCG_ALIGNMENT_H
#include "macros.h"
/*! \file alignment.h
This file contains C++ utilities about types alignment.
*/
2016-06-15 18:43:10 +12:00
namespace tcg {
2016-03-19 06:57:51 +13:00
//**************************************************************************
// Private stuff
//**************************************************************************
// From http://stackoverflow.com/questions/6959261/how-can-i-simulate-alignast
union _MaxAlign {
2016-06-15 18:43:10 +12:00
int i;
long l;
long long ll;
long double ld;
double d;
void *p;
void (*pf)();
_MaxAlign *ps;
2016-03-19 06:57:51 +13:00
};
//---------------------------------------------------------------
template <typename T, bool>
struct _AlignTypeDetail;
template <typename T>
struct _AlignTypeDetail<T, false> {
2016-06-15 18:43:10 +12:00
typedef T type;
2016-03-19 06:57:51 +13:00
};
template <typename T>
struct _AlignTypeDetail<T, true> {
2016-06-15 18:43:10 +12:00
typedef char type;
2016-03-19 06:57:51 +13:00
};
template <size_t alignment, typename U>
struct _AlignType {
2016-06-15 18:43:10 +12:00
typedef typename _AlignTypeDetail<U, (alignment < sizeof(U))>::type type;
2016-03-19 06:57:51 +13:00
};
template <typename T>
struct _Aligner {
2016-06-15 18:43:10 +12:00
char c;
T t;
2016-03-19 06:57:51 +13:00
};
//**************************************************************************
// TCG alignment unions
//**************************************************************************
template <int alignment>
union aligner_type {
private:
2016-06-15 18:43:10 +12:00
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;
2016-03-19 06:57:51 +13:00
};
//---------------------------------------------------------------
template <typename T>
union aligned_buffer {
2016-06-24 05:35:59 +12:00
typedef aligner_type<sizeof(_Aligner<T>) - sizeof(T)> aligner_type_t;
2016-03-19 06:57:51 +13:00
2016-06-24 05:35:59 +12:00
aligner_type_t m_aligner;
2016-06-15 18:43:10 +12:00
char m_buf[sizeof(T)];
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
TCG_STATIC_ASSERT(sizeof(_Aligner<T>) - sizeof(T) ==
2016-06-24 05:35:59 +12:00
sizeof(_Aligner<aligner_type_t>) - sizeof(aligner_type_t));
2016-03-19 06:57:51 +13:00
};
//**************************************************************************
// TCG alignment traits
//**************************************************************************
template <typename T>
struct alignment_traits {
2016-06-15 18:43:10 +12:00
static const int alignment = sizeof(_Aligner<T>) - sizeof(T);
2016-03-19 06:57:51 +13:00
2016-06-24 05:35:59 +12:00
typedef aligner_type<alignment> aligner_type_traits;
2016-06-15 18:43:10 +12:00
typedef aligned_buffer<T> buffer_type;
2016-03-19 06:57:51 +13:00
};
2016-06-15 18:43:10 +12:00
} // namespace tcg
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
#endif // TCG_ALIGNMENT_H