From 88d0881337098e95c9f76b4657e5836d4fd7e2ef Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 8 Dec 2022 13:29:53 +0000 Subject: [PATCH] Sync to 20.35.5 --- library.json | 2 +- library.properties | 2 +- src/etl/absolute.h | 4 +- src/etl/algorithm.h | 46 +- src/etl/alignment.h | 4 +- src/etl/array.h | 5 +- src/etl/array_view.h | 13 +- src/etl/atomic/atomic_gcc_sync.h | 14 + src/etl/basic_string.h | 9 +- src/etl/binary.h | 39 +- src/etl/bip_buffer_spsc_atomic.h | 6 +- src/etl/bit.h | 28 +- src/etl/bit_stream.h | 6 +- src/etl/bitset.h | 1302 +----- src/etl/bresenham_line.h | 4 +- src/etl/byte_stream.h | 8 +- src/etl/callback_timer.h | 4 +- src/etl/callback_timer_atomic.h | 5 +- src/etl/callback_timer_interrupt.h | 5 +- src/etl/callback_timer_locked.h | 5 +- src/etl/char_traits.h | 66 +- src/etl/checksum.h | 4 +- src/etl/circular_buffer.h | 7 +- src/etl/circular_iterator.h | 753 ++++ src/etl/container.h | 4 +- src/etl/cyclic_value.h | 5 +- src/etl/debounce.h | 4 +- src/etl/debug_count.h | 6 +- src/etl/deque.h | 6 +- src/etl/endianness.h | 15 +- src/etl/error_handler.h | 10 +- src/etl/expected.h | 253 ++ src/etl/factorial.h | 4 +- src/etl/fibonacci.h | 4 +- src/etl/file_error_numbers.h | 2 + src/etl/fixed_iterator.h | 18 +- src/etl/flags.h | 8 +- src/etl/fnv_1.h | 3 +- src/etl/forward_list.h | 4 +- src/etl/frame_check_sequence.h | 5 +- src/etl/fsm.h | 4 +- src/etl/generators/fsm_generator.h | 4 +- src/etl/generators/message_packet_generator.h | 74 +- src/etl/generators/message_router_generator.h | 90 +- src/etl/generators/smallest_generator.h | 8 +- src/etl/generators/type_lookup_generator.h | 6 +- src/etl/generators/type_traits_generator.h | 8 +- src/etl/generators/variant_pool_generator.h | 4 +- src/etl/hash.h | 68 +- src/etl/ihash.h | 6 +- src/etl/indirect_vector.h | 14 +- src/etl/initializer_list.h | 2 +- src/etl/instance_count.h | 4 +- src/etl/integral_limits.h | 8 +- src/etl/intrusive_forward_list.h | 13 +- src/etl/intrusive_links.h | 5 +- src/etl/intrusive_list.h | 13 +- src/etl/intrusive_queue.h | 4 +- src/etl/intrusive_stack.h | 4 +- src/etl/io_port.h | 4 +- src/etl/iterator.h | 299 +- src/etl/jenkins.h | 5 +- src/etl/limits.h | 20 +- src/etl/list.h | 4 +- src/etl/log.h | 4 +- src/etl/map.h | 4 +- src/etl/mem_cast.h | 6 +- src/etl/memory.h | 148 +- src/etl/memory_model.h | 4 +- src/etl/message.h | 4 +- src/etl/message_broker.h | 330 ++ src/etl/message_bus.h | 53 +- src/etl/message_packet.h | 536 ++- src/etl/message_router.h | 258 +- src/etl/message_router_registry.h | 4 +- src/etl/message_timer.h | 6 +- src/etl/message_timer_atomic.h | 6 +- src/etl/message_timer_interrupt.h | 6 +- src/etl/message_timer_locked.h | 6 +- src/etl/message_types.h | 4 +- src/etl/multimap.h | 4 +- src/etl/multiset.h | 4 +- src/etl/murmur3.h | 4 +- src/etl/mutex.h | 2 +- src/etl/null_type.h | 2 + src/etl/optional.h | 396 +- src/etl/parameter_pack.h | 4 +- src/etl/pearson.h | 4 +- src/etl/placement_new.h | 6 +- src/etl/platform.h | 92 +- src/etl/poly_span.h | 6 +- src/etl/power.h | 6 +- src/etl/priority_queue.h | 5 +- src/etl/private/addressof.h | 61 + src/etl/private/bitset_legacy.h | 1490 +++++++ src/etl/private/bitset_new.h | 3917 +++++++++++++++++ src/etl/private/delegate_cpp03.h | 34 +- .../diagnostic_pessimizing_move_push.h | 39 + .../private/diagnostic_uninitialized_push.h | 45 + src/etl/private/minmax_pop.h | 2 +- src/etl/private/minmax_push.h | 2 +- src/etl/private/pvoidvector.h | 5 +- src/etl/private/to_string_helper.h | 4 +- src/etl/private/variant_legacy.h | 13 +- src/etl/private/variant_variadic.h | 42 +- src/etl/private/vector_base.h | 4 +- src/etl/profiles/determine_compiler.h | 6 + src/etl/queue.h | 6 +- src/etl/queue_lockable.h | 6 +- src/etl/queue_mpmc_mutex.h | 6 +- src/etl/queue_spsc_atomic.h | 6 +- src/etl/queue_spsc_isr.h | 6 +- src/etl/queue_spsc_locked.h | 6 +- src/etl/radix.h | 4 +- src/etl/random.h | 4 +- src/etl/ratio.h | 4 +- src/etl/reference_counted_message.h | 4 +- src/etl/reference_counted_object.h | 34 +- src/etl/reference_flat_map.h | 4 +- src/etl/reference_flat_multimap.h | 4 +- src/etl/reference_flat_multiset.h | 5 +- src/etl/reference_flat_set.h | 5 +- src/etl/result.h | 57 +- src/etl/scaled_rounding.h | 35 +- src/etl/scheduler.h | 4 +- src/etl/set.h | 5 +- src/etl/smallest.h | 8 +- src/etl/span.h | 99 +- src/etl/sqrt.h | 4 +- src/etl/stack.h | 6 +- src/etl/state_chart.h | 4 +- src/etl/string.h | 6 +- src/etl/string_utilities.h | 6 +- src/etl/string_view.h | 41 +- src/etl/task.h | 4 +- src/etl/timer.h | 5 +- src/etl/to_arithmetic.h | 1017 +++++ src/etl/type_lookup.h | 4 +- src/etl/type_traits.h | 8 +- src/etl/u16string.h | 6 +- src/etl/u32string.h | 6 +- src/etl/unaligned_type.h | 260 +- src/etl/unordered_map.h | 101 +- src/etl/unordered_multimap.h | 99 +- src/etl/unordered_multiset.h | 96 +- src/etl/unordered_set.h | 160 +- src/etl/utility.h | 121 +- src/etl/variant_pool.h | 4 +- src/etl/vector.h | 23 +- src/etl/version.h | 4 +- src/etl/wstring.h | 8 +- 151 files changed, 10732 insertions(+), 2514 deletions(-) create mode 100644 src/etl/circular_iterator.h create mode 100644 src/etl/expected.h create mode 100644 src/etl/message_broker.h create mode 100644 src/etl/private/addressof.h create mode 100644 src/etl/private/bitset_legacy.h create mode 100644 src/etl/private/bitset_new.h create mode 100644 src/etl/private/diagnostic_pessimizing_move_push.h create mode 100644 src/etl/private/diagnostic_uninitialized_push.h create mode 100644 src/etl/to_arithmetic.h diff --git a/library.json b/library.json index 6245a7c..f18b337 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.32.1", + "version": "20.35.5", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index c833012..5169672 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.32.1 +version=20.35.5 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/src/etl/absolute.h b/src/etl/absolute.h index cfbe80f..5812f86 100644 --- a/src/etl/absolute.h +++ b/src/etl/absolute.h @@ -68,8 +68,8 @@ namespace etl ETL_CONSTEXPR typename etl::enable_if::value, TReturn>::type absolute_unsigned(T value) { - return (value == etl::integral_limits::min) ? etl::integral_limits::max / 2U - : (value < T(0)) ? TReturn(-value) : TReturn(value); + return (value == etl::integral_limits::min) ? (etl::integral_limits::max / 2U) + 1U + : (value < T(0)) ? TReturn(-value) : TReturn(value); } //*************************************************************************** diff --git a/src/etl/algorithm.h b/src/etl/algorithm.h index b8cdbad..cb287de 100644 --- a/src/etl/algorithm.h +++ b/src/etl/algorithm.h @@ -38,15 +38,15 @@ SOFTWARE. /// Additional new variants of certain algorithms. ///\ingroup utilities -#include -#include - #include "platform.h" #include "type_traits.h" #include "iterator.h" #include "functional.h" #include "utility.h" +#include +#include + #include "private/minmax_push.h" #if ETL_USING_STL @@ -183,13 +183,6 @@ namespace etl { return std::copy_n(sb, count, db); } -#elif ETL_USING_STL && ETL_USING_CPP11 && !ETL_FORCE_CONSTEXPR_ALGORITHMS - // Use the STL implementation - template - TIterator2 copy_n(TIterator1 sb, TSize count, TIterator2 db) - { - return std::copy_n(sb, count, db); - } #else // Non-pointer or not trivially copyable or not using builtin memcpy. template @@ -236,12 +229,6 @@ namespace etl { return std::move(sb, se, db); } -#elif ETL_USING_STL && ETL_USING_CPP11 && !ETL_FORCE_CONSTEXPR_ALGORITHMS - template - TIterator2 move(TIterator1 sb, TIterator1 se, TIterator2 db) - { - return std::move(sb, se, db); - } #else // non-pointer or not trivially copyable template @@ -267,12 +254,6 @@ namespace etl { return std::move_backward(sb, se, de); } -#elif ETL_USING_STL && ETL_USING_CPP11 && !ETL_FORCE_CONSTEXPR_ALGORITHMS - template - TIterator2 move_backward(TIterator1 sb, TIterator1 se, TIterator2 de) - { - return std::move_backward(sb, se, de); - } #else // non-pointer or not trivially copyable template @@ -424,6 +405,27 @@ namespace etl etl::upper_bound(first, last, value, compare())); } + //*************************************************************************** + // binary_search + //*************************************************************************** + template + ETL_NODISCARD + bool binary_search(TIterator first, TIterator last, const T& value, Compare compare) + { + first = etl::lower_bound(first, last, value, compare); + + return (!(first == last) && !(compare(value, *first))); + } + + template + ETL_NODISCARD + bool binary_search(TIterator first, TIterator last, const T& value) + { + typedef etl::less::value_type> compare; + + return binary_search(first, last, value, compare()); + } + //*************************************************************************** // find_if //*************************************************************************** diff --git a/src/etl/alignment.h b/src/etl/alignment.h index 2e3b626..a5ccb9a 100644 --- a/src/etl/alignment.h +++ b/src/etl/alignment.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_ALIGNMENT_INCLUDED #define ETL_ALIGNMENT_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "static_assert.h" +#include + ///\defgroup alignment alignment /// Creates a variable of the specified type at the specified alignment. /// \ingroup utilities diff --git a/src/etl/array.h b/src/etl/array.h index f94b94f..1435ddb 100644 --- a/src/etl/array.h +++ b/src/etl/array.h @@ -31,10 +31,7 @@ SOFTWARE. #ifndef ETL_ARRAY_INCLUDED #define ETL_ARRAY_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" @@ -46,6 +43,8 @@ SOFTWARE. #include "nth_type.h" #include "initializer_list.h" +#include + ///\defgroup array array /// A replacement for std::array if you haven't got C++0x11. ///\ingroup containers diff --git a/src/etl/array_view.h b/src/etl/array_view.h index 0223cb8..84ceeea 100644 --- a/src/etl/array_view.h +++ b/src/etl/array_view.h @@ -40,10 +40,9 @@ SOFTWARE. #include "nullptr.h" #include "hash.h" #include "algorithm.h" -#include "memory.h" #include "type_traits.h" -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 #include #endif @@ -155,7 +154,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR array_view(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR array_view(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { @@ -165,14 +164,14 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR array_view(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR array_view(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { } #endif -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //************************************************************************* /// Construct from std::array. //************************************************************************* @@ -215,7 +214,7 @@ namespace etl template ETL_CONSTEXPR array_view(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { @@ -228,7 +227,7 @@ namespace etl template ETL_CONSTEXPR array_view(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { diff --git a/src/etl/atomic/atomic_gcc_sync.h b/src/etl/atomic/atomic_gcc_sync.h index 337c375..6f54c77 100644 --- a/src/etl/atomic/atomic_gcc_sync.h +++ b/src/etl/atomic/atomic_gcc_sync.h @@ -39,6 +39,20 @@ SOFTWARE. #include #include +// Select the amtomic builtins based on the ARM5 version of the GCC compiler. +#if defined(ETL_COMPILER_ARM5) + #define ETL_USE_SYNC_BUILTINS +#endif + +// Select the amtomic builtins based on the ARM6 version of the GCC compiler. +#if defined(ETL_COMPILER_ARM6) + #if ETL_COMPILER_FULL_VERSION >= 40700 + #define ETL_USE_ATOMIC_BUILTINS + #else + #define ETL_USE_SYNC_BUILTINS + #endif +#endif + // Select the amtomic builtins based on the version of the GCC compiler. #if defined(ETL_COMPILER_GCC) #if ETL_COMPILER_FULL_VERSION >= 40700 diff --git a/src/etl/basic_string.h b/src/etl/basic_string.h index d1fee18..4489203 100644 --- a/src/etl/basic_string.h +++ b/src/etl/basic_string.h @@ -31,12 +31,7 @@ SOFTWARE. #ifndef ETL_BASIC_STRING_INCLUDED #define ETL_BASIC_STRING_INCLUDED -#include -#include -#include - #include "platform.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" @@ -53,6 +48,10 @@ SOFTWARE. #include "binary.h" #include "flags.h" +#include +#include +#include + #include "private/minmax_push.h" //***************************************************************************** diff --git a/src/etl/binary.h b/src/etl/binary.h index 218e1c3..658d41b 100644 --- a/src/etl/binary.h +++ b/src/etl/binary.h @@ -441,7 +441,7 @@ namespace etl ETL_CONSTEXPR14 bool has_zero_byte(TValue value) { typedef typename etl::make_unsigned::type unsigned_t; - const unsigned_t mask = etl::binary_fill(0x7FU); + ETL_CONSTEXPR14 const unsigned_t mask = etl::binary_fill(0x7FU); const unsigned_t temp = unsigned_t(~((((unsigned_t(value) & mask) + mask) | unsigned_t(value)) | mask)); return (temp != 0U); @@ -455,7 +455,7 @@ namespace etl ETL_CONSTEXPR14 bool has_zero_byte() { typedef typename etl::make_unsigned::type unsigned_t; - const unsigned_t mask = etl::binary_fill(0x7FU); + ETL_CONSTEXPR14 const unsigned_t mask = etl::binary_fill(0x7FU); const unsigned_t temp = unsigned_t(~((((unsigned_t(N) & mask) + mask) | unsigned_t(N)) | mask)); return (temp != 0U); @@ -2181,6 +2181,41 @@ namespace etl return ((static_cast::type>(value) & 1U) == 0U); } + //*********************************** + template + class lsb_mask + { + public: + + static ETL_CONSTANT T value = static_cast(etl::max_value_for_nbits::value); + }; + + //*********************************** + template + ETL_CONSTEXPR14 T make_lsb_mask(size_t nbits) + { + typedef typename etl::make_unsigned::type type; + + return (nbits == etl::integral_limits::bits) ? static_cast(etl::integral_limits::max) + : static_cast((static_cast(1U) << nbits) - 1U); + }; + + //*********************************** + template + class msb_mask + { + public: + + static ETL_CONSTANT T value = static_cast(etl::reverse_bits_const::value>::value); + }; + + //*********************************** + template + ETL_CONSTEXPR T make_msb_mask(size_t nbits) + { + return static_cast(etl::reverse_bits(make_lsb_mask(nbits))); + }; + //*************************************************************************** /// 8 bit binary byte constants. ///\ingroup binary diff --git a/src/etl/bip_buffer_spsc_atomic.h b/src/etl/bip_buffer_spsc_atomic.h index c22bd77..dad2411 100644 --- a/src/etl/bip_buffer_spsc_atomic.h +++ b/src/etl/bip_buffer_spsc_atomic.h @@ -38,9 +38,6 @@ SOFTWARE. #ifndef ETL_BIP_BUFFER_SPSC_ATOMIC_INCLUDED #define ETL_BIP_BUFFER_SPSC_ATOMIC_INCLUDED -#include -#include - #include "platform.h" #include "alignment.h" #include "parameter_type.h" @@ -53,6 +50,9 @@ SOFTWARE. #include "span.h" #include "file_error_numbers.h" +#include +#include + #if ETL_HAS_ATOMIC namespace etl diff --git a/src/etl/bit.h b/src/etl/bit.h index 602b914..eb7d581 100644 --- a/src/etl/bit.h +++ b/src/etl/bit.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_BIT_INCLUDED #define ETL_BIT_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "binary.h" @@ -40,6 +38,8 @@ SOFTWARE. #include "endianness.h" #include "type_traits.h" +#include + #if ETL_USING_CPP20 && ETL_USING_STL #include #endif @@ -47,13 +47,14 @@ SOFTWARE. namespace etl { //*************************************************************************** - /// bit_cast + /// bit_cast - Type to different type. //*************************************************************************** template - ETL_CONSTEXPR14 - typename etl::enable_if<(sizeof(TDestination) == sizeof(TSource)) && - etl::is_trivially_copyable::value && - etl::is_trivially_copyable::value, TDestination>::type + ETL_NODISCARD + typename etl::enable_if::value&& etl::is_integral::value) && + (sizeof(TDestination) == sizeof(TSource)) && + etl::is_trivially_copyable::value && + etl::is_trivially_copyable::value, TDestination>::type bit_cast(const TSource& source) ETL_NOEXCEPT { TDestination destination; @@ -63,6 +64,19 @@ namespace etl return destination; } + //*************************************************************************** + /// bit_cast - Integral to integral + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if<(etl::is_integral::value && etl::is_integral::value) && + (sizeof(TDestination) == sizeof(TSource)), TDestination>::type + bit_cast(const TSource& source) ETL_NOEXCEPT + { + return static_cast(source); + } + //*************************************************************************** /// byteswap //*************************************************************************** diff --git a/src/etl/bit_stream.h b/src/etl/bit_stream.h index 8b43b3a..5135cab 100644 --- a/src/etl/bit_stream.h +++ b/src/etl/bit_stream.h @@ -26,9 +26,6 @@ SOFTWARE. #ifndef ETL_BIT_STREAM_INCLUDED #define ETL_BIT_STREAM_INCLUDED -#include -#include - #include "platform.h" #include "type_traits.h" #include "nullptr.h" @@ -44,6 +41,9 @@ SOFTWARE. #include "exception.h" #include "error_handler.h" +#include +#include + #include "private/minmax_push.h" namespace etl diff --git a/src/etl/bitset.h b/src/etl/bitset.h index 731fffc..d827c76 100644 --- a/src/etl/bitset.h +++ b/src/etl/bitset.h @@ -31,1308 +31,12 @@ SOFTWARE. #ifndef ETL_BITSET_INCLUDED #define ETL_BITSET_INCLUDED -#include -#include -#include - #include "platform.h" -#include "algorithm.h" -#include "iterator.h" - -#include "integral_limits.h" -#include "algorithm.h" -#include "nullptr.h" -#include "log.h" -#include "exception.h" -#include "integral_limits.h" -#include "binary.h" -#include "char_traits.h" -#include "static_assert.h" -#include "error_handler.h" -#include "span.h" -#include "string.h" - -#include "private/minmax_push.h" - -#if defined(ETL_COMPILER_KEIL) -#pragma diag_suppress 1300 -#endif - -#if ETL_USING_CPP11 - #define ETL_STR(x) x - #define ETL_STRL(x) L##x - #define ETL_STRu(x) u##x - #define ETL_STRU(x) U##x +#if defined(ETL_USE_LEGACY_BITSET) + #include "private/bitset_legacy.h" #else - #define ETL_STR(x) x - #define ETL_STRL(x) x - #define ETL_STRu(x) x - #define ETL_STRU(x) x + #include "private/bitset_new.h" #endif -//***************************************************************************** -///\defgroup bitset bitset -/// Similar to std::bitset but without requiring std::string. -///\ingroup containers -//***************************************************************************** - -namespace etl -{ - //*************************************************************************** - /// Exception base for bitset - ///\ingroup bitset - //*************************************************************************** - class bitset_exception : public etl::exception - { - public: - - bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset null pointer exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_nullptr : public bitset_exception - { - public: - - bitset_nullptr(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset type_too_small exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_type_too_small : public bitset_exception - { - public: - - bitset_type_too_small(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Bitset overflow exception. - ///\ingroup bitset - //*************************************************************************** - class bitset_overflow : public bitset_exception - { - public: - - bitset_overflow(string_type file_name_, numeric_type line_number_) - : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_) - { - } - }; - - //************************************************************************* - /// The base class for etl::bitset - ///\ingroup bitset - //************************************************************************* - class ibitset - { - protected: - - // The type used for each element in the array. -#if !defined(ETL_BITSET_ELEMENT_TYPE) - typedef uint_least8_t element_t; -#else - typedef ETL_BITSET_ELEMENT_TYPE element_t; -#endif - - public: - - static ETL_CONSTANT element_t ALL_SET = etl::integral_limits::max; - static ETL_CONSTANT element_t ALL_CLEAR = 0; - - static ETL_CONSTANT size_t BITS_PER_ELEMENT = etl::integral_limits::bits; - -#if ETL_USING_CPP11 - typedef etl::span span_type; - typedef etl::span const_span_type; -#endif - - enum - { - npos = etl::integral_limits::max - }; - - //************************************************************************* - /// The reference type returned. - //************************************************************************* - class bit_reference - { - public: - - friend class ibitset; - - //******************************* - /// Conversion operator. - //******************************* - operator bool() const - { - return p_bitset->test(position); - } - - //******************************* - /// Assignment operator. - //******************************* - bit_reference& operator = (bool b) - { - p_bitset->set(position, b); - return *this; - } - - //******************************* - /// Assignment operator. - //******************************* - bit_reference& operator = (const bit_reference& r) - { - p_bitset->set(position, bool(r)); - return *this; - } - - //******************************* - /// Flip the bit. - //******************************* - bit_reference& flip() - { - p_bitset->flip(position); - return *this; - } - - //******************************* - /// Return the logical inverse of the bit. - //******************************* - bool operator~() const - { - return !p_bitset->test(position); - } - - private: - - //******************************* - /// Default constructor. - //******************************* - bit_reference() - : p_bitset(ETL_NULLPTR), - position(0) - { - } - - //******************************* - /// Constructor. - //******************************* - bit_reference(ibitset& r_bitset, size_t position_) - : p_bitset(&r_bitset), - position(position_) - { - } - - ibitset* p_bitset; ///< The bitset. - size_t position; ///< The position in the bitset. - }; - - //************************************************************************* - /// The size of the bitset. - //************************************************************************* - size_t size() const - { - return NBITS; - } - - //************************************************************************* - /// Count the number of bits set. - //************************************************************************* - size_t count() const - { - size_t n = 0UL; - - for (size_t i = 0UL; i < SIZE; ++i) - { - n += etl::count_bits(pdata[i]); - } - - return n; - } - - //************************************************************************* - /// Tests a bit at a position. - /// Positions greater than the number of configured bits will return false. - //************************************************************************* - bool test(size_t position) const - { - size_t index; - element_t mask; - - if (SIZE == 0) - { - return false; - } - else if (SIZE == 1) - { - index = 0; - mask = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - mask = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); - } - - return (pdata[index] & mask) != 0; - } - - //************************************************************************* - /// Set the bit at the position. - //************************************************************************* - ibitset& set() - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] = ALL_SET; - } - - pdata[SIZE - 1] &= TOP_MASK; - - return *this; - } - - //************************************************************************* - /// Set the bit at the position. - //************************************************************************* - ibitset& set(size_t position, bool value = true) - { - size_t index; - element_t bit; - - if (SIZE == 0) { - return *this; - } - else if (SIZE == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); - } - - if (value) - { - pdata[index] |= bit; - } - else - { - pdata[index] &= ~bit; - } - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - ibitset& set(const char* text) - { - reset(); - - size_t i = etl::min(NBITS, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STR('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - ibitset& from_string(const char* text) - { - reset(); - - size_t i = etl::min(NBITS, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRL('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a wide string. - //************************************************************************* - ibitset& from_string(const wchar_t* text) - { - reset(); - - size_t i = etl::min(NBITS, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRL('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a u16 string. - //************************************************************************* - ibitset& from_string(const char16_t* text) - { - reset(); - - size_t i = etl::min(NBITS, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRu('1')); - } - - return *this; - } - - //************************************************************************* - /// Set from a u32 string. - //************************************************************************* - ibitset& from_string(const char32_t* text) - { - reset(); - - size_t i = etl::min(NBITS, etl::strlen(text)); - - while (i > 0) - { - set(--i, *text++ == ETL_STRU('1')); - } - - return *this; - } - - //************************************************************************* - /// Put to a value. - //************************************************************************* - template - typename etl::enable_if::value, T>::type - value() const - { - for (size_t i = sizeof(long long) / sizeof(element_t); i < SIZE; ++i) - { - ETL_ASSERT_AND_RETURN_VALUE(!(pdata[i]), ETL_ERROR(etl::bitset_overflow), T(0)); - } - - T v = T(0); - - const bool OK = (sizeof(T) * CHAR_BIT) >= (SIZE * BITS_PER_ELEMENT); - - ETL_ASSERT(OK, ETL_ERROR(etl::bitset_type_too_small)); - - if (OK) - { - uint_least8_t shift = 0U; - - for (size_t i = 0UL; i < SIZE; ++i) - { - v |= T(typename etl::make_unsigned::type(pdata[i]) << shift); - shift += uint_least8_t(BITS_PER_ELEMENT); - } - } - - return v; - } - - //************************************************************************* - /// Put to a unsigned long. - //************************************************************************* - unsigned long to_ulong() const - { - return value(); - } - - //************************************************************************* - /// Put to a unsigned long long. - //************************************************************************* - unsigned long long to_ullong() const - { - return value(); - } - - //************************************************************************* - /// Resets the bitset. - //************************************************************************* - ibitset& reset() - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] = ALL_CLEAR; - } - - return *this; - } - - //************************************************************************* - /// Reset the bit at the position. - //************************************************************************* - ibitset& reset(size_t position) - { - size_t index; - element_t bit; - - if (SIZE == 0) - { - return *this; - } - else if (SIZE == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> etl::log2::value; - bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); - } - - pdata[index] &= ~bit; - - return *this; - } - - //************************************************************************* - /// Flip all of the bits. - //************************************************************************* - ibitset& flip() - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] = ~pdata[i]; - } - - pdata[SIZE - 1] &= TOP_MASK; - - return *this; - } - - //************************************************************************* - /// Flip the bit at the position. - //************************************************************************* - ibitset& flip(size_t position) - { - if (position < NBITS) - { - size_t index; - element_t bit; - - if (SIZE == 0) - { - return *this; - } - else if (SIZE == 1) - { - index = 0; - bit = element_t(1) << position; - } - else - { - index = position >> log2::value; - bit = element_t(1) << (position & (BITS_PER_ELEMENT - 1)); - } - - pdata[index] ^= bit; - } - - return *this; - } - - //************************************************************************* - // Are all the bits sets? - //************************************************************************* - bool all() const - { - if (SIZE == 0UL) - { - return true; - } - - // All but the last. - for (size_t i = 0UL; i < (SIZE - 1); ++i) - { - if (pdata[i] != ALL_SET) - { - return false; - } - } - - // The last. - if (pdata[SIZE - 1] != (ALL_SET & TOP_MASK)) - { - return false; - } - - return true; - } - - //************************************************************************* - /// Are any of the bits set? - //************************************************************************* - bool any() const - { - return !none(); - } - - //************************************************************************* - /// Are none of the bits set? - //************************************************************************* - bool none() const - { - for (size_t i = 0UL; i < SIZE; ++i) - { - if (pdata[i] != 0) - { - return false; - } - } - - return true; - } - - //************************************************************************* - /// Finds the first bit in the specified state. - ///\param state The state to search for. - ///\returns The position of the bit or SIZE if none were found. - //************************************************************************* - size_t find_first(bool state) const - { - return find_next(state, 0); - } - - //************************************************************************* - /// Finds the next bit in the specified state. - ///\param state The state to search for. - ///\param position The position to start from. - ///\returns The position of the bit or SIZE if none were found. - //************************************************************************* - size_t find_next(bool state, size_t position) const - { - // Where to start. - size_t index; - size_t bit; - - if (SIZE == 0) - { - return ibitset::npos; - } - else if (SIZE == 1) - { - index = 0; - bit = position; - } - else - { - index = position >> log2::value; - bit = position & (BITS_PER_ELEMENT - 1); - } - - element_t mask = 1 << bit; - - // For each element in the bitset... - while (index < SIZE) - { - element_t value = pdata[index]; - - // Needs checking? - if ((state && (value != ALL_CLEAR)) || - (!state && (value != ALL_SET))) - { - // For each bit in the element... - while ((bit < BITS_PER_ELEMENT) && (position < NBITS)) - { - // Equal to the required state? - if (((value & mask) != 0) == state) - { - return position; - } - - // Move on to the next bit. - mask <<= 1; - ++position; - ++bit; - } - } - else - { - position += (BITS_PER_ELEMENT - bit); - } - - // Start at the beginning for all other elements. - bit = 0; - mask = 1; - - ++index; - } - - return ibitset::npos; - } - - //************************************************************************* - /// Read [] operator. - //************************************************************************* - bool operator[] (size_t position) const - { - return test(position); - } - - //************************************************************************* - /// Write [] operator. - //************************************************************************* - bit_reference operator [] (size_t position) - { - return bit_reference(*this, position); - } - - //************************************************************************* - /// operator &= - //************************************************************************* - ibitset& operator &=(const ibitset& other) - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] &= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator |= - //************************************************************************* - ibitset& operator |=(const ibitset& other) - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] |= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator ^= - //************************************************************************* - ibitset& operator ^=(const ibitset& other) - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] ^= other.pdata[i]; - } - - return *this; - } - - //************************************************************************* - /// operator <<= - //************************************************************************* - ibitset& operator<<=(size_t shift) - { - if (SIZE != 0UL) - { - // Just one element? - if (SIZE == 1UL) - { - pdata[0] <<= shift; - } - else if (shift == BITS_PER_ELEMENT) - { - for (size_t i = (SIZE - 1); i > 0U; --i) - { - pdata[i] = pdata[i - 1]; - } - - pdata[0] = 0; - } - else - { - // TODO Optimise. - size_t source = NBITS - shift - 1; - size_t destination = NBITS - 1; - - for (size_t i = 0UL; i < (NBITS - shift); ++i) - { - set(destination--, test(source--)); - } - - for (size_t i = 0UL; i < shift; ++i) - { - reset(destination--); - } - } - } - - return *this; - } - - //************************************************************************* - /// operator >>= - //************************************************************************* - ibitset& operator>>=(size_t shift) - { - if (SIZE != 0UL) - { - // Just one element? - if (SIZE == 1UL) - { - pdata[0] >>= shift; - } - // Shift is the size of an element? - else if (shift == BITS_PER_ELEMENT) - { - for (size_t i = 0UL; i < (SIZE - 1); ++i) - { - pdata[i] = pdata[i + 1]; - } - - pdata[SIZE - 1] = 0; - } - else - { - // TODO Optimise. - size_t source = shift; - size_t destination = 0UL; - - for (size_t i = 0UL; i < (NBITS - shift); ++i) - { - set(destination++, test(source++)); - } - - for (size_t i = 0UL; i < shift; ++i) - { - reset(destination++); - } - } - } - - return *this; - } - - //************************************************************************* - /// operator = - //************************************************************************* - ibitset& operator =(const ibitset& other) - { - if (this != &other) - { - etl::copy_n(other.pdata, SIZE, pdata); - } - - return *this; - } - - //************************************************************************* - /// swap - //************************************************************************* - void swap(ibitset& other) - { - etl::swap_ranges(pdata, pdata + SIZE, other.pdata); - } - -#if ETL_USING_CPP11 - //************************************************************************* - /// span - /// Returns a span of the underlying data. - //************************************************************************* - span_type span() - { - return span_type(pdata, pdata + SIZE); - } - - //************************************************************************* - /// span - /// Returns a const span of the underlying data. - //************************************************************************* - const_span_type span() const - { - return const_span_type(pdata, pdata + SIZE); - } -#endif - - protected: - - //************************************************************************* - /// Initialise from an unsigned long long. - //************************************************************************* - ibitset& initialise(unsigned long long value) - { - reset(); - - const size_t SHIFT = (integral_limits::bits <= (int)BITS_PER_ELEMENT) ? 0 : BITS_PER_ELEMENT; - - // Can we do it in one hit? - if (SHIFT == 0) - { - pdata[0] = element_t(value); - } - else - { - size_t i = 0UL; - - while ((value != 0) && (i < SIZE)) - { - pdata[i++] = value & ALL_SET; - value = value >> SHIFT; - } - } - - pdata[SIZE - 1] &= TOP_MASK; - - return *this; - } - - //************************************************************************* - /// Invert - //************************************************************************* - void invert() - { - for (size_t i = 0UL; i < SIZE; ++i) - { - pdata[i] = ~pdata[i]; - } - - pdata[SIZE - 1] &= TOP_MASK; - } - - //************************************************************************* - /// Gets a reference to the specified bit. - //************************************************************************* - bit_reference get_bit_reference(size_t position) - { - return bit_reference(*this, position); - } - - //************************************************************************* - /// Constructor. - //************************************************************************* - ibitset(size_t nbits_, size_t size_, element_t* pdata_) - : NBITS(nbits_), - SIZE(size_), - pdata(pdata_) - { - size_t allocated_bits = SIZE * BITS_PER_ELEMENT; - size_t top_mask_shift = ((BITS_PER_ELEMENT - (allocated_bits - NBITS)) % BITS_PER_ELEMENT); - TOP_MASK = element_t(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); - } - - //************************************************************************* - /// Compare bitsets. - //************************************************************************* - static bool is_equal(const ibitset& lhs, const ibitset&rhs) - { - return etl::equal(lhs.pdata, lhs.pdata + lhs.SIZE, rhs.pdata); - } - - element_t TOP_MASK; - - private: - - // Disable copy construction. - ibitset(const ibitset&); - - const size_t NBITS; - const size_t SIZE; - element_t* pdata; - - //************************************************************************* - /// Destructor. - //************************************************************************* -#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS) - public: - virtual ~ibitset() - { - } -#else - protected: - ~ibitset() - { - } -#endif - }; - - //************************************************************************* - /// The class emulates an array of bool elements, but optimized for space allocation. - /// Will accommodate any number of bits. - /// Does not use std::string. - ///\tparam MAXN The number of bits. - ///\ingroup bitset - //************************************************************************* - template - class bitset : public etl::ibitset - { - - static ETL_CONSTANT size_t ARRAY_SIZE = (MAXN % BITS_PER_ELEMENT == 0) ? MAXN / BITS_PER_ELEMENT : MAXN / BITS_PER_ELEMENT + 1; - - public: - - static ETL_CONSTANT size_t ALLOCATED_BITS = ARRAY_SIZE * BITS_PER_ELEMENT; - - public: - - //************************************************************************* - /// Default constructor. - //************************************************************************* - bitset() - : etl::ibitset(MAXN, ARRAY_SIZE, data) - { - reset(); - } - - //************************************************************************* - /// Copy constructor. - //************************************************************************* - bitset(const bitset& other) - : etl::ibitset(MAXN, ARRAY_SIZE, data) - { - etl::copy_n(other.data, ARRAY_SIZE, data); - } - - //************************************************************************* - /// Construct from a value. - //************************************************************************* - bitset(unsigned long long value) - : etl::ibitset(MAXN, ARRAY_SIZE, data) - { - initialise(value); - } - - //************************************************************************* - /// Construct from a string. - //************************************************************************* - bitset(const char* text) - : etl::ibitset(MAXN, ARRAY_SIZE, data) - { - set(text); - } - - //************************************************************************* - /// Set all of the bits. - //************************************************************************* - bitset& set() - { - etl::ibitset::set(); - return *this; - } - - //************************************************************************* - /// Set the bit at the position. - //************************************************************************* - bitset& set(size_t position, bool value = true) - { - etl::ibitset::set(position, value); - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& set(const char* text) - { - ETL_ASSERT(text != 0, ETL_ERROR(bitset_nullptr)); - etl::ibitset::set(text); - - return *this; - } - - //************************************************************************* - /// Set from a string. - //************************************************************************* - bitset& from_string(const char* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a wide string. - //************************************************************************* - bitset& from_string(const wchar_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u16 string. - //************************************************************************* - bitset& from_string(const char16_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Set from a u32 string. - //************************************************************************* - bitset& from_string(const char32_t* text) - { - ibitset::from_string(text); - - return *this; - } - - //************************************************************************* - /// Put to a value. - //************************************************************************* - template - typename etl::enable_if::value, T>::type - value() const - { - ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (ARRAY_SIZE * BITS_PER_ELEMENT), "Type too small"); - - return ibitset::value(); - } - - //************************************************************************* - /// Reset all of the bits. - //************************************************************************* - bitset& reset() - { - ibitset::reset(); - return *this; - } - - //************************************************************************* - /// Reset the bit at the position. - //************************************************************************* - bitset& reset(size_t position) - { - etl::ibitset::reset(position); - return *this; - } - - //************************************************************************* - /// Flip all of the bits. - //************************************************************************* - bitset& flip() - { - ibitset::flip(); - return *this; - } - - //************************************************************************* - /// Flip the bit at the position. - //************************************************************************* - bitset& flip(size_t position) - { - etl::ibitset::flip(position); - return *this; - } - - //************************************************************************* - /// Returns a string representing the bitset. - //************************************************************************* -#if ETL_USING_CPP11 - template > -#else - template -#endif - TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const - { - TString result; - - result.resize(MAXN, '\0'); - - ETL_ASSERT_AND_RETURN_VALUE((result.size() == MAXN), ETL_ERROR(etl::bitset_overflow), result); - - for (size_t i = MAXN; i > 0; --i) - { - result[MAXN - i] = test(i - 1) ? one : zero; - } - - return result; - } - - //************************************************************************* - /// operator = - //************************************************************************* - bitset& operator =(const bitset& other) - { - if (this != &other) - { - etl::copy_n(other.data, ARRAY_SIZE, data); - } - - return *this; - } - - //************************************************************************* - /// operator &= - //************************************************************************* - bitset& operator &=(const bitset& other) - { - etl::ibitset::operator &=(other); - return *this; - } - - //************************************************************************* - /// operator |= - //************************************************************************* - bitset& operator |=(const bitset& other) - { - etl::ibitset::operator |=(other); - return *this; - } - - //************************************************************************* - /// operator ^= - //************************************************************************* - bitset& operator ^=(const bitset& other) - { - ibitset::operator ^=(other); - return *this; - } - - //************************************************************************* - /// operator ~ - //************************************************************************* - bitset operator ~() const - { - etl::bitset temp(*this); - - temp.invert(); - - return temp; - } - - //************************************************************************* - /// operator << - //************************************************************************* - bitset operator<<(size_t shift) const - { - etl::bitset temp(*this); - - temp <<= shift; - - return temp; - } - - //************************************************************************* - /// operator <<= - //************************************************************************* - bitset& operator<<=(size_t shift) - { - etl::ibitset::operator <<=(shift); - return *this; - } - - //************************************************************************* - /// operator >> - //************************************************************************* - bitset operator>>(size_t shift) const - { - bitset temp(*this); - - temp >>= shift; - - return temp; - } - - //************************************************************************* - /// operator >>= - //************************************************************************* - bitset& operator>>=(size_t shift) - { - etl::ibitset::operator >>=(shift); - return *this; - } - - //************************************************************************* - /// operator == - //************************************************************************* - friend bool operator == (const bitset& lhs, const bitset& rhs) - { - return etl::ibitset::is_equal(lhs, rhs); - } - - private: - - element_t data[ARRAY_SIZE > 0U ? ARRAY_SIZE : 1U]; - }; - - //*************************************************************************** - /// operator & - ///\ingroup bitset - //*************************************************************************** - template - bitset operator & (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp &= rhs; - return temp; - } - - //*************************************************************************** - /// operator | - ///\ingroup bitset - //*************************************************************************** - template - bitset operator | (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp |= rhs; - return temp; - } - - //*************************************************************************** - /// operator ^ - ///\ingroup bitset - //*************************************************************************** - template - bitset operator ^ (const bitset& lhs, const bitset& rhs) - { - bitset temp(lhs); - temp ^= rhs; - return temp; - } - - //*************************************************************************** - /// operator != - ///\ingroup bitset - //*************************************************************************** - template - bool operator != (const bitset& lhs, const bitset& rhs) - { - return !(lhs == rhs); - } -} - -//************************************************************************* -/// swap -//************************************************************************* -template -void swap(etl::bitset& lhs, etl::bitset& rhs) -{ - lhs.swap(rhs); -} - -#include "private/minmax_pop.h" - #endif diff --git a/src/etl/bresenham_line.h b/src/etl/bresenham_line.h index 89452a7..a519ea3 100644 --- a/src/etl/bresenham_line.h +++ b/src/etl/bresenham_line.h @@ -31,14 +31,14 @@ SOFTWARE. #ifndef ETL_BRESENHAM_LINE_INCLUDED #define ETL_BRESENHAM_LINE_INCLUDED -#include - #include "platform.h" #include "iterator.h" #include "static_assert.h" #include "type_traits.h" #include "utility.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/byte_stream.h b/src/etl/byte_stream.h index 4aca966..934a8a4 100644 --- a/src/etl/byte_stream.h +++ b/src/etl/byte_stream.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_BYTE_STREAM_INCLUDED #define ETL_BYTE_STREAM_INCLUDED -#include -#include - #include "platform.h" #include "type_traits.h" #include "nullptr.h" @@ -49,6 +46,9 @@ SOFTWARE. #include "exception.h" #include "error_handler.h" +#include +#include + namespace etl { //*************************************************************************** @@ -216,7 +216,7 @@ namespace etl typename etl::enable_if::value || etl::is_floating_point::value, void>::type write_unchecked(const etl::span& range) { - typename etl::span::const_iterator itr = range.begin(); + typename etl::span::iterator itr = range.begin(); while (itr != range.end()) { diff --git a/src/etl/callback_timer.h b/src/etl/callback_timer.h index 3d524c5..12acb1f 100644 --- a/src/etl/callback_timer.h +++ b/src/etl/callback_timer.h @@ -29,8 +29,6 @@ SOFTWARE. #ifndef ETL_CALLBACK_TIMER_INCLUDED #define ETL_CALLBACK_TIMER_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "nullptr.h" @@ -42,6 +40,8 @@ SOFTWARE. #include "placement_new.h" #include "delegate.h" +#include + #if defined(ETL_IN_UNIT_TEST) && ETL_NOT_USING_STL #define ETL_DISABLE_TIMER_UPDATES #define ETL_ENABLE_TIMER_UPDATES diff --git a/src/etl/callback_timer_atomic.h b/src/etl/callback_timer_atomic.h index ff2d861..650d8ae 100644 --- a/src/etl/callback_timer_atomic.h +++ b/src/etl/callback_timer_atomic.h @@ -29,10 +29,7 @@ SOFTWARE. #ifndef ETL_CALLBACK_TIMER_ATOMIC_INCLUDED #define ETL_CALLBACK_TIMER_ATOMIC_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "nullptr.h" #include "function.h" @@ -42,6 +39,8 @@ SOFTWARE. #include "placement_new.h" #include "delegate.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/callback_timer_interrupt.h b/src/etl/callback_timer_interrupt.h index 8a97024..02ebd93 100644 --- a/src/etl/callback_timer_interrupt.h +++ b/src/etl/callback_timer_interrupt.h @@ -29,10 +29,7 @@ SOFTWARE. #ifndef ETL_CALLBACK_TIMER_INTERRUPT_INCLUDED #define ETL_CALLBACK_TIMER_INTERRUPT_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "nullptr.h" #include "delegate.h" @@ -41,6 +38,8 @@ SOFTWARE. #include "error_handler.h" #include "placement_new.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/callback_timer_locked.h b/src/etl/callback_timer_locked.h index fb4f380..ad6eacd 100644 --- a/src/etl/callback_timer_locked.h +++ b/src/etl/callback_timer_locked.h @@ -29,10 +29,7 @@ SOFTWARE. #ifndef ETL_CALLBACK_TIMER_LOCKED_INCLUDED #define ETL_CALLBACK_TIMER_LOCKED_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "nullptr.h" #include "delegate.h" @@ -41,6 +38,8 @@ SOFTWARE. #include "error_handler.h" #include "placement_new.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/char_traits.h b/src/etl/char_traits.h index 718b542..da3ed88 100644 --- a/src/etl/char_traits.h +++ b/src/etl/char_traits.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_CHAR_TRAITS_INCLUDED #define ETL_CHAR_TRAITS_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" +#include + //***************************************************************************** ///\defgroup char_traits char_traits /// Character traits @@ -123,6 +123,22 @@ namespace etl return count; } + //************************************************************************* + ETL_CONSTEXPR14 static size_t length(const char_type* str, size_t max_length) + { + size_t count = 0UL; + + if (str != 0) + { + while ((count < max_length) && (*str++ != 0)) + { + ++count; + } + } + + return count; + } + //************************************************************************* static void assign(char_type& r, const char_type& c) { @@ -130,7 +146,7 @@ namespace etl } //************************************************************************* - static char_type* assign(char_type* p, size_t n, char_type c) + static ETL_CONSTEXPR char_type* assign(char_type* p, size_t n, char_type c) { if (p != 0) { @@ -141,32 +157,32 @@ namespace etl } //************************************************************************* - static char_type* move(char_type* dest, const char_type* src, size_t count) + static ETL_CONSTEXPR char_type* move(char_type* dst, const char_type* src, size_t count) { - if ((dest < src) || (dest > (src + count))) + if ((dst < src) || (dst > (src + count))) { - etl::copy_n(src, src + count, dest); + etl::copy_n(src, count, dst); } else { - etl::copy_n(ETL_OR_STD::reverse_iterator(src + count), + etl::copy_n(ETL_OR_STD::reverse_iterator(src + count), count, - ETL_OR_STD::reverse_iterator(dest + count)); + ETL_OR_STD::reverse_iterator(dst + count)); } - return dest; + return dst; } //************************************************************************* - static char_type* copy(char_type* dest, const char_type* src, size_t count) + static ETL_CONSTEXPR char_type* copy(char_type* dst, const char_type* src, size_t count) { - etl::copy_n(src, src + count, dest); + etl::copy_n(src, count, dst); - return dest; + return dst; } //************************************************************************* - static int compare(const char_type* s1, const char_type* s2, size_t count) + static ETL_CONSTEXPR14 int compare(const char_type* s1, const char_type* s2, size_t count) { for (size_t i = 0UL; i < count; ++i) { @@ -187,7 +203,7 @@ namespace etl } //************************************************************************* - static const char_type* find(const char_type* p, size_t count, const char_type& ch) + static ETL_CONSTEXPR14 const char_type* find(const char_type* p, size_t count, const char_type& ch) { for (size_t i = 0UL; i < count; ++i) { @@ -203,45 +219,53 @@ namespace etl } //************************************************************************* - static char_type to_char_type(int_type c) + static ETL_CONSTEXPR char_type to_char_type(int_type c) { return static_cast(c); } //************************************************************************* - static int_type to_int_type(char_type c) + static ETL_CONSTEXPR int_type to_int_type(char_type c) { return static_cast(c); } //************************************************************************* - static bool eq_int_type(int_type c1, int_type c2) + static ETL_CONSTEXPR bool eq_int_type(int_type c1, int_type c2) { return (c1 == c2); } //************************************************************************* - static int_type eof() + static ETL_CONSTEXPR int_type eof() { return -1; } //************************************************************************* - static int_type not_eof(int_type e) + static ETL_CONSTEXPR int_type not_eof(int_type e) { return (e == eof()) ? eof() - 1 : e; } }; - //*************************************************************************** /// Alternative strlen for all character types. //*************************************************************************** template - size_t strlen(const T* t) + ETL_CONSTEXPR size_t strlen(const T* t) { return etl::char_traits::length(t); } + + //*************************************************************************** + /// Alternative strlen for all character types, with maximum length. + //*************************************************************************** + template + size_t strlen(const T* t, size_t max_length) + { + return etl::char_traits::length(t, max_length); + } } #endif diff --git a/src/etl/checksum.h b/src/etl/checksum.h index 3f0fa3e..4cb8339 100644 --- a/src/etl/checksum.h +++ b/src/etl/checksum.h @@ -27,12 +27,12 @@ SOFTWARE. #ifndef ETL_CHECKSUM_INCLUDED #define ETL_CHECKSUM_INCLUDED -#include - #include "platform.h" #include "binary.h" #include "frame_check_sequence.h" +#include + ///\defgroup checksum Checksum calculation ///\ingroup maths diff --git a/src/etl/circular_buffer.h b/src/etl/circular_buffer.h index 0320b44..cdff83b 100644 --- a/src/etl/circular_buffer.h +++ b/src/etl/circular_buffer.h @@ -1235,7 +1235,7 @@ namespace etl #endif //************************************************************************* - /// Copy Constructor. + /// Construct a copy. //************************************************************************* circular_buffer_ext(const circular_buffer_ext& other, void* buffer, size_t max_size) : icircular_buffer(reinterpret_cast(buffer), max_size) @@ -1246,6 +1246,11 @@ namespace etl } } + //************************************************************************* + /// Copy Constructor (Deleted) + //************************************************************************* + circular_buffer_ext(const circular_buffer_ext& other) ETL_DELETE; + //************************************************************************* /// Assignment operator //************************************************************************* diff --git a/src/etl/circular_iterator.h b/src/etl/circular_iterator.h new file mode 100644 index 0000000..63e43da --- /dev/null +++ b/src/etl/circular_iterator.h @@ -0,0 +1,753 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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_CIRCULAR_ITERATOR_INCLUDED +#define ETL_CIRCULAR_ITERATOR_INCLUDED + +#include "platform.h" +#include "iterator.h" +#include "static_assert.h" + +///\defgroup iterator Iterator types + +namespace etl +{ + namespace private_circular_iterator + { + //*************************************************************************** + /// Common circular iterator implementation. + //*************************************************************************** + template + class circular_iterator_common + : public etl::iterator::iterator_category, typename etl::iterator_traits::value_type> + { + public: + + typedef typename etl::iterator_traits::value_type value_type; + typedef typename etl::iterator_traits::difference_type difference_type; + typedef typename etl::iterator_traits::pointer pointer; + typedef typename etl::iterator_traits::reference reference; + typedef typename etl::iterator_traits::iterator_category iterator_category; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_common() + : itr_begin(TIterator()) + , itr_end(TIterator()) + , itr(TIterator()) + { + } + + //*************************************************************************** + /// Construct from iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_common(TIterator itr_begin_, TIterator itr_end_, TIterator start_) + : itr_begin(itr_begin_) + , itr_end(itr_end_) + , itr(start_) + { + } + + //*************************************************************************** + /// Copy constructor + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_common(const circular_iterator_common& other) + : itr_begin(other.itr_begin) + , itr_end(other.itr_end) + , itr(other.itr) + { + } + + //*************************************************************************** + /// Assignment + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_common& operator =(const circular_iterator_common& other) + { + itr_begin = other.itr_begin; + itr_end = other.itr_end; + itr = other.itr; + + return *this; + } + + //*************************************************************************** + /// Beginning of the range. + //*************************************************************************** + ETL_CONSTEXPR14 TIterator begin() const + { + return itr_begin; + } + + //*************************************************************************** + /// End of the range. + //*************************************************************************** + ETL_CONSTEXPR14 TIterator end() const + { + return itr_end; + } + + //*************************************************************************** + /// How long is the range? + //*************************************************************************** + ETL_CONSTEXPR14 size_t size() const + { + return etl::distance(itr_begin, itr_end); + } + + //*************************************************************************** + /// Is there nothing to iterate over? + //*************************************************************************** + ETL_CONSTEXPR14 bool empty() const + { + return (itr_begin == itr_end); + } + + //*************************************************************************** + /// Dereference operator. + //*************************************************************************** + ETL_CONSTEXPR14 value_type operator *() + { + return *itr; + } + + //*************************************************************************** + /// Dereference operator. + //*************************************************************************** + ETL_CONSTEXPR14 const value_type operator *() const + { + return *itr; + } + + //*************************************************************************** + /// -> operator. + //*************************************************************************** + ETL_CONSTEXPR14 TIterator operator ->() + { + return itr; + } + + //*************************************************************************** + /// -> operator. + //*************************************************************************** + ETL_CONSTEXPR14 const TIterator operator ->() const + { + return itr; + } + + //*************************************************************************** + /// Conversion operator. + //*************************************************************************** + ETL_CONSTEXPR14 operator TIterator() const + { + return itr; + } + + //*************************************************************************** + /// Conversion to base iterator type. + //*************************************************************************** + ETL_CONSTEXPR14 TIterator current() const + { + return itr; + } + + protected: + + TIterator itr_begin; ///< The underlying begin iterator. + TIterator itr_end; ///< The underlying end iterator. + TIterator itr; ///< The underlying iterator. + }; + + //*************************************************************************** + /// A circular iterator class. + /// This iterator can be given a pair of iterator values, which will loop if the start or end of the range is reached. + ///\ingroup iterator + //*************************************************************************** + template ::iterator_category> + class circular_iterator_impl + { + ETL_STATIC_ASSERT((etl::is_same::value_type), "input_iterator_catagory is not supported by circular_iterator"); + ETL_STATIC_ASSERT((etl::is_same::value_type), "output_iterator_catagory is not supported by circular_iterator"); + }; + + //*************************************************************************** + /// A circular iterator class. + /// Specialisation for forward iterators. + ///\ingroup iterator + /// //*************************************************************************** + template + class circular_iterator_impl + : public circular_iterator_common + { + private: + + typedef circular_iterator_common common_t; + + public: + + using common_t::operator=; + + typedef typename common_t::value_type value_type; + typedef typename common_t::difference_type difference_type; + typedef typename common_t::pointer pointer; + typedef typename common_t::reference reference; + typedef typename common_t::iterator_category iterator_category; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl() + : common_t() + { + } + + //*************************************************************************** + /// Construct from iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_) + : common_t(itr_begin_, itr_end_, itr_begin_) + { + } + + //*************************************************************************** + /// Construct from start + iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_) + : common_t(itr_begin_, itr_end_, start_) + { + } + + //*************************************************************************** + /// Copy constructor + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other) + : common_t(other) + { + } + + //*************************************************************************** + /// Assignment + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other) + { + common_t::operator=(other); + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator ++() + { + if (++this->itr == this->itr_end) + { + this->itr = this->itr_begin; + } + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl operator ++(int) + { + circular_iterator_impl original(*this); + + ++(*this); + + return (original); + } + }; + + //*************************************************************************** + /// A circular iterator class. + /// Specialisation for random access iterators. + ///\ingroup iterator + /// //*************************************************************************** + template + class circular_iterator_impl + : public circular_iterator_common + { + private: + + typedef circular_iterator_common common_t; + + public: + + using common_t::operator=; + + typedef typename common_t::value_type value_type; + typedef typename common_t::difference_type difference_type; + typedef typename common_t::pointer pointer; + typedef typename common_t::reference reference; + typedef typename common_t::iterator_category iterator_category; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl() + : common_t() + { + } + + //*************************************************************************** + /// Construct from iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_) + : common_t(itr_begin_, itr_end_, itr_begin_) + { + } + + //*************************************************************************** + /// Construct from start + iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_) + : common_t(itr_begin_, itr_end_, start_) + { + } + + //*************************************************************************** + /// Copy constructor + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other) + : common_t(other) + { + } + + //*************************************************************************** + /// Assignment + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other) + { + common_t::operator=(other); + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator ++() + { + if (++this->itr == this->itr_end) + { + this->itr = this->itr_begin; + } + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl operator ++(int) + { + circular_iterator_impl original(*this); + + ++(*this); + + return (original); + } + + //*************************************************************************** + /// Decrement. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator --() + { + if (this->itr == this->itr_begin) + { + typename etl::reverse_iterator ritr(this->itr_end); + ++ritr; + this->itr = ritr.base(); + } + else + { + --this->itr; + } + + return *this; + } + + //*************************************************************************** + /// Decrement. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl operator --(int) + { + circular_iterator_impl original(*this); + + --(*this); + + return (original); + } + }; + + //*************************************************************************** + /// A circular iterator class. + /// Specialisation for random access iterators. + ///\ingroup iterator + //*************************************************************************** + template + class circular_iterator_impl + : public etl::private_circular_iterator::circular_iterator_common + { + private: + + typedef etl::private_circular_iterator::circular_iterator_common common_t; + + public: + + using common_t::operator=; + + typedef typename common_t::value_type value_type; + typedef typename common_t::difference_type difference_type; + typedef typename common_t::pointer pointer; + typedef typename common_t::reference reference; + typedef typename common_t::iterator_category iterator_category; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl() + : common_t() + { + } + + //*************************************************************************** + /// Construct from iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_) + : common_t(itr_begin_, itr_end_, itr_begin_) + { + } + + //*************************************************************************** + /// Construct from start + iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(TIterator itr_begin_, TIterator itr_end_, TIterator start_) + : common_t(itr_begin_, itr_end_, start_) + { + } + + //*************************************************************************** + /// Copy constructor + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl(const circular_iterator_impl& other) + : common_t(other) + { + } + + //*************************************************************************** + /// Assignment + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator =(const circular_iterator_impl& other) + { + common_t::operator=(other); + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator ++() + { + if (++this->itr == this->itr_end) + { + this->itr = this->itr_begin; + } + + return *this; + } + + //*************************************************************************** + /// Increment. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl operator ++(int) + { + circular_iterator_impl original(*this); + + ++(*this); + + return (original); + } + + //*************************************************************************** + /// Decrement. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator --() + { + if (this->itr == this->itr_begin) + { + typename etl::reverse_iterator ritr(this->itr_end); + ++ritr; + this->itr = ritr.base(); + } + else + { + --this->itr; + } + + return *this; + } + + //*************************************************************************** + /// Decrement. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl operator --(int) + { + circular_iterator_impl original(*this); + + --(*this); + + return (original); + } + + //*************************************************************************** + /// += operator. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator +=(difference_type offset) + { + const difference_type length = difference_type(this->size()); + offset %= length; + + if (offset != 0) + { + const difference_type distance_from_begin = etl::distance(this->itr_begin, this->itr); + const difference_type distance_to_end = etl::distance(this->itr, this->itr_end); + + if (offset > 0) + { + if (distance_to_end > offset) + { + offset = distance_from_begin + offset; + } + else + { + offset = offset - distance_to_end; + } + } + else + { + offset = -offset; + + if (distance_from_begin >= offset) + { + offset = distance_from_begin - offset; + } + else + { + offset = offset - distance_from_begin; + offset = length - offset; + } + } + + this->itr = this->itr_begin + offset; + } + + return *this; + } + + //*************************************************************************** + /// -= operator. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator_impl& operator -=(typename etl::iterator_traits::difference_type offset) + { + return operator +=(-offset); + } + }; + } + + //*************************************************************************** + /// A circular iterator class. + /// This iterator can be given a pair of iterator values, which will loop if the start or end of the range is reached. + ///\ingroup iterator + //************************************************************************** + template + class circular_iterator ETL_FINAL + : public etl::private_circular_iterator::circular_iterator_impl::iterator_category> + { + private: + + typedef typename etl::private_circular_iterator::circular_iterator_impl::iterator_category> impl_t; + + public: + + using impl_t::operator=; + + typedef typename impl_t::value_type value_type; + typedef typename impl_t::difference_type difference_type; + typedef typename impl_t::pointer pointer; + typedef typename impl_t::reference reference; + typedef typename impl_t::iterator_category iterator_category; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator() + : impl_t() + { + } + + //*************************************************************************** + /// Construct from iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_) + : impl_t(itr_begin_, itr_end_, itr_begin_) + { + } + + //*************************************************************************** + /// Construct from start + iterators. + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator(TIterator itr_begin_, TIterator itr_end_, TIterator start_) + : impl_t(itr_begin_, itr_end_, start_) + { + } + + //*************************************************************************** + /// Copy constructor + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator(const circular_iterator& other) + : impl_t(other) + { + } + + //*************************************************************************** + /// Assignment + //*************************************************************************** + ETL_CONSTEXPR14 circular_iterator& operator =(const circular_iterator& other) + { + impl_t::operator=(other); + + return *this; + } + }; + + //***************************************************************************** + /// + addition operator. + //***************************************************************************** + template + ETL_CONSTEXPR14 etl::circular_iterator operator +(etl::circular_iterator& lhs, + typename etl::iterator_traits::difference_type offset) + { + etl::circular_iterator result(lhs); + result += offset; + + return result; + } + + //***************************************************************************** + /// - offset operator. + //***************************************************************************** + template + ETL_CONSTEXPR14 etl::circular_iterator operator -(etl::circular_iterator& lhs, + typename etl::iterator_traits::difference_type offset) + { + etl::circular_iterator result(lhs); + result -= offset; + + return result; + } + + //***************************************************************************** + /// - circular_iterator difference operator. + //***************************************************************************** + template + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type operator -(etl::circular_iterator& lhs, + etl::circular_iterator& rhs) + { + return TIterator(lhs) - TIterator(rhs); + } + + //***************************************************************************** + /// Equality operator. circular_iterator == circular_iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator ==(const etl::circular_iterator& lhs, + const etl::circular_iterator& rhs) + { + return TIterator(lhs) == TIterator(rhs); + } + + //***************************************************************************** + /// Equality operator. circular_iterator == iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator ==(const etl::circular_iterator& lhs, + TIterator rhs) + { + return TIterator(lhs) == rhs; + } + + //***************************************************************************** + /// Equality operator. iterator == circular_iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator ==(TIterator lhs, + const etl::circular_iterator& rhs) + { + return lhs == TIterator(rhs); + } + + + //***************************************************************************** + /// Inequality operator. circular_iterator == circular_iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator !=(const etl::circular_iterator& lhs, + const etl::circular_iterator& rhs) + { + return !(lhs == rhs); + } + + //***************************************************************************** + /// Inequality operator. circular_iterator == iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator !=(const etl::circular_iterator& lhs, + TIterator rhs) + { + return !(lhs == rhs); + } + + //***************************************************************************** + /// Inequality operator. iterator == circular_iterator. + //***************************************************************************** + template + ETL_CONSTEXPR14 bool operator !=(TIterator& lhs, + const etl::circular_iterator& rhs) + { + return !(lhs == rhs); + } +} + +#endif diff --git a/src/etl/container.h b/src/etl/container.h index f7e2145..f9200c9 100644 --- a/src/etl/container.h +++ b/src/etl/container.h @@ -31,10 +31,10 @@ SOFTWARE. #ifndef ETL_CONTAINER_INCLUDED #define ETL_CONTAINER_INCLUDED -#include - #include "platform.h" #include "iterator.h" +#include + #endif diff --git a/src/etl/cyclic_value.h b/src/etl/cyclic_value.h index 8f2b353..086ce9e 100644 --- a/src/etl/cyclic_value.h +++ b/src/etl/cyclic_value.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_CYCLIC_VALUE_INCLUDED #define ETL_CYCLIC_VALUE_INCLUDED -#include - ///\defgroup cyclic_value cyclic_value /// Provides a value that cycles between two limits. /// \ingroup utilities @@ -42,9 +40,10 @@ SOFTWARE. #include "exception.h" #include "static_assert.h" #include "type_traits.h" - #include "algorithm.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/debounce.h b/src/etl/debounce.h index 5fc461b..aad3ff4 100644 --- a/src/etl/debounce.h +++ b/src/etl/debounce.h @@ -31,11 +31,11 @@ SOFTWARE. #ifndef ETL_DEBOUNCE_INCLUDED #define ETL_DEBOUNCE_INCLUDED -#include - #include "platform.h" #include "static_assert.h" +#include + namespace etl { namespace private_debounce diff --git a/src/etl/debug_count.h b/src/etl/debug_count.h index 33ef568..2eeba53 100644 --- a/src/etl/debug_count.h +++ b/src/etl/debug_count.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_DEBUG_COUNT_INCLUDED #define ETL_DEBUG_COUNT_INCLUDED +#include "platform.h" +#include "atomic.h" + #include #include -#include "atomic.h" -#include "platform.h" - ///\defgroup debug_count debug count ///\ingroup utilities diff --git a/src/etl/deque.h b/src/etl/deque.h index 6f3f3ce..8a514e2 100644 --- a/src/etl/deque.h +++ b/src/etl/deque.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_DEQUE_INCLUDED #define ETL_DEQUE_INCLUDED -#include -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -48,6 +45,9 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include +#include + #include "private/minmax_push.h" //***************************************************************************** diff --git a/src/etl/endianness.h b/src/etl/endianness.h index 459df58..2c433f3 100644 --- a/src/etl/endianness.h +++ b/src/etl/endianness.h @@ -31,18 +31,18 @@ SOFTWARE. #ifndef ETL_ENDIAN_INCLUDED #define ETL_ENDIAN_INCLUDED -#include - #include "platform.h" #include "enum_type.h" #include "binary.h" +#include + #if ETL_USING_CPP20 && ETL_USING_STL #include #endif ///\defgroup endian endian -/// Constants & utilities for endianess +/// Constants & utilities for endianness ///\ingroup utilities // Have we not already defined ETL_ENDIAN_NATIVE? @@ -52,6 +52,15 @@ SOFTWARE. #define ETL_ENDIAN_LITTLE std::endian::little #define ETL_ENDIAN_BIG std::endian::big #define ETL_ENDIAN_NATIVE std::endian::native + // Is this the IAR compiler? + #elif defined(ETL_COMPILER_IAR) && defined(__LITTLE_ENDIAN__) + #define ETL_ENDIAN_LITTLE 0 + #define ETL_ENDIAN_BIG 1 + #if __LITTLE_ENDIAN__ == 1 + #define ETL_ENDIAN_NATIVE ETL_ENDIAN_LITTLE + #elif __LITTLE_ENDIAN__ == 0 + #define ETL_ENDIAN_NATIVE ETL_ENDIAN_BIG + #endif // If not can we use the compiler macros? #elif defined(__BYTE_ORDER__) // Test the two versions of the macro we are likely to see. diff --git a/src/etl/error_handler.h b/src/etl/error_handler.h index 5bedd4a..a904fd7 100644 --- a/src/etl/error_handler.h +++ b/src/etl/error_handler.h @@ -36,13 +36,13 @@ SOFTWARE. /// Error handler for when throwing exceptions is not required. ///\ingroup utilities -#include - #include "platform.h" #include "exception.h" #include "function.h" #include "nullptr.h" +#include + #if defined(ETL_LOG_ERRORS) || defined(ETL_IN_UNIT_TEST) namespace etl { @@ -325,9 +325,11 @@ namespace etl #endif #if defined(ETL_VERBOSE_ERRORS) - #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number. + #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number. + #define ETL_ERROR_WITH_VALUE(e, v) (e(__FILE__, __LINE__, (v))) // Make an exception with the file name, line number and value. #else - #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number. + #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number. + #define ETL_ERROR_WITH_VALUE(e, v) (e("", __LINE__, (v))) // Make an exception with the file name, line number and value. #endif #if defined(ETL_VERBOSE_ERRORS) diff --git a/src/etl/expected.h b/src/etl/expected.h new file mode 100644 index 0000000..9ca6d03 --- /dev/null +++ b/src/etl/expected.h @@ -0,0 +1,253 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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_EXPECTED_INCLUDED +#define ETL_EXPECTED_INCLUDED + +#include "platform.h" +#include "type_traits.h" +#include "utility.h" + +namespace etl +{ + //*************************************************************************** + /// Unexpected type. + /// etl::unexpected represents an unexpected value stored in etl::expected. + //*************************************************************************** + template + class unexpected + { + public: + + //******************************************* + /// Copy constructor. + //******************************************* + ETL_CONSTEXPR14 unexpected(const unexpected& other) + : error_value(other.error_value) + { + } + +#if ETL_USING_CPP11 + //******************************************* + /// Move constructor. + //******************************************* + ETL_CONSTEXPR unexpected(unexpected&& other) + : error_value(etl::move(other.error_value)) + { + } +#endif + +#if ETL_USING_CPP11 + //******************************************* + /// Construct from argument. + //******************************************* + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(TErr&& e) + : error_value(etl::forward(e)) + { + } +#else + //******************************************* + /// Construct from argument. + //******************************************* + template + explicit unexpected(const TErr& e, typename etl::enable_if::type, etl::unexpected >::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + : error_value(e) + { + } +#endif + +#if ETL_USING_CPP11 + //******************************************* + /// Construct from arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, Args&&... args) + : error_value(etl::forward(args)...) + { + } +#endif + +#if ETL_HAS_INITIALIZER_LIST + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, std::initializer_list init, Args&&... args) + : error_value(init, etl::forward(args)...) + { + } +#endif + + //******************************************* + /// Assign from etl::unexpected. + //******************************************* + ETL_CONSTEXPR14 + etl::unexpected& operator =(const etl::unexpected& rhs) + { + error_value = rhs.error_value; + + return *this; + } + +#if ETL_USING_CPP11 + //******************************************* + /// Move assign from etl::unexpected. + //******************************************* + ETL_CONSTEXPR14 + etl::unexpected& operator =(etl::unexpected&& rhs) + { + error_value = etl::move(rhs.error_value); + + return *this; + } +#endif + +#if ETL_USING_CPP11 + //******************************************* + /// Get the error. + //******************************************* + constexpr const TError& error() const& noexcept + { + return error_value; + } + + //******************************************* + /// Get the error. + //******************************************* + constexpr const TError&& error() const&& noexcept + { + return etl::move(error_value); + } + +#if ETL_USING_CPP14 + //******************************************* + /// Get the error. + //******************************************* + constexpr TError& error() & noexcept + { + return error_value; + } + + //******************************************* + /// Get the error. + //******************************************* + constexpr TError&& error() && noexcept + { + return etl::move(error_value); + } +#else + //******************************************* + /// Get the error. + //******************************************* + TError& error() & noexcept + { + return error_value; + } + + //******************************************* + /// Get the error. + //******************************************* + TError&& error() && noexcept + { + return etl::move(error_value); + } +#endif + +#else + //******************************************* + /// Get the error. + //******************************************* + const TError& error() const + { + return error_value; + } +#endif + + //******************************************* + /// Swap with another etl::unexpected. + //******************************************* + void swap(etl::unexpected& other) + { + using ETL_OR_STD::swap; + + swap(error_value, other.error_value); + } + + private: + + TError error_value; + }; + +#if ETL_USING_CPP17 + template + unexpected(TError) -> unexpected; +#endif +} + +//******************************************* +/// Equivalence operator. +//******************************************* +template +ETL_CONSTEXPR14 +bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) +{ + return lhs.error_value == rhs.error_value; +} + +//******************************************* +/// Swap etl::unexpected. +//******************************************* +template +ETL_CONSTEXPR14 +void swap(etl::unexpected& lhs, etl::unexpected& rhs) +{ + lhs.swap(rhs); +} + +//***************************************************************************** +/// unexpect_t +//***************************************************************************** +struct unexpect_t +{ + ETL_CONSTEXPR14 explicit unexpect_t() + { + } +}; + +#if ETL_CPP17_SUPPORTED +inline constexpr unexpect_t unexpect{}; +#else +static const unexpect_t unexpect; +#endif + +#endif diff --git a/src/etl/factorial.h b/src/etl/factorial.h index 9852c5c..43446aa 100644 --- a/src/etl/factorial.h +++ b/src/etl/factorial.h @@ -31,10 +31,10 @@ SOFTWARE. #ifndef ETL_FACTORIAL_INCLUDED #define ETL_FACTORIAL_INCLUDED -#include - #include "platform.h" +#include + ///\defgroup factorial factorial /// fibonacci : Calculates the Nth factorial value. ///\ingroup maths diff --git a/src/etl/fibonacci.h b/src/etl/fibonacci.h index 1a15974..9105f8a 100644 --- a/src/etl/fibonacci.h +++ b/src/etl/fibonacci.h @@ -31,10 +31,10 @@ SOFTWARE. #ifndef ETL_FIBONACCI_INCLUDED #define ETL_FIBONACCI_INCLUDED -#include - #include "platform.h" +#include + ///\defgroup fibonacci fibonacci /// fibonacci : Calculates the Nth Fibonacci value. ///\ingroup maths diff --git a/src/etl/file_error_numbers.h b/src/etl/file_error_numbers.h index 211c597..7d6a0e1 100644 --- a/src/etl/file_error_numbers.h +++ b/src/etl/file_error_numbers.h @@ -98,5 +98,7 @@ SOFTWARE. #define ETL_BIT_STREAM_FILE_ID "65" #define ETL_BYTE_STREAM_FILE_ID "66" #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" +#define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" +#define ETL_TO_ARITHMETIC_FILE_ID "69" #endif diff --git a/src/etl/fixed_iterator.h b/src/etl/fixed_iterator.h index d20d09d..74be085 100644 --- a/src/etl/fixed_iterator.h +++ b/src/etl/fixed_iterator.h @@ -34,8 +34,6 @@ SOFTWARE. #include "platform.h" #include "iterator.h" -#include "iterator.h" - ///\defgroup iterator Iterator types namespace etl @@ -208,8 +206,8 @@ namespace etl /// - fixed_iterator operator. //***************************************************************************** template - typename etl::iterator_traits::difference_type operator -(etl::fixed_iterator& lhs, - etl::fixed_iterator& rhs) + typename etl::iterator_traits::difference_type operator -(const etl::fixed_iterator& lhs, + const etl::fixed_iterator& rhs) { return TIterator(lhs) - TIterator(rhs); } @@ -219,7 +217,7 @@ namespace etl //***************************************************************************** template bool operator ==(const etl::fixed_iterator& lhs, - const etl::fixed_iterator& rhs) + const etl::fixed_iterator& rhs) { return TIterator(lhs) == TIterator(rhs); } @@ -229,7 +227,7 @@ namespace etl //***************************************************************************** template bool operator ==(const etl::fixed_iterator& lhs, - TIterator rhs) + TIterator rhs) { return TIterator(lhs) == rhs; } @@ -239,7 +237,7 @@ namespace etl //***************************************************************************** template bool operator ==(TIterator lhs, - const etl::fixed_iterator& rhs) + const etl::fixed_iterator& rhs) { return lhs == TIterator(rhs); } @@ -250,7 +248,7 @@ namespace etl //***************************************************************************** template bool operator !=(const etl::fixed_iterator& lhs, - const etl::fixed_iterator& rhs) + const etl::fixed_iterator& rhs) { return !(lhs == rhs); } @@ -260,7 +258,7 @@ namespace etl //***************************************************************************** template bool operator !=(const etl::fixed_iterator& lhs, - TIterator rhs) + TIterator rhs) { return !(lhs == rhs); } @@ -270,7 +268,7 @@ namespace etl //***************************************************************************** template bool operator !=(TIterator& lhs, - const etl::fixed_iterator& rhs) + const etl::fixed_iterator& rhs) { return !(lhs == rhs); } diff --git a/src/etl/flags.h b/src/etl/flags.h index 4d5b75d..5bdf2aa 100644 --- a/src/etl/flags.h +++ b/src/etl/flags.h @@ -31,10 +31,6 @@ SOFTWARE. #ifndef ETL_FLAGS_INCLUDED #define ETL_FLAGS_INCLUDED -#include -#include -#include - #include "platform.h" #include "algorithm.h" #include "type_traits.h" @@ -42,6 +38,10 @@ SOFTWARE. #include "static_assert.h" #include "initializer_list.h" +#include +#include +#include + namespace etl { //************************************************************************* diff --git a/src/etl/fnv_1.h b/src/etl/fnv_1.h index 85cc1dc..f64c106 100644 --- a/src/etl/fnv_1.h +++ b/src/etl/fnv_1.h @@ -31,14 +31,13 @@ SOFTWARE. #ifndef ETL_FNV_1_INCLUDED #define ETL_FNV_1_INCLUDED -#include - #include "platform.h" #include "static_assert.h" #include "type_traits.h" #include "ihash.h" #include "frame_check_sequence.h" +#include #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 1300 diff --git a/src/etl/forward_list.h b/src/etl/forward_list.h index a4b077c..68337fc 100644 --- a/src/etl/forward_list.h +++ b/src/etl/forward_list.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_FORWARD_LIST_INCLUDED #define ETL_FORWARD_LIST_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -50,6 +48,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + #include "private/minmax_push.h" //***************************************************************************** diff --git a/src/etl/frame_check_sequence.h b/src/etl/frame_check_sequence.h index df85d00..dd63955 100644 --- a/src/etl/frame_check_sequence.h +++ b/src/etl/frame_check_sequence.h @@ -27,15 +27,14 @@ SOFTWARE. #ifndef ETL_FRAME_CHECK_SEQUENCE_INCLUDED #define ETL_FRAME_CHECK_SEQUENCE_INCLUDED -#include - #include "platform.h" #include "static_assert.h" #include "type_traits.h" #include "binary.h" - #include "iterator.h" +#include + ETL_STATIC_ASSERT(ETL_USING_8BIT_TYPES, "This file does not currently support targets with no 8bit type"); ///\defgroup frame_check_sequence Frame check sequence calculation diff --git a/src/etl/fsm.h b/src/etl/fsm.h index 1a2b435..b7f2f91 100644 --- a/src/etl/fsm.h +++ b/src/etl/fsm.h @@ -51,8 +51,6 @@ SOFTWARE. #ifndef ETL_FSM_INCLUDED #define ETL_FSM_INCLUDED -#include - #include "platform.h" #include "array.h" #include "nullptr.h" @@ -63,6 +61,8 @@ SOFTWARE. #include "integral_limits.h" #include "largest.h" +#include + #include "private/minmax_push.h" namespace etl diff --git a/src/etl/generators/fsm_generator.h b/src/etl/generators/fsm_generator.h index 685eefb..a510de9 100644 --- a/src/etl/generators/fsm_generator.h +++ b/src/etl/generators/fsm_generator.h @@ -63,8 +63,6 @@ cog.outl("//******************************************************************** #ifndef ETL_FSM_INCLUDED #define ETL_FSM_INCLUDED -#include - #include "platform.h" #include "array.h" #include "nullptr.h" @@ -75,6 +73,8 @@ cog.outl("//******************************************************************** #include "integral_limits.h" #include "largest.h" +#include + #include "private/minmax_push.h" namespace etl diff --git a/src/etl/generators/message_packet_generator.h b/src/etl/generators/message_packet_generator.h index d02c58c..afc9e0d 100644 --- a/src/etl/generators/message_packet_generator.h +++ b/src/etl/generators/message_packet_generator.h @@ -96,19 +96,20 @@ namespace etl public: //******************************************** +#include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } +#include "etl/private/diagnostic_pop.h" //******************************************** /// //******************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(T&& msg) - : data() - , valid(true) + : valid(true) { if constexpr (IsIMessage) { @@ -137,6 +138,7 @@ namespace etl ETL_STATIC_ASSERT(IsInMessageList, "Message not in packet type list"); } } +#include "etl/private/diagnostic_pop.h" //********************************************** void copy(const message_packet& other) @@ -422,15 +424,16 @@ namespace etl cog.outl("public:") cog.outl("") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet()") - cog.outl(" : data()") - cog.outl(" , valid(false)") + cog.outl(" : valid(false)") cog.outl(" {") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(const etl::imessage& msg)") - cog.outl(" : data()") cog.outl(" {") cog.outl(" if (accepts(msg))") cog.outl(" {") @@ -444,11 +447,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(etl::imessage&& msg)") - cog.outl(" : data()") cog.outl(" {") cog.outl(" if (accepts(msg))") cog.outl(" {") @@ -462,10 +466,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.out(" template ::type, etl::message_packet<") for n in range(1, int(Handlers)): cog.out("T%s, " % n) @@ -476,13 +482,14 @@ namespace etl cog.out("T%s, " % n) cog.outl("T%s>::value, int>::type>" % int(Handlers)) cog.outl(" explicit message_packet(TMessage&& msg)") - cog.outl(" : data()") - cog.outl(" , valid(true)") + cog.outl(" : valid(true)") cog.outl(" {") generate_static_assert_cpp11(int(Handlers)) cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#else") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" template ") cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet<") for n in range(1, int(Handlers)): @@ -493,35 +500,37 @@ namespace etl for n in range(1, int(Handlers)): cog.out("T%s, " % n) cog.outl("T%s>::value, int>::type = 0)" % int(Handlers)) - cog.outl(" : data()") - cog.outl(" , valid(true)") + cog.outl(" : valid(true)") cog.outl(" {") generate_static_assert_cpp03(int(Handlers)) cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(const message_packet& other)") - cog.outl(" : data()") - cog.outl(" , valid(other.is_valid())") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") cog.outl(" if (valid)") cog.outl(" {") cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(message_packet&& other)") - cog.outl(" : data()") - cog.outl(" , valid(other.is_valid())") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") cog.outl(" if (valid)") cog.outl(" {") cog.outl(" add_new_message(etl::move(other.get()));") cog.outl(" }") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") @@ -697,15 +706,16 @@ namespace etl cog.outl("public:") cog.outl("") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet()") - cog.outl(" : data()") - cog.outl(" , valid(false)") + cog.outl(" : valid(false)") cog.outl(" {") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(const etl::imessage& msg)") - cog.outl(" : data()") cog.outl(" {") cog.outl(" if (accepts(msg))") cog.outl(" {") @@ -719,11 +729,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(etl::imessage&& msg)") - cog.outl(" : data()") cog.outl(" {") cog.outl(" if (accepts(msg))") cog.outl(" {") @@ -737,10 +748,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.out(" template ::type, etl::message_packet<") for t in range(1, n): cog.out("T%s, " % t) @@ -750,14 +763,15 @@ namespace etl for t in range(1, n): cog.out("T%s, " % t) cog.outl("T%s>::value, int>::type>" % n) - cog.outl(" explicit message_packet(etl::imessage&& msg)") - cog.outl(" : data()") - cog.outl(" , valid(true)") + cog.outl(" explicit message_packet(TMessage&& msg)") + cog.outl(" : valid(true)") cog.outl(" {") generate_static_assert_cpp11(n) cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#else") cog.outl(" //********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" template ") cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet<") for t in range(1, n): @@ -768,35 +782,37 @@ namespace etl for t in range(1, n): cog.out("T%s, " % t) cog.outl("T%s>::value, int>::type = 0)" % n) - cog.outl(" : data()") - cog.outl(" , valid(true)") + cog.outl(" : valid(true)") cog.outl(" {") generate_static_assert_cpp03(n) cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(const message_packet& other)") - cog.outl(" : data()") - cog.outl(" , valid(other.is_valid())") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") cog.outl(" if (valid)") cog.outl(" {") cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") + cog.outl("#include \"etl/private/diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(message_packet&& other)") - cog.outl(" : data()") - cog.outl(" , valid(other.is_valid())") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") cog.outl(" if (valid)") cog.outl(" {") cog.outl(" add_new_message(etl::move(other.get()));") cog.outl(" }") cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") diff --git a/src/etl/generators/message_router_generator.h b/src/etl/generators/message_router_generator.h index d5869e5..1bfe767 100644 --- a/src/etl/generators/message_router_generator.h +++ b/src/etl/generators/message_router_generator.h @@ -63,8 +63,6 @@ cog.outl("//******************************************************************** #ifndef ETL_MESSAGE_ROUTER_INCLUDED #define ETL_MESSAGE_ROUTER_INCLUDED -#include - #include "platform.h" #include "message.h" #include "shared_message.h" @@ -79,6 +77,8 @@ cog.outl("//******************************************************************** #include "successor.h" #include "type_traits.h" +#include + namespace etl { //*************************************************************************** @@ -169,6 +169,8 @@ namespace etl NULL_MESSAGE_ROUTER = 255, MESSAGE_BUS = 254, ALL_MESSAGE_ROUTERS = 253, + MESSAGE_BROKER = 252, + MESSAGE_ROUTER = 251, MAX_MESSAGE_ROUTER = 249 }; @@ -201,11 +203,18 @@ namespace etl { public: + //******************************************** null_message_router() : imessage_router(imessage_router::NULL_MESSAGE_ROUTER) { } + //******************************************** + null_message_router(etl::imessage_router& successor) + : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor) + { + } + //******************************************** using etl::imessage_router::receive; @@ -272,9 +281,30 @@ namespace etl { public: + //******************************************** + message_producer() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //******************************************** + message_producer(etl::imessage_router& successor) + : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor) + { + } + + //******************************************** message_producer(etl::message_router_id_t id_) : imessage_router(id_) { + ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); + } + + //******************************************** + 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)); } //******************************************** @@ -340,6 +370,26 @@ namespace etl destination.receive(message); } + //*************************************************************************** + /// 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) + { + destination.receive(id, message); + } + + //*************************************************************************** + /// 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) + { + destination.receive(id, message); + } + //************************************************************************************************* // For C++17 and above. //************************************************************************************************* @@ -354,6 +404,18 @@ namespace etl typedef etl::message_packet message_packet; + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** message_router(etl::message_router_id_t id_) : imessage_router(id_) @@ -518,6 +580,18 @@ namespace etl cog.outl(" }") cog.outl("") cog.outl(" //**********************************************") + cog.outl(" message_router()") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::imessage_router& successor_)") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" using etl::imessage_router::receive;") cog.outl("") cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") @@ -673,6 +747,18 @@ namespace etl cog.outl(" }") cog.outl("") cog.outl(" //**********************************************") + cog.outl(" message_router()") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::imessage_router& successor_)") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" using etl::imessage_router::receive;") cog.outl("") cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") diff --git a/src/etl/generators/smallest_generator.h b/src/etl/generators/smallest_generator.h index d0c9228..10f599e 100644 --- a/src/etl/generators/smallest_generator.h +++ b/src/etl/generators/smallest_generator.h @@ -65,11 +65,11 @@ cog.outl("//******************************************************************** #ifndef ETL_SMALLEST_INCLUDED #define ETL_SMALLEST_INCLUDED -#include - #include "platform.h" #include "integral_limits.h" +#include + ///\defgroup smallest smallest ///\ingroup utilities @@ -256,6 +256,7 @@ namespace etl typedef uint_least32_t type; }; +#if ETL_USING_64BIT_TYPES //************************************************************************* // Greater than 32 bits. //************************************************************************* @@ -264,6 +265,7 @@ namespace etl { typedef uint_least64_t type; }; +#endif //************************************************************************* // Determine the type to hold the number of bits based on the index. @@ -298,6 +300,7 @@ namespace etl typedef int_least32_t type; }; +#if ETL_USING_64BIT_TYPES //************************************************************************* // Greater than 32 bits. //************************************************************************* @@ -306,6 +309,7 @@ namespace etl { typedef int_least64_t type; }; +#endif } //*************************************************************************** diff --git a/src/etl/generators/type_lookup_generator.h b/src/etl/generators/type_lookup_generator.h index 376c8c1..2563729 100644 --- a/src/etl/generators/type_lookup_generator.h +++ b/src/etl/generators/type_lookup_generator.h @@ -29,14 +29,14 @@ SOFTWARE. #ifndef ETL_TYPE_LOOKUP_INCLUDED #define ETL_TYPE_LOOKUP_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "static_assert.h" #include "integral_limits.h" #include "null_type.h" +#include + /*[[[cog import cog cog.outl("#if 0") @@ -274,7 +274,7 @@ namespace etl cog.outl(" {") cog.outl(" value =") for n in range(1, int(NTypes) + 1) : - cog.outl(" (unsigned int) etl::is_same::value ? T%s::ID :" % (n, n)) + cog.outl(" (unsigned int) etl::is_same::value ? (unsigned int)T%s::ID :" % (n, n)) cog.outl(" (unsigned int) UNKNOWN") cog.outl(" };") cog.outl("") diff --git a/src/etl/generators/type_traits_generator.h b/src/etl/generators/type_traits_generator.h index 8546198..b7e16d8 100644 --- a/src/etl/generators/type_traits_generator.h +++ b/src/etl/generators/type_traits_generator.h @@ -65,13 +65,13 @@ cog.outl("//******************************************************************** #ifndef ETL_TYPE_TRAITS_INCLUDED #define ETL_TYPE_TRAITS_INCLUDED -#include -#include - #include "platform.h" #include "nullptr.h" #include "static_assert.h" +#include +#include + ///\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. @@ -1601,7 +1601,7 @@ namespace etl #endif //*************************************************************************** -#if ETL_USING_CPP11 && ETL_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED)) +#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED)) //********************************************* // Use the STL's definitions. diff --git a/src/etl/generators/variant_pool_generator.h b/src/etl/generators/variant_pool_generator.h index 22f7dc3..1bbd1f7 100644 --- a/src/etl/generators/variant_pool_generator.h +++ b/src/etl/generators/variant_pool_generator.h @@ -63,14 +63,14 @@ cog.outl("//******************************************************************** #ifndef ETL_VARIANT_POOL_INCLUDED #define ETL_VARIANT_POOL_INCLUDED -#include - #include "platform.h" #include "pool.h" #include "type_traits.h" #include "static_assert.h" #include "largest.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/hash.h b/src/etl/hash.h index 3b610fa..8f0e79f 100644 --- a/src/etl/hash.h +++ b/src/etl/hash.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_HASH_INCLUDED #define ETL_HASH_INCLUDED -#include -#include - #include "platform.h" #if ETL_USING_8BIT_TYPES @@ -43,6 +40,9 @@ SOFTWARE. #include "type_traits.h" #include "static_assert.h" +#include +#include + ///\defgroup hash Standard hash calculations ///\ingroup maths @@ -86,13 +86,41 @@ namespace etl return fnv_1a_64(begin, end); } #endif + + //************************************************************************* + /// Primary definition of base hash class, by default is poisoned + //************************************************************************* + template + struct hash_base + { + private: + hash_base(); // Can't default construct + hash_base(const hash_base& other); // Can't copy construct + hash_base& operator=(const hash_base& other); // Can't copy assign + +#if ETL_USING_CPP11 + hash_base(hash_base&& other); // Can't move construct + hash_base& operator=(hash_base&& other); // Can't move assign +#endif + }; + + // Specialization for enums depends on definitions for integers, so it comes later } +#if ETL_USING_CPP11 + //*************************************************************************** + /// Generic declaration for etl::hash, including default for enums + ///\ingroup hash + //*************************************************************************** + template + struct hash : private_hash::hash_base::value>{}; +#else //*************************************************************************** /// Generic declaration for etl::hash ///\ingroup hash //*************************************************************************** template struct hash; +#endif //*************************************************************************** /// Specialisation for bool. @@ -335,6 +363,10 @@ namespace etl float v; } u; + if (v == -0.0f) + { // -0.0 and 0.0 are represented differently at bit level + v = 0.0f; + } u.v = v; return u.s; @@ -365,6 +397,10 @@ namespace etl double v; } u; + if (v == -0.0) + { // -0.0 and 0.0 are represented differently at bit level + v = 0.0; + } u.v = v; return u.s; @@ -395,6 +431,10 @@ namespace etl long double v; } u; + if (v == -0.0L) + { // -0.0 and 0.0 are represented differently at bit level + v = 0.0L; + } u.v = v; return u.s; @@ -436,6 +476,28 @@ namespace etl } } }; + + namespace private_hash + { + //************************************************************************* + /// Specialization for enums + //************************************************************************* + template + struct hash_base + { + size_t operator()(T v) const + { + if (sizeof(size_t) >= sizeof(T)) + { + return static_cast(v); + } + else + { + return ::etl::hash()(static_cast(v)); + } + } + }; + } } #endif // ETL_USING_8BIT_TYPES diff --git a/src/etl/ihash.h b/src/etl/ihash.h index cbbbe75..a73f729 100644 --- a/src/etl/ihash.h +++ b/src/etl/ihash.h @@ -31,15 +31,13 @@ SOFTWARE. #ifndef ETL_IHASH_INCLUDED #define ETL_IHASH_INCLUDED -#include - #include "platform.h" - #include "utility.h" - #include "exception.h" #include "error_handler.h" +#include + ///\defgroup ihash Common data for all hash type classes. ///\ingroup hash diff --git a/src/etl/indirect_vector.h b/src/etl/indirect_vector.h index 73cf111..002cad0 100644 --- a/src/etl/indirect_vector.h +++ b/src/etl/indirect_vector.h @@ -1509,7 +1509,7 @@ namespace etl #endif //************************************************************************* - /// Copy constructor. + /// Construct a copy. //************************************************************************* indirect_vector_ext(const indirect_vector_ext& other, etl::ivector& lookup_, etl::ipool& pool_) : etl::iindirect_vector(lookup_, pool_) @@ -1518,6 +1518,11 @@ namespace etl this->assign(other.begin(), other.end()); } + //************************************************************************* + /// Copy constructor (Deleted) + //************************************************************************* + indirect_vector_ext(const indirect_vector_ext& other) ETL_DELETE; + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -1533,7 +1538,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* - /// Move constructor. + /// Move construct. //************************************************************************* indirect_vector_ext(indirect_vector_ext&& other, etl::ivector& lookup_, etl::ipool& pool_) : etl::iindirect_vector(lookup_, pool_) @@ -1542,6 +1547,11 @@ namespace etl this->move_container(etl::move(other)); } + //************************************************************************* + /// Move constructor. + //************************************************************************* + indirect_vector_ext(indirect_vector_ext&& other) ETL_DELETE; + //************************************************************************* /// Move assignment operator. //************************************************************************* diff --git a/src/etl/initializer_list.h b/src/etl/initializer_list.h index bf1fbac..73b9470 100644 --- a/src/etl/initializer_list.h +++ b/src/etl/initializer_list.h @@ -225,4 +225,4 @@ namespace std #endif // (ETL_USING_STL && ETL_NOT_USING_STLPORT && !defined(ETL_FORCE_ETL_INITIALIZER_LIST)) || defined(ETL_IN_UNIT_TEST) || defined(ETL_FORCE_STD_INITIALIZER_LIST) #endif // ETL_USING_CPP11 && !defined(ETL_NO_INITIALIZER_LIST) #endif // ETL_HAS_INITIALIZER_LIST -#endif // ETL_INITIALIZER_LIST_INCLUDED \ No newline at end of file +#endif // ETL_INITIALIZER_LIST_INCLUDED diff --git a/src/etl/instance_count.h b/src/etl/instance_count.h index 1717ed9..608ec3c 100644 --- a/src/etl/instance_count.h +++ b/src/etl/instance_count.h @@ -31,10 +31,10 @@ SOFTWARE. #ifndef ETL_INSTANCE_COUNT_INCLUDED #define ETL_INSTANCE_COUNT_INCLUDED -#include - #include "platform.h" +#include + ///\defgroup instance_count instance count ///\ingroup utilities diff --git a/src/etl/integral_limits.h b/src/etl/integral_limits.h index 033e991..a93f6c8 100644 --- a/src/etl/integral_limits.h +++ b/src/etl/integral_limits.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_INTEGRAL_LIMITS_INCLUDED #define ETL_INTEGRAL_LIMITS_INCLUDED -#include -#include - #include "platform.h" #include "type_traits.h" +#include +#include + #include "private/minmax_push.h" //***************************************************************************** @@ -215,6 +215,8 @@ namespace etl static ETL_CONSTANT int bits = CHAR_BIT * (sizeof(unsigned long long) / sizeof(char)); static ETL_CONSTANT bool is_signed = etl::is_signed::value; }; + + static ETL_CONSTANT size_t npos = etl::integral_limits::max; } #include "private/minmax_pop.h" diff --git a/src/etl/intrusive_forward_list.h b/src/etl/intrusive_forward_list.h index 997081b..da74970 100644 --- a/src/etl/intrusive_forward_list.h +++ b/src/etl/intrusive_forward_list.h @@ -32,23 +32,18 @@ SOFTWARE. #define ETL_INTRUSIVE_FORWARD_LIST_INCLUDED #include "platform.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" - -#include "private/minmax_push.h" - -#include - -#include "platform.h" #include "nullptr.h" #include "type_traits.h" #include "exception.h" #include "error_handler.h" #include "intrusive_links.h" -#include "algorithm.h" -#include "iterator.h" + +#include + +#include "private/minmax_push.h" namespace etl { diff --git a/src/etl/intrusive_links.h b/src/etl/intrusive_links.h index c6c7caa..c234c0d 100644 --- a/src/etl/intrusive_links.h +++ b/src/etl/intrusive_links.h @@ -31,17 +31,16 @@ SOFTWARE. #ifndef ETL_INTRUSIVE_LINKS_INCLUDED #define ETL_INTRUSIVE_LINKS_INCLUDED -#include - #include "platform.h" #include "nullptr.h" #include "type_traits.h" #include "exception.h" #include "error_handler.h" - #include "utility.h" #include "algorithm.h" +#include + //***************************************************************************** // Note: // The link functions work slightly differently to the STL 'insert' convention diff --git a/src/etl/intrusive_list.h b/src/etl/intrusive_list.h index f55ddca..800c9d8 100644 --- a/src/etl/intrusive_list.h +++ b/src/etl/intrusive_list.h @@ -31,12 +31,6 @@ SOFTWARE. #ifndef ETL_INTRUSIVE_LIST_INCLUDED #define ETL_INTRUSIVE_LIST_INCLUDED -#include "platform.h" - -#include "private/minmax_push.h" - -#include - #include "platform.h" #include "nullptr.h" #include "type_traits.h" @@ -44,13 +38,14 @@ SOFTWARE. #include "error_handler.h" #include "intrusive_links.h" #include "static_assert.h" -#include "algorithm.h" -#include "iterator.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" +#include + +#include "private/minmax_push.h" + namespace etl { //*************************************************************************** diff --git a/src/etl/intrusive_queue.h b/src/etl/intrusive_queue.h index 235b166..7268d32 100644 --- a/src/etl/intrusive_queue.h +++ b/src/etl/intrusive_queue.h @@ -31,13 +31,13 @@ SOFTWARE. #ifndef ETL_INTRUSIVE_QUEUE_INCLUDED #define ETL_INTRUSIVE_QUEUE_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "error_handler.h" #include "intrusive_links.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/intrusive_stack.h b/src/etl/intrusive_stack.h index e10df25..694a7ed 100644 --- a/src/etl/intrusive_stack.h +++ b/src/etl/intrusive_stack.h @@ -31,13 +31,13 @@ SOFTWARE. #ifndef ETL_INTRUSIVE_STACK_INCLUDED #define ETL_INTRUSIVE_STACK_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "error_handler.h" #include "intrusive_links.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/io_port.h b/src/etl/io_port.h index 807b172..e18347b 100644 --- a/src/etl/io_port.h +++ b/src/etl/io_port.h @@ -35,13 +35,11 @@ SOFTWARE. /// IO port access ///\ingroup utilities -#include - #include "platform.h" #include "nullptr.h" #include "iterator.h" -#include "iterator.h" +#include namespace etl { diff --git a/src/etl/iterator.h b/src/etl/iterator.h index e37351e..016eec1 100644 --- a/src/etl/iterator.h +++ b/src/etl/iterator.h @@ -34,6 +34,7 @@ SOFTWARE. #include "platform.h" #include "type_traits.h" #include "utility.h" +#include "private/addressof.h" #if ETL_USING_STL || defined(ETL_IN_UNIT_TEST) #include @@ -51,7 +52,7 @@ namespace etl struct forward_iterator_tag : public input_iterator_tag {}; struct bidirectional_iterator_tag : public forward_iterator_tag {}; struct random_access_iterator_tag : public bidirectional_iterator_tag {}; - struct contiguous_iterator_tag : public random_access_iterator_tag {}; + //struct contiguous_iterator_tag : public random_access_iterator_tag {}; //*************************************************************************** // iterator_traits @@ -91,10 +92,8 @@ namespace etl //*************************************************************************** // advance -#if ETL_NOT_USING_STL - template - ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag) + ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::output_iterator_tag) { while (n--) { @@ -103,7 +102,7 @@ namespace etl } template - ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag) + ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::forward_iterator_tag) { while (n--) { @@ -112,7 +111,7 @@ namespace etl } template - ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag) + ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::bidirectional_iterator_tag) { if (n > 0) { @@ -131,34 +130,23 @@ namespace etl } template - ETL_CONSTEXPR17 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag) + ETL_CONSTEXPR14 void advance_helper(TIterator& itr, TDistance n, ETL_OR_STD::random_access_iterator_tag) { itr += n; } template - ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n) + ETL_CONSTEXPR14 void advance(TIterator& itr, TDistance n) { typedef typename etl::iterator_traits::iterator_category tag; advance_helper(itr, n, tag()); } -#else - - template - ETL_CONSTEXPR17 void advance(TIterator& itr, TDistance n) - { - std::advance(itr, n); - } - -#endif - //*************************************************************************** // distance -#if ETL_NOT_USING_STL template - ETL_CONSTEXPR17 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag) + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::input_iterator_tag) { typename etl::iterator_traits::difference_type d = 0; @@ -172,7 +160,7 @@ namespace etl } template - ETL_CONSTEXPR17 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::forward_iterator_tag) + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::forward_iterator_tag) { typename etl::iterator_traits::difference_type d = 0; @@ -186,7 +174,7 @@ namespace etl } template - ETL_CONSTEXPR17 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::bidirectional_iterator_tag) + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::bidirectional_iterator_tag) { typename etl::iterator_traits::difference_type d = 0; @@ -200,52 +188,36 @@ namespace etl } template - ETL_CONSTEXPR17 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::random_access_iterator_tag) + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETL_OR_STD::random_access_iterator_tag) { return last - first; } template - ETL_CONSTEXPR17 typename etl::iterator_traits::difference_type distance(TIterator first, TIterator last) + ETL_CONSTEXPR14 typename etl::iterator_traits::difference_type distance(TIterator first, TIterator last) { typedef typename etl::iterator_traits::iterator_category tag; return distance_helper(first, last, tag()); } -#else - - template - ETL_CONSTEXPR17 typename std::iterator_traits::difference_type distance(TIterator first, TIterator last) - { - return std::distance(first, last); - } - -#endif - //*************************************************************************** // Previous template - ETL_CONSTEXPR17 TIterator prev(TIterator itr, typename etl::iterator_traits::difference_type n = 1) + ETL_CONSTEXPR14 TIterator prev(TIterator itr, typename etl::iterator_traits::difference_type n = 1) { -#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED etl::advance(itr, -n); -#else - std::advance(itr, -n); -#endif + return itr; } //*************************************************************************** // Next template - ETL_CONSTEXPR17 TIterator next(TIterator itr, typename etl::iterator_traits::difference_type n = 1) + ETL_CONSTEXPR14 TIterator next(TIterator itr, typename etl::iterator_traits::difference_type n = 1) { -#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED etl::advance(itr, n); -#else - std::advance(itr, n); -#endif + return itr; } @@ -281,7 +253,7 @@ namespace etl } template - ETL_CONSTEXPR14 reverse_iterator& operator=(const reverse_iterator& other) + ETL_CONSTEXPR14 reverse_iterator& operator =(const reverse_iterator& other) { current = other.base(); @@ -371,49 +343,49 @@ namespace etl TIterator current; }; - template + template ETL_CONSTEXPR14 bool operator ==(const reverse_iterator& lhs, const reverse_iterator& rhs) { return lhs.base() == rhs.base(); } - template + template ETL_CONSTEXPR14 bool operator !=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return !(lhs == rhs); } - template + template ETL_CONSTEXPR14 bool operator <(const reverse_iterator& lhs, const reverse_iterator& rhs) { return rhs.base() < lhs.base(); } - template + template ETL_CONSTEXPR14 bool operator >(const reverse_iterator& lhs, const reverse_iterator& rhs) { return rhs < lhs; } - template + template ETL_CONSTEXPR14 bool operator <=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return !(rhs < lhs); } - template + template ETL_CONSTEXPR14 bool operator >=(const reverse_iterator& lhs, const reverse_iterator& rhs) { return !(lhs < rhs); } - template + template ETL_CONSTEXPR14 typename reverse_iterator::difference_type operator -(const reverse_iterator& lhs, const reverse_iterator& rhs) { return rhs.base() - lhs.base(); } - template + template ETL_CONSTEXPR14 reverse_iterator operator +(TDifference n, const reverse_iterator& itr) { return itr.operator +(n); @@ -604,7 +576,226 @@ namespace etl return etl::move_iterator(itr); } -#endif +#endif //ETL_USING_CPP11 + + //*************************************************************************** + // back_insert_iterator + //*************************************************************************** + + //*************************************************************************** + ///\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 + //*************************************************************************** + template + class back_insert_iterator : public etl::iterator + { + 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. + 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. + /// @return This %iterator, for chained operations. + //*************************************************************************** + ETL_CONSTEXPR14 back_insert_iterator& operator =(const typename TContainer::value_type& value) + { + container->push_back(value); + + return (*this); + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Move assignment operator. + //*************************************************************************** + ETL_CONSTEXPR14 back_insert_iterator& operator =(typename TContainer::value_type&& value) + { + container->push_back(etl::move(value)); + + return (*this); + } +#endif // ETL_USING_CPP11 + + //*************************************************************************** + /// Dereference operator. + /// Simply returns *this. + //*************************************************************************** + ETL_NODISCARD ETL_CONSTEXPR14 back_insert_iterator& operator *() + { + return (*this); + } + + //*************************************************************************** + /// Pre-increment operator. + /// Simply returns *this. (This %iterator does not @a move.) + //*************************************************************************** + ETL_CONSTEXPR14 back_insert_iterator& operator ++() + { + return (*this); + } + + //*************************************************************************** + /// Post-increment operator. + /// Simply returns *this. (This %iterator does not @a move.) + //*************************************************************************** + ETL_CONSTEXPR14 back_insert_iterator operator ++(int) + { + return (*this); + } + + protected: + + TContainer* container; + }; + + //*************************************************************************** + /// 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. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + etl::back_insert_iterator back_inserter(TContainer& container) + { + return etl::back_insert_iterator(container); + } + + //*************************************************************************** + // front_insert_iterator + //*************************************************************************** + + //*************************************************************************** + ///\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. + //*************************************************************************** + template + class front_insert_iterator : public etl::iterator + { + 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)) + { + } + + //*************************************************************************** + /// 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. + /// @return This %iterator, for chained operations. + //*************************************************************************** + ETL_CONSTEXPR14 front_insert_iterator& operator =(const typename TContainer::value_type& value) + { + container->push_front(value); + return (*this); + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Move assignment operator. + //*************************************************************************** + ETL_CONSTEXPR14 front_insert_iterator& operator =(typename TContainer::value_type&& value) + { + container->push_front(etl::move(value)); + return (*this); + } +#endif // ETL_USING_CPP11 + + //*************************************************************************** + /// Dereference operator. + /// Simply returns *this. + //*************************************************************************** + ETL_NODISCARD ETL_CONSTEXPR14 front_insert_iterator& operator *() + { + return (*this); + } + + //*************************************************************************** + /// Pre-increment operator. + /// Simply returns *this. (This %iterator does not @a move.) + //*************************************************************************** + ETL_CONSTEXPR14 front_insert_iterator& operator ++() + { + return (*this); + } + + //*************************************************************************** + /// Post-increment operator. + /// Simply returns *this. (This %iterator does not @a move.) + //*************************************************************************** + ETL_CONSTEXPR14 front_insert_iterator operator ++(int) + { + return (*this); + } + + protected: + + TContainer* container; + }; + + //*************************************************************************** + /// 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. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + etl::front_insert_iterator front_inserter(TContainer& container) + { + return etl::front_insert_iterator(container); + } //*************************************************************************** // Helper templates. diff --git a/src/etl/jenkins.h b/src/etl/jenkins.h index eea4517..6e36877 100644 --- a/src/etl/jenkins.h +++ b/src/etl/jenkins.h @@ -31,17 +31,16 @@ SOFTWARE. #ifndef ETL_JENKINS_INCLUDED #define ETL_JENKINS_INCLUDED -#include - #include "platform.h" #include "static_assert.h" #include "type_traits.h" #include "error_handler.h" #include "ihash.h" #include "frame_check_sequence.h" - #include "iterator.h" +#include + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 1300 #endif diff --git a/src/etl/limits.h b/src/etl/limits.h index 4b3f8f8..eae016b 100644 --- a/src/etl/limits.h +++ b/src/etl/limits.h @@ -275,7 +275,7 @@ namespace etl //*************************************************************************** // char8_t template<> - class numeric_limits : public etl_integral_limits + class numeric_limits : public etl_integral_limits { public: @@ -284,15 +284,15 @@ namespace etl static ETL_CONSTANT bool is_signed = etl::is_signed::value; static ETL_CONSTANT bool is_modulo = false; - static ETL_CONSTEXPR char min() { return char(CHAR_MIN); } - static ETL_CONSTEXPR char max() { return char(CHAR_MAX); } - static ETL_CONSTEXPR char lowest() { return char(CHAR_MIN); } - static ETL_CONSTEXPR char epsilon() { return 0; } - static ETL_CONSTEXPR char round_error() { return 0; } - static ETL_CONSTEXPR char denorm_min() { return 0; } - static ETL_CONSTEXPR char infinity() { return 0; } - static ETL_CONSTEXPR char quiet_NaN() { return 0; } - static ETL_CONSTEXPR char signaling_NaN() { return 0; } + static ETL_CONSTEXPR char8_t min() { return char8_t(CHAR_MIN); } + static ETL_CONSTEXPR char8_t max() { return char8_t(CHAR_MAX); } + static ETL_CONSTEXPR char8_t lowest() { return char8_t(CHAR_MIN); } + static ETL_CONSTEXPR char8_t epsilon() { return 0; } + static ETL_CONSTEXPR char8_t round_error() { return 0; } + static ETL_CONSTEXPR char8_t denorm_min() { return 0; } + static ETL_CONSTEXPR char8_t infinity() { return 0; } + static ETL_CONSTEXPR char8_t quiet_NaN() { return 0; } + static ETL_CONSTEXPR char8_t signaling_NaN() { return 0; } }; #endif diff --git a/src/etl/list.h b/src/etl/list.h index c6a5256..6ba5070 100644 --- a/src/etl/list.h +++ b/src/etl/list.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_LIST_INCLUDED #define ETL_LIST_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -51,6 +49,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + #include "private/minmax_push.h" //***************************************************************************** diff --git a/src/etl/log.h b/src/etl/log.h index 32518b4..e049026 100644 --- a/src/etl/log.h +++ b/src/etl/log.h @@ -31,10 +31,10 @@ SOFTWARE. #ifndef ETL_LOG_INCLUDED #define ETL_LOG_INCLUDED -#include - #include "platform.h" +#include + ///\defgroup log log /// log : Calculates logs to any base, rounded down to the nearest integer.
/// log2 : Calculates logs to base 2, rounded down to the nearest integer.
diff --git a/src/etl/map.h b/src/etl/map.h index 66379ca..3c0ba2b 100644 --- a/src/etl/map.h +++ b/src/etl/map.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_MAP_INCLUDED #define ETL_MAP_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -50,6 +48,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + #include "private/minmax_push.h" #include "private/comparator_is_transparent.h" diff --git a/src/etl/mem_cast.h b/src/etl/mem_cast.h index 2fe3afb..d611dab 100644 --- a/src/etl/mem_cast.h +++ b/src/etl/mem_cast.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_MEM_CAST_INCLUDED #define ETL_MEM_CAST_INCLUDED -#include -#include - #include "platform.h" #include "memory.h" #include "static_assert.h" @@ -45,6 +42,9 @@ SOFTWARE. #include "file_error_numbers.h" #include "binary.h" +#include +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/memory.h b/src/etl/memory.h index 6e68bfc..0725d2e 100644 --- a/src/etl/memory.h +++ b/src/etl/memory.h @@ -40,6 +40,8 @@ SOFTWARE. #include "alignment.h" #include "placement_new.h" +#include "private/addressof.h" + #include #include @@ -52,21 +54,6 @@ SOFTWARE. namespace etl { - //***************************************************************************** - /// Gets the address of an object. - /// https://en.cppreference.com/w/cpp/memory/addressof - ///\ingroup memory - //***************************************************************************** - template - ETL_CONSTEXPR17 T* addressof(T& t) - { -#if ETL_USING_CPP11 && ETL_USING_STL - return std::addressof(t); -#else - return reinterpret_cast(&const_cast(reinterpret_cast(t))); -#endif - } - #if ETL_NOT_USING_STL //***************************************************************************** /// Fills uninitialised memory range with a value. @@ -1245,7 +1232,19 @@ namespace etl template struct default_delete { - void operator()(T* p) const + //********************************* + ETL_CONSTEXPR default_delete() ETL_NOEXCEPT + { + } + + //********************************* + template + default_delete(const default_delete&) ETL_NOEXCEPT + { + } + + //********************************* + void operator()(T * p) const ETL_NOEXCEPT { delete p; } @@ -1260,6 +1259,18 @@ namespace etl template struct default_delete { + //********************************* + ETL_CONSTEXPR default_delete() ETL_NOEXCEPT + { + } + + //********************************* + template + default_delete(const default_delete&) ETL_NOEXCEPT + { + } + + //********************************* template void operator()(U* p) const { @@ -1296,10 +1307,23 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr(unique_ptr&& p_) ETL_NOEXCEPT - : p(p_.release()) - , deleter(etl::move(p_.deleter)) + unique_ptr(unique_ptr&& other) ETL_NOEXCEPT { + if (&other != this) + { + p = other.release(); + deleter = etl::move(other.deleter); + } + } +#else + //********************************* + unique_ptr(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + p = other.release(); + deleter = other.deleter; + } } #endif @@ -1319,6 +1343,13 @@ namespace etl , deleter(etl::move(deleter_)) { } + + template + unique_ptr(unique_ptr&& u) ETL_NOEXCEPT + : p(u.release()) + , deleter(etl::forward(u.get_deleter())) + { + } #endif //********************************* @@ -1381,7 +1412,7 @@ namespace etl return (p != ETL_NULLPTR); } -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //********************************* unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT { @@ -1401,9 +1432,25 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr& operator =(unique_ptr&& p_) ETL_NOEXCEPT + unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT + { + if (&other != this) + { + reset(other.release()); + deleter = etl::move(other.deleter); + } + + return *this; + } +#else + //********************************* + unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT { - reset(p_.release()); + if (&other != this) + { + reset(other.release()); + deleter = other.deleter; + } return *this; } @@ -1453,7 +1500,7 @@ namespace etl typedef T& reference; //********************************* - ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT + ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT : p(ETL_NULLPTR) { } @@ -1466,17 +1513,31 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr(unique_ptr&& p_) ETL_NOEXCEPT - : p(p_.release()) - , deleter(etl::move(p_.deleter)) + unique_ptr(unique_ptr&& other) ETL_NOEXCEPT { + if (&other != this) + { + p = other.release(); + deleter = etl::move(other.deleter); + } + } +#else + //********************************* + unique_ptr(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + p = other.release(); + deleter = other.deleter; + } } #endif //********************************* - unique_ptr(pointer p_, typename etl::conditional::value, - TDeleter, - typename etl::add_lvalue_reference::type>::type deleter_) ETL_NOEXCEPT + unique_ptr(pointer p_, + typename etl::conditional::value, + TDeleter, + typename etl::add_lvalue_reference::type>::type deleter_) ETL_NOEXCEPT : p(p_) , deleter(deleter_) { @@ -1489,6 +1550,13 @@ namespace etl , deleter(etl::move(deleter_)) { } + + template + unique_ptr(unique_ptr&& u) ETL_NOEXCEPT + : p(u.release()) + , deleter(etl::forward(u.get_deleter())) + { + } #endif //********************************* @@ -1550,7 +1618,7 @@ namespace etl return (p != ETL_NULLPTR); } -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //********************************* unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT { @@ -1570,9 +1638,25 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr& operator =(unique_ptr&& p_) ETL_NOEXCEPT + unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT { - reset(p_.release()); + if (&other != this) + { + reset(other.release()); + deleter = etl::move(other.deleter); + } + + return *this; + } +#else + //********************************* + unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + reset(other.release()); + deleter = other.deleter; + } return *this; } diff --git a/src/etl/memory_model.h b/src/etl/memory_model.h index d1c6628..4cf720f 100644 --- a/src/etl/memory_model.h +++ b/src/etl/memory_model.h @@ -31,10 +31,12 @@ SOFTWARE. #ifndef ETL_MEMORY_MODEL_INCLUDED #define ETL_MEMORY_MODEL_INCLUDED +#include "platform.h" #include "user_type.h" -#include #include "type_lookup.h" +#include + namespace etl { ETL_DECLARE_USER_TYPE(memory_model, int) diff --git a/src/etl/message.h b/src/etl/message.h index 366ca99..aeebb35 100644 --- a/src/etl/message.h +++ b/src/etl/message.h @@ -29,8 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_INCLUDED #define ETL_MESSAGE_INCLUDED -#include - #include "platform.h" #include "error_handler.h" #include "exception.h" @@ -38,6 +36,8 @@ SOFTWARE. #include "type_traits.h" #include "static_assert.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/message_broker.h b/src/etl/message_broker.h new file mode 100644 index 0000000..abedc8e --- /dev/null +++ b/src/etl/message_broker.h @@ -0,0 +1,330 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2017 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_MESSAGE_BROKER_INCLUDED +#define ETL_MESSAGE_BROKER_INCLUDED + +#include "platform.h" +#include "nullptr.h" +#include "message_types.h" +#include "message.h" +#include "message_router.h" +#include "span.h" + +#include + +namespace etl +{ + //*************************************************************************** + /// Message broker + //*************************************************************************** + class message_broker : public etl::imessage_router + { + private: + + //******************************************* + class subscription_node + { + friend class message_broker; + + protected: + + //******************************* + subscription_node() + : p_next(ETL_NULLPTR) + { + } + + //******************************* + void set_next(subscription_node* sub) + { + p_next = sub; + } + + //******************************* + subscription_node* get_next() const + { + return p_next; + } + + //******************************* + void terminate() + { + set_next(ETL_NULLPTR); + } + + //******************************* + void append(subscription_node* sub) + { + if (sub != ETL_NULLPTR) + { + sub->set_next(get_next()); + } + set_next(sub); + } + + subscription_node* p_next; + }; + + public: + + typedef etl::span message_id_span_t; + + //******************************************* + class subscription : public subscription_node + { + public: + + friend class message_broker; + + //******************************* + subscription(etl::imessage_router& router_) + : p_router(&router_) + { + } + + private: + + //******************************* + virtual message_id_span_t message_id_list() const = 0; + + //******************************* + etl::imessage_router* get_router() const + { + return p_router; + } + + //******************************* + subscription* next_subscription() const + { + return static_cast(get_next()); + } + + etl::imessage_router* const p_router; + }; + + using etl::imessage_router::receive; + + //******************************************* + /// Constructor. + //******************************************* + message_broker() + : imessage_router(etl::imessage_router::MESSAGE_BROKER) + , head() + { + } + + //******************************************* + /// Constructor. + //******************************************* + message_broker(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_BROKER, successor_) + , head() + { + } + + //******************************************* + /// Constructor. + //******************************************* + message_broker(etl::message_router_id_t id_) + : imessage_router(id_) + , head() + { + ETL_ASSERT((id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER) || (id_ == etl::imessage_router::MESSAGE_BROKER), ETL_ERROR(etl::message_router_illegal_id)); + } + + //******************************************* + /// Constructor. + //******************************************* + message_broker(etl::message_router_id_t id_, etl::imessage_router& successor_) + : imessage_router(id_, successor_) + , head() + { + ETL_ASSERT((id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER) || (id_ == etl::imessage_router::MESSAGE_BROKER), ETL_ERROR(etl::message_router_illegal_id)); + } + + //******************************************* + /// Subscribe to the broker. + //******************************************* + void subscribe(etl::message_broker::subscription& new_sub) + { + initialise_insertion_point(new_sub.get_router(), &new_sub); + } + + //******************************************* + void unsubscribe(etl::imessage_router& router) + { + initialise_insertion_point(&router, ETL_NULLPTR); + } + + //******************************************* + virtual void receive(const etl::imessage& msg) ETL_OVERRIDE + { + const etl::message_id_t id = msg.get_message_id(); + + if (!empty()) + { + // Scan the subscription lists. + subscription* sub = static_cast(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()) + { + sub->get_router()->receive(msg); + } + + sub = sub->next_subscription(); + } + } + + // Always pass the message on to the successor. + if (has_successor()) + { + etl::imessage_router& successor = get_successor(); + + successor.receive(msg); + } + } + + //******************************************* + virtual void receive(etl::shared_message shared_msg) ETL_OVERRIDE + { + const etl::message_id_t id = shared_msg.get_message().get_message_id(); + + if (!empty()) + { + // Scan the subscription lists. + subscription* sub = static_cast(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()) + { + sub->get_router()->receive(shared_msg); + } + + sub = sub->next_subscription(); + } + } + + // Always pass the message on to a successor. + if (has_successor()) + { + get_successor().receive(shared_msg); + } + } + + using imessage_router::accepts; + + //******************************************* + /// Message brokers accept all messages. + //******************************************* + virtual bool accepts(etl::message_id_t) const ETL_OVERRIDE + { + return true; + } + + //******************************************* + void clear() + { + head.terminate(); + } + + //******************************************** + ETL_DEPRECATED virtual bool is_null_router() const ETL_OVERRIDE + { + return false; + } + + //******************************************** + virtual bool is_producer() const ETL_OVERRIDE + { + return true; + } + + //******************************************** + virtual bool is_consumer() const ETL_OVERRIDE + { + return true; + } + + //******************************************** + bool empty() const + { + return head.get_next() == ETL_NULLPTR; + } + + private: + + //******************************************* + void initialise_insertion_point(const etl::imessage_router* p_router, etl::message_broker::subscription* p_new_sub) + { + const etl::imessage_router* p_target_router = p_router; + + subscription_node* p_sub = head.get_next(); + subscription_node* p_sub_previous = &head; + + while (p_sub != ETL_NULLPTR) + { + // Do we already have a subscription for the router? + if (static_cast(p_sub)->get_router() == p_target_router) + { + // Then unlink it. + p_sub_previous->set_next(p_sub->get_next()); // Jump over the subscription. + p_sub->terminate(); // Terminate the unlinked subscription. + + // We're done now. + break; + } + + // Move on up the list. + p_sub = p_sub->get_next(); + p_sub_previous = p_sub_previous->get_next(); + } + + if (p_new_sub != ETL_NULLPTR) + { + // Link in the new subscription. + p_sub_previous->append(p_new_sub); + } + } + + subscription_node head; + }; +} + +#endif diff --git a/src/etl/message_bus.h b/src/etl/message_bus.h index 134d094..64b7958 100644 --- a/src/etl/message_bus.h +++ b/src/etl/message_bus.h @@ -26,11 +26,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#ifndef ETL_MESSAGE_BUS_ -#define ETL_MESSAGE_BUS_ - -#include -#include "algorithm.h" +#ifndef ETL_MESSAGE_BUS_INCLUDED +#define ETL_MESSAGE_BUS_INCLUDED #include "platform.h" #include "algorithm.h" @@ -42,6 +39,8 @@ SOFTWARE. #include "message.h" #include "message_router.h" +#include + namespace etl { //*************************************************************************** @@ -208,9 +207,9 @@ namespace etl // Do any message buses. // These are always at the end of the list. router_list_t::iterator irouter = etl::lower_bound(router_list.begin(), - router_list.end(), - etl::imessage_bus::MESSAGE_BUS, - compare_router_id()); + router_list.end(), + etl::imessage_bus::MESSAGE_BUS, + compare_router_id()); while (irouter != router_list.end()) { @@ -336,7 +335,7 @@ namespace etl //******************************************* void clear() { - return router_list.clear(); + router_list.clear(); } //******************************************** @@ -368,6 +367,15 @@ namespace etl { } + //******************************************* + /// Constructor. + //******************************************* + imessage_bus(router_list_t& list, etl::imessage_router& successor) + : imessage_router(etl::imessage_router::MESSAGE_BUS, successor), + router_list(list) + { + } + private: //******************************************* @@ -405,29 +413,18 @@ namespace etl { } + //******************************************* + /// Constructor. + //******************************************* + message_bus(etl::imessage_router& successor) + : imessage_bus(router_list, successor) + { + } + private: etl::vector router_list; }; - - //*************************************************************************** - /// Send a message to a bus. - //*************************************************************************** - static inline void send_message(etl::imessage_bus& bus, - const etl::imessage& message) - { - bus.receive(message); - } - - //*************************************************************************** - /// Send a message to a bus. - //*************************************************************************** - static inline void send_message(etl::imessage_bus& bus, - etl::message_router_id_t id, - const etl::imessage& message) - { - bus.receive(id, message); - } } #endif diff --git a/src/etl/message_packet.h b/src/etl/message_packet.h index 3da882d..7a2f051 100644 --- a/src/etl/message_packet.h +++ b/src/etl/message_packet.h @@ -84,19 +84,20 @@ namespace etl public: //******************************************** +#include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } +#include "etl/private/diagnostic_pop.h" //******************************************** /// //******************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(T&& msg) - : data() - , valid(true) + : valid(true) { if constexpr (IsIMessage) { @@ -125,6 +126,7 @@ namespace etl ETL_STATIC_ASSERT(IsInMessageList, "Message not in packet type list"); } } +#include "etl/private/diagnostic_pop.h" //********************************************** void copy(const message_packet& other) @@ -332,15 +334,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -354,11 +357,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -372,16 +376,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value, int>::type> explicit message_packet(TMessage&& msg) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -390,14 +395,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -406,30 +412,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -616,15 +625,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -638,11 +648,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -656,16 +667,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -674,14 +686,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -690,30 +703,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -898,15 +914,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -920,11 +937,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -938,16 +956,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -956,14 +975,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -972,30 +992,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -1178,15 +1201,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -1200,11 +1224,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -1218,16 +1243,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1236,14 +1262,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1252,30 +1279,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -1455,15 +1485,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -1477,11 +1508,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -1495,16 +1527,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1513,14 +1546,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1529,30 +1563,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -1727,15 +1764,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -1749,11 +1787,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -1767,16 +1806,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1785,14 +1825,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -1801,30 +1842,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -1997,15 +2041,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -2019,11 +2064,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -2037,16 +2083,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2055,14 +2102,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2071,30 +2119,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -2265,15 +2316,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -2287,11 +2339,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -2305,16 +2358,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2323,14 +2377,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8, T9>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2339,30 +2394,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -2530,15 +2588,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -2552,11 +2611,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -2570,16 +2630,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2588,14 +2649,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7, T8>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2604,30 +2666,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -2790,15 +2855,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -2812,11 +2878,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -2830,16 +2897,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2848,14 +2916,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6, T7>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -2864,30 +2933,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -3048,15 +3120,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -3070,11 +3143,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -3088,16 +3162,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3106,14 +3181,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5, T6>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3122,30 +3198,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -3304,15 +3383,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -3326,11 +3406,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -3344,16 +3425,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3362,14 +3444,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4, T5>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3378,30 +3461,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -3557,15 +3643,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -3579,11 +3666,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -3597,16 +3685,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3615,14 +3704,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3, T4>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3631,30 +3721,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -3805,15 +3898,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -3827,11 +3921,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -3845,16 +3940,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3863,14 +3959,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2, T3>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -3879,30 +3976,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -4051,15 +4151,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -4073,11 +4174,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -4091,16 +4193,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -4109,14 +4212,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1, T2>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -4125,30 +4229,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** @@ -4295,15 +4402,16 @@ namespace etl public: //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet() - : data() - , valid(false) + : valid(false) { } + #include "etl/private/diagnostic_pop.h" //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(const etl::imessage& msg) - : data() { if (accepts(msg)) { @@ -4317,11 +4425,12 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" explicit message_packet(etl::imessage&& msg) - : data() { if (accepts(msg)) { @@ -4335,16 +4444,17 @@ namespace etl ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); } + #include "etl/private/diagnostic_pop.h" #endif #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS) //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template ::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1>::value, int>::type> - explicit message_packet(etl::imessage&& msg) - : data() - , valid(true) + explicit message_packet(TMessage&& msg) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static constexpr bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -4353,14 +4463,15 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #else //******************************************** + #include "etl/private/diagnostic_uninitialized_push.h" template explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet >::value && !etl::is_same::type, etl::imessage>::value && !etl::is_one_of::type, T1>::value, int>::type = 0) - : data() - , valid(true) + : valid(true) { // Not etl::message_packet, not etl::imessage and in typelist. static const bool Enabled = (!etl::is_same::type, etl::message_packet >::value && @@ -4369,30 +4480,33 @@ namespace etl ETL_STATIC_ASSERT(Enabled, "Message not in packet type list"); } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(const message_packet& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(other.get()); } } + #include "etl/private/diagnostic_pop.h" #if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) //********************************************** + #include "etl/private/diagnostic_uninitialized_push.h" message_packet(message_packet&& other) - : data() - , valid(other.is_valid()) + : valid(other.is_valid()) { if (valid) { add_new_message(etl::move(other.get())); } } + #include "etl/private/diagnostic_pop.h" #endif //********************************************** diff --git a/src/etl/message_router.h b/src/etl/message_router.h index 50b7205..e5f9e12 100644 --- a/src/etl/message_router.h +++ b/src/etl/message_router.h @@ -51,8 +51,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_ROUTER_INCLUDED #define ETL_MESSAGE_ROUTER_INCLUDED -#include - #include "platform.h" #include "message.h" #include "shared_message.h" @@ -67,6 +65,8 @@ SOFTWARE. #include "successor.h" #include "type_traits.h" +#include + namespace etl { //*************************************************************************** @@ -157,6 +157,8 @@ namespace etl NULL_MESSAGE_ROUTER = 255, MESSAGE_BUS = 254, ALL_MESSAGE_ROUTERS = 253, + MESSAGE_BROKER = 252, + MESSAGE_ROUTER = 251, MAX_MESSAGE_ROUTER = 249 }; @@ -189,11 +191,18 @@ namespace etl { public: + //******************************************** null_message_router() : imessage_router(imessage_router::NULL_MESSAGE_ROUTER) { } + //******************************************** + null_message_router(etl::imessage_router& successor) + : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor) + { + } + //******************************************** using etl::imessage_router::receive; @@ -260,9 +269,30 @@ namespace etl { public: + //******************************************** + message_producer() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //******************************************** + message_producer(etl::imessage_router& successor) + : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor) + { + } + + //******************************************** message_producer(etl::message_router_id_t id_) : imessage_router(id_) { + ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); + } + + //******************************************** + 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)); } //******************************************** @@ -328,6 +358,26 @@ namespace etl destination.receive(message); } + //*************************************************************************** + /// 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) + { + destination.receive(id, message); + } + + //*************************************************************************** + /// 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) + { + destination.receive(id, message); + } + //************************************************************************************************* // For C++17 and above. //************************************************************************************************* @@ -342,6 +392,18 @@ namespace etl typedef etl::message_packet message_packet; + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** message_router(etl::message_router_id_t id_) : imessage_router(id_) @@ -492,6 +554,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -627,6 +701,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -761,6 +847,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -894,6 +992,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1025,6 +1135,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1154,6 +1276,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1282,6 +1416,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1409,6 +1555,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1534,6 +1692,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1657,6 +1827,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1778,6 +1960,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -1898,6 +2092,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -2016,6 +2222,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -2132,6 +2350,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -2247,6 +2477,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; @@ -2361,6 +2603,18 @@ namespace etl ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); } + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + //********************************************** using etl::imessage_router::receive; diff --git a/src/etl/message_router_registry.h b/src/etl/message_router_registry.h index c0c8998..e538435 100644 --- a/src/etl/message_router_registry.h +++ b/src/etl/message_router_registry.h @@ -29,8 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_ROUTER_REGISTRY_INCLUDED #define ETL_MESSAGE_ROUTER_REGISTRY_INCLUDED -#include - #include "platform.h" #include "file_error_numbers.h" #include "message_router.h" @@ -40,6 +38,8 @@ SOFTWARE. #include "iterator.h" #include "memory.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/message_timer.h b/src/etl/message_timer.h index 326c3d2..97d0bd7 100644 --- a/src/etl/message_timer.h +++ b/src/etl/message_timer.h @@ -29,9 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_TIMER_INCLUDED #define ETL_MESSAGE_TIMER_INCLUDED -#include -#include "algorithm.h" - #include "platform.h" #include "nullptr.h" #include "message_types.h" @@ -41,6 +38,9 @@ SOFTWARE. #include "static_assert.h" #include "timer.h" #include "atomic.h" +#include "algorithm.h" + +#include #if defined(ETL_IN_UNIT_TEST) && ETL_NOT_USING_STL #define ETL_DISABLE_TIMER_UPDATES diff --git a/src/etl/message_timer_atomic.h b/src/etl/message_timer_atomic.h index b67728d..e8ba055 100644 --- a/src/etl/message_timer_atomic.h +++ b/src/etl/message_timer_atomic.h @@ -29,9 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_TIMER_ATOMIC_INCLUDED #define ETL_MESSAGE_TIMER_ATOMIC_INCLUDED -#include -#include "algorithm.h" - #include "platform.h" #include "nullptr.h" #include "message_types.h" @@ -41,6 +38,9 @@ SOFTWARE. #include "static_assert.h" #include "timer.h" #include "atomic.h" +#include "algorithm.h" + +#include #if ETL_HAS_ATOMIC diff --git a/src/etl/message_timer_interrupt.h b/src/etl/message_timer_interrupt.h index 88f2e13..2390f3f 100644 --- a/src/etl/message_timer_interrupt.h +++ b/src/etl/message_timer_interrupt.h @@ -29,9 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_TIMER_INTERRUPT_INCLUDED #define ETL_MESSAGE_TIMER_INTERRUPT_INCLUDED -#include -#include "algorithm.h" - #include "platform.h" #include "nullptr.h" #include "message_types.h" @@ -41,6 +38,9 @@ SOFTWARE. #include "static_assert.h" #include "timer.h" #include "delegate.h" +#include "algorithm.h" + +#include namespace etl { diff --git a/src/etl/message_timer_locked.h b/src/etl/message_timer_locked.h index 81b9aaf..731df31 100644 --- a/src/etl/message_timer_locked.h +++ b/src/etl/message_timer_locked.h @@ -29,9 +29,6 @@ SOFTWARE. #ifndef ETL_MESSAGE_TIMER_LOCKED_INCLUDED #define ETL_MESSAGE_TIMER_LOCKED_INCLUDED -#include -#include "algorithm.h" - #include "platform.h" #include "nullptr.h" #include "message_types.h" @@ -41,6 +38,9 @@ SOFTWARE. #include "static_assert.h" #include "timer.h" #include "delegate.h" +#include "algorithm.h" + +#include namespace etl { diff --git a/src/etl/message_types.h b/src/etl/message_types.h index ae20e64..7a42285 100644 --- a/src/etl/message_types.h +++ b/src/etl/message_types.h @@ -29,10 +29,10 @@ SOFTWARE. #ifndef ETL_MESSAGE_DEFS_INCLUDED #define ETL_MESSAGE_DEFS_INCLUDED -#include - #include "platform.h" +#include + namespace etl { /// Allow alternative type for message id. diff --git a/src/etl/multimap.h b/src/etl/multimap.h index 11f0346..cf4639a 100644 --- a/src/etl/multimap.h +++ b/src/etl/multimap.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_MULTIMAP_INCLUDED #define ETL_MULTIMAP_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -50,6 +48,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + #include "private/minmax_push.h" #include "private/comparator_is_transparent.h" diff --git a/src/etl/multiset.h b/src/etl/multiset.h index 585b40e..92d3379 100644 --- a/src/etl/multiset.h +++ b/src/etl/multiset.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_MULTISET_INCLUDED #define ETL_MULTISET_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -49,6 +47,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + #include "private/minmax_push.h" #include "private/comparator_is_transparent.h" diff --git a/src/etl/murmur3.h b/src/etl/murmur3.h index 18fa491..8ef6aae 100644 --- a/src/etl/murmur3.h +++ b/src/etl/murmur3.h @@ -31,13 +31,13 @@ SOFTWARE. #ifndef ETL_MURMUR3_INCLUDED #define ETL_MURMUR3_INCLUDED -#include - #include "platform.h" #include "ihash.h" #include "binary.h" #include "error_handler.h" +#include + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 1300 #endif diff --git a/src/etl/mutex.h b/src/etl/mutex.h index eb49c98..625c4dc 100644 --- a/src/etl/mutex.h +++ b/src/etl/mutex.h @@ -31,7 +31,7 @@ SOFTWARE. #include "platform.h" -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 #include "mutex/mutex_std.h" #define ETL_HAS_MUTEX 1 #elif defined(ETL_TARGET_OS_CMSIS_OS2) diff --git a/src/etl/null_type.h b/src/etl/null_type.h index 863c1ad..31ae246 100644 --- a/src/etl/null_type.h +++ b/src/etl/null_type.h @@ -29,6 +29,8 @@ SOFTWARE. #ifndef ETL_NULL_TYPE_INCLUDED #define ETL_NULL_TYPE_INCLUDED +#include "platform.h" + #include namespace etl diff --git a/src/etl/optional.h b/src/etl/optional.h index b4c9779..4707d55 100644 --- a/src/etl/optional.h +++ b/src/etl/optional.h @@ -103,28 +103,36 @@ namespace etl ///\tparam The type to store. ///\ingroup utilities //***************************************************************************** + template ::value> + class optional; + + //***************************************************************************** + /// For non POD types. + //***************************************************************************** template - class optional + class optional { public: //*************************************************************************** /// Constructor. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" optional() - : storage() - , valid(false) + : valid(false) { } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Constructor with nullopt. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" optional(etl::nullopt_t) - : storage() - , valid(false) + : valid(false) { } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Copy constructor. @@ -359,7 +367,6 @@ namespace etl return valid; } - //*************************************************************************** /// Get a reference to the value. //*************************************************************************** @@ -503,15 +510,320 @@ namespace etl private: + bool valid; typename etl::aligned_storage_as::type storage; + }; + + //***************************************************************************** + /// For POD types. + //***************************************************************************** + template + class optional + { + public: + + //*************************************************************************** + /// Constructor. + //*************************************************************************** + ETL_CONSTEXPR14 optional() + : valid(false) + , storage() + { + } + + //*************************************************************************** + /// Constructor with nullopt. + //*************************************************************************** + ETL_CONSTEXPR14 optional(etl::nullopt_t) + : valid(false) + , storage() + { + } + + //*************************************************************************** + /// Copy constructor. + //*************************************************************************** + ETL_CONSTEXPR14 optional(const optional& other) + : valid(bool(other)) + , storage(other.storage) + { + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Move constructor. + //*************************************************************************** + ETL_CONSTEXPR14 optional(optional&& other) + : valid(bool(other)) + , storage(etl::move(other.storage)) + { + } +#endif + + //*************************************************************************** + /// Constructor from value type. + //*************************************************************************** + ETL_CONSTEXPR14 optional(const T& value_) + : valid(true) + , storage(value_) + { + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Constructor from value type. + //*************************************************************************** + ETL_CONSTEXPR14 optional(T&& value_) + : valid(true) + , storage(etl::move(value_)) + { + } +#endif + + //*************************************************************************** + /// Assignment operator from nullopt. + //*************************************************************************** + ETL_CONSTEXPR14 optional& operator =(etl::nullopt_t) + { + return *this; + } + + //*************************************************************************** + /// Assignment operator from optional. + //*************************************************************************** + ETL_CONSTEXPR14 optional& operator =(const optional& other) + { + if (this != &other) + { + storage = other.storage; + valid = other.valid; + } + + return *this; + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Assignment operator from optional. + //*************************************************************************** + ETL_CONSTEXPR14 optional& operator =(optional&& other) + { + if (this != &other) + { + storage = etl::move(other.storage); + valid = other.valid; + } + + return *this; + } +#endif + + //*************************************************************************** + /// Assignment operator from value type. + //*************************************************************************** + ETL_CONSTEXPR14 optional& operator =(const T& value_) + { + storage = value_; + valid = true; + + return *this; + } + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Assignment operator from value type. + //*************************************************************************** + ETL_CONSTEXPR14 optional& operator =(T&& value_) + { + storage = etl::move(value_); + valid = true; + + return *this; + } +#endif + + //*************************************************************************** + /// Pointer operator. + //*************************************************************************** + ETL_CONSTEXPR14 T* operator ->() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return &storage; + } + + //*************************************************************************** + /// Pointer operator. + //*************************************************************************** + ETL_CONSTEXPR14 const T* operator ->() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return &storage; + } + + //*************************************************************************** + /// Dereference operator. + //*************************************************************************** + ETL_CONSTEXPR14 T& operator *() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return storage; + } + + //*************************************************************************** + /// Dereference operator. + //*************************************************************************** + ETL_CONSTEXPR14 const T& operator *() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return storage; + } + + //*************************************************************************** + /// Bool conversion operator. + //*************************************************************************** + ETL_CONSTEXPR14 operator bool() const + { + return valid; + } + + //*************************************************************************** + // Check whether optional contains value + //*************************************************************************** + ETL_CONSTEXPR14 bool has_value() const ETL_NOEXCEPT + { + return valid; + } + + //*************************************************************************** + /// Get a reference to the value. + //*************************************************************************** + ETL_CONSTEXPR14 T& value() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return storage; + } + + //*************************************************************************** + /// Get a const reference to the value. + //*************************************************************************** + ETL_CONSTEXPR14 const T& value() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(optional_invalid)); +#endif + + return storage; + } + + //*************************************************************************** + /// Gets the value or a default if no valid. + //*************************************************************************** + ETL_CONSTEXPR14 T value_or(T default_value) const + { + return valid ? value() : default_value; + } + + //*************************************************************************** + /// Swaps this value with another. + //*************************************************************************** + ETL_CONSTEXPR14 void swap(optional& other) + { + optional temp(*this); + *this = other; + other = temp; + } + + //*************************************************************************** + /// Reset back to invalid. + //*************************************************************************** + ETL_CONSTEXPR14 void reset() + { + valid = false; + } + +#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_OPTIONAL_FORCE_CPP03_IMPLEMENTATION) + //************************************************************************* + /// Emplaces a value. + ///\param args The arguments to construct with. + //************************************************************************* + template + ETL_CONSTEXPR14 void emplace(Args && ... args) + { + storage = T(ETL_OR_STD::forward(args)...); + valid = true; + } +#else + //************************************************************************* + /// Emplaces a value. + /// 1 parameter. + //************************************************************************* + template + void emplace(const T1& value1) + { + storage = value1; + valid = true; + } + + //************************************************************************* + /// Emplaces a value. + /// 2 parameters. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2) + { + storage = T(value1, value2); + valid = true; + } + + //************************************************************************* + /// Emplaces a value. + /// 3 parameters. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3) + { + storage = T(value1, value2, value3); + valid = true; + } + + //************************************************************************* + /// Emplaces a value. + /// 4 parameters. + //************************************************************************* + template + void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + { + storage = T(value1, value2, value3, value4); + valid = true; + } +#endif + + private: + bool valid; + T storage; }; //*************************************************************************** /// Equality operator. cppreference 1 //*************************************************************************** template - bool operator ==(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator ==(const etl::optional& lhs, const etl::optional& rhs) { if (bool(lhs) != bool(rhs)) { @@ -531,7 +843,7 @@ namespace etl /// Equality operator. cppreference 2 //*************************************************************************** template - bool operator !=(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator !=(const etl::optional& lhs, const etl::optional& rhs) { return !(lhs == rhs); } @@ -540,7 +852,7 @@ namespace etl /// Less than operator. cppreference 3 //*************************************************************************** template - bool operator <(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator <(const etl::optional& lhs, const etl::optional& rhs) { if (!bool(rhs)) { @@ -560,7 +872,7 @@ namespace etl /// Less than equal operator. cppreference 4 //*************************************************************************** template - bool operator <=(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator <=(const etl::optional& lhs, const etl::optional& rhs) { if (!bool(lhs)) { @@ -580,7 +892,7 @@ namespace etl /// greater than operator. cppreference 5 //*************************************************************************** template - bool operator >(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator >(const etl::optional& lhs, const etl::optional& rhs) { if (!bool(lhs)) { @@ -600,7 +912,7 @@ namespace etl /// greater than equal operator. cppreference 6 //*************************************************************************** template - bool operator >=(const etl::optional& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator >=(const etl::optional& lhs, const etl::optional& rhs) { if (!bool(rhs)) { @@ -620,7 +932,7 @@ namespace etl /// Equality operator. cppreference 7 //*************************************************************************** template - bool operator ==(const etl::optional& lhs, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator ==(const etl::optional& lhs, etl::nullopt_t) { return !bool(lhs); } @@ -629,7 +941,7 @@ namespace etl /// Equality operator. cppreference 8 //*************************************************************************** template - bool operator ==(etl::nullopt_t, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator ==(etl::nullopt_t, const etl::optional& rhs) { return !bool(rhs); } @@ -638,7 +950,7 @@ namespace etl /// Inequality operator. cppreference 9 //*************************************************************************** template - bool operator !=(const etl::optional& lhs, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator !=(const etl::optional& lhs, etl::nullopt_t) { return !(lhs == etl::nullopt); } @@ -647,7 +959,7 @@ namespace etl /// Inequality operator. cppreference 10 //*************************************************************************** template - bool operator !=(etl::nullopt_t , const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator !=(etl::nullopt_t , const etl::optional& rhs) { return !(etl::nullopt == rhs); } @@ -656,7 +968,7 @@ namespace etl /// Less than operator. cppreference 11 //*************************************************************************** template - bool operator <(const etl::optional&, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator <(const etl::optional&, etl::nullopt_t) { return false; } @@ -665,7 +977,7 @@ namespace etl /// Less than operator. cppreference 12 //*************************************************************************** template - bool operator <(etl::nullopt_t, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator <(etl::nullopt_t, const etl::optional& rhs) { return bool(rhs); } @@ -674,7 +986,7 @@ namespace etl /// Less than equal operator. cppreference 13 //*************************************************************************** template - bool operator <=(const etl::optional& lhs, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator <=(const etl::optional& lhs, etl::nullopt_t) { return !bool(lhs); } @@ -683,7 +995,7 @@ namespace etl /// Less than equal operator. cppreference 14 //*************************************************************************** template - bool operator <=(etl::nullopt_t, const etl::optional&) + ETL_CONSTEXPR14 bool operator <=(etl::nullopt_t, const etl::optional&) { return true; } @@ -692,7 +1004,7 @@ namespace etl /// Greater than operator. cppreference 15 //*************************************************************************** template - bool operator >(const etl::optional& lhs, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator >(const etl::optional& lhs, etl::nullopt_t) { return bool(lhs); } @@ -701,7 +1013,7 @@ namespace etl /// Greater than operator. cppreference 16 //*************************************************************************** template - bool operator >(etl::nullopt_t, const etl::optional&) + ETL_CONSTEXPR14 bool operator >(etl::nullopt_t, const etl::optional&) { return false; } @@ -710,7 +1022,7 @@ namespace etl /// Greater than equal operator. cppreference 17 //*************************************************************************** template - bool operator >=(const etl::optional&, etl::nullopt_t) + ETL_CONSTEXPR14 bool operator >=(const etl::optional&, etl::nullopt_t) { return true; } @@ -719,7 +1031,7 @@ namespace etl /// Greater than equal operator. cppreference 18 //*************************************************************************** template - bool operator >=(etl::nullopt_t, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator >=(etl::nullopt_t, const etl::optional& rhs) { return !bool(rhs); } @@ -728,7 +1040,7 @@ namespace etl /// Equality operator. cppreference 19 //************************************************************************** template - bool operator ==(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator ==(const etl::optional& lhs, const U& rhs) { return bool(lhs) ? lhs.value() == rhs : false; } @@ -737,7 +1049,7 @@ namespace etl /// Inequality operator. cppreference 21 //************************************************************************** template - bool operator !=(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator !=(const etl::optional& lhs, const U& rhs) { return !(lhs == rhs); } @@ -746,7 +1058,7 @@ namespace etl /// Equality operator. cppreference 20 //************************************************************************** template - bool operator ==(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator ==(const U& lhs, const etl::optional& rhs) { return bool(rhs) ? rhs.value() == lhs : false; } @@ -755,7 +1067,7 @@ namespace etl /// Inequality operator. cppreference 22 //************************************************************************** template - bool operator !=(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator !=(const U& lhs, const etl::optional& rhs) { return !(lhs == rhs); } @@ -764,7 +1076,7 @@ namespace etl /// Less than operator. cppreference 23 //*************************************************************************** template - bool operator <(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator <(const etl::optional& lhs, const U& rhs) { return bool(lhs) ? lhs.value() < rhs : true; } @@ -773,7 +1085,7 @@ namespace etl /// Less than operator. cppreference 24 //*************************************************************************** template - bool operator <(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator <(const U& lhs, const etl::optional& rhs) { return bool(rhs) ? lhs < rhs.value() : false; } @@ -782,7 +1094,7 @@ namespace etl /// Less than equal operator. cppreference 25 //*************************************************************************** template - bool operator <=(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator <=(const etl::optional& lhs, const U& rhs) { return bool(lhs) ? lhs.value() <= rhs : true; } @@ -791,7 +1103,7 @@ namespace etl /// Less than equal operator. cppreference 26 //*************************************************************************** template - bool operator <=(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator <=(const U& lhs, const etl::optional& rhs) { return bool(rhs) ? lhs <= rhs.value() : false; } @@ -800,7 +1112,7 @@ namespace etl /// Greater than operator. cppreference 27 //*************************************************************************** template - bool operator >(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator >(const etl::optional& lhs, const U& rhs) { return bool(lhs) ? lhs.value() > rhs : false; } @@ -809,7 +1121,7 @@ namespace etl /// Greater than operator. cppreference 28 //*************************************************************************** template - bool operator >(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator >(const U& lhs, const etl::optional& rhs) { return bool(rhs) ? lhs > rhs.value() : true; } @@ -818,7 +1130,7 @@ namespace etl /// Greater than equal operator. cppreference 29 //*************************************************************************** template - bool operator >=(const etl::optional& lhs, const U& rhs) + ETL_CONSTEXPR14 bool operator >=(const etl::optional& lhs, const U& rhs) { return bool(lhs) ? lhs.value() >= rhs : false; } @@ -827,7 +1139,7 @@ namespace etl /// Greater than equal operator. cppreference 30 //*************************************************************************** template - bool operator >=(const U& lhs, const etl::optional& rhs) + ETL_CONSTEXPR14 bool operator >=(const U& lhs, const etl::optional& rhs) { return bool(rhs) ? lhs >= rhs.value() : true; } @@ -836,17 +1148,25 @@ namespace etl /// Make an optional. //*************************************************************************** template - etl::optional::type> make_optional(T& value) + ETL_CONSTEXPR14 etl::optional::type> make_optional(T& value) { return etl::optional::type>(value); } + + //*************************************************************************** + /// Template deduction guides. + //*************************************************************************** +#if ETL_CPP17_SUPPORTED + template + optional(T) -> optional; +#endif } //************************************************************************* /// Swaps the values. //************************************************************************* template -void swap(etl::optional& lhs, etl::optional& rhs) +ETL_CONSTEXPR14 void swap(etl::optional& lhs, etl::optional& rhs) { lhs.swap(rhs); } diff --git a/src/etl/parameter_pack.h b/src/etl/parameter_pack.h index a439dad..e576045 100644 --- a/src/etl/parameter_pack.h +++ b/src/etl/parameter_pack.h @@ -29,11 +29,11 @@ SOFTWARE. #ifndef ETL_PARAMETER_PACK #define ETL_PARAMETER_PACK -#include - #include "platform.h" #include "type_traits.h" +#include + #if ETL_CPP11_NOT_SUPPORTED #if !defined(ETL_IN_UNIT_TEST) #error NOT SUPPORTED FOR C++03 OR BELOW diff --git a/src/etl/pearson.h b/src/etl/pearson.h index f5bf064..7d740fd 100644 --- a/src/etl/pearson.h +++ b/src/etl/pearson.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_PEARSON_INCLUDED #define ETL_PEARSON_INCLUDED -#include - #include "platform.h" #include "static_assert.h" #include "type_traits.h" @@ -40,6 +38,8 @@ SOFTWARE. #include "array.h" #include "iterator.h" +#include + ETL_STATIC_ASSERT(ETL_USING_8BIT_TYPES, "This file does not currently support targets with no 8bit type"); #if defined(ETL_COMPILER_KEIL) diff --git a/src/etl/placement_new.h b/src/etl/placement_new.h index 882d870..d2aff1a 100644 --- a/src/etl/placement_new.h +++ b/src/etl/placement_new.h @@ -37,7 +37,11 @@ SOFTWARE. // Figure out if we can use the standard library header, if haven't already done so in etl_profile.h #if !defined(ETL_USING_STD_NEW) #if defined(__has_include) - #define ETL_USING_STD_NEW __has_include() + #if __has_include() + #define ETL_USING_STD_NEW 1 + #else + #define ETL_USING_STD_NEW 0 + #endif #elif (defined(ARDUINO) && defined(__AVR__)) #define ETL_USING_STD_NEW 0 #else diff --git a/src/etl/platform.h b/src/etl/platform.h index bcebd65..4bb3a43 100644 --- a/src/etl/platform.h +++ b/src/etl/platform.h @@ -31,6 +31,21 @@ SOFTWARE. #ifndef ETL_PLATFORM_INCLUDED #define ETL_PLATFORM_INCLUDED +//************************************* +// Enable all limit macros +// Note: This macro must be defined before the first include of stdint.h +#if !defined(__STDC_LIMIT_MACROS) + #define __STDC_LIMIT_MACROS +#endif + +//************************************* +// Enable all constant macros +// Note: This macro must be defined before the first include of stdint.h +#if !defined(__STDC_CONSTANT_MACROS) + #define __STDC_CONSTANT_MACROS +#endif + +#include #include #include @@ -195,9 +210,17 @@ SOFTWARE. //************************************* // Indicate if nullptr is used. #if ETL_NO_NULLPTR_SUPPORT -#define ETL_HAS_NULLPTR 0 + #define ETL_HAS_NULLPTR 0 +#else + #define ETL_HAS_NULLPTR 1 +#endif + +//************************************* +// Indicate if legacy bitset is used. +#if defined(ETL_USE_LEGACY_BITSET) + #define ETL_USING_LEGACY_BITSET 1 #else -#define ETL_HAS_NULLPTR 1 + #define ETL_USING_LEGACY_BITSET 0 #endif //************************************* @@ -212,17 +235,20 @@ SOFTWARE. // The macros below are dependent on the profile. // C++11 #if ETL_USING_CPP11 && !defined(ETL_FORCE_NO_ADVANCED_CPP) - #define ETL_CONSTEXPR constexpr - #define ETL_CONSTANT constexpr - #define ETL_DELETE = delete - #define ETL_EXPLICIT explicit - #define ETL_OVERRIDE override - #define ETL_FINAL final - #define ETL_NORETURN [[noreturn]] - #define ETL_MOVE(x) etl::move(x) + #define ETL_CONSTEXPR constexpr + #define ETL_CONSTANT constexpr + #define ETL_STATIC_CONSTANT constexpr + #define ETL_DELETE = delete + #define ETL_EXPLICIT explicit + #define ETL_OVERRIDE override + #define ETL_FINAL final + #define ETL_NORETURN [[noreturn]] + #define ETL_MOVE(x) etl::move(x) + #define ETL_ENUM_CLASS(name) enum class name + #define ETL_ENUM_CLASS_TYPE(name, type) enum class name : type #if ETL_USING_EXCEPTIONS - #define ETL_NOEXCEPT noexcept + #define ETL_NOEXCEPT noexcept #define ETL_NOEXCEPT_EXPR(expression) noexcept(expression) #else #define ETL_NOEXCEPT @@ -230,7 +256,8 @@ SOFTWARE. #endif #else #define ETL_CONSTEXPR - #define ETL_CONSTANT const + #define ETL_CONSTANT const + #define ETL_STATIC_CONSTANT static const #define ETL_DELETE #define ETL_EXPLICIT #define ETL_OVERRIDE @@ -239,13 +266,15 @@ SOFTWARE. #define ETL_NOEXCEPT #define ETL_NOEXCEPT_EXPR(expression) #define ETL_MOVE(x) x + #define ETL_ENUM_CLASS(name) enum name + #define ETL_ENUM_CLASS_TYPE(name, type) enum name #endif //************************************* // C++14 #if ETL_USING_CPP14 && !defined(ETL_FORCE_NO_ADVANCED_CPP) - #define ETL_CONSTEXPR14 constexpr - #define ETL_DEPRECATED [[deprecated]] + #define ETL_CONSTEXPR14 constexpr + #define ETL_DEPRECATED [[deprecated]] #define ETL_DEPRECATED_REASON(reason) [[deprecated(reason)]] #else #define ETL_CONSTEXPR14 @@ -274,11 +303,11 @@ SOFTWARE. //************************************* // C++20 #if ETL_USING_CPP20 && !defined(ETL_FORCE_NO_ADVANCED_CPP) - #define ETL_LIKELY [[likely]] - #define ETL_UNLIKELY [[unlikely]] - #define ETL_CONSTEXPR20 constexpr - #define ETL_CONSTEVAL consteval - #define ETL_CONSTINIT constinit + #define ETL_LIKELY [[likely]] + #define ETL_UNLIKELY [[unlikely]] + #define ETL_CONSTEXPR20 constexpr + #define ETL_CONSTEVAL consteval + #define ETL_CONSTINIT constinit #define ETL_NO_UNIQUE_ADDRESS [[no_unique_address]] #else #define ETL_LIKELY @@ -320,7 +349,7 @@ SOFTWARE. //************************************* // Determine if the ETL can use std::array #if !defined(ETL_HAS_STD_ARRAY) - #if ETL_USING_CPP11 && ETL_USING_STL + #if ETL_USING_STL && ETL_USING_CPP11 #define ETL_HAS_STD_ARRAY 1 #else #define ETL_HAS_STD_ARRAY 0 @@ -331,7 +360,8 @@ SOFTWARE. // Determine if the ETL should support atomics. #if defined(ETL_NO_ATOMICS) || \ defined(ETL_TARGET_DEVICE_ARM_CORTEX_M0) || \ - defined(ETL_TARGET_DEVICE_ARM_CORTEX_M0_PLUS) + defined(ETL_TARGET_DEVICE_ARM_CORTEX_M0_PLUS) || \ + defined(__STDC_NO_ATOMICS__) #define ETL_HAS_ATOMIC 0 #else #if ((ETL_USING_CPP11 && (ETL_USING_STL || defined(ETL_IN_UNIT_TEST))) || \ @@ -369,12 +399,6 @@ SOFTWARE. #define ETL_HAS_INITIALIZER_LIST 0 #endif -//************************************* -// Set force flag to 0 if not already set. -#if !defined(ETL_FORCE_CONSTEXPR_ALGORITHMS) - #define ETL_FORCE_CONSTEXPR_ALGORITHMS 0 -#endif - //************************************* // Check for availability of certain builtins #include "profiles/determine_builtin_support.h" @@ -388,7 +412,11 @@ namespace etl namespace traits { // Documentation: https://www.etlcpp.com/etl_traits.html + // General + static ETL_CONSTANT long cplusplus = __cplusplus; + static ETL_CONSTANT int language_standard = ETL_LANGUAGE_STANDARD; + // Using... static ETL_CONSTANT bool using_stl = (ETL_USING_STL == 1); static ETL_CONSTANT bool using_stlport = (ETL_USING_STLPORT == 1); static ETL_CONSTANT bool using_cpp11 = (ETL_USING_CPP11 == 1); @@ -396,9 +424,6 @@ namespace etl static ETL_CONSTANT bool using_cpp17 = (ETL_USING_CPP17 == 1); static ETL_CONSTANT bool using_cpp20 = (ETL_USING_CPP20 == 1); static ETL_CONSTANT bool using_cpp23 = (ETL_USING_CPP23 == 1); - static ETL_CONSTANT long cplusplus = __cplusplus; - static ETL_CONSTANT int language_standard = ETL_LANGUAGE_STANDARD; - static ETL_CONSTANT bool using_exceptions = (ETL_USING_EXCEPTIONS == 1); static ETL_CONSTANT bool using_gcc_compiler = (ETL_USING_GCC_COMPILER == 1); static ETL_CONSTANT bool using_microsoft_compiler = (ETL_USING_MICROSOFT_COMPILER == 1); static ETL_CONSTANT bool using_arm5_compiler = (ETL_USING_ARM5_COMPILER == 1); @@ -410,6 +435,10 @@ namespace etl static ETL_CONSTANT bool using_intel_compiler = (ETL_USING_INTEL_COMPILER == 1); static ETL_CONSTANT bool using_texas_instruments_compiler = (ETL_USING_TEXAS_INSTRUMENTS_COMPILER == 1); static ETL_CONSTANT bool using_generic_compiler = (ETL_USING_GENERIC_COMPILER == 1); + static ETL_CONSTANT bool using_legacy_bitset = (ETL_USING_LEGACY_BITSET == 1); + static ETL_CONSTANT bool using_exceptions = (ETL_USING_EXCEPTIONS == 1); + + // Has... static ETL_CONSTANT bool has_initializer_list = (ETL_HAS_INITIALIZER_LIST == 1); static ETL_CONSTANT bool has_8bit_types = (ETL_USING_8BIT_TYPES == 1); static ETL_CONSTANT bool has_64bit_types = (ETL_USING_64BIT_TYPES == 1); @@ -426,7 +455,10 @@ namespace etl static ETL_CONSTANT bool has_ivector_repair = (ETL_HAS_IVECTOR_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); + + // Is... static ETL_CONSTANT bool is_debug_build = (ETL_IS_DEBUG_BUILD == 1); + } } diff --git a/src/etl/poly_span.h b/src/etl/poly_span.h index 6208cc6..79d3f32 100644 --- a/src/etl/poly_span.h +++ b/src/etl/poly_span.h @@ -45,7 +45,7 @@ SOFTWARE. #include "private/dynamic_extent.h" -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 #include #endif @@ -344,7 +344,7 @@ namespace etl ETL_STATIC_ASSERT((etl::is_base_of::value || etl::is_same::value), "TBase not a base of the data type"); } -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //************************************************************************* /// Construct from std::array. //************************************************************************* @@ -712,7 +712,7 @@ namespace etl ETL_STATIC_ASSERT((etl::is_base_of::value || etl::is_same::value), "TBase not a base of the data type"); } -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //************************************************************************* /// Construct from std::array. //************************************************************************* diff --git a/src/etl/power.h b/src/etl/power.h index c539835..7816dd8 100644 --- a/src/etl/power.h +++ b/src/etl/power.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_POW_INCLUDED #define ETL_POW_INCLUDED -#include -#include - #include "platform.h" #include "log.h" +#include +#include + ///\defgroup power power /// power : Calculates N to the power POWER. ///\ingroup maths diff --git a/src/etl/priority_queue.h b/src/etl/priority_queue.h index 766d669..46be290 100644 --- a/src/etl/priority_queue.h +++ b/src/etl/priority_queue.h @@ -31,10 +31,7 @@ SOFTWARE. #ifndef ETL_PRIORITY_QUEUE_INCLUDED #define ETL_PRIORITY_QUEUE_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "utility.h" #include "functional.h" @@ -45,6 +42,8 @@ SOFTWARE. #include "error_handler.h" #include "exception.h" +#include + //***************************************************************************** ///\defgroup queue queue /// A priority queue with the capacity defined at compile time, diff --git a/src/etl/private/addressof.h b/src/etl/private/addressof.h new file mode 100644 index 0000000..67fc8d2 --- /dev/null +++ b/src/etl/private/addressof.h @@ -0,0 +1,61 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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_ADDRESSOF_INCLUDED +#define ETL_ADDRESSOF_INCLUDED + +#include "../platform.h" + +#if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL + #include +#endif + +///\defgroup memory memory +///\ingroup etl + +namespace etl +{ + //***************************************************************************** + /// Gets the address of an object. + /// https://en.cppreference.com/w/cpp/memory/addressof + ///\ingroup memory + //***************************************************************************** + template + ETL_CONSTEXPR17 T* addressof(T& t) + { +#if ETL_USING_STL && ETL_USING_CPP11 + return std::addressof(t); +#else + return reinterpret_cast(&const_cast(reinterpret_cast(t))); +#endif + } +} + +#endif diff --git a/src/etl/private/bitset_legacy.h b/src/etl/private/bitset_legacy.h new file mode 100644 index 0000000..53aa382 --- /dev/null +++ b/src/etl/private/bitset_legacy.h @@ -0,0 +1,1490 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2014 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_BITSET_LEGACY_INCLUDED +#define ETL_BITSET_LEGACY_INCLUDED + +#include "../platform.h" +#include "../algorithm.h" +#include "../iterator.h" +#include "../integral_limits.h" +#include "../algorithm.h" +#include "../nullptr.h" +#include "../log.h" +#include "../exception.h" +#include "../integral_limits.h" +#include "../binary.h" +#include "../char_traits.h" +#include "../static_assert.h" +#include "../error_handler.h" +#include "../span.h" +#include "../string.h" + +#include +#include +#include + +#include "minmax_push.h" + +#if defined(ETL_COMPILER_KEIL) +#pragma diag_suppress 1300 +#endif + +#if ETL_USING_CPP11 + #define ETL_STR(x) x + #define ETL_STRL(x) L##x + #define ETL_STRu(x) u##x + #define ETL_STRU(x) U##x +#else + #define ETL_STR(x) x + #define ETL_STRL(x) x + #define ETL_STRu(x) x + #define ETL_STRU(x) x +#endif + +//***************************************************************************** +///\defgroup bitset bitset +/// Similar to std::bitset but without requiring std::string. +///\ingroup containers +//***************************************************************************** + +namespace etl +{ + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset null pointer exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_nullptr : public bitset_exception + { + public: + + bitset_nullptr(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:null pointer", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset type_too_small exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_type_too_small : public bitset_exception + { + public: + + bitset_type_too_small(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"B"), file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset overflow exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_overflow : public bitset_exception + { + public: + + bitset_overflow(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:overflow", ETL_BITSET_FILE_ID"C"), file_name_, line_number_) + { + } + }; + + //************************************************************************* + /// The base class for etl::bitset + ///\ingroup bitset + //************************************************************************* + class ibitset + { + protected: + + // The type used for each element in the array. +#if !defined(ETL_BITSET_ELEMENT_TYPE) + #define ETL_BITSET_ELEMENT_TYPE uint_least8_t +#endif + + public: + + typedef typename etl::make_unsigned::type element_type; + typedef element_type element_t; // Backward compatibility + + static ETL_CONSTANT element_type ALL_SET = etl::integral_limits::max; + static ETL_CONSTANT element_type ALL_CLEAR = 0; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + +#if ETL_USING_CPP11 + typedef etl::span span_type; + typedef etl::span const_span_type; +#endif + + enum + { + npos = etl::integral_limits::max + }; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class ibitset; + + //******************************* + /// Conversion operator. + //******************************* + operator bool() const + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + bit_reference& operator = (bool b) + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + bit_reference& operator = (const bit_reference& r) + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + bit_reference& flip() + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + bool operator~() const + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + bit_reference() + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + bit_reference(ibitset& r_bitset, size_t position_) + : p_bitset(&r_bitset) + , position(position_) + { + } + + ibitset* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + size_t size() const + { + return Active_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + size_t count() const + { + size_t n = 0UL; + + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + n += etl::count_bits(pdata[i]); + } + + return n; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + bool test(size_t position) const + { + size_t index; + element_type mask; + + if (Number_Of_Elements == 0) + { + return false; + } + else if (Number_Of_Elements == 1) + { + index = 0; + mask = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + mask = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + return (pdata[index] & mask) != 0; + } + + //************************************************************************* + /// Set all bits. + //************************************************************************* + ibitset& set() + { + ::memset(pdata, 0xFF, Number_Of_Elements); + pdata[Number_Of_Elements - 1U] = Top_Mask; + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ibitset& set(size_t position, bool value = true) + { + size_t index; + element_type bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + if (value) + { + pdata[index] |= bit; + } + else + { + pdata[index] &= ~bit; + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ibitset& from_string(const char* text) + { + reset(); + + size_t i = etl::min(Active_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRL('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ibitset& from_string(const wchar_t* text) + { + reset(); + + size_t i = etl::min(Active_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRL('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ibitset& from_string(const char16_t* text) + { + reset(); + + size_t i = etl::min(Active_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRu('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ibitset& from_string(const char32_t* text) + { + reset(); + + size_t i = etl::min(Active_Bits, etl::strlen(text)); + + while (i > 0) + { + set(--i, *text++ == ETL_STRU('1')); + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ibitset& set(const char* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a wstring. + //************************************************************************* + ibitset& set(const wchar_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u16string. + //************************************************************************* + ibitset& set(const char16_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u32string. + //************************************************************************* + ibitset& set(const char32_t* text) + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Put to a value. + //************************************************************************* + template + typename etl::enable_if::value, T>::type + value() const + { + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element); + + ETL_ASSERT_AND_RETURN_VALUE(OK, ETL_ERROR(etl::bitset_type_too_small), T(0)); + + if (OK) + { + uint_least8_t shift = 0U; + + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + v |= T(typename etl::make_unsigned::type(pdata[i]) << shift); + shift += uint_least8_t(Bits_Per_Element); + } + } + + return v; + } + + //************************************************************************* + /// Put to a unsigned long. + //************************************************************************* + unsigned long to_ulong() const + { + return value(); + } + + //************************************************************************* + /// Put to a unsigned long long. + //************************************************************************* + unsigned long long to_ullong() const + { + return value(); + } + + //************************************************************************* + /// Resets the bitset. + //************************************************************************* + ibitset& reset() + { + ::memset(pdata, 0x00, Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ibitset& reset(size_t position) + { + size_t index; + element_type bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] &= ~bit; + + return *this; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ibitset& flip() + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] = ~pdata[i]; + } + + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ibitset& flip(size_t position) + { + if (position < Active_Bits) + { + size_t index; + element_type bit; + + if (Number_Of_Elements == 0) + { + return *this; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pdata[index] ^= bit; + } + + return *this; + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + bool all() const + { + if (Number_Of_Elements == 0UL) + { + return true; + } + + // All but the last. + for (size_t i = 0UL; i < (Number_Of_Elements - 1U); ++i) + { + if (pdata[i] != ALL_SET) + { + return false; + } + } + + // The last. + if (pdata[Number_Of_Elements - 1U] != (ALL_SET & Top_Mask)) + { + return false; + } + + return true; + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + bool any() const + { + return !none(); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + bool none() const + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + if (pdata[i] != 0) + { + return false; + } + } + + return true; + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or Number_Of_Elements if none were found. + //************************************************************************* + size_t find_first(bool state) const + { + return find_next(state, 0); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or ibitset::npos if none were found. + //************************************************************************* + size_t find_next(bool state, size_t position) const + { + // Where to start. + size_t index; + size_t bit; + + if (Number_Of_Elements == 0) + { + return ibitset::npos; + } + else if (Number_Of_Elements == 1) + { + index = 0; + bit = position; + } + else + { + index = position >> log2::value; + bit = position & (Bits_Per_Element - 1); + } + + element_type mask = 1 << bit; + + // For each element in the bitset... + while (index < Number_Of_Elements) + { + element_type value = pdata[index]; + + // Needs checking? + if ((state && (value != ALL_CLEAR)) || + (!state && (value != ALL_SET))) + { + // For each bit in the element... + while ((bit < Bits_Per_Element) && (position < Active_Bits)) + { + // Equal to the required state? + if (((value & mask) != 0) == state) + { + return position; + } + + // Move on to the next bit. + mask <<= 1; + ++position; + ++bit; + } + } + else + { + position += (Bits_Per_Element - bit); + } + + // Start at the beginning for all other elements. + bit = 0; + mask = 1; + + ++index; + } + + return ibitset::npos; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + bool operator[] (size_t position) const + { + return test(position); + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + bit_reference operator [] (size_t position) + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ibitset& operator &=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] &= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ibitset& operator |=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] |= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ibitset& operator ^=(const ibitset& other) + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] ^= other.pdata[i]; + } + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ibitset& operator<<=(size_t shift) + { + if (shift >= Active_Bits) + { + reset(); + } + else if (Number_Of_Elements != 0UL) + { + // Just one element? + if (Number_Of_Elements == 1UL) + { + pdata[0] <<= shift; + } + else if (shift == Bits_Per_Element) + { + etl::copy_backward(pdata, pdata + Number_Of_Elements - 1U, pdata + Number_Of_Elements); + pdata[0] = 0; + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); + + // Where we are shifting from. + int src_index = int(Number_Of_Elements - (shift / Bits_Per_Element) - 1U); + + // Where we are shifting to. + int dst_index = int(Number_Of_Elements - 1U); + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_type msb_mask = etl::integral_limits::max - lsb_mask; + const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift); + + // First lsb. + element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + + // Now do the shifting. + while (src_index >= 0) + { + // Shift msb. + element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); + pdata[dst_index] = pdata[dst_index] | msb; + --dst_index; + + // Shift lsb. + element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); + pdata[dst_index] = lsb; + --src_index; + } + + // Clear the remaining bits. + // First lsb. + pdata[dst_index] &= lsb_shifted_mask; + --dst_index; + + // The other remaining bytes on the right. + while (dst_index >= 0) + { + pdata[dst_index] = 0; + --dst_index; + } + } + + // Truncate any bits shifted to the left. + clear_unused_bits_in_msb(); + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ibitset& operator>>=(size_t shift) + { + if (shift >= Active_Bits) + { + reset(); + } + else if (Number_Of_Elements != 0UL) + { + // Just one element? + if (Number_Of_Elements == 1UL) + { + pdata[0] >>= shift; + } + // Shift is the size of an element? + else if (shift == Bits_Per_Element) + { + etl::copy(pdata + 1, pdata + Number_Of_Elements, pdata); + pdata[Number_Of_Elements - 1U] = 0; + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = shift % Bits_Per_Element; + + // Where we are shifting from. + int src_index = int(shift / Bits_Per_Element); + + // Where we are shifting to. + int dst_index = 0; + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_type msb_mask = etl::integral_limits::max - lsb_mask; + const element_type msb_shifted_mask = element_type(msb_mask >> msb_shift); + + // Now do the shifting. + while (src_index < int(Number_Of_Elements - 1)) + { + // Shift msb. + element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); + ++src_index; + + // Shift lsb. + element_type lsb = element_type((pdata[src_index] & lsb_mask) << lsb_shift); + + // Combine them. + pdata[dst_index] = lsb | msb; + ++dst_index; + } + + // Final msb. + element_type msb = element_type((pdata[src_index] & msb_mask) >> msb_shift); + pdata[dst_index] = msb; + + // Clear the remaining bits. + // First msb. + pdata[dst_index] &= msb_shifted_mask; + ++dst_index; + + // The other remaining bytes. + while (dst_index < int(Number_Of_Elements)) + { + pdata[dst_index] = 0; + ++dst_index; + } + } + } + + return *this; + } + + //************************************************************************* + /// operator = + //************************************************************************* + ibitset& operator =(const ibitset& other) + { + if (this != &other) + { + etl::copy_n(other.pdata, Number_Of_Elements, pdata); + } + + return *this; + } + + //************************************************************************* + /// swap + //************************************************************************* + void swap(ibitset& other) + { + etl::swap_ranges(pdata, pdata + Number_Of_Elements, other.pdata); + } + +#if ETL_USING_CPP11 + //************************************************************************* + /// span + /// Returns a span of the underlying data. + //************************************************************************* + span_type span() + { + return span_type(pdata, pdata + Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying data. + //************************************************************************* + const_span_type span() const + { + return const_span_type(pdata, pdata + Number_Of_Elements); + } +#endif + + protected: + + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ibitset& initialise(unsigned long long value) + { + reset(); + + const size_t Shift = (integral_limits::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element; + + // Can we do it in one hit? + if (Shift == 0) + { + pdata[0] = element_type(value); + } + else + { + size_t i = 0UL; + + while ((value != 0) && (i < Number_Of_Elements)) + { + pdata[i++] = value & ALL_SET; + value = value >> Shift; + } + } + + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Invert + //************************************************************************* + void invert() + { + for (size_t i = 0UL; i < Number_Of_Elements; ++i) + { + pdata[i] = ~pdata[i]; + } + + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Gets a reference to the specified bit. + //************************************************************************* + bit_reference get_bit_reference(size_t position) + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Constructor. + //************************************************************************* + ibitset(size_t nbits_, size_t size_, element_type* pdata_) + : Active_Bits(nbits_) + , Number_Of_Elements(size_) + , pdata(pdata_) + { + const size_t allocated_bits = Number_Of_Elements * Bits_Per_Element; + const size_t top_mask_shift = ((Bits_Per_Element - (allocated_bits - Active_Bits)) % Bits_Per_Element); + Top_Mask = element_type(top_mask_shift == 0 ? ALL_SET : ~(ALL_SET << top_mask_shift)); + } + + //************************************************************************* + /// Compare bitsets. + //************************************************************************* + static bool is_equal(const ibitset& lhs, const ibitset&rhs) + { + return etl::equal(lhs.pdata, lhs.pdata + lhs.Number_Of_Elements, rhs.pdata); + } + + element_type Top_Mask; + + private: + + //************************************************************************* + /// Correct the unused top bits after bit manipulation. + //************************************************************************* + void clear_unused_bits_in_msb() + { + pdata[Number_Of_Elements - 1U] &= Top_Mask; + } + + // Disable copy construction. + ibitset(const ibitset&); + + const size_t Active_Bits; + const size_t Number_Of_Elements; + element_type* pdata; + + //************************************************************************* + /// Destructor. + //************************************************************************* +#if defined(ETL_POLYMORPHIC_BITSET) || defined(ETL_POLYMORPHIC_CONTAINERS) + public: + virtual ~ibitset() + { + } +#else + protected: + ~ibitset() + { + } +#endif + }; + + //************************************************************************* + /// The class emulates an array of bool elements, but optimized for space allocation. + /// Will accommodate any number of bits. + /// Does not use std::string. + ///\tparam MaxN The number of bits. + ///\ingroup bitset + //************************************************************************* + template + class bitset : public etl::ibitset + { + + static ETL_CONSTANT size_t Array_Size = (MaxN % Bits_Per_Element == 0) ? MaxN / Bits_Per_Element : MaxN / Bits_Per_Element + 1; + + public: + + static ETL_CONSTANT size_t ALLOCATED_BITS = Array_Size * Bits_Per_Element; + static ETL_CONSTANT size_t Allocated_Bits = ALLOCATED_BITS; + + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + bitset() + : etl::ibitset(MaxN, Array_Size, data) + { + reset(); + } + + //************************************************************************* + /// Copy constructor. + //************************************************************************* + bitset(const bitset& other) + : etl::ibitset(MaxN, Array_Size, data) + { + etl::copy_n(other.data, Array_Size, data); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + bitset(unsigned long long value) + : etl::ibitset(MaxN, Array_Size, data) + { + initialise(value); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const wchar_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char16_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + bitset(const char32_t* text) + : etl::ibitset(MaxN, Array_Size, data) + { + set(text); + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + bitset& set() + { + etl::ibitset::set(); + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + bitset& set(size_t position, bool value = true) + { + etl::ibitset::set(position, value); + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const wchar_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char16_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& set(const char32_t* text) + { + ETL_ASSERT_AND_RETURN_VALUE(text != 0, ETL_ERROR(bitset_nullptr), *this); + etl::ibitset::set(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + bitset& from_string(const char* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + bitset& from_string(const wchar_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + bitset& from_string(const char16_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + bitset& from_string(const char32_t* text) + { + ibitset::from_string(text); + + return *this; + } + + //************************************************************************* + /// Put to a value. + //************************************************************************* + template + typename etl::enable_if::value, T>::type + value() const + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Array_Size * Bits_Per_Element), "Type too small"); + + return ibitset::value(); + } + + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + bitset& reset() + { + ibitset::reset(); + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + bitset& reset(size_t position) + { + etl::ibitset::reset(position); + return *this; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + bitset& flip() + { + ibitset::flip(); + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + bitset& flip(size_t position) + { + etl::ibitset::flip(position); + return *this; + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + TString to_string(typename TString::value_type zero = typename TString::value_type('0'), typename TString::value_type one = typename TString::value_type('1')) const + { + TString result; + + result.resize(MaxN, '\0'); + + ETL_ASSERT_AND_RETURN_VALUE((result.size() == MaxN), ETL_ERROR(etl::bitset_overflow), result); + + for (size_t i = MaxN; i > 0; --i) + { + result[MaxN - i] = test(i - 1) ? one : zero; + } + + return result; + } + + //************************************************************************* + /// operator = + //************************************************************************* + bitset& operator =(const bitset& other) + { + if (this != &other) + { + etl::copy_n(other.data, Array_Size, data); + } + + return *this; + } + + //************************************************************************* + /// operator &= + //************************************************************************* + bitset& operator &=(const bitset& other) + { + etl::ibitset::operator &=(other); + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + bitset& operator |=(const bitset& other) + { + etl::ibitset::operator |=(other); + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + bitset& operator ^=(const bitset& other) + { + ibitset::operator ^=(other); + return *this; + } + + //************************************************************************* + /// operator ~ + //************************************************************************* + bitset operator ~() const + { + etl::bitset temp(*this); + + temp.invert(); + + return temp; + } + + //************************************************************************* + /// operator << + //************************************************************************* + bitset operator<<(size_t shift) const + { + etl::bitset temp(*this); + + temp <<= shift; + + return temp; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + bitset& operator<<=(size_t shift) + { + etl::ibitset::operator <<=(shift); + return *this; + } + + //************************************************************************* + /// operator >> + //************************************************************************* + bitset operator>>(size_t shift) const + { + bitset temp(*this); + + temp >>= shift; + + return temp; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + bitset& operator>>=(size_t shift) + { + etl::ibitset::operator >>=(shift); + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend bool operator == (const bitset& lhs, const bitset& rhs) + { + return etl::ibitset::is_equal(lhs, rhs); + } + + private: + + element_type data[Array_Size > 0U ? Array_Size : 1U]; + }; + + //*************************************************************************** + /// operator & + ///\ingroup bitset + //*************************************************************************** + template + bitset operator & (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp &= rhs; + return temp; + } + + //*************************************************************************** + /// operator | + ///\ingroup bitset + //*************************************************************************** + template + bitset operator | (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp |= rhs; + return temp; + } + + //*************************************************************************** + /// operator ^ + ///\ingroup bitset + //*************************************************************************** + template + bitset operator ^ (const bitset& lhs, const bitset& rhs) + { + bitset temp(lhs); + temp ^= rhs; + return temp; + } + + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + bool operator != (const bitset& lhs, const bitset& rhs) + { + return !(lhs == rhs); + } +} + +//************************************************************************* +/// swap +//************************************************************************* +template +void swap(etl::bitset& lhs, etl::bitset& rhs) +{ + lhs.swap(rhs); +} + +#include "minmax_pop.h" + +#endif diff --git a/src/etl/private/bitset_new.h b/src/etl/private/bitset_new.h new file mode 100644 index 0000000..fc387cd --- /dev/null +++ b/src/etl/private/bitset_new.h @@ -0,0 +1,3917 @@ +///\file +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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_BITSET_NEW_INCLUDED +#define ETL_BITSET_NEW_INCLUDED + +#include "../platform.h" +#include "../algorithm.h" +#include "../iterator.h" +#include "../integral_limits.h" +#include "../algorithm.h" +#include "../nullptr.h" +#include "../log.h" +#include "../exception.h" +#include "../integral_limits.h" +#include "../binary.h" +#include "../char_traits.h" +#include "../static_assert.h" +#include "../error_handler.h" +#include "../span.h" +#include "../string.h" + +#include +#include +#include + +#include "minmax_push.h" + +#if defined(ETL_COMPILER_KEIL) +#pragma diag_suppress 1300 +#endif + +#if ETL_USING_CPP11 + #define ETL_STR(x) x + #define ETL_STRL(x) L##x + #define ETL_STRu(x) u##x + #define ETL_STRU(x) U##x +#else + #define ETL_STR(x) x + #define ETL_STRL(x) x + #define ETL_STRu(x) x + #define ETL_STRU(x) x +#endif + +//***************************************************************************** +///\defgroup bitset bitset +/// Similar to std::bitset but without requiring std::string. +///\ingroup containers +//***************************************************************************** + +namespace etl +{ + struct bitset_constants + { + static ETL_CONSTANT size_t npos = etl::integral_limits::max; + }; + + //*************************************************************************** + /// Exception base for bitset + ///\ingroup bitset + //*************************************************************************** + class bitset_exception : public etl::exception + { + public: + + bitset_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Bitset type_too_small exception. + ///\ingroup bitset + //*************************************************************************** + class bitset_string_too_small : public bitset_exception + { + public: + + bitset_string_too_small(string_type file_name_, numeric_type line_number_) + : bitset_exception(ETL_ERROR_TEXT("bitset:type_too_small", ETL_BITSET_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //************************************************************************* + /// The implementation class for multi-element etl::bitset + ///\ingroup bitset + //************************************************************************* + template + class bitset_impl : public bitset_constants + { + public: + + typedef typename etl::make_unsigned::type element_type; + + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + static ETL_CONSTANT element_type All_Set_Element = etl::integral_limits::max; + static ETL_CONSTANT element_type All_Clear_Element = element_type(0); + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count(const_pointer pbuffer, size_t number_of_elements) const ETL_NOEXCEPT + { + size_t n = 0UL; + + for (size_t i = 0UL; i < number_of_elements; ++i) + { + n += etl::count_bits(pbuffer[i]); + } + + return n; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(const_pointer pbuffer, size_t number_of_elements, size_t position) const ETL_NOEXCEPT + { + size_t index = 0U; + element_type mask = element_type(0); + + if (number_of_elements == 1U) + { + index = 0; + mask = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + mask = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + return (pbuffer[index] & mask) != 0; + } + + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pbuffer, size_t number_of_elements, size_t position, bool value = true) ETL_NOEXCEPT + { + size_t index = 0; + element_type bit = 0; + + if (number_of_elements == 0) + { + return; + } + else if (number_of_elements == 1U) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + if (value) + { + pbuffer[index] |= bit; + } + else + { + pbuffer[index] &= ~bit; + } + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 void from_string(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + etl::fill_n(pbuffer, number_of_elements, All_Clear_Element); + } + else + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pbuffer[element_index++] = All_Clear_Element; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pbuffer, number_of_elements, --i, *text++ == ETL_STR('1')); + } + } + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ETL_CONSTEXPR14 void from_string(pointer pbuffer, size_t number_of_elements, size_t total_bits, const wchar_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + etl::fill_n(pbuffer, number_of_elements, All_Clear_Element); + } + else + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pbuffer[element_index++] = All_Clear_Element; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pbuffer, number_of_elements, --i, *text++ == ETL_STRL('1')); + } + } + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ETL_CONSTEXPR14 void from_string(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char16_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + etl::fill_n(pbuffer, number_of_elements, All_Clear_Element); + } + else + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pbuffer[element_index++] = All_Clear_Element; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pbuffer, number_of_elements, --i, *text++ == ETL_STRu('1')); + } + } + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ETL_CONSTEXPR14 void from_string(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char32_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + etl::fill_n(pbuffer, number_of_elements, All_Clear_Element); + } + else + { + size_t string_length = etl::strlen(text); + size_t element_index = etl::min(number_of_elements - 1U, (string_length / Bits_Per_Element)); + + // Only reset elements we need to. + while (element_index != number_of_elements) + { + pbuffer[element_index++] = All_Clear_Element; + } + + // Build from the string. + size_t i = etl::min(total_bits, string_length); + + while (i > 0) + { + set(pbuffer, number_of_elements, --i, *text++ == ETL_STRU('1')); + } + } + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char* text) ETL_NOEXCEPT + { + from_string(pbuffer, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a wstring. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pbuffer, size_t number_of_elements, size_t total_bits, const wchar_t* text) ETL_NOEXCEPT + { + from_string(pbuffer, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a u16string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char16_t* text) ETL_NOEXCEPT + { + from_string(pbuffer, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Set from a u32string. + //************************************************************************* + ETL_CONSTEXPR14 void set(pointer pbuffer, size_t number_of_elements, size_t total_bits, const char32_t* text) ETL_NOEXCEPT + { + from_string(pbuffer, number_of_elements, total_bits, text); + } + + //************************************************************************* + /// Get as a value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value(const_pointer pbuffer, size_t number_of_elements) const ETL_NOEXCEPT + { + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= (number_of_elements * Bits_Per_Element); + + if (OK) + { + uint_least8_t shift = 0U; + + for (size_t i = 0UL; i < number_of_elements; ++i) + { + v |= T(typename etl::make_unsigned::type(pbuffer[i]) << shift); + shift += uint_least8_t(Bits_Per_Element); + } + } + + return v; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void reset(pointer pbuffer, size_t number_of_elements, size_t position) ETL_NOEXCEPT + { + size_t index = 0U; + element_type bit = element_type(0); + + if (number_of_elements == 0) + { + return; + } + else if (number_of_elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> etl::log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pbuffer[index] &= ~bit; + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 void flip(pointer pbuffer, size_t number_of_elements) ETL_NOEXCEPT + { + for (size_t i = 0UL; i < number_of_elements; ++i) + { + pbuffer[i] = ~pbuffer[i]; + } + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 void flip(pointer pbuffer, size_t number_of_elements, size_t total_bits, size_t position) ETL_NOEXCEPT + { + if (position < total_bits) + { + size_t index = 0U; + element_type bit = element_type(0); + + if (number_of_elements == 0) + { + return; + } + else if (number_of_elements == 1) + { + index = 0; + bit = element_type(1) << position; + } + else + { + index = position >> log2::value; + bit = element_type(1) << (position & (Bits_Per_Element - 1)); + } + + pbuffer[index] ^= bit; + } + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all(const_pointer pbuffer, size_t number_of_elements, element_type top_mask) const ETL_NOEXCEPT + { + if (number_of_elements == 0UL) + { + return true; + } + + // All but the last. + for (size_t i = 0UL; i < (number_of_elements - 1U); ++i) + { + if (pbuffer[i] != All_Set_Element) + { + return false; + } + } + + // The last. + if (pbuffer[number_of_elements - 1U] != (All_Set_Element & top_mask)) + { + return false; + } + + return true; + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none(const_pointer pbuffer, size_t number_of_elements) const ETL_NOEXCEPT + { + for (size_t i = 0UL; i < number_of_elements; ++i) + { + if (pbuffer[i] != 0) + { + return false; + } + } + + return true; + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or Number_Of_Elements if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_first(const_pointer pbuffer, size_t number_of_elements, size_t total_bits, bool state) const ETL_NOEXCEPT + { + return find_next(pbuffer, number_of_elements, total_bits, state, 0); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_next(const_pointer pbuffer, size_t number_of_elements, size_t total_bits, bool state, size_t position) const ETL_NOEXCEPT + { + // Where to start. + size_t index = position >> log2::value; + size_t bit = position & (Bits_Per_Element - 1); + + element_type mask = 1 << bit; + + // For each element in the bitset... + while (index < number_of_elements) + { + element_type value = pbuffer[index]; + + // Needs checking? + if ((state && (value != All_Clear_Element)) || + (!state && (value != All_Set_Element))) + { + // For each bit in the element... + while ((bit < Bits_Per_Element) && (position < total_bits)) + { + // Equal to the required state? + if (((value & mask) != 0) == state) + { + return position; + } + + // Move on to the next bit. + mask <<= 1; + ++position; + ++bit; + } + } + else + { + position += (Bits_Per_Element - bit); + } + + // Start at the beginning for all other elements. + bit = 0; + mask = 1; + + ++index; + } + + return npos; + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* + template + ETL_CONSTEXPR14 TString to_string(const_pointer pbuffer, + size_t number_of_elements, + size_t active_bits, + typename TString::value_type zero, + typename TString::value_type one) const + { + TString result; + + result.resize(active_bits, '\0'); + + // Check that the string type can contain the digits. + ETL_ASSERT_AND_RETURN_VALUE(result.size() == active_bits, ETL_ERROR(etl::bitset_string_too_small), result); + + for (size_t i = active_bits; i > 0; --i) + { + result[active_bits - i] = test(pbuffer, number_of_elements, i - 1) ? one : zero; + } + + return result; + } + + //************************************************************************* + /// shift_left_equals + //************************************************************************* + ETL_CONSTEXPR14 void shift_left_equals(pointer pbuffer, size_t number_of_elements, size_t shift) ETL_NOEXCEPT + { + if (number_of_elements == 1U) + { + // Just one element. + pbuffer[0] <<= shift; + } + else if ((shift % Bits_Per_Element) == 0U) + { + // Shift by whole element. + const size_t element_shift = shift / Bits_Per_Element; + etl::copy_backward(pbuffer, pbuffer + number_of_elements - element_shift, pbuffer + number_of_elements); + etl::fill_n(pbuffer, element_shift, All_Clear_Element); + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = Bits_Per_Element - (shift % Bits_Per_Element); + + // Where we are shifting from. + int src_index = int(number_of_elements - (shift / Bits_Per_Element) - 1U); + + // Where we are shifting to. + int dst_index = int(number_of_elements - 1U); + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_type msb_mask = etl::integral_limits::max - lsb_mask; + const element_type lsb_shifted_mask = element_type(lsb_mask << lsb_shift); + + // First lsb. + element_type lsb = element_type((pbuffer[src_index] & lsb_mask) << lsb_shift); + pbuffer[dst_index] = lsb; + --src_index; + + // Now do the shifting. + while (src_index >= 0) + { + // Shift msb. + element_type msb = element_type((pbuffer[src_index] & msb_mask) >> msb_shift); + pbuffer[dst_index] = pbuffer[dst_index] | msb; + --dst_index; + + // Shift lsb. + element_type lsb = element_type((pbuffer[src_index] & lsb_mask) << lsb_shift); + pbuffer[dst_index] = lsb; + --src_index; + } + + // Clear the remaining bits. + // First lsb. + pbuffer[dst_index] &= lsb_shifted_mask; + --dst_index; + + // The other remaining bytes on the right. + while (dst_index >= 0) + { + pbuffer[dst_index] = 0; + --dst_index; + } + } + } + + //************************************************************************* + /// shift_right_equals + //************************************************************************* + ETL_CONSTEXPR14 void shift_right_equals(pointer pbuffer, size_t number_of_elements, size_t shift) ETL_NOEXCEPT + { + if (number_of_elements == 1U) + { + // Just one element. + pbuffer[0] >>= shift; + } + else if ((shift % Bits_Per_Element) == 0U) + { + // Shift by whole elements. + const size_t element_shift = (shift / Bits_Per_Element); + pointer pzeros_begin = etl::copy(pbuffer + element_shift, pbuffer + number_of_elements, pbuffer); + etl::fill_n(pzeros_begin, element_shift, All_Clear_Element); + } + else + { + // The place where the elements are split when shifting. + const size_t split_position = shift % Bits_Per_Element; + + // Where we are shifting from. + int src_index = int(shift / Bits_Per_Element); + + // Where we are shifting to. + int dst_index = 0; + + // Shift control constants. + const size_t lsb_shift = Bits_Per_Element - split_position; + const size_t msb_shift = split_position; + + const element_type lsb_mask = element_type(etl::integral_limits::max >> (Bits_Per_Element - split_position)); + const element_type msb_mask = etl::integral_limits::max - lsb_mask; + const element_type msb_shifted_mask = element_type(msb_mask >> msb_shift); + + // Now do the shifting. + while (src_index < int(number_of_elements - 1)) + { + // Shift msb. + element_type msb = element_type((pbuffer[src_index] & msb_mask) >> msb_shift); + ++src_index; + + // Shift lsb. + element_type lsb = element_type((pbuffer[src_index] & lsb_mask) << lsb_shift); + + // Combine them. + pbuffer[dst_index] = lsb | msb; + ++dst_index; + } + + // Final msb. + element_type msb = element_type((pbuffer[src_index] & msb_mask) >> msb_shift); + pbuffer[dst_index] = msb; + + // Clear the remaining bits. + // First msb. + pbuffer[dst_index] &= msb_shifted_mask; + ++dst_index; + + // The other remaining bytes. + while (dst_index < int(number_of_elements)) + { + pbuffer[dst_index] = 0; + ++dst_index; + } + } + } + + //************************************************************************* + /// and_equals + //************************************************************************* + ETL_CONSTEXPR14 void and_equals(pointer pbuffer, const_pointer pbuffer2, size_t number_of_elements) ETL_NOEXCEPT + { + for (size_t i = 0U; i < number_of_elements; ++i) + { + pbuffer[i] &= pbuffer2[i]; + } + } + + //************************************************************************* + /// or_equals + //************************************************************************* + ETL_CONSTEXPR14 void or_equals(pointer pbuffer, const_pointer pbuffer2, size_t number_of_elements) ETL_NOEXCEPT + { + for (size_t i = 0U; i < number_of_elements; ++i) + { + pbuffer[i] |= pbuffer2[i]; + } + } + + //************************************************************************* + /// xor_equals + //************************************************************************* + ETL_CONSTEXPR14 void xor_equals(pointer pbuffer, const_pointer pbuffer2, size_t number_of_elements) ETL_NOEXCEPT + { + for (size_t i = 0U; i < number_of_elements; ++i) + { + pbuffer[i] ^= pbuffer2[i]; + } + } + + //************************************************************************* + /// Initialise from an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 void initialise(pointer pbuffer, size_t number_of_elements, unsigned long long value) ETL_NOEXCEPT + { + const size_t Shift = (etl::integral_limits::bits <= (int)Bits_Per_Element) ? 0 : Bits_Per_Element; + + // Can we do it in one hit? + if (Shift == 0) + { + pbuffer[0] = element_type(value); + } + else + { + size_t i = 0UL; + + // Set the non-zero elements. + while ((value != 0) && (i != number_of_elements)) + { + pbuffer[i++] = value & All_Set_Element; + value = value >> Shift; + } + + // Clear the remaining elements. + while (i != number_of_elements) + { + pbuffer[i++] = All_Clear_Element; + } + } + } + + //************************************************************************* + /// Swap bitset buffers. + //************************************************************************* + ETL_CONSTEXPR14 void swap(pointer pbuffer1, pointer pbuffer2, size_t number_of_elements) + { + const pointer pbuffer1_end = pbuffer1 + number_of_elements; + + while (pbuffer1 != pbuffer1_end) + { + element_type temp = *pbuffer1; + *pbuffer1 = *pbuffer2; + *pbuffer2 = temp; + ++pbuffer1; + ++pbuffer2; + } + } + }; + + //*************************************************************************** + template ::bits == Active_Bits> + class bitset; + + //*************************************************************************** + /// Specialisation for zero bits. + /// Just defines 'npos'. + //*************************************************************************** + template <> + class bitset<0U, void, true> : public bitset_constants + { + }; + + //*************************************************************************** + /// Specialisation for zero bits. + //*************************************************************************** + template <> + class bitset<0U, void, false> : public bitset_constants + { + }; + + //*************************************************************************** + /// Specialisation that uses a single element if the element type is the + /// same size as the number of active bits. + //*************************************************************************** + template + class bitset : public bitset_constants + { + public: + + // The element type is the unsigned variant of 'TElement'. + typedef typename etl::make_unsigned::type element_type; + + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + static ETL_CONSTANT size_t Number_Of_Elements = 1U; + static ETL_CONSTANT size_t Allocated_Bits = Bits_Per_Element; + static ETL_CONSTANT element_type All_Set_Element = etl::integral_limits::type>::max; + static ETL_CONSTANT element_type All_Clear_Element = element_type(0); + static ETL_CONSTANT size_t Top_Mask_Shift = 0U; + static ETL_CONSTANT element_type Top_Mask = All_Set_Element; + + typedef etl::span span_type; + typedef etl::span const_span_type; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class bitset; + + //******************************* + /// Conversion operator. + //******************************* + ETL_CONSTEXPR14 operator bool() const ETL_NOEXCEPT + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (bool b) ETL_NOEXCEPT + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (const bit_reference& r) ETL_NOEXCEPT + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + ETL_CONSTEXPR14 bit_reference& flip() ETL_NOEXCEPT + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + ETL_CONSTEXPR14 bool operator~() const ETL_NOEXCEPT + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference() ETL_NOEXCEPT + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference(bitset& r_bitset, size_t position_) ETL_NOEXCEPT + : p_bitset(&r_bitset) + , position(position_) + { + } + + bitset* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset() ETL_NOEXCEPT + : buffer(All_Clear_Element) + { + } + + //************************************************************************* + /// Copy constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const bitset& other) ETL_NOEXCEPT + : buffer(other.buffer) + { + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset(unsigned long long value) ETL_NOEXCEPT + : buffer(element_type(value)) + { + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char* text) ETL_NOEXCEPT + : buffer(All_Clear_Element) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const wchar_t* text) ETL_NOEXCEPT + : buffer(All_Clear_Element) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char16_t* text) ETL_NOEXCEPT + : buffer(All_Clear_Element) + { + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char32_t* text) ETL_NOEXCEPT + : buffer(All_Clear_Element) + { + set(text); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator =(const bitset& other) ETL_NOEXCEPT + { + buffer = other.buffer; + + return *this; + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set() ETL_NOEXCEPT + { + buffer = All_Set_Element; + + return *this; + } + + //************************************************************************* + /// Set from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(element_type value) ETL_NOEXCEPT + { + buffer = value; + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(size_t position, bool value = true) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + if (value == true) + { + buffer |= mask; + } + else + { + buffer &= ~mask; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const wchar_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char16_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char32_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STR('1')) + { + buffer |= mask; + } + else + { + buffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const wchar_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRL('1')) + { + buffer |= mask; + } + else + { + buffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char16_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRu('1')) + { + buffer |= mask; + } + else + { + buffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char32_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRU('1')) + { + buffer |= mask; + } + else + { + buffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Get as an integral value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element), "Integral type too small"); + + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= Bits_Per_Element; + + if (OK) + { + v = T(typename etl::make_unsigned::type(buffer)); + } + + return v; + } + + //************************************************************************* + /// Get as an unsigned long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long to_ulong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Get as an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long long to_ullong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset() ETL_NOEXCEPT + { + buffer = All_Clear_Element; + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset(size_t position) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + buffer &= ~mask; + } + + return *this; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + return (buffer & mask) != 0U; + } + + return false; + } + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT + { + return Active_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count() const ETL_NOEXCEPT + { + return etl::count_bits(buffer); + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all() const ETL_NOEXCEPT + { + return buffer == All_Set_Element; + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all(element_type mask) const ETL_NOEXCEPT + { + return buffer == (All_Set_Element & mask); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none() const ETL_NOEXCEPT + { + return buffer == All_Clear_Element; + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none(element_type mask) const ETL_NOEXCEPT + { + return (buffer & mask) == All_Clear_Element; + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any() const ETL_NOEXCEPT + { + return !none(); + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any(element_type mask) const ETL_NOEXCEPT + { + return !none(mask); + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip() ETL_NOEXCEPT + { + buffer = ~buffer; + + return *this; + } + + //************************************************************************* + /// Flip some of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip_bits(element_type mask = etl::integral_limits::max) ETL_NOEXCEPT + { + buffer ^= mask; + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip(size_t position) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + buffer ^= mask; + } + + return *this; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bool operator[] (size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + return (buffer & mask) != 0U; + } + + return false; + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bit_reference operator [] (size_t position) ETL_NOEXCEPT + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + ETL_CONSTEXPR14 TString to_string(typename TString::value_type zero = typename TString::value_type('0'), + typename TString::value_type one = typename TString::value_type('1')) const + { + TString result; + + result.resize(Active_Bits, '\0'); + + // Check that the string type can contain the digits. + ETL_ASSERT_AND_RETURN_VALUE(result.size() == Active_Bits, ETL_ERROR(etl::bitset_string_too_small), result); + + for (size_t i = Active_Bits; i > 0; --i) + { + result[Active_Bits - i] = test(i - 1) ? one : zero; + } + + return result; + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_first(bool state) const ETL_NOEXCEPT + { + return find_next(state, 0U); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_next(bool state, size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + // Where to start. + size_t bit = position; + + element_type mask = 1U << position; + + // Needs checking? + if ((state && (buffer != All_Clear_Element)) || (!state && (buffer != All_Set_Element))) + { + // For each bit in the element... + while (bit < Active_Bits) + { + // Equal to the required state? + if (((buffer & mask) != 0) == state) + { + return bit; + } + + // Move on to the next bit. + mask <<= 1; + ++bit; + } + } + } + + return npos; + } + + //************************************************************************* + /// operator & + //************************************************************************* + ETL_CONSTEXPR14 bitset operator &(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp &= other; + + return temp; + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator &=(const bitset& other) ETL_NOEXCEPT + { + buffer &= other.buffer; + + return *this; + } + + //************************************************************************* + /// operator | + //************************************************************************* + ETL_CONSTEXPR14 bitset operator |(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp |= other; + + return temp; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator |=(const bitset& other) ETL_NOEXCEPT + { + buffer |= other.buffer; + + return *this; + } + + //************************************************************************* + /// operator ^ + //************************************************************************* + ETL_CONSTEXPR14 bitset operator ^(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp ^= other; + + return temp; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator ^=(const bitset& other) ETL_NOEXCEPT + { + buffer ^= other.buffer; + + return *this; + } + + //************************************************************************* + /// operator ~ + //************************************************************************* + ETL_CONSTEXPR14 bitset operator ~() const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp.flip(); + + return temp; + } + + //************************************************************************* + /// operator << + //************************************************************************* + ETL_CONSTEXPR14 bitset operator <<(size_t shift) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp <<= shift; + + return temp; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator <<=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + buffer <<= shift; + } + + return *this; + } + + //************************************************************************* + /// operator >> + //************************************************************************* + ETL_CONSTEXPR14 bitset operator >>(size_t shift) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp >>= shift; + + return temp; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator >>=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + buffer >>= shift; + } + + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend ETL_CONSTEXPR14 bool operator ==(const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + return (lhs.buffer == rhs.buffer); + } + + //************************************************************************* + /// swap + //************************************************************************* + ETL_CONSTEXPR14 void swap(etl::bitset& other) ETL_NOEXCEPT + { + element_type temp = buffer; + buffer = other.buffer; + other.buffer = temp; + } + + //************************************************************************* + /// span + /// Returns a span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 span_type span() ETL_NOEXCEPT + { + return span_type(&buffer, 1); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 const_span_type span() const ETL_NOEXCEPT + { + return const_span_type(&buffer, 1); + } + + private: + + element_type buffer; + }; + + //************************************************************************* + /// The specialisation that uses an array of the default element type. + //************************************************************************* + template + class bitset : public bitset_constants + { + private: + + //************************************************************************* + // If the 'TElement' is the default 'void', then use 'char', otherwise uses + // the unsigned variant of 'TElement'. + //************************************************************************* + struct select_element_type + { + typedef typename etl::make_unsigned::value, char, TElement>::type>::type type; + }; + + public: + + typedef typename select_element_type::type element_type; + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::bitset_impl::Bits_Per_Element; + static ETL_CONSTANT size_t Number_Of_Elements = (Active_Bits % Bits_Per_Element == 0) ? Active_Bits / Bits_Per_Element : Active_Bits / Bits_Per_Element + 1; + static ETL_CONSTANT size_t Allocated_Bits = Number_Of_Elements * Bits_Per_Element; + static ETL_CONSTANT size_t Top_Mask_Shift = ((Bits_Per_Element - (Allocated_Bits - Active_Bits)) % Bits_Per_Element); + static ETL_CONSTANT element_type All_Set_Element = etl::bitset_impl::All_Set_Element; + static ETL_CONSTANT element_type All_Clear_Element = etl::bitset_impl::All_Clear_Element; + static ETL_CONSTANT element_type Top_Mask = element_type(Top_Mask_Shift == 0 ? All_Set_Element : ~(All_Set_Element << Top_Mask_Shift)); + + static ETL_CONSTANT size_t ALLOCATED_BITS = Allocated_Bits; ///< For backward compatibility. + + typedef etl::span span_type; + typedef etl::span const_span_type; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class bitset; + + //******************************* + /// Conversion operator. + //******************************* + ETL_CONSTEXPR14 operator bool() const ETL_NOEXCEPT + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (bool b) ETL_NOEXCEPT + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (const bit_reference& r) ETL_NOEXCEPT + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + ETL_CONSTEXPR14 bit_reference& flip() ETL_NOEXCEPT + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + ETL_CONSTEXPR14 bool operator~() const ETL_NOEXCEPT + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference() ETL_NOEXCEPT + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference(bitset& r_bitset, size_t position_) ETL_NOEXCEPT + : p_bitset(&r_bitset) + , position(position_) + { + } + + bitset* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset() ETL_NOEXCEPT + : buffer() + { + reset(); + } + + //************************************************************************* + /// Copy constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const bitset& other) ETL_NOEXCEPT + : buffer() + { + etl::copy_n(other.buffer, Number_Of_Elements, buffer); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset(unsigned long long value) ETL_NOEXCEPT + : buffer() + { + ibitset.initialise(buffer, Number_Of_Elements, value); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char* text) ETL_NOEXCEPT + : buffer() + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const wchar_t* text) ETL_NOEXCEPT + : buffer() + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char16_t* text) ETL_NOEXCEPT + : buffer() + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset(const char32_t* text) ETL_NOEXCEPT + : buffer() + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator =(const bitset& other) ETL_NOEXCEPT + { + etl::copy_n(other.buffer, Number_Of_Elements, buffer); + + return *this; + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set() ETL_NOEXCEPT + { + etl::fill_n(buffer, Number_Of_Elements, All_Set_Element); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(size_t position, bool value = true) ETL_NOEXCEPT + { + ibitset.set(buffer, Number_Of_Elements, position, value); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char* text) ETL_NOEXCEPT + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const wchar_t* text) ETL_NOEXCEPT + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char16_t* text) ETL_NOEXCEPT + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& set(const char32_t* text) ETL_NOEXCEPT + { + ibitset.set(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char* text) ETL_NOEXCEPT + { + ibitset.from_string(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const wchar_t* text) ETL_NOEXCEPT + { + ibitset.from_string(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char16_t* text) ETL_NOEXCEPT + { + ibitset.from_string(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset& from_string(const char32_t* text) ETL_NOEXCEPT + { + ibitset.from_string(buffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Get as an integral value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element), "Type too small"); + + return ibitset.template value(buffer, Number_Of_Elements); + } + + //************************************************************************* + /// Get as an unsigned long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long to_ulong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Get as an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long long to_ullong() const ETL_NOEXCEPT + { + return value(); + } + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset() ETL_NOEXCEPT + { + etl::fill_n(buffer, Number_Of_Elements, All_Clear_Element); + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& reset(size_t position) ETL_NOEXCEPT + { + ibitset.reset(buffer, Number_Of_Elements, position); + return *this; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT + { + return ibitset.test(buffer, Number_Of_Elements, position); + } + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT + { + return Active_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count() const ETL_NOEXCEPT + { + return ibitset.count(buffer, Number_Of_Elements); + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all() const ETL_NOEXCEPT + { + return ibitset.all(buffer, Number_Of_Elements, Top_Mask); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none() const ETL_NOEXCEPT + { + return ibitset.none(buffer, Number_Of_Elements); + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any() const ETL_NOEXCEPT + { + return !none(); + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip() ETL_NOEXCEPT + { + ibitset.flip(buffer, Number_Of_Elements); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset& flip(size_t position) ETL_NOEXCEPT + { + ibitset.flip(buffer, Number_Of_Elements, Active_Bits, position); + + return *this; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bool operator[] (size_t position) const ETL_NOEXCEPT + { + return ibitset.test(buffer, Number_Of_Elements, position); + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bit_reference operator [] (size_t position) ETL_NOEXCEPT + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + ETL_CONSTEXPR14 TString to_string(typename TString::value_type zero = typename TString::value_type('0'), + typename TString::value_type one = typename TString::value_type('1')) const + { + return ibitset.template to_string(buffer, Number_Of_Elements, Active_Bits, zero, one); + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_first(bool state) const ETL_NOEXCEPT + { + return ibitset.find_next(buffer, Number_Of_Elements, Active_Bits, state, 0); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_next(bool state, size_t position) const ETL_NOEXCEPT + { + return ibitset.find_next(buffer, Number_Of_Elements, Active_Bits, state, position); + } + + //************************************************************************* + /// operator & + //************************************************************************* + ETL_CONSTEXPR14 bitset operator &(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp &= other; + + return temp; + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator &=(const bitset& other) ETL_NOEXCEPT + { + ibitset.and_equals(&buffer[0], &other.buffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator | + //************************************************************************* + ETL_CONSTEXPR14 bitset operator |(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp |= other; + + return temp; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator |=(const bitset& other) ETL_NOEXCEPT + { + ibitset.or_equals(&buffer[0], &other.buffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator ^ + //************************************************************************* + ETL_CONSTEXPR14 bitset operator ^(const bitset& other) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp ^= other; + + return temp; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator ^=(const bitset& other) ETL_NOEXCEPT + { + ibitset.xor_equals(&buffer[0], &other.buffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator ~ + //************************************************************************* + ETL_CONSTEXPR14 bitset operator ~() const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp.flip(); + + return temp; + } + + //************************************************************************* + /// operator << + //************************************************************************* + ETL_CONSTEXPR14 bitset operator <<(size_t shift) const ETL_NOEXCEPT + { + etl::bitset temp(*this); + + temp <<= shift; + + return temp; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator <<=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + ibitset.shift_left_equals(buffer, Number_Of_Elements, shift); + clear_unused_bits_in_msb(); + } + + return *this; + } + + //************************************************************************* + /// operator >> + //************************************************************************* + ETL_CONSTEXPR14 bitset operator >>(size_t shift) const ETL_NOEXCEPT + { + bitset temp(*this); + + temp >>= shift; + + return temp; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ETL_CONSTEXPR14 bitset& operator >>=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + ibitset.shift_right_equals(buffer, Number_Of_Elements, shift); + } + + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend ETL_CONSTEXPR14 bool operator ==(const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + return etl::equal(lhs.buffer, + lhs.buffer + lhs.Number_Of_Elements, + rhs.buffer); + } + + //************************************************************************* + /// swap + //************************************************************************* + ETL_CONSTEXPR14 void swap(etl::bitset& other) ETL_NOEXCEPT + { + ibitset.swap(buffer, other.buffer, Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 span_type span() ETL_NOEXCEPT + { + return span_type(buffer, Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 const_span_type span() const ETL_NOEXCEPT + { + return const_span_type(buffer, Number_Of_Elements); + } + + private: + + //************************************************************************* + /// Correct the unused top bits after bit manipulation. + //************************************************************************* + ETL_CONSTEXPR14 void clear_unused_bits_in_msb() ETL_NOEXCEPT + { + buffer[Number_Of_Elements - 1U] &= Top_Mask; + } + + etl::bitset_impl ibitset; + + element_type buffer[Number_Of_Elements > 0U ? Number_Of_Elements : 1U]; + }; + + //*************************************************************************** + /// operator & + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bitset operator & (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp &= rhs; + return temp; + } + + //*************************************************************************** + /// operator | + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bitset operator | (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp |= rhs; + return temp; + } + + //*************************************************************************** + /// operator ^ + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bitset operator ^ (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + bitset temp(lhs); + temp ^= rhs; + return temp; + } + + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator != (const bitset& lhs, const bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } +} + +//************************************************************************* +/// swap +//************************************************************************* +template +ETL_CONSTEXPR14 void swap(etl::bitset& lhs, etl::bitset& rhs) ETL_NOEXCEPT +{ + lhs.swap(rhs); +} + +//*************************************************************************** +/// bitset_ext +//*************************************************************************** +namespace etl +{ + //*************************************************************************** + template ::bits == Active_Bits> + class bitset_ext; + + //*************************************************************************** + /// Specialisation for zero bits. + /// Just defines 'npos'. + //*************************************************************************** + template <> + class bitset_ext<0U, void, true> : public bitset_constants + { + }; + + //*************************************************************************** + /// Specialisation for zero bits. + //*************************************************************************** + template <> + class bitset_ext<0U, void, false> : public bitset_constants + { + }; + + //*************************************************************************** + /// Specialisation that uses a single element if the element type is the + /// same size as the number of active bits. + //*************************************************************************** + template + class bitset_ext : public bitset_constants + { + public: + + // The element type is the unsigned variant of 'TElement'. + typedef typename etl::make_unsigned::type element_type; + + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::integral_limits::bits; + static ETL_CONSTANT size_t Number_Of_Elements = 1U; + static ETL_CONSTANT size_t Allocated_Bits = Bits_Per_Element; + static ETL_CONSTANT element_type All_Set_Element = etl::integral_limits::type>::max; + static ETL_CONSTANT element_type All_Clear_Element = element_type(0); + static ETL_CONSTANT size_t Top_Mask_Shift = 0U; + static ETL_CONSTANT element_type Top_Mask = All_Set_Element; + + typedef etl::span span_type; + typedef etl::span const_span_type; + + typedef element_type buffer_type; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class bitset_ext; + + //******************************* + /// Conversion operator. + //******************************* + ETL_CONSTEXPR14 operator bool() const ETL_NOEXCEPT + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (bool b) ETL_NOEXCEPT + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (const bit_reference& r) ETL_NOEXCEPT + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + ETL_CONSTEXPR14 bit_reference& flip() ETL_NOEXCEPT + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + ETL_CONSTEXPR14 bool operator~() const ETL_NOEXCEPT + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference() ETL_NOEXCEPT + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference(bitset_ext& r_bitset, size_t position_) ETL_NOEXCEPT + : p_bitset(&r_bitset) + , position(position_) + { + } + + bitset_ext* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = All_Clear_Element; + } + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = All_Clear_Element; + } + + //************************************************************************* + /// Construct copy. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = *other.pbuffer; + } + + //************************************************************************* + /// Construct copy. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = *other.pbuffer; + } + + //************************************************************************* + /// Copy Constructor (Deleted). + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other) ETL_NOEXCEPT ETL_DELETE; + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(unsigned long long value, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = element_type(value); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(unsigned long long value, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = element_type(value); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const wchar_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const wchar_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char16_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char16_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char32_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char32_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(&buffer) + { + *pbuffer = All_Clear_Element; + set(text); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator =(const bitset_ext& other) ETL_NOEXCEPT + { + *pbuffer = *other.pbuffer; + + return *this; + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set() ETL_NOEXCEPT + { + *pbuffer = All_Set_Element; + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(size_t position, bool value = true) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + if (value == true) + { + *pbuffer |= mask; + } + else + { + *pbuffer &= ~mask; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const wchar_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char16_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char32_t* text) ETL_NOEXCEPT + { + from_string(text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STR('1')) + { + *pbuffer |= mask; + } + else + { + *pbuffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const wchar_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRL('1')) + { + *pbuffer |= mask; + } + else + { + *pbuffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char16_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRu('1')) + { + *pbuffer |= mask; + } + else + { + *pbuffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char32_t* text) ETL_NOEXCEPT + { + if (text == ETL_NULLPTR) + { + reset(); + } + else + { + size_t string_length = etl::strlen(text); + + // Build from the string. + string_length = etl::min(Active_Bits, string_length); + + element_type mask = element_type(element_type(1) << (string_length - 1U)); + + for (size_t i = 0U; i < string_length; ++i) + { + if (text[i] == ETL_STRU('1')) + { + *pbuffer |= mask; + } + else + { + *pbuffer &= ~mask; + } + + mask >>= 1U; + } + } + + return *this; + } + + //************************************************************************* + /// Get as an integral value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element), "Integral type too small"); + + T v = T(0); + + const bool OK = (sizeof(T) * CHAR_BIT) >= Bits_Per_Element; + + if (OK) + { + v = T(typename etl::make_unsigned::type(*pbuffer)); + } + + return v; + } + + //************************************************************************* + /// Get as an unsigned long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long to_ulong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Get as an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long long to_ullong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& reset() ETL_NOEXCEPT + { + *pbuffer = All_Clear_Element; + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& reset(size_t position) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + *pbuffer &= ~mask; + } + + return *this; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + return (*pbuffer & mask) != 0U; + } + + return false; + } + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT + { + return Active_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count() const ETL_NOEXCEPT + { + return etl::count_bits(*pbuffer); + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all() const ETL_NOEXCEPT + { + return *pbuffer == All_Set_Element; + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all(element_type mask) const ETL_NOEXCEPT + { + return *pbuffer == (All_Set_Element & mask); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none() const ETL_NOEXCEPT + { + return *pbuffer == All_Clear_Element; + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none(element_type mask) const ETL_NOEXCEPT + { + return (*pbuffer & mask) == All_Clear_Element; + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any() const ETL_NOEXCEPT + { + return !none(); + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any(element_type mask) const ETL_NOEXCEPT + { + return !none(mask); + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& flip() ETL_NOEXCEPT + { + *pbuffer = ~*pbuffer; + + return *this; + } + + //************************************************************************* + /// Flip some of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& flip_bits(element_type mask = etl::integral_limits::max) ETL_NOEXCEPT + { + *pbuffer ^= mask; + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& flip(size_t position) ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + *pbuffer ^= mask; + } + + return *this; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bool operator[] (size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + const element_type mask = element_type(element_type(1) << position); + return (*pbuffer & mask) != 0U; + } + + return false; + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bit_reference operator [] (size_t position) ETL_NOEXCEPT + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + ETL_CONSTEXPR14 TString to_string(typename TString::value_type zero = typename TString::value_type('0'), + typename TString::value_type one = typename TString::value_type('1')) const + { + TString result; + + result.resize(Active_Bits, '\0'); + + // Check that the string type can contain the digits. + ETL_ASSERT_AND_RETURN_VALUE(result.size() == Active_Bits, ETL_ERROR(etl::bitset_string_too_small), result); + + for (size_t i = Active_Bits; i > 0; --i) + { + result[Active_Bits - i] = test(i - 1) ? one : zero; + } + + return result; + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_first(bool state) const ETL_NOEXCEPT + { + return find_next(state, 0U); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_next(bool state, size_t position) const ETL_NOEXCEPT + { + if (position < Active_Bits) + { + // Where to start. + size_t bit = position; + + element_type mask = 1U << position; + + // Needs checking? + if ((state && (*pbuffer != All_Clear_Element)) || (!state && (*pbuffer != All_Set_Element))) + { + // For each bit in the element... + while (bit < Active_Bits) + { + // Equal to the required state? + if (((*pbuffer & mask) != 0) == state) + { + return bit; + } + + // Move on to the next bit. + mask <<= 1; + ++bit; + } + } + } + + return npos; + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator &=(const bitset_ext& other) ETL_NOEXCEPT + { + *pbuffer &= *other.pbuffer; + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator |=(const bitset_ext& other) ETL_NOEXCEPT + { + *pbuffer |= *other.pbuffer; + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator ^=(const bitset_ext& other) ETL_NOEXCEPT + { + *pbuffer ^= *other.pbuffer; + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator <<=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + *pbuffer <<= shift; + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator >>=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + *pbuffer >>= shift; + } + + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend ETL_CONSTEXPR14 bool operator ==(const bitset_ext& lhs, const bitset_ext& rhs) ETL_NOEXCEPT + { + return (*lhs.pbuffer == *rhs.pbuffer); + } + + //************************************************************************* + /// swap + //************************************************************************* + ETL_CONSTEXPR14 void swap(etl::bitset_ext& other) ETL_NOEXCEPT + { + element_type temp = *pbuffer; + *pbuffer = *other.pbuffer; + *other.pbuffer = temp; + } + + //************************************************************************* + /// span + /// Returns a span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 span_type span() ETL_NOEXCEPT + { + return span_type(pbuffer, 1); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying buffer. + //************************************************************************* + ETL_CONSTEXPR14 const_span_type span() const ETL_NOEXCEPT + { + return const_span_type(pbuffer, 1); + } + + private: + + element_type* pbuffer; + }; + + //************************************************************************* + /// The specialisation that uses an array of the default element type. + //************************************************************************* + template + class bitset_ext : public bitset_constants + { + private: + + //************************************************************************* + // If the 'TElement' is the default 'void', then use 'char', otherwise uses + // the unsigned variant of 'TElement'. + //************************************************************************* + struct select_element_type + { + typedef typename etl::make_unsigned::value, char, TElement>::type>::type type; + }; + + public: + + typedef typename select_element_type::type element_type; + typedef element_type* pointer; + typedef const element_type* const_pointer; + + static ETL_CONSTANT size_t Bits_Per_Element = etl::bitset_impl::Bits_Per_Element; + static ETL_CONSTANT size_t Number_Of_Elements = (Active_Bits % Bits_Per_Element == 0) ? Active_Bits / Bits_Per_Element : Active_Bits / Bits_Per_Element + 1; + static ETL_CONSTANT size_t Allocated_Bits = Number_Of_Elements * Bits_Per_Element; + static ETL_CONSTANT size_t Top_Mask_Shift = ((Bits_Per_Element - (Allocated_Bits - Active_Bits)) % Bits_Per_Element); + static ETL_CONSTANT element_type All_Set_Element = etl::bitset_impl::All_Set_Element; + static ETL_CONSTANT element_type All_Clear_Element = etl::bitset_impl::All_Clear_Element; + static ETL_CONSTANT element_type Top_Mask = element_type(Top_Mask_Shift == 0 ? All_Set_Element : ~(All_Set_Element << Top_Mask_Shift)); + + static ETL_CONSTANT size_t ALLOCATED_BITS = Allocated_Bits; ///< For backward compatibility. + + typedef etl::span span_type; + typedef etl::span const_span_type; + + typedef etl::array buffer_type; + + //************************************************************************* + /// The reference type returned. + //************************************************************************* + class bit_reference + { + public: + + friend class bitset_ext; + + //******************************* + /// Conversion operator. + //******************************* + ETL_CONSTEXPR14 operator bool() const ETL_NOEXCEPT + { + return p_bitset->test(position); + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (bool b) ETL_NOEXCEPT + { + p_bitset->set(position, b); + return *this; + } + + //******************************* + /// Assignment operator. + //******************************* + ETL_CONSTEXPR14 bit_reference& operator = (const bit_reference& r) ETL_NOEXCEPT + { + p_bitset->set(position, bool(r)); + return *this; + } + + //******************************* + /// Flip the bit. + //******************************* + ETL_CONSTEXPR14 bit_reference& flip() ETL_NOEXCEPT + { + p_bitset->flip(position); + return *this; + } + + //******************************* + /// Return the logical inverse of the bit. + //******************************* + ETL_CONSTEXPR14 bool operator~() const ETL_NOEXCEPT + { + return !p_bitset->test(position); + } + + private: + + //******************************* + /// Default constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference() ETL_NOEXCEPT + : p_bitset(ETL_NULLPTR) + , position(0) + { + } + + //******************************* + /// Constructor. + //******************************* + ETL_CONSTEXPR14 bit_reference(bitset_ext& r_bitset, size_t position_) ETL_NOEXCEPT + : p_bitset(&r_bitset) + , position(position_) + { + } + + bitset_ext* p_bitset; ///< The bitset. + size_t position; ///< The position in the bitset. + }; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + reset(); + } + + //************************************************************************* + /// Default constructor. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + reset(); + } + + //************************************************************************* + /// Construct copy. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + etl::copy_n(other.pbuffer, Number_Of_Elements, pbuffer); + } + + //************************************************************************* + /// Construct copy. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + etl::copy_n(other.pbuffer, Number_Of_Elements, pbuffer); + } + + //************************************************************************* + /// Copy Constructor (Deleted). + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const bitset_ext& other) ETL_NOEXCEPT ETL_DELETE; + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(unsigned long long value, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + ibitset.initialise(pbuffer, Number_Of_Elements, value); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a value. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(unsigned long long value, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + ibitset.initialise(pbuffer, Number_Of_Elements, value); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const wchar_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const wchar_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char16_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char16_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char32_t* text, element_type* pbuffer_) ETL_NOEXCEPT + : pbuffer(pbuffer_) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Construct from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext(const char32_t* text, buffer_type& buffer) ETL_NOEXCEPT + : pbuffer(buffer.data()) + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + clear_unused_bits_in_msb(); + } + + //************************************************************************* + /// Assignment operator. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator =(const bitset_ext& other) ETL_NOEXCEPT + { + etl::copy_n(other.pbuffer, Number_Of_Elements, pbuffer); + + return *this; + } + + //************************************************************************* + /// Set all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set() ETL_NOEXCEPT + { + etl::fill_n(pbuffer, Number_Of_Elements, All_Set_Element); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(size_t position, bool value = true) ETL_NOEXCEPT + { + ibitset.set(pbuffer, Number_Of_Elements, position, value); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char* text) ETL_NOEXCEPT + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const wchar_t* text) ETL_NOEXCEPT + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char16_t* text) ETL_NOEXCEPT + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& set(const char32_t* text) ETL_NOEXCEPT + { + ibitset.set(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char* text) ETL_NOEXCEPT + { + ibitset.from_string(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a wide string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const wchar_t* text) ETL_NOEXCEPT + { + ibitset.from_string(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u16 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char16_t* text) ETL_NOEXCEPT + { + ibitset.from_string(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Set from a u32 string. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& from_string(const char32_t* text) ETL_NOEXCEPT + { + ibitset.from_string(pbuffer, Number_Of_Elements, Active_Bits, text); + + return *this; + } + + //************************************************************************* + /// Get as an integral value. + //************************************************************************* + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + value() const ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Only integral types are supported"); + ETL_STATIC_ASSERT((sizeof(T) * CHAR_BIT) >= (Number_Of_Elements * Bits_Per_Element), "Type too small"); + + return ibitset.template value(pbuffer, Number_Of_Elements); + } + + //************************************************************************* + /// Get as an unsigned long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long to_ulong() const ETL_NOEXCEPT + { + return value(); + } + + //************************************************************************* + /// Get as an unsigned long long. + //************************************************************************* + ETL_CONSTEXPR14 unsigned long long to_ullong() const ETL_NOEXCEPT + { + return value(); + } + //************************************************************************* + /// Reset all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& reset() ETL_NOEXCEPT + { + etl::fill_n(pbuffer, Number_Of_Elements, All_Clear_Element); + + return *this; + } + + //************************************************************************* + /// Reset the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& reset(size_t position) ETL_NOEXCEPT + { + ibitset.reset(pbuffer, Number_Of_Elements, position); + return *this; + } + + //************************************************************************* + /// Tests a bit at a position. + /// Positions greater than the number of configured bits will return false. + //************************************************************************* + ETL_CONSTEXPR14 bool test(size_t position) const ETL_NOEXCEPT + { + return ibitset.test(pbuffer, Number_Of_Elements, position); + } + + //************************************************************************* + /// The number of bits in the bitset. + //************************************************************************* + ETL_CONSTEXPR14 size_t size() const ETL_NOEXCEPT + { + return Active_Bits; + } + + //************************************************************************* + /// Count the number of bits set. + //************************************************************************* + ETL_CONSTEXPR14 size_t count() const ETL_NOEXCEPT + { + return ibitset.count(pbuffer, Number_Of_Elements); + } + + //************************************************************************* + // Are all the bits sets? + //************************************************************************* + ETL_CONSTEXPR14 bool all() const ETL_NOEXCEPT + { + return ibitset.all(pbuffer, Number_Of_Elements, Top_Mask); + } + + //************************************************************************* + /// Are none of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool none() const ETL_NOEXCEPT + { + return ibitset.none(pbuffer, Number_Of_Elements); + } + + //************************************************************************* + /// Are any of the bits set? + //************************************************************************* + ETL_CONSTEXPR14 bool any() const ETL_NOEXCEPT + { + return !none(); + } + + //************************************************************************* + /// Flip all of the bits. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& flip() ETL_NOEXCEPT + { + ibitset.flip(pbuffer, Number_Of_Elements); + clear_unused_bits_in_msb(); + + return *this; + } + + //************************************************************************* + /// Flip the bit at the position. + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& flip(size_t position) ETL_NOEXCEPT + { + ibitset.flip(pbuffer, Number_Of_Elements, Active_Bits, position); + + return *this; + } + + //************************************************************************* + /// Read [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bool operator[] (size_t position) const ETL_NOEXCEPT + { + return ibitset.test(pbuffer, Number_Of_Elements, position); + } + + //************************************************************************* + /// Write [] operator. + //************************************************************************* + ETL_CONSTEXPR14 bit_reference operator [] (size_t position) ETL_NOEXCEPT + { + return bit_reference(*this, position); + } + + //************************************************************************* + /// Returns a string representing the bitset. + //************************************************************************* +#if ETL_USING_CPP11 + template > +#else + template +#endif + ETL_CONSTEXPR14 TString to_string(typename TString::value_type zero = typename TString::value_type('0'), + typename TString::value_type one = typename TString::value_type('1')) const + { + return ibitset.template to_string(pbuffer, Number_Of_Elements, Active_Bits, zero, one); + } + + //************************************************************************* + /// Finds the first bit in the specified state. + ///\param state The state to search for. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_first(bool state) const ETL_NOEXCEPT + { + return ibitset.find_next(pbuffer, Number_Of_Elements, Active_Bits, state, 0); + } + + //************************************************************************* + /// Finds the next bit in the specified state. + ///\param state The state to search for. + ///\param position The position to start from. + ///\returns The position of the bit or npos if none were found. + //************************************************************************* + ETL_CONSTEXPR14 size_t find_next(bool state, size_t position) const ETL_NOEXCEPT + { + return ibitset.find_next(pbuffer, Number_Of_Elements, Active_Bits, state, position); + } + + //************************************************************************* + /// operator &= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator &=(const bitset_ext& other) ETL_NOEXCEPT + { + ibitset.and_equals(&pbuffer[0], &other.pbuffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator |= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator |=(const bitset_ext& other) ETL_NOEXCEPT + { + ibitset.or_equals(&pbuffer[0], &other.pbuffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator ^= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator ^=(const bitset_ext& other) ETL_NOEXCEPT + { + ibitset.xor_equals(&pbuffer[0], &other.pbuffer[0], Number_Of_Elements); + + return *this; + } + + //************************************************************************* + /// operator <<= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator <<=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + ibitset.shift_left_equals(pbuffer, Number_Of_Elements, shift); + clear_unused_bits_in_msb(); + } + + return *this; + } + + //************************************************************************* + /// operator >>= + //************************************************************************* + ETL_CONSTEXPR14 bitset_ext& operator >>=(size_t shift) ETL_NOEXCEPT + { + if (shift >= Active_Bits) + { + reset(); + } + else + { + ibitset.shift_right_equals(pbuffer, Number_Of_Elements, shift); + } + + return *this; + } + + //************************************************************************* + /// operator == + //************************************************************************* + friend ETL_CONSTEXPR14 bool operator ==(const bitset_ext& lhs, const bitset_ext& rhs) ETL_NOEXCEPT + { + return etl::equal(lhs.pbuffer, + lhs.pbuffer + lhs.Number_Of_Elements, + rhs.pbuffer); + } + + //************************************************************************* + /// swap + //************************************************************************* + ETL_CONSTEXPR14 void swap(etl::bitset_ext& other) ETL_NOEXCEPT + { + ibitset.swap(pbuffer, other.pbuffer, Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a span of the underlying pbuffer. + //************************************************************************* + ETL_CONSTEXPR14 span_type span() ETL_NOEXCEPT + { + return span_type(pbuffer, Number_Of_Elements); + } + + //************************************************************************* + /// span + /// Returns a const span of the underlying pbuffer. + //************************************************************************* + ETL_CONSTEXPR14 const_span_type span() const ETL_NOEXCEPT + { + return const_span_type(pbuffer, Number_Of_Elements); + } + + private: + + //************************************************************************* + /// Correct the unused top bits after bit manipulation. + //************************************************************************* + ETL_CONSTEXPR14 void clear_unused_bits_in_msb() ETL_NOEXCEPT + { + pbuffer[Number_Of_Elements - 1U] &= Top_Mask; + } + + etl::bitset_impl ibitset; + element_type* pbuffer; + }; + + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator != (const bitset_ext& lhs, const bitset_ext& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } +} + +//************************************************************************* +/// swap +//************************************************************************* +template +ETL_CONSTEXPR14 void swap(etl::bitset_ext& lhs, etl::bitset_ext& rhs) ETL_NOEXCEPT +{ + lhs.swap(rhs); +} + + +#include "minmax_pop.h" + +#endif diff --git a/src/etl/private/delegate_cpp03.h b/src/etl/private/delegate_cpp03.h index 01218a8..8afb09c 100644 --- a/src/etl/private/delegate_cpp03.h +++ b/src/etl/private/delegate_cpp03.h @@ -66,11 +66,11 @@ namespace etl //*********************************** template struct call_if_impl - { - TDelegate& d = static_cast(*this); - + { etl::optional call_if(TParam param) { + TDelegate& d = static_cast(*this); + etl::optional result; if (d.is_valid()) @@ -88,8 +88,8 @@ namespace etl { bool call_if() { - TDelegate& d = static_cast(*this); - + TDelegate& d = static_cast(*this); + if (d.is_valid()) { d(); @@ -106,10 +106,10 @@ namespace etl template struct call_if_impl { - TDelegate& d = static_cast(*this); - etl::optional call_if() { + TDelegate& d = static_cast(*this); + etl::optional result; if (d.is_valid()) @@ -435,7 +435,11 @@ namespace etl //************************************************************************* struct invocation_element { - invocation_element() = default; + invocation_element() + : object(ETL_NULLPTR) + , stub(ETL_NULLPTR) + { + } //*********************************************************************** invocation_element(void* object_, stub_type stub_) @@ -457,8 +461,8 @@ namespace etl } //*********************************************************************** - void* object = ETL_NULLPTR; - stub_type stub = ETL_NULLPTR; + void* object; + stub_type stub; }; //************************************************************************* @@ -823,7 +827,11 @@ namespace etl //************************************************************************* struct invocation_element { - invocation_element() = default; + invocation_element() + : object(ETL_NULLPTR) + , stub(ETL_NULLPTR) + { + } //*********************************************************************** invocation_element(void* object_, stub_type stub_) @@ -845,8 +853,8 @@ namespace etl } //*********************************************************************** - void* object = ETL_NULLPTR; - stub_type stub = ETL_NULLPTR; + void* object; + stub_type stub; }; //************************************************************************* diff --git a/src/etl/private/diagnostic_pessimizing_move_push.h b/src/etl/private/diagnostic_pessimizing_move_push.h new file mode 100644 index 0000000..ef07764 --- /dev/null +++ b/src/etl/private/diagnostic_pessimizing_move_push.h @@ -0,0 +1,39 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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(__clang__) || defined(__llvm__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpessimizing-move" +#endif diff --git a/src/etl/private/diagnostic_uninitialized_push.h b/src/etl/private/diagnostic_uninitialized_push.h new file mode 100644 index 0000000..414d0aa --- /dev/null +++ b/src/etl/private/diagnostic_uninitialized_push.h @@ -0,0 +1,45 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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 "-Wuninitialized" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif + +#if defined(__clang__) || defined(__llvm__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wuninitialized" +#endif diff --git a/src/etl/private/minmax_pop.h b/src/etl/private/minmax_pop.h index 5d3b34d..ea66ebb 100644 --- a/src/etl/private/minmax_pop.h +++ b/src/etl/private/minmax_pop.h @@ -32,7 +32,7 @@ SOFTWARE. * The header include guard has been intentionally omitted. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) #if !defined(ETL_COMPILER_ARM5) #pragma pop_macro("min") #pragma pop_macro("max") diff --git a/src/etl/private/minmax_push.h b/src/etl/private/minmax_push.h index 879ffe3..1e41bd6 100644 --- a/src/etl/private/minmax_push.h +++ b/src/etl/private/minmax_push.h @@ -33,7 +33,7 @@ SOFTWARE. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) #if !defined(ETL_COMPILER_ARM5) #pragma push_macro("min") #pragma push_macro("max") diff --git a/src/etl/private/pvoidvector.h b/src/etl/private/pvoidvector.h index 243dde7..882dc11 100644 --- a/src/etl/private/pvoidvector.h +++ b/src/etl/private/pvoidvector.h @@ -33,17 +33,16 @@ SOFTWARE. #define ETL_IN_PVOIDVECTOR -#include - #include "../platform.h" #include "../algorithm.h" #include "vector_base.h" #include "../type_traits.h" #include "../error_handler.h" - #include "../functional.h" #include "../iterator.h" +#include + #include "minmax_push.h" namespace etl diff --git a/src/etl/private/to_string_helper.h b/src/etl/private/to_string_helper.h index 69b10f6..4105f64 100644 --- a/src/etl/private/to_string_helper.h +++ b/src/etl/private/to_string_helper.h @@ -33,8 +33,6 @@ SOFTWARE. ///\ingroup private -#include - #include "../platform.h" #include "../absolute.h" #include "../negative.h" @@ -46,6 +44,8 @@ SOFTWARE. #include "../iterator.h" #include "../limits.h" +#include + #if ETL_USING_STL && ETL_USING_CPP11 #include // For std::begin, std::end and std::size #endif diff --git a/src/etl/private/variant_legacy.h b/src/etl/private/variant_legacy.h index ab8171e..9302a78 100644 --- a/src/etl/private/variant_legacy.h +++ b/src/etl/private/variant_legacy.h @@ -28,8 +28,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include - #include "../platform.h" #include "../utility.h" #include "../array.h" @@ -43,6 +41,8 @@ SOFTWARE. #include "../null_type.h" #include "../placement_new.h" +#include + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 940 #pragma diag_suppress 111 @@ -55,7 +55,7 @@ SOFTWARE. //***************************************************************************** namespace etl { -#if !defined(ETL_USE_LEGACY_VARIANT) +#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT) namespace legacy { #endif @@ -452,11 +452,12 @@ namespace etl /// Default constructor. /// Sets the state of the instance to containing no valid data. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" variant() - : data() - , type_id(UNSUPPORTED_TYPE_ID) + : type_id(UNSUPPORTED_TYPE_ID) { } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Constructor that catches any types that are not supported. @@ -978,7 +979,7 @@ namespace etl #undef ETL_GEN_LEGACY_VISIT -#if !defined(ETL_USE_LEGACY_VARIANT) +#if ETL_USING_CPP11 && !defined(ETL_USE_LEGACY_VARIANT) } #endif } diff --git a/src/etl/private/variant_variadic.h b/src/etl/private/variant_variadic.h index 622eb92..b69017a 100644 --- a/src/etl/private/variant_variadic.h +++ b/src/etl/private/variant_variadic.h @@ -28,8 +28,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include - #include "../platform.h" #include "../utility.h" #include "../largest.h" @@ -45,6 +43,8 @@ SOFTWARE. #include "../memory.h" #include "../initializer_list.h" +#include + #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 940 #pragma diag_suppress 111 @@ -524,8 +524,8 @@ namespace etl /// Default constructor. /// Sets the state of the instance to containing no valid data. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" ETL_CONSTEXPR14 variant() - : data() { using type = typename etl::private_variant::parameter_pack::template type_from_index<0U>::type; @@ -533,42 +533,45 @@ namespace etl operation = operation_type::value, etl::is_move_constructible::value>::do_operation; type_id = 0U; } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Constructor from a value. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template , variant>::value, int> = 0> ETL_CONSTEXPR14 variant(T&& value) - : data() - , operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) + : operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) , type_id(etl::private_variant::parameter_pack::template index_of_type>::value) { static_assert(etl::is_one_of, TTypes...>::value, "Unsupported type"); construct_in_place>(data, etl::forward(value)); } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Construct from arguments. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template ETL_CONSTEXPR14 explicit variant(etl::in_place_type_t, TArgs&&... args) - : data() - , operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) + : operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) , type_id(etl::private_variant::parameter_pack::template index_of_type>::value) { static_assert(etl::is_one_of, TTypes...>::value, "Unsupported type"); construct_in_place_args>(data, etl::forward(args)...); } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Construct from arguments. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t, TArgs&&... args) - : data() - , type_id(Index) + : type_id(Index) { using type = typename private_variant::parameter_pack:: template type_from_index_t; static_assert(etl::is_one_of ::value, "Unsupported type"); @@ -577,29 +580,31 @@ namespace etl operation = operation_type::value, etl::is_move_constructible::value>::do_operation; } +#include "etl/private/diagnostic_pop.h" #if ETL_HAS_INITIALIZER_LIST //*************************************************************************** /// Construct from type, initializer_list and arguments. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template ETL_CONSTEXPR14 explicit variant(etl::in_place_type_t, std::initializer_list init, TArgs&&... args) - : data() - , operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) + : operation(operation_type, etl::is_copy_constructible>::value, etl::is_move_constructible>::value>::do_operation) , type_id(private_variant::parameter_pack:: template index_of_type>::value) { static_assert(etl::is_one_of, TTypes...> ::value, "Unsupported type"); construct_in_place_args>(data, init, etl::forward(args)...); } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Construct from index, initializer_list and arguments. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" template ETL_CONSTEXPR14 explicit variant(etl::in_place_index_t, std::initializer_list init, TArgs&&... args) - : data() - , type_id(Index) + : type_id(Index) { using type = typename private_variant::parameter_pack:: template type_from_index_t; static_assert(etl::is_one_of ::value, "Unsupported type"); @@ -608,15 +613,16 @@ namespace etl operation = operation_type::value, etl::is_move_constructible::value>::do_operation; } +#include "etl/private/diagnostic_pop.h" #endif //*************************************************************************** /// Copy constructor. ///\param other The other variant object to copy. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" ETL_CONSTEXPR14 variant(const variant& other) - : data() - , operation(other.operation) + : operation(other.operation) , type_id(other.type_id) { if (this != &other) @@ -631,14 +637,15 @@ namespace etl } } } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Move constructor. ///\param other The other variant object to copy. //*************************************************************************** +#include "etl/private/diagnostic_uninitialized_push.h" ETL_CONSTEXPR14 variant(variant&& other) - : data() - , operation(other.operation) + : operation(other.operation) , type_id(other.type_id) { if (this != &other) @@ -657,6 +664,7 @@ namespace etl type_id = variant_npos; } } +#include "etl/private/diagnostic_pop.h" //*************************************************************************** /// Destructor. diff --git a/src/etl/private/vector_base.h b/src/etl/private/vector_base.h index cb45df0..d55a41a 100644 --- a/src/etl/private/vector_base.h +++ b/src/etl/private/vector_base.h @@ -35,13 +35,13 @@ SOFTWARE. #ifndef ETL_VECTOR_BASE_INCLUDED #define ETL_VECTOR_BASE_INCLUDED -#include - #include "../platform.h" #include "../exception.h" #include "../error_handler.h" #include "../debug_count.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/profiles/determine_compiler.h b/src/etl/profiles/determine_compiler.h index e94548a..feb11de 100644 --- a/src/etl/profiles/determine_compiler.h +++ b/src/etl/profiles/determine_compiler.h @@ -31,6 +31,9 @@ SOFTWARE. #ifndef ETL_DETERMINE_COMPILER_H_INCLUDED #define ETL_DETERMINE_COMPILER_H_INCLUDED +//***************************************************************************** +// Macros that are conditionally defined. +//***************************************************************************** #if !defined(ETL_COMPILER_GCC) && \ !defined(ETL_COMPILER_MICROSOFT) && \ !defined(ETL_COMPILER_ARM5) && \ @@ -121,6 +124,9 @@ SOFTWARE. #endif #endif +//***************************************************************************** +// 'Using' macros that are always defined. +//***************************************************************************** #if defined(ETL_COMPILER_GCC) #define ETL_USING_GCC_COMPILER 1 #else diff --git a/src/etl/queue.h b/src/etl/queue.h index 4d19d8b..1dcd768 100644 --- a/src/etl/queue.h +++ b/src/etl/queue.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_QUEUE_INCLUDED #define ETL_QUEUE_INCLUDED -#include -#include - #include "platform.h" #include "iterator.h" #include "alignment.h" @@ -48,6 +45,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + //***************************************************************************** ///\defgroup queue queue /// A First-in / first-out queue with the capacity defined at compile time, diff --git a/src/etl/queue_lockable.h b/src/etl/queue_lockable.h index 9f1602c..f3e525c 100644 --- a/src/etl/queue_lockable.h +++ b/src/etl/queue_lockable.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_QUEUE_LOCKABLE_INCLUDED #define ETL_QUEUE_LOCKABLE_INCLUDED -#include -#include - #include "platform.h" #include "memory.h" #include "parameter_type.h" @@ -43,6 +40,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + namespace etl { template diff --git a/src/etl/queue_mpmc_mutex.h b/src/etl/queue_mpmc_mutex.h index c8d510a..318506e 100644 --- a/src/etl/queue_mpmc_mutex.h +++ b/src/etl/queue_mpmc_mutex.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_MPMC_QUEUE_MUTEX_INCLUDED #define ETL_MPMC_QUEUE_MUTEX_INCLUDED -#include -#include - #include "platform.h" #include "mutex.h" @@ -46,6 +43,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + namespace etl { template diff --git a/src/etl/queue_spsc_atomic.h b/src/etl/queue_spsc_atomic.h index 864cc9a..84febb7 100644 --- a/src/etl/queue_spsc_atomic.h +++ b/src/etl/queue_spsc_atomic.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_SPSC_QUEUE_ATOMIC_INCLUDED #define ETL_SPSC_QUEUE_ATOMIC_INCLUDED -#include -#include - #include "platform.h" #include "alignment.h" #include "parameter_type.h" @@ -43,6 +40,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + #if ETL_HAS_ATOMIC namespace etl diff --git a/src/etl/queue_spsc_isr.h b/src/etl/queue_spsc_isr.h index ab8b1c1..5a2b04a 100644 --- a/src/etl/queue_spsc_isr.h +++ b/src/etl/queue_spsc_isr.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_SPSC_QUEUE_ISR_INCLUDED #define ETL_SPSC_QUEUE_ISR_INCLUDED -#include -#include - #include "platform.h" #include "alignment.h" #include "parameter_type.h" @@ -42,6 +39,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + namespace etl { template diff --git a/src/etl/queue_spsc_locked.h b/src/etl/queue_spsc_locked.h index b9b4224..ad3e1a7 100644 --- a/src/etl/queue_spsc_locked.h +++ b/src/etl/queue_spsc_locked.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_SPSC_QUEUE_LOCKED_INCLUDED #define ETL_SPSC_QUEUE_LOCKED_INCLUDED -#include -#include - #include "platform.h" #include "memory.h" #include "parameter_type.h" @@ -43,6 +40,9 @@ SOFTWARE. #include "utility.h" #include "placement_new.h" +#include +#include + namespace etl { template diff --git a/src/etl/radix.h b/src/etl/radix.h index c21f1aa..63bf47f 100644 --- a/src/etl/radix.h +++ b/src/etl/radix.h @@ -31,11 +31,11 @@ SOFTWARE. #ifndef ETL_RADIX_INCLUDED #define ETL_RADIX_INCLUDED -#include - #include "platform.h" #include "enum_type.h" +#include + ///\defgroup radix radix /// Radix constants for binary, octal, decimal and hex. ///\ingroup etl diff --git a/src/etl/random.h b/src/etl/random.h index fa0571c..0bca835 100644 --- a/src/etl/random.h +++ b/src/etl/random.h @@ -31,11 +31,11 @@ SOFTWARE. #ifndef ETL_RANDOM_INCLUDED #define ETL_RANDOM_INCLUDED -#include - #include "platform.h" #include "binary.h" +#include + namespace etl { #if defined(ETL_POLYMORPHIC_RANDOM) diff --git a/src/etl/ratio.h b/src/etl/ratio.h index a4dc504..b548360 100644 --- a/src/etl/ratio.h +++ b/src/etl/ratio.h @@ -31,11 +31,11 @@ SOFTWARE. #ifndef ETL_RATIO_INCLUDED #define ETL_RATIO_INCLUDED +#include "platform.h" + #include #include -#include "platform.h" - ///\defgroup ratio ratio ///\ingroup maths diff --git a/src/etl/reference_counted_message.h b/src/etl/reference_counted_message.h index cd06726..69c35e2 100644 --- a/src/etl/reference_counted_message.h +++ b/src/etl/reference_counted_message.h @@ -29,8 +29,6 @@ SOFTWARE. #ifndef ETL_REFERENCE_COUNTED_MESSAGE_INCLUDED #define ETL_REFERENCE_COUNTED_MESSAGE_INCLUDED -#include - #include "platform.h" #include "message.h" #include "atomic.h" @@ -39,6 +37,8 @@ SOFTWARE. #include "type_traits.h" #include "ireference_counted_message_pool.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/reference_counted_object.h b/src/etl/reference_counted_object.h index b99c8f4..f506b4e 100644 --- a/src/etl/reference_counted_object.h +++ b/src/etl/reference_counted_object.h @@ -29,13 +29,41 @@ #ifndef ETL_REFERENCE_COUNTED_OBJECT_INCLUDED #define ETL_REFERENCE_COUNTED_OBJECT_INCLUDED -#include - #include "platform.h" #include "atomic.h" +#include "error_handler.h" + +#include namespace etl { + + //*************************************************************************** + /// Exceptions for reference counting + ///\ingroup reference_counting + //*************************************************************************** + class reference_counting_exception : public etl::exception + { + public: + reference_counting_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Reference counter overrun exception + ///\ingroup reference_counting + //*************************************************************************** + class reference_count_overrun : public etl::reference_counting_exception + { + public: + reference_count_overrun(string_type file_name_, numeric_type line_number_) + : etl::reference_counting_exception(ETL_ERROR_TEXT("reference_counting:overrun", ETL_REFERENCE_COUNTED_OBJECT_FILE_ID"A"), file_name_, line_number_) + { + } + }; + //*************************************************************************** /// The base of all reference counters. //*************************************************************************** @@ -87,7 +115,7 @@ namespace etl //*************************************************************************** ETL_NODISCARD virtual int32_t decrement_reference_count() ETL_OVERRIDE { - assert(reference_count > 0); + ETL_ASSERT(reference_count > 0, ETL_ERROR(reference_count_overrun)); return int32_t(--reference_count); } diff --git a/src/etl/reference_flat_map.h b/src/etl/reference_flat_map.h index 7c4a41a..0b0d070 100644 --- a/src/etl/reference_flat_map.h +++ b/src/etl/reference_flat_map.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_REFERENCE_FLAT_MAP_INCLUDED #define ETL_REFERENCE_FLAT_MAP_INCLUDED -#include - #include "platform.h" #include "vector.h" #include "error_handler.h" @@ -47,6 +45,8 @@ SOFTWARE. #include "private/comparator_is_transparent.h" +#include + //***************************************************************************** ///\defgroup reference_flat_map reference_flat_map /// An reference_flat_map with the capacity defined at compile time. diff --git a/src/etl/reference_flat_multimap.h b/src/etl/reference_flat_multimap.h index b207635..b12b4a0 100644 --- a/src/etl/reference_flat_multimap.h +++ b/src/etl/reference_flat_multimap.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_REFERENCE_FLAT_MULTIMAP_INCLUDED #define ETL_REFERENCE_FLAT_MULTIMAP_INCLUDED -#include - #include "platform.h" #include "exception.h" #include "error_handler.h" @@ -45,6 +43,8 @@ SOFTWARE. #include "private/comparator_is_transparent.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/reference_flat_multiset.h b/src/etl/reference_flat_multiset.h index 1ed5f8f..e1501d5 100644 --- a/src/etl/reference_flat_multiset.h +++ b/src/etl/reference_flat_multiset.h @@ -31,10 +31,7 @@ SOFTWARE. #ifndef ETL_REFERENCE_FLAT_MULTISET_INCLUDED #define ETL_REFERENCE_FLAT_MULTISET_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" @@ -48,6 +45,8 @@ SOFTWARE. #include "private/comparator_is_transparent.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/reference_flat_set.h b/src/etl/reference_flat_set.h index 5a6126b..69a2ced 100644 --- a/src/etl/reference_flat_set.h +++ b/src/etl/reference_flat_set.h @@ -31,10 +31,7 @@ SOFTWARE. #ifndef ETL_REFERENCE_FLAT_SET_INCLUDED #define ETL_REFERENCE_FLAT_SET_INCLUDED -#include - #include "platform.h" - #include "algorithm.h" #include "iterator.h" #include "functional.h" @@ -49,6 +46,8 @@ SOFTWARE. #include "private/comparator_is_transparent.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/result.h b/src/etl/result.h index 2916d9e..9d79dbf 100644 --- a/src/etl/result.h +++ b/src/etl/result.h @@ -93,16 +93,16 @@ namespace etl //******************************************* /// Construct from error //******************************************* - result(const TError& err) - : data(err) + result(const TError& error) + : data(error) { } //******************************************* /// Move construct from error //******************************************* - result(TError&& err) - : data(etl::move(err)) + result(TError&& error) + : data(etl::move(error)) { } @@ -145,21 +145,29 @@ namespace etl //******************************************* /// Copy assign from error //******************************************* - result& operator =(const TError& err) + result& operator =(const TError& error) { - data = err; + data = error; return *this; } //******************************************* /// Move assign from error //******************************************* - result& operator =(TError&& err) + result& operator =(TError&& error) { - data = etl::move(err); + data = etl::move(error); return *this; } + //******************************************* + /// true if result contains a value + //******************************************* + bool has_value() const + { + return (data.index() == 0U); + } + //******************************************* /// true if result contains a value //******************************************* @@ -227,15 +235,18 @@ namespace etl public: //******************************************* - /// Cannot be default constructed + /// Default Constructor //******************************************* - result() = delete; + result() + : err(TError()) + { + } //******************************************* /// Copy constructor //******************************************* result(const result& other) - : data(other.data) + : err(other.err) { } @@ -243,41 +254,41 @@ namespace etl /// Move constructor //******************************************* result(result&& other) - : data(etl::move(other.data)) + : err(etl::move(other.err)) { } //******************************************* /// Construct from error //******************************************* - result(const TError& err) - : data(err) + result(const TError& err_) + : err(err_) { } //******************************************* /// Move construct from error //******************************************* - result(TError&& err) - : data(etl::move(err)) + result(TError&& err_) + : err(etl::move(err_)) { } //******************************************* /// Copy assign from error //******************************************* - result& operator =(const TError& err) + result& operator =(const TError& err_) { - data = err; + err = err_; return *this; } //******************************************* /// Move assign from error //******************************************* - result& operator =(TError&& err) + result& operator =(TError&& err_) { - data = etl::move(err); + err = etl::move(err_); return *this; } @@ -303,7 +314,7 @@ namespace etl //******************************************* const TError& error() const { - return etl::get(data); + return err; } //******************************************* @@ -312,12 +323,12 @@ namespace etl //******************************************* TError&& error() { - return etl::get(etl::move(data)); + return etl::move(err); } private: - etl::variant data; + TError err; }; } diff --git a/src/etl/scaled_rounding.h b/src/etl/scaled_rounding.h index ff875ac..d8a97da 100644 --- a/src/etl/scaled_rounding.h +++ b/src/etl/scaled_rounding.h @@ -37,14 +37,13 @@ SOFTWARE. namespace etl { - template struct scaled_rounding_t { typedef typename etl::conditional::value, int32_t, uint32_t>::type type; }; - //***************************************************************************** + //***************************************************************************** /// A set of rounding algorithms for scaled integrals. /// \tparam T The integral type. /// \tparam SCALING The scaling factor. @@ -64,7 +63,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_ceiling_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -85,7 +84,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_ceiling_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -98,7 +97,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_floor_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -119,7 +118,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_floor_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -133,7 +132,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_half_up_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -156,7 +155,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_half_up_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -170,7 +169,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_half_down_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -193,7 +192,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_half_down_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -206,7 +205,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_zero_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -220,7 +219,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_zero_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -233,7 +232,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_infinity_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -254,7 +253,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_infinity_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -268,7 +267,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_half_even_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -299,7 +298,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_half_even_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; @@ -313,7 +312,7 @@ namespace etl /// \param value Scaled integral. /// \return Unscaled, rounded integral. //*************************************************************************** - template + template T round_half_odd_unscaled(T value) { ETL_STATIC_ASSERT(etl::is_integral::value, "Type must be an integral"); @@ -344,7 +343,7 @@ namespace etl /// \param value Scaled integral. /// \return Scaled, rounded integral. //*************************************************************************** - template + template T round_half_odd_scaled(T value) { typedef typename scaled_rounding_t::type scale_t; diff --git a/src/etl/scheduler.h b/src/etl/scheduler.h index 8abf6bf..d601519 100644 --- a/src/etl/scheduler.h +++ b/src/etl/scheduler.h @@ -29,8 +29,6 @@ SOFTWARE. #ifndef ETL_SCHEDULER_INCLUDED #define ETL_SCHEDULER_INCLUDED -#include - #include "platform.h" #include "vector.h" #include "nullptr.h" @@ -40,6 +38,8 @@ SOFTWARE. #include "type_traits.h" #include "function.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/set.h b/src/etl/set.h index 0fac988..d21c14b 100644 --- a/src/etl/set.h +++ b/src/etl/set.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_SET_INCLUDED #define ETL_SET_INCLUDED -#include - #include "platform.h" #include "pool.h" #include "exception.h" @@ -51,6 +49,9 @@ SOFTWARE. #include "initializer_list.h" #include "private/comparator_is_transparent.h" + +#include + #include "private/minmax_push.h" //***************************************************************************** diff --git a/src/etl/smallest.h b/src/etl/smallest.h index 8c10acb..c2c981a 100644 --- a/src/etl/smallest.h +++ b/src/etl/smallest.h @@ -53,11 +53,11 @@ SOFTWARE. #ifndef ETL_SMALLEST_INCLUDED #define ETL_SMALLEST_INCLUDED -#include - #include "platform.h" #include "integral_limits.h" +#include + ///\defgroup smallest smallest ///\ingroup utilities @@ -226,6 +226,7 @@ namespace etl typedef uint_least32_t type; }; +#if ETL_USING_64BIT_TYPES //************************************************************************* // Greater than 32 bits. //************************************************************************* @@ -234,6 +235,7 @@ namespace etl { typedef uint_least64_t type; }; +#endif //************************************************************************* // Determine the type to hold the number of bits based on the index. @@ -268,6 +270,7 @@ namespace etl typedef int_least32_t type; }; +#if ETL_USING_64BIT_TYPES //************************************************************************* // Greater than 32 bits. //************************************************************************* @@ -276,6 +279,7 @@ namespace etl { typedef int_least64_t type; }; +#endif } //*************************************************************************** diff --git a/src/etl/span.h b/src/etl/span.h index 74adaa8..32f2710 100644 --- a/src/etl/span.h +++ b/src/etl/span.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" #include "iterator.h" +#include "circular_iterator.h" #include "nullptr.h" #include "hash.h" #include "type_traits.h" @@ -42,7 +43,7 @@ SOFTWARE. #include "private/dynamic_extent.h" -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 #include #endif @@ -66,11 +67,12 @@ namespace etl 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 reverse_iterator; - typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; + typedef T* iterator; + typedef ETL_OR_STD::reverse_iterator reverse_iterator; + + typedef etl::circular_iterator circular_iterator; + typedef etl::circular_iterator > reverse_circular_iterator; static ETL_CONSTANT size_t extent = Extent; @@ -83,10 +85,10 @@ namespace etl } //************************************************************************* - /// Construct from pointer + size + /// Construct from iterators + size //************************************************************************* template - ETL_CONSTEXPR span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT + ETL_CONSTEXPR explicit span(const TIterator begin_, const TSize /*size_*/) ETL_NOEXCEPT : pbegin(etl::addressof(*begin_)) { } @@ -95,7 +97,7 @@ namespace etl /// Construct from iterators //************************************************************************* template - ETL_CONSTEXPR span(const TIterator begin_, const TIterator /*end_*/) + ETL_CONSTEXPR explicit span(const TIterator begin_, const TIterator /*end_*/) : pbegin(etl::addressof(*begin_)) { } @@ -132,7 +134,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -141,13 +143,13 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } #endif -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //************************************************************************* /// Construct from std::array. //************************************************************************* @@ -187,7 +189,7 @@ namespace etl template span(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -199,7 +201,7 @@ namespace etl template ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value&& - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -213,6 +215,15 @@ namespace etl { } + //************************************************************************* + /// Copy constructor + //************************************************************************* + template + ETL_CONSTEXPR span(const etl::span& other, typename etl::enable_if<(Extent == etl::dynamic_extent) || (N == etl::dynamic_extent) || (N == Extent), void>::type) ETL_NOEXCEPT + : pbegin(other.pbegin) + { + } + //************************************************************************* /// Returns a reference to the first element. //************************************************************************* @@ -245,6 +256,14 @@ namespace etl return pbegin; } + //************************************************************************* + /// Returns a circular iterator to the beginning of the span. + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT + { + return circular_iterator(begin(), end()); + } + //************************************************************************* /// Returns an iterator to the end of the span. //************************************************************************* @@ -261,6 +280,14 @@ namespace etl return reverse_iterator((pbegin + Extent)); } + //************************************************************************* + /// Returns a reverse circular iterator to the end of the span. + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT + { + return reverse_circular_iterator(rbegin(), rend()); + } + //************************************************************************* /// Returns a reverse iterator to the end of the span. //************************************************************************* @@ -410,10 +437,12 @@ namespace etl 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 reverse_iterator; - typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; + + typedef T* iterator; + typedef ETL_OR_STD::reverse_iterator reverse_iterator; + + typedef etl::circular_iterator circular_iterator; + typedef etl::circular_iterator > reverse_circular_iterator; static ETL_CONSTANT size_t extent = etl::dynamic_extent; @@ -481,7 +510,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -491,14 +520,14 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { } #endif -#if ETL_USING_CPP11 && ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 //************************************************************************* /// Construct from std::array. //************************************************************************* @@ -541,7 +570,7 @@ namespace etl template ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -554,7 +583,7 @@ namespace etl template ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -570,6 +599,16 @@ namespace etl { } + //************************************************************************* + /// Copy constructor + //************************************************************************* + template + ETL_CONSTEXPR span(const etl::span& other) ETL_NOEXCEPT + : pbegin(other.begin()) + , pend(other.begin() + N) + { + } + //************************************************************************* /// Returns a reference to the first element. //************************************************************************* @@ -602,6 +641,14 @@ namespace etl return pbegin; } + //************************************************************************* + /// Returns a circular iterator to the beginning of the span. + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT + { + return circular_iterator(begin(), end()); + } + //************************************************************************* /// Returns an iterator to the end of the span. //************************************************************************* @@ -618,6 +665,14 @@ namespace etl return reverse_iterator(pend); } + //************************************************************************* + /// Returns a reverse circular iterator to the end of the span. + //************************************************************************* + ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT + { + return reverse_circular_iterator(rbegin(), rend()); + } + //************************************************************************* /// Returns a reverse iterator to the end of the span. //************************************************************************* diff --git a/src/etl/sqrt.h b/src/etl/sqrt.h index 62976fa..18b13db 100644 --- a/src/etl/sqrt.h +++ b/src/etl/sqrt.h @@ -31,12 +31,12 @@ SOFTWARE. #ifndef ETL_SQRT_INCLUDED #define ETL_SQRT_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "constant.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/stack.h b/src/etl/stack.h index 512d612..5400619 100644 --- a/src/etl/stack.h +++ b/src/etl/stack.h @@ -31,9 +31,6 @@ SOFTWARE. #ifndef ETL_STACK_INCLUDED #define ETL_STACK_INCLUDED -#include -#include - #include "platform.h" #include "algorithm.h" #include "utility.h" @@ -46,6 +43,9 @@ SOFTWARE. #include "type_traits.h" #include "placement_new.h" +#include +#include + //***************************************************************************** ///\defgroup stack stack /// A Last-in / first-out stack with the capacity defined at compile time, diff --git a/src/etl/state_chart.h b/src/etl/state_chart.h index 8ef23e4..a55230f 100644 --- a/src/etl/state_chart.h +++ b/src/etl/state_chart.h @@ -29,14 +29,14 @@ SOFTWARE. #ifndef ETL_STATE_CHART_INCLUDED #define ETL_STATE_CHART_INCLUDED -#include - #include "platform.h" #include "nullptr.h" #include "array.h" #include "array_view.h" #include "utility.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/string.h b/src/etl/string.h index 1ea8e41..a1415e2 100644 --- a/src/etl/string.h +++ b/src/etl/string.h @@ -472,9 +472,9 @@ namespace etl /// Make string from string literal or array //*************************************************************************** template - etl::string make_string(const char(&text)[ARRAY_SIZE]) + etl::string make_string(const char(&text)[ARRAY_SIZE]) { - return etl::string(text, etl::strlen(text)); + return etl::string(text, etl::strlen(text, ARRAY_SIZE - 1)); } //*************************************************************************** @@ -483,7 +483,7 @@ namespace etl template etl::string make_string_with_capacity(const char(&text)[SIZE]) { - return etl::string(text, etl::strlen(text)); + return etl::string(text, etl::strlen(text, SIZE)); } } diff --git a/src/etl/string_utilities.h b/src/etl/string_utilities.h index f713366..e3df469 100644 --- a/src/etl/string_utilities.h +++ b/src/etl/string_utilities.h @@ -41,6 +41,8 @@ SOFTWARE. #include #include +#include "private/minmax_push.h" + namespace etl { //*************************************************************************** @@ -833,4 +835,6 @@ namespace etl } } -#endif \ No newline at end of file +#include "private/minmax_pop.h" + +#endif diff --git a/src/etl/string_view.h b/src/etl/string_view.h index cc8d887..8bad7c0 100644 --- a/src/etl/string_view.h +++ b/src/etl/string_view.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_STRING_VIEW_INCLUDED #define ETL_STRING_VIEW_INCLUDED -#include - #include "platform.h" #include "memory.h" #include "iterator.h" @@ -45,6 +43,8 @@ SOFTWARE. #include "algorithm.h" #include "private/minmax_push.h" +#include + namespace etl { //*************************************************************************** @@ -290,7 +290,7 @@ namespace etl //************************************************************************* /// Assign from a view. //************************************************************************* - ETL_CONSTEXPR etl::basic_string_view& operator=(const etl::basic_string_view& other) + ETL_CONSTEXPR14 etl::basic_string_view& operator=(const etl::basic_string_view& other) { mbegin = other.mbegin; mend = other.mend; @@ -435,7 +435,7 @@ namespace etl ETL_CONSTEXPR14 bool starts_with(etl::basic_string_view view) const { return (size() >= view.size()) && - (compare(0, view.size(), view) == 0); + (compare(0, view.size(), view) == 0); } ETL_CONSTEXPR14 bool starts_with(T c) const @@ -448,7 +448,7 @@ namespace etl size_t lengthtext = TTraits::length(text); return (size() >= lengthtext) && - (compare(0, lengthtext, text) == 0); + (compare(0, lengthtext, text) == 0); } //************************************************************************* @@ -457,7 +457,7 @@ namespace etl ETL_CONSTEXPR14 bool ends_with(etl::basic_string_view view) const { return (size() >= view.size()) && - (compare(size() - view.size(), npos, view) == 0); + (compare(size() - view.size(), npos, view) == 0); } ETL_CONSTEXPR14 bool ends_with(T c) const @@ -471,7 +471,7 @@ namespace etl size_t lengthview = size(); return (lengthview >= lengthtext) && - (compare(lengthview - lengthtext, lengthtext, text) == 0); + (compare(lengthview - lengthtext, lengthtext, text) == 0); } //************************************************************************* @@ -809,27 +809,38 @@ namespace etl /// make_string_view. //************************************************************************* template - ETL_CONSTEXPR string_view make_string_view(const char(&text)[ARRAY_SIZE]) + ETL_CONSTEXPR14 string_view make_string_view(const char(&text)[ARRAY_SIZE]) { - return string_view(text, ARRAY_SIZE - 1U); + size_t length = etl::char_traits::length(text, ARRAY_SIZE - 1U); + + return string_view(text, length); } + //*********************************** template - ETL_CONSTEXPR wstring_view make_string_view(const wchar_t(&text)[ARRAY_SIZE]) + ETL_CONSTEXPR14 wstring_view make_string_view(const wchar_t(&text)[ARRAY_SIZE]) { - return wstring_view(text, ARRAY_SIZE - 1U); + size_t length = etl::char_traits::length(text, ARRAY_SIZE - 1U); + + return wstring_view(text, length); } + //*********************************** template - ETL_CONSTEXPR u16string_view make_string_view(const char16_t(&text)[ARRAY_SIZE]) + ETL_CONSTEXPR14 u16string_view make_string_view(const char16_t(&text)[ARRAY_SIZE]) { - return u16string_view(text, ARRAY_SIZE - 1U); + size_t length = etl::char_traits::length(text, ARRAY_SIZE - 1U); + + return u16string_view(text, length); } + //*********************************** template - ETL_CONSTEXPR u32string_view make_string_view(const char32_t(&text)[ARRAY_SIZE]) + ETL_CONSTEXPR14 u32string_view make_string_view(const char32_t(&text)[ARRAY_SIZE]) { - return u32string_view(text, ARRAY_SIZE - 1U); + size_t length = etl::char_traits::length(text, ARRAY_SIZE - 1U); + + return u32string_view(text, length); } //************************************************************************* diff --git a/src/etl/task.h b/src/etl/task.h index b4048df..35badb2 100644 --- a/src/etl/task.h +++ b/src/etl/task.h @@ -29,12 +29,12 @@ SOFTWARE. #ifndef ETL_TASK_INCLUDED #define ETL_TASK_INCLUDED -#include - #include "platform.h" #include "error_handler.h" #include "exception.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/timer.h b/src/etl/timer.h index 4980d4f..6b9411c 100644 --- a/src/etl/timer.h +++ b/src/etl/timer.h @@ -29,12 +29,11 @@ SOFTWARE. #ifndef ETL_TIMER_INCLUDED #define ETL_TIMER_INCLUDED -#include - #include "platform.h" - #include "atomic.h" +#include + //***************************************************************************** // Definitions common to timers. //***************************************************************************** diff --git a/src/etl/to_arithmetic.h b/src/etl/to_arithmetic.h new file mode 100644 index 0000000..da0f505 --- /dev/null +++ b/src/etl/to_arithmetic.h @@ -0,0 +1,1017 @@ +///\file +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 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_TO_ARITHMETIC_INCLUDED +#define ETL_TO_ARITHMETIC_INCLUDED + +#include "platform.h" +#include "type_traits.h" +#include "integral_limits.h" +#include "limits.h" +#include "string_view.h" +#include "basic_string.h" +#include "format_spec.h" +#include "radix.h" +#include "string_utilities.h" +#include "iterator.h" +#include "bit.h" +#include "smallest.h" +#include "absolute.h" +#include "expected.h" + +namespace etl +{ + //*************************************************************************** + /// Status values for to_arithmetic. + //*************************************************************************** + struct to_arithmetic_status + { + enum enum_type + { + Valid, + Invalid_Radix, + Invalid_Format, + Invalid_Float, + Signed_To_Unsigned, + Overflow + }; + + ETL_DECLARE_ENUM_TYPE(to_arithmetic_status, int) + ETL_ENUM_TYPE(Valid, "Valid") + ETL_ENUM_TYPE(Invalid_Radix, "Invalid Radix") + ETL_ENUM_TYPE(Invalid_Format, "Invalid Format") + ETL_ENUM_TYPE(Invalid_Float, "Invalid Float") + ETL_ENUM_TYPE(Signed_To_Unsigned, "Signed To Unsigned") + ETL_ENUM_TYPE(Overflow, "Overflow") + ETL_END_ENUM_TYPE + }; + + //*************************************************************************** + /// Status values for to_arithmetic. + //*************************************************************************** + template + class to_arithmetic_result + { + public: + + typedef TValue value_type; + typedef etl::to_arithmetic_status error_type; + typedef etl::unexpected unexpected_type; + + //******************************************* + /// Default constructor. + //******************************************* + ETL_CONSTEXPR14 + to_arithmetic_result() + : conversion_value(static_cast(0)) + , conversion_status(error_type::Valid) + { + } + + //******************************************* + /// Copy constructor. + //******************************************* + ETL_CONSTEXPR14 + to_arithmetic_result(const to_arithmetic_result& other) + : conversion_value(other.conversion_value) + , conversion_status(other.conversion_status) + { + } + + //******************************************* + /// Returns true if the result has a valid value. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (conversion_status.error() == error_type::Valid); + } + + //******************************************* + /// Returns true if the result has a valid value. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator bool() const + { + return has_value(); + } + + //******************************************* + /// Returns the value, if valid. + /// Otherwise undefined. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + value_type value() const + { + return conversion_value; + } + + //******************************************* + /// Returns the value, if valid. + /// Otherwise undefined. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator value_type() const + { + return value(); + } + + //******************************************* + /// Returns the conversion status. + /// One of the following:- + /// Valid + /// Invalid_Radix + /// Invalid_Format + /// Invalid_Float + /// Signed_To_Unsigned + /// Overflow + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type error() const + { + return etl::to_arithmetic_status(conversion_status.error()); + } + + //******************************************* + /// Assignment from a value. + //******************************************* + ETL_CONSTEXPR14 + to_arithmetic_result& operator =(value_type value_) + { + conversion_value = value_; + + return *this; + } + + //******************************************* + /// Assignment from an unexpected_type. + //******************************************* + ETL_CONSTEXPR14 + to_arithmetic_result& operator =(unexpected_type status_) + { + conversion_status = status_; + + return *this; + } + + private: + + value_type conversion_value; + unexpected_type conversion_status; + }; + + namespace private_to_arithmetic + { + static ETL_CONSTANT char Positive_Char = '+'; + static ETL_CONSTANT char Negative_Char = '-'; + static ETL_CONSTANT char Radix_Point1_Char = '.'; + static ETL_CONSTANT char Radix_Point2_Char = ','; + static ETL_CONSTANT char Exponential_Char = 'e'; + + //******************************************* + ETL_NODISCARD + inline + ETL_CONSTEXPR14 + bool is_valid(char c, etl::radix::value_type radix) + { + switch (radix) + { + case etl::radix::binary: + { + return (c >= '0') && (c <= '1'); + break; + } + + case etl::radix::octal: + { + return (c >= '0') && (c <= '7'); + break; + } + + case etl::radix::decimal: + { + return (c >= '0') && (c <= '9'); + break; + } + + case etl::radix::hex: + { + return ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')); + break; + } + + default: + { + return false; + break; + } + } + } + + //******************************************* + ETL_NODISCARD + inline + ETL_CONSTEXPR14 + char digit_value(char c, etl::radix::value_type radix) + { + switch (radix) + { + case etl::radix::binary: + case etl::radix::octal: + case etl::radix::decimal: + { + return c - '0'; + break; + } + + case etl::radix::hex: + { + if ((c >= '0') && (c <= '9')) + { + return c - '0'; + } + else + { + return (c - 'a') + 10; + } + break; + } + + default: + { + return 0; + break; + } + } + } + + //******************************************* + ETL_NODISCARD + inline + ETL_CONSTEXPR14 + char to_lower(char c) + { + if ((c >= 'A') && (c <= 'Z')) + { + c += 32; + } + + return c; + } + + //******************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR14 + char convert(TChar c) + { + return to_lower(static_cast(c)); + } + + //*************************************************************************** + /// Checks to see if the text starts with a '+' or '-' prefix, and modifies the view to remove it. + /// Returns true if the text has a '-' prefix. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + bool check_and_remove_sign_prefix(etl::basic_string_view& view) + { + if (!view.empty()) + { + // Check for prefix. + const char c = convert(view[0]); + const bool has_positive_prefix = (c == Positive_Char); + const bool has_negative_prefix = (c == Negative_Char); + + // Step over the prefix, if present. + if (has_positive_prefix || has_negative_prefix) + { + view.remove_prefix(1); + return has_negative_prefix; + } + } + + return false; + } + + //*************************************************************************** + /// Checks to see if the radix is valid. + //*************************************************************************** + ETL_NODISCARD + inline + ETL_CONSTEXPR14 + bool is_valid_radix(const etl::radix::value_type radix) + { + return (radix == etl::radix::binary) || + (radix == etl::radix::octal) || + (radix == etl::radix::decimal) || + (radix == etl::radix::hex); + } + + //*************************************************************************** + /// Accumulate integrals + //*************************************************************************** + template + struct integral_accumulator + { + //********************************* + ETL_CONSTEXPR14 + integral_accumulator(etl::radix::value_type radix_, TValue maximum_) + : radix(radix_) + , maximum(maximum_) + , integral_value(0) + , conversion_status(to_arithmetic_status::Valid) + { + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool add(const char c) + { + bool is_success = false; + bool is_not_overflow = false; + + const bool is_valid_char = is_valid(c, radix); + + if (is_valid_char) + { + TValue old_value = integral_value; + integral_value *= radix; + + // No multipication overflow? + is_not_overflow = ((integral_value / radix) == old_value); + + if (is_not_overflow) + { + const char digit = digit_value(c, radix); + + // No addition overflow? + is_not_overflow = ((maximum - digit) >= integral_value); + + if ((maximum - digit) >= integral_value) + { + integral_value += digit; + is_success = true; + } + } + } + + // Check the status of the conversion. + if (is_valid_char == false) + { + conversion_status = to_arithmetic_status::Invalid_Format; + } + else if (is_not_overflow == false) + { + conversion_status = to_arithmetic_status::Overflow; + } + + return is_success; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return conversion_status == to_arithmetic_status::Valid; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + TValue value() const + { + return integral_value; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + to_arithmetic_status status() const + { + return conversion_status; + } + + private: + + etl::radix::value_type radix; + TValue maximum; + TValue integral_value; + to_arithmetic_status conversion_status; + }; + + //*************************************************************************** + /// Accumulate floating point + //*************************************************************************** + struct floating_point_accumulator + { + //********************************* + ETL_CONSTEXPR14 + floating_point_accumulator() + : divisor(1) + , floating_point_value(0) + , is_negative_mantissa(false) + , is_negative_exponent(false) + , expecting_sign(true) + , exponent_value(0) + , state(Parsing_Integral) + , conversion_status(to_arithmetic_status::Valid) + { + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool add(char c) + { + bool is_success = true; + + switch (state) + { + //*************************** + case Parsing_Integral: + { + if (expecting_sign && ((c == Positive_Char) || (c == Negative_Char))) + { + is_negative_mantissa = (c == Negative_Char); + expecting_sign = false; + } + // Radix point? + else if ((c == Radix_Point1_Char) || (c == Radix_Point2_Char)) + { + expecting_sign = false; + state = Parsing_Fractional; + } + // Exponential? + else if (c == Exponential_Char) + { + expecting_sign = true; + state = Parsing_Exponential; + } + else if (is_valid(c, etl::radix::decimal)) + { + const char digit = digit_value(c, etl::radix::decimal); + floating_point_value *= 10; + is_negative_mantissa ? floating_point_value -= digit : floating_point_value += digit; + conversion_status = to_arithmetic_status::Valid; + expecting_sign = false; + } + else + { + conversion_status = to_arithmetic_status::Invalid_Format; + is_success = false; + } + break; + } + + //*************************** + case Parsing_Fractional: + { + // Radix point? + if ((c == Radix_Point1_Char) || (c == Radix_Point2_Char)) + { + conversion_status = to_arithmetic_status::Invalid_Format; + is_success = false; + } + // Exponential? + else if (c == Exponential_Char) + { + expecting_sign = true; + state = Parsing_Exponential; + } + else if (is_valid(c, etl::radix::decimal)) + { + const char digit = digit_value(c, etl::radix::decimal); + divisor *= 10; + long double fraction = digit / divisor; + is_negative_mantissa ? floating_point_value -= fraction : floating_point_value += fraction; + conversion_status = to_arithmetic_status::Valid; + } + else + { + conversion_status = to_arithmetic_status::Invalid_Format; + is_success = false; + } + break; + } + + //*************************** + case Parsing_Exponential: + { + if (expecting_sign && ((c == Positive_Char) || (c == Negative_Char))) + { + is_negative_exponent = (c == Negative_Char); + expecting_sign = false; + } + // Radix point? + else if ((c == Radix_Point1_Char) || (c == Radix_Point2_Char) || (c == Exponential_Char)) + { + conversion_status = to_arithmetic_status::Invalid_Format; + is_success = false; + } + else if (is_valid(c, etl::radix::decimal)) + { + const char digit = digit_value(c, etl::radix::decimal); + exponent_value *= etl::radix::decimal; + is_negative_exponent ? exponent_value -= digit : exponent_value += digit; + } + else + { + conversion_status = to_arithmetic_status::Invalid_Format; + is_success = false; + } + break; + } + + //*************************** + default: + { + is_success = false; + break; + } + } + + return is_success; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (conversion_status == to_arithmetic_status::Valid); + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + long double value() const + { + return floating_point_value; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + to_arithmetic_status status() const + { + return conversion_status; + } + + //********************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + int exponent() const + { + return exponent_value; + } + + private: + + enum + { + Parsing_Integral, + Parsing_Fractional, + Parsing_Exponential + }; + + long double divisor; + long double floating_point_value; + bool is_negative_mantissa; + bool is_negative_exponent; + bool expecting_sign; + int exponent_value; + int state; + to_arithmetic_status conversion_status; + }; + + //*************************************************************************** + // Define an unsigned accumulator type that is at least as large as TValue. + //*************************************************************************** + template + struct accumulator_type_select; + + template <> + struct accumulator_type_select<8U> + { + typedef uint32_t type; + }; + + template <> + struct accumulator_type_select<16U> + { + typedef uint32_t type; + }; + + template <> + struct accumulator_type_select<32U> + { + typedef uint32_t type; + }; + +#if ETL_USING_64BIT_TYPES + template <> + struct accumulator_type_select<64U> + { + typedef uint64_t type; + }; +#endif + + //*************************************************************************** + /// Text to integral from view, radix value and maximum. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + etl::to_arithmetic_result to_arithmetic_integral(const etl::basic_string_view& view, + const etl::radix::value_type radix, + const TAccumulatorType maximum) + { + etl::to_arithmetic_result accumulator_result; + typedef typename etl::unexpected unexpected_type; + + typename etl::basic_string_view::const_iterator itr = view.begin(); + const typename etl::basic_string_view::const_iterator itr_end = view.end(); + + integral_accumulator accumulator(radix, maximum); + + while ((itr != itr_end) && accumulator.add(convert(*itr))) + { + // Keep looping until done or an error occurs. + ++itr; + } + + if (accumulator.has_value()) + { + accumulator_result = accumulator.value(); + } + else + { + accumulator_result = unexpected_type(accumulator.status()); + } + + return accumulator_result; + } + } + + //*************************************************************************** + /// Text to integral from view and radix value type. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(etl::basic_string_view view, + const etl::radix::value_type radix) + { + using namespace etl::private_to_arithmetic; + + typedef etl::to_arithmetic_result result_type; + typedef typename result_type::unexpected_type unexpected_type; + + result_type result; + + if (is_valid_radix(radix)) + { + // Is this a negative number? + const bool is_negative = check_and_remove_sign_prefix(view); + + if (view.empty()) + { + result = unexpected_type(to_arithmetic_status::Invalid_Format); + } + else + { + // Make sure we're not trying to put a negative value into an unsigned type. + if (is_negative && etl::is_unsigned::value) + { + result = unexpected_type(to_arithmetic_status::Signed_To_Unsigned); + } + else + { + const bool is_decimal = (radix == etl::radix::decimal); + + // Select the type we use for the accumulator. + typedef typename accumulator_type_select::bits>::type accumulator_type; + + // Find the maximum absolute value for the type value we're trying to convert to. + const accumulator_type maximum = is_negative ? etl::absolute_unsigned(etl::integral_limits::min) + : is_decimal ? etl::integral_limits::max + : etl::integral_limits::type>::max; + // Do the conversion. + etl::to_arithmetic_result accumulator_result = to_arithmetic_integral(view, radix, maximum); + + result = unexpected_type(accumulator_result.error()); + + // Was it successful? + if (accumulator_result.has_value()) + { + typedef typename etl::make_unsigned::type uvalue_t; + const uvalue_t uvalue = static_cast(accumulator_result.value()); + + // Convert from the accumulator type to the desired type. + result = (is_negative ? static_cast(0) - uvalue : etl::bit_cast(uvalue)); + } + } + } + } + else + { + result = unexpected_type(to_arithmetic_status::Invalid_Radix); + } + + return result; + } + + //*************************************************************************** + /// Text to integral from view and default decimal radix. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::basic_string_view& view) + { + return etl::to_arithmetic(view, etl::radix::decimal); + } + + //*************************************************************************** + /// Text to integral from view and radix format spec. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::basic_string_view& view, const typename etl::private_basic_format_spec::base_spec& spec) + { + return etl::to_arithmetic(view, spec.base); + } + + //*************************************************************************** + /// Text to integral from pointer, length and radix value type. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const TChar* cp, size_t length, const etl::radix::value_type radix) + { + return etl::to_arithmetic(etl::basic_string_view(cp, length), radix); + } + + //*************************************************************************** + /// Text to integral from pointer, length and default decimal radix. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const TChar* cp, size_t length) + { + return etl::to_arithmetic(etl::basic_string_view(cp, length), etl::radix::decimal); + } + + //*************************************************************************** + /// Text to integral from pointer, length and radix format spec. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const TChar* cp, size_t length, const typename etl::private_basic_format_spec::base_spec& spec) + { + return etl::to_arithmetic(etl::basic_string_view(cp, length), spec.base); + } + + //*************************************************************************** + /// Text to integral from string and radix value type. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::ibasic_string& str, const etl::radix::value_type radix) + { + return etl::to_arithmetic(etl::basic_string_view(str), radix);; + } + + //*************************************************************************** + /// Text to integral from string and default decimal radix. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::ibasic_string& str) + { + return etl::to_arithmetic(etl::basic_string_view(str), etl::radix::decimal);; + } + + //*************************************************************************** + /// Text to integral from string and radix format spec. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::ibasic_string& str, const typename etl::private_basic_format_spec::base_spec& spec) + { + return etl::to_arithmetic(etl::basic_string_view(str), spec);; + } + + //*************************************************************************** + /// Floating point from view. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(etl::basic_string_view view) + { + using namespace etl::private_to_arithmetic; + + typedef etl::to_arithmetic_result result_type; + typedef typename result_type::unexpected_type unexpected_type; + + result_type result; + + if (view.empty()) + { + result = unexpected_type(to_arithmetic_status::Invalid_Format); + } + else + { + floating_point_accumulator accumulator; + + typename etl::basic_string_view::const_iterator itr = view.begin(); + const typename etl::basic_string_view::const_iterator itr_end = view.end(); + + while ((itr != itr_end) && accumulator.add(convert(*itr))) + { + // Keep looping until done or an error occurs. + ++itr; + } + + result = unexpected_type(accumulator.status()); + + if (result.has_value()) + { + TValue value = static_cast(accumulator.value()); + int exponent = accumulator.exponent(); + + value *= pow(static_cast(10.0), static_cast(exponent)); + + // Check that the result is a valid floating point number. + if ((value == etl::numeric_limits::infinity()) || + (value == -etl::numeric_limits::infinity())) + { + result = unexpected_type(to_arithmetic_status::Overflow); + } + // Check for NaN. + else if (value != value) + { + result = unexpected_type(to_arithmetic_status::Invalid_Float); + } + else + { + result = value; + } + } + } + + return result; + } + + //*************************************************************************** + /// Floating point from pointer and length. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const TChar* cp, size_t length) + { + return etl::to_arithmetic(etl::basic_string_view(cp, length)); + } + + //*************************************************************************** + /// Floating point from pointer. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const TChar* cp) + { + return etl::to_arithmetic(etl::basic_string_view(cp, etl::strlen(cp))); + } + + //*************************************************************************** + /// Floating point from string. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, etl::to_arithmetic_result >::type + to_arithmetic(const etl::ibasic_string& str) + { + return etl::to_arithmetic(etl::basic_string_view(str)); + } +} + +//*************************************************************************** +/// Equality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator ==(const etl::to_arithmetic_result& lhs, const etl::to_arithmetic_result& rhs) +{ + if (lhs.has_value() && rhs.has_value()) + { + return (lhs.value() == rhs.value()); + } + else + { + return (lhs.status() == rhs.status()); + } +} + +//*************************************************************************** +/// Equality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator ==(const etl::to_arithmetic_result& lhs, const U& rhs) +{ + return bool(lhs) ? lhs.value() == rhs : false; +} + +//*************************************************************************** +/// Equality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator ==(const T& lhs, const etl::to_arithmetic_result& rhs) +{ + return bool(rhs) ? rhs.value() == lhs : false; +} + +//*************************************************************************** +/// Inequality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator !=(const etl::to_arithmetic_result& lhs, const etl::to_arithmetic_result& rhs) +{ + return !(lhs == rhs); +} + +//*************************************************************************** +/// Inequality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator !=(const etl::to_arithmetic_result& lhs, const U& rhs) +{ + return !(lhs == rhs); +} + +//*************************************************************************** +/// Inequality test for etl::to_arithmetic_result +//*************************************************************************** +template +ETL_CONSTEXPR14 bool operator !=(const T& lhs, const etl::to_arithmetic_result& rhs) +{ + return !(lhs == rhs); +} + +#endif diff --git a/src/etl/type_lookup.h b/src/etl/type_lookup.h index 94991ca..5533745 100644 --- a/src/etl/type_lookup.h +++ b/src/etl/type_lookup.h @@ -29,14 +29,14 @@ SOFTWARE. #ifndef ETL_TYPE_LOOKUP_INCLUDED #define ETL_TYPE_LOOKUP_INCLUDED -#include - #include "platform.h" #include "type_traits.h" #include "static_assert.h" #include "integral_limits.h" #include "null_type.h" +#include + #if 0 #error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. #endif diff --git a/src/etl/type_traits.h b/src/etl/type_traits.h index 03aa822..3ef8d97 100644 --- a/src/etl/type_traits.h +++ b/src/etl/type_traits.h @@ -53,13 +53,13 @@ SOFTWARE. #ifndef ETL_TYPE_TRAITS_INCLUDED #define ETL_TYPE_TRAITS_INCLUDED -#include -#include - #include "platform.h" #include "nullptr.h" #include "static_assert.h" +#include +#include + ///\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. @@ -1594,7 +1594,7 @@ namespace etl #endif //*************************************************************************** -#if ETL_USING_CPP11 && ETL_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED)) +#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED)) //********************************************* // Use the STL's definitions. diff --git a/src/etl/u16string.h b/src/etl/u16string.h index d280f2d..88f5303 100644 --- a/src/etl/u16string.h +++ b/src/etl/u16string.h @@ -455,9 +455,9 @@ namespace etl /// Make string from string literal or array //*************************************************************************** template - etl::u16string make_string(const char16_t(&text)[ARRAY_SIZE]) + etl::u16string make_string(const char16_t(&text)[ARRAY_SIZE]) { - return etl::u16string(text, etl::strlen(text)); + return etl::u16string(text, etl::strlen(text, ARRAY_SIZE - 1U)); } //*************************************************************************** @@ -466,7 +466,7 @@ namespace etl template etl::u16string make_string_with_capacity(const char16_t(&text)[SIZE]) { - return etl::u16string(text, etl::strlen(text)); + return etl::u16string(text, etl::strlen(text, SIZE)); } } diff --git a/src/etl/u32string.h b/src/etl/u32string.h index 9edf634..1dda329 100644 --- a/src/etl/u32string.h +++ b/src/etl/u32string.h @@ -455,9 +455,9 @@ namespace etl /// Make string from string literal or array //*************************************************************************** template - etl::u32string make_string(const char32_t(&text)[ARRAY_SIZE]) + etl::u32string make_string(const char32_t(&text)[ARRAY_SIZE]) { - return etl::u32string(text, etl::strlen(text)); + return etl::u32string(text, etl::strlen(text, ARRAY_SIZE - 1U)); } //*************************************************************************** @@ -466,7 +466,7 @@ namespace etl template etl::u32string make_string_with_capacity(const char32_t(&text)[SIZE]) { - return etl::u32string(text, etl::strlen(text)); + return etl::u32string(text, etl::strlen(text, SIZE)); } } diff --git a/src/etl/unaligned_type.h b/src/etl/unaligned_type.h index 54b7220..09acddb 100644 --- a/src/etl/unaligned_type.h +++ b/src/etl/unaligned_type.h @@ -58,10 +58,11 @@ namespace etl static ETL_CONSTANT size_t Size = Size_; - typedef char* pointer; - typedef const char* const_pointer; - typedef char* iterator; - typedef const char* const_iterator; + typedef unsigned char storage_type; + typedef storage_type* pointer; + typedef const storage_type* const_pointer; + typedef storage_type* iterator; + typedef const storage_type* const_iterator; typedef etl::reverse_iterator reverse_iterator; typedef etl::reverse_iterator const_reverse_iterator; @@ -196,7 +197,7 @@ namespace etl //************************************************************************* /// Index operator. //************************************************************************* - char& operator[](int i) + storage_type& operator[](int i) { return storage[i]; } @@ -204,19 +205,22 @@ namespace etl //************************************************************************* /// Const index operator. //************************************************************************* - ETL_CONSTEXPR const char& operator[](int i) const + ETL_CONSTEXPR const storage_type& operator[](int i) const { return storage[i]; } protected: - char storage[Size]; + unsigned char storage[Size]; }; } //************************************************************************* /// unaligned_type + ///\brief Allows an arithmetic type to be stored at an unaligned address. + ///\tparam T The arithmetic type. + ///\tparam Endian The endianness of the arithmetic type. //************************************************************************* template class unaligned_type : public private_unaligned_type::unaligned_type_common @@ -227,7 +231,15 @@ namespace etl typedef T value_type; - static ETL_CONSTANT int Endian = Endian_; + typedef typename private_unaligned_type::unaligned_type_common::storage_type storage_type; + typedef typename private_unaligned_type::unaligned_type_common::pointer pointer; + typedef typename private_unaligned_type::unaligned_type_common::const_pointer const_pointer; + typedef typename private_unaligned_type::unaligned_type_common::iterator iterator; + typedef typename private_unaligned_type::unaligned_type_common::const_iterator const_iterator; + typedef typename private_unaligned_type::unaligned_type_common::reverse_iterator reverse_iterator; + typedef typename private_unaligned_type::unaligned_type_common::const_reverse_iterator const_reverse_iterator; + + static ETL_CONSTANT int Endian = Endian_; static ETL_CONSTANT size_t Size = private_unaligned_type::unaligned_type_common::Size; //************************************************************************* @@ -356,68 +368,70 @@ namespace etl struct unaligned_copy; //******************************************* - // Size == 1 + /// Unaligned copy + /// Size == 1 //******************************************* template struct unaligned_copy { //******************************* - static ETL_CONSTEXPR14 void copy(T value, char* store) + static ETL_CONSTEXPR14 void copy(T value, pointer store) { - store[0] = static_cast(value); + store[0] = static_cast(value); } //******************************* - static ETL_CONSTEXPR14 void copy(const char* store, T& value) + static ETL_CONSTEXPR14 void copy(const_pointer store, T& value) { value = static_cast(store[0]); } //******************************* - static ETL_CONSTEXPR14 void copy(const char* src, int /*endian_src*/, char* dst) + static ETL_CONSTEXPR14 void copy(const_pointer src, int /*endian_src*/, unsigned char* dst) { dst[0] = src[0]; } }; //******************************************* - // Size == 2 + /// Unaligned copy + /// Size == 2 //******************************************* template struct unaligned_copy { //******************************* - static ETL_CONSTEXPR14 void copy(T value, char* store) + static ETL_CONSTEXPR14 void copy(T value, unsigned char* store) { if (Endian == etl::endianness::value()) { - store[0] = static_cast(value); - store[1] = static_cast(value >> (1U * CHAR_BIT)); + store[0] = static_cast(value); + store[1] = static_cast(value >> (1U * CHAR_BIT)); } else { - store[1] = static_cast(value); - store[0] = static_cast(value >> (1U * CHAR_BIT)); + store[1] = static_cast(value); + store[0] = static_cast(value >> (1U * CHAR_BIT)); } } //******************************* - static ETL_CONSTEXPR14 void copy(const char* store, T& value) + static ETL_CONSTEXPR14 void copy(const_pointer store, T& value) { if (Endian == etl::endianness::value()) { - value = static_cast(static_cast(store[0])); + value = static_cast(static_cast(store[0])); value |= static_cast(static_cast(store[1])) << (1U * CHAR_BIT); } else { - value = static_cast(static_cast(store[1])); + value = static_cast(static_cast(store[1])); value |= static_cast(static_cast(store[0])) << (1U * CHAR_BIT); } } //******************************* - static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst) + static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst) { if (Endian == endian_src) { @@ -433,42 +447,43 @@ namespace etl }; //******************************************* - // Size == 4 + /// Unaligned copy + /// Size == 4 //******************************************* template struct unaligned_copy { - static ETL_CONSTEXPR14 void copy(T value, char* store) + static ETL_CONSTEXPR14 void copy(T value, unsigned char* store) { if (Endian == etl::endianness::value()) { - store[0] = static_cast(value); - store[1] = static_cast(value >> (1U * CHAR_BIT)); - store[2] = static_cast(value >> (2U * CHAR_BIT)); - store[3] = static_cast(value >> (3U * CHAR_BIT)); + store[0] = static_cast(value); + store[1] = static_cast(value >> (1U * CHAR_BIT)); + store[2] = static_cast(value >> (2U * CHAR_BIT)); + store[3] = static_cast(value >> (3U * CHAR_BIT)); } else { - store[3] = static_cast(value); - store[2] = static_cast(value >> (1U * CHAR_BIT)); - store[1] = static_cast(value >> (2U * CHAR_BIT)); - store[0] = static_cast(value >> (3U * CHAR_BIT)); + store[3] = static_cast(value); + store[2] = static_cast(value >> (1U * CHAR_BIT)); + store[1] = static_cast(value >> (2U * CHAR_BIT)); + store[0] = static_cast(value >> (3U * CHAR_BIT)); } } //******************************* - static ETL_CONSTEXPR14 void copy(const char* store, T& value) + static ETL_CONSTEXPR14 void copy(const_pointer store, T& value) { if (Endian == etl::endianness::value()) { - value = static_cast(static_cast(store[0])); + value = static_cast(static_cast(store[0])); value |= static_cast(static_cast(store[1])) << (1U * CHAR_BIT); value |= static_cast(static_cast(store[2])) << (2U * CHAR_BIT); value |= static_cast(static_cast(store[3])) << (3U * CHAR_BIT); } else { - value = static_cast(static_cast(store[3])); + value = static_cast(static_cast(store[3])); value |= static_cast(static_cast(store[2])) << (1U * CHAR_BIT); value |= static_cast(static_cast(store[1])) << (2U * CHAR_BIT); value |= static_cast(static_cast(store[0])) << (3U * CHAR_BIT); @@ -476,7 +491,7 @@ namespace etl } //******************************* - static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst) + static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst) { if (Endian == endian_src) { @@ -496,43 +511,44 @@ namespace etl }; //******************************************* - // Size == 8 + /// Unaligned copy + /// Size == 8 //******************************************* template struct unaligned_copy { - static ETL_CONSTEXPR14 void copy(T value, char* store) + static ETL_CONSTEXPR14 void copy(T value, unsigned char* store) { if (Endian == etl::endianness::value()) { - store[0] = static_cast(value); - store[1] = static_cast(value >> (1U * CHAR_BIT)); - store[2] = static_cast(value >> (2U * CHAR_BIT)); - store[3] = static_cast(value >> (3U * CHAR_BIT)); - store[4] = static_cast(value >> (4U * CHAR_BIT)); - store[5] = static_cast(value >> (5U * CHAR_BIT)); - store[6] = static_cast(value >> (6U * CHAR_BIT)); - store[7] = static_cast(value >> (7U * CHAR_BIT)); + store[0] = static_cast(value); + store[1] = static_cast(value >> (1U * CHAR_BIT)); + store[2] = static_cast(value >> (2U * CHAR_BIT)); + store[3] = static_cast(value >> (3U * CHAR_BIT)); + store[4] = static_cast(value >> (4U * CHAR_BIT)); + store[5] = static_cast(value >> (5U * CHAR_BIT)); + store[6] = static_cast(value >> (6U * CHAR_BIT)); + store[7] = static_cast(value >> (7U * CHAR_BIT)); } else { - store[7] = static_cast(value); - store[6] = static_cast(value >> (1U * CHAR_BIT)); - store[5] = static_cast(value >> (2U * CHAR_BIT)); - store[4] = static_cast(value >> (3U * CHAR_BIT)); - store[3] = static_cast(value >> (4U * CHAR_BIT)); - store[2] = static_cast(value >> (5U * CHAR_BIT)); - store[1] = static_cast(value >> (6U * CHAR_BIT)); - store[0] = static_cast(value >> (7U * CHAR_BIT)); + store[7] = static_cast(value); + store[6] = static_cast(value >> (1U * CHAR_BIT)); + store[5] = static_cast(value >> (2U * CHAR_BIT)); + store[4] = static_cast(value >> (3U * CHAR_BIT)); + store[3] = static_cast(value >> (4U * CHAR_BIT)); + store[2] = static_cast(value >> (5U * CHAR_BIT)); + store[1] = static_cast(value >> (6U * CHAR_BIT)); + store[0] = static_cast(value >> (7U * CHAR_BIT)); } } //******************************* - static ETL_CONSTEXPR14 void copy(const char* store, T& value) + static ETL_CONSTEXPR14 void copy(const_pointer store, T& value) { if (Endian == etl::endianness::value()) { - value = static_cast(static_cast(store[0])); + value = static_cast(static_cast(store[0])); value |= static_cast(static_cast(store[1])) << (1U * CHAR_BIT); value |= static_cast(static_cast(store[2])) << (2U * CHAR_BIT); value |= static_cast(static_cast(store[3])) << (3U * CHAR_BIT); @@ -543,7 +559,7 @@ namespace etl } else { - value = static_cast(static_cast(store[7])); + value = static_cast(static_cast(store[7])); value |= static_cast(static_cast(store[6])) << (1U * CHAR_BIT); value |= static_cast(static_cast(store[5])) << (2U * CHAR_BIT); value |= static_cast(static_cast(store[4])) << (3U * CHAR_BIT); @@ -555,7 +571,7 @@ namespace etl } //******************************* - static ETL_CONSTEXPR14 void copy(const char* src, int endian_src, char* dst) + static ETL_CONSTEXPR14 void copy(const_pointer src, int endian_src, unsigned char* dst) { if (Endian == endian_src) { @@ -585,89 +601,89 @@ namespace etl #if ETL_HAS_CONSTEXPR_ENDIANNESS // Host order - typedef unaligned_type host_char_t; - typedef unaligned_type host_schar_t; - typedef unaligned_type host_uchar_t; - typedef unaligned_type host_short_t; - typedef unaligned_type host_ushort_t; - typedef unaligned_type host_int_t; - typedef unaligned_type host_uint_t; - typedef unaligned_type host_long_t; - typedef unaligned_type host_ulong_t; - typedef unaligned_type host_long_long_t; + typedef unaligned_type host_char_t; + typedef unaligned_type host_schar_t; + typedef unaligned_type host_uchar_t; + typedef unaligned_type host_short_t; + typedef unaligned_type host_ushort_t; + typedef unaligned_type host_int_t; + typedef unaligned_type host_uint_t; + typedef unaligned_type host_long_t; + typedef unaligned_type host_ulong_t; + typedef unaligned_type host_long_long_t; typedef unaligned_type host_ulong_long_t; #if ETL_USING_8BIT_TYPES - typedef unaligned_type host_int8_t; - typedef unaligned_type host_uint8_t; + typedef unaligned_type host_int8_t; + typedef unaligned_type host_uint8_t; #endif - typedef unaligned_type host_int16_t; - typedef unaligned_type host_uint16_t; - typedef unaligned_type host_int32_t; - typedef unaligned_type host_uint32_t; + typedef unaligned_type host_int16_t; + typedef unaligned_type host_uint16_t; + typedef unaligned_type host_int32_t; + typedef unaligned_type host_uint32_t; #if ETL_USING_64BIT_TYPES - typedef unaligned_type host_int64_t; - typedef unaligned_type host_uint64_t; + typedef unaligned_type host_int64_t; + typedef unaligned_type host_uint64_t; #endif - typedef unaligned_type host_float_t; - typedef unaligned_type host_double_t; - typedef unaligned_type host_long_double_t; + typedef unaligned_type host_float_t; + typedef unaligned_type host_double_t; + typedef unaligned_type host_long_double_t; #endif // Little Endian - typedef unaligned_type le_char_t; - typedef unaligned_type le_schar_t; - typedef unaligned_type le_uchar_t; - typedef unaligned_type le_short_t; - typedef unaligned_type le_ushort_t; - typedef unaligned_type le_int_t; - typedef unaligned_type le_uint_t; - typedef unaligned_type le_long_t; - typedef unaligned_type le_ulong_t; - typedef unaligned_type le_long_long_t; + typedef unaligned_type le_char_t; + typedef unaligned_type le_schar_t; + typedef unaligned_type le_uchar_t; + typedef unaligned_type le_short_t; + typedef unaligned_type le_ushort_t; + typedef unaligned_type le_int_t; + typedef unaligned_type le_uint_t; + typedef unaligned_type le_long_t; + typedef unaligned_type le_ulong_t; + typedef unaligned_type le_long_long_t; typedef unaligned_type le_ulong_long_t; #if ETL_USING_8BIT_TYPES - typedef unaligned_type le_int8_t; - typedef unaligned_type le_uint8_t; + typedef unaligned_type le_int8_t; + typedef unaligned_type le_uint8_t; #endif - typedef unaligned_type le_int16_t; - typedef unaligned_type le_uint16_t; - typedef unaligned_type le_int32_t; - typedef unaligned_type le_uint32_t; + typedef unaligned_type le_int16_t; + typedef unaligned_type le_uint16_t; + typedef unaligned_type le_int32_t; + typedef unaligned_type le_uint32_t; #if ETL_USING_64BIT_TYPES - typedef unaligned_type le_int64_t; - typedef unaligned_type le_uint64_t; + typedef unaligned_type le_int64_t; + typedef unaligned_type le_uint64_t; #endif - typedef unaligned_type le_float_t; - typedef unaligned_type le_double_t; - typedef unaligned_type le_long_double_t; + typedef unaligned_type le_float_t; + typedef unaligned_type le_double_t; + typedef unaligned_type le_long_double_t; // Big Endian - typedef unaligned_type be_char_t; - typedef unaligned_type be_schar_t; - typedef unaligned_type be_uchar_t; - typedef unaligned_type be_short_t; - typedef unaligned_type be_ushort_t; - typedef unaligned_type be_int_t; - typedef unaligned_type be_uint_t; - typedef unaligned_type be_long_t; - typedef unaligned_type be_ulong_t; - typedef unaligned_type be_long_long_t; + typedef unaligned_type be_char_t; + typedef unaligned_type be_schar_t; + typedef unaligned_type be_uchar_t; + typedef unaligned_type be_short_t; + typedef unaligned_type be_ushort_t; + typedef unaligned_type be_int_t; + typedef unaligned_type be_uint_t; + typedef unaligned_type be_long_t; + typedef unaligned_type be_ulong_t; + typedef unaligned_type be_long_long_t; typedef unaligned_type be_ulong_long_t; #if ETL_USING_8BIT_TYPES - typedef unaligned_type be_int8_t; - typedef unaligned_type be_uint8_t; + typedef unaligned_type be_int8_t; + typedef unaligned_type be_uint8_t; #endif - typedef unaligned_type be_int16_t; - typedef unaligned_type be_uint16_t; - typedef unaligned_type be_int32_t; - typedef unaligned_type be_uint32_t; + typedef unaligned_type be_int16_t; + typedef unaligned_type be_uint16_t; + typedef unaligned_type be_int32_t; + typedef unaligned_type be_uint32_t; #if ETL_USING_64BIT_TYPES - typedef unaligned_type be_int64_t; - typedef unaligned_type be_uint64_t; + typedef unaligned_type be_int64_t; + typedef unaligned_type be_uint64_t; #endif - typedef unaligned_type be_float_t; - typedef unaligned_type be_double_t; - typedef unaligned_type be_long_double_t; + typedef unaligned_type be_float_t; + typedef unaligned_type be_double_t; + typedef unaligned_type be_long_double_t; // Network Order typedef be_char_t net_char_t; diff --git a/src/etl/unordered_map.h b/src/etl/unordered_map.h index 130d30e..705dc4c 100644 --- a/src/etl/unordered_map.h +++ b/src/etl/unordered_map.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_UNORDERED_MAP_INCLUDED #define ETL_UNORDERED_MAP_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -54,6 +52,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + //***************************************************************************** ///\defgroup unordered_map unordered_map /// A unordered_map with the capacity defined at compile time. @@ -142,11 +142,11 @@ namespace etl typedef const value_type* const_pointer; typedef size_t size_type; - typedef const TKey& key_parameter_t; typedef etl::forward_link<0> link_t; // Default link. + // The nodes that store the elements. // The nodes that store the elements. struct node_t : public link_t { @@ -158,6 +158,17 @@ namespace etl value_type key_value_pair; }; + friend bool operator ==(const node_t& lhs, const node_t& rhs) + { + return (lhs.key_value_pair.first == rhs.key_value_pair.first) && + (lhs.key_value_pair.second == rhs.key_value_pair.second); + } + + friend bool operator !=(const node_t& lhs, const node_t& rhs) + { + return !(lhs == rhs); + } + protected: typedef etl::intrusive_forward_list bucket_t; @@ -167,14 +178,14 @@ namespace etl // Local iterators iterate over one bucket. typedef typename bucket_t::iterator local_iterator; - typedef typename bucket_t::const_iterator local_const_iterator; + typedef typename bucket_t::const_iterator const_local_iterator; //********************************************************************* class iterator : public etl::iterator { public: - typedef typename iunordered_map::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_map::key_type key_type; typedef typename iunordered_map::mapped_type mapped_type; typedef typename iunordered_map::hasher hasher; @@ -317,7 +328,7 @@ namespace etl { public: - typedef typename iunordered_map::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_map::key_type key_type; typedef typename iunordered_map::mapped_type mapped_type; typedef typename iunordered_map::hasher hasher; @@ -505,7 +516,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_map bucket. ///\return A const iterator to the beginning of the unordered_map bucket. //********************************************************************* - local_const_iterator begin(size_t i) const + const_local_iterator begin(size_t i) const { return pbuckets[i].cbegin(); } @@ -514,7 +525,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_map bucket. ///\return A const iterator to the beginning of the unordered_map bucket. //********************************************************************* - local_const_iterator cbegin(size_t i) const + const_local_iterator cbegin(size_t i) const { return pbuckets[i].cbegin(); } @@ -559,7 +570,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_map bucket. ///\return A const iterator to the end of the unordered_map bucket. //********************************************************************* - local_const_iterator end(size_t i) const + const_local_iterator end(size_t i) const { return pbuckets[i].cend(); } @@ -568,7 +579,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_map bucket. ///\return A const iterator to the end of the unordered_map bucket. //********************************************************************* - local_const_iterator cend(size_t i) const + const_local_iterator cend(size_t i) const { return pbuckets[i].cend(); } @@ -792,7 +803,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key_value_pair.first == key) + if (key_equal_function(inode->key_value_pair.first, key)) { break; } @@ -851,8 +862,8 @@ namespace etl ::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); + // Just add the pointer to the bucket; + bucket.insert_after(bucket.before_begin(), node); adjust_first_last_markers_after_insert(pbucket); @@ -868,7 +879,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key_value_pair.first == key) + if (key_equal_function(inode->key_value_pair.first, key)) { break; } @@ -885,8 +896,8 @@ namespace etl ::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); + // Add the node to the end of the bucket; + bucket.insert_after(inode_previous, node); adjust_first_last_markers_after_insert(&bucket); ++inode_previous; @@ -956,7 +967,7 @@ namespace etl local_iterator icurrent = bucket.begin(); // Search for the key, if we have it. - while ((icurrent != bucket.end()) && (icurrent->key_value_pair.first != key)) + while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key_value_pair.first, key))) { ++iprevious; ++icurrent; @@ -1278,6 +1289,8 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); assign(rhs.cbegin(), rhs.cend()); } @@ -1292,6 +1305,9 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + clear(); + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); this->move(rhs.begin(), rhs.end()); } @@ -1304,12 +1320,14 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_map(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_) + iunordered_map(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_) : pnodepool(&node_pool_) , pbuckets(pbuckets_) , number_of_buckets(number_of_buckets_) , first(pbuckets) , last(pbuckets) + , key_hash_function(key_hash_function_) + , key_equal_function(key_equal_function_) { } @@ -1494,7 +1512,21 @@ namespace etl template bool operator ==(const etl::iunordered_map& lhs, const etl::iunordered_map& rhs) { - return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin()); + const bool sizes_match = (lhs.size() == rhs.size()); + bool elements_match = true; + + if (sizes_match) + { + for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + { + if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + { + elements_match = false; + } + } + } + + return (sizes_match && elements_match); } //*************************************************************************** @@ -1528,8 +1560,8 @@ namespace etl //************************************************************************* /// Default constructor. //************************************************************************* - unordered_map() - : base(node_pool, buckets, MAX_BUCKETS_) + unordered_map(const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS_, hash, equal) { } @@ -1537,7 +1569,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_map(const unordered_map& other) - : base(node_pool, buckets, MAX_BUCKETS_) + : base(node_pool, buckets, MAX_BUCKETS_, other.hash_function(), other.key_eq()) { base::assign(other.cbegin(), other.cend()); } @@ -1547,7 +1579,7 @@ namespace etl /// Move constructor. //************************************************************************* unordered_map(unordered_map&& other) - : base(node_pool, buckets, MAX_BUCKETS_) + : base(node_pool, buckets, MAX_BUCKETS_, other.hash_function(), other.key_eq()) { if (this != &other) { @@ -1563,8 +1595,8 @@ namespace etl ///\param last The iterator to the last element + 1. //************************************************************************* template - unordered_map(TIterator first_, TIterator last_) - : base(node_pool, buckets, MAX_BUCKETS_) + unordered_map(TIterator first_, TIterator last_, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS_, hash, equal) { base::assign(first_, last_); } @@ -1573,8 +1605,8 @@ namespace etl //************************************************************************* /// Construct from initializer_list. //************************************************************************* - unordered_map(std::initializer_list> init) - : base(node_pool, buckets, MAX_BUCKETS_) + unordered_map(std::initializer_list> init, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS_, hash, equal) { base::assign(init.begin(), init.end()); } @@ -1593,12 +1625,7 @@ namespace etl //************************************************************************* unordered_map& operator = (const unordered_map& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::assign(rhs.cbegin(), rhs.cend()); - } - + base::operator=(rhs); return *this; } @@ -1608,13 +1635,7 @@ namespace etl //************************************************************************* unordered_map& operator = (unordered_map&& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::clear(); - base::move(rhs.begin(), rhs.end()); - } - + base::operator=(etl::move(rhs)); return *this; } #endif diff --git a/src/etl/unordered_multimap.h b/src/etl/unordered_multimap.h index 9f5131c..9775db7 100644 --- a/src/etl/unordered_multimap.h +++ b/src/etl/unordered_multimap.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_UNORDERED_MULTIMAP_INCLUDED #define ETL_UNORDERED_MULTIMAP_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -54,6 +52,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + //***************************************************************************** ///\defgroup unordered_multimap unordered_multimap /// A unordered_multimap with the capacity defined at compile time. @@ -146,7 +146,9 @@ namespace etl typedef etl::forward_link<0> link_t; // Default link. - struct node_t : public link_t // The nodes that store the elements. + //********************************************************************* + // The nodes that store the elements. + struct node_t : public link_t { node_t(const_reference key_value_pair_) : key_value_pair(key_value_pair_) @@ -156,6 +158,17 @@ namespace etl value_type key_value_pair; }; + friend bool operator ==(const node_t& lhs, const node_t& rhs) + { + return (lhs.key_value_pair.first == rhs.key_value_pair.first) && + (lhs.key_value_pair.second == rhs.key_value_pair.second); + } + + friend bool operator !=(const node_t& lhs, const node_t& rhs) + { + return !(lhs == rhs); + } + protected: typedef etl::intrusive_forward_list bucket_t; @@ -165,14 +178,14 @@ namespace etl // Local iterators iterate over one bucket. typedef typename bucket_t::iterator local_iterator; - typedef typename bucket_t::const_iterator local_const_iterator; + typedef typename bucket_t::const_iterator const_local_iterator; //********************************************************************* class iterator : public etl::iterator { public: - typedef typename iunordered_multimap::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_multimap::key_type key_type; typedef typename iunordered_multimap::mapped_type mapped_type; typedef typename iunordered_multimap::hasher hasher; @@ -315,7 +328,7 @@ namespace etl { public: - typedef typename iunordered_multimap::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_multimap::key_type key_type; typedef typename iunordered_multimap::mapped_type mapped_type; typedef typename iunordered_multimap::hasher hasher; @@ -504,7 +517,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_multimap bucket. ///\return A const iterator to the beginning of the unordered_multimap bucket. //********************************************************************* - local_const_iterator begin(size_t i) const + const_local_iterator begin(size_t i) const { return pbuckets[i].cbegin(); } @@ -513,7 +526,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_multimap bucket. ///\return A const iterator to the beginning of the unordered_multimap bucket. //********************************************************************* - local_const_iterator cbegin(size_t i) const + const_local_iterator cbegin(size_t i) const { return pbuckets[i].cbegin(); } @@ -558,7 +571,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_multimap bucket. ///\return A const iterator to the end of the unordered_multimap bucket. //********************************************************************* - local_const_iterator end(size_t i) const + const_local_iterator end(size_t i) const { return pbuckets[i].cend(); } @@ -567,7 +580,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_multimap bucket. ///\return A const iterator to the end of the unordered_multimap bucket. //********************************************************************* - local_const_iterator cend(size_t i) const + const_local_iterator cend(size_t i) const { return pbuckets[i].cend(); } @@ -678,7 +691,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key_value_pair.first == key) + if (key_equal_function(inode->key_value_pair.first, key)) { break; } @@ -747,7 +760,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key_value_pair.first == key) + if (key_equal_function(inode->key_value_pair.first, key)) { break; } @@ -831,7 +844,7 @@ namespace etl while (icurrent != bucket.end()) { - if (icurrent->key_value_pair.first == key) + if (key_equal_function(icurrent->key_value_pair.first, key)) { bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key_value_pair.~value_type(); // Destroy the value. @@ -970,7 +983,7 @@ namespace etl ++l; ++n; - while ((l != end()) && (key == l->first)) + while ((l != end()) && key_equal_function(key, l->first)) { ++l; ++n; @@ -1065,7 +1078,7 @@ namespace etl { ++l; - while ((l != end()) && (key == l->first)) + while ((l != end()) && key_equal_function(key, l->first)) { ++l; } @@ -1091,7 +1104,7 @@ namespace etl { ++l; - while ((l != end()) && (key == l->first)) + while ((l != end()) && key_equal_function(key, l->first)) { ++l; } @@ -1184,6 +1197,8 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); assign(rhs.cbegin(), rhs.cend()); } @@ -1199,6 +1214,9 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + clear(); + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); move(rhs.begin(), rhs.end()); } @@ -1211,12 +1229,14 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_multimap(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_) + iunordered_multimap(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_) : pnodepool(&node_pool_) , pbuckets(pbuckets_) , number_of_buckets(number_of_buckets_) , first(pbuckets) , last(pbuckets) + , key_hash_function(key_hash_function_) + , key_equal_function(key_equal_function_) { } @@ -1400,7 +1420,21 @@ namespace etl template bool operator ==(const etl::iunordered_multimap& lhs, const etl::iunordered_multimap& rhs) { - return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin()); + const bool sizes_match = (lhs.size() == rhs.size()); + bool elements_match = true; + + if (sizes_match) + { + for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + { + if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + { + elements_match = false; + } + } + } + + return (sizes_match && elements_match); } //*************************************************************************** @@ -1434,8 +1468,8 @@ namespace etl //************************************************************************* /// Default constructor. //************************************************************************* - unordered_multimap() - : base(node_pool, buckets, MAX_BUCKETS) + unordered_multimap(const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { } @@ -1443,7 +1477,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_multimap(const unordered_multimap& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1457,7 +1491,7 @@ namespace etl /// Move constructor. //************************************************************************* unordered_multimap(unordered_multimap&& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1474,8 +1508,8 @@ namespace etl ///\param last The iterator to the last element + 1. //************************************************************************* template - unordered_multimap(TIterator first_, TIterator last_) - : base(node_pool, buckets, MAX_BUCKETS) + unordered_multimap(TIterator first_, TIterator last_, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { base::assign(first_, last_); } @@ -1484,8 +1518,8 @@ namespace etl //************************************************************************* /// Construct from initializer_list. //************************************************************************* - unordered_multimap(std::initializer_list> init) - : base(node_pool, buckets, MAX_BUCKETS_) + unordered_multimap(std::initializer_list> init, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS_, hash, equal) { base::assign(init.begin(), init.end()); } @@ -1504,11 +1538,7 @@ namespace etl //************************************************************************* unordered_multimap& operator = (const unordered_multimap& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::assign(rhs.cbegin(), rhs.cend()); - } + base::operator=(rhs); return *this; } @@ -1519,12 +1549,7 @@ namespace etl //************************************************************************* unordered_multimap& operator = (unordered_multimap&& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::clear(); - base::move(rhs.begin(), rhs.end()); - } + base::operator=(etl::move(rhs)); return *this; } diff --git a/src/etl/unordered_multiset.h b/src/etl/unordered_multiset.h index 6fba7d1..1821d6e 100644 --- a/src/etl/unordered_multiset.h +++ b/src/etl/unordered_multiset.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_UNORDERED_MULTISET_INCLUDED #define ETL_UNORDERED_MULTISET_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -53,6 +51,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + //***************************************************************************** ///\defgroup unordered_multiset unordered_multiset /// A unordered_multiset with the capacity defined at compile time. @@ -143,6 +143,7 @@ namespace etl typedef etl::forward_link<0> link_t; + //********************************************************************* // The nodes that store the elements. struct node_t : public link_t { @@ -154,6 +155,16 @@ namespace etl value_type key; }; + friend bool operator ==(const node_t& lhs, const node_t& rhs) + { + return (lhs.key == rhs.key); + } + + friend bool operator !=(const node_t& lhs, const node_t& rhs) + { + return !(lhs == rhs); + } + protected: typedef etl::intrusive_forward_list bucket_t; @@ -163,14 +174,14 @@ namespace etl // Local iterators iterate over one bucket. typedef typename bucket_t::iterator local_iterator; - typedef typename bucket_t::const_iterator local_const_iterator; + typedef typename bucket_t::const_iterator const_local_iterator; //********************************************************************* class iterator : public etl::iterator { public: - typedef typename iunordered_multiset::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_multiset::key_type key_type; typedef typename iunordered_multiset::hasher hasher; typedef typename iunordered_multiset::key_equal key_equal; @@ -312,7 +323,7 @@ namespace etl { public: - typedef typename iunordered_multiset::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_multiset::key_type key_type; typedef typename iunordered_multiset::hasher hasher; typedef typename iunordered_multiset::key_equal key_equal; @@ -500,7 +511,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_multiset bucket. ///\return A const iterator to the beginning of the unordered_multiset bucket. //********************************************************************* - local_const_iterator begin(size_t i) const + const_local_iterator begin(size_t i) const { return pbuckets[i].cbegin(); } @@ -509,7 +520,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_multiset bucket. ///\return A const iterator to the beginning of the unordered_multiset bucket. //********************************************************************* - local_const_iterator cbegin(size_t i) const + const_local_iterator cbegin(size_t i) const { return pbuckets[i].cbegin(); } @@ -554,7 +565,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_multiset bucket. ///\return A const iterator to the end of the unordered_multiset bucket. //********************************************************************* - local_const_iterator end(size_t i) const + const_local_iterator end(size_t i) const { return pbuckets[i].cend(); } @@ -563,7 +574,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_multiset bucket. ///\return A const iterator to the end of the unordered_multiset bucket. //********************************************************************* - local_const_iterator cend(size_t i) const + const_local_iterator cend(size_t i) const { return pbuckets[i].cend(); } @@ -673,7 +684,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key == key) + if (key_equal_function(inode->key, key)) { break; } @@ -742,7 +753,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key == key) + if (key_equal_function(inode->key, key)) { break; } @@ -814,7 +825,7 @@ namespace etl while (icurrent != bucket.end()) { - if (icurrent->key == key) + if (key_equal_function(icurrent->key, key)) { bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key.~value_type(); // Destroy the value. @@ -953,7 +964,7 @@ namespace etl ++l; ++n; - while ((l != end()) && (key == *l)) + while ((l != end()) && key_equal_function(key, *l)) { ++l; ++n; @@ -1048,7 +1059,7 @@ namespace etl { ++l; - while ((l != end()) && (key == *l)) + while ((l != end()) && key_equal_function(key, *l)) { ++l; } @@ -1074,7 +1085,7 @@ namespace etl { ++l; - while ((l != end()) && (key == *l)) + while ((l != end()) && key_equal_function(key, *l)) { ++l; } @@ -1167,6 +1178,8 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); assign(rhs.cbegin(), rhs.cend()); } @@ -1183,6 +1196,8 @@ namespace etl if (this != &rhs) { clear(); + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); move(rhs.begin(), rhs.end()); } @@ -1195,12 +1210,14 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_multiset(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_) + iunordered_multiset(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_) : pnodepool(&node_pool_) , pbuckets(pbuckets_) , number_of_buckets(number_of_buckets_) , first(pbuckets) , last(pbuckets) + , key_hash_function(key_hash_function_) + , key_equal_function(key_equal_function_) { } @@ -1384,7 +1401,21 @@ namespace etl template bool operator ==(const etl::iunordered_multiset& lhs, const etl::iunordered_multiset& rhs) { - return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin()); + const bool sizes_match = (lhs.size() == rhs.size()); + bool elements_match = true; + + if (sizes_match) + { + for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + { + if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + { + elements_match = false; + } + } + } + + return (sizes_match && elements_match); } //*************************************************************************** @@ -1412,15 +1443,15 @@ namespace etl public: - static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_; + static ETL_CONSTANT size_t MAX_SIZE = MAX_SIZE_; static ETL_CONSTANT size_t MAX_BUCKETS = MAX_BUCKETS_; //************************************************************************* /// Default constructor. //************************************************************************* - unordered_multiset() - : base(node_pool, buckets, MAX_BUCKETS) + unordered_multiset(const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { } @@ -1428,7 +1459,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_multiset(const unordered_multiset& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1443,7 +1474,7 @@ namespace etl /// Move constructor. //************************************************************************* unordered_multiset(unordered_multiset&& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1460,8 +1491,8 @@ namespace etl ///\param last The iterator to the last element + 1. //************************************************************************* template - unordered_multiset(TIterator first_, TIterator last_) - : base(node_pool, buckets, MAX_BUCKETS) + unordered_multiset(TIterator first_, TIterator last_, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { base::assign(first_, last_); } @@ -1470,8 +1501,8 @@ namespace etl //************************************************************************* /// Construct from initializer_list. //************************************************************************* - unordered_multiset(std::initializer_list init) - : base(node_pool, buckets, MAX_BUCKETS) + unordered_multiset(std::initializer_list init, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { base::assign(init.begin(), init.end()); } @@ -1490,11 +1521,7 @@ namespace etl //************************************************************************* unordered_multiset& operator = (const unordered_multiset& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::assign(rhs.cbegin(), rhs.cend()); - } + base::operator =(rhs); return *this; } @@ -1505,12 +1532,7 @@ namespace etl //************************************************************************* unordered_multiset& operator = (unordered_multiset&& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::clear(); - base::move(rhs.begin(), rhs.end()); - } + base::operator =(etl::move(rhs)); return *this; } diff --git a/src/etl/unordered_set.h b/src/etl/unordered_set.h index 0ffa77c..3a729c6 100644 --- a/src/etl/unordered_set.h +++ b/src/etl/unordered_set.h @@ -31,8 +31,6 @@ SOFTWARE. #ifndef ETL_UNORDERED_SET_INCLUDED #define ETL_UNORDERED_SET_INCLUDED -#include - #include "platform.h" #include "algorithm.h" #include "iterator.h" @@ -54,6 +52,8 @@ SOFTWARE. #include "placement_new.h" #include "initializer_list.h" +#include + //***************************************************************************** ///\defgroup unordered_set unordered_set /// A unordered_set with the capacity defined at compile time. @@ -144,6 +144,7 @@ namespace etl typedef etl::forward_link<0> link_t; + //********************************************************************* // The nodes that store the elements. struct node_t : public link_t { @@ -155,6 +156,16 @@ namespace etl value_type key; }; + friend bool operator ==(const node_t& lhs, const node_t& rhs) + { + return (lhs.key == rhs.key); + } + + friend bool operator !=(const node_t& lhs, const node_t& rhs) + { + return !(lhs == rhs); + } + protected: typedef etl::intrusive_forward_list bucket_t; @@ -164,14 +175,14 @@ namespace etl // Local iterators iterate over one bucket. typedef typename bucket_t::iterator local_iterator; - typedef typename bucket_t::const_iterator local_const_iterator; + typedef typename bucket_t::const_iterator const_local_iterator; //********************************************************************* class iterator : public etl::iterator { public: - typedef typename iunordered_set::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_set::key_type key_type; typedef typename iunordered_set::hasher hasher; typedef typename iunordered_set::key_equal key_equal; @@ -313,7 +324,7 @@ namespace etl { public: - typedef typename iunordered_set::value_type value_type; + typedef typename etl::iterator::value_type value_type; typedef typename iunordered_set::key_type key_type; typedef typename iunordered_set::hasher hasher; typedef typename iunordered_set::key_equal key_equal; @@ -501,7 +512,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_set bucket. ///\return A const iterator to the beginning of the unordered_set bucket. //********************************************************************* - local_const_iterator begin(size_t i) const + const_local_iterator begin(size_t i) const { return pbuckets[i].cbegin(); } @@ -510,7 +521,7 @@ namespace etl /// Returns a const_iterator to the beginning of the unordered_set bucket. ///\return A const iterator to the beginning of the unordered_set bucket. //********************************************************************* - local_const_iterator cbegin(size_t i) const + const_local_iterator cbegin(size_t i) const { return pbuckets[i].cbegin(); } @@ -555,7 +566,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_set bucket. ///\return A const iterator to the end of the unordered_set bucket. //********************************************************************* - local_const_iterator end(size_t i) const + const_local_iterator end(size_t i) const { return pbuckets[i].cend(); } @@ -564,7 +575,7 @@ namespace etl /// Returns a const_iterator to the end of the unordered_set bucket. ///\return A const iterator to the end of the unordered_set bucket. //********************************************************************* - local_const_iterator cend(size_t i) const + const_local_iterator cend(size_t i) const { return pbuckets[i].cend(); } @@ -674,7 +685,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key == key) + if (key_equal_function(inode->key, key)) { break; } @@ -747,7 +758,7 @@ namespace etl while (inode != bucket.end()) { // Do we already have this key? - if (inode->key == key) + if (key_equal_function(inode->key, key)) { break; } @@ -835,7 +846,7 @@ namespace etl local_iterator icurrent = bucket.begin(); // Search for the key, if we have it. - while ((icurrent != bucket.end()) && (icurrent->key != key)) + while ((icurrent != bucket.end()) && (!key_equal_function(icurrent->key, key))) { ++iprevious; ++icurrent; @@ -1161,6 +1172,8 @@ namespace etl // Skip if doing self assignment if (this != &rhs) { + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); assign(rhs.cbegin(), rhs.cend()); } @@ -1177,6 +1190,8 @@ namespace etl if (this != &rhs) { clear(); + key_hash_function = rhs.hash_function(); + key_equal_function = rhs.key_eq(); move(rhs.begin(), rhs.end()); } @@ -1189,12 +1204,14 @@ namespace etl //********************************************************************* /// Constructor. //********************************************************************* - iunordered_set(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_) + iunordered_set(pool_t& node_pool_, bucket_t* pbuckets_, size_t number_of_buckets_, hasher key_hash_function_, key_equal key_equal_function_) : pnodepool(&node_pool_) , pbuckets(pbuckets_) , number_of_buckets(number_of_buckets_) , first(pbuckets) , last(pbuckets) + , key_hash_function(key_hash_function_) + , key_equal_function(key_equal_function_) { } @@ -1297,40 +1314,40 @@ namespace etl //********************************************************************* void adjust_first_last_markers_after_erase(bucket_t* pcurrent) { - if (empty()) - { - first = pbuckets; - last = pbuckets; - } - else - { - if (pcurrent == first) - { - // We erased the first so, we need to search again from where we erased. - while (first->empty()) - { - ++first; - } - } - else if (pcurrent == 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; - bucket_t* pend = last; +if (empty()) +{ + first = pbuckets; + last = pbuckets; +} +else +{ + if (pcurrent == first) + { + // We erased the first so, we need to search again from where we erased. + while (first->empty()) + { + ++first; + } + } + else if (pcurrent == 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; + bucket_t* pend = last; - last = first; + last = first; - while (pcurrent != pend) - { - if (!pcurrent->empty()) - { - last = pcurrent; - } - - ++pcurrent; - } - } + while (pcurrent != pend) + { + if (!pcurrent->empty()) + { + last = pcurrent; } + + ++pcurrent; + } + } +} } // Disable copy construction. @@ -1358,9 +1375,9 @@ namespace etl /// For library debugging purposes only. ETL_DECLARE_DEBUG_COUNT - //************************************************************************* - /// Destructor. - //************************************************************************* + //************************************************************************* + /// Destructor. + //************************************************************************* #if defined(ETL_POLYMORPHIC_UNORDERED_SET) || defined(ETL_POLYMORPHIC_CONTAINERS) public: virtual ~iunordered_set() @@ -1378,20 +1395,34 @@ namespace etl /// Equal operator. ///\param lhs Reference to the first unordered_set. ///\param rhs Reference to the second unordered_set. - ///\return true if the arrays are equal, otherwise false + ///\return true if the sets are equal, otherwise false ///\ingroup unordered_set //*************************************************************************** template bool operator ==(const etl::iunordered_set& lhs, const etl::iunordered_set& rhs) { - return (lhs.size() == rhs.size()) && etl::equal(lhs.begin(), lhs.end(), rhs.begin()); + const bool sizes_match = (lhs.size() == rhs.size()); + bool elements_match = true; + + if (sizes_match) + { + for (size_t i = 0; (i < lhs.bucket_count()) && elements_match; ++i) + { + if (!etl::is_permutation(lhs.begin(i), lhs.end(i), rhs.begin(i))) + { + elements_match = false; + } + } + } + + return (sizes_match && elements_match); } //*************************************************************************** /// Not equal operator. ///\param lhs Reference to the first unordered_set. ///\param rhs Reference to the second unordered_set. - ///\return true if the arrays are not equal, otherwise false + ///\return true if the sets are not equal, otherwise false ///\ingroup unordered_set //*************************************************************************** template @@ -1418,8 +1449,8 @@ namespace etl //************************************************************************* /// Default constructor. //************************************************************************* - unordered_set() - : base(node_pool, buckets, MAX_BUCKETS) + unordered_set(const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { } @@ -1427,7 +1458,7 @@ namespace etl /// Copy constructor. //************************************************************************* unordered_set(const unordered_set& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1441,7 +1472,7 @@ namespace etl /// Move constructor. //************************************************************************* unordered_set(unordered_set&& other) - : base(node_pool, buckets, MAX_BUCKETS) + : base(node_pool, buckets, MAX_BUCKETS, other.hash_function(), other.key_eq()) { // Skip if doing self assignment if (this != &other) @@ -1458,8 +1489,8 @@ namespace etl ///\param last The iterator to the last element + 1. //************************************************************************* template - unordered_set(TIterator first_, TIterator last_) - : base(node_pool, buckets, MAX_BUCKETS) + unordered_set(TIterator first_, TIterator last_, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { base::assign(first_, last_); } @@ -1468,8 +1499,8 @@ namespace etl //************************************************************************* /// Construct from initializer_list. //************************************************************************* - unordered_set(std::initializer_list init) - : base(node_pool, buckets, MAX_BUCKETS) + unordered_set(std::initializer_list init, const THash& hash = THash(), const TKeyEqual& equal = TKeyEqual()) + : base(node_pool, buckets, MAX_BUCKETS, hash, equal) { base::assign(init.begin(), init.end()); } @@ -1488,11 +1519,7 @@ namespace etl //************************************************************************* unordered_set& operator = (const unordered_set& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::assign(rhs.cbegin(), rhs.cend()); - } + base::operator=(rhs); return *this; } @@ -1503,12 +1530,7 @@ namespace etl //************************************************************************* unordered_set& operator = (unordered_set&& rhs) { - // Skip if doing self assignment - if (this != &rhs) - { - base::clear(); - base::move(rhs.begin(), rhs.end()); - } + base::operator=(etl::move(rhs)); return *this; } diff --git a/src/etl/utility.h b/src/etl/utility.h index c6f09ec..0016aac 100644 --- a/src/etl/utility.h +++ b/src/etl/utility.h @@ -93,24 +93,36 @@ namespace etl } #endif - //****************************************************************************** + //*************************************************************************** + ///\brief pair holds two objects of arbitrary type + /// + ///\tparam T1, T2 The types of the elements that the pair stores + //*************************************************************************** template struct pair { - typedef T1 first_type; - typedef T2 second_type; + typedef T1 first_type; ///< @c first_type is the first bound type + typedef T2 second_type; ///< @c second_type is the second bound type - T1 first; - T2 second; + T1 first; ///< @c first is a copy of the first object + T2 second; ///< @c second is a copy of the second object - /// Default constructor + //*************************************************************************** + ///\brief Default constructor + /// + /// The default constructor creates @c first and @c second using their respective default constructors. + //*************************************************************************** ETL_CONSTEXPR pair() : first(T1()) , second(T2()) { } - /// Constructor from parameters + //*************************************************************************** + ///\brief Constructor from parameters + /// + /// Two objects may be passed to a @c pair constructor to be copied. + //*************************************************************************** ETL_CONSTEXPR14 pair(const T1& a, const T2& b) : first(a) , second(b) @@ -118,7 +130,9 @@ namespace etl } #if ETL_USING_CPP11 - /// Move constructor from parameters + //*************************************************************************** + ///\brief Move constructor from parameters. + //*************************************************************************** template ETL_CONSTEXPR14 pair(U1&& a, U2&& b) : first(etl::forward(a)) @@ -127,7 +141,11 @@ namespace etl } #endif - /// Copy constructor + //*************************************************************************** + ///\brief Copy constructor + /// + /// There is also a templated copy constructor for the @c pair class itself. + //*************************************************************************** template ETL_CONSTEXPR14 pair(const pair& other) : first(other.first) @@ -224,7 +242,14 @@ namespace etl #endif }; - //****************************************************************************** + //*************************************************************************** + ///\brief A convenience wrapper for creating a @ref pair from two objects. + /// + ///\param a The first object. + ///\param b The second object. + /// + ///\return A newly-constructed @ref pair object of the appropriate type. + //*************************************************************************** #if ETL_USING_CPP11 template inline pair make_pair(T1&& a, T2&& b) @@ -246,13 +271,14 @@ namespace etl a.swap(b); } - //****************************************************************************** + /// Two pairs of the same type are equal iff their members are equal. template inline bool operator ==(const pair& a, const pair& b) { return (a.first == b.first) && (a.second == b.second); } + /// Uses @c operator== to find the result. template inline bool operator !=(const pair& a, const pair& b) { @@ -266,24 +292,97 @@ namespace etl (!(b.first < a.first) && (a.second < b.second)); } + /// Uses @c operator< to find the result. template inline bool operator >(const pair& a, const pair& b) { return (b < a); } + /// Uses @c operator< to find the result. template inline bool operator <=(const pair& a, const pair& b) { return !(b < a); } + /// Uses @c operator< to find the result. template inline bool operator >=(const pair& a, const pair& b) { return !(a < b); } + //*************************************************************************** + ///\brief Functor to select @ref pair::first + /// + ///\ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element. + /// + ///\b Example + ///\snippet test_utility.cpp test_select1st_example + /// + ///\tparam TPair The function object's argument type. + /// + ///\see select2nd + //*************************************************************************** + template + struct select1st + { + typedef typename TPair::first_type type; ///< type of member @ref pair::first. + + //*************************************************************************** + ///\brief Function call that return @c p.first. + ///\return a reference to member @ref pair::first of the @c pair `p` + //*************************************************************************** + type& operator()(TPair& p) const + { + return p.first; + } + + //*************************************************************************** + ///\copydoc operator()(TPair&)const + // + const type& operator()(const TPair& p) const + { + return p.first; + } + }; + + //*************************************************************************** + ///\brief Functor to select @ref pair::second + /// + ///\ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element. + /// + ///\b Example + ///\snippet test_utility.cpp test_select2nd_example + /// + ///\tparam TPair The function object's argument type. + /// + ///\see select1st + //*************************************************************************** + template + struct select2nd + { + typedef typename TPair::second_type type; ///< type of member @ref pair::second. + + //*************************************************************************** + ///\brief Function call. The return value is `p.second`. + ///\return a reference to member `second` of the pair `p`. + //*************************************************************************** + type& operator()(TPair& p) const + { + return p.second; + } + + //*************************************************************************** + ///\copydoc operator()(TPair&)const + //*************************************************************************** + const type& operator()(const TPair& p) const + { + return p.second; + } + }; + #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED //*************************************************************************** /// exchange (const) diff --git a/src/etl/variant_pool.h b/src/etl/variant_pool.h index 42592cb..c60bd14 100644 --- a/src/etl/variant_pool.h +++ b/src/etl/variant_pool.h @@ -51,14 +51,14 @@ SOFTWARE. #ifndef ETL_VARIANT_POOL_INCLUDED #define ETL_VARIANT_POOL_INCLUDED -#include - #include "platform.h" #include "pool.h" #include "type_traits.h" #include "static_assert.h" #include "largest.h" +#include + namespace etl { //*************************************************************************** diff --git a/src/etl/vector.h b/src/etl/vector.h index 6fee8de..b10c327 100644 --- a/src/etl/vector.h +++ b/src/etl/vector.h @@ -33,10 +33,6 @@ SOFTWARE. #define ETL_IN_VECTOR_H -#include -#include -#include - #include "platform.h" #include "algorithm.h" #include "type_traits.h" @@ -54,6 +50,10 @@ SOFTWARE. #include "algorithm.h" #include "initializer_list.h" +#include +#include +#include + //***************************************************************************** ///\defgroup vector vector /// A vector with the capacity defined at compile time. @@ -1311,6 +1311,9 @@ namespace etl //************************************************************************* /// Destructor. //************************************************************************* +#ifdef ETL_IVECTOR_REPAIR_ENABLE + virtual +#endif ~vector() { this->clear(); @@ -1723,7 +1726,7 @@ namespace etl #endif //************************************************************************* - /// Copy constructor. + /// Construct a copy. //************************************************************************* vector_ext(const vector_ext& other, void* buffer, size_t max_size) : etl::ivector(reinterpret_cast(buffer), max_size) @@ -1731,6 +1734,11 @@ namespace etl (void)etl::ivector::operator = (other); } + //************************************************************************* + /// Copy constructor (Deleted) + //************************************************************************* + vector_ext(const vector_ext& other) ETL_DELETE; + //************************************************************************* /// Assignment operator. //************************************************************************* @@ -1751,6 +1759,11 @@ namespace etl (void)etl::ivector::operator = (etl::move(other)); } + //************************************************************************* + /// Move constructor (Deleted) + //************************************************************************* + vector_ext(vector_ext&& other) ETL_DELETE; + //************************************************************************* /// Move assignment operator. //************************************************************************* diff --git a/src/etl/version.h b/src/etl/version.h index 16c15f5..77b83eb 100644 --- a/src/etl/version.h +++ b/src/etl/version.h @@ -39,8 +39,8 @@ SOFTWARE. ///\ingroup utilities #define ETL_VERSION_MAJOR 20 -#define ETL_VERSION_MINOR 32 -#define ETL_VERSION_PATCH 1 +#define ETL_VERSION_MINOR 35 +#define ETL_VERSION_PATCH 5 #define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH) diff --git a/src/etl/wstring.h b/src/etl/wstring.h index 10b22c1..cde74be 100644 --- a/src/etl/wstring.h +++ b/src/etl/wstring.h @@ -455,18 +455,18 @@ namespace etl /// Make string from string literal or array //*************************************************************************** template - etl::wstring make_string(const wchar_t(&text)[ARRAY_SIZE]) + etl::wstring make_string(const wchar_t(&text)[ARRAY_SIZE]) { - return etl::wstring(text, etl::strlen(text)); + return etl::wstring(text, etl::strlen(text, ARRAY_SIZE - 1U)); } //*************************************************************************** - /// Make string with max capacity from string literal or char array + /// Make string with max capacity from string literal or array //*************************************************************************** template etl::wstring make_string_with_capacity(const wchar_t(&text)[SIZE]) { - return etl::wstring(text, etl::strlen(text)); + return etl::wstring(text, etl::strlen(text, SIZE)); } }