Merge branch 'development'

This commit is contained in:
John Wellbelove 2024-04-16 11:02:12 +01:00
commit 411364f1e7
187 changed files with 17916 additions and 8157 deletions

1
.gitignore vendored
View File

@ -386,3 +386,4 @@ test/vs2022/Debug MSVC C++20 - No virtual messages
examples/MutexMessageRouter/.vs
support/time remaining test.xlsx
test/vs2022/Debug MSVC C++20 - Force C++03
test/vs2022/Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser

View File

@ -59,7 +59,7 @@ get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
# function returns an empty string via _git_dir_var.
#
# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and
# neither foo nor bar contain a file/directory .git. This wil return
# neither foo nor bar contain a file/directory .git. This will return
# C:/bla/.git
#
function(_git_find_closest_git_dir _start_dir _git_dir_var)

View File

@ -119,7 +119,7 @@ Uart uart1(0, USART1_IRQ_HANDLER);
Uart uart2(1, USART2_IRQ_HANDLER);
// Declare a global callback for the timer.
// Uses the most efficient callback type for a class, as everthing is known at compile time.
// Uses the most efficient callback type for a class, as everything is known at compile time.
etl::delegate<void(size_t)> timer_member_callback = etl::delegate<void(size_t)>::create<Timer, timer, &Timer::InterruptHandler>();
// Declare the callbacks for the free functions.

View File

@ -119,7 +119,7 @@ Uart uart1(0, USART1_IRQ_HANDLER);
Uart uart2(1, USART2_IRQ_HANDLER);
// Declare a global callback for the timer.
// Uses the most efficient callback type for a class, as everthing is known at compile time.
// Uses the most efficient callback type for a class, as everything is known at compile time.
etl::function_imp<Timer, size_t, timer, &Timer::InterruptHandler> timer_member_callback;
// Declare the callbacks for the free functions.

View File

@ -169,6 +169,18 @@ namespace etl
return first2;
}
//***************************************************************************
// generate
template <typename TIterator, typename TFunction>
ETL_CONSTEXPR14
void generate(TIterator db, TIterator de, TFunction funct)
{
while (db != de)
{
*db++ = funct();
}
}
//***************************************************************************
// copy
#if ETL_USING_STL && ETL_USING_CPP20
@ -2009,9 +2021,7 @@ namespace etl
template <typename TIterator, typename T>
ETL_CONSTEXPR14
TIterator remove(TIterator first, TIterator last, const T& value)
{
first = etl::find(first, last, value);
{
if (first != last)
{
TIterator itr = first;
@ -2039,8 +2049,6 @@ namespace etl
ETL_CONSTEXPR14
TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate)
{
first = etl::find_if(first, last, predicate);
if (first != last)
{
TIterator itr = first;
@ -2177,7 +2185,7 @@ namespace etl
//***************************************************************************
/// copy_if
/// A safer form of copy_if where it terminates when the first end iterator is reached.
/// There is currently no STL equivelent.
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator,
@ -3065,6 +3073,154 @@ namespace etl
return multimin_iter_compare(compare, t, multimin_iter_compare(compare, tx...));
}
#endif
//***************************************************************************
/// partition
/// For forward iterators only
/// Does at most etl::distance(first, last) swaps.
//***************************************************************************
template <typename TIterator, typename TPredicate>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_forward_iterator<TIterator>::value, TIterator>::type
partition(TIterator first, TIterator last, TPredicate predicate)
{
first = etl::find_if_not(first, last, predicate);
if (first == last)
{
return first;
}
for (TIterator i = etl::next(first); i != last; ++i)
{
if (predicate(*i))
{
using ETL_OR_STD::swap;
swap(*i, *first);
++first;
}
}
return first;
}
//***************************************************************************
/// partition
/// For iterators that support bidirectional iteration.
/// Does at most (etl::distance(first, last) / 2) swaps.
//***************************************************************************
template <typename TIterator, typename TPredicate>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_bidirectional_iterator_concept<TIterator>::value, TIterator>::type
partition(TIterator first, TIterator last, TPredicate predicate)
{
while (first != last)
{
first = etl::find_if_not(first, last, predicate);
if (first == last)
{
break;
}
last = etl::find_if(etl::reverse_iterator<TIterator>(last),
etl::reverse_iterator<TIterator>(first),
predicate).base();
if (first == last)
{
break;
}
--last;
using ETL_OR_STD::swap;
swap(*first, *last);
++first;
}
return first;
}
//*********************************************************
namespace private_algorithm
{
using ETL_OR_STD::swap;
template <typename TIterator, typename TCompare>
#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
constexpr
#endif
TIterator nth_partition(TIterator first, TIterator last, TCompare compare)
{
typedef typename etl::iterator_traits<TIterator>::value_type value_type;
TIterator pivot = last; // Maybe find a better pivot choice?
value_type pivot_value = *pivot;
// Swap the pivot with the last, if necessary.
if (pivot != last)
{
swap(*pivot, *last);
}
TIterator i = first;
for (TIterator j = first; j < last; ++j)
{
if (!compare(pivot_value, *j)) // Hack to get '*j <= pivot_value' in terms of 'pivot_value < *j'
{
swap(*i, *j);
++i;
}
}
swap(*i, *last);
return i;
}
}
//*********************************************************
/// nth_element
/// see https://en.cppreference.com/w/cpp/algorithm/nth_element
//*********************************************************
#if ETL_USING_CPP11
template <typename TIterator, typename TCompare = etl::less<typename etl::iterator_traits<TIterator>::value_type> >
#else
template <typename TIterator, typename TCompare>
#endif
#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST))
constexpr
#endif
typename etl::enable_if<etl::is_random_access_iterator_concept<TIterator>::value, void>::type
nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare = TCompare())
{
if (first == last)
{
return;
}
// 'last' must point to the actual last value.
--last;
while (first <= last)
{
TIterator p = private_algorithm::nth_partition(first, last, compare);
if (p == nth)
{
return;
}
else if (p > nth)
{
last = p - 1;
}
else
{
first = p + 1;
}
}
}
}
#include "private/minmax_pop.h"

View File

@ -94,15 +94,15 @@ namespace etl
static ETL_CONSTANT size_t SIZE = SIZE_;
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef T value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
@ -386,11 +386,12 @@ namespace etl
/// If the range is smaller than the array then the unused array elements are left unmodified.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
///\return An iterator to the first unassigned array element, or end().
//*************************************************************************
template <typename TIterator>
void assign(TIterator first, const TIterator last)
iterator assign(TIterator first, const TIterator last)
{
etl::copy_s(first, last, begin(), end());
return etl::copy_s(first, last, begin(), end());
}
//*************************************************************************
@ -398,15 +399,18 @@ namespace etl
/// If the range is smaller than the array then the unused array elements are initialised with the supplied value.
///\param first The iterator to the first item in the range.
///\param last The iterator to one past the final item in the range.
///\return An iterator to the first array element set to 'value', or end().
//*************************************************************************
template <typename TIterator>
void assign(TIterator first, const TIterator last, parameter_t value)
iterator assign(TIterator first, const TIterator last, parameter_t value)
{
// Copy from the range.
iterator p = etl::copy(first, last, begin());
iterator p = etl::copy_s(first, last, begin(), end());
// Initialise any that are left.
etl::fill(p, end(), value);
return p;
}
//*************************************************************************

View File

@ -167,7 +167,7 @@ namespace etl
T operator --(int) volatile
{
return __atomic_fetch_sub(&value, 1), etl::memory_order_seq_cst;
return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst);
}
// Add

View File

@ -172,10 +172,10 @@ namespace etl
static ETL_CONSTANT private_basic_format_spec::base_spec hex(16U);
//*********************************
static ETL_CONSTANT private_basic_format_spec::left_spec left;
static ETL_CONSTANT private_basic_format_spec::left_spec left = private_basic_format_spec::left_spec();
//*********************************
static ETL_CONSTANT private_basic_format_spec::right_spec right;
static ETL_CONSTANT private_basic_format_spec::right_spec right = private_basic_format_spec::right_spec();
//*********************************
static ETL_CONSTANT private_basic_format_spec::boolalpha_spec boolalpha(true);

View File

@ -1262,7 +1262,7 @@ namespace etl
/// Erases a sequence.
///\param position Position to start from.
///\param length Number of characters.
///\return A refernce to this string.
///\return A reference to this string.
//*********************************************************************
etl::ibasic_string<T>& erase(size_type position, size_type length_ = npos)
{

View File

@ -58,28 +58,28 @@ namespace etl
}
//*************************************************************************
/// Construct from text and format spec.
/// Construct from text and format fmt.
//*************************************************************************
basic_string_stream(TIString& text_, const TFormat& spec_)
: text(text_)
, spec(spec_)
, format(spec_)
{
}
//*************************************************************************
/// Set the format spec.
/// Set the format fmt.
//*************************************************************************
void set_format(const TFormat& spec_)
{
spec = spec_;
format = spec_;
}
//*************************************************************************
/// Get a const reference to the format spec.
/// Get a const reference to the format fmt.
//*************************************************************************
const TFormat& get_format() const
{
return spec;
return format;
}
//*************************************************************************
@ -121,27 +121,27 @@ namespace etl
//*********************************
/// TFormat
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, const TFormat& spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, const TFormat& fmt)
{
ss.spec = spec;
ss.format = fmt;
return ss;
}
//*********************************
/// etl::base_spec from etl::setbase, etl::bin, etl::oct, etl::dec & etl::hex stream manipulators
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::base_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::base_spec fmt)
{
ss.spec.base(spec.base);
ss.format.base(fmt.base);
return ss;
}
//*********************************
/// etl::width_spec from etl::setw stream manipulator
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::width_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::width_spec fmt)
{
ss.spec.width(spec.width);
ss.format.width(fmt.width);
return ss;
}
@ -149,63 +149,63 @@ namespace etl
/// etl::fill_spec from etl::setfill stream manipulator
//*********************************
template <typename TChar>
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::fill_spec<TChar> spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::fill_spec<TChar> fmt)
{
ss.spec.fill(spec.fill);
ss.format.fill(fmt.fill);
return ss;
}
//*********************************
/// etl::precision_spec from etl::setprecision stream manipulator
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::precision_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::precision_spec fmt)
{
ss.spec.precision(spec.precision);
ss.format.precision(fmt.precision);
return ss;
}
//*********************************
/// etl::boolalpha_spec from etl::boolalpha & etl::noboolalpha stream manipulators
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::boolalpha_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::boolalpha_spec fmt)
{
ss.spec.boolalpha(spec.boolalpha);
ss.format.boolalpha(fmt.boolalpha);
return ss;
}
//*********************************
/// etl::uppercase_spec from etl::uppercase & etl::nouppercase stream manipulators
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::uppercase_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::uppercase_spec fmt)
{
ss.spec.upper_case(spec.upper_case);
ss.format.upper_case(fmt.upper_case);
return ss;
}
//*********************************
/// etl::showbase_spec from etl::showbase & etl::noshowbase stream manipulators
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::showbase_spec spec)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::showbase_spec fmt)
{
ss.spec.show_base(spec.show_base);
ss.format.show_base(fmt.show_base);
return ss;
}
//*********************************
/// etl::left_spec from etl::left stream manipulator
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::left_spec /*spec*/)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::left_spec /*fmt*/)
{
ss.spec.left();
ss.format.left();
return ss;
}
//*********************************
/// etl::right_spec from etl::left stream manipulator
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::right_spec /*spec*/)
friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::right_spec /*fmt*/)
{
ss.spec.right();
ss.format.right();
return ss;
}
@ -214,7 +214,7 @@ namespace etl
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, TStringView view)
{
etl::to_string(view, ss.text, ss.spec, true);
etl::to_string(view, ss.text, ss.format, true);
return ss;
}
@ -241,9 +241,9 @@ namespace etl
//*********************************
/// From a string interface
//*********************************
friend basic_string_stream& operator <<(basic_string_stream& ss, const TIString& text)
friend basic_string_stream& operator <<(basic_string_stream& ss, const TIString& t)
{
etl::to_string(text, ss.text, ss.spec, true);
etl::to_string(t, ss.text, ss.format, true);
return ss;
}
@ -251,9 +251,9 @@ namespace etl
/// From a string
//*********************************
template <template <size_t> class TString, size_t SIZE>
friend basic_string_stream& operator <<(basic_string_stream& ss, const TString<SIZE>& text)
friend basic_string_stream& operator <<(basic_string_stream& ss, const TString<SIZE>& t)
{
const TIString& itext = text;
const TIString& itext = t;
etl::to_string(itext, ss.str(), ss.get_format(), true);
return ss;
}
@ -264,14 +264,14 @@ namespace etl
template <typename T>
friend basic_string_stream& operator <<(basic_string_stream& ss, const T& value)
{
etl::to_string(value, ss.text, ss.spec, true);
etl::to_string(value, ss.text, ss.format, true);
return ss;
}
private:
TIString& text;
TFormat spec;
TIString& text;
TFormat format;
basic_string_stream(const basic_string_stream&) ETL_DELETE;
basic_string_stream& operator =(const basic_string_stream&) ETL_DELETE;

View File

@ -343,45 +343,6 @@ namespace etl
return TReturn((value ^ mask) - mask);
}
//***************************************************************************
/// Find the position of the first set bit.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_set_bit_position(T value)
{
return count_trailing_zeros(value);
}
//***************************************************************************
/// Find the position of the first clear bit.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_clear_bit_position(T value)
{
value = ~value;
return count_trailing_zeros(value);
}
//***************************************************************************
/// Find the position of the first bit that is clear or set.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_bit_position(bool state, T value)
{
if (!state)
{
value = ~value;
}
return count_trailing_zeros(value);
}
//***************************************************************************
/// Gets the value of the bit at POSITION
/// Starts from LSB.
@ -2097,6 +2058,45 @@ namespace etl
return static_cast<T>(count_leading_ones(static_cast<unsigned_t>(value)));
}
//***************************************************************************
/// Find the position of the first set bit.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_set_bit_position(T value)
{
return count_trailing_zeros(value);
}
//***************************************************************************
/// Find the position of the first clear bit.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_clear_bit_position(T value)
{
value = ~value;
return count_trailing_zeros(value);
}
//***************************************************************************
/// Find the position of the first bit that is clear or set.
/// Starts from LSB.
///\ingroup binary
//***************************************************************************
template <typename T>
ETL_CONSTEXPR14 uint_least8_t first_bit_position(bool state, T value)
{
if (!state)
{
value = ~value;
}
return count_trailing_zeros(value);
}
#if ETL_USING_8BIT_TYPES
//*****************************************************************************
/// Binary interleave
@ -2276,6 +2276,111 @@ namespace etl
return msb_mask<T, NBits>::value;
}
//***************************************************************************
/// Bit 'not' a value
///\ingroup binary
//***************************************************************************
template <typename T>
struct binary_not : public etl::unary_function<T, T>
{
//***********************************
ETL_NODISCARD
ETL_CONSTEXPR
T operator ()(T value) const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
return ~value;
}
};
//***************************************************************************
/// Bit 'and' a value with another
///\ingroup binary
//***************************************************************************
template <typename T>
struct binary_and : public etl::unary_function<T, T>
{
//***********************************
ETL_CONSTEXPR
explicit binary_and(T parameter_) ETL_NOEXCEPT
: parameter(parameter_)
{
}
//***********************************
ETL_NODISCARD
ETL_CONSTEXPR
T operator ()(T value) const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
return value & parameter;
}
private:
T parameter;
};
//***************************************************************************
/// Bit 'or' a value with another
///\ingroup binary
//***************************************************************************
template <typename T>
struct binary_or : public etl::unary_function<T, T>
{
//***********************************
ETL_CONSTEXPR
explicit binary_or(T parameter_) ETL_NOEXCEPT
: parameter(parameter_)
{
}
//***********************************
ETL_NODISCARD
ETL_CONSTEXPR
T operator ()(T value) const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
return value | parameter;
}
private:
T parameter;
};
//***************************************************************************
/// Bit 'exclusive-or' a value with another
///\ingroup binary
//***************************************************************************
template <typename T>
struct binary_xor : public etl::unary_function<T, T>
{
//***********************************
ETL_CONSTEXPR
explicit binary_xor(T parameter_) ETL_NOEXCEPT
: parameter(parameter_)
{
}
//***********************************
ETL_NODISCARD
ETL_CONSTEXPR
T operator ()(T value) const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Not an integral type");
return value ^ parameter;
}
private:
T parameter;
};
//***************************************************************************
/// 8 bit binary byte constants.
///\ingroup binary

View File

@ -861,7 +861,7 @@ namespace etl
}
//***************************************************************************
/// Sets the function to call afer every write.
/// Sets the function to call after every write.
//***************************************************************************
void set_callback(callback_type callback_)
{
@ -869,7 +869,7 @@ namespace etl
}
//***************************************************************************
/// Gets the function to call afer every write.
/// Gets the function to call after every write.
//***************************************************************************
callback_type get_callback() const
{

View File

@ -62,17 +62,17 @@ namespace etl
/// An implementation of a bloom filter.
/// Allows up to three hashes to be defined.
/// Hashes must support the () operator and define 'argument_type'.
///\tparam DESIRED_WIDTH The desired number of hash results that can be stored. Rounded up to best fit the underlying bitset.
///\tparam Desired_Width The desired number of hash results that can be stored. Rounded up to best fit the underlying bitset.
///\tparam THash1 The first hash generator class.
///\tparam THash2 The second hash generator class. If omitted, uses the null hash.
///\tparam THash3 The third hash generator class. If omitted, uses the null hash.
/// The hash classes must define <b>argument_type</b>.
///\ingroup bloom_filter
//***************************************************************************
template <size_t DESIRED_WIDTH,
typename THash1,
typename THash2 = private_bloom_filter::null_hash,
typename THash3 = private_bloom_filter::null_hash>
template <size_t Desired_Width,
typename THash1,
typename THash2 = private_bloom_filter::null_hash,
typename THash3 = private_bloom_filter::null_hash>
class bloom_filter
{
private:
@ -85,7 +85,7 @@ namespace etl
enum
{
// Make the most efficient use of the bitset.
WIDTH = etl::bitset<DESIRED_WIDTH>::ALLOCATED_BITS
WIDTH = etl::bitset<Desired_Width>::Allocated_Bits
};
//***************************************************************************

View File

@ -69,7 +69,7 @@ namespace etl
byte_stream_writer(etl::span<char> span_, etl::endian stream_endianness_, callback_type callback_ = callback_type())
: pdata(span_.begin())
, pcurrent(span_.begin())
, length(span_.size_bytes())
, stream_length(span_.size_bytes())
, stream_endianness(stream_endianness_)
, callback(callback_)
{
@ -81,7 +81,7 @@ namespace etl
byte_stream_writer(etl::span<unsigned char> span_, etl::endian stream_endianness_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<char*>(span_.begin()))
, pcurrent(reinterpret_cast<char*>(span_.begin()))
, length(span_.size_bytes())
, stream_length(span_.size_bytes())
, stream_endianness(stream_endianness_)
, callback(callback_)
{
@ -93,7 +93,7 @@ namespace etl
byte_stream_writer(void* begin_, void* end_, etl::endian stream_endianness_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<char*>(begin_))
, pcurrent(reinterpret_cast<char*>(begin_))
, length(etl::distance(reinterpret_cast<char*>(begin_), reinterpret_cast<char*>(end_)))
, stream_length(etl::distance(reinterpret_cast<char*>(begin_), reinterpret_cast<char*>(end_)))
, stream_endianness(stream_endianness_)
, callback(callback_)
{
@ -105,7 +105,7 @@ namespace etl
byte_stream_writer(void* begin_, size_t length_, etl::endian stream_endianness_, callback_type callback_ = callback_type())
: pdata(reinterpret_cast<char*>(begin_))
, pcurrent(reinterpret_cast<char*>(begin_))
, length(length_)
, stream_length(length_)
, stream_endianness(stream_endianness_)
, callback(callback_)
{
@ -118,7 +118,7 @@ namespace etl
byte_stream_writer(T(&begin_)[Size], etl::endian stream_endianness_, callback_type callback_ = callback_type())
: pdata(begin_)
, pcurrent(begin_)
, length(begin_ + (Size * sizeof(T)))
, stream_length(begin_ + (Size * sizeof(T)))
, stream_endianness(stream_endianness_)
, callback(callback_)
{
@ -333,7 +333,7 @@ namespace etl
//***************************************************************************
etl::span<char> free_data()
{
return etl::span<char>(pcurrent, pdata + length);
return etl::span<char>(pcurrent, pdata + stream_length);
}
//***************************************************************************
@ -341,7 +341,7 @@ namespace etl
//***************************************************************************
etl::span<const char> free_data() const
{
return etl::span<const char>(pcurrent, pdata + length);
return etl::span<const char>(pcurrent, pdata + stream_length);
}
//***************************************************************************
@ -349,7 +349,7 @@ namespace etl
//***************************************************************************
etl::span<char> data()
{
return etl::span<char>(pdata, pdata + length);
return etl::span<char>(pdata, pdata + stream_length);
}
//***************************************************************************
@ -357,7 +357,7 @@ namespace etl
//***************************************************************************
etl::span<const char> data() const
{
return etl::span<const char>(pdata, pdata + length);
return etl::span<const char>(pdata, pdata + stream_length);
}
//***************************************************************************
@ -389,7 +389,7 @@ namespace etl
//***************************************************************************
size_t capacity() const
{
return length;
return stream_length;
}
//***************************************************************************
@ -410,7 +410,7 @@ namespace etl
}
//***************************************************************************
/// Sets the function to call afer every write.
/// Sets the function to call after every write.
//***************************************************************************
void set_callback(callback_type callback_)
{
@ -418,7 +418,7 @@ namespace etl
}
//***************************************************************************
/// Gets the function to call afer every write.
/// Gets the function to call after every write.
//***************************************************************************
callback_type get_callback() const
{
@ -481,7 +481,7 @@ namespace etl
char* const pdata; ///< The start of the byte stream buffer.
char* pcurrent; ///< The current position in the byte stream buffer.
const size_t length; ///< The length of the byte stream buffer.
const size_t stream_length; ///< The length of the byte stream buffer.
const etl::endian stream_endianness; ///< The endianness of the stream data.
callback_type callback; ///< An optional callback on every step on the write buffer.
};
@ -503,7 +503,7 @@ namespace etl
byte_stream_reader(etl::span<char> span_, etl::endian stream_endianness_)
: pdata(span_.begin())
, pcurrent(span_.begin())
, length(span_.size_bytes())
, stream_length(span_.size_bytes())
, stream_endianness(stream_endianness_)
{
}
@ -514,7 +514,7 @@ namespace etl
byte_stream_reader(etl::span<const char> span_, etl::endian stream_endianness_)
: pdata(span_.begin())
, pcurrent(span_.begin())
, length(span_.size_bytes())
, stream_length(span_.size_bytes())
, stream_endianness(stream_endianness_)
{
}
@ -525,7 +525,7 @@ namespace etl
byte_stream_reader(const void* begin_, const void* end_, etl::endian stream_endianness_)
: pdata(reinterpret_cast<const char*>(begin_))
, pcurrent(reinterpret_cast<const char*>(begin_))
, length(etl::distance(reinterpret_cast<const char*>(begin_), reinterpret_cast<const char*>(end_)))
, stream_length(etl::distance(reinterpret_cast<const char*>(begin_), reinterpret_cast<const char*>(end_)))
, stream_endianness(stream_endianness_)
{
}
@ -536,7 +536,7 @@ namespace etl
byte_stream_reader(const void* begin_, size_t length_, etl::endian stream_endianness_)
: pdata(reinterpret_cast<const char*>(begin_))
, pcurrent(reinterpret_cast<const char*>(begin_))
, length(length_)
, stream_length(length_)
, stream_endianness(stream_endianness_)
{
}
@ -548,7 +548,7 @@ namespace etl
byte_stream_reader(T(&begin_)[Size], etl::endian stream_endianness_)
: pdata(begin_)
, pcurrent(begin_)
, length(begin_ + (Size * sizeof(T)))
, stream_length(begin_ + (Size * sizeof(T)))
, stream_endianness(stream_endianness_)
{
}
@ -560,7 +560,7 @@ namespace etl
byte_stream_reader(const T(&begin_)[Size], etl::endian stream_endianness_)
: pdata(begin_)
, pcurrent(begin_)
, length(begin_ + (Size * sizeof(T)))
, stream_length(begin_ + (Size * sizeof(T)))
, stream_endianness(stream_endianness_)
{
}
@ -766,7 +766,7 @@ namespace etl
//***************************************************************************
etl::span<const char> free_data() const
{
return etl::span<const char>(pcurrent, pdata + length);
return etl::span<const char>(pcurrent, pdata + stream_length);
}
//***************************************************************************
@ -774,7 +774,7 @@ namespace etl
//***************************************************************************
etl::span<const char> data() const
{
return etl::span<const char>(pdata, pdata + length);
return etl::span<const char>(pdata, pdata + stream_length);
}
//***************************************************************************
@ -790,7 +790,7 @@ namespace etl
//***************************************************************************
size_t size_bytes() const
{
return length;
return stream_length;
}
//***************************************************************************
@ -801,7 +801,7 @@ namespace etl
{
size_t used = etl::distance(pdata, pcurrent);
return (length - used) / sizeof(T);
return (stream_length - used) / sizeof(T);
}
//***************************************************************************
@ -855,7 +855,7 @@ namespace etl
const char* const pdata; ///< The start of the byte stream buffer.
const char* pcurrent; ///< The current position in the byte stream buffer.
const size_t length; ///< The length of the byte stream buffer.
const size_t stream_length; ///< The length of the byte stream buffer.
const etl::endian stream_endianness; ///< The endianness of the stream data.
};

View File

@ -708,12 +708,26 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
return !active_list.empty();
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = active_list.front().delta;
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
if (has_active_timer())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -297,13 +297,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
++process_semaphore;
bool result = !active_list.empty();
--process_semaphore;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
++process_semaphore;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
--process_semaphore;
return delta;

View File

@ -301,14 +301,30 @@ namespace etl
}
//*******************************************
/// Get the time to the next timer event.
/// Check if there is an active timer.
//*******************************************
uint32_t time_to_next() const
bool has_active_timer() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
return !active_list.empty();
}
uint32_t delta = active_list.front().delta;
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
if (!active_list.empty())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -309,13 +309,31 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
lock();
bool result = !active_list.empty();
unlock();
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
lock();
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
unlock();
return delta;

View File

@ -153,7 +153,7 @@ namespace etl
}
//*************************************************************************
ETL_CONSTEXPR14 static size_t length(const char_type* str, size_t max_length)
static ETL_CONSTEXPR14 size_t length(const char_type* str, size_t max_length)
{
size_t count = 0UL;

View File

@ -246,6 +246,22 @@ namespace etl
return &picb->pbuffer[current];
}
//*************************************************************************
/// [] operator
//*************************************************************************
reference operator [](size_t index)
{
return pbuffer[(current + index) % picb->buffer_size];
}
//*************************************************************************
/// [] operator
//*************************************************************************
const_reference operator [](size_t index) const
{
return pbuffer[(current + index) % picb->buffer_size];
}
//*************************************************************************
/// Pre-increment.
//*************************************************************************
@ -335,6 +351,18 @@ namespace etl
return temp;
}
//*************************************************************************
/// Add offset.
//*************************************************************************
friend iterator operator +(int n, const iterator& rhs)
{
iterator temp = rhs;
temp += n;
return temp;
}
//*************************************************************************
/// Subtract offset.
//*************************************************************************
@ -517,6 +545,14 @@ namespace etl
return &(picb->pbuffer[current]);
}
//*************************************************************************
/// [] operator
//*************************************************************************
const_reference operator [](size_t index) const
{
return pbuffer[(current + index) % picb->buffer_size];
}
//*************************************************************************
/// Pre-increment.
//*************************************************************************
@ -998,22 +1034,6 @@ namespace etl
return distance(rhs, lhs);
}
//*************************************************************************
/// - operator for reverse_iterator
//*************************************************************************
friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs)
{
return distance(lhs.base(), rhs.base());
}
//*************************************************************************
/// - operator for const_reverse_iterator
//*************************************************************************
friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs)
{
return distance(lhs.base(), rhs.base());
}
protected:
//*************************************************************************
@ -1208,11 +1228,9 @@ namespace etl
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
virtual
#endif
virtual void repair() ETL_OVERRIDE
#else
void repair()
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
ETL_OVERRIDE
#endif
{
ETL_ASSERT(etl::is_trivially_copyable<T>::value, ETL_ERROR(etl::circular_buffer_incompatible_type));
@ -1395,11 +1413,9 @@ namespace etl
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
virtual
#endif
void repair()
#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -40,40 +40,73 @@ SOFTWARE.
/// Comparisons only using less than operator
///\ingroup utilities
//*****************************************************************************
namespace etl
{
//***************************************************************************
/// Defines <=, >, >= in terms of <
/// Default
/// Defines <=, >, >=, ==, !=, <=> in terms of <
/// Default implementation of TLess is etl::less
//***************************************************************************
template <typename T, typename TLess = etl::less<T> >
struct compare
{
enum cmp_result
{
Less = -1,
Equal = 0,
Greater = 1
};
typedef typename etl::parameter_type<T>::type first_argument_type;
typedef typename etl::parameter_type<T>::type second_argument_type;
typedef bool result_type;
static result_type lt(first_argument_type lhs, second_argument_type rhs)
static ETL_CONSTEXPR bool lt(first_argument_type lhs, second_argument_type rhs)
{
return TLess()(lhs, rhs);
}
static result_type gt(first_argument_type lhs, second_argument_type rhs)
static ETL_CONSTEXPR bool gt(first_argument_type lhs, second_argument_type rhs)
{
return TLess()(rhs, lhs);
}
static result_type lte(first_argument_type lhs, second_argument_type rhs)
static ETL_CONSTEXPR bool lte(first_argument_type lhs, second_argument_type rhs)
{
return !gt(lhs, rhs);
}
static result_type gte(first_argument_type lhs, second_argument_type rhs)
static ETL_CONSTEXPR bool gte(first_argument_type lhs, second_argument_type rhs)
{
return !lt(lhs, rhs);
}
static ETL_CONSTEXPR bool eq(first_argument_type lhs, second_argument_type rhs)
{
return gte(lhs, rhs) && lte(lhs, rhs);
}
static ETL_CONSTEXPR bool ne(first_argument_type lhs, second_argument_type rhs)
{
return !eq(lhs, rhs);
}
static ETL_CONSTEXPR cmp_result cmp(first_argument_type lhs, second_argument_type rhs)
{
return lt(lhs, rhs) ? Less : gt(lhs, rhs) ? Greater : Equal;
}
};
//***************************************************************************
/// Default implementation of TLess is etl::less
//***************************************************************************
#if ETL_USING_CPP11
template <typename T, typename TLess = etl::less<T> >
#else
template <typename T, typename TLess>
#endif
ETL_CONSTEXPR14 int three_way_compare(const T& lhs, const T& rhs)
{
return etl::compare<T>::cmp(lhs, rhs);
}
}
#endif

View File

@ -40,6 +40,8 @@ SOFTWARE.
#include "crc8_ebu.h"
#include "crc8_icode.h"
#include "crc8_itu.h"
#include "crc8_j1850_zero.h"
#include "crc8_j1850.h"
#include "crc8_maxim.h"
#include "crc8_rohc.h"
#include "crc8_wcdma.h"

79
include/etl/crc8_j1850.h Normal file
View File

@ -0,0 +1,79 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
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_CRC8_J1850_INCLUDED
#define ETL_CRC8_J1850_INCLUDED
#include "platform.h"
#include "private/crc_implementation.h"
///\defgroup SAE J1850 8 bit CRC calculation
///\ingroup crc
namespace etl
{
#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION)
template <size_t Table_Size>
using crc8_j1850_t = etl::crc_type<etl::private_crc::crc8_j1850_parameters, Table_Size>;
#else
template <size_t Table_Size>
class crc8_j1850_t : public etl::crc_type<etl::private_crc::crc8_j1850_parameters, Table_Size>
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_j1850_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_j1850_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
#endif
typedef etl::crc8_j1850_t<256U> crc8_j1850_t256;
typedef etl::crc8_j1850_t<16U> crc8_j1850_t16;
typedef etl::crc8_j1850_t<4U> crc8_j1850_t4;
typedef crc8_j1850_t256 crc8_j1850;
}
#endif

View File

@ -0,0 +1,79 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2021 John Wellbelove
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_CRC8_J1850_ZERO_INCLUDED
#define ETL_CRC8_J1850_ZERO_INCLUDED
#include "platform.h"
#include "private/crc_implementation.h"
///\defgroup SAE J1850 Zero 8 bit CRC calculation
///\ingroup crc
namespace etl
{
#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION)
template <size_t Table_Size>
using crc8_j1850_zero_t = etl::crc_type<etl::private_crc::crc8_j1850_zero_parameters, Table_Size>;
#else
template <size_t Table_Size>
class crc8_j1850_zero_t : public etl::crc_type<etl::private_crc::crc8_j1850_zero_parameters, Table_Size>
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
crc8_j1850_zero_t()
{
this->reset();
}
//*************************************************************************
/// Constructor from range.
/// \param begin Start of the range.
/// \param end End of the range.
//*************************************************************************
template<typename TIterator>
crc8_j1850_zero_t(TIterator begin, const TIterator end)
{
this->reset();
this->add(begin, end);
}
};
#endif
typedef etl::crc8_j1850_zero_t<256U> crc8_j1850_zero_t256;
typedef etl::crc8_j1850_zero_t<16U> crc8_j1850_zero_t16;
typedef etl::crc8_j1850_zero_t<4U> crc8_j1850_zero_t4;
typedef crc8_j1850_zero_t256 crc8_j1850_zero;
}
#endif

View File

@ -49,19 +49,19 @@ namespace etl
//***************************************************************************
/// Provides a value that cycles between two limits.
//***************************************************************************
template <typename T, T FIRST = 0, T LAST = 0, bool EtlRuntimeSpecialisation = ((FIRST == 0) && (LAST == 0))>
template <typename T, T First = 0, T Last = 0, bool EtlRuntimeSpecialisation = ((First == 0) && (Last == 0))>
class cyclic_value;
//***************************************************************************
/// Provides a value that cycles between two limits.
/// Provides a value that cycles between two compile time limits.
/// Supports incrementing and decrementing.
///\tparam T The type of the variable.
///\tparam FIRST The first value of the range.
///\tparam LAST The last value of the range.
///\tparam First The first value of the range.
///\tparam Last The last value of the range.
///\ingroup cyclic_value
//***************************************************************************
template <typename T, T FIRST, T LAST>
class cyclic_value<T, FIRST, LAST, false>
template <typename T, T First, T Last>
class cyclic_value<T, First, Last, false>
{
public:
@ -70,7 +70,7 @@ namespace etl
/// The initial value is set to the first value.
//*************************************************************************
cyclic_value()
: value(FIRST)
: value(First)
{
}
@ -87,7 +87,7 @@ namespace etl
//*************************************************************************
/// Copy constructor.
//*************************************************************************
cyclic_value(const cyclic_value<T, FIRST, LAST>& other)
cyclic_value(const cyclic_value<T, First, Last>& other)
: value(other.value)
{
}
@ -95,7 +95,7 @@ namespace etl
//*************************************************************************
/// Assignment operator.
//*************************************************************************
cyclic_value& operator =(const cyclic_value<T, FIRST, LAST>& other)
cyclic_value& operator =(const cyclic_value<T, First, Last>& other)
{
value = other.value;
@ -104,17 +104,18 @@ namespace etl
//*************************************************************************
/// Sets the value.
/// Truncates to the First/Last range.
///\param value The value.
//*************************************************************************
void set(T value_)
{
if (value_ > LAST)
if (value_ > Last)
{
value_ = LAST;
value_ = Last;
}
else if (value_ < FIRST)
else if (value_ < First)
{
value_ = FIRST;
value_ = First;
}
value = value_;
@ -125,7 +126,7 @@ namespace etl
//*************************************************************************
void to_first()
{
value = FIRST;
value = First;
}
//*************************************************************************
@ -133,7 +134,7 @@ namespace etl
//*************************************************************************
void to_last()
{
value = LAST;
value = Last;
}
//*************************************************************************
@ -181,9 +182,9 @@ namespace etl
//*************************************************************************
cyclic_value& operator ++()
{
if (value >= LAST) ETL_UNLIKELY
if (value >= Last) ETL_UNLIKELY
{
value = FIRST;
value = First;
}
else
{
@ -210,9 +211,9 @@ namespace etl
//*************************************************************************
cyclic_value& operator --()
{
if (value <= FIRST) ETL_UNLIKELY
if (value <= First) ETL_UNLIKELY
{
value = LAST;
value = Last;
}
else
{
@ -264,23 +265,23 @@ namespace etl
//*************************************************************************
/// Gets the first value.
//*************************************************************************
const T first() const
static ETL_CONSTEXPR T first()
{
return FIRST;
return First;
}
//*************************************************************************
/// Gets the last value.
//*************************************************************************
const T last() const
static ETL_CONSTEXPR T last()
{
return LAST;
return Last;
}
//*************************************************************************
/// Swaps the values.
//*************************************************************************
void swap(cyclic_value<T, FIRST, LAST>& other)
void swap(cyclic_value<T, First, Last>& other)
{
using ETL_OR_STD::swap; // Allow ADL
@ -290,7 +291,7 @@ namespace etl
//*************************************************************************
/// Swaps the values.
//*************************************************************************
friend void swap(cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs)
friend void swap(cyclic_value<T, First, Last>& lhs, cyclic_value<T, First, Last>& rhs)
{
lhs.swap(rhs);
}
@ -298,7 +299,7 @@ namespace etl
//*************************************************************************
/// Operator ==.
//*************************************************************************
friend bool operator == (const cyclic_value<T, FIRST, LAST>& lhs, const cyclic_value<T, FIRST, LAST>& rhs)
friend bool operator == (const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
{
return lhs.value == rhs.value;
}
@ -306,7 +307,7 @@ namespace etl
//*************************************************************************
/// Operator !=.
//*************************************************************************
friend bool operator != (const cyclic_value<T, FIRST, LAST>& lhs, const cyclic_value<T, FIRST, LAST>& rhs)
friend bool operator != (const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
{
return !(lhs == rhs);
}
@ -317,15 +318,15 @@ namespace etl
};
//***************************************************************************
/// Provides a value that cycles between two limits.
/// Provides a value that cycles between two run time limits.
/// Supports incrementing and decrementing.
///\tparam T The type of the variable.
///\tparam FIRST The first value of the range.
///\tparam LAST The last value of the range.
///\tparam First The first value of the range.
///\tparam Last The last value of the range.
///\ingroup cyclic_value
//***************************************************************************
template <typename T, T FIRST, T LAST>
class cyclic_value<T, FIRST, LAST, true>
template <typename T, T First, T Last>
class cyclic_value<T, First, Last, true>
{
public:
@ -335,9 +336,9 @@ namespace etl
/// The initial value is set to the first value.
//*************************************************************************
cyclic_value()
: value(FIRST),
first_value(FIRST),
last_value(LAST)
: value(First)
, first_value(First)
, last_value(Last)
{
}
@ -348,9 +349,9 @@ namespace etl
///\param last The last value in the range.
//*************************************************************************
cyclic_value(T first_, T last_)
: value(first_),
first_value(first_),
last_value(last_)
: value(first_)
, first_value(first_)
, last_value(last_)
{
}
@ -372,9 +373,9 @@ namespace etl
/// Copy constructor.
//*************************************************************************
cyclic_value(const cyclic_value& other)
: value(other.value),
first_value(other.first_value),
last_value(other.last_value)
: value(other.value)
, first_value(other.first_value)
, last_value(other.last_value)
{
}
@ -570,7 +571,7 @@ namespace etl
//*************************************************************************
/// Swaps the values.
//*************************************************************************
void swap(cyclic_value<T, FIRST, LAST>& other)
void swap(cyclic_value<T, First, Last>& other)
{
using ETL_OR_STD::swap; // Allow ADL
@ -582,7 +583,7 @@ namespace etl
//*************************************************************************
/// Swaps the values.
//*************************************************************************
friend void swap(cyclic_value<T, FIRST, LAST>& lhs, cyclic_value<T, FIRST, LAST>& rhs)
friend void swap(cyclic_value<T, First, Last>& lhs, cyclic_value<T, First, Last>& rhs)
{
lhs.swap(rhs);
}
@ -590,7 +591,7 @@ namespace etl
//*************************************************************************
/// Operator ==.
//*************************************************************************
friend bool operator == (const cyclic_value<T, FIRST, LAST>& lhs, const cyclic_value<T, FIRST, LAST>& rhs)
friend bool operator == (const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
{
return (lhs.value == rhs.value) &&
(lhs.first_value == rhs.first_value) &&
@ -600,7 +601,7 @@ namespace etl
//*************************************************************************
/// Operator !=.
//*************************************************************************
friend bool operator != (const cyclic_value<T, FIRST, LAST>& lhs, const cyclic_value<T, FIRST, LAST>& rhs)
friend bool operator != (const cyclic_value<T, First, Last>& lhs, const cyclic_value<T, First, Last>& rhs)
{
return !(lhs == rhs);
}

View File

@ -41,7 +41,6 @@ SOFTWARE.
#include "debug_count.h"
#include "algorithm.h"
#include "type_traits.h"
#include "iterator.h"
#include "placement_new.h"
#include "initializer_list.h"
@ -258,17 +257,17 @@ namespace etl
//***************************************************
iterator(const iterator& other)
: index(other.index),
p_deque(other.p_deque),
p_buffer(other.p_buffer)
: index(other.index)
, p_deque(other.p_deque)
, p_buffer(other.p_buffer)
{
}
//***************************************************
iterator& operator =(const iterator& other)
{
index = other.index;
p_deque = other.p_deque;
index = other.index;
p_deque = other.p_deque;
p_buffer = other.p_buffer;
return *this;
@ -352,6 +351,24 @@ namespace etl
return &p_buffer[index];
}
//***************************************************
reference operator [](size_t i)
{
iterator result(*this);
result += i;
return *result;
}
//***************************************************
const_reference operator [](size_t i) const
{
iterator result(*this);
result += i;
return *result;
}
//***************************************************
friend iterator operator +(const iterator& lhs, difference_type offset)
{
@ -360,6 +377,14 @@ namespace etl
return result;
}
//***************************************************
friend iterator operator +(difference_type offset, const iterator& lhs)
{
iterator result(lhs);
result += offset;
return result;
}
//***************************************************
friend iterator operator -(const iterator& lhs, difference_type offset)
{
@ -596,6 +621,15 @@ namespace etl
return &p_buffer[index];
}
//***************************************************
reference operator [](size_t i)
{
iterator result(*this);
result += i;
return *result;
}
//***************************************************
friend const_iterator operator +(const const_iterator& lhs, difference_type offset)
{
@ -604,6 +638,14 @@ namespace etl
return result;
}
//***************************************************
friend const_iterator operator +(difference_type offset, const const_iterator& lhs)
{
const_iterator result(lhs);
result += offset;
return result;
}
//***************************************************
friend const_iterator operator -(const const_iterator& lhs, difference_type offset)
{
@ -2054,22 +2096,6 @@ namespace etl
return distance(rhs, lhs);
}
//*************************************************************************
/// - operator for reverse_iterator
//*************************************************************************
friend difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs)
{
return distance(lhs.base(), rhs.base());
}
//*************************************************************************
/// - operator for const_reverse_iterator
//*************************************************************************
friend difference_type operator -(const const_reverse_iterator& lhs, const const_reverse_iterator& rhs)
{
return distance(lhs.base(), rhs.base());
}
//*************************************************************************
/// Assignment operator.
//*************************************************************************
@ -2483,11 +2509,9 @@ namespace etl
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_IDEQUE_REPAIR_ENABLE
virtual
#endif
void repair()
#ifdef ETL_IDEQUE_REPAIR_ENABLE
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED

View File

@ -38,6 +38,7 @@ SOFTWARE.
#include "error_handler.h"
#include "utility.h"
#include "variant.h"
#include "initializer_list.h"
namespace etl
{
@ -353,6 +354,7 @@ namespace etl
{
}
#if ETL_HAS_INITIALIZER_LIST
//*******************************************
/// Construct value type from initializser_list and arguments.
//*******************************************
@ -361,6 +363,7 @@ namespace etl
: storage(il, etl::forward<Args>(args)...)
{
}
#endif
//*******************************************
/// Construct error type from arguments.
@ -608,17 +611,23 @@ namespace etl
template <typename... Args>
ETL_CONSTEXPR14 value_type& emplace(Args&&... args) ETL_NOEXCEPT
{
storage.emplace(etl::forward<Args>(args)...);
storage.template emplace<value_type>(etl::forward<Args>(args)...);
return value();
}
//*******************************************
///
//*******************************************
#if ETL_HAS_INITIALIZER_LIST
template <typename U, typename... Args>
ETL_CONSTEXPR14 value_type& emplace(std::initializer_list<U>& il, Args&&... args) ETL_NOEXCEPT
ETL_CONSTEXPR14 value_type& emplace(std::initializer_list<U> il, Args&&... args) ETL_NOEXCEPT
{
storage.emplace(il, etl::forward<Args>(args)...);
storage.template emplace<value_type>(il, etl::forward<Args>(args)...);
return value();
}
#endif
#else
//*******************************************
///

View File

@ -76,7 +76,7 @@ namespace etl
}
//***********************************
add_insert_iterator& operator =(typename TFrame_Check_Sequence::value_type value)
add_insert_iterator& operator =(uint8_t value)
{
p_fcs->add(value);
return *this;

View File

@ -158,7 +158,7 @@ namespace etl
};
//***************************************************************************
/// Exception for forbidden state chages.
/// Exception for forbidden state changes.
//***************************************************************************
class fsm_state_composite_state_change_forbidden : public etl::fsm_exception
{
@ -169,6 +169,18 @@ namespace etl
}
};
//***************************************************************************
/// Exception for message received but not started.
//***************************************************************************
class fsm_not_started : public etl::fsm_exception
{
public:
fsm_not_started(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:not started", ETL_FSM_FILE_ID"F"), file_name_, line_number_)
{
}
};
namespace private_fsm
{
template <typename T = void>
@ -404,31 +416,38 @@ namespace etl
//*******************************************
void receive(const etl::imessage& message) ETL_OVERRIDE
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if (have_changed_state(next_state_id))
if (is_started())
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
do
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
do
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
}
else if (is_self_transition(next_state_id))
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
p_state->on_enter_state();
}
}
else if (is_self_transition(next_state_id))
else
{
p_state->on_exit_state();
p_state->on_enter_state();
ETL_ASSERT_FAIL(ETL_ERROR(etl::fsm_not_started));
}
}
@ -587,11 +606,11 @@ namespace etl
//********************************************
template <typename TMessage>
bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& state_id)
bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& new_state_id)
{
if (TMessage::ID == msg.get_message_id())
{
state_id = static_cast<TDerived*>(this)->on_event(static_cast<const TMessage&>(msg));
new_state_id = static_cast<TDerived*>(this)->on_event(static_cast<const TMessage&>(msg));
return true;
}
else

View File

@ -32,6 +32,7 @@ SOFTWARE.
#define ETL_FUNCTIONAL_INCLUDED
#include "platform.h"
#include "utility.h"
///\defgroup functional functional
///\ingroup utilities
@ -528,6 +529,73 @@ namespace etl
return ~lhs;
}
};
#if ETL_USING_CPP11
namespace private_functional
{
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
class mem_fn_impl
{
public:
typedef TReturnType(TClassType::* MemberFunctionType)(TArgs...);
ETL_CONSTEXPR mem_fn_impl(MemberFunctionType member_function_)
: member_function(member_function_)
{
}
ETL_CONSTEXPR TReturnType operator()(TClassType& instance, TArgs... args) const
{
return (instance.*member_function)(etl::forward<TArgs>(args)...);
}
private:
MemberFunctionType member_function;
};
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
class const_mem_fn_impl
{
public:
typedef TReturnType(TClassType::* MemberFunctionType)(TArgs...) const;
ETL_CONSTEXPR const_mem_fn_impl(MemberFunctionType member_function_)
: member_function(member_function_)
{
}
ETL_CONSTEXPR TReturnType operator()(const TClassType& instance, TArgs... args) const
{
return (instance.*member_function)(etl::forward<TArgs>(args)...);
}
private:
MemberFunctionType member_function;
};
}
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
ETL_CONSTEXPR
private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType(TClassType::* member_function)(TArgs...))
{
return private_functional::mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
}
//***************************************************************************
template<typename TReturnType, typename TClassType, typename... TArgs>
ETL_CONSTEXPR
private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...> mem_fn(TReturnType(TClassType::* member_function)(TArgs...) const)
{
return private_functional::const_mem_fn_impl<TReturnType, TClassType, TArgs...>(member_function);
}
#endif
}
#endif

View File

@ -177,7 +177,7 @@ namespace etl
};
//***************************************************************************
/// Exception for forbidden state chages.
/// Exception for forbidden state changes.
//***************************************************************************
class fsm_state_composite_state_change_forbidden : public etl::fsm_exception
{
@ -188,6 +188,18 @@ namespace etl
}
};
//***************************************************************************
/// Exception for message received but not started.
//***************************************************************************
class fsm_not_started : public etl::fsm_exception
{
public:
fsm_not_started(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:not started", ETL_FSM_FILE_ID"F"), file_name_, line_number_)
{
}
};
namespace private_fsm
{
template <typename T = void>
@ -430,31 +442,38 @@ namespace etl
//*******************************************
void receive(const etl::imessage& message) ETL_OVERRIDE
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if (have_changed_state(next_state_id))
if (is_started())
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
do
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
do
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
}
else if (is_self_transition(next_state_id))
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
p_state->on_enter_state();
}
}
else if (is_self_transition(next_state_id))
else
{
p_state->on_exit_state();
p_state->on_enter_state();
ETL_ASSERT_FAIL(ETL_ERROR(etl::fsm_not_started));
}
}
@ -613,11 +632,11 @@ namespace etl
//********************************************
template <typename TMessage>
bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& state_id)
bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& new_state_id)
{
if (TMessage::ID == msg.get_message_id())
{
state_id = static_cast<TDerived*>(this)->on_event(static_cast<const TMessage&>(msg));
new_state_id = static_cast<TDerived*>(this)->on_event(static_cast<const TMessage&>(msg));
return true;
}
else

View File

@ -111,7 +111,7 @@ namespace etl
///
//********************************************
#include "private/diagnostic_uninitialized_push.h"
template <typename T>
template <typename T, typename = typename etl::enable_if<IsIMessage<T> || IsInMessageList<T>, int>::type>
explicit message_packet(T&& msg)
: valid(true)
{
@ -133,10 +133,6 @@ namespace etl
{
add_new_message_type<T>(etl::forward<T>(msg));
}
else if constexpr (IsMessagePacket<T>)
{
copy(etl::forward<T>(msg));
}
else
{
ETL_STATIC_ASSERT(IsInMessageList<T>, "Message not in packet type list");
@ -144,6 +140,30 @@ namespace etl
}
#include "private/diagnostic_pop.h"
//**********************************************
message_packet(const message_packet& other)
{
valid = other.is_valid();
if (valid)
{
add_new_message(other.get());
}
}
#if ETL_USING_CPP11
//**********************************************
message_packet(message_packet&& other)
{
valid = other.is_valid();
if (valid)
{
add_new_message(etl::move(other.get()));
}
}
#endif
//**********************************************
void copy(const message_packet& other)
{

View File

@ -51,7 +51,7 @@ cog.outl("//********************************************************************
// Note: You will need Python and COG installed.
//
// python -m cogapp -d -e -omessage_router.h -DHandlers=<n> message_router_generator.h
// Where <n> is the number of messages to support.
// Where <n> is the maximum number of messages to support.
//
// e.g.
// To generate handlers for up to 16 messages...
@ -212,8 +212,8 @@ namespace etl
}
//********************************************
null_message_router(etl::imessage_router& successor)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor)
null_message_router(etl::imessage_router& successor_)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_)
{
}
@ -290,8 +290,8 @@ namespace etl
}
//********************************************
message_producer(etl::imessage_router& successor)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor)
message_producer(etl::imessage_router& successor_)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_)
{
}
@ -303,8 +303,8 @@ namespace etl
}
//********************************************
message_producer(etl::message_router_id_t id_, etl::imessage_router& successor)
: imessage_router(id_, successor)
message_producer(etl::message_router_id_t id_, etl::imessage_router& successor_)
: imessage_router(id_, successor_)
{
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
@ -354,11 +354,22 @@ namespace etl
}
};
//***************************************************************************
/// Is T ultimately derived from etl::imessage_router?
//***************************************************************************
template <typename T>
struct is_message_router : public etl::bool_constant<etl::is_base_of<etl::imessage_router, typename etl::remove_cvref<T>::type>::value>
{
};
//***************************************************************************
/// Send a message to a router.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
const etl::imessage& message)
template <typename TRouter, typename TMessage>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value, void>::type
send_message(TRouter& destination,
const TMessage& message)
{
destination.receive(message);
}
@ -366,8 +377,11 @@ namespace etl
//***************************************************************************
/// Send a shared message to a router.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::shared_message message)
template <typename TRouter>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value, void>::type
send_message(TRouter& destination,
etl::shared_message message)
{
destination.receive(message);
}
@ -375,9 +389,12 @@ namespace etl
//***************************************************************************
/// Send a message to a router with a particular id.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::message_router_id_t id,
const etl::imessage& message)
template <typename TRouter, typename TMessage>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value, void>::type
send_message(TRouter& destination,
etl::message_router_id_t id,
const TMessage& message)
{
destination.receive(id, message);
}
@ -385,9 +402,12 @@ namespace etl
//***************************************************************************
/// Send a shared message to a router with a particular id.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::message_router_id_t id,
etl::shared_message message)
template <typename TRouter>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value, void>::type
send_message(TRouter& destination,
etl::message_router_id_t id,
etl::shared_message message)
{
destination.receive(id, message);
}

View File

@ -74,7 +74,7 @@ cog.outl("//********************************************************************
///\defgroup type_traits type_traits
/// A set of type traits definitions.
/// Derived from either the standard or alternate definitions, dependant on whether or not ETL_NO_STL is defined.
/// Derived from either the standard or alternate definitions, dependent on whether or not ETL_NO_STL is defined.
/// \ingroup utilities
#if ETL_USING_STL && ETL_USING_CPP11
@ -2077,6 +2077,21 @@ typedef integral_constant<bool, true> true_type;
{
};
#if ETL_USING_CPP11
//*********************************************
// is_default_constructible
template<typename T, typename = void>
struct is_default_constructible : etl::false_type { };
template<typename T>
struct is_default_constructible<T, etl::void_t<decltype(T())>> : etl::true_type { };
#else
template <typename T>
struct is_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
{
};
#endif
#if ETL_USING_CPP17
template <typename T1, typename T2>
@ -2088,6 +2103,9 @@ typedef integral_constant<bool, true> true_type;
template<typename T, typename... TArgs>
inline constexpr bool is_constructible_v = etl::is_constructible<T, TArgs...>::value;
template<typename T, typename... TArgs>
inline constexpr bool is_default_constructible_v = etl::is_default_constructible<T, TArgs...>::value;
template<typename T>
inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible<T>::value;

View File

@ -55,7 +55,7 @@ namespace etl
/// Can only be called once.
/// Subsequent calls will do nothing.
///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true.
/// If the first state has child states then they will be recersively entered.
/// If the first state has child states then they will be recursively entered.
//*******************************************
void start(bool call_on_enter_state = true) ETL_OVERRIDE
{
@ -98,30 +98,37 @@ namespace etl
//*******************************************
void receive(const etl::imessage& message) ETL_OVERRIDE
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if (next_state_id != ifsm_state::No_State_Change)
if (is_started())
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
// Have we changed state?
if (p_next_state != p_state)
if (next_state_id != ifsm_state::No_State_Change)
{
etl::ifsm_state* p_root = common_ancestor(p_state, p_next_state);
do_exits(p_root, p_state);
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
p_state = p_next_state;
next_state_id = do_enters(p_root, p_next_state, true);
if (next_state_id != ifsm_state::No_State_Change)
// Have we changed state?
if (p_next_state != p_state)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_state = state_list[next_state_id];
etl::ifsm_state* p_root = common_ancestor(p_state, p_next_state);
do_exits(p_root, p_state);
p_state = p_next_state;
next_state_id = do_enters(p_root, p_next_state, true);
if (next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT_OR_RETURN(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_state = state_list[next_state_id];
}
}
}
}
else
{
ETL_ASSERT_FAIL(ETL_ERROR(etl::fsm_not_started));
}
}
private:

View File

@ -209,7 +209,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_forward_list_empty));
#endif
remove_link_after(start);
disconnect_link_after(start);
}
//*************************************************************************
@ -297,7 +297,7 @@ namespace etl
//*************************************************************************
/// Remove a link.
//*************************************************************************
void remove_link_after(link_type& link)
void disconnect_link_after(link_type& link)
{
link_type* p_next = link.etl_next;
@ -333,6 +333,89 @@ namespace etl
start.etl_next = &terminator;
current_size = 0;
}
//*************************************************************************
/// Tests if the link is in this list.
/// Returns the previous link to it, if found, otherwise ETL_NULLPTR.
//*************************************************************************
link_type* is_link_in_list(link_type& search_link)
{
link_type* p_link = start.etl_next;
link_type* p_previous = &start;
while (p_link != ETL_NULLPTR)
{
if (&search_link == p_link)
{
return p_previous;
}
p_previous = p_link;
if (p_link != ETL_NULLPTR)
{
p_link = p_link->link_type::etl_next;
}
}
return ETL_NULLPTR;
}
//*************************************************************************
/// Remove the specified node from the list.
/// Returns ETL_NULLPTR if the link was not in this list.
/// Returns the next
//*************************************************************************
link_type* remove_link(link_type& link)
{
link_type* result = ETL_NULLPTR;
link_type* p_previous = is_link_in_list(link);
if (p_previous != ETL_NULLPTR)
{
link_type* p_next = link.etl_next;
disconnect_link_after(*p_previous);
if (p_next != &this->terminator)
{
result = p_next;
}
}
return result;
}
//*************************************************************************
/// Remove a range of elements.
//*************************************************************************
link_type* remove_link_range_after(link_type* p_first, link_type* p_last)
{
link_type* p_after = p_first->etl_next;
// Join the ends.
etl::link<link_type>(p_first, p_last);
// Unlink the erased range.
link_type* p_unlink = p_after;
while (p_unlink != p_last)
{
link_type* p_next = p_unlink->etl_next;
p_unlink->clear();
p_unlink = p_next;
}
if (p_after == &this->terminator)
{
return ETL_NULLPTR;
}
else
{
return p_last;
}
}
};
template <typename TLink>
@ -361,6 +444,8 @@ namespace etl
typedef intrusive_forward_list<TValue, TLink> list_type;
typedef TValue node_type;
//*************************************************************************
/// iterator.
//*************************************************************************
@ -404,7 +489,9 @@ namespace etl
reference operator *() const
{
#include "etl/private/diagnostic_null_dereference_push.h"
return *static_cast<pointer>(p_value);
#include "etl/private/diagnostic_pop.h"
}
pointer operator &() const
@ -662,7 +749,7 @@ namespace etl
if (next != end())
{
++next;
this->remove_link_after(*position.p_value);
this->disconnect_link_after(*position.p_value);
}
}
@ -680,22 +767,9 @@ namespace etl
link_type* p_first = first.p_value;
link_type* p_last = last.p_value;
link_type* p_after = p_first->etl_next;
// Join the ends.
etl::link<link_type>(p_first, p_last);
link_type* p_after = this->remove_link_range_after(p_first, p_last);
// Unlink the erased range.
link_type* p_unlink = p_after;
while (p_unlink != p_last)
{
link_type* p_next = p_unlink->etl_next;
p_unlink->clear();
p_unlink = p_next;
}
if (p_after == &this->terminator)
if (p_after == ETL_NULLPTR)
{
return end();
}
@ -710,6 +784,14 @@ namespace etl
}
}
//*************************************************************************
/// Erases the specified node.
//*************************************************************************
node_type* erase(node_type& node)
{
return static_cast<node_type*>(this->remove_link(node));
}
//*************************************************************************
/// Removes all but the one element from every consecutive group of equal
/// elements in the container.
@ -730,7 +812,7 @@ namespace etl
// Is this value the same as the last?
if (isEqual(*static_cast<pointer>(current), *static_cast<pointer>(last)))
{
this->remove_link_after(*last);
this->disconnect_link_after(*last);
}
else
{

View File

@ -175,7 +175,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty));
#endif
remove_link(get_head());
disconnect_link(get_head());
}
//*************************************************************************
@ -196,7 +196,7 @@ namespace etl
#if defined(ETL_CHECK_PUSH_POP)
ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty));
#endif
remove_link(get_tail());
disconnect_link(get_tail());
}
//*************************************************************************
@ -320,7 +320,7 @@ namespace etl
//*************************************************************************
/// Remove a link.
//*************************************************************************
void remove_link(link_type& link)
void disconnect_link(link_type& link)
{
etl::unlink<link_type>(link);
--current_size;
@ -329,7 +329,7 @@ namespace etl
//*************************************************************************
/// Remove a link.
//*************************************************************************
void remove_link(link_type* link)
void disconnect_link(link_type* link)
{
etl::unlink<link_type>(*link);
--current_size;
@ -375,6 +375,74 @@ namespace etl
etl::link(terminal_link, terminal_link);
current_size = 0;
}
//*************************************************************************
/// Tests if the link is in this list.
//*************************************************************************
bool is_link_in_list(link_type& search_link) const
{
link_type* p_link = terminal_link.link_type::etl_next;
while (p_link != &terminal_link)
{
if (&search_link == p_link)
{
return true;
}
p_link = p_link->link_type::etl_next;
}
return false;
}
//*************************************************************************
/// Remove the specified node from the list.
/// Returns ETL_NULLPTR if the link was not in this list or was the last in the list.
//*************************************************************************
link_type* remove_link(link_type& link)
{
link_type* result = ETL_NULLPTR;
if (is_link_in_list(link))
{
link_type* p_next = link.etl_next;
disconnect_link(link);
if (p_next != &terminal_link)
{
result = p_next;
}
}
return result;
}
//*************************************************************************
/// Removes a range of links.
//*************************************************************************
link_type* remove_link_range(link_type* p_first, link_type* p_last)
{
// Join the ends.
etl::link<link_type>(p_first->etl_previous, p_last);
while (p_first != p_last)
{
link_type* p_next = p_first->etl_next;
p_first->clear();
p_first = p_next;
}
if (p_last == &terminal_link)
{
return ETL_NULLPTR;
}
else
{
return p_last;
}
}
};
//***************************************************************************
@ -392,6 +460,8 @@ namespace etl
typedef intrusive_list<TValue, TLink> list_type;
typedef TValue node_type;
// STL style typedefs.
typedef TValue value_type;
typedef value_type* pointer;
@ -458,7 +528,9 @@ namespace etl
reference operator *() const
{
#include "etl/private/diagnostic_null_dereference_push.h"
return *static_cast<pointer>(p_value);
#include "etl/private/diagnostic_pop.h"
}
pointer operator &() const
@ -724,7 +796,7 @@ namespace etl
iterator next(position);
++next;
this->remove_link(*position.p_value);
this->disconnect_link(*position.p_value);
return next;
}
@ -737,7 +809,7 @@ namespace etl
iterator next(position);
++next;
this->remove_link(*position.p_value);
this->disconnect_link(*position.p_value);
return next;
}
@ -756,17 +828,9 @@ namespace etl
this->current_size -= etl::distance(first, last);
// Join the ends.
etl::link<link_type>(p_first->etl_previous, p_last);
p_last = this->remove_link_range(p_first, p_last);
while (p_first != p_last)
{
link_type* p_next = p_first->etl_next;
p_first->clear();
p_first = p_next;
}
if (p_last == &this->terminal_link)
if (p_last == ETL_NULLPTR)
{
return end();
}
@ -776,6 +840,14 @@ namespace etl
}
}
//*************************************************************************
/// Erases the specified node.
//*************************************************************************
node_type* erase(node_type& node)
{
return static_cast<node_type*>(this->remove_link(node));
}
//*************************************************************************
/// Removes all but the one element from every consecutive group of equal
/// elements in the container.

View File

@ -583,36 +583,25 @@ namespace etl
//***************************************************************************
//***************************************************************************
///\brief Turns assignment into insertion.
///
/// These are output iterators, constructed from a container-of-T.
/// Assigning a T to the iterator appends it to the container using push_back.
///
/// @tparam TContainer
/// Turns assignment into push_back
//***************************************************************************
template <typename TContainer>
class back_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
{
public:
/// A nested typedef for the type of whatever container you used.
typedef TContainer container_type;
/// The only way to create this %iterator is with a container.
//***************************************************************************
/// Constructor
//***************************************************************************
explicit ETL_CONSTEXPR14 back_insert_iterator(TContainer& c)
: container(etl::addressof(c))
{
}
//***************************************************************************
/// This kind of %iterator doesn't really have a @a position in the
/// container (you can think of the position as being permanently at
/// the end, if you like). Assigning a value to the %iterator will
/// always append the value to the end of the container.
///
/// @param value An instance of whatever type container_type::const_reference is;
/// presumably a reference-to-const T for container<T>.
/// @return This %iterator, for chained operations.
/// Assignment operator
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator& operator =(const typename TContainer::value_type& value)
{
@ -635,7 +624,6 @@ namespace etl
//***************************************************************************
/// Dereference operator.
/// Simply returns *this.
//***************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 back_insert_iterator& operator *()
{
@ -644,7 +632,6 @@ namespace etl
//***************************************************************************
/// Pre-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator& operator ++()
{
@ -653,7 +640,6 @@ namespace etl
//***************************************************************************
/// Post-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 back_insert_iterator operator ++(int)
{
@ -666,15 +652,7 @@ namespace etl
};
//***************************************************************************
/// This wrapper function helps in creating back_insert_iterator instances.
/// Typing the name of the %iterator requires knowing the precise full
/// type of the container, which can be tedious and impedes generic
/// programming. Using this function lets you take advantage of automatic
/// template parameter deduction, making the compiler match the correct types for you.
///
/// @tparam TContainer The container type.
/// @param container A container of arbitrary type.
/// @return An instance of back_insert_iterator working on @p container.
/// Creates a back_insert_iterator from a container.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
@ -689,28 +667,17 @@ namespace etl
//***************************************************************************
//***************************************************************************
///\brief Turns assignment into insertion.
///
/// These are output iterators, constructed from a container-of-T.
/// Assigning a T to the iterator prepends it to the container using
/// push_front.
///
/// Tip: Using the front_inserter function to create these iterators can
/// save typing.
///
///\tparam TContainer The container type.
/// Turns assignment into a push_front.
//***************************************************************************
template <typename TContainer>
class front_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
{
public:
/// A nested typedef for the type of whatever container you used.
typedef TContainer container_type;
//***************************************************************************
/// Constructor
/// The only way to create this %iterator is with a container.
//***************************************************************************
explicit ETL_CONSTEXPR14 front_insert_iterator(TContainer& c)
: container(etl::addressof(c))
@ -718,15 +685,7 @@ namespace etl
}
//***************************************************************************
/// This kind of %iterator doesn't really have a @a position in the
/// container (you can think of the position as being permanently at
/// the front, if you like). Assigning a value to the %iterator will
/// always prepend the value to the front of the container.
///
/// @param value An instance of whatever type
/// container_type::const_reference is; presumably a
/// reference-to-const T for container<T>.
/// @return This %iterator, for chained operations.
/// Assignment operator
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator& operator =(const typename TContainer::value_type& value)
{
@ -747,7 +706,6 @@ namespace etl
//***************************************************************************
/// Dereference operator.
/// Simply returns *this.
//***************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 front_insert_iterator& operator *()
{
@ -756,7 +714,6 @@ namespace etl
//***************************************************************************
/// Pre-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator& operator ++()
{
@ -765,7 +722,6 @@ namespace etl
//***************************************************************************
/// Post-increment operator.
/// Simply returns *this. (This %iterator does not @a move.)
//***************************************************************************
ETL_CONSTEXPR14 front_insert_iterator operator ++(int)
{
@ -778,16 +734,7 @@ namespace etl
};
//***************************************************************************
/// This wrapper function helps in creating front_insert_iterator instances.
/// Typing the name of the %iterator requires knowing the precise full
/// type of the container, which can be tedious and impedes generic
/// programming. Using this function lets you take advantage of automatic
/// template parameter deduction, making the compiler match the correct
/// types for you.
///
///\tparam TContainer The container type.
///\param container A container of arbitrary type.
///\return An instance of front_insert_iterator working on @p x.
/// Creates a front_insert_iterator from a container.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
@ -797,6 +744,90 @@ namespace etl
return etl::front_insert_iterator<TContainer>(container);
}
//***************************************************************************
// push_insert_iterator
//***************************************************************************
//***************************************************************************
/// Turns assignment into a push.
//***************************************************************************
template <typename TContainer>
class push_insert_iterator : public etl::iterator<ETL_OR_STD::output_iterator_tag, void, void, void, void>
{
public:
typedef TContainer container_type;
//***************************************************************************
/// Constructor
//***************************************************************************
explicit ETL_CONSTEXPR14 push_insert_iterator(TContainer& c)
: container(etl::addressof(c))
{
}
//***************************************************************************
/// Assignment operator
//***************************************************************************
ETL_CONSTEXPR14 push_insert_iterator& operator =(const typename TContainer::value_type& value)
{
container->push(value);
return (*this);
}
#if ETL_USING_CPP11
//***************************************************************************
/// Move assignment operator.
//***************************************************************************
ETL_CONSTEXPR14 push_insert_iterator& operator =(typename TContainer::value_type&& value)
{
container->push(etl::move(value));
return (*this);
}
#endif // ETL_USING_CPP11
//***************************************************************************
/// Dereference operator.
//***************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 push_insert_iterator& operator *()
{
return (*this);
}
//***************************************************************************
/// Pre-increment operator.
//***************************************************************************
ETL_CONSTEXPR14 push_insert_iterator& operator ++()
{
return (*this);
}
//***************************************************************************
/// Post-increment operator.
//***************************************************************************
ETL_CONSTEXPR14 push_insert_iterator operator ++(int)
{
return (*this);
}
protected:
TContainer* container;
};
//***************************************************************************
/// Creates a push_insert_iterator from a container.
//***************************************************************************
template <typename TContainer>
ETL_NODISCARD
ETL_CONSTEXPR14
etl::push_insert_iterator<TContainer> push_inserter(TContainer& container)
{
return etl::push_insert_iterator<TContainer>(container);
}
//***************************************************************************
// Helper templates.
//***************************************************************************

View File

@ -80,19 +80,19 @@ SOFTWARE.
#if defined(ETL_NO_CPP_NAN_SUPPORT)
#if defined(NAN)
#include "etl/private/diagnostic_useless_cast_push.h"
#include "private/diagnostic_useless_cast_push.h"
#define ETL_NANF NAN
#define ETL_NAN static_cast<double>(NAN)
#define ETL_NANL static_cast<long double>(NAN)
#define ETL_HAS_NAN true
#include "etl/private/diagnostic_pop.h"
#include "private/diagnostic_pop.h"
#else
#include "etl/private/diagnostic_useless_cast_push.h"
#include "private/diagnostic_useless_cast_push.h"
#define ETL_NANF HUGE_VALF
#define ETL_NAN HUGE_VAL
#define ETL_NANL HUGE_VALL
#define ETL_HAS_NAN false
#include "etl/private/diagnostic_pop.h"
#include "private/diagnostic_pop.h"
#endif
#else
#define ETL_NANF nanf("")

View File

@ -43,7 +43,6 @@ SOFTWARE.
#include "type_traits.h"
#include "algorithm.h"
#include "memory.h"
#include "iterator.h"
#include "static_assert.h"
#include "parameter_type.h"
#include "placement_new.h"

View File

@ -1496,10 +1496,10 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = allocate_data_node();
::new (&node.value) value_type(value);
Data_Node* node = allocate_data_node();
::new (&node->value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
//*************************************************************************
@ -1507,12 +1507,12 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node_with_key(const_key_reference key)
{
Data_Node& node = allocate_data_node();
Data_Node* node = allocate_data_node();
::new ((void*)etl::addressof(node.value.first)) key_type(key);
::new ((void*)etl::addressof(node.value.second)) mapped_type();
::new ((void*)etl::addressof(node->value.first)) key_type(key);
::new ((void*)etl::addressof(node->value.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#if ETL_USING_CPP11
@ -1521,10 +1521,10 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = allocate_data_node();
::new (&node.value) value_type(etl::move(value));
Data_Node* node = allocate_data_node();
::new (&node->value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
//*************************************************************************
@ -1532,12 +1532,12 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node_with_key(rvalue_key_reference key)
{
Data_Node& node = allocate_data_node();
Data_Node* node = allocate_data_node();
::new ((void*)etl::addressof(node.value.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node.value.second)) mapped_type();
::new ((void*)etl::addressof(node->value.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node->value.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#endif
@ -1545,10 +1545,10 @@ namespace etl
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& allocate_data_node()
Data_Node* allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();
return (p_node_pool->*func)();
}
//*************************************************************************

View File

@ -1424,7 +1424,10 @@ namespace etl
//*********************************
unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT
{
reset(nullptr);
if (p)
{
reset(nullptr);
}
return *this;
}
@ -1432,7 +1435,10 @@ namespace etl
//*********************************
unique_ptr& operator =(void*) ETL_NOEXCEPT
{
reset(NULL);
if (p)
{
reset(NULL);
}
return *this;
}

View File

@ -62,6 +62,8 @@ namespace etl
}
};
class message_tag {};
#if ETL_HAS_VIRTUAL_MESSAGES
//***************************************************************************
/// Message interface.
@ -85,10 +87,14 @@ namespace etl
/// Virtual.
//***************************************************************************
template <etl::message_id_t ID_, typename TBase = etl::imessage>
class message : public TBase
class message : public TBase, public etl::message_tag
{
public:
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TBase>::value), "TBase is not derived from etl::imessage");
typedef TBase base_type;
//***********************************
ETL_NODISCARD virtual etl::message_id_t get_message_id() const ETL_NOEXCEPT ETL_OVERRIDE
{
@ -149,12 +155,14 @@ namespace etl
/// Non-virtual.
//***************************************************************************
template <etl::message_id_t ID_, typename TBase = etl::imessage>
class message : public TBase
class message : public TBase, public etl::message_tag
{
public:
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TBase>::value), "TBase is not derived from etl::imessage");
typedef TBase base_type;
//***********************************
message() ETL_NOEXCEPT
: TBase(ID)
@ -183,6 +191,78 @@ namespace etl
//***************************************************************************
template <etl::message_id_t ID_, typename TBase>
ETL_CONSTANT etl::message_id_t etl::message<ID_, TBase>::ID;
//***************************************************************************
/// Is T an etl::imessage?
//***************************************************************************
template <typename T>
struct is_imessage : public etl::bool_constant<etl::is_same<etl::imessage, typename etl::remove_cvref<T>::type>::value>
{
};
//***************************************************************************
/// Is T ultimately derived from etl::imessage?
//***************************************************************************
template <typename T>
struct is_message : public etl::bool_constant<etl::is_base_of<etl::imessage, typename etl::remove_cvref<T>::type>::value>
{
};
//***************************************************************************
/// Is T an etl::message<> or derived from etl::message<>
//***************************************************************************
template <typename T>
struct is_message_type : public etl::bool_constant<etl::is_base_of<etl::message_tag, typename etl::remove_cvref<T>::type>::value>
{
};
//***************************************************************************
/// Is T a base of etl::message<T>
//***************************************************************************
template <typename T>
struct is_message_base : public etl::bool_constant<etl::is_message<T>::value && !etl::is_message_type<T>::value>
{
};
//***************************************************************************
/// Is T a user defined base of etl::message<T> and not an etl::imessage
//***************************************************************************
template <typename T>
struct is_user_message_base : public etl::bool_constant<etl::is_message_base<T>::value && !etl::is_imessage<T>::value>
{
};
#if ETL_USING_CPP17
//***************************************************************************
/// Is T an etl::imessage?
//***************************************************************************
template <typename T>
inline constexpr bool is_imessage_v = is_imessage<T>::value;
//***************************************************************************
/// Is T ultimately derived from etl::imessage?
//***************************************************************************
template <typename T>
inline constexpr bool is_message_v = is_message<T>::value;
//***************************************************************************
/// Is T derived from etl::message<>
//***************************************************************************
template <typename T>
inline constexpr bool is_message_type_v = is_message_type<T>::value;
//***************************************************************************
/// Is T a base of etl::message<T>
//***************************************************************************
template <typename T>
inline constexpr bool is_message_base_v = is_message_base<T>::value;
//***************************************************************************
/// Is T a user defined base of etl::message<T>
//***************************************************************************
template <typename T>
inline constexpr bool is_user_message_base_v = is_user_message_base<T>::value;
#endif
}
#endif

View File

@ -228,9 +228,7 @@ namespace etl
// Always pass the message on to the successor.
if (has_successor())
{
etl::imessage_router& successor = get_successor();
successor.receive(destination_router_id, msg);
get_successor().receive(destination_router_id, msg);
}
}
@ -276,11 +274,48 @@ namespace etl
using imessage_router::accepts;
//*******************************************
/// Message brokers accept all messages.
/// Message brokers accept messages determined
/// by the subscribed routers.
//*******************************************
virtual bool accepts(etl::message_id_t) const ETL_OVERRIDE
virtual bool accepts(etl::message_id_t id) const ETL_OVERRIDE
{
return true;
if (!empty())
{
// Scan the subscription lists.
subscription* sub = static_cast<subscription*>(head.get_next());
while (sub != ETL_NULLPTR)
{
message_id_span_t message_ids = sub->message_id_list();
message_id_span_t::iterator itr = etl::find(message_ids.begin(), message_ids.end(), id);
if (itr != message_ids.end())
{
etl::imessage_router* router = sub->get_router();
if (router->accepts(id))
{
return true;
}
}
sub = sub->next_subscription();
}
}
// Check any successor.
if (has_successor())
{
if (get_successor().accepts(id))
{
return true;
}
}
return false;
//return true;
}
//*******************************************

View File

@ -227,11 +227,9 @@ namespace etl
if (has_successor())
{
etl::imessage_router& successor = get_successor();
if (successor.accepts(message.get_message_id()))
if (get_successor().accepts(message.get_message_id()))
{
successor.receive(destination_router_id, message);
get_successor().receive(destination_router_id, message);
}
}
}
@ -306,11 +304,9 @@ namespace etl
if (has_successor())
{
etl::imessage_router& successor = get_successor();
if (successor.accepts(shared_msg.get_message().get_message_id()))
if (get_successor().accepts(shared_msg.get_message().get_message_id()))
{
successor.receive(destination_router_id, shared_msg);
get_successor().receive(destination_router_id, shared_msg);
}
}
}
@ -319,11 +315,35 @@ namespace etl
//*******************************************
/// Does this message bus accept the message id?
/// Yes!, it accepts everything!
/// Returns <b>true</b> on the first router that does.
//*******************************************
bool accepts(etl::message_id_t) const ETL_OVERRIDE
bool accepts(etl::message_id_t id) const ETL_OVERRIDE
{
return true;
// Check the list of subscribed routers.
router_list_t::iterator irouter = router_list.begin();
while (irouter != router_list.end())
{
etl::imessage_router& router = **irouter;
if (router.accepts(id))
{
return true;
}
++irouter;
}
// Check any successor.
if (has_successor())
{
if (get_successor().accepts(id))
{
return true;
}
}
return false;
}
//*******************************************
@ -370,9 +390,9 @@ namespace etl
//*******************************************
/// Constructor.
//*******************************************
imessage_bus(router_list_t& list, etl::imessage_router& successor)
: imessage_router(etl::imessage_router::MESSAGE_BUS, successor),
router_list(list)
imessage_bus(router_list_t& router_list_, etl::imessage_router& successor_)
: imessage_router(etl::imessage_router::MESSAGE_BUS, successor_),
router_list(router_list_)
{
}
@ -416,8 +436,8 @@ namespace etl
//*******************************************
/// Constructor.
//*******************************************
message_bus(etl::imessage_router& successor)
: imessage_bus(router_list, successor)
message_bus(etl::imessage_router& successor_)
: imessage_bus(router_list, successor_)
{
}

View File

@ -99,7 +99,7 @@ namespace etl
///
//********************************************
#include "private/diagnostic_uninitialized_push.h"
template <typename T>
template <typename T, typename = typename etl::enable_if<IsIMessage<T> || IsInMessageList<T>, int>::type>
explicit message_packet(T&& msg)
: valid(true)
{
@ -121,10 +121,6 @@ namespace etl
{
add_new_message_type<T>(etl::forward<T>(msg));
}
else if constexpr (IsMessagePacket<T>)
{
copy(etl::forward<T>(msg));
}
else
{
ETL_STATIC_ASSERT(IsInMessageList<T>, "Message not in packet type list");
@ -132,6 +128,30 @@ namespace etl
}
#include "private/diagnostic_pop.h"
//**********************************************
message_packet(const message_packet& other)
{
valid = other.is_valid();
if (valid)
{
add_new_message(other.get());
}
}
#if ETL_USING_CPP11
//**********************************************
message_packet(message_packet&& other)
{
valid = other.is_valid();
if (valid)
{
add_new_message(etl::move(other.get()));
}
}
#endif
//**********************************************
void copy(const message_packet& other)
{

View File

@ -39,7 +39,7 @@ SOFTWARE.
// Note: You will need Python and COG installed.
//
// python -m cogapp -d -e -omessage_router.h -DHandlers=<n> message_router_generator.h
// Where <n> is the number of messages to support.
// Where <n> is the maximum number of messages to support.
//
// e.g.
// To generate handlers for up to 16 messages...
@ -200,8 +200,8 @@ namespace etl
}
//********************************************
null_message_router(etl::imessage_router& successor)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor)
null_message_router(etl::imessage_router& successor_)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_)
{
}
@ -278,8 +278,8 @@ namespace etl
}
//********************************************
message_producer(etl::imessage_router& successor)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor)
message_producer(etl::imessage_router& successor_)
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_)
{
}
@ -291,8 +291,8 @@ namespace etl
}
//********************************************
message_producer(etl::message_router_id_t id_, etl::imessage_router& successor)
: imessage_router(id_, successor)
message_producer(etl::message_router_id_t id_, etl::imessage_router& successor_)
: imessage_router(id_, successor_)
{
ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));
}
@ -342,11 +342,22 @@ namespace etl
}
};
//***************************************************************************
/// Is T ultimately derived from etl::imessage_router?
//***************************************************************************
template <typename T>
struct is_message_router : public etl::bool_constant<etl::is_base_of<etl::imessage_router, typename etl::remove_cvref<T>::type>::value>
{
};
//***************************************************************************
/// Send a message to a router.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
const etl::imessage& message)
template <typename TRouter, typename TMessage>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value, void>::type
send_message(TRouter& destination,
const TMessage& message)
{
destination.receive(message);
}
@ -354,8 +365,11 @@ namespace etl
//***************************************************************************
/// Send a shared message to a router.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::shared_message message)
template <typename TRouter>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value, void>::type
send_message(TRouter& destination,
etl::shared_message message)
{
destination.receive(message);
}
@ -363,9 +377,12 @@ namespace etl
//***************************************************************************
/// Send a message to a router with a particular id.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::message_router_id_t id,
const etl::imessage& message)
template <typename TRouter, typename TMessage>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value && etl::is_message<TMessage>::value, void>::type
send_message(TRouter& destination,
etl::message_router_id_t id,
const TMessage& message)
{
destination.receive(id, message);
}
@ -373,9 +390,12 @@ namespace etl
//***************************************************************************
/// Send a shared message to a router with a particular id.
//***************************************************************************
static inline void send_message(etl::imessage_router& destination,
etl::message_router_id_t id,
etl::shared_message message)
template <typename TRouter>
static
typename etl::enable_if<etl::is_message_router<TRouter>::value, void>::type
send_message(TRouter& destination,
etl::message_router_id_t id,
etl::shared_message message)
{
destination.receive(id, message);
}

View File

@ -589,13 +589,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
ETL_DISABLE_TIMER_UPDATES;
bool result = !active_list.empty();
ETL_ENABLE_TIMER_UPDATES;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
ETL_DISABLE_TIMER_UPDATES;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
ETL_ENABLE_TIMER_UPDATES;
return delta;

View File

@ -302,13 +302,31 @@ namespace etl
return false;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
++process_semaphore;
bool result = !active_list.empty();
--process_semaphore;
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
++process_semaphore;
uint32_t delta = active_list.front().delta;
if (!active_list.empty())
{
delta = active_list.front().delta;
}
--process_semaphore;
return delta;

View File

@ -312,14 +312,30 @@ namespace etl
}
//*******************************************
/// Get the time to the next timer event.
/// Check if there is an active timer.
//*******************************************
uint32_t time_to_next() const
bool has_active_timer() const
{
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
return !active_list.empty();
}
uint32_t delta = active_list.front().delta;
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
TInterruptGuard guard;
(void)guard; // Silence 'unused variable warnings.
if (!active_list.empty())
{
delta = active_list.front().delta;
}
return delta;
}

View File

@ -318,14 +318,32 @@ namespace etl
unlock = unlock_;
}
//*******************************************
/// Check if there is an active timer.
//*******************************************
bool has_active_timer() const
{
lock();
bool result = !active_list.empty();
unlock();
return result;
}
//*******************************************
/// Get the time to the next timer event.
/// Returns etl::timer::interval::No_Active_Interval if there is no active timer.
//*******************************************
uint32_t time_to_next() const
{
lock();
uint32_t delta = static_cast<uint32_t>(etl::timer::interval::No_Active_Interval);
uint32_t delta = active_list.front().delta;
lock();
if (!active_list.empty())
{
delta = active_list.front().delta;
}
unlock();
return delta;
}

View File

@ -324,7 +324,7 @@ namespace etl
{
typedef T value_type;
virtual bool operator()(const value_type& current, const value_type& last) const = 0;
virtual bool operator()(const value_type& lhs, const value_type& rhs) const = 0;
};
//***************************************************************************
@ -334,9 +334,9 @@ namespace etl
{
typedef T value_type;
virtual bool operator()(const value_type& current, const value_type& last) const ETL_OVERRIDE
virtual bool operator()(const value_type& lhs, const value_type& rhs) const ETL_OVERRIDE
{
return etl::not_equal_to<value_type>()(current, last);
return etl::not_equal_to<value_type>()(lhs, rhs);
}
};
@ -347,9 +347,9 @@ namespace etl
{
typedef T value_type;
virtual bool operator()(const value_type& current, const value_type& last) const ETL_OVERRIDE
virtual bool operator()(const value_type& lhs, const value_type& rhs) const ETL_OVERRIDE
{
return etl::less<value_type>()(current, last);
return etl::less<value_type>()(lhs, rhs);
}
};
@ -360,9 +360,9 @@ namespace etl
{
typedef T value_type;
virtual bool operator()(const value_type& current, const value_type& last) const ETL_OVERRIDE
virtual bool operator()(const value_type& lhs, const value_type& rhs) const ETL_OVERRIDE
{
return etl::greater<value_type>()(current, last);
return etl::greater<value_type>()(lhs, rhs);
}
};

View File

@ -1542,10 +1542,10 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = allocate_data_node();
::new (&node.value) const value_type(value);
Data_Node* node = allocate_data_node();
::new (&node->value) const value_type(value);
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#if ETL_USING_CPP11
@ -1554,20 +1554,20 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = allocate_data_node();
::new (&node.value) const value_type(etl::move(value));
Data_Node* node = allocate_data_node();
::new (&node->value) const value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#endif
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& allocate_data_node()
Data_Node* allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();
return (p_node_pool->*func)();
}
//*************************************************************************

View File

@ -1530,10 +1530,10 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(value);
Data_Node* node = allocate_data_node();
::new ((void*)&node->value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#if ETL_USING_CPP11
@ -1542,20 +1542,20 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(etl::move(value));
Data_Node* node = allocate_data_node();
::new ((void*)&node->value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#endif
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& allocate_data_node()
Data_Node* allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();
return (p_node_pool->*func)();
}
//*************************************************************************

File diff suppressed because it is too large Load Diff

View File

@ -202,6 +202,14 @@ SOFTWARE.
#define ETL_HAS_IDEQUE_REPAIR 0
#endif
//*************************************
// Option to enable repair-after-memcpy for icircular_buffer.
#if defined(ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE)
#define ETL_HAS_ICIRCULAR_BUFFER_REPAIR 1
#else
#define ETL_HAS_ICIRCULAR_BUFFER_REPAIR 0
#endif
//*************************************
// Indicate if C++ exceptions are enabled.
#if defined(ETL_THROW_EXCEPTIONS)
@ -249,7 +257,6 @@ SOFTWARE.
#define ETL_CONSTEXPR constexpr
#define ETL_CONSTEXPR11 constexpr // Synonym for ETL_CONSTEXPR
#define ETL_CONSTANT constexpr
#define ETL_STATIC_CONSTANT constexpr
#define ETL_DELETE = delete
#define ETL_EXPLICIT explicit
#define ETL_OVERRIDE override
@ -271,7 +278,6 @@ SOFTWARE.
#define ETL_CONSTEXPR
#define ETL_CONSTEXPR11
#define ETL_CONSTANT const
#define ETL_STATIC_CONSTANT static const
#define ETL_DELETE
#define ETL_EXPLICIT
#define ETL_OVERRIDE
@ -479,6 +485,7 @@ namespace etl
static ETL_CONSTANT bool has_string_clear_after_use = (ETL_HAS_STRING_CLEAR_AFTER_USE == 1);
static ETL_CONSTANT bool has_istring_repair = (ETL_HAS_ISTRING_REPAIR == 1);
static ETL_CONSTANT bool has_ivector_repair = (ETL_HAS_IVECTOR_REPAIR == 1);
static ETL_CONSTANT bool has_icircular_buffer_repair = (ETL_HAS_ICIRCULAR_BUFFER_REPAIR == 1);
static ETL_CONSTANT bool has_mutable_array_view = (ETL_HAS_MUTABLE_ARRAY_VIEW == 1);
static ETL_CONSTANT bool has_ideque_repair = (ETL_HAS_IDEQUE_REPAIR == 1);
static ETL_CONSTANT bool has_virtual_messages = (ETL_HAS_VIRTUAL_MESSAGES == 1);

View File

@ -151,10 +151,10 @@ namespace etl
typedef typename etl::make_unsigned<ETL_BITSET_ELEMENT_TYPE>::type element_type;
typedef element_type element_t; // Backward compatibility
static ETL_CONSTANT element_type ALL_SET = etl::integral_limits<element_type>::max;
static ETL_CONSTANT element_type ALL_SET = etl::integral_limits<element_type>::max;
static ETL_CONSTANT element_type ALL_CLEAR = 0;
static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits<element_type>::bits;
static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits<element_type>::bits;
#if ETL_USING_CPP11
typedef etl::span<element_type> span_type;
@ -311,7 +311,7 @@ namespace etl
//*************************************************************************
ibitset& set()
{
::memset(pdata, 0xFF, Number_Of_Elements);
etl::fill_n(pdata, Number_Of_Elements - 1U, ALL_SET);
pdata[Number_Of_Elements - 1U] = Top_Mask;
return *this;
@ -429,7 +429,14 @@ namespace etl
//*************************************************************************
ibitset& set(const char* text)
{
from_string(text);
if (text == ETL_NULLPTR)
{
reset();
}
else
{
from_string(text);
}
return *this;
}
@ -439,7 +446,14 @@ namespace etl
//*************************************************************************
ibitset& set(const wchar_t* text)
{
from_string(text);
if (text == ETL_NULLPTR)
{
reset();
}
else
{
from_string(text);
}
return *this;
}
@ -449,7 +463,14 @@ namespace etl
//*************************************************************************
ibitset& set(const char16_t* text)
{
from_string(text);
if (text == ETL_NULLPTR)
{
reset();
}
else
{
from_string(text);
}
return *this;
}
@ -459,7 +480,14 @@ namespace etl
//*************************************************************************
ibitset& set(const char32_t* text)
{
from_string(text);
if (text == ETL_NULLPTR)
{
reset();
}
else
{
from_string(text);
}
return *this;
}
@ -491,7 +519,7 @@ namespace etl
return v;
}
//*************************************************************************
//*************************************************************************
/// Put to a unsigned long.
//*************************************************************************
unsigned long to_ulong() const
@ -512,7 +540,7 @@ namespace etl
//*************************************************************************
ibitset& reset()
{
::memset(pdata, 0x00, Number_Of_Elements);
etl::fill_n(pdata, Number_Of_Elements, ALL_CLEAR);
return *this;
}
@ -554,10 +582,10 @@ namespace etl
//*************************************************************************
ibitset& flip()
{
for (size_t i = 0UL; i < Number_Of_Elements; ++i)
{
pdata[i] = ~pdata[i];
}
etl::transform_n(pdata,
Number_Of_Elements,
pdata,
etl::binary_not<element_type>());
clear_unused_bits_in_msb();
@ -832,7 +860,7 @@ namespace etl
--dst_index;
// Shift lsb.
element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift);
lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift);
pdata[dst_index] = lsb;
--src_index;
}
@ -1194,7 +1222,6 @@ namespace etl
//*************************************************************************
bitset<MaxN>& set(const char* text)
{
ETL_ASSERT_OR_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this);
etl::ibitset::set(text);
return *this;
@ -1205,7 +1232,6 @@ namespace etl
//*************************************************************************
bitset<MaxN>& set(const wchar_t* text)
{
ETL_ASSERT_OR_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this);
etl::ibitset::set(text);
return *this;
@ -1216,7 +1242,6 @@ namespace etl
//*************************************************************************
bitset<MaxN>& set(const char16_t* text)
{
ETL_ASSERT_OR_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this);
etl::ibitset::set(text);
return *this;
@ -1227,7 +1252,6 @@ namespace etl
//*************************************************************************
bitset<MaxN>& set(const char32_t* text)
{
ETL_ASSERT_OR_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this);
etl::ibitset::set(text);
return *this;

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,8 @@ namespace etl
typedef crc_parameters<uint8_t, 0x07U, 0x00U, 0x55U, false> crc8_itu_parameters;
typedef crc_parameters<uint8_t, 0x31U, 0x00U, 0x00U, true> crc8_maxim_parameters;
typedef crc_parameters<uint8_t, 0x9BU, 0x00U, 0x00U, true> crc8_wcdma_parameters;
typedef crc_parameters<uint8_t, 0x1DU, 0xFFU, 0xFFU, false> crc8_j1850_parameters;
typedef crc_parameters<uint8_t, 0x1DU, 0x00U, 0x00U, false> crc8_j1850_zero_parameters;
// 16 bit.
typedef crc_parameters<uint16_t, 0x8005U, 0x0000U, 0x0000U, true> crc16_parameters;

View File

@ -0,0 +1,44 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2024 John Wellbelove
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.
******************************************************************************/
/*
* The header include guard has been intentionally omitted.
* This file is intended to evaluated multiple times by design.
*/
#if defined(__GNUC__) && !defined(__clang__) && !defined(__llvm__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnull-dereference"
#endif
#if defined(__clang__) || defined(__llvm__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnull-dereference"
#endif

View File

@ -986,7 +986,7 @@ namespace etl
/// Less than or equal operator.
///\param lhs Reference to the first vector.
///\param rhs Reference to the second vector.
///\return <b>true</b> if the first vector is lexigraphically less than or equal to the second, otherwise <b>false</b>
///\return <b>true</b> if the first vector is lexicographically less than or equal to the second, otherwise <b>false</b>
///\ingroup vector
//***************************************************************************
template <typename T>
@ -999,7 +999,7 @@ namespace etl
/// Greater than or equal operator.
///\param lhs Reference to the first vector.
///\param rhs Reference to the second vector.
///\return <b>true</b> if the first vector is lexigraphically greater than or equal to the second, otherwise <b>false</b>
///\return <b>true</b> if the first vector is lexicographically greater than or equal to the second, otherwise <b>false</b>
///\ingroup vector
//***************************************************************************
template <typename T>

View File

@ -41,6 +41,7 @@ SOFTWARE.
#include "../placement_new.h"
#include "../visitor.h"
#include "../memory.h"
#include "../compare.h"
#include "../initializer_list.h"
#include <stdint.h>
@ -531,7 +532,7 @@ namespace etl
default_construct_in_place<type>(data);
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
type_id = 0U;
type_id = variant_npos;
}
#include "diagnostic_pop.h"
@ -701,6 +702,29 @@ namespace etl
return *static_cast<T*>(data);
}
#if ETL_HAS_INITIALIZER_LIST
//***************************************************************************
/// Emplace by type with variadic constructor parameters.
//***************************************************************************
template <typename T, typename U, typename... TArgs>
T& emplace(std::initializer_list<U> il, TArgs&&... args)
{
static_assert(etl::is_one_of<T, TTypes...>::value, "Unsupported type");
using type = etl::remove_cvref_t<T>;
operation(private_variant::Destroy, data, nullptr);
construct_in_place_args<type>(data, il, etl::forward<TArgs>(args)...);
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
type_id = etl::private_variant::parameter_pack<TTypes...>::template index_of_type<T>::value;
return *static_cast<T*>(data);
}
#endif
//***************************************************************************
/// Emplace by index with variadic constructor parameters.
//***************************************************************************
@ -722,6 +746,29 @@ namespace etl
return *static_cast<type*>(data);
}
#if ETL_HAS_INITIALIZER_LIST
//***************************************************************************
/// Emplace by index with variadic constructor parameters.
//***************************************************************************
template <size_t Index, typename U, typename... TArgs>
typename etl::variant_alternative<Index, variant<TArgs...>>::type& emplace(std::initializer_list<U> il, TArgs&&... args)
{
static_assert(Index < etl::private_variant::parameter_pack<TTypes...>::size, "Index out of range");
using type = typename etl::private_variant::parameter_pack<TTypes...>::template type_from_index<Index>::type;
operation(private_variant::Destroy, data, nullptr);
construct_in_place_args<type>(data, il, etl::forward<TArgs>(args)...);
operation = operation_type<type, etl::is_copy_constructible<type>::value, etl::is_move_constructible<type>::value>::do_operation;
type_id = Index;
return *static_cast<type*>(data);
}
#endif
//***************************************************************************
/// Move assignment operator for type.
///\param value The value to assign.
@ -997,7 +1044,7 @@ namespace etl
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
//***************************************************************************
/// Call the relevent visitor by attempting each one.
/// Call the relevant visitor by attempting each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_visitor(TVisitor& visitor, etl::index_sequence<I...>)
@ -1006,7 +1053,7 @@ namespace etl
}
//***************************************************************************
/// Call the relevent visitor by attempting each one.
/// Call the relevant visitor by attempting each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_visitor(TVisitor& visitor, etl::index_sequence<I...>) const
@ -1015,7 +1062,7 @@ namespace etl
}
#else
//***************************************************************************
/// /// Call the relevent visitor.
/// /// Call the relevant visitor.
//***************************************************************************
template <typename TVisitor>
void do_visitor(TVisitor& visitor)
@ -1065,7 +1112,7 @@ namespace etl
}
//***************************************************************************
/// /// Call the relevent visitor.
/// /// Call the relevant visitor.
//***************************************************************************
template <typename TVisitor>
void do_visitor(TVisitor& visitor) const
@ -1125,7 +1172,7 @@ namespace etl
{
// Workaround for MSVC (2023/05/13)
// It doesn't compile 'visitor.visit(etl::get<Index>(*this))' correctly for C++17 & C++20.
// Changed all of the instances for consistancy.
// Changed all of the instances for consistency.
auto& v = etl::get<Index>(*this);
visitor.visit(v);
return true;
@ -1146,7 +1193,7 @@ namespace etl
{
// Workaround for MSVC (2023/05/13)
// It doesn't compile 'visitor.visit(etl::get<Index>(*this))' correctly for C++17 & C++20.
// Changed all of the instances for consistancy.
// Changed all of the instances for consistency.
auto& v = etl::get<Index>(*this);
visitor.visit(v);
return true;
@ -1159,7 +1206,7 @@ namespace etl
#if ETL_USING_CPP17 && !defined(ETL_VARIANT_FORCE_CPP11)
//***************************************************************************
/// Call the relevent visitor by attempting each one.
/// Call the relevant visitor by attempting each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_operator(TVisitor& visitor, etl::index_sequence<I...>)
@ -1168,7 +1215,7 @@ namespace etl
}
//***************************************************************************
/// Call the relevent visitor by attempting each one.
/// Call the relevant visitor by attempting each one.
//***************************************************************************
template <typename TVisitor, size_t... I>
void do_operator(TVisitor& visitor, etl::index_sequence<I...>) const
@ -1177,7 +1224,7 @@ namespace etl
}
#else
//***************************************************************************
/// Call the relevent visitor.
/// Call the relevant visitor.
//***************************************************************************
template <typename TVisitor>
void do_operator(TVisitor& visitor)
@ -1241,7 +1288,7 @@ namespace etl
}
//***************************************************************************
/// Call the relevent visitor.
/// Call the relevant visitor.
//***************************************************************************
template <typename TVisitor>
void do_operator(TVisitor& visitor) const
@ -1693,7 +1740,7 @@ namespace etl
//***************************************************************************
/// Helper to instantiate the function pointers needed for the "jump table".
/// Embedds the 'TVarRest' (remaining variants) into its type to come around
/// Embeds the 'TVarRest' (remaining variants) into its type to come around
/// the "double expansion" otherwise needed in "do_visit".
//***************************************************************************
template <typename TRet, typename TCallable, typename TCurVariant, typename... TVarRest>
@ -1770,7 +1817,7 @@ namespace etl
} // namespace private_variant
//***************************************************************************
/// c++11/14 compatible etl::visit for etl::variant. Supports both c++17
/// C++11/14 compatible etl::visit for etl::variant. Supports both c++17
/// "auto return type" signature and c++20 explicit template return type.
//***************************************************************************
template <typename TRet = private_variant::visit_auto_return, typename... TVariants, typename TCallable, typename TDeducedReturn = private_variant::visit_result_t<TRet, TCallable, TVariants...> >
@ -1778,5 +1825,221 @@ namespace etl
{
return private_variant::visit<TDeducedReturn>(static_cast<TCallable&&>(f), static_cast<TVariants&&>(vs)...);
}
namespace private_variant
{
//***************************************************************************
/// C++11 compatible visitor function for testing variant equality.
/// Assumes that the two variants are already known to contain the same type.
//***************************************************************************
template <typename TVariant>
struct equality_visitor
{
equality_visitor(const TVariant& rhs_)
: rhs(rhs_)
{
}
template <typename TValue>
bool operator()(const TValue& lhs_downcasted)
{
return lhs_downcasted == etl::get<TValue>(rhs);
}
const TVariant& rhs;
};
//***************************************************************************
/// C++11 compatible visitor function for testing variant '<' (less than).
/// Assumes that the two variants are already known to contain the same type.
//***************************************************************************
template <typename TVariant>
struct less_than_visitor
{
less_than_visitor(const TVariant& rhs_)
: rhs(rhs_)
{
}
template <typename TValue>
bool operator()(const TValue& lhs_downcasted)
{
return lhs_downcasted < etl::get<TValue>(rhs);
}
const TVariant& rhs;
};
}
//***************************************************************************
/// Checks if the variants are equal.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator ==(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
// If both variants are valueless, they are considered equal
if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
{
return true;
}
// If one variant is valueless and the other is not, they are not equal
if (lhs.valueless_by_exception() || rhs.valueless_by_exception())
{
return false;
}
// If variants have different types, they are not equal
if (lhs.index() != rhs.index())
{
return false;
}
// Variants have the same type, apply the equality operator for the contained values
private_variant::equality_visitor<etl::variant<TTypes...>> visitor(rhs);
return etl::visit(visitor, lhs);
}
//***************************************************************************
/// Checks if the variants not equal.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator !=(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
return !(lhs == rhs);
}
//***************************************************************************
/// Checks if the lhs variant is less than rhs.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator <(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
// If both variants are valueless, they are considered equal, so not less than
if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
{
return false;
}
// A valueless variant is always less than a variant with a value
if (lhs.valueless_by_exception())
{
return true;
}
// A variant with a value is never less than a valueless variant
if (rhs.valueless_by_exception())
{
return false;
}
// If variants have different types, compare the type index
if (lhs.index() != rhs.index())
{
return lhs.index() < rhs.index();
}
// Variants have the same type, apply the less than operator for the contained values
private_variant::less_than_visitor<etl::variant<TTypes...>> visitor(rhs);
return etl::visit(visitor, lhs);
}
//***************************************************************************
/// Checks if the lhs variant is greater than rhs.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator >(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
return (rhs < lhs);
}
//***************************************************************************
/// Checks if the lhs variant is less than or equal to rhs.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator <=(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
return !(lhs > rhs);
}
//***************************************************************************
/// Checks if the lhs variant is greater than or equal to rhs.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
template <typename... TTypes>
ETL_CONSTEXPR14 bool operator >=(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
return !(lhs < rhs);
}
namespace private_variant
{
#if ETL_USING_CPP20 && ETL_USING_STL
//***************************************************************************
/// C++20 compatible visitor function for testing variant '<=>'.
/// Assumes that the two variants are already known to contain the same type.
//***************************************************************************
template <typename TVariant>
struct compare_visitor
{
compare_visitor(const TVariant& rhs_)
: rhs(rhs_)
{
}
template <typename TValue>
std::strong_ordering operator()(const TValue& lhs_downcasted)
{
return lhs_downcasted <=> etl::get<TValue>(rhs);
}
const TVariant& rhs;
};
#endif
}
//***************************************************************************
/// Defines the 'spaceship' <=> operator for comparing variants.
/// Only defined if using C++20 and STL.
/// https://en.cppreference.com/w/cpp/utility/variant/operator_cmp
//***************************************************************************
#if ETL_USING_CPP20 && ETL_USING_STL && !(defined(ETL_DEVELOPMENT_OS_APPLE) && defined(ETL_COMPILER_CLANG))
template <typename... TTypes>
ETL_CONSTEXPR14
std::common_comparison_category_t<std::compare_three_way_result_t<TTypes>...>
operator <=>(const etl::variant<TTypes...>& lhs, const etl::variant<TTypes...>& rhs)
{
if (lhs.valueless_by_exception() && rhs.valueless_by_exception())
{
return std::strong_ordering::equal;
}
else if (lhs.valueless_by_exception())
{
return std::strong_ordering::less;
}
else if (rhs.valueless_by_exception())
{
return std::strong_ordering::greater;
}
else if (lhs.index() != rhs.index())
{
return lhs.index() <=> rhs.index();
}
else
{
// Variants have the same type, apply the equality operator for the contained values
private_variant::compare_visitor<etl::variant<TTypes...>> visitor(rhs);
return etl::visit(visitor, lhs);
}
}
#endif
}
#endif

View File

@ -868,9 +868,9 @@ namespace etl
/// Default constructor.
//*************************************************************************
queue_spsc_locked(const etl::ifunction<void>& lock,
const etl::ifunction<void>& unlock)
: base_t(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, lock, unlock)
queue_spsc_locked(const etl::ifunction<void>& lock_,
const etl::ifunction<void>& unlock_)
: base_t(reinterpret_cast<T*>(buffer.raw), MAX_SIZE, lock_, unlock_)
{
}

View File

@ -47,19 +47,19 @@ namespace etl
{
enum enum_type
{
undefined = 0,
binary = 2,
octal = 8,
decimal = 10,
hex = 16
undefined = 0,
binary = 2,
octal = 8,
decimal = 10,
hexadecimal = 16
};
ETL_DECLARE_ENUM_TYPE(radix, uint_least8_t)
ETL_ENUM_TYPE(undefined, "undefined")
ETL_ENUM_TYPE(binary, "binary")
ETL_ENUM_TYPE(octal, "octal")
ETL_ENUM_TYPE(decimal, "decimal")
ETL_ENUM_TYPE(hex, "hex")
ETL_ENUM_TYPE(undefined, "undefined")
ETL_ENUM_TYPE(binary, "binary")
ETL_ENUM_TYPE(octal, "octal")
ETL_ENUM_TYPE(decimal, "decimal")
ETL_ENUM_TYPE(hexadecimal, "hexadecimal")
ETL_END_ENUM_TYPE
};
}

View File

@ -462,12 +462,12 @@ namespace etl
random_pcg()
{
#include "etl/private/diagnostic_useless_cast_push.h"
#include "private/diagnostic_useless_cast_push.h"
// An attempt to come up with a unique non-zero seed,
// based on the address of the instance.
uintptr_t n = reinterpret_cast<uintptr_t>(this);
value = static_cast<uint64_t>(n);
#include "etl/private/diagnostic_pop.h"
#include "private/diagnostic_pop.h"
}
//***************************************************************************

View File

@ -69,14 +69,19 @@ namespace etl
typedef TMessage message_type;
typedef TCounter counter_type;
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor
/// \param owner The message owner.
/// \param args The constructor arguments.
//***************************************************************************
reference_counted_message(etl::ireference_counted_message_pool& owner_)
: owner(owner_)
template <typename... TArgs>
reference_counted_message(etl::ireference_counted_message_pool& owner_, TArgs&&... args)
: rc_object(etl::forward<TArgs>(args)...)
, owner(owner_)
{
}
#endif
//***************************************************************************
/// Constructor
@ -222,4 +227,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -100,6 +100,35 @@ namespace etl
{
}
#if ETL_USING_CPP11
//*************************************************************************
/// Allocate a reference counted message from the pool.
//*************************************************************************
template <typename TMessage, typename... TArgs>
etl::reference_counted_message<TMessage, TCounter>* allocate(TArgs&&... args)
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
typedef etl::reference_counted_message<TMessage, TCounter> rcm_t;
typedef rcm_t* prcm_t;
prcm_t p = ETL_NULLPTR;
lock();
p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
unlock();
if (p != ETL_NULLPTR)
{
::new(p) rcm_t(*this, etl::forward<TArgs>(args)...);
}
ETL_ASSERT((p != ETL_NULLPTR), ETL_ERROR(etl::reference_counted_message_pool_allocation_failure));
return p;
}
#endif
//*************************************************************************
/// Allocate a reference counted message from the pool.
//*************************************************************************
@ -182,13 +211,13 @@ namespace etl
// Size of the first pool message type.
static constexpr size_t size1 = sizeof(etl::reference_counted_message<TMessage1, TCounter>);
// Maximum size of the the rest of the pool message types.
// Maximum size of the rest of the pool message types.
static constexpr size_t size2 = pool_message_parameters<TMessages...>::max_size;
// Size of the first pool message type.
static constexpr size_t alignment1 = etl::alignment_of<etl::reference_counted_message<TMessage1, TCounter>>::value;
// Maximum size of the the rest of the pool message types.
// Maximum size of the rest of the pool message types.
static constexpr size_t alignment2 = pool_message_parameters<TMessages...>::max_alignment;
public:
@ -216,8 +245,8 @@ namespace etl
};
#else
template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct pool_message_parameters
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage1 not derived from etl::imessage");
@ -230,23 +259,23 @@ namespace etl
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage8 not derived from etl::imessage");
static ETL_CONSTANT size_t max_size = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::size;
static ETL_CONSTANT size_t max_alignment = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
etl::reference_counted_message<TMessage2, TCounter>,
etl::reference_counted_message<TMessage3, TCounter>,
etl::reference_counted_message<TMessage4, TCounter>,
etl::reference_counted_message<TMessage5, TCounter>,
etl::reference_counted_message<TMessage6, TCounter>,
etl::reference_counted_message<TMessage7, TCounter>,
etl::reference_counted_message<TMessage8, TCounter> >::alignment;
};
#endif
@ -290,4 +319,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -33,6 +33,7 @@
#include "atomic.h"
#include "exception.h"
#include "error_handler.h"
#include "utility.h"
#include <stdint.h>
@ -223,6 +224,17 @@ namespace etl
{
}
#if ETL_USING_CPP11
//***************************************************************************
/// Constructor.
//***************************************************************************
template <typename... TArgs>
reference_counted_object(TArgs&&... args)
: object(etl::forward<TArgs>(args)...)
{
}
#endif
//***************************************************************************
/// Get a reference to the counted object.
//***************************************************************************
@ -276,4 +288,4 @@ namespace etl
#endif
}
#endif
#endif

View File

@ -1407,10 +1407,10 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(const_reference value)
{
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(value);
Data_Node* node = allocate_data_node();
::new ((void*)&node->value) value_type(value);
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#if ETL_USING_CPP11
@ -1419,20 +1419,20 @@ namespace etl
//*************************************************************************
Data_Node& allocate_data_node(rvalue_reference value)
{
Data_Node& node = allocate_data_node();
::new ((void*)&node.value) value_type(etl::move(value));
Data_Node* node = allocate_data_node();
::new ((void*)&node->value) value_type(etl::move(value));
ETL_INCREMENT_DEBUG_COUNT;
return node;
return *node;
}
#endif
//*************************************************************************
/// Create a Data_Node.
//*************************************************************************
Data_Node& allocate_data_node()
Data_Node* allocate_data_node()
{
Data_Node* (etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
return *(p_node_pool->*func)();
return (p_node_pool->*func)();
}
//*************************************************************************

View File

@ -49,6 +49,17 @@ namespace etl
{
public:
#if ETL_USING_CPP11
//*************************************************************************
/// Creator for in-place instantiation
//*************************************************************************
template <typename TMessage, typename TPool, typename... TArgs>
static shared_message create(TPool& owner, TArgs&&... args)
{
return shared_message(owner, etl::in_place_type_t<TMessage>(), etl::forward<TArgs>(args)...);
}
#endif
//*************************************************************************
/// Constructor
//*************************************************************************
@ -59,13 +70,32 @@ namespace etl
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage not derived from etl::imessage");
p_rcmessage = owner.allocate(message);
if (p_rcmessage != ETL_NULLPTR)
{
p_rcmessage->get_reference_counter().set_reference_count(1U);
}
}
#if ETL_USING_CPP11
//*************************************************************************
/// Constructor
//*************************************************************************
template <typename TPool, typename TMessage, typename... TArgs>
shared_message(TPool& owner, etl::in_place_type_t<TMessage>, TArgs&&... args)
{
ETL_STATIC_ASSERT((etl::is_base_of<etl::ireference_counted_message_pool, TPool>::value), "TPool not derived from etl::ireference_counted_message_pool");
ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "TMessage not derived from etl::imessage");
p_rcmessage = owner.template allocate<TMessage>(etl::forward<TArgs>(args)...);
if (p_rcmessage != ETL_NULLPTR)
{
p_rcmessage->get_reference_counter().set_reference_count(1U);
}
}
#endif
//*************************************************************************
/// Constructor
//*************************************************************************
@ -193,5 +223,4 @@ namespace etl
};
}
#endif
#endif

View File

@ -42,6 +42,7 @@ SOFTWARE.
#include "memory.h"
#include "array.h"
#include "byte.h"
#include "static_assert.h"
#include "private/dynamic_extent.h"
@ -78,14 +79,6 @@ namespace etl
static ETL_CONSTANT size_t extent = Extent;
//*************************************************************************
/// Default constructor.
//*************************************************************************
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
{
}
//*************************************************************************
/// Construct from iterators + size
//*************************************************************************
@ -295,6 +288,9 @@ namespace etl
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
{
// If Extent is static, check that original span contains at least COUNT elements
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? COUNT <= Extent : true, "Original span does not contain COUNT elements");
return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
}
@ -312,6 +308,9 @@ namespace etl
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
{
// If Extent is static, check that original span contains at least COUNT elements
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? COUNT <= Extent : true, "Original span does not contain COUNT elements");
return etl::span<element_type, COUNT>(pbegin + Extent - COUNT, (pbegin + Extent));
}
@ -331,6 +330,12 @@ namespace etl
ETL_NODISCARD ETL_CONSTEXPR
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
{
// If Extent is static, check that OFFSET is within the original span
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? OFFSET <= Extent : true, "OFFSET is not within the original span");
// If count is also static, check that OFFSET + COUNT is within the original span
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
return (COUNT == etl::dynamic_extent) ? etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, (pbegin + Extent))
: etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
@ -341,6 +346,12 @@ namespace etl
template <size_t OFFSET, size_t COUNT>
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
// If Extent is static, check that OFFSET is within the original span
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) ? OFFSET <= Extent : true, "OFFSET is not within the original span");
// If count is also static, check that OFFSET + COUNT is within the original span
ETL_STATIC_ASSERT((Extent != etl::dynamic_extent) && (COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET)>(pbegin + OFFSET, (pbegin + Extent));
@ -720,7 +731,7 @@ namespace etl
//*************************************************************************
/// Equality function.
/// Performs a comparision of the range values.
/// Performs a comparison of the range values.
/// Returns <b>true</b> if one of the following are <b>true</b>
/// 1. Both spans are empty.
/// 2. They both point to the same range of data.

View File

@ -246,9 +246,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::istring::repair_buffer(buffer);
@ -434,9 +435,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -662,6 +662,7 @@ namespace etl
if (mbegin[i] == view[j])
{
found = true;
break;
}
}
@ -715,6 +716,7 @@ namespace etl
if (mbegin[position] == view[j])
{
found = true;
break;
}
}

View File

@ -104,6 +104,17 @@ namespace etl
Inactive = 0xFFFFFFFFUL
};
};
// Timer time interval.
struct interval
{
enum
{
No_Active_Interval = 0xFFFFFFFFUL
};
typedef uint32_t type;
};
};
}

View File

@ -251,7 +251,7 @@ namespace etl
break;
}
case etl::radix::hex:
case etl::radix::hexadecimal:
{
return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'));
break;
@ -281,7 +281,7 @@ namespace etl
break;
}
case etl::radix::hex:
case etl::radix::hexadecimal:
{
if ((c >= '0') && (c <= '9'))
{
@ -363,7 +363,7 @@ namespace etl
return (radix == etl::radix::binary) ||
(radix == etl::radix::octal) ||
(radix == etl::radix::decimal) ||
(radix == etl::radix::hex);
(radix == etl::radix::hexadecimal);
}
//***************************************************************************
@ -397,7 +397,7 @@ namespace etl
TValue old_value = integral_value;
integral_value *= radix;
// No multipication overflow?
// No multiplication overflow?
is_not_overflow = ((integral_value / radix) == old_value);
if (is_not_overflow)

View File

@ -35,274 +35,262 @@ SOFTWARE.
namespace etl
{
#define ETL_TYPEDEF(T, name) class name##_tag; typedef etl::type_def<name##_tag, T> name
#define ETL_TYPEDEF(T, name) class name##_tag; typedef etl::type_def<name##_tag, T> name
//*************************************************************************
/// A template type to define strong typedefs.
/// Usage:
///\code
/// // Short form.
/// ETL_TYPEDEF(int, mytype);
///
/// // Long form.
/// class mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
class type_def
//*************************************************************************
/// A template type to define strong typedefs.
/// Usage:
///\code
/// // Short form.
/// ETL_TYPEDEF(int, mytype);
///
/// // Long form.
/// class mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
class type_def
{
public:
typedef TValue value_type;
typedef TIdType id_type;
//*********************************************************************
ETL_CONSTEXPR type_def()
: value(TValue())
{
public:
}
typedef TValue value_type;
typedef TIdType id_type;
//*********************************************************************
ETL_CONSTEXPR type_def(TValue value_)
: value(value_)
{
}
//*********************************************************************
type_def()
: value(TValue())
{
}
//*********************************************************************
ETL_CONSTEXPR type_def(const type_def& other)
: value(other.value)
{
}
//*********************************************************************
type_def(TValue value_)
: value(value_)
{
}
//*********************************************************************
ETL_CONSTEXPR operator TValue() const
{
return value;
}
//*********************************************************************
type_def(const type_def& other)
: value(other.value)
{
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ++()
{
++value;
return *this;
}
//*********************************************************************
operator TValue() const
{
return value;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def operator ++(int)
{
type_def temp(*this);
type_def::operator ++();
return temp;
}
//*********************************************************************
type_def& operator ++()
{
++value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator --()
{
--value;
return *this;
}
//*********************************************************************
type_def operator ++(int)
{
type_def temp(*this);
type_def::operator ++();
return temp;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def operator --(int)
{
type_def temp(*this);
type_def::operator --();
return temp;
}
//*********************************************************************
type_def& operator --()
{
--value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(TValue rhs)
{
value += rhs;
return *this;
}
//*********************************************************************
type_def operator --(int)
{
type_def temp(*this);
type_def::operator --();
return temp;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(const type_def& rhs)
{
value += rhs.value;
return *this;
}
//*********************************************************************
type_def& operator +=(TValue rhs)
{
value += rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator -=(TValue rhs)
{
value -= rhs;
return *this;
}
//*********************************************************************
type_def& operator +=(const type_def& rhs)
{
value += rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator -=(const type_def& rhs)
{
value -= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator -=(TValue rhs)
{
value -= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator *=(TValue rhs)
{
value *= rhs;
return *this;
}
//*********************************************************************
type_def& operator -=(const type_def& rhs)
{
value -= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator *=(const type_def& rhs)
{
value *= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator *=(TValue rhs)
{
value *= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator /=(TValue rhs)
{
value /= rhs;
return *this;
}
//*********************************************************************
type_def& operator *=(const type_def& rhs)
{
value *= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator /=(const type_def& rhs)
{
value /= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator /=(TValue rhs)
{
value /= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator %=(TValue rhs)
{
value %= rhs;
return *this;
}
//*********************************************************************
type_def& operator /=(const type_def& rhs)
{
value /= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator %=(const type_def& rhs)
{
value %= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator %=(TValue rhs)
{
value %= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator &=(TValue rhs)
{
value &= rhs;
return *this;
}
//*********************************************************************
type_def& operator %=(const type_def& rhs)
{
value %= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator &=(const type_def& rhs)
{
value &= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator &=(TValue rhs)
{
value &= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator |=(TValue rhs)
{
value |= rhs;
return *this;
}
//*********************************************************************
type_def& operator &=(const type_def& rhs)
{
value &= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator |=(const type_def& rhs)
{
value |= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator |=(TValue rhs)
{
value |= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ^=(TValue rhs)
{
value ^= rhs;
return *this;
}
//*********************************************************************
type_def& operator |=(const type_def& rhs)
{
value |= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ^=(const type_def& rhs)
{
value ^= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator ^=(TValue rhs)
{
value ^= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator <<=(TValue rhs)
{
value <<= rhs;
return *this;
}
//*********************************************************************
type_def& operator ^=(const type_def& rhs)
{
value ^= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator >>=(TValue rhs)
{
value >>= rhs;
return *this;
}
//*********************************************************************
type_def& operator <<=(TValue rhs)
{
value <<= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
type_def& operator >>=(TValue rhs)
{
value >>= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
}
//*********************************************************************
type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
TValue& get()
{
return value;
}
//*********************************************************************
type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR const TValue& get() const
{
return value;
}
//*********************************************************************
TValue& get()
{
return value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator >(const type_def& lhs, const type_def& rhs)
{
return lhs.value > rhs.value;
}
//*********************************************************************
const TValue& get() const
{
return value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator >=(const type_def& lhs, const type_def& rhs)
{
return lhs.value >= rhs.value;
}
//*********************************************************************
friend bool operator <(const type_def& lhs, const type_def& rhs)
{
return lhs.value < rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator ==(const type_def& lhs, const type_def& rhs)
{
return lhs.value == rhs.value;
}
//*********************************************************************
friend bool operator <=(const type_def& lhs, const type_def& rhs)
{
return lhs.value <= rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator !=(const type_def& lhs, const type_def& rhs)
{
return lhs.value != rhs.value;
}
//*********************************************************************
friend bool operator >(const type_def& lhs, const type_def& rhs)
{
return lhs.value > rhs.value;
}
private:
//*********************************************************************
friend bool operator >=(const type_def& lhs, const type_def& rhs)
{
return lhs.value >= rhs.value;
}
//*********************************************************************
friend bool operator ==(const type_def& lhs, const type_def& rhs)
{
return lhs.value == rhs.value;
}
//*********************************************************************
friend bool operator !=(const type_def& lhs, const type_def& rhs)
{
return lhs.value != rhs.value;
}
private:
TValue value;
};
TValue value;
};
}
#endif

View File

@ -62,7 +62,7 @@ SOFTWARE.
///\defgroup type_traits type_traits
/// A set of type traits definitions.
/// Derived from either the standard or alternate definitions, dependant on whether or not ETL_NO_STL is defined.
/// Derived from either the standard or alternate definitions, dependent on whether or not ETL_NO_STL is defined.
/// \ingroup utilities
#if ETL_USING_STL && ETL_USING_CPP11
@ -2070,6 +2070,21 @@ typedef integral_constant<bool, true> true_type;
{
};
#if ETL_USING_CPP11
//*********************************************
// is_default_constructible
template<typename T, typename = void>
struct is_default_constructible : etl::false_type { };
template<typename T>
struct is_default_constructible<T, etl::void_t<decltype(T())>> : etl::true_type { };
#else
template <typename T>
struct is_default_constructible : public etl::bool_constant<etl::is_arithmetic<T>::value || etl::is_pointer<T>::value>
{
};
#endif
#if ETL_USING_CPP17
template <typename T1, typename T2>
@ -2081,6 +2096,9 @@ typedef integral_constant<bool, true> true_type;
template<typename T, typename... TArgs>
inline constexpr bool is_constructible_v = etl::is_constructible<T, TArgs...>::value;
template<typename T, typename... TArgs>
inline constexpr bool is_default_constructible_v = etl::is_default_constructible<T, TArgs...>::value;
template<typename T>
inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible<T>::value;

View File

@ -230,9 +230,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::iu16string::repair_buffer(buffer);
@ -414,9 +415,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -230,9 +230,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::iu32string::repair_buffer(buffer);
@ -414,9 +415,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -247,9 +247,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::iu8string::repair_buffer(buffer);
@ -435,9 +436,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -659,13 +659,13 @@ namespace etl
// Doesn't exist, so add a new one.
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node.key_value_pair.second)) mapped_type();
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair.first)) key_type(etl::move(key));
::new ((void*)etl::addressof(node->key_value_pair.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT;
pbucket->insert_after(pbucket->before_begin(), node);
pbucket->insert_after(pbucket->before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
@ -703,13 +703,13 @@ namespace etl
// Doesn't exist, so add a new one.
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair.first)) key_type(key);
::new ((void*)etl::addressof(node.key_value_pair.second)) mapped_type();
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair.first)) key_type(key);
::new ((void*)etl::addressof(node->key_value_pair.second)) mapped_type();
ETL_INCREMENT_DEBUG_COUNT;
pbucket->insert_after(pbucket->before_begin(), node);
pbucket->insert_after(pbucket->before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
@ -835,13 +835,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(key_value_pair);
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair)) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
@ -870,13 +870,13 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(key_value_pair);
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair)) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -913,13 +913,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(etl::move(key_value_pair));
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair)) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
@ -948,13 +948,13 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new ((void*)etl::addressof(node.key_value_pair)) value_type(etl::move(key_value_pair));
node_t* node = allocate_data_node();
node->clear();
::new ((void*)etl::addressof(node->key_value_pair)) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -1420,14 +1420,14 @@ namespace etl
//*************************************************************************
/// Move from a range
//*************************************************************************
void move(iterator first, iterator last)
void move(iterator b, iterator e)
{
while (first != last)
while (b != e)
{
iterator temp = first;
iterator temp = b;
++temp;
insert(etl::move(*first));
first = temp;
insert(etl::move(*b));
b = temp;
}
}
#endif
@ -1437,10 +1437,10 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& allocate_data_node()
node_t* allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
return (pnodepool->*func)();
}
//*********************************************************************
@ -1489,26 +1489,26 @@ namespace etl
else if (pbucket == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
pbucket = first;
bucket_t* pend = last;
last = first;
while (pcurrent != pend)
while (pbucket != pend)
{
if (!pcurrent->empty())
if (!pbucket->empty())
{
last = pcurrent;
last = pbucket;
}
++pcurrent;
++pbucket;
}
}
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
/// Delete a data node at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
@ -1569,20 +1569,41 @@ namespace etl
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
///\ingroup unordered_map
//***************************************************************************
template <typename TKey, typename T, typename TKeyCompare>
bool operator ==(const etl::iunordered_map<TKey, T, TKeyCompare>& lhs, const etl::iunordered_map<TKey, T, TKeyCompare>& rhs)
template <typename TKey, typename T, typename THash, typename TKeyEqual>
bool operator ==(const etl::iunordered_map<TKey, T, THash, TKeyEqual>& lhs,
const etl::iunordered_map<TKey, T, THash, TKeyEqual>& rhs)
{
const bool sizes_match = (lhs.size() == rhs.size());
bool elements_match = true;
typedef typename etl::iunordered_map<TKey, T, THash, TKeyEqual>::const_iterator itr_t;
if (sizes_match)
{
for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i)
itr_t l_begin = lhs.begin();
itr_t l_end = lhs.end();
while ((l_begin != l_end) && elements_match)
{
if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i)))
const TKey key = l_begin->first;
const T l_value = l_begin->second;
// See if the lhs key exists in the rhs.
ETL_OR_STD::pair<itr_t, itr_t> range = rhs.equal_range(key);
if (range.first != rhs.end())
{
// See if the values match
const T r_value = range.first->second;
elements_match = (r_value == l_value);
}
else
{
elements_match = false;
}
++l_begin;
}
}
@ -1596,8 +1617,9 @@ namespace etl
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
///\ingroup unordered_map
//***************************************************************************
template <typename TKey, typename T, typename TKeyCompare>
bool operator !=(const etl::iunordered_map<TKey, T, TKeyCompare>& lhs, const etl::iunordered_map<TKey, T, TKeyCompare>& rhs)
template <typename TKey, typename T, typename THash, typename TKeyEqual>
bool operator !=(const etl::iunordered_map<TKey, T, THash, TKeyEqual>& lhs,
const etl::iunordered_map<TKey, T, THash, TKeyEqual>& rhs)
{
return !(lhs == rhs);
}

View File

@ -675,13 +675,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(key_value_pair);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key_value_pair) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
result = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
@ -705,13 +705,13 @@ namespace etl
}
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(key_value_pair);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key_value_pair) value_type(key_value_pair);
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -746,13 +746,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(etl::move(key_value_pair));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key_value_pair) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(pbucket);
result = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
@ -776,13 +776,13 @@ namespace etl
}
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key_value_pair) value_type(etl::move(key_value_pair));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key_value_pair) value_type(etl::move(key_value_pair));
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -1274,14 +1274,14 @@ namespace etl
//*************************************************************************
/// Move from a range
//*************************************************************************
void move(iterator first, iterator last)
void move(iterator b, iterator e)
{
while (first != last)
while (b != e)
{
iterator temp = first;
iterator temp = b;
++temp;
insert(etl::move(*first));
first = temp;
insert(etl::move(*b));
b = temp;
}
}
#endif
@ -1291,10 +1291,10 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& allocate_data_node()
node_t* allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
return (pnodepool->*func)();
}
//*********************************************************************
@ -1323,7 +1323,7 @@ namespace etl
//*********************************************************************
/// Adjust the first and last markers according to the erased entry.
//*********************************************************************
void adjust_first_last_markers_after_erase(bucket_t* pcurrent)
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
{
if (empty())
{
@ -1332,7 +1332,7 @@ namespace etl
}
else
{
if (pcurrent == first)
if (pbucket == first)
{
// We erased the first so, we need to search again from where we erased.
while (first->empty())
@ -1340,29 +1340,29 @@ namespace etl
++first;
}
}
else if (pcurrent == last)
else if (pbucket == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
pbucket = first;
bucket_t* pend = last;
last = first;
while (pcurrent != pend)
while (pbucket != pend)
{
if (!pcurrent->empty())
if (!pbucket->empty())
{
last = pcurrent;
last = pbucket;
}
++pcurrent;
++pbucket;
}
}
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
/// Delete a data node at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
@ -1423,20 +1423,48 @@ namespace etl
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
///\ingroup unordered_multimap
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator ==(const etl::iunordered_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_multimap<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename T, typename THash, typename TKeyEqual>
bool operator ==(const etl::iunordered_multimap<TKey, T, THash, TKeyEqual>& lhs,
const etl::iunordered_multimap<TKey, T, THash, TKeyEqual>& rhs)
{
const bool sizes_match = (lhs.size() == rhs.size());
bool elements_match = true;
typedef typename etl::iunordered_multimap<TKey, T, THash, TKeyEqual>::const_iterator itr_t;
if (sizes_match)
{
for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i)
itr_t l_begin = lhs.begin();
itr_t l_end = lhs.end();
while ((l_begin != l_end) && elements_match)
{
if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i)))
const TKey key = l_begin->first;
const T l_value = l_begin->second;
// See if the lhs keys exist in the rhs.
ETL_OR_STD::pair<itr_t, itr_t> l_range = lhs.equal_range(key);
ETL_OR_STD::pair<itr_t, itr_t> r_range = rhs.equal_range(key);
if (r_range.first != rhs.end())
{
bool distance_match = (etl::distance(l_range.first, l_range.second) == etl::distance(r_range.first, r_range.second));
if (distance_match)
{
elements_match = etl::is_permutation(l_range.first, l_range.second, r_range.first, r_range.second);
}
else
{
elements_match = false;
}
}
else
{
elements_match = false;
}
++l_begin;
}
}
@ -1450,8 +1478,9 @@ namespace etl
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
///\ingroup unordered_multimap
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator !=(const etl::iunordered_multimap<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_multimap<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename T, typename THash, typename TKeyEqual>
bool operator !=(const etl::iunordered_multimap<TKey, T, THash, TKeyEqual>& lhs,
const etl::iunordered_multimap<TKey, T, THash, TKeyEqual>& rhs)
{
return !(lhs == rhs);
}

View File

@ -664,13 +664,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(&bucket);
result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
@ -695,13 +695,13 @@ namespace etl
}
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -735,13 +735,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(&bucket);
result.first = iterator((pbuckets + number_of_buckets), pbucket, pbucket->begin());
@ -766,13 +766,13 @@ namespace etl
}
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -1252,14 +1252,14 @@ namespace etl
//*************************************************************************
/// Move from a range
//*************************************************************************
void move(iterator first, iterator last)
void move(iterator b, iterator e)
{
while (first != last)
while (b != e)
{
iterator temp = first;
iterator temp = b;
++temp;
insert(etl::move(*first));
first = temp;
insert(etl::move(*b));
b = temp;
}
}
#endif
@ -1269,10 +1269,10 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& allocate_data_node()
node_t* allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
return (pnodepool->*func)();
}
//*********************************************************************
@ -1301,7 +1301,7 @@ namespace etl
//*********************************************************************
/// Adjust the first and last markers according to the erased entry.
//*********************************************************************
void adjust_first_last_markers_after_erase(bucket_t* pcurrent)
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
{
if (empty())
{
@ -1310,7 +1310,7 @@ namespace etl
}
else
{
if (pcurrent == first)
if (pbucket == first)
{
// We erased the first so, we need to search again from where we erased.
while (first->empty())
@ -1318,29 +1318,29 @@ namespace etl
++first;
}
}
else if (pcurrent == last)
else if (pbucket == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
pbucket = first;
bucket_t* pend = last;
last = first;
while (pcurrent != pend)
while (pbucket != pend)
{
if (!pcurrent->empty())
if (!pbucket->empty())
{
last = pcurrent;
last = pbucket;
}
++pcurrent;
++pbucket;
}
}
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
/// Delete a data node at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
@ -1401,20 +1401,47 @@ namespace etl
///\return <b>true</b> if the arrays are equal, otherwise <b>false</b>
///\ingroup unordered_multiset
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator ==(const etl::iunordered_multiset<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_multiset<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename THash, typename TKeyEqual>
bool operator ==(const etl::iunordered_multiset<TKey, THash, TKeyEqual>& lhs,
const etl::iunordered_multiset<TKey, THash, TKeyEqual>& rhs)
{
const bool sizes_match = (lhs.size() == rhs.size());
bool elements_match = true;
typedef typename etl::iunordered_multiset<TKey, THash, TKeyEqual>::const_iterator itr_t;
if (sizes_match)
{
for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i)
itr_t l_begin = lhs.begin();
itr_t l_end = lhs.end();
while ((l_begin != l_end) && elements_match)
{
if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i)))
const TKey l_value = *l_begin;
// See if the lhs keys exist in the rhs.
ETL_OR_STD::pair<itr_t, itr_t> l_range = lhs.equal_range(l_value);
ETL_OR_STD::pair<itr_t, itr_t> r_range = rhs.equal_range(l_value);
if (r_range.first != rhs.end())
{
bool distance_match = (etl::distance(l_range.first, l_range.second) == etl::distance(r_range.first, r_range.second));
if (distance_match)
{
elements_match = etl::is_permutation(l_range.first, l_range.second, r_range.first, r_range.second);
}
else
{
elements_match = false;
}
}
else
{
elements_match = false;
}
++l_begin;
}
}
@ -1428,8 +1455,9 @@ namespace etl
///\return <b>true</b> if the arrays are not equal, otherwise <b>false</b>
///\ingroup unordered_multiset
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator !=(const etl::iunordered_multiset<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_multiset<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename THash, typename TKeyEqual>
bool operator !=(const etl::iunordered_multiset<TKey, THash, TKeyEqual>& lhs,
const etl::iunordered_multiset<TKey, THash, TKeyEqual>& rhs)
{
return !(lhs == rhs);
}

View File

@ -678,13 +678,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(&bucket);
result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
@ -712,13 +712,13 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(key);
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(key);
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -766,13 +766,13 @@ namespace etl
if (bucket.empty())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT;
// Just add the pointer to the bucket;
bucket.insert_after(bucket.before_begin(), node);
bucket.insert_after(bucket.before_begin(), *node);
adjust_first_last_markers_after_insert(&bucket);
result.first = iterator(pbuckets + number_of_buckets, pbucket, pbucket->begin());
@ -800,13 +800,13 @@ namespace etl
if (inode == bucket.end())
{
// Get a new node.
node_t& node = allocate_data_node();
node.clear();
::new (&node.key) value_type(etl::move(key));
node_t* node = allocate_data_node();
node->clear();
::new (&node->key) value_type(etl::move(key));
ETL_INCREMENT_DEBUG_COUNT;
// Add the node to the end of the bucket;
bucket.insert_after(inode_previous, node);
bucket.insert_after(inode_previous, *node);
adjust_first_last_markers_after_insert(&bucket);
++inode_previous;
@ -1272,20 +1272,20 @@ namespace etl
//*************************************************************************
/// Move from a range
//*************************************************************************
void move(iterator first, iterator last)
void move(iterator b, iterator e)
{
#if ETL_IS_DEBUG_BUILD
difference_type d = etl::distance(first, last);
difference_type d = etl::distance(b, e);
ETL_ASSERT(d >= 0, ETL_ERROR(unordered_set_iterator));
ETL_ASSERT(size_t(d) <= max_size(), ETL_ERROR(unordered_set_full));
#endif
while (first != last)
while (b != e)
{
iterator temp = first;
iterator temp = b;
++temp;
insert(etl::move(*first));
first = temp;
insert(etl::move(*b));
b = temp;
}
}
#endif
@ -1295,10 +1295,10 @@ namespace etl
//*************************************************************************
/// Create a node.
//*************************************************************************
node_t& allocate_data_node()
node_t* allocate_data_node()
{
node_t* (etl::ipool::*func)() = &etl::ipool::allocate<node_t>;
return *(pnodepool->*func)();
return (pnodepool->*func)();
}
//*********************************************************************
@ -1309,7 +1309,7 @@ namespace etl
if (size() == 1)
{
first = pbucket;
last = pbucket;
last = pbucket;
}
else
{
@ -1327,7 +1327,7 @@ namespace etl
//*********************************************************************
/// Adjust the first and last markers according to the erased entry.
//*********************************************************************
void adjust_first_last_markers_after_erase(bucket_t* pcurrent)
void adjust_first_last_markers_after_erase(bucket_t* pbucket)
{
if (empty())
{
@ -1336,7 +1336,7 @@ namespace etl
}
else
{
if (pcurrent == first)
if (pbucket == first)
{
// We erased the first so, we need to search again from where we erased.
while (first->empty())
@ -1344,29 +1344,29 @@ namespace etl
++first;
}
}
else if (pcurrent == last)
else if (pbucket == last)
{
// We erased the last, so we need to search again. Start from the first, go no further than the current last.
bucket_t* pcurrent = first;
pbucket = first;
bucket_t* pend = last;
last = first;
while (pcurrent != pend)
while (pbucket != pend)
{
if (!pcurrent->empty())
if (!pbucket->empty())
{
last = pcurrent;
last = pbucket;
}
++pcurrent;
++pbucket;
}
}
}
}
//*********************************************************************
/// Delete a data noe at the specified location.
/// Delete a data node at the specified location.
//*********************************************************************
local_iterator delete_data_node(local_iterator iprevious, local_iterator icurrent, bucket_t& bucket)
{
@ -1427,20 +1427,40 @@ namespace etl
///\return <b>true</b> if the sets are equal, otherwise <b>false</b>
///\ingroup unordered_set
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator ==(const etl::iunordered_set<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_set<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename THash, typename TKeyEqual>
bool operator ==(const etl::iunordered_set<TKey, THash, TKeyEqual>& lhs,
const etl::iunordered_set<TKey, THash, TKeyEqual>& rhs)
{
const bool sizes_match = (lhs.size() == rhs.size());
bool elements_match = true;
typedef typename etl::iunordered_set<TKey, THash, TKeyEqual>::const_iterator itr_t;
if (sizes_match)
{
for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i)
itr_t l_begin = lhs.begin();
itr_t l_end = lhs.end();
while ((l_begin != l_end) && elements_match)
{
if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i)))
const TKey l_value = *l_begin;
// See if the lhs key exists in the rhs.
ETL_OR_STD::pair<itr_t, itr_t> range = rhs.equal_range(l_value);
if (range.first != rhs.end())
{
// See if the values match
const TKey r_value = *(range.first);
elements_match = (r_value == l_value);
}
else
{
elements_match = false;
}
++l_begin;
}
}
@ -1454,8 +1474,9 @@ namespace etl
///\return <b>true</b> if the sets are not equal, otherwise <b>false</b>
///\ingroup unordered_set
//***************************************************************************
template <typename TKey, typename TMapped, typename TKeyCompare>
bool operator !=(const etl::iunordered_set<TKey, TMapped, TKeyCompare>& lhs, const etl::iunordered_set<TKey, TMapped, TKeyCompare>& rhs)
template <typename TKey, typename THash, typename TKeyEqual>
bool operator !=(const etl::iunordered_set<TKey, THash, TKeyEqual>& lhs,
const etl::iunordered_set<TKey, THash, TKeyEqual>& rhs)
{
return !(lhs == rhs);
}

View File

@ -1346,11 +1346,9 @@ namespace etl
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#ifdef ETL_IVECTOR_REPAIR_ENABLE
virtual
#endif
virtual void repair() ETL_OVERRIDE
#else
void repair()
#ifdef ETL_IVECTOR_REPAIR_ENABLE
ETL_OVERRIDE
#endif
{
ETL_ASSERT_OR_RETURN(etl::is_trivially_copyable<T>::value, ETL_ERROR(etl::vector_incompatible_type));
@ -1527,9 +1525,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#ifdef ETL_IVECTOR_REPAIR_ENABLE
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}
@ -1649,9 +1648,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#ifdef ETL_IVECTOR_REPAIR_ENABLE
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::ivector<T*>::repair_buffer(buffer);
@ -1806,9 +1806,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#ifdef ETL_IVECTOR_REPAIR_ENABLE
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::ivector<T*>::repair_buffer(this->p_buffer);

View File

@ -231,9 +231,10 @@ namespace etl
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
#if ETL_HAS_ISTRING_REPAIR
virtual
#endif
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
etl::iwstring::repair_buffer(buffer);
}
@ -414,9 +415,10 @@ namespace etl
//*************************************************************************
/// Fix the internal pointers after a low level memory copy.
//*************************************************************************
void repair()
#if ETL_HAS_ISTRING_REPAIR
ETL_OVERRIDE
virtual void repair() ETL_OVERRIDE
#else
void repair()
#endif
{
}

View File

@ -1,5 +1,6 @@
===============================================================================
20.38.11
#812-Implement-SAE-J1850-CRC8
#850 Fixed names according to Arduino's guidelines
===============================================================================
@ -160,7 +161,7 @@ Comments and noexcept updates to placement new
etl::variant (variadic) refactor and updates for C++ standards compatibility
etl::overload available in C++17 only
map/flat_map speed optimisations
Various C++03 compatibilty updates for maps
Various C++03 compatibility updates for maps
Refactored Bash compilation scripts to allow selection of C++ standard and optimisation level
Renamed Bash compilation scripts. Changed 'sanity checks' to 'syntax checks
Some internal constant case changes from all upper to capital case
@ -226,7 +227,7 @@ Removed unused ETL_USE_MEM_BUILTINS option
===============================================================================
20.35.7
Updated etl::delgate to handle const functors correctly
Updated etl::delegate to handle const functors correctly
===============================================================================
20.35.6
@ -274,7 +275,7 @@ Removed duplicate include in etl::array_view
#621 No need to initialize the C-compiler, small speed improvement
#626 Empty etl::optional ctor storage initialization performance
Removed constexpr for etl::bit_cast due to unreliability of compiler support
Added has_value() as an alias for is_value() for etl::result (consistancy with STL conventions)
Added has_value() as an alias for is_value() for etl::result (consistency with STL conventions)
Added ETL_ERROR_WITH_VALUE macro for exceptions that require a value
Changed scaling template parameter for etl::scaled_rounding to uint32_t
Remove redundant etl::pair functions
@ -471,7 +472,7 @@ Fixed send_message function signatures.
20.24.0
#503 Algorithm transform uses expensive post increment operator - Fixed for all occurrences of iterator increment.
#504 ETL_CONSTANT vs const in binary.h - Fixed.
Many algorithms will leverage built-ins, if available. Dependant on compiler version.
Many algorithms will leverage built-ins, if available. Dependent on compiler version.
Added detection or selection of built-ins.
Much of etl::string and etl::string_view can be constexpr.
Added ETL initializer_list implementations that are compatible with major compilers.
@ -839,7 +840,7 @@ Added example application for shared messages.
Added a lockable queue with locks implemented as pure virtuals.
Refactored the other queues.
Fixed missing virtual destructor for C++11 observer.
Added etl::successor class for consistant 'chain of responsibilty' pattern generation.
Added etl::successor class for consistent 'chain of responsibilty' pattern generation.
Added missing constructors to unique_ptr.
Added nullptr check to unique_ptr destructor.
Fixed VS2019 warning for etl::deque iterators.
@ -1807,7 +1808,7 @@ Added constexpr constructors to string_view and array_view.
===============================================================================
14.8.2
Added missing #include "stl/interator.h" in frame_check_sequence.h
Added missing #include "stl/iterator.h" in frame_check_sequence.h
===============================================================================
14.8.1
@ -2040,7 +2041,7 @@ Added SPSC & MPPC queues
===============================================================================
11.3.0
Improved compatibility with 64 bit pltforms.
Improved compatibility with 64 bit platforms.
===============================================================================
11.2.0
@ -2077,7 +2078,7 @@ Improved etl::endianness. Added static functions.
===============================================================================
10.19.2
Fixed strict aliasing warnings for endianess.
Fixed strict aliasing warnings for endianness.
===============================================================================
10.19.1
@ -2086,7 +2087,7 @@ Fixed strict aliasing warnings for aligned storage.
===============================================================================
10.19.0
Added 'create' and 'destroy' functions to pools.
Modified class heirarchy.
Modified class hierarchy.
etl::generic_pool is derived from on etl::ipool.
etl::pool is derived from etl::generic_pool.

Binary file not shown.

View File

@ -98,6 +98,8 @@ add_executable(etl_tests
test_crc8_ebu.cpp
test_crc8_icode.cpp
test_crc8_itu.cpp
test_crc8_j1850_zero.cpp
test_crc8_j1850.cpp
test_crc8_maxim.cpp
test_crc8_rohc.cpp
test_crc8_wcdma.cpp
@ -381,6 +383,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
-Werror
-Wfloat-equal
-Wuseless-cast
-Wshadow
-Wnull-dereference
)
endif ()
@ -393,11 +397,13 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-Wextra
-Werror
-Wfloat-equal
-Wshadow
-Wnull-dereference
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (ETL_ENABLE_SANITIZER)
if (ETL_ENABLE_SANITIZER MATCHES "ON")
message(STATUS "Compiling with Sanitizer enabled")
# MinGW doesn't presently support sanitization
if (NOT MINGW)

View File

@ -19,10 +19,10 @@
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK(" #value ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK(" #value ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -41,10 +41,10 @@
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), #value); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK(" #value ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK(" #value ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -62,10 +62,10 @@
UnitTest::CheckEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -83,10 +83,10 @@
UnitTest::CheckEqualHex(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -104,10 +104,10 @@
UnitTest::CheckNotEqual(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -125,10 +125,10 @@
UnitTest::CheckNotEqualHex(*UnitTest::CurrentTest::Results(), expected, actual, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_EQUAL(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -146,10 +146,10 @@
UnitTest::CheckClose(*UnitTest::CurrentTest::Results(), expected, actual, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_CLOSE(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_CLOSE(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -167,10 +167,10 @@
UnitTest::CheckArrayEqual(*UnitTest::CurrentTest::Results(), expected, actual, count, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -188,10 +188,10 @@
UnitTest::CheckArrayClose(*UnitTest::CurrentTest::Results(), expected, actual, count, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \
@ -209,10 +209,10 @@
UnitTest::CheckArray2DClose(*UnitTest::CurrentTest::Results(), expected, actual, rows, columns, tolerance, UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__)); \
}) \
UNITTEST_IMPL_RETHROW (UnitTest::RequiredCheckException) \
UNITTEST_IMPL_CATCH (std::exception, e, \
UNITTEST_IMPL_CATCH (std::exception, exc, \
{ \
UnitTest::MemoryOutStream UnitTest_message; \
UnitTest_message << "Unhandled exception (" << e.what() << ") in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"; \
UnitTest_message << "Unhandled exception (" << exc.what() << ") in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"; \
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
UnitTest_message.GetText()); \
}) \

View File

@ -34,7 +34,7 @@ namespace UnitTest
template <>
inline std::string DisplayValue(const char& c)
{
using type = std::char_traits<char>::int_type;
typedef std::char_traits<char>::int_type type;
std::ostringstream oss;
@ -47,7 +47,7 @@ namespace UnitTest
template <>
inline std::string DisplayValue(const char8_t& c)
{
using type = std::char_traits<char8_t>::int_type;
typedef std::char_traits<char8_t>::int_type type;
std::ostringstream oss;
@ -60,7 +60,7 @@ namespace UnitTest
template <>
inline std::string DisplayValue(const wchar_t& c)
{
using type = std::char_traits<wchar_t>::int_type;
typedef std::char_traits<wchar_t>::int_type type;
std::ostringstream oss;
@ -73,7 +73,7 @@ namespace UnitTest
template <>
inline std::string DisplayValue(const char16_t& c)
{
using type = std::char_traits<char16_t>::int_type;
typedef std::char_traits<char16_t>::int_type type;
std::ostringstream oss;
@ -85,7 +85,7 @@ namespace UnitTest
template <>
inline std::string DisplayValue(const char32_t& c)
{
using type = std::char_traits<char32_t>::int_type;
typedef std::char_traits<char32_t>::int_type type;
std::ostringstream oss;
@ -171,6 +171,7 @@ namespace UnitTest
return !value;
}
#if __cplusplus >= 201103L
template< typename Expected, typename Actual >
void CheckEqual(TestResults& results, Expected&& expected, Actual&& actual, TestDetails const& details)
{
@ -183,6 +184,20 @@ namespace UnitTest
results.OnTestFailure(details, stream.GetText());
}
}
#else
template< typename Expected, typename Actual >
void CheckEqual(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details)
{
if (!(expected == actual))
{
UnitTest::MemoryOutStream stream;
stream << "Expected "
<< DisplayValue(expected) << " but was " << DisplayValue(actual);
results.OnTestFailure(details, stream.GetText());
}
}
#endif
template< typename Expected, typename Actual >
void CheckEqualHex(TestResults& results, Expected const& expected, Actual const& actual, TestDetails const& details)
@ -190,7 +205,9 @@ namespace UnitTest
if (!(expected == actual))
{
UnitTest::MemoryOutStream stream;
stream << std::hex << std::uppercase << std::setfill('0') << "Expected 0x" << std::setw(2 * sizeof(Expected)) << expected << " but was 0x" << std::setw(2 * sizeof(Actual)) << actual;
stream << std::hex << std::uppercase << std::setfill('0')
<< "Expected 0x" << std::setw(2 * sizeof(Expected)) << (expected & ~(typename std::make_unsigned<Expected>::type(0)))
<< " but was 0x" << std::setw(2 * sizeof(Actual)) << (actual & ~(typename std::make_unsigned<Actual>::type(0)));
results.OnTestFailure(details, stream.GetText());
}
@ -214,7 +231,8 @@ namespace UnitTest
if (expected == actual)
{
UnitTest::MemoryOutStream stream;
stream << std::hex << std::uppercase << std::setfill('0') << std::setw(2 * sizeof(Actual)) << "Expected not equal, but both values are " << actual;
stream << std::hex << std::uppercase << std::setfill('0') << std::setw(2 * sizeof(Actual))
<< "Expected not equal, but both values are " << (actual & ~(typename std::make_unsigned<Actual>::type(0)));
results.OnTestFailure(details, stream.GetText());
}

View File

@ -39,12 +39,12 @@ namespace UnitTest {
testObject.RunImpl();
})
#endif
UNITTEST_IMPL_CATCH(RequiredCheckException, e, { (void)e; })
UNITTEST_IMPL_CATCH(AssertException, e, { (void)e; })
UNITTEST_IMPL_CATCH(std::exception, e,
UNITTEST_IMPL_CATCH(RequiredCheckException, exc, { (void)exc; })
UNITTEST_IMPL_CATCH(AssertException, exc, { (void)exc; })
UNITTEST_IMPL_CATCH(std::exception, exc,
{
MemoryOutStream stream;
stream << "Unhandled exception: " << e.what();
stream << "Unhandled exception: " << exc.what();
CurrentTest::Results()->OnTestFailure(details, stream.GetText());
})
UNITTEST_IMPL_CATCH_ALL

View File

@ -54,21 +54,61 @@ target_include_directories(etl_tests
${CMAKE_CURRENT_LIST_DIR}
)
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GCC compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Using Clang compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Werror
-Wfloat-equal
-Wuseless-cast
-Wshadow
-Wnull-dereference
)
target_link_options(etl_tests
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wshadow
-Wnull-dereference
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (ETL_ENABLE_SANITIZER MATCHES "ON")
message(STATUS "Compiling with Sanitizer enabled")
# MinGW doesn't presently support sanitization
if (NOT MINGW)
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
target_link_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
endif()
endif ()
endif ()
# Enable the 'make test' CMake target using the executable defined above
add_test(etl_error_handler_unit_tests etl_tests)

View File

@ -54,21 +54,61 @@ target_include_directories(etl_tests
${CMAKE_CURRENT_LIST_DIR}
)
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GCC compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Using Clang compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wuseless-cast
-Wshadow
-Wnull-dereference
)
target_link_options(etl_tests
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wshadow
-Wnull-dereference
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (ETL_ENABLE_SANITIZER MATCHES "ON")
message(STATUS "Compiling with Sanitizer enabled")
# MinGW doesn't presently support sanitization
if (NOT MINGW)
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
target_link_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
endif()
endif ()
endif ()
# Enable the 'make test' CMake target using the executable defined above
add_test(etl_error_handler_unit_tests etl_tests)

View File

@ -55,21 +55,61 @@ target_include_directories(etl_tests
${CMAKE_CURRENT_LIST_DIR}
)
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GCC compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Using Clang compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wuseless-cast
-Wshadow
-Wnull-dereference
)
target_link_options(etl_tests
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wshadow
-Wnull-dereference
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (ETL_ENABLE_SANITIZER MATCHES "ON")
message(STATUS "Compiling with Sanitizer enabled")
# MinGW doesn't presently support sanitization
if (NOT MINGW)
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
target_link_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
endif()
endif ()
endif ()
# Enable the 'make test' CMake target using the executable defined above
add_test(etl_error_handler_unit_tests etl_tests)

View File

@ -55,21 +55,61 @@ target_include_directories(etl_tests
${CMAKE_CURRENT_LIST_DIR}
)
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GCC compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Using Clang compiler")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wuseless-cast
-Wshadow
-Wnull-dereference
)
target_link_options(etl_tests
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
-fno-omit-frame-pointer
-fno-common
-Wall
-Wextra
-Werror
-Wfloat-equal
-Wshadow
-Wnull-dereference
)
endif ()
if ((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
if (ETL_ENABLE_SANITIZER MATCHES "ON")
message(STATUS "Compiling with Sanitizer enabled")
# MinGW doesn't presently support sanitization
if (NOT MINGW)
target_compile_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
target_link_options(etl_tests
PRIVATE
-fsanitize=address,undefined,bounds
)
endif()
endif ()
endif ()
# Enable the 'make test' CMake target using the executable defined above
add_test(etl_initializer_list_unit_tests etl_tests)

View File

@ -40,26 +40,26 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -283,7 +283,7 @@ compiler=$clang_compiler
SetConfigurationName "STL"
PrintHeader
rm * -rf
cmake -DCMAKE_C_COMPILER="gcc" -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF ..
cmake -DCMAKE_C_COMPILER="clang" -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF -DETL_OPTIMISATION=$opt -DETL_CXX_STANDARD=$cxx_standard -DETL_ENABLE_SANITIZER=$sanitize -DETL_MESSAGES_ARE_NOT_VIRTUAL=OFF ..
cmake --build .
if [ $? -eq 0 ]; then
PassedCompilation

View File

@ -38,6 +38,10 @@ set_target_properties(t98 PROPERTIES
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)
target_compile_options(t98
PRIVATE
-fsyntax-only
)
target_sources(t98 PRIVATE etl_profile.h
../absolute.h.t.cpp
../algorithm.h.t.cpp
@ -123,6 +127,8 @@ target_sources(t98 PRIVATE etl_profile.h
../crc8_maxim.h.t.cpp
../crc8_rohc.h.t.cpp
../crc8_wcdma.h.t.cpp
../crc8_j1850.h.t.cpp
../crc8_j1850_zero.h.t.cpp
../cyclic_value.h.t.cpp
../debounce.h.t.cpp
../debug_count.h.t.cpp

View File

@ -38,6 +38,10 @@ set_target_properties(t11 PROPERTIES
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)
target_compile_options(t11
PRIVATE
-fsyntax-only
)
target_sources(t11 PRIVATE etl_profile.h
../absolute.h.t.cpp
../algorithm.h.t.cpp
@ -123,6 +127,8 @@ target_sources(t11 PRIVATE etl_profile.h
../crc8_maxim.h.t.cpp
../crc8_rohc.h.t.cpp
../crc8_wcdma.h.t.cpp
../crc8_j1850.h.t.cpp
../crc8_j1850_zero.h.t.cpp
../cyclic_value.h.t.cpp
../debounce.h.t.cpp
../debug_count.h.t.cpp

Some files were not shown because too many files have changed in this diff Show More