Merge remote-tracking branch 'origin/feature/C++11_variadic_templates' into development

This commit is contained in:
John Wellbelove 2019-05-26 13:45:12 +01:00
commit 03755c4609
12 changed files with 416 additions and 63 deletions

View File

@ -1 +1 @@
python -m cogapp -d -e -olargest.h -DNTypes=16 largest_generator.h
python -m cogapp -d -e -osmallest.h -DNTypes=16 smallest_generator.h

View File

@ -61,8 +61,55 @@ SOFTWARE.
#include "smallest.h"
#include "static_assert.h"
namespace etl
namespace etl
{
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_TYPE_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type and size.
/// Defines 'value_type' which is the type of the largest parameter.
/// Defines 'size' which is the size of the largest parameter.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
class largest_type
{
private:
// Define 'largest_other' as 'largest_type' with all but the first parameter.
using largest_other = typename largest_type<TRest...>::type;
public:
// Set 'type' to be the largest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::size_of<T1>() > etl::size_of<largest_other>()), // Boolean
T1, // TrueType
largest_other> // FalseType
::type; // The largest type of the two.
// The size of the largest type.
enum
{
size = etl::size_of<type>()
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
class largest_type<T1>
{
public:
using type = T1;
enum
{
size = etl::size_of<type>()
};
};
#else
//***************************************************************************
/// Template to determine the largest type and size.
/// Supports up to 16 types.
@ -107,7 +154,48 @@ namespace etl
size = sizeof(type)
};
};
#endif
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_ALIGNMENT_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest alignment.
/// Defines <b>value</b> which is the largest alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
struct largest_alignment
{
// Define 'largest_other' as 'largest_type' with all but the first parameter.
using largest_other = typename largest_alignment<TRest...>::type;
// Set 'type' to be the largest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::alignment_of<T1>::value > etl::alignment_of<largest_other>::value), // Boolean
T1, // TrueType
largest_other> // FalseType
::type; // The largest type of the two.
// The largest alignment.
enum
{
value = etl::alignment_of<type>::value
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
struct largest_alignment<T1>
{
typedef T1 type;
enum
{
value = etl::alignment_of<type>::value
};
};
#else
//***************************************************************************
/// Template to determine the largest alignment.
/// Supports up to 16 types.
@ -151,6 +239,7 @@ namespace etl
value = etl::alignment_of<type>::value
};
};
#endif
//***************************************************************************
/// Defines a type that is as larger or larger than the specified type.
@ -203,6 +292,24 @@ namespace etl
typedef typename etl::smallest_int_for_bits<etl::integral_limits<T>::bits + 1>::type type;
};
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type, size and alignment.
/// Defines <b>value</b> which is the largest type, size and alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename... T>
struct largest
{
using type = typename etl::largest_type<T...>::type;
enum
{
size = etl::largest_type<T...>::size,
alignment = etl::largest_alignment<T...>::value
};
};
#else
//***************************************************************************
/// Template to determine the largest type, size and alignment.
/// Supports up to 16 types.
@ -223,6 +330,7 @@ namespace etl
alignment = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value
};
};
#endif
}
#endif

View File

@ -73,8 +73,55 @@ cog.outl("//********************************************************************
#include "smallest.h"
#include "static_assert.h"
namespace etl
namespace etl
{
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_TYPE_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type and size.
/// Defines 'value_type' which is the type of the largest parameter.
/// Defines 'size' which is the size of the largest parameter.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
class largest_type
{
private:
// Define 'largest_other' as 'largest_type' with all but the first parameter.
using largest_other = typename largest_type<TRest...>::type;
public:
// Set 'type' to be the largest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::size_of<T1>() > etl::size_of<largest_other>()), // Boolean
T1, // TrueType
largest_other> // FalseType
::type; // The largest type of the two.
// The size of the largest type.
enum
{
size = etl::size_of<type>()
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
class largest_type<T1>
{
public:
using type = T1;
enum
{
size = etl::size_of<type>()
};
};
#else
/*[[[cog
import cog
cog.outl("//***************************************************************************")
@ -137,7 +184,48 @@ namespace etl
cog.outl("};")
]]]*/
/*[[[end]]]*/
#endif
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_ALIGNMENT_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest alignment.
/// Defines <b>value</b> which is the largest alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
struct largest_alignment
{
// Define 'largest_other' as 'largest_type' with all but the first parameter.
using largest_other = typename largest_alignment<TRest...>::type;
// Set 'type' to be the largest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::alignment_of<T1>::value > etl::alignment_of<largest_other>::value), // Boolean
T1, // TrueType
largest_other> // FalseType
::type; // The largest type of the two.
// The largest alignment.
enum
{
value = etl::alignment_of<type>::value
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
struct largest_alignment<T1>
{
typedef T1 type;
enum
{
value = etl::alignment_of<type>::value
};
};
#else
/*[[[cog
import cog
cog.outl("//***************************************************************************")
@ -199,6 +287,7 @@ namespace etl
cog.outl("};")
]]]*/
/*[[[end]]]*/
#endif
//***************************************************************************
/// Defines a type that is as larger or larger than the specified type.
@ -251,6 +340,24 @@ namespace etl
typedef typename etl::smallest_int_for_bits<etl::integral_limits<T>::bits + 1>::type type;
};
#if ETL_CPP11_SUPPORTED && !defined(ETL_LARGEST_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type, size and alignment.
/// Defines <b>value</b> which is the largest type, size and alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename... T>
struct largest
{
using type = typename etl::largest_type<T...>::type;
enum
{
size = etl::largest_type<T...>::size,
alignment = etl::largest_alignment<T...>::value
};
};
#else
/*[[[cog
import cog
cog.outl("//***************************************************************************")
@ -296,6 +403,7 @@ namespace etl
cog.outl("};")
]]]*/
/*[[[end]]]*/
#endif
}
#endif

View File

@ -63,6 +63,53 @@ SOFTWARE.
namespace etl
{
#if ETL_CPP11_SUPPORTED && !defined(ETL_SMALLEST_TYPE_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type and size.
/// Defines 'value_type' which is the type of the largest parameter.
/// Defines 'size' which is the size of the largest parameter.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
class smallest_type
{
private:
// Define 'smallest_other' as 'smallest_type' with all but the first parameter.
using smallest_other = typename smallest_type<TRest...>::type;
public:
// Set 'type' to be the smallest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::size_of<T1>() < etl::size_of<smallest_other>()), // Boolean
T1, // TrueType
smallest_other> // FalseType
::type; // The smallest type of the two.
// The size of the smallest type.
enum
{
size = etl::size_of<type>()
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
class smallest_type<T1>
{
public:
using type = T1;
enum
{
size = etl::size_of<type>()
};
};
#else
//***************************************************************************
/// Template to determine the smallest type and size.
/// Supports up to 16 types.
@ -131,7 +178,8 @@ namespace etl
size = sizeof(type)
};
};
#endif
namespace private_smallest
{
//*************************************************************************
@ -139,7 +187,7 @@ namespace etl
//*************************************************************************
template <const int index>
struct best_fit_uint_type;
//*************************************************************************
// Less than or equal to 8 bits.
//*************************************************************************
@ -220,7 +268,7 @@ namespace etl
}
//***************************************************************************
/// Template to determine the smallest unsigned int type that can contain a
/// Template to determine the smallest unsigned int type that can contain a
/// value with the specified number of bits.
/// Defines 'type' which is the type of the smallest unsigned integer.
///\ingroup smallest
@ -229,9 +277,9 @@ namespace etl
struct smallest_uint_for_bits
{
private:
// Determines the index of the best unsigned type for the required number of bits.
static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) +
static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) +
((NBITS > 16) ? 1 : 0) +
((NBITS > 32) ? 1 : 0);
@ -241,7 +289,7 @@ namespace etl
};
//***************************************************************************
/// Template to determine the smallest signed int type that can contain a
/// Template to determine the smallest signed int type that can contain a
/// value with the specified number of bits.
/// Defines 'type' which is the type of the smallest signed integer.
///\ingroup smallest
@ -274,7 +322,7 @@ namespace etl
// Determines the index of the best unsigned type for the required value.
static const int TYPE_INDEX = ((VALUE > UINT_LEAST8_MAX) ? 1 : 0) +
((VALUE > UINT16_MAX) ? 1 : 0) +
((VALUE > UINT16_MAX) ? 1 : 0) +
((VALUE > UINT32_MAX) ? 1 : 0);
public:
@ -294,7 +342,7 @@ namespace etl
private:
// Determines the index of the best signed type for the required value.
static const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX) || (VALUE < INT_LEAST8_MIN)) ? 1 : 0) +
static const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX) || (VALUE < INT_LEAST8_MIN)) ? 1 : 0) +
(((VALUE > INT16_MAX) || (VALUE < INT16_MIN)) ? 1 : 0) +
(((VALUE > INT32_MAX) || (VALUE < INT32_MIN)) ? 1 : 0);

View File

@ -75,6 +75,53 @@ cog.outl("//********************************************************************
namespace etl
{
#if ETL_CPP11_SUPPORTED && !defined(ETL_SMALLEST_TYPE_FORCE_CPP03)
//***************************************************************************
/// Template to determine the largest type and size.
/// Defines 'value_type' which is the type of the largest parameter.
/// Defines 'size' which is the size of the largest parameter.
///\ingroup largest
//***************************************************************************
template <typename T1, typename... TRest>
class smallest_type
{
private:
// Define 'smallest_other' as 'smallest_type' with all but the first parameter.
using smallest_other = typename smallest_type<TRest...>::type;
public:
// Set 'type' to be the smallest of the first parameter and any of the others.
// This is recursive.
using type = typename etl::conditional<(etl::size_of<T1>() < etl::size_of<smallest_other>()), // Boolean
T1, // TrueType
smallest_other> // FalseType
::type; // The smallest type of the two.
// The size of the smallest type.
enum
{
size = etl::size_of<type>()
};
};
//***************************************************************************
// Specialisation for one template parameter.
//***************************************************************************
template <typename T1>
class smallest_type<T1>
{
public:
using type = T1;
enum
{
size = etl::size_of<type>()
};
};
#else
/*[[[cog
import cog
cog.outl("//***************************************************************************")
@ -161,7 +208,8 @@ namespace etl
cog.outl("};")
]]]*/
/*[[[end]]]*/
#endif
namespace private_smallest
{
//*************************************************************************
@ -169,7 +217,7 @@ namespace etl
//*************************************************************************
template <const int index>
struct best_fit_uint_type;
//*************************************************************************
// Less than or equal to 8 bits.
//*************************************************************************
@ -250,7 +298,7 @@ namespace etl
}
//***************************************************************************
/// Template to determine the smallest unsigned int type that can contain a
/// Template to determine the smallest unsigned int type that can contain a
/// value with the specified number of bits.
/// Defines 'type' which is the type of the smallest unsigned integer.
///\ingroup smallest
@ -259,9 +307,9 @@ namespace etl
struct smallest_uint_for_bits
{
private:
// Determines the index of the best unsigned type for the required number of bits.
static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) +
static const int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) +
((NBITS > 16) ? 1 : 0) +
((NBITS > 32) ? 1 : 0);
@ -271,7 +319,7 @@ namespace etl
};
//***************************************************************************
/// Template to determine the smallest signed int type that can contain a
/// Template to determine the smallest signed int type that can contain a
/// value with the specified number of bits.
/// Defines 'type' which is the type of the smallest signed integer.
///\ingroup smallest
@ -304,7 +352,7 @@ namespace etl
// Determines the index of the best unsigned type for the required value.
static const int TYPE_INDEX = ((VALUE > UINT_LEAST8_MAX) ? 1 : 0) +
((VALUE > UINT16_MAX) ? 1 : 0) +
((VALUE > UINT16_MAX) ? 1 : 0) +
((VALUE > UINT32_MAX) ? 1 : 0);
public:
@ -324,7 +372,7 @@ namespace etl
private:
// Determines the index of the best signed type for the required value.
static const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX) || (VALUE < INT_LEAST8_MIN)) ? 1 : 0) +
static const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX) || (VALUE < INT_LEAST8_MIN)) ? 1 : 0) +
(((VALUE > INT16_MAX) || (VALUE < INT16_MIN)) ? 1 : 0) +
(((VALUE > INT32_MAX) || (VALUE < INT32_MIN)) ? 1 : 0);

View File

@ -487,19 +487,40 @@ namespace etl
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0>{};
#if ETL_CPP11_SUPPORTED
//***************************************************************************"
/// Template to determine if a type is one of a specified list.
///\ingroup types
//***************************************************************************"
template <typename T, typename T1, typename... TRest>
struct is_one_of
{
static const bool value = etl::is_same<T, T1>::value ||
etl::is_one_of<T, TRest...>::value;
};
template <typename T, typename T1>
struct is_one_of<T, T1>
{
static const bool value = etl::is_same<T, T1>::value;
};
#else
//***************************************************************************
/// Template to determine if a type is one of a specified list.
///\ingroup types
//***************************************************************************
template <typename T,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void,
typename T17 = void>
struct is_one_of
{
static const bool value =
static const bool value =
etl::is_same<T, T1>::value ||
etl::is_same<T, T2>::value ||
etl::is_same<T, T3>::value ||
@ -519,6 +540,8 @@ namespace etl
etl::is_same<T, T17>::value;
};
#endif
//***************************************************************************
// A set of templates to allow related types to be derived.
//***************************************************************************
@ -597,23 +620,19 @@ namespace etl
//***************************************************************************
// size_of
//***************************************************************************
#if ETL_CPP11_SUPPORTED
template <typename T>
struct size_of
constexpr size_t size_of()
{
enum
{
size = sizeof(T)
};
};
return sizeof(T);
}
template <>
struct size_of<void>
constexpr size_t size_of<void>()
{
enum
{
size = 1
};
};
return 1;
}
#endif
}
#endif

View File

@ -499,6 +499,27 @@ namespace etl
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0>{};
#if ETL_CPP11_SUPPORTED
//***************************************************************************"
/// Template to determine if a type is one of a specified list.
///\ingroup types
//***************************************************************************"
template <typename T, typename T1, typename... TRest>
struct is_one_of
{
static const bool value = etl::is_same<T, T1>::value ||
etl::is_one_of<T, TRest...>::value;
};
template <typename T, typename T1>
struct is_one_of<T, T1>
{
static const bool value = etl::is_same<T, T1>::value;
};
#else
/*[[[cog
import cog
cog.outl("//***************************************************************************")
@ -524,6 +545,8 @@ namespace etl
]]]*/
/*[[[end]]]*/
#endif
//***************************************************************************
// A set of templates to allow related types to be derived.
//***************************************************************************
@ -602,23 +625,19 @@ namespace etl
//***************************************************************************
// size_of
//***************************************************************************
#if ETL_CPP11_SUPPORTED
template <typename T>
struct size_of
constexpr size_t size_of()
{
enum
{
size = sizeof(T)
};
};
return sizeof(T);
}
template <>
struct size_of<void>
constexpr size_t size_of<void>()
{
enum
{
size = 1
};
};
return 1;
}
#endif
}
#endif

View File

@ -38,8 +38,8 @@ SOFTWARE.
///\ingroup utilities
#define ETL_VERSION_MAJOR 14
#define ETL_VERSION_MINOR 24
#define ETL_VERSION_PATCH 2
#define ETL_VERSION_MINOR 25
#define ETL_VERSION_PATCH 0
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH)
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH))

View File

@ -1,3 +1,8 @@
===============================================================================
14.25.0
Added variadic template versions of etl::largest, etl::largest_type,
etl::largest_alignment and etl::smallest
===============================================================================
14.24.2
Fixed bug in 'vector of pointers' move constructor.

View File

@ -86,6 +86,7 @@ SOFTWARE.
//#define ETL_QUEUE_ISR_FORCE_CPP03
//#define ETL_QUEUE_LOCKED_FORCE_CPP03
//#define ETL_OPTIONAL_FORCE_CPP03
//#define ETL_LARGEST_TYPE_FORCE_CPP03
#ifdef _MSC_VER
#include "etl/profiles/msvc_x86.h"

View File

@ -33,7 +33,7 @@ SOFTWARE.
#include <type_traits>
namespace
{
{
SUITE(test_largest)
{
//*************************************************************************
@ -92,7 +92,7 @@ namespace
struct S1 { char a; char b; char c; };
struct S2 { char a; short b; char c; };
struct S3 { int a; short b; char c; };
size_t size = etl::largest_alignment<S1, S2, S3>::value;
CHECK_EQUAL(std::alignment_of<S3>::value, size);

View File

@ -49,13 +49,10 @@ namespace
namespace etl
{
template <>
struct size_of<TestData>
constexpr size_t size_of<TestData>()
{
enum
{
size = 20
};
};
return 20;
}
}
namespace
@ -749,10 +746,10 @@ namespace
//*************************************************************************
TEST(size_of)
{
CHECK_EQUAL(1, etl::size_of<void>::size);
CHECK_EQUAL(1, etl::size_of<char>::size);
CHECK_EQUAL(2, etl::size_of<short>::size);
CHECK_EQUAL(4, etl::size_of<int>::size);
CHECK_EQUAL(20, etl::size_of<TestData>::size);
CHECK_EQUAL(1, etl::size_of<void>());
CHECK_EQUAL(1, etl::size_of<char>());
CHECK_EQUAL(2, etl::size_of<short>());
CHECK_EQUAL(4, etl::size_of<int>());
CHECK_EQUAL(20, etl::size_of<TestData>());
}
}