Merge branch 'development'

This commit is contained in:
John Wellbelove 2017-12-21 14:12:29 +00:00
commit 1b11cf5c58
32 changed files with 2036 additions and 2882 deletions

View File

@ -1,5 +1,5 @@
name=Embedded Template Library
version=10.6.0
version=10.8.0
author= John Wellbelove <john.wellbelove@etlcpp.com>
maintainer=John Wellbelove <john.wellbelove@etlcpp.com>
sentence=A C++ template library tailored for embedded systems.

470
src/binary.cpp Normal file
View File

@ -0,0 +1,470 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com
Copyright(c) 2017 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "platform.h"
#include "binary.h"
namespace etl
{
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Reverse 8 bits.
//***************************************************************************
uint8_t reverse_bits(uint8_t value)
{
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
value = (value >> 4) | (value << 4);
return value;
}
#endif
//***************************************************************************
/// Reverse 16 bits.
//***************************************************************************
uint16_t reverse_bits(uint16_t value)
{
value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
value = (value >> 8) | (value << 8);
return value;
}
//***************************************************************************
/// Reverse 32 bits.
//***************************************************************************
uint32_t reverse_bits(uint32_t value)
{
value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
value = (value >> 16) | (value << 16);
return value;
}
//***************************************************************************
/// Reverse 64 bits.
//***************************************************************************
uint64_t reverse_bits(uint64_t value)
{
value = ((value & 0xAAAAAAAAAAAAAAAA) >> 1) | ((value & 0x5555555555555555) << 1);
value = ((value & 0xCCCCCCCCCCCCCCCC) >> 2) | ((value & 0x3333333333333333) << 2);
value = ((value & 0xF0F0F0F0F0F0F0F0) >> 4) | ((value & 0x0F0F0F0F0F0F0F0F) << 4);
value = ((value & 0xFF00FF00FF00FF00) >> 8) | ((value & 0x00FF00FF00FF00FF) << 8);
value = ((value & 0xFFFF0000FFFF0000) >> 16) | ((value & 0x0000FFFF0000FFFF) << 16);
value = (value >> 32) | (value << 32);
return value;
}
//***************************************************************************
/// Reverse bytes 16 bit.
//***************************************************************************
uint16_t reverse_bytes(uint16_t value)
{
value = (value >> 8) | (value << 8);
return value;
}
//***************************************************************************
/// Reverse bytes 32 bit.
//***************************************************************************
uint32_t reverse_bytes(uint32_t value)
{
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
value = (value >> 16) | (value << 16);
return value;
}
//***************************************************************************
/// Reverse bytes 64 bit.
//***************************************************************************
uint64_t reverse_bytes(uint64_t value)
{
value = ((value & 0xFF00FF00FF00FF00) >> 8) | ((value & 0x00FF00FF00FF00FF) << 8);
value = ((value & 0xFFFF0000FFFF0000) >> 16) | ((value & 0x0000FFFF0000FFFF) << 16);
value = (value >> 32) | (value << 32);
return value;
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
uint8_t gray_to_binary(uint8_t value)
{
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
#endif
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
uint16_t gray_to_binary(uint16_t value)
{
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
uint32_t gray_to_binary(uint32_t value)
{
value ^= (value >> 16);
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
uint64_t gray_to_binary(uint64_t value)
{
value ^= (value >> 32);
value ^= (value >> 16);
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Count set bits. 8 bits.
//***************************************************************************
uint_least8_t count_bits(uint8_t value)
{
uint32_t count;
static const int S[] = { 1, 2, 4 };
static const uint8_t B[] = { 0x55, 0x33, 0x0F };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
return uint_least8_t(count);
}
#endif
//***************************************************************************
/// Count set bits. 16 bits.
//***************************************************************************
uint_least8_t count_bits(uint16_t value)
{
uint32_t count;
static const int S[] = { 1, 2, 4, 8 };
static const uint16_t B[] = { 0x5555, 0x3333, 0x0F0F, 0x00FF };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
count = ((count >> S[3]) + count) & B[3];
return count;
}
//***************************************************************************
/// Count set bits. 32 bits.
//***************************************************************************
uint_least8_t count_bits(uint32_t value)
{
uint32_t count;
value = value - ((value >> 1) & 0x55555555);
value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
count = (((value + (value >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
return uint_least8_t(count);
}
//***************************************************************************
/// Count set bits. 64 bits.
//***************************************************************************
uint_least8_t count_bits(uint64_t value)
{
uint64_t count;
static const int S[] = { 1, 2, 4, 8, 16, 32 };
static const uint64_t B[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF, 0x00000000FFFFFFFF };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
count = ((count >> S[3]) + count) & B[3];
count = ((count >> S[4]) + count) & B[4];
count = ((count >> S[5]) + count) & B[5];
return uint_least8_t(count);
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Parity. 8bits. 0 = even, 1 = odd
//***************************************************************************
uint_least8_t parity(uint8_t value)
{
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
#endif
//***************************************************************************
/// Parity. 16bits. 0 = even, 1 = odd
//***************************************************************************
uint_least8_t parity(uint16_t value)
{
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
//***************************************************************************
/// Parity. 32bits. 0 = even, 1 = odd
//***************************************************************************
uint_least8_t parity(uint32_t value)
{
value ^= value >> 16;
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
//***************************************************************************
/// Parity. 64bits. 0 = even, 1 = odd
//***************************************************************************
uint_least8_t parity(uint64_t value)
{
value ^= value >> 32;
value ^= value >> 16;
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x69966996 >> value) & 1;
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Count trailing zeros. bit.
/// Uses a binary search.
//***************************************************************************
uint_least8_t count_trailing_zeros(uint8_t value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
#endif
//***************************************************************************
/// Count trailing zeros. 16bit.
/// Uses a binary search.
//***************************************************************************
uint_least8_t count_trailing_zeros(uint16_t value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
//***************************************************************************
/// Count trailing zeros. 32bit.
/// Uses a binary search.
//***************************************************************************
uint_least8_t count_trailing_zeros(uint32_t value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFFFF) == 0)
{
value >>= 16;
count += 16;
}
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
//***************************************************************************
/// Count trailing zeros. 64bit.
/// Uses a binary search.
//***************************************************************************
uint_least8_t count_trailing_zeros(uint64_t value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFFFFFFFF) == 0)
{
value >>= 32;
count += 32;
}
if ((value & 0xFFFF) == 0)
{
value >>= 16;
count += 16;
}
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
}

View File

@ -52,34 +52,12 @@ namespace etl
//***************************************************************************
/// Maximum value that can be contained in N bits.
//***************************************************************************
namespace __private_binary__
{
/// Helper definition for non-zero NBITS.
template <const size_t NBITS>
struct max_value_for_nbits_helper
{
typedef typename etl::smallest_uint_for_bits<NBITS>::type value_type;
static const value_type value = (uint64_t(1) << (NBITS - 1)) | max_value_for_nbits_helper<NBITS - 1>::value;
};
/// Specialisation for when NBITS == 0.
template <>
struct max_value_for_nbits_helper<0>
{
typedef etl::smallest_uint_for_bits<0>::type value_type;
static const value_type value = 1;
};
template <const size_t NBITS>
const typename max_value_for_nbits_helper<NBITS>::value_type max_value_for_nbits_helper<NBITS>::value;
}
/// Definition for non-zero NBITS.
template <const size_t NBITS>
struct max_value_for_nbits
{
typedef typename etl::smallest_uint_for_bits<NBITS>::type value_type;
static const value_type value = __private_binary__::max_value_for_nbits_helper<NBITS>::value;
static const value_type value = (value_type(1) << (NBITS - 1)) | max_value_for_nbits<NBITS - 1>::value;
};
/// Specialisation for when NBITS == 0.
@ -172,108 +150,33 @@ namespace etl
return result;
}
//***************************************************************************
/// Reverse bits.
//***************************************************************************
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Reverse 8 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint8_t>::value, T>::type
reverse_bits(T value)
{
value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
value = (value >> 4) | (value << 4);
return value;
}
uint8_t reverse_bits(uint8_t value);
inline int8_t reverse_bits(int8_t value) { return int8_t(reverse_bits(uint8_t(value))); }
#endif
uint16_t reverse_bits(uint16_t value);
inline int16_t reverse_bits(int16_t value) { return int16_t(reverse_bits(uint16_t(value))); }
uint32_t reverse_bits(uint32_t value);
inline int32_t reverse_bits(int32_t value) { return int32_t(reverse_bits(uint32_t(value))); }
uint64_t reverse_bits(uint64_t value);
inline int64_t reverse_bits(int64_t value) { return int64_t(reverse_bits(uint64_t(value))); }
//***************************************************************************
/// Reverse 16 bits.
/// Reverse bytes.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, T>::type
reverse_bits(T value)
{
value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
value = (value >> 8) | (value << 8);
return value;
}
//***************************************************************************
/// Reverse 32 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, T>::type
reverse_bits(T value)
{
value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
value = (value >> 16) | (value << 16);
return value;
}
//***************************************************************************
/// Reverse 64 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, T>::type
reverse_bits(T value)
{
value = ((value & 0xAAAAAAAAAAAAAAAA) >> 1) | ((value & 0x5555555555555555) << 1);
value = ((value & 0xCCCCCCCCCCCCCCCC) >> 2) | ((value & 0x3333333333333333) << 2);
value = ((value & 0xF0F0F0F0F0F0F0F0) >> 4) | ((value & 0x0F0F0F0F0F0F0F0F) << 4);
value = ((value & 0xFF00FF00FF00FF00) >> 8) | ((value & 0x00FF00FF00FF00FF) << 8);
value = ((value & 0xFFFF0000FFFF0000) >> 16) | ((value & 0x0000FFFF0000FFFF) << 16);
value = (value >> 32) | (value << 32);
return value;
}
//***************************************************************************
/// Reverse bytes 16 bit.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, T>::type
reverse_bytes(T value)
{
value = (value >> 8) | (value << 8);
return value;
}
//***************************************************************************
/// Reverse bytes 32 bit.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, T>::type
reverse_bytes(T value)
{
value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
value = (value >> 16) | (value << 16);
return value;
}
//***************************************************************************
/// Reverse bytes 64 bit.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, T>::type
reverse_bytes(T value)
{
value = ((value & 0xFF00FF00FF00FF00) >> 8) | ((value & 0x00FF00FF00FF00FF) << 8);
value = ((value & 0xFFFF0000FFFF0000) >> 16) | ((value & 0x0000FFFF0000FFFF) << 16);
value = (value >> 32) | (value << 32);
return value;
}
#if ETL_8BIT_SUPPORT
inline uint8_t reverse_bytes(uint8_t value) { return value; }
inline int8_t reverse_bytes(int8_t value) { return value; }
#endif
uint16_t reverse_bytes(uint16_t value);
inline int16_t reverse_bytes(int16_t value) { return int16_t(reverse_bytes(uint16_t(value))); }
uint32_t reverse_bytes(uint32_t value);
inline int32_t reverse_bytes(int32_t value) { return int32_t(reverse_bytes(uint32_t(value))); }
uint64_t reverse_bytes(uint64_t value);
inline int64_t reverse_bytes(int64_t value) { return int64_t(reverse_bytes(uint64_t(value))); }
//***************************************************************************
/// Converts binary to Gray code.
@ -286,201 +189,47 @@ namespace etl
return (value >> 1) ^ value;
}
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint8_t>::value, T>::type
gray_to_binary(T value)
{
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
uint8_t gray_to_binary(uint8_t value);
inline int8_t gray_to_binary(int8_t value) { return int8_t(gray_to_binary(uint8_t(value))); }
#endif
uint16_t gray_to_binary(uint16_t value);
inline int16_t gray_to_binary(int16_t value) { return int16_t(gray_to_binary(uint16_t(value))); }
uint32_t gray_to_binary(uint32_t value);
inline int32_t gray_to_binary(int32_t value) { return int32_t(gray_to_binary(uint32_t(value))); }
uint64_t gray_to_binary(uint64_t value);
inline int64_t gray_to_binary(int64_t value) { return int64_t(gray_to_binary(uint64_t(value))); }
//***************************************************************************
/// Converts Gray code to binary.
/// Count set bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, T>::type
gray_to_binary(T value)
{
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, T>::type
gray_to_binary(T value)
{
value ^= (value >> 16);
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
//***************************************************************************
/// Converts Gray code to binary.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, T>::type
gray_to_binary(T value)
{
value ^= (value >> 32);
value ^= (value >> 16);
value ^= (value >> 8);
value ^= (value >> 4);
value ^= (value >> 2);
value ^= (value >> 1);
return value;
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Count set bits. 8 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint8_t>::value, size_t>::type
count_bits(T value)
{
uint32_t count;
static const int S[] = { 1, 2, 4 };
static const uint8_t B[] = { 0x55, 0x33, 0x0F };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
return count;
}
uint_least8_t count_bits(uint8_t value);
inline uint_least8_t count_bits(int8_t value) { return count_bits(uint8_t(value)); }
#endif
uint_least8_t count_bits(uint16_t value);
inline uint_least8_t count_bits(int16_t value) { return count_bits(uint16_t(value)); }
uint_least8_t count_bits(uint32_t value);
inline uint_least8_t count_bits(int32_t value) { return count_bits(uint32_t(value)); }
uint_least8_t count_bits(uint64_t value);
inline uint_least8_t count_bits(int64_t value) { return count_bits(uint64_t(value)); }
//***************************************************************************
/// Count set bits. 16 bits.
/// Parity. 0 = even, 1 = odd
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, size_t>::type
count_bits(T value)
{
uint32_t count;
static const int S[] = { 1, 2, 4, 8 };
static const uint16_t B[] = { 0x5555, 0x3333, 0x0F0F, 0x00FF };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
count = ((count >> S[3]) + count) & B[3];
return count;
}
//***************************************************************************
/// Count set bits. 32 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, size_t>::type
count_bits(T value)
{
uint32_t count;
value = value - ((value >> 1) & 0x55555555);
value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
count = (((value + (value >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
return count;
}
//***************************************************************************
/// Count set bits. 64 bits.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, size_t>::type
count_bits(T value)
{
uint64_t count;
static const int S[] = { 1, 2, 4, 8, 16, 32 };
static const uint64_t B[] = { 0x5555555555555555, 0x3333333333333333, 0x0F0F0F0F0F0F0F0F, 0x00FF00FF00FF00FF, 0x0000FFFF0000FFFF, 0x00000000FFFFFFFF };
count = value - ((value >> 1) & B[0]);
count = ((count >> S[1]) & B[1]) + (count & B[1]);
count = ((count >> S[2]) + count) & B[2];
count = ((count >> S[3]) + count) & B[3];
count = ((count >> S[4]) + count) & B[4];
count = ((count >> S[5]) + count) & B[5];
return size_t(count);
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Parity. 8bits. 0 = even, 1 = odd
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint8_t>::value, size_t>::type
parity(T value)
{
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
uint_least8_t parity(uint8_t value);
inline uint_least8_t parity(int8_t value) { return parity(uint8_t(value)); }
#endif
//***************************************************************************
/// Parity. 16bits. 0 = even, 1 = odd
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, size_t>::type
parity(T value)
{
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
//***************************************************************************
/// Parity. 32bits. 0 = even, 1 = odd
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, size_t>::type
parity(T value)
{
value ^= value >> 16;
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x6996 >> value) & 1;
}
//***************************************************************************
/// Parity. 64bits. 0 = even, 1 = odd
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, size_t>::type
parity(T value)
{
value ^= value >> 32;
value ^= value >> 16;
value ^= value >> 8;
value ^= value >> 4;
value &= 0x0F;
return (0x69966996 >> value) & 1;
}
uint_least8_t parity(uint16_t value);
inline uint_least8_t parity(int16_t value) { return parity(uint16_t(value)); }
uint_least8_t parity(uint32_t value);
inline uint_least8_t parity(int32_t value) { return parity(uint32_t(value)); }
uint_least8_t parity(uint64_t value);
inline uint_least8_t parity(int64_t value) { return parity(uint64_t(value)); }
//***************************************************************************
/// Fold a binary number down to a set number of bits using XOR.
@ -521,15 +270,39 @@ namespace etl
STATIC_ASSERT(etl::is_signed<TReturn>::value, "TReturn not a signed type");
STATIC_ASSERT(NBITS <= std::numeric_limits<TReturn>::digits, "NBITS too large for return type");
typedef typename etl::make_unsigned<TReturn>::type mask_t;
mask_t negative = (1 << (NBITS - 1));
TReturn signed_value = value;
const TReturn negative = (TReturn(1) << (NBITS - 1));
TReturn signed_value = value & ((1 << NBITS) - 1);
if ((signed_value & negative) != 0)
{
mask_t sign_bits = ~((1 << NBITS) - 1);
signed_value = value | sign_bits;
const TReturn sign_bits = ~((TReturn(1) << NBITS) - 1);
signed_value |= sign_bits;
}
return signed_value;
}
//***************************************************************************
/// Sign extend.
/// Converts an N bit binary number, where bit N-1 is the sign bit, and SHIFT
/// is the right shift amount, to a signed integral type.
//***************************************************************************
template <typename TReturn, const size_t NBITS, const size_t SHIFT, typename TValue>
TReturn sign_extend(TValue value)
{
STATIC_ASSERT(etl::is_integral<TValue>::value, "TValue not an integral type");
STATIC_ASSERT(etl::is_integral<TReturn>::value, "TReturn not an integral type");
STATIC_ASSERT(etl::is_signed<TReturn>::value, "TReturn not a signed type");
STATIC_ASSERT(NBITS <= std::numeric_limits<TReturn>::digits, "NBITS too large for return type");
STATIC_ASSERT(SHIFT <= std::numeric_limits<TReturn>::digits, "SHIFT too large");
const TReturn negative = (TReturn(1) << (NBITS - 1));
TReturn signed_value = (value >> SHIFT) & ((1 << NBITS) - 1);
if ((signed_value & negative) != 0)
{
const TReturn sign_bits = ~((TReturn(1) << NBITS) - 1);
signed_value |= sign_bits;
}
return signed_value;
@ -547,201 +320,57 @@ namespace etl
STATIC_ASSERT(etl::is_signed<TReturn>::value, "TReturn not a signed type");
assert(NBITS <= std::numeric_limits<TReturn>::digits);
typedef typename etl::make_unsigned<TReturn>::type mask_t;
mask_t negative = (TReturn(1) << (NBITS - 1));
TReturn signed_value = value;
const TReturn negative = (TReturn(1) << (NBITS - 1));
TReturn signed_value = value & ((1 << NBITS) - 1);
if ((signed_value & negative) != 0)
{
mask_t sign_bits = ~((1 << NBITS) - 1);
signed_value = value | sign_bits;
const TReturn sign_bits = ~((TReturn(1) << NBITS) - 1);
signed_value |= sign_bits;
}
return signed_value;
}
//***************************************************************************
/// Sign extend.
/// Converts an N bit binary number, where bit N-1 is the sign bit, and SHIFT
/// is the right shift amount, to a signed integral type.
//***************************************************************************
template <typename TReturn, typename TValue>
TReturn sign_extend(TValue value, const size_t NBITS, const size_t SHIFT)
{
STATIC_ASSERT(etl::is_integral<TValue>::value, "TValue not an integral type");
STATIC_ASSERT(etl::is_integral<TReturn>::value, "TReturn not an integral type");
STATIC_ASSERT(etl::is_signed<TReturn>::value, "TReturn not a signed type");
assert(NBITS <= std::numeric_limits<TReturn>::digits);
const TReturn negative = (TReturn(1) << (NBITS - 1));
TReturn signed_value = (value >> SHIFT) & ((1 << NBITS) - 1);
if ((signed_value & negative) != 0)
{
const TReturn sign_bits = ~((TReturn(1) << NBITS) - 1);
signed_value |= sign_bits;
}
return signed_value;
}
#if ETL_8BIT_SUPPORT
//***************************************************************************
/// Count trailing zeros. bit.
/// Uses a binary search.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint8_t>::value, uint_least8_t>::type
count_trailing_zeros(T value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
#if ETL_8BIT_SUPPORT
uint_least8_t count_trailing_zeros(uint8_t value);
inline uint_least8_t count_trailing_zeros(int8_t value) { return count_trailing_zeros(uint8_t(value)); }
#endif
//***************************************************************************
/// Count trailing zeros. 16bit.
/// Uses a binary search.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint16_t>::value, uint_least8_t>::type
count_trailing_zeros(T value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
//***************************************************************************
/// Count trailing zeros. 32bit.
/// Uses a binary search.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint32_t>::value, uint_least8_t>::type
count_trailing_zeros(T value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFFFF) == 0)
{
value >>= 16;
count += 16;
}
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
//***************************************************************************
/// Count trailing zeros. 64bit.
/// Uses a binary search.
//***************************************************************************
template <typename T>
typename etl::enable_if<etl::is_same<typename etl::make_unsigned<T>::type, uint64_t>::value, uint_least8_t>::type
count_trailing_zeros(T value)
{
uint_least8_t count;
if (value & 0x1)
{
count = 0;
}
else
{
count = 1;
if ((value & 0xFFFFFFFF) == 0)
{
value >>= 32;
count += 32;
}
if ((value & 0xFFFF) == 0)
{
value >>= 16;
count += 16;
}
if ((value & 0xFF) == 0)
{
value >>= 8;
count += 8;
}
if ((value & 0xF) == 0)
{
value >>= 4;
count += 4;
}
if ((value & 0x3) == 0)
{
value >>= 2;
count += 2;
}
count -= value & 0x1;
}
return count;
}
uint_least8_t count_trailing_zeros(uint16_t value);
inline uint_least8_t count_trailing_zeros(int16_t value) { return count_trailing_zeros(uint16_t(value)); }
uint_least8_t count_trailing_zeros(uint32_t value);
inline uint_least8_t count_trailing_zeros(int32_t value) { return count_trailing_zeros(uint32_t(value)); }
uint_least8_t count_trailing_zeros(uint64_t value);
inline uint_least8_t count_trailing_zeros(int64_t value) { return count_trailing_zeros(uint64_t(value)); }
//***************************************************************************
/// Find the position of the first set bit.
@ -750,7 +379,7 @@ namespace etl
template <typename T>
uint_least8_t first_set_bit_position(T value)
{
return count_trailing_zeros(value);
return count_trailing_zeros(value);
}
//***************************************************************************
@ -760,8 +389,8 @@ namespace etl
template <typename T>
uint_least8_t first_clear_bit_position(T value)
{
value = ~value;
return count_trailing_zeros(value);
value = ~value;
return count_trailing_zeros(value);
}
//***************************************************************************
@ -771,14 +400,28 @@ namespace etl
template <typename T>
uint_least8_t first_bit_position(bool state, T value)
{
if (!state)
{
value = ~value;
}
if (!state)
{
value = ~value;
}
return count_trailing_zeros(value);
return count_trailing_zeros(value);
}
//***************************************************************************
/// Gets the value of the bit at POSITION
/// Starts from LSB.
//***************************************************************************
template <const size_t POSITION>
struct bit
{
typedef typename etl::smallest_uint_for_bits<POSITION + 1>::type value_type;
static const value_type value = value_type(1) << POSITION;
};
template <const size_t POSITION>
const typename bit<POSITION>::value_type bit<POSITION>::value;
//***************************************************************************
/// 8 bit binary constants.
//***************************************************************************
@ -1041,6 +684,42 @@ namespace etl
b11111110 = 254,
b11111111 = 255
};
enum bit_constant
{
b0 = 0x1,
b1 = 0x2,
b2 = 0x4,
b3 = 0x8,
b4 = 0x10,
b5 = 0x20,
b6 = 0x40,
b7 = 0x80,
b8 = 0x100,
b9 = 0x200,
b10 = 0x400,
b11 = 0x800,
b12 = 0x1000,
b13 = 0x2000,
b14 = 0x4000,
b15 = 0x8000,
b16 = 0x10000,
b17 = 0x20000,
b18 = 0x40000,
b19 = 0x80000,
b20 = 0x100000,
b21 = 0x200000,
b22 = 0x400000,
b23 = 0x800000,
b24 = 0x1000000,
b25 = 0x2000000,
b26 = 0x4000000,
b27 = 0x8000000,
b28 = 0x10000000,
b29 = 0x20000000,
b30 = 0x40000000,
b31 = 0x80000000
};
}
#endif

View File

@ -195,8 +195,8 @@ namespace etl
{
size_t operator()(const etl::istring& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
@ -205,8 +205,8 @@ namespace etl
{
size_t operator()(const etl::string<SIZE>& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
#endif

View File

@ -93,6 +93,11 @@ namespace etl
return count;
}
inline void clear()
{
count = 0;
}
private:
int32_t count;
@ -129,6 +134,11 @@ namespace etl
{
return 0;
}
inline void clear()
{
}
#endif
};
}

View File

@ -30,6 +30,7 @@ SOFTWARE.
#define __ETL_FACTORY__
#include <stdint.h>
#include <utility>
#include "platform.h"
#include "error_handler.h"
@ -39,6 +40,13 @@ SOFTWARE.
#include "alignment.h"
#include "static_assert.h"
#include "type_lookup.h"
#include <pool.h>
#if defined(ETL_COMPILER_GCC)
#warning THIS CLASS IS DEPRECATED!USE VARIANT_POOL INSTEAD.
#elif defined(ETL_COMPILER_MICROSOFT)
#pragma message ("THIS CLASS IS DEPRECATED! USE VARIANT_POOL INSTEAD.")
#endif
#undef ETL_FILE
#define ETL_FILE "40"
@ -81,21 +89,21 @@ namespace etl
//***************************************************************************
template <const size_t MAX_SIZE_,
typename T1,
typename T2 = etl::type_id_pair<>,
typename T3 = etl::type_id_pair<>,
typename T4 = etl::type_id_pair<>,
typename T5 = etl::type_id_pair<>,
typename T6 = etl::type_id_pair<>,
typename T7 = etl::type_id_pair<>,
typename T8 = etl::type_id_pair<>,
typename T9 = etl::type_id_pair<>,
typename T10 = etl::type_id_pair<>,
typename T11 = etl::type_id_pair<>,
typename T12 = etl::type_id_pair<>,
typename T13 = etl::type_id_pair<>,
typename T14 = etl::type_id_pair<>,
typename T15 = etl::type_id_pair<>,
typename T16 = etl::type_id_pair<>>
typename T2 = etl::type_id_pair<etl::null_type, -2>,
typename T3 = etl::type_id_pair<etl::null_type, -3>,
typename T4 = etl::type_id_pair<etl::null_type, -4>,
typename T5 = etl::type_id_pair<etl::null_type, -5>,
typename T6 = etl::type_id_pair<etl::null_type, -6>,
typename T7 = etl::type_id_pair<etl::null_type, -7>,
typename T8 = etl::type_id_pair<etl::null_type, -8>,
typename T9 = etl::type_id_pair<etl::null_type, -9>,
typename T10 = etl::type_id_pair<etl::null_type, -10>,
typename T11 = etl::type_id_pair<etl::null_type, -11>,
typename T12 = etl::type_id_pair<etl::null_type, -12>,
typename T13 = etl::type_id_pair<etl::null_type, -13>,
typename T14 = etl::type_id_pair<etl::null_type, -14>,
typename T15 = etl::type_id_pair<etl::null_type, -15>,
typename T16 = etl::type_id_pair<etl::null_type, -16> >
class factory
{
private:
@ -125,15 +133,13 @@ namespace etl
static const size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
/// Constructor
/// Default constructor.
//*************************************************************************
factory()
: p_next(reinterpret_cast<char*>(&buffer[0])),
items_allocated(0),
items_initialised(0)
{
}
#if !ETL_CPP11_SUPPORTED
//*************************************************************************
/// Creates the object. Default constructor.
//*************************************************************************
@ -142,11 +148,20 @@ namespace etl
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = reinterpret_cast<T*>(allocate_item());
T* p = nullptr;
if (p != nullptr)
if (pool.full())
{
new (p) T();
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T();
}
}
return p;
@ -160,11 +175,20 @@ namespace etl
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = reinterpret_cast<T*>(allocate_item());
T* p = nullptr;
if (p != nullptr)
if (pool.full())
{
new (p) T(p1);
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1);
}
}
return p;
@ -178,11 +202,20 @@ namespace etl
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = reinterpret_cast<T*>(allocate_item());
T* p = nullptr;
if (p != nullptr)
if (pool.full())
{
new (p) T(p1, p2);
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2);
}
}
return p;
@ -196,11 +229,20 @@ namespace etl
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = reinterpret_cast<T*>(allocate_item());
T* p = nullptr;
if (p != nullptr)
if (pool.full())
{
new (p) T(p1, p2, p3);
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2, p3);
}
}
return p;
@ -214,11 +256,20 @@ namespace etl
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = reinterpret_cast<T*>(allocate_item());
T* p = nullptr;
if (p != nullptr)
if (pool.full())
{
new (p) T(p1, p2, p3, p4);
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2, p3, p4);
}
}
return p;
@ -278,6 +329,45 @@ namespace etl
STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
return create_from_type<type>(p1, p2, p3, p4);
}
#else
//*************************************************************************
/// Creates the object from a type. Variadic parameter constructor.
//*************************************************************************
template <typename T, typename... Args>
T* create_from_type(Args&&... args)
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(std::forward<Args>(args)...);
}
}
return p;
}
//*************************************************************************
/// Creates the object from an index. Variadic parameter constructor.
//*************************************************************************
template <size_t ID, typename... Args>
typename lookup_t::template type_from_id<ID>::type* create_from_id(Args&&... args)
{
typedef typename lookup_t::template type_from_id<ID>::type type;
STATIC_ASSERT((!etl::is_same<void, type>::value), "Invalid index");
return create_from_type<type>(std::forward<Args>(args)...);
}
#endif
//*************************************************************************
/// Destroys the object.
@ -286,26 +376,37 @@ namespace etl
bool destroy(const T* const p)
{
STATIC_ASSERT((etl::is_one_of<T, TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::value ||
etl::is_base_of<T, TT1>::value ||
etl::is_base_of<T, TT2>::value ||
etl::is_base_of<T, TT3>::value ||
etl::is_base_of<T, TT1>::value ||
etl::is_base_of<T, TT2>::value ||
etl::is_base_of<T, TT3>::value ||
etl::is_base_of<T, TT4>::value ||
etl::is_base_of<T, TT5>::value ||
etl::is_base_of<T, TT6>::value ||
etl::is_base_of<T, TT7>::value ||
etl::is_base_of<T, TT8>::value ||
etl::is_base_of<T, TT9>::value ||
etl::is_base_of<T, TT10>::value ||
etl::is_base_of<T, TT11>::value ||
etl::is_base_of<T, TT12>::value ||
etl::is_base_of<T, TT13>::value ||
etl::is_base_of<T, TT14>::value ||
etl::is_base_of<T, TT15>::value ||
etl::is_base_of<T, TT5>::value ||
etl::is_base_of<T, TT6>::value ||
etl::is_base_of<T, TT7>::value ||
etl::is_base_of<T, TT8>::value ||
etl::is_base_of<T, TT9>::value ||
etl::is_base_of<T, TT10>::value ||
etl::is_base_of<T, TT11>::value ||
etl::is_base_of<T, TT12>::value ||
etl::is_base_of<T, TT13>::value ||
etl::is_base_of<T, TT14>::value ||
etl::is_base_of<T, TT15>::value ||
etl::is_base_of<T, TT16>::value), "Invalid type");
p->~T();
return release_item(reinterpret_cast<char*>(const_cast<T*>(p)));
void* vp = reinterpret_cast<char*>(const_cast<T*>(p));
if (pool.is_in_pool(vp))
{
pool.release(vp);
return true;
}
else
{
ETL_ASSERT(false, ETL_ERROR(factory_did_not_create));
return false;
}
}
//*************************************************************************
@ -321,7 +422,7 @@ namespace etl
//*************************************************************************
size_t available() const
{
return MAX_SIZE - items_allocated;
return pool.available();
}
//*************************************************************************
@ -329,7 +430,7 @@ namespace etl
//*************************************************************************
size_t size() const
{
return items_allocated;
return pool.size();
}
//*************************************************************************
@ -338,7 +439,7 @@ namespace etl
//*************************************************************************
bool empty() const
{
return items_allocated == 0;
return pool.empty();
}
//*************************************************************************
@ -347,7 +448,7 @@ namespace etl
//*************************************************************************
bool full() const
{
return items_allocated == MAX_SIZE;;
return pool.full();
}
private:
@ -355,121 +456,10 @@ namespace etl
factory(const factory&);
factory& operator =(const factory&);
//*************************************************************************
/// Allocate an item from the pool.
//*************************************************************************
char* allocate_item()
{
char* p_value = nullptr;
// Any free space left?
if (items_allocated < MAX_SIZE)
{
// Initialise another one if necessary.
if (items_initialised < MAX_SIZE)
{
uintptr_t p = reinterpret_cast<uintptr_t>(reinterpret_cast<char*>(&buffer[0]) + (items_initialised * ITEM_SIZE));
*reinterpret_cast<uintptr_t*>(p) = p + ITEM_SIZE;
++items_initialised;
}
// Get the address of new allocated item.
p_value = p_next;
++items_allocated;
if (items_allocated != MAX_SIZE)
{
// Set up the pointer to the next free item
p_next = *reinterpret_cast<char**>(p_next);
}
else
{
// No more left!
p_next = nullptr;
}
}
else
{
ETL_ASSERT(false, ETL_ERROR(etl::factory_cannot_create));
}
return p_value;
}
//*************************************************************************
/// Release an item back to the pool.
//*************************************************************************
bool release_item(char* p_value)
{
if (is_item_in_pool(p_value))
{
if (p_next != nullptr)
{
// Point it to the current free item.
*(uintptr_t*)p_value = reinterpret_cast<uintptr_t>(p_next);
}
else
{
// This is the only free item.
*((uintptr_t*)p_value) = 0;
}
p_next = p_value;
--items_allocated;
return true;
}
else
{
ETL_ASSERT(false, ETL_ERROR(factory_did_not_create));
}
return false;
}
//*************************************************************************
/// Check if the item belongs to this pool.
//*************************************************************************
bool is_item_in_pool(char* p) const
{
if (empty() || (p == nullptr))
{
return false;
}
// Within the range of the buffer?
intptr_t distance = p - reinterpret_cast<const char*>(&buffer[0]);
bool is_within_range = (distance >= 0) && (distance <= intptr_t((ITEM_SIZE * MAX_SIZE) - ITEM_SIZE));
// Modulus and division can be slow on some architectures, so only do this in debug.
#if defined(ETL_DEBUG)
// Is the address on a valid object boundary?
bool is_valid_address = ((distance % ITEM_SIZE) == 0);
#else
bool is_valid_address = true;
#endif
return is_within_range && is_valid_address;
}
// The pool element.
union Element
{
uintptr_t next; ///< Pointer to the next free element.
char value[etl::largest<TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::size]; ///< Storage for value type.
typename etl::type_with_alignment<etl::largest<TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::alignment>::type dummy; ///< Dummy item to get correct alignment.
};
///< The memory for the pool of objects.
typename etl::aligned_storage<sizeof(Element), etl::alignment_of<Element>::value>::type buffer[MAX_SIZE];
static const uint32_t ITEM_SIZE = sizeof(Element);
char* p_next;
uint32_t items_allocated; ///< The number of items allocated.
uint32_t items_initialised; ///< The number of items initialised.
// The pool.
etl::generic_pool<etl::largest<TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::size,
etl::largest<TT1, TT2, TT3, TT4, TT5, TT6, TT7, TT8, TT9, TT10, TT11, TT12, TT13, TT14, TT15, TT16>::alignment,
MAX_SIZE> pool;
};
}

View File

@ -37,4 +37,4 @@
37 task
38 message
39 message_bus
40 factory
40 factory / variant_pool

View File

@ -28,8 +28,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_LIST__
#define __ETL_LIST__
#ifndef __ETL_FORWARD_LIST__
#define __ETL_FORWARD_LIST__
#include <iterator>
#include <algorithm>

129
src/fsm.h
View File

@ -324,7 +324,7 @@ namespace etl
/// Does this FSM accept the message id?
/// Yes, it accepts everything!
//*******************************************
bool accepts(etl::message_id_t) const
bool accepts(etl::message_id_t id) const
{
return true;
}
@ -383,10 +383,10 @@ namespace etl
//***************************************************************************
// The definition for all 16 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1 = void, 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,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1 = void, 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>
class fsm_state : public ifsm_state
{
@ -402,6 +402,8 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
@ -442,10 +444,10 @@ namespace etl
//***************************************************************************
// Specialisation for 15 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13, typename T14, typename T15>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, void> : public ifsm_state
{
@ -461,10 +463,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -499,10 +504,10 @@ namespace etl
//***************************************************************************
// Specialisation for 14 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13, typename T14>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, void, void> : public ifsm_state
{
@ -518,10 +523,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -555,10 +563,10 @@ namespace etl
//***************************************************************************
// Specialisation for 13 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, void, void, void> : public ifsm_state
{
@ -574,10 +582,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -610,9 +621,9 @@ namespace etl
//***************************************************************************
// Specialisation for 12 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, void, void, void, void> : public ifsm_state
{
@ -628,10 +639,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -663,9 +677,9 @@ namespace etl
//***************************************************************************
// Specialisation for 11 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, void, void, void, void, void> : public ifsm_state
{
@ -681,10 +695,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -715,9 +732,9 @@ namespace etl
//***************************************************************************
// Specialisation for 10 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, void, void, void, void, void, void> : public ifsm_state
{
@ -733,10 +750,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -766,9 +786,9 @@ namespace etl
//***************************************************************************
// Specialisation for 9 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, T9, void, void, void, void, void, void, void> : public ifsm_state
{
@ -784,10 +804,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -816,8 +839,8 @@ namespace etl
//***************************************************************************
// Specialisation for 8 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, T8, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -833,10 +856,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -864,8 +890,8 @@ namespace etl
//***************************************************************************
// Specialisation for 7 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, T7, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -881,10 +907,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -911,8 +940,8 @@ namespace etl
//***************************************************************************
// Specialisation for 6 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, T6, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -928,10 +957,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -957,8 +989,8 @@ namespace etl
//***************************************************************************
// Specialisation for 5 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, T5, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -974,10 +1006,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -1002,7 +1037,7 @@ namespace etl
//***************************************************************************
// Specialisation for 4 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, T4, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -1018,10 +1053,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -1045,7 +1083,7 @@ namespace etl
//***************************************************************************
// Specialisation for 3 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, T3, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -1061,10 +1099,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -1087,7 +1128,7 @@ namespace etl
//***************************************************************************
// Specialisation for 2 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2>
class fsm_state<TContext, TDerived, STATE_ID_, T1, T2, void, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -1103,10 +1144,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)
@ -1128,7 +1172,7 @@ namespace etl
//***************************************************************************
// Specialisation for 1 message type.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1>
class fsm_state<TContext, TDerived, STATE_ID_, T1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void> : public ifsm_state
{
@ -1144,10 +1188,13 @@ namespace etl
{
}
protected:
inline TContext& get_fsm_context() const
{
return static_cast<TContext&>(ifsm_state::get_fsm_context());
}
private:
etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)

View File

@ -422,6 +422,8 @@ namespace etl
cog.outl(" {")
cog.outl(" }")
cog.outl("")
cog.outl("protected:")
cog.outl("")
cog.outl(" inline TContext& get_fsm_context() const")
cog.outl(" {")
cog.outl(" return static_cast<TContext&>(ifsm_state::get_fsm_context());")
@ -493,10 +495,13 @@ namespace etl
cog.outl(" {")
cog.outl(" }")
cog.outl("")
cog.outl("protected:")
cog.outl("")
cog.outl(" inline TContext& get_fsm_context() const")
cog.outl(" {")
cog.outl(" return static_cast<TContext&>(ifsm_state::get_fsm_context());")
cog.outl(" }")
cog.outl("")
cog.outl("private:")
cog.outl("")
cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)")

View File

@ -336,11 +336,6 @@ namespace etl
typedef TObject object_type; ///< The type of object.
typedef void parameter_type; ///< The type of parameter sent to the function.
//*************************************************************************
/// Constructor.
///\param object Reference to the object
//*************************************************************************
//*************************************************************************
/// The function operator that calls the destination function.
///\param data The data to pass to the function.

View File

@ -52,7 +52,7 @@ namespace etl
/// Hash to use when size_t is 16 bits.
/// T is always expected to be size_t.
//*************************************************************************
template <typename T = size_t>
template <typename T>
typename enable_if<sizeof(T) == sizeof(uint16_t), size_t>::type
generic_hash(const uint8_t* begin, const uint8_t* end)
{
@ -65,7 +65,7 @@ namespace etl
/// Hash to use when size_t is 32 bits.
/// T is always expected to be size_t.
//*************************************************************************
template <typename T = size_t>
template <typename T>
typename enable_if<sizeof(T) == sizeof(uint32_t), size_t>::type
generic_hash(const uint8_t* begin, const uint8_t* end)
{
@ -76,7 +76,7 @@ namespace etl
/// Hash to use when size_t is 64 bits.
/// T is always expected to be size_t.
//*************************************************************************
template <typename T = size_t>
template <typename T>
typename enable_if<sizeof(T) == sizeof(uint64_t), size_t>::type
generic_hash(const uint8_t* begin, const uint8_t* end)
{

View File

@ -133,6 +133,18 @@ namespace etl
successor = &successor_;
}
//********************************************
imessage_router& get_successor() const
{
return *successor;
}
//********************************************
bool has_successor() const
{
return (successor != nullptr);
}
enum
{
NULL_MESSAGE_ROUTER = 255,
@ -156,14 +168,14 @@ namespace etl
{
}
etl::imessage_router* successor;
private:
// Disabled.
imessage_router(const imessage_router&);
imessage_router& operator =(const imessage_router&);
etl::imessage_router* successor;
etl::message_router_id_t message_router_id;
};
@ -354,9 +366,9 @@ namespace etl
case T16::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T16&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -512,9 +524,9 @@ namespace etl
case T15::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T15&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -668,9 +680,9 @@ namespace etl
case T14::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T14&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -822,9 +834,9 @@ namespace etl
case T13::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T13&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -973,9 +985,9 @@ namespace etl
case T12::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1122,9 +1134,9 @@ namespace etl
case T11::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1269,9 +1281,9 @@ namespace etl
case T10::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1414,9 +1426,9 @@ namespace etl
case T9::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1556,9 +1568,9 @@ namespace etl
case T8::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1696,9 +1708,9 @@ namespace etl
case T7::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1833,9 +1845,9 @@ namespace etl
case T6::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -1968,9 +1980,9 @@ namespace etl
case T5::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -2100,9 +2112,9 @@ namespace etl
case T4::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -2230,9 +2242,9 @@ namespace etl
case T3::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -2358,9 +2370,9 @@ namespace etl
case T2::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{
@ -2484,9 +2496,9 @@ namespace etl
case T1::ID: static_cast<TDerived*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
default:
{
if (successor != nullptr)
if (has_successor())
{
successor->receive(source, msg);
get_successor().receive(source, msg);
}
else
{

View File

@ -145,6 +145,18 @@ namespace etl
successor = &successor_;
}
//********************************************
imessage_router& get_successor() const
{
return *successor;
}
//********************************************
bool has_successor() const
{
return (successor != nullptr);
}
enum
{
NULL_MESSAGE_ROUTER = 255,
@ -168,14 +180,14 @@ namespace etl
{
}
etl::imessage_router* successor;
private:
// Disabled.
imessage_router(const imessage_router&);
imessage_router& operator =(const imessage_router&);
etl::imessage_router* successor;
etl::message_router_id_t message_router_id;
};
@ -362,9 +374,9 @@ namespace etl
cog.outl(" break;")
cog.outl(" default:")
cog.outl(" {")
cog.outl(" if (successor != nullptr)")
cog.outl(" if (has_successor())")
cog.outl(" {")
cog.outl(" successor->receive(source, msg);")
cog.outl(" get_successor().receive(source, msg);")
cog.outl(" }")
cog.outl(" else")
cog.outl(" {")
@ -534,9 +546,9 @@ namespace etl
cog.outl(" break;")
cog.outl(" default:")
cog.outl(" {")
cog.outl(" if (successor != nullptr)")
cog.outl(" if (has_successor())")
cog.outl(" {")
cog.outl(" successor->receive(source, msg);")
cog.outl(" get_successor().receive(source, msg);")
cog.outl(" }")
cog.outl(" else")
cog.outl(" {")

View File

@ -178,9 +178,12 @@ namespace etl
protected:
static const uint_least8_t kLeft = 0;
static const uint_least8_t kRight = 1;
static const uint_least8_t kNeither = 2;
enum
{
kLeft,
kRight,
kNeither
};
//*************************************************************************
/// The node element in the multimap.

View File

@ -178,9 +178,12 @@ namespace etl
protected:
static const uint_least8_t kLeft = 0;
static const uint_least8_t kRight = 1;
static const uint_least8_t kNeither = 2;
enum
{
kLeft,
kRight,
kNeither
};
//*************************************************************************
/// The node element in the multiset.

View File

@ -40,7 +40,7 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
/// Calculates the smallest value that, when squared, will be greater than or equal to VALUE.
/// Calculates the smallest value that, when squared, will be not greater than VALUE.
//***************************************************************************
template <const size_t VALUE, const size_t I = 1>
struct sqrt

View File

@ -64,7 +64,7 @@ namespace etl
}
//*********************************************************************
explicit type_def(TValue value_)
type_def(TValue value_)
: value(value_)
{
}
@ -237,11 +237,18 @@ namespace etl
return *this;
}
//*********************************************************************
type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
value = rhs.value;
return *this;
}
//*********************************************************************

File diff suppressed because it is too large Load Diff

View File

@ -60,15 +60,12 @@ cog.outl("//********************************************************************
namespace etl
{
namespace __private_type_lookup__
{
struct null_type {};
}
struct null_type {};
//***************************************************************************
/// The type/id pair type to use for type/id lookup template parameters.
//***************************************************************************
template <typename T = __private_type_lookup__::null_type, size_t ID_ = 0>
template <typename T, int ID_>
struct type_id_pair
{
typedef T type;
@ -82,7 +79,7 @@ namespace etl
//***************************************************************************
/// The type/type pair type to use for type/type lookup template parameters.
//***************************************************************************
template <typename T1 = __private_type_lookup__::null_type, typename T2 = __private_type_lookup__::null_type>
template <typename T1, typename T2>
struct type_type_pair
{
typedef T1 type1;
@ -92,28 +89,24 @@ namespace etl
/*[[[cog
import cog
cog.outl("//***************************************************************************")
cog.outl("// Default for %s types." % int(NTypes))
cog.outl("// For %s types." % int(NTypes))
cog.outl("//***************************************************************************")
cog.outl("template <typename T1,")
for n in range(2, int(NTypes)):
cog.outl(" typename T%s = etl::type_id_pair<>," %n)
cog.outl(" typename T%s = etl::type_id_pair<> >" %NTypes)
cog.outl(" typename T%s = etl::type_id_pair<etl::null_type, -%s>," %(n, n))
cog.outl(" typename T%s = etl::type_id_pair<etl::null_type, -%s> >" %(NTypes, NTypes))
cog.outl("struct type_id_lookup")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" typedef __private_type_lookup__::null_type null_type;")
cog.outl("")
cog.outl("public:")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" template <size_t ID>")
cog.outl(" template <int ID>")
cog.outl(" struct type_from_id")
cog.outl(" {")
cog.outl(" typedef ")
for n in range(1, int(NTypes) + 1):
cog.outl(" typename etl::conditional<ID == T%s::ID, typename T%s::type," %(n, n))
cog.out(" null_type>")
cog.out(" etl::null_type>")
for n in range(1, int(NTypes) + 1):
if n == int(NTypes):
cog.outl("::type type;")
@ -122,9 +115,9 @@ namespace etl
if n % 4 == 0:
if n != int(NTypes):
cog.outl("")
cog.out(" ")
cog.out(" ")
cog.outl("")
cog.outl(" STATIC_ASSERT(!(etl::is_same<null_type, type>::value), \"Invalid id\");")
cog.outl(" STATIC_ASSERT(!(etl::is_same<etl::null_type, type>::value), \"Invalid id\");")
cog.outl(" };")
cog.outl("")
cog.outl(" //************************************")
@ -161,108 +154,16 @@ namespace etl
cog.outl(" return id_from_type<T>::value;")
cog.outl(" }")
cog.outl("};")
for n in range(int(NTypes) - 1, 0, -1):
cog.outl("")
cog.outl("//***************************************************************************")
if n == 1:
cog.outl("// Specialisation for %d type." % n)
else:
cog.outl("// Specialisation for %d types." % n)
cog.outl("//***************************************************************************")
cog.out("template <")
for t in range(1, n + 1):
cog.out("typename T%s" %t)
if t == n:
cog.outl(">")
else:
cog.outl(",")
cog.out(" ")
cog.out("struct type_id_lookup<")
for t in range(1, n + 1):
cog.out("T%s, " %t)
if t % 4 == 0:
cog.outl("")
cog.out(" ")
for t in range(n, int(NTypes) - 1):
cog.out("etl::type_id_pair<>, ")
if t % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("etl::type_id_pair<> >")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" typedef __private_type_lookup__::null_type null_type;")
cog.outl("")
cog.outl("public:")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" template <size_t ID>")
cog.outl(" struct type_from_id")
cog.outl(" {")
cog.outl(" typedef ")
for t in range(1, n + 1):
cog.outl(" typename etl::conditional<ID == T%s::ID, typename T%s::type," %(t, t))
cog.out(" null_type>")
for t in range(1, n + 1):
if t == n:
cog.outl("::type type;")
else:
cog.out("::type>")
if t % 8 == 0:
cog.outl("")
cog.out(" ")
cog.outl("")
cog.outl(" STATIC_ASSERT(!(etl::is_same<null_type, type>::value), \"Invalid id\");")
cog.outl(" };")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" enum")
cog.outl(" {")
cog.outl(" UNKNOWN = UINT_MAX")
cog.outl(" };")
cog.outl("")
cog.outl(" template <typename T>")
cog.outl(" struct id_from_type")
cog.outl(" {")
cog.outl(" enum")
cog.outl(" {")
cog.outl(" value =")
for t in range(1, n + 1) :
cog.outl(" (unsigned int) etl::is_same<T, typename T%s::type>::value ? T%s::ID :" % (t, t))
cog.outl(" (unsigned int) UNKNOWN")
cog.outl(" };")
cog.outl("")
cog.outl(" STATIC_ASSERT(((unsigned int)value != (unsigned int)UNKNOWN), \"Invalid type\");")
cog.outl(" };")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" template <typename T>")
cog.outl(" static unsigned int get_id_from_type(const T&)")
cog.outl(" {")
cog.outl(" return get_id_from_type<T>();")
cog.outl(" }")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" template <typename T>")
cog.outl(" static unsigned int get_id_from_type()")
cog.outl(" {")
cog.outl(" return id_from_type<T>::value;")
cog.outl(" }")
cog.outl("};")
cog.outl("")
cog.outl("//***************************************************************************")
cog.outl("// Default for %s types." % int(NTypes))
cog.outl("// For %s types." % int(NTypes))
cog.outl("//***************************************************************************")
cog.outl("template <typename T1,")
for n in range(2, int(NTypes)):
cog.outl(" typename T%s = etl::type_type_pair<>," %n)
cog.outl(" typename T%s = etl::type_type_pair<> >" %NTypes)
cog.outl(" typename T%s = etl::type_type_pair<etl::null_type, etl::null_type>," %n)
cog.outl(" typename T%s = etl::type_type_pair<etl::null_type, etl::null_type> >" %NTypes)
cog.outl("struct type_type_lookup")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" typedef __private_type_lookup__::null_type null_type;")
cog.outl("")
cog.outl("public:")
cog.outl("")
cog.outl(" //************************************")
@ -272,7 +173,7 @@ namespace etl
cog.outl(" typedef ")
for n in range(1, int(NTypes) + 1):
cog.outl(" typename etl::conditional<etl::is_same<T, typename T%s::type1>::value, typename T%s::type2," %(n, n))
cog.out(" null_type>")
cog.out(" etl::null_type>")
for n in range(1, int(NTypes) + 1):
if n == int(NTypes):
cog.outl("::type type;")
@ -281,66 +182,11 @@ namespace etl
if n % 8 == 0:
if n != int(NTypes):
cog.outl("")
cog.out(" ")
cog.out(" ")
cog.outl("")
cog.outl(" STATIC_ASSERT(!(etl::is_same<null_type, type>::value), \"Invalid type\");")
cog.outl(" STATIC_ASSERT(!(etl::is_same<etl::null_type, type>::value), \"Invalid type\");")
cog.outl(" };")
cog.outl("};")
for n in range(int(NTypes) - 1, 0, -1):
cog.outl("")
cog.outl("//***************************************************************************")
if n == 1:
cog.outl("// Specialisation for %d type." % n)
else:
cog.outl("// Specialisation for %d types." % n)
cog.outl("//***************************************************************************")
cog.out("template <")
for t in range(1, n + 1):
cog.out("typename T%s" %t)
if t == n:
cog.outl(">")
else:
cog.outl(",")
cog.out(" ")
cog.out("struct type_type_lookup<")
for t in range(1, n + 1):
cog.out("T%s, " %t)
if t % 4 == 0:
cog.outl("")
cog.out(" ")
for t in range(n, int(NTypes) - 1):
cog.out("etl::type_type_pair<>, ")
if t % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("etl::type_type_pair<> >")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" typedef __private_type_lookup__::null_type null_type;")
cog.outl("")
cog.outl("public:")
cog.outl("")
cog.outl(" //************************************")
cog.outl(" template <typename T>")
cog.outl(" struct type_from_type")
cog.outl(" {")
cog.outl(" typedef ")
for t in range(1, n + 1):
cog.outl(" typename etl::conditional<etl::is_same<T, typename T%s::type1>::value, typename T%s::type2," %(t, t))
cog.out(" null_type>")
for t in range(1, n + 1):
if t == n:
cog.outl("::type type;")
else:
cog.out("::type>")
if t % 8 == 0:
cog.outl("")
cog.out(" ")
cog.outl("")
cog.outl(" STATIC_ASSERT(!(etl::is_same<null_type, type>::value), \"Invalid type\");")
cog.outl(" };")
cog.outl("};")
]]]*/
/*[[[end]]]*/
}

View File

@ -54,6 +54,7 @@ SOFTWARE.
#define __ETL_TYPE_TRAITS__
#include <stddef.h>
#include <stdint.h>
#include "platform.h"
#include "nullptr.h"
@ -334,7 +335,7 @@ namespace etl
struct conditional_integral_constant<false, T, TRUE_VALUE, FALSE_VALUE>
{
STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
static const T value = FALSE_VALUE;
static const T value = FALSE_VALUE;
};
/// make_signed
@ -484,14 +485,14 @@ namespace etl
///\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 ||

View File

@ -66,6 +66,7 @@ cog.outl("//********************************************************************
#define __ETL_TYPE_TRAITS__
#include <stddef.h>
#include <stdint.h>
#include "platform.h"
#include "nullptr.h"
@ -333,7 +334,10 @@ namespace etl
/// conditional_integral_constant
///\ingroup type_traits
template <bool B, typename T, T TRUE_VALUE, T FALSE_VALUE>
struct conditional_integral_constant
struct conditional_integral_constant;
template <typename T, T TRUE_VALUE, T FALSE_VALUE>
struct conditional_integral_constant<true, T, TRUE_VALUE, FALSE_VALUE>
{
STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
static const T value = TRUE_VALUE;

View File

@ -199,8 +199,8 @@ namespace etl
{
size_t operator()(const etl::iu16string& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
@ -209,8 +209,8 @@ namespace etl
{
size_t operator()(const etl::u16string<SIZE>& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
#endif

View File

@ -199,8 +199,8 @@ namespace etl
{
size_t operator()(const etl::iu32string& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
@ -209,8 +209,8 @@ namespace etl
{
size_t operator()(const etl::u32string<SIZE>& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
#endif

374
src/variant_pool.h Normal file
View File

@ -0,0 +1,374 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2017 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_VARIANT_POOL__
#define __ETL_VARIANT_POOL__
#include <stdint.h>
#include <utility>
#include "platform.h"
#include "error_handler.h"
#include "exception.h"
#include "largest.h"
#include "type_traits.h"
#include "alignment.h"
#include "static_assert.h"
#include "type_lookup.h"
#include <pool.h>
#undef ETL_FILE
#define ETL_FILE "40"
namespace etl
{
//***************************************************************************
class variant_pool_exception : public etl::exception
{
public:
variant_pool_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
class variant_pool_cannot_create : public etl::variant_pool_exception
{
public:
variant_pool_cannot_create(string_type file_name_, numeric_type line_number_)
: variant_pool_exception(ETL_ERROR_TEXT("variant_pool:cannot create", ETL_FILE"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
class variant_pool_did_not_create : public etl::variant_pool_exception
{
public:
variant_pool_did_not_create(string_type file_name_, numeric_type line_number_)
: variant_pool_exception(ETL_ERROR_TEXT("variant_pool:did not create", ETL_FILE"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
template <const size_t MAX_SIZE_,
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>
class variant_pool
{
public:
static const size_t MAX_SIZE = MAX_SIZE_;
//*************************************************************************
/// Default constructor.
//*************************************************************************
variant_pool()
{
}
#if !ETL_CPP11_SUPPORTED
//*************************************************************************
/// Creates the object. Default constructor.
//*************************************************************************
template <typename T>
T* create()
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T();
}
}
return p;
}
//*************************************************************************
/// Creates the object. One parameter constructor.
//*************************************************************************
template <typename T, typename TP1>
T* create(const TP1& p1)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1);
}
}
return p;
}
//*************************************************************************
/// Creates the object. Two parameter constructor.
//*************************************************************************
template <typename T, typename TP1, typename TP2>
T* create(const TP1& p1, const TP2& p2)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2);
}
}
return p;
}
//*************************************************************************
/// Creates the object. Three parameter constructor.
//*************************************************************************
template <typename T, typename TP1, typename TP2, typename TP3>
T* create(const TP1& p1, const TP2& p2, const TP3& p3)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2, p3);
}
}
return p;
}
//*************************************************************************
/// Creates the object. Four parameter constructor.
//*************************************************************************
template <typename T, typename TP1, typename TP2, typename TP3, typename TP4>
T* create(const TP1& p1, const TP2& p2, const TP3& p3, const TP4& p4)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(p1, p2, p3, p4);
}
}
return p;
}
#else
//*************************************************************************
/// Creates the object from a type. Variadic parameter constructor.
//*************************************************************************
template <typename T, typename... Args>
T* create(Args&&... args)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value), "Unsupported type");
T* p = nullptr;
if (pool.full())
{
ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create));
}
else
{
p = pool.template allocate<T>();
if (p != nullptr)
{
new (p) T(std::forward<Args>(args)...);
}
}
return p;
}
#endif
//*************************************************************************
/// Destroys the object.
//*************************************************************************
template <typename T>
bool destroy(const T* const p)
{
STATIC_ASSERT((etl::is_one_of<T, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value ||
etl::is_base_of<T, T1>::value ||
etl::is_base_of<T, T2>::value ||
etl::is_base_of<T, T3>::value ||
etl::is_base_of<T, T4>::value ||
etl::is_base_of<T, T5>::value ||
etl::is_base_of<T, T6>::value ||
etl::is_base_of<T, T7>::value ||
etl::is_base_of<T, T8>::value ||
etl::is_base_of<T, T9>::value ||
etl::is_base_of<T, T10>::value ||
etl::is_base_of<T, T11>::value ||
etl::is_base_of<T, T12>::value ||
etl::is_base_of<T, T13>::value ||
etl::is_base_of<T, T14>::value ||
etl::is_base_of<T, T15>::value ||
etl::is_base_of<T, T16>::value), "Invalid type");
p->~T();
void* vp = reinterpret_cast<char*>(const_cast<T*>(p));
if (pool.is_in_pool(vp))
{
pool.release(vp);
return true;
}
else
{
ETL_ASSERT(false, ETL_ERROR(variant_pool_did_not_create));
return false;
}
}
//*************************************************************************
/// Returns the maximum number of items in the variant_pool.
//*************************************************************************
size_t max_size() const
{
return MAX_SIZE;
}
//*************************************************************************
/// Returns the number of free items in the variant_pool.
//*************************************************************************
size_t available() const
{
return pool.available();
}
//*************************************************************************
/// Returns the number of allocated items in the variant_pool.
//*************************************************************************
size_t size() const
{
return pool.size();
}
//*************************************************************************
/// Checks to see if there are no allocated items in the variant_pool.
/// \return <b>true</b> if there are none allocated.
//*************************************************************************
bool empty() const
{
return pool.empty();
}
//*************************************************************************
/// Checks to see if there are no free items in the variant_pool.
/// \return <b>true</b> if there are none free.
//*************************************************************************
bool full() const
{
return pool.full();
}
private:
variant_pool(const variant_pool&);
variant_pool& operator =(const variant_pool&);
// The pool.
etl::generic_pool<etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
etl::largest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::alignment,
MAX_SIZE> pool;
};
}
#undef ETL_FILE
#endif

View File

@ -200,8 +200,8 @@ namespace etl
{
size_t operator()(const etl::iwstring& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
@ -210,8 +210,8 @@ namespace etl
{
size_t operator()(const etl::wstring<SIZE>& text) const
{
return etl::__private_hash__::generic_hash<>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
return etl::__private_hash__::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&text[0]),
reinterpret_cast<const uint8_t*>(&text[text.size()]));
}
};
#endif

41
support/Release notes.txt Normal file
View File

@ -0,0 +1,41 @@
10.8.0
Added etl::variant_pool as a replacement for etl::factory.
Deprecated etl::factory
etl::forward_list
Renamed include guard to avoid clash with list.
Removed factory from unit tests.
multimap & multiset
Changed static const to enum.
hash & strings
Removed default function template parameter value.
FSM
Moved get_fsm_context() from public to protected in etl::state
Binary
Added sign_extend functions with shift parameter.
Added new binary.cpp for non-template functions.
Added bit<> template constant
Added bit enumerations
Debug count
Added clear()
Type lookup
Simplified codebase
Message router
Added 'successor' member to allow implementation 'Chain Of Responsibility' pattern.
IO Ports
Changes value() to read().
Rewrite of classes to improve efficiency by removing iterator indirection step.
Fixed inconsistencies in the dynamic IO port API.
Type traits
Added 'conditional_integral_constant' to complement 'conditional'

View File

@ -60,6 +60,7 @@
<Unit filename="../../src/alignment.h" />
<Unit filename="../../src/array.h" />
<Unit filename="../../src/basic_string.h" />
<Unit filename="../../src/binary.cpp" />
<Unit filename="../../src/binary.h" />
<Unit filename="../../src/bitset.h" />
<Unit filename="../../src/bloom_filter.h" />
@ -99,7 +100,6 @@
<Unit filename="../../src/etl_arduino.h" />
<Unit filename="../../src/exception.h" />
<Unit filename="../../src/factorial.h" />
<Unit filename="../../src/factory.h" />
<Unit filename="../../src/fibonacci.h" />
<Unit filename="../../src/fixed_iterator.h" />
<Unit filename="../../src/flat_map.h" />
@ -205,6 +205,7 @@
<Unit filename="../../src/user_type.h" />
<Unit filename="../../src/utility.h" />
<Unit filename="../../src/variant.h" />
<Unit filename="../../src/variant_pool.h" />
<Unit filename="../../src/vector.h" />
<Unit filename="../../src/visitor.h" />
<Unit filename="../../src/wstring.h" />
@ -304,7 +305,6 @@
<Unit filename="../test_enum_type.cpp" />
<Unit filename="../test_error_handler.cpp" />
<Unit filename="../test_exception.cpp" />
<Unit filename="../test_factory.cpp" />
<Unit filename="../test_fixed_iterator.cpp" />
<Unit filename="../test_flat_map.cpp" />
<Unit filename="../test_flat_multimap.cpp" />
@ -369,6 +369,7 @@
<Unit filename="../test_user_type.cpp" />
<Unit filename="../test_utility.cpp" />
<Unit filename="../test_variant.cpp" />
<Unit filename="../test_variant_pool.cpp" />
<Unit filename="../test_vector.cpp" />
<Unit filename="../test_vector_non_trivial.cpp" />
<Unit filename="../test_vector_pointer.cpp" />

View File

@ -99,8 +99,12 @@ TReturn test_fold_bits(uint64_t value, int size)
// Slow gray to binary
template <typename T>
T compare_gray_to_binary(T value)
T compare_gray_to_binary(T value_)
{
typedef typename std::make_unsigned<T>::type type;
type value = type(value_);
T mask;
for (mask = value >> 1; mask != 0; mask = mask >> 1)
{
@ -647,6 +651,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint8_t>::max(); ++i)
{
CHECK_EQUAL(compare_gray_to_binary(uint8_t(i)), etl::gray_to_binary(uint8_t(i)));
CHECK_EQUAL(compare_gray_to_binary(int8_t(i)), etl::gray_to_binary(int8_t(i)));
}
}
@ -656,6 +661,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint16_t>::max(); ++i)
{
CHECK_EQUAL(compare_gray_to_binary(uint16_t(i)), etl::gray_to_binary(uint16_t(i)));
CHECK_EQUAL(compare_gray_to_binary(int16_t(i)), etl::gray_to_binary(int16_t(i)));
}
}
@ -670,6 +676,7 @@ namespace
{
uint32_t value = hash.value();
CHECK_EQUAL(compare_gray_to_binary(value), etl::gray_to_binary(value));
CHECK_EQUAL(int32_t(compare_gray_to_binary(value)), etl::gray_to_binary(int32_t(value)));
}
}
@ -684,6 +691,7 @@ namespace
{
uint64_t value = hash.value();
CHECK_EQUAL(compare_gray_to_binary(value), etl::gray_to_binary(value));
CHECK_EQUAL(int64_t(compare_gray_to_binary(value)), etl::gray_to_binary(int64_t(value)));
}
}
@ -693,6 +701,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint8_t>::max(); ++i)
{
CHECK_EQUAL(test_count(i), etl::count_bits(uint8_t(i)));
CHECK_EQUAL(test_count(i), etl::count_bits(int8_t(i)));
}
}
@ -702,6 +711,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint16_t>::max(); ++i)
{
CHECK_EQUAL(test_count(i), etl::count_bits(uint16_t(i)));
CHECK_EQUAL(test_count(i), etl::count_bits(int16_t(i)));
}
}
@ -717,6 +727,7 @@ namespace
uint32_t value = hash.value();
CHECK_EQUAL(test_count(value), etl::count_bits(value));
CHECK_EQUAL(test_count(value), etl::count_bits(int32_t(value)));
}
}
@ -732,6 +743,7 @@ namespace
uint64_t value = hash.value();
CHECK_EQUAL(test_count(value), etl::count_bits(value));
CHECK_EQUAL(test_count(value), etl::count_bits(int64_t(value)));
}
}
@ -741,6 +753,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint8_t>::max(); ++i)
{
CHECK_EQUAL(test_parity(i), etl::parity(uint8_t(i)));
CHECK_EQUAL(test_parity(i), etl::parity(int8_t(i)));
}
}
@ -750,6 +763,7 @@ namespace
for (size_t i = 1; i <= std::numeric_limits<uint16_t>::max(); ++i)
{
CHECK_EQUAL(test_parity(i), etl::parity(uint16_t(i)));
CHECK_EQUAL(test_parity(i), etl::parity(int16_t(i)));
}
}
@ -765,6 +779,7 @@ namespace
uint32_t value = hash.value();
CHECK_EQUAL(test_parity(value), etl::parity(value));
CHECK_EQUAL(test_parity(value), etl::parity(int32_t(value)));
}
}
@ -780,6 +795,7 @@ namespace
uint64_t value = hash.value();
CHECK_EQUAL(test_parity(value), etl::parity(value));
CHECK_EQUAL(test_parity(value), etl::parity(int64_t(value)));
}
}
@ -857,7 +873,7 @@ namespace
TEST(test_max_value_for_bits)
{
// Check that the values are correct.
//CHECK_EQUAL(0, etl::max_value_for_nbits<0>::value);
//CHECK_EQUAL(0U, etl::max_value_for_nbits<0>::value);
CHECK_EQUAL(1U, etl::max_value_for_nbits<1>::value);
CHECK_EQUAL(3U, etl::max_value_for_nbits<2>::value);
CHECK_EQUAL(7U, etl::max_value_for_nbits<3>::value);
@ -1037,6 +1053,57 @@ namespace
CHECK_EQUAL(178956970, (etl::sign_extend<int64_t, 30>(value32)));
}
//*************************************************************************
TEST(test_sign_extend_template1b)
{
uint8_t value8 = 0x2A;
uint8_t value8mask = 0x3F;
const uint32_t value_initial = 0x55555555;
uint32_t value;
// Shift 0
value = value_initial;
value &= ~value8mask;
value |= value8;
CHECK_EQUAL(-22, (etl::sign_extend<int32_t, 6, 0>(value)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t, 6, 0>(value)));
// Shift 3
value = value_initial;
value &= ~(value8mask << 3);
value |= (value8 << 3);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t, 6, 3>(value)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t, 6, 3>(value)));
// Shift 6
value = value_initial;
value &= ~(value8mask << 6);
value |= (value8 << 6);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t, 6, 6>(value)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t, 6, 6>(value)));
// Shift 12
value = value_initial;
value &= ~(value8mask << 12);
value |= (value8 << 12);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t, 6, 12>(value)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t, 6, 12>(value)));
// Shift 26
value = value_initial;
value &= ~(value8mask << 26);
value |= (value8 << 26);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t, 6, 26>(value)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t, 6, 26>(value)));
}
//*************************************************************************
TEST(test_sign_extend_template2)
{
@ -1082,6 +1149,135 @@ namespace
CHECK_EQUAL(178956970, (etl::sign_extend<int32_t>(value32, 30)));
CHECK_EQUAL(178956970, (etl::sign_extend<int64_t>(value32, 30)));
}
//*************************************************************************
TEST(test_sign_extend_template2b)
{
uint8_t value8 = 0x2A;
uint8_t value8mask = 0x3F;
const uint32_t value_initial = 0x55555555;
uint32_t value;
// Shift 0
value = value_initial;
value &= ~value8mask;
value |= value8;
CHECK_EQUAL(-22, (etl::sign_extend<int32_t>(value, 6, 0)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t>(value, 6, 0)));
// Shift 3
value = value_initial;
value &= ~(value8mask << 3);
value |= (value8 << 3);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t>(value, 6, 3)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t>(value, 6, 3)));
// Shift 6
value = value_initial;
value &= ~(value8mask << 6);
value |= (value8 << 6);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t>(value, 6, 6)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t>(value, 6, 6)));
// Shift 12
value = value_initial;
value &= ~(value8mask << 12);
value |= (value8 << 12);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t>(value, 6, 12)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t>(value, 6, 12)));
// Shift 26
value = value_initial;
value &= ~(value8mask << 26);
value |= (value8 << 26);
CHECK_EQUAL(-22, (etl::sign_extend<int32_t>(value, 6, 26)));
CHECK_EQUAL(-22, (etl::sign_extend<int64_t>(value, 6, 26)));
}
//*************************************************************************
TEST(test_bit)
{
const uint32_t N = 1;
CHECK_EQUAL(N << 0, etl::bit<0>::value);
CHECK_EQUAL(N << 1, etl::bit<1>::value);
CHECK_EQUAL(N << 2, etl::bit<2>::value);
CHECK_EQUAL(N << 3, etl::bit<3>::value);
CHECK_EQUAL(N << 4, etl::bit<4>::value);
CHECK_EQUAL(N << 5, etl::bit<5>::value);
CHECK_EQUAL(N << 6, etl::bit<6>::value);
CHECK_EQUAL(N << 7, etl::bit<7>::value);
CHECK_EQUAL(N << 8, etl::bit<8>::value);
CHECK_EQUAL(N << 9, etl::bit<9>::value);
CHECK_EQUAL(N << 10, etl::bit<10>::value);
CHECK_EQUAL(N << 11, etl::bit<11>::value);
CHECK_EQUAL(N << 12, etl::bit<12>::value);
CHECK_EQUAL(N << 13, etl::bit<13>::value);
CHECK_EQUAL(N << 14, etl::bit<14>::value);
CHECK_EQUAL(N << 15, etl::bit<15>::value);
CHECK_EQUAL(N << 16, etl::bit<16>::value);
CHECK_EQUAL(N << 17, etl::bit<17>::value);
CHECK_EQUAL(N << 18, etl::bit<18>::value);
CHECK_EQUAL(N << 19, etl::bit<19>::value);
CHECK_EQUAL(N << 20, etl::bit<20>::value);
CHECK_EQUAL(N << 21, etl::bit<21>::value);
CHECK_EQUAL(N << 22, etl::bit<22>::value);
CHECK_EQUAL(N << 23, etl::bit<23>::value);
CHECK_EQUAL(N << 24, etl::bit<24>::value);
CHECK_EQUAL(N << 25, etl::bit<25>::value);
CHECK_EQUAL(N << 26, etl::bit<26>::value);
CHECK_EQUAL(N << 27, etl::bit<27>::value);
CHECK_EQUAL(N << 28, etl::bit<28>::value);
CHECK_EQUAL(N << 29, etl::bit<29>::value);
CHECK_EQUAL(N << 30, etl::bit<30>::value);
CHECK_EQUAL(N << 31, etl::bit<31>::value);
}
//*************************************************************************
TEST(test_bits_constants)
{
const uint32_t N = 1;
CHECK_EQUAL(N << 0, etl::b0);
CHECK_EQUAL(N << 1, etl::b1);
CHECK_EQUAL(N << 2, etl::b2);
CHECK_EQUAL(N << 3, etl::b3);
CHECK_EQUAL(N << 4, etl::b4);
CHECK_EQUAL(N << 5, etl::b5);
CHECK_EQUAL(N << 6, etl::b6);
CHECK_EQUAL(N << 7, etl::b7);
CHECK_EQUAL(N << 8, etl::b8);
CHECK_EQUAL(N << 9, etl::b9);
CHECK_EQUAL(N << 10, etl::b10);
CHECK_EQUAL(N << 11, etl::b11);
CHECK_EQUAL(N << 12, etl::b12);
CHECK_EQUAL(N << 13, etl::b13);
CHECK_EQUAL(N << 14, etl::b14);
CHECK_EQUAL(N << 15, etl::b15);
CHECK_EQUAL(N << 16, etl::b16);
CHECK_EQUAL(N << 17, etl::b17);
CHECK_EQUAL(N << 18, etl::b18);
CHECK_EQUAL(N << 19, etl::b19);
CHECK_EQUAL(N << 20, etl::b20);
CHECK_EQUAL(N << 21, etl::b21);
CHECK_EQUAL(N << 22, etl::b22);
CHECK_EQUAL(N << 23, etl::b23);
CHECK_EQUAL(N << 24, etl::b24);
CHECK_EQUAL(N << 25, etl::b25);
CHECK_EQUAL(N << 26, etl::b26);
CHECK_EQUAL(N << 27, etl::b27);
CHECK_EQUAL(N << 28, etl::b28);
CHECK_EQUAL(N << 29, etl::b29);
CHECK_EQUAL(N << 30, etl::b30);
CHECK_EQUAL(N << 31, uint32_t(etl::b31));
}
};
}

315
test/test_variant_pool.cpp Normal file
View File

@ -0,0 +1,315 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
http://www.etlcpp.com
Copyright(c) 2017 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "UnitTest++.h"
#include "ExtraCheckMacros.h"
#include "variant_pool.h"
#include <string>
#include <type_traits>
namespace
{
bool destructor;
//***********************************
struct Base
{
Base()
{
destructor = false;
}
virtual ~Base()
{
}
virtual void Set() = 0;
};
//***********************************
struct Derived1 : public Base
{
int i;
Derived1()
: i(0)
{
}
~Derived1()
{
destructor = true;
}
void Set()
{
i = 1;
}
};
//***********************************
struct Derived2 : public Base
{
double d;
Derived2()
: d(0.0)
{
}
~Derived2()
{
destructor = true;
}
void Set()
{
d = 1.2;
}
};
//***********************************
struct Derived3 : public Base
{
std::string s;
Derived3()
: s("constructed")
{
}
Derived3(const char* p1)
: s("constructed")
{
s.append(p1);
}
Derived3(const char* p1, const std::string& p2)
: s("constructed")
{
s.append(p1);
s.append(p2);
}
Derived3(const char* p1, const std::string& p2, const char* p3)
: s("constructed")
{
s.append(p1);
s.append(p2);
s.append(p3);
}
Derived3(const char* p1, const std::string& p2, const char* p3, const std::string& p4)
: s("constructed")
{
s.append(p1);
s.append(p2);
s.append(p3);
s.append(p4);
}
~Derived3()
{
destructor = true;
}
void Set()
{
s = "set";
}
};
//***********************************
struct NonDerived
{
NonDerived()
: s("constructed")
{
}
~NonDerived()
{
destructor = true;
}
void Set()
{
s = "set";
}
std::string s;
};
const size_t SIZE = 5;
// Notice that the type declaration order is not important.
typedef etl::variant_pool<SIZE, Derived1, NonDerived, Derived3, Derived2, int> Factory;
SUITE(test_variant_pool)
{
//*************************************************************************
TEST(test_sizes)
{
Factory variant_pool;
size_t ms = Factory::MAX_SIZE;
CHECK_EQUAL(SIZE, ms);
CHECK_EQUAL(SIZE, variant_pool.max_size());
CHECK_EQUAL(SIZE, variant_pool.available());
CHECK_EQUAL(0U, variant_pool.size());
CHECK(variant_pool.empty());
CHECK(!variant_pool.full());
variant_pool.create<Derived1>();
CHECK_EQUAL(SIZE - 1U, variant_pool.available());
CHECK_EQUAL(1U, variant_pool.size());
CHECK(!variant_pool.empty());
CHECK(!variant_pool.full());
variant_pool.create<Derived1>();
variant_pool.create<Derived1>();
variant_pool.create<Derived1>();
variant_pool.create<Derived1>();
CHECK_EQUAL(0U, variant_pool.available());
CHECK_EQUAL(SIZE, variant_pool.size());
CHECK(!variant_pool.empty());
CHECK(variant_pool.full());
CHECK_THROW(variant_pool.create<Derived1>(), etl::variant_pool_cannot_create);
}
//*************************************************************************
TEST(test_create_release)
{
Factory variant_pool;
Base* p;
// Derived 1
p = variant_pool.create<Derived1>();
Derived1* pd1 = static_cast<Derived1*>(p);
CHECK_EQUAL(0, pd1->i);
p->Set();
CHECK_EQUAL(1, pd1->i);
variant_pool.destroy(p);
CHECK(destructor);
// Derived 2
destructor = false;
p = variant_pool.create<Derived2>();
Derived2* pd2 = static_cast<Derived2*>(p);
CHECK_EQUAL(0.0, pd2->d);
p->Set();
CHECK_EQUAL(1.2, pd2->d);
variant_pool.destroy(p);
CHECK(destructor);
// Derived 3
destructor = false;
p = variant_pool.create<Derived3>();
Derived3* pd3 = static_cast<Derived3*>(p);
CHECK_EQUAL("constructed", pd3->s);
p->Set();
CHECK_EQUAL("set", pd3->s);
variant_pool.destroy(p);
CHECK(destructor);
// Non Derived
destructor = false;
NonDerived* pnd = variant_pool.create<NonDerived>();
CHECK_EQUAL("constructed", pnd->s);
pnd->Set();
CHECK_EQUAL("set", pnd->s);
variant_pool.destroy(pnd);
CHECK(destructor);
// Integral
int* pi = variant_pool.create<int>();
variant_pool.destroy(pi);
}
//*************************************************************************
TEST(test_create_release_const)
{
Factory variant_pool;
const Derived1& d = *variant_pool.create<Derived1>();
CHECK_EQUAL(0, d.i);
variant_pool.destroy(&d);
CHECK(destructor);
}
//*************************************************************************
TEST(test_create_emplace)
{
Factory variant_pool;
Base* p;
Derived3* pd3;
p = variant_pool.create<Derived3>("1");
pd3 = static_cast<Derived3*>(p);
CHECK_EQUAL("constructed1", pd3->s);
variant_pool.destroy(p);
p = variant_pool.create<Derived3>("1", "2");
pd3 = static_cast<Derived3*>(p);
CHECK_EQUAL("constructed12", pd3->s);
variant_pool.destroy(p);
p = variant_pool.create<Derived3>("1", "2", "3");
pd3 = static_cast<Derived3*>(p);
CHECK_EQUAL("constructed123", pd3->s);
variant_pool.destroy(p);
p = variant_pool.create<Derived3>("1", "2", "3", "4");
pd3 = static_cast<Derived3*>(p);
CHECK_EQUAL("constructed1234", pd3->s);
variant_pool.destroy(p);
}
//*************************************************************************
TEST(test_did_not_create)
{
Factory variant_pool1;
Factory variant_pool2;
Base* p;
p = variant_pool1.create<Derived1>();
CHECK_NO_THROW(variant_pool1.destroy(p));
p = variant_pool2.create<Derived1>();
CHECK_THROW(variant_pool1.destroy(p), etl::variant_pool_did_not_create);
}
};
}

View File

@ -136,7 +136,6 @@
<ClInclude Include="..\..\src\compare.h" />
<ClInclude Include="..\..\src\constant.h" />
<ClInclude Include="..\..\src\c\ecl_timer.h" />
<ClInclude Include="..\..\src\factory.h" />
<ClInclude Include="..\..\src\fsm.h" />
<ClInclude Include="..\..\src\fsm_generator.h" />
<ClInclude Include="..\..\src\largest_generator.h" />
@ -166,6 +165,7 @@
<ClInclude Include="..\..\src\type_lookup.h" />
<ClInclude Include="..\..\src\type_lookup_generator.h" />
<ClInclude Include="..\..\src\type_traits_generator.h" />
<ClInclude Include="..\..\src\variant_pool.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\AssertException.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\CheckMacros.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\Checks.h" />
@ -298,6 +298,7 @@
<ClInclude Include="..\murmurhash3.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\binary.cpp" />
<ClCompile Include="..\..\src\c\ecl_timer.c" />
<ClCompile Include="..\..\unittest-cpp\UnitTest++\AssertException.cpp" />
<ClCompile Include="..\..\unittest-cpp\UnitTest++\Checks.cpp" />
@ -357,7 +358,6 @@
<ClCompile Include="..\test_enum_type.cpp" />
<ClCompile Include="..\test_error_handler.cpp" />
<ClCompile Include="..\test_exception.cpp" />
<ClCompile Include="..\test_factory.cpp" />
<ClCompile Include="..\test_fixed_iterator.cpp" />
<ClCompile Include="..\test_flat_multimap.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -452,6 +452,7 @@
<ClCompile Include="..\test_user_type.cpp" />
<ClCompile Include="..\test_utility.cpp" />
<ClCompile Include="..\test_variant.cpp" />
<ClCompile Include="..\test_variant_pool.cpp" />
<ClCompile Include="..\test_vector.cpp" />
<ClCompile Include="..\test_vector_non_trivial.cpp" />
<ClCompile Include="..\test_vector_pointer.cpp" />

View File

@ -489,9 +489,6 @@
<ClInclude Include="..\..\src\sqrt.h">
<Filter>ETL\Maths</Filter>
</ClInclude>
<ClInclude Include="..\..\src\factory.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\type_lookup.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
@ -561,6 +558,9 @@
<ClInclude Include="..\ecl_user.h">
<Filter>Source Files\ECL</Filter>
</ClInclude>
<ClInclude Include="..\..\src\variant_pool.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\main.cpp">
@ -854,9 +854,6 @@
<ClCompile Include="..\test_parameter_type.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_factory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_type_lookup.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -932,6 +929,12 @@
<ClCompile Include="..\test_c_timer_framework.cpp">
<Filter>Source Files\ECL</Filter>
</ClCompile>
<ClCompile Include="..\..\src\binary.cpp">
<Filter>ETL\Utilities</Filter>
</ClCompile>
<ClCompile Include="..\test_variant_pool.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\Doxyfile">