mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Added C++11 alignment matcher code
This commit is contained in:
parent
81cd2df218
commit
c9bb331f4c
@ -102,16 +102,61 @@ namespace etl
|
||||
|
||||
namespace private_alignment
|
||||
{
|
||||
#if ETL_USING_CPP11
|
||||
//***************************************************************************
|
||||
// Matcher.
|
||||
//***************************************************************************
|
||||
template <bool IS_MATCH, const size_t ALIGNMENT, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
template <bool Is_Match, size_t Alignment, typename... TRest>
|
||||
class type_with_alignment_matcher;
|
||||
|
||||
// Matching alignment.
|
||||
template <size_t Alignment, typename T1, typename... TRest>
|
||||
class type_with_alignment_matcher<true, Alignment, T1, TRest...>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
// Non-matching alignment
|
||||
template <size_t Alignment, typename T1, typename T2, typename... TRest>
|
||||
class type_with_alignment_matcher <false, Alignment, T1, T2, TRest...>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename type_with_alignment_matcher < Alignment <= etl::alignment_of<T2>::value , Alignment, T2, TRest... > ::type type;
|
||||
};
|
||||
|
||||
// Non-matching alignment, none left.
|
||||
template <size_t Alignment, typename T1>
|
||||
class type_with_alignment_matcher <false, Alignment, T1>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Helper.
|
||||
//***************************************************************************
|
||||
template <size_t Alignment, typename T1, typename... T>
|
||||
class type_with_alignment_helper
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T...>::type type;
|
||||
};
|
||||
#else
|
||||
//***************************************************************************
|
||||
// Matcher.
|
||||
//***************************************************************************
|
||||
template <bool Is_Match, const size_t Alignment, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
|
||||
class type_with_alignment_matcher;
|
||||
|
||||
// Matching alignment.
|
||||
template <size_t ALIGNMENT, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class type_with_alignment_matcher <true, ALIGNMENT, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class type_with_alignment_matcher <true, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -119,17 +164,17 @@ namespace etl
|
||||
};
|
||||
|
||||
// Non-matching alignment.
|
||||
template <size_t ALIGNMENT, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class type_with_alignment_matcher <false, ALIGNMENT, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
template <size_t Alignment, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||
class type_with_alignment_matcher <false, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename type_with_alignment_matcher<ALIGNMENT <= etl::alignment_of<T2>::value, ALIGNMENT, T2, T3, T4, T5, T6, T7, T8, void>::type type;
|
||||
typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T2>::value, Alignment, T2, T3, T4, T5, T6, T7, T8, void>::type type;
|
||||
};
|
||||
|
||||
// Non-matching alignment, none left.
|
||||
template <size_t ALIGNMENT>
|
||||
class type_with_alignment_matcher <false, ALIGNMENT, void, void, void, void, void, void, void, void>
|
||||
template <size_t Alignment>
|
||||
class type_with_alignment_matcher <false, Alignment, void, void, void, void, void, void, void, void>
|
||||
{
|
||||
public:
|
||||
|
||||
@ -139,38 +184,39 @@ namespace etl
|
||||
//***************************************************************************
|
||||
// Helper.
|
||||
//***************************************************************************
|
||||
template <size_t ALIGNMENT, typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
|
||||
template <size_t Alignment, typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
|
||||
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void>
|
||||
class type_with_alignment_helper
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename type_with_alignment_matcher<ALIGNMENT <= etl::alignment_of<T1>::value, ALIGNMENT, T1, T2, T3, T4, T5, T6, T7, T8>::type type;
|
||||
typedef typename type_with_alignment_matcher<Alignment <= etl::alignment_of<T1>::value, Alignment, T1, T2, T3, T4, T5, T6, T7, T8>::type type;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Gets a type that has the same as the specified alignment.
|
||||
///\ingroup alignment
|
||||
//***************************************************************************
|
||||
template <size_t ALIGNMENT>
|
||||
template <size_t Alignment>
|
||||
class type_with_alignment
|
||||
{
|
||||
public:
|
||||
|
||||
#if ETL_NOT_USING_64BIT_TYPES
|
||||
typedef typename private_alignment::type_with_alignment_helper<ALIGNMENT, int_least8_t, int_least16_t, int32_t, float, double, void*>::type type;
|
||||
typedef typename private_alignment::type_with_alignment_helper<Alignment, int_least8_t, int_least16_t, int32_t, float, double, void*>::type type;
|
||||
#else
|
||||
typedef typename private_alignment::type_with_alignment_helper<ALIGNMENT, int_least8_t, int_least16_t, int32_t, int64_t, float, double, void*>::type type;
|
||||
typedef typename private_alignment::type_with_alignment_helper<Alignment, int_least8_t, int_least16_t, int32_t, int64_t, float, double, void*>::type type;
|
||||
#endif
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Aligned storage
|
||||
/// LENGTH should be determined in terms of sizeof()
|
||||
/// Length should be determined in terms of sizeof()
|
||||
///\ingroup alignment
|
||||
//***************************************************************************
|
||||
template <size_t LENGTH, const size_t ALIGNMENT>
|
||||
template <size_t Length, const size_t Alignment>
|
||||
struct aligned_storage
|
||||
{
|
||||
struct type
|
||||
@ -184,7 +230,7 @@ namespace etl
|
||||
template <typename T>
|
||||
operator T& ()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
T* t = *this;
|
||||
return *t;
|
||||
}
|
||||
@ -193,7 +239,7 @@ namespace etl
|
||||
template <typename T>
|
||||
operator const T& () const
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
const T* t = *this;
|
||||
return *t;
|
||||
}
|
||||
@ -202,7 +248,7 @@ namespace etl
|
||||
template <typename T>
|
||||
operator T* ()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
@ -210,7 +256,7 @@ namespace etl
|
||||
template <typename T>
|
||||
operator const T* () const
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
return reinterpret_cast<const T*>(data);
|
||||
}
|
||||
|
||||
@ -218,7 +264,7 @@ namespace etl
|
||||
template <typename T>
|
||||
T& get_reference()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
T* t = *this;
|
||||
return *t;
|
||||
}
|
||||
@ -227,7 +273,7 @@ namespace etl
|
||||
template <typename T>
|
||||
const T& get_reference() const
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
const T* t = *this;
|
||||
return *t;
|
||||
}
|
||||
@ -236,7 +282,7 @@ namespace etl
|
||||
template <typename T>
|
||||
T* get_address()
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
return reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
@ -244,39 +290,39 @@ namespace etl
|
||||
template <typename T>
|
||||
const T* get_address() const
|
||||
{
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
ETL_STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((Alignment % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
|
||||
return reinterpret_cast<const T*>(data);
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5)
|
||||
alignas(ALIGNMENT) char data[LENGTH];
|
||||
alignas(Alignment) char data[Length];
|
||||
#else
|
||||
union
|
||||
{
|
||||
char data[LENGTH];
|
||||
typename etl::type_with_alignment<ALIGNMENT>::type etl_alignment_type; // A POD type that has the same alignment as ALIGNMENT.
|
||||
char data[Length];
|
||||
typename etl::type_with_alignment<Alignment>::type etl_alignment_type; // A POD type that has the same alignment as Alignment.
|
||||
};
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <size_t LENGTH, const size_t ALIGNMENT>
|
||||
using aligned_storage_t = typename aligned_storage<LENGTH, ALIGNMENT>::type;
|
||||
template <size_t Length, const size_t Alignment>
|
||||
using aligned_storage_t = typename aligned_storage<Length, Alignment>::type;
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Aligned storage as
|
||||
///\ingroup alignment
|
||||
//***************************************************************************
|
||||
template <size_t LENGTH, typename T>
|
||||
struct aligned_storage_as : public etl::aligned_storage<LENGTH, etl::alignment_of<T>::value>
|
||||
template <size_t Length, typename T>
|
||||
struct aligned_storage_as : public etl::aligned_storage<Length, etl::alignment_of<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <size_t LENGTH, typename T>
|
||||
using aligned_storage_as_t = typename aligned_storage_as<LENGTH, T>::type;
|
||||
template <size_t Length, typename T>
|
||||
using aligned_storage_as_t = typename aligned_storage_as<Length, T>::type;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user