mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-26 20:38:45 +08:00
Merge branch 'development'
This commit is contained in:
commit
1b11cf5c58
@ -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
470
src/binary.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
677
src/binary.h
677
src/binary.h
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
328
src/factory.h
328
src/factory.h
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -37,4 +37,4 @@
|
||||
37 task
|
||||
38 message
|
||||
39 message_bus
|
||||
40 factory
|
||||
40 factory / variant_pool
|
||||
|
||||
@ -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
129
src/fsm.h
@ -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)
|
||||
|
||||
@ -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)")
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
{
|
||||
|
||||
@ -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(" {")
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
//*********************************************************************
|
||||
|
||||
1949
src/type_lookup.h
1949
src/type_lookup.h
File diff suppressed because it is too large
Load Diff
@ -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]]]*/
|
||||
}
|
||||
|
||||
@ -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 ||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
374
src/variant_pool.h
Normal 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
|
||||
@ -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
41
support/Release notes.txt
Normal 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'
|
||||
@ -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" />
|
||||
|
||||
@ -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
315
test/test_variant_pool.cpp
Normal 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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" />
|
||||
|
||||
@ -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">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user