From df83a04166c9da12d9cee7c81df8e413fab00ebd Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 18 Aug 2018 10:09:56 +0100 Subject: [PATCH] Merge remote-tracking branch 'origin/master' into feature/no_stl # Conflicts: # include/etl/memory.h # include/etl/private/ivectorpointer.h # include/etl/stl/alternate/limits.h # include/etl/stl/iterator.h # test/test_no_stl_algorithm.cpp # test/test_no_stl_functional.cpp # test/test_no_stl_limits.cpp # test/test_no_stl_utility.cpp # test/test_vector_pointer.cpp # test/vs2017/etl.vcxproj.filters --- CMakeLists.txt | 5 +- LICENSE | 4 +- README.md | 2 +- .../ArmTimerCallbacks.uvprojx | 2 +- .../ArmTimerCallbacks - C++/etl_profile.h | 5 +- examples/ArmTimerCallbacks - C++/main.cpp | 19 +- include/etl/algorithm.h | 8 + include/etl/array_view.h | 37 +- include/etl/atomic/atomic_gcc_sync.h | 14 +- include/etl/atomic/atomic_std.h | 4 +- include/etl/debug_count.h | 31 +- include/etl/deque.h | 50 +- include/etl/factory.h | 2 +- include/etl/flat_map.h | 34 +- include/etl/flat_multimap.h | 26 +- include/etl/flat_multiset.h | 22 +- include/etl/flat_set.h | 26 +- include/etl/forward_list.h | 70 +-- include/etl/fsm.h | 70 +++ include/etl/fsm_generator.h | 14 + include/etl/intrusive_forward_list.h | 38 +- include/etl/list.h | 32 +- include/etl/map.h | 20 +- include/etl/math_constants.h | 51 ++ include/etl/memory.h | 354 ++++++++++- include/etl/memory_model.h | 36 +- include/etl/multimap.h | 20 +- include/etl/multiset.h | 20 +- include/etl/observer.h | 14 +- include/etl/priority_queue.h | 24 +- include/etl/private/ivectorpointer.h | 24 +- include/etl/private/pvoidvector.h | 483 ++------------ include/etl/private/vector_base.h | 2 +- include/etl/queue.h | 104 ++-- include/etl/queue_mpmc_mutex.h | 78 ++- include/etl/queue_spsc_atomic.h | 103 +-- include/etl/queue_spsc_isr.h | 68 +- include/etl/reference_flat_map.h | 28 +- include/etl/reference_flat_multimap.h | 26 +- include/etl/reference_flat_multiset.h | 22 +- include/etl/reference_flat_set.h | 20 +- include/etl/set.h | 20 +- include/etl/stack.h | 8 +- include/etl/stl/alternate/limits.h | 1 + include/etl/stl/iterator.h | 2 +- include/etl/unordered_map.h | 20 +- include/etl/unordered_multimap.h | 16 +- include/etl/unordered_multiset.h | 14 +- include/etl/unordered_set.h | 16 +- include/etl/variant.h | 18 +- include/etl/variant_pool.h | 2 +- include/etl/vector.h | 42 +- include/etl/version.h | 8 +- library.properties | 1 + src/binary.cpp | 4 +- src/crc16.cpp | 2 +- src/crc16_ccitt.cpp | 2 +- src/crc16_kermit.cpp | 2 +- src/crc32.cpp | 2 +- src/crc32_c.cpp | 2 +- src/crc64_ecma.cpp | 2 +- src/crc8_ccitt.cpp | 4 +- src/error_handler.cpp | 6 +- src/pearson.cpp | 4 +- src/private/pvoidvector.cpp | 456 ++++++++++++++ src/random.cpp | 4 +- support/Release notes.txt | 54 ++ test/codeblocks/ETL.cbp | 14 +- test/data.h | 2 +- test/etl_profile.h | 4 +- test/murmurhash3.cpp | 2 +- test/murmurhash3.h | 2 +- test/test_algorithm.cpp | 4 +- test/test_alignment.cpp | 4 +- test/test_array.cpp | 4 +- test/test_array_view.cpp | 4 +- test/test_array_wrapper.cpp | 2 +- test/test_atomic_gcc_sync.cpp | 4 +- test/test_atomic_std.cpp | 4 +- test/test_binary.cpp | 8 +- test/test_bitset.cpp | 2 +- test/test_bloom_filter.cpp | 12 +- test/test_bsd_checksum.cpp | 2 +- test/test_c_timer_framework.cpp | 2 +- test/test_callback_timer.cpp | 4 +- test/test_checksum.cpp | 2 +- test/test_compare.cpp | 2 +- test/test_constant.cpp | 4 +- test/test_container.cpp | 2 +- test/test_crc.cpp | 12 +- test/test_cyclic_value.cpp | 2 +- test/test_debounce.cpp | 2 +- test/test_deque.cpp | 2 +- test/test_embedded_compile.cpp | 42 +- test/test_endian.cpp | 2 +- test/test_enum_type.cpp | 2 +- test/test_error_handler.cpp | 4 +- test/test_exception.cpp | 2 +- test/test_factory.cpp | 2 +- test/test_fixed_iterator.cpp | 2 +- test/test_flat_map.cpp | 3 +- test/test_flat_multimap.cpp | 3 +- test/test_flat_multiset.cpp | 3 +- test/test_flat_set.cpp | 3 +- test/test_fnv_1.cpp | 2 +- test/test_forward_list.cpp | 3 +- test/test_fsm.cpp | 10 +- test/test_function.cpp | 2 +- test/test_functional.cpp | 2 +- test/test_hash.cpp | 2 +- test/test_instance_count.cpp | 2 +- test/test_integral_limits.cpp | 2 +- test/test_intrusive_forward_list.cpp | 2 +- test/test_intrusive_links.cpp | 2 +- test/test_intrusive_list.cpp | 2 +- test/test_intrusive_queue.cpp | 4 +- test/test_intrusive_stack.cpp | 4 +- test/test_io_port.cpp | 13 +- test/test_iterator.cpp | 2 +- test/test_jenkins.cpp | 2 +- test/test_largest.cpp | 2 +- test/test_list.cpp | 3 +- test/test_map.cpp | 3 +- test/test_maths.cpp | 14 +- test/test_memory.cpp | 46 +- test/test_message_bus.cpp | 10 +- test/test_message_router.cpp | 8 +- test/test_message_timer.cpp | 6 +- test/test_multimap.cpp | 3 +- test/test_multiset.cpp | 3 +- test/test_murmur3.cpp | 2 +- test/test_no_stl_algorithm.cpp | 2 +- test/test_no_stl_functional.cpp | 2 +- test/test_no_stl_limits.cpp | 2 +- test/test_no_stl_utility.cpp | 2 +- test/test_numeric.cpp | 2 +- test/test_observer.cpp | 8 +- test/test_optional.cpp | 4 +- test/test_packet.cpp | 8 +- test/test_parameter_type.cpp | 2 +- test/test_pearson.cpp | 2 +- test/test_pool.cpp | 4 +- test/test_priority_queue.cpp | 2 +- test/test_queue.cpp | 2 +- test/test_queue_memory_model_small.cpp | 589 ++++++++++++++++++ test/test_queue_mpmc_mutex.cpp | 22 +- test/test_queue_mpmc_mutex_small.cpp | 460 ++++++++++++++ test/test_queue_spsc_atomic.cpp | 2 +- test/test_queue_spsc_atomic_small.cpp | 330 ++++++++++ test/test_queue_spsc_isr.cpp | 2 +- test/test_queue_spsc_isr_small.cpp | 587 +++++++++++++++++ test/test_random.cpp | 2 +- test/test_reference_flat_map.cpp | 2 +- test/test_reference_flat_multimap.cpp | 2 +- test/test_reference_flat_multiset.cpp | 2 +- test/test_reference_flat_set.cpp | 2 +- test/test_set.cpp | 3 +- test/test_smallest.cpp | 2 +- test/test_stack.cpp | 2 +- test/test_string_char.cpp | 24 +- test/test_string_u16.cpp | 22 +- test/test_string_u32.cpp | 24 +- test/test_string_view.cpp | 12 +- test/test_string_wchar_t.cpp | 22 +- test/test_task_scheduler.cpp | 6 +- test/test_type_def.cpp | 2 +- test/test_type_lookup.cpp | 2 +- test/test_type_select.cpp | 4 +- test/test_type_traits.cpp | 2 +- test/test_unordered_map.cpp | 2 +- test/test_unordered_multimap.cpp | 2 +- test/test_unordered_multiset.cpp | 4 +- test/test_unordered_set.cpp | 4 +- test/test_user_type.cpp | 2 +- test/test_utility.cpp | 2 +- test/test_variant.cpp | 2 +- test/test_variant_pool.cpp | 2 +- test/test_vector.cpp | 2 +- test/test_vector_non_trivial.cpp | 2 +- test/test_vector_pointer.cpp | 30 +- test/test_visitor.cpp | 2 +- test/test_xor_checksum.cpp | 2 +- test/test_xor_rotate_checksum.cpp | 2 +- test/vs2017/etl.vcxproj | 13 +- test/vs2017/etl.vcxproj.filters | 15 + 185 files changed, 4100 insertions(+), 1215 deletions(-) create mode 100644 include/etl/math_constants.h create mode 100644 test/test_queue_memory_model_small.cpp create mode 100644 test/test_queue_mpmc_mutex_small.cpp create mode 100644 test/test_queue_spsc_atomic_small.cpp create mode 100644 test/test_queue_spsc_isr_small.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 61c57638..1c03b3bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,11 +34,8 @@ add_library(etl ) target_include_directories(etl PUBLIC - include/etl - include/etl/atomic + include include/etl/profiles - PRIVATE - include/etl/private ) if (${ETL_PROFILE} STREQUAL DEFAULT) diff --git a/LICENSE b/LICENSE index 8f66b070..0e19085c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 jwellbelove -https://github.com/ETLCPP/etl -http://www.etlcpp.com +Copyright (c) 2016 jwellbelove, https://github.com/ETLCPP/etl, http://www.etlcpp.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1a4efc26..cfbd3f07 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Embedded Template Library (ETL) ------------------------- -AppVeyor [![Build status](https://ci.appveyor.com/api/projects/status/b7jgecv7unqjw4u0/branch/master?svg=true)](https://ci.appveyor.com/project/jwellbelove/etl/branch/master) +AppVeyor [![Build status](https://ci.appveyor.com/api/projects/status/b7jgecv7unqjw4u0/branch/master?svg=true)](https://ci.appveyor.com/project/jwellbelove/etl/branch/master) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) **Motivation** diff --git a/examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvprojx b/examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvprojx index ed494f20..b7fa094b 100644 --- a/examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvprojx +++ b/examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvprojx @@ -336,7 +336,7 @@ - ..\..\src;..\ArmTimerCallbacks - C++ + ..\..\include;..\ArmTimerCallbacks - C++ diff --git a/examples/ArmTimerCallbacks - C++/etl_profile.h b/examples/ArmTimerCallbacks - C++/etl_profile.h index 4560ba1e..a2e2f33f 100644 --- a/examples/ArmTimerCallbacks - C++/etl_profile.h +++ b/examples/ArmTimerCallbacks - C++/etl_profile.h @@ -9,13 +9,14 @@ #define ETL_IVECTOR_REPAIR_ENABLE #define ETL_IDEQUE_REPAIR_ENABLE #define ETL_IN_UNIT_TEST +#define ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK #if (__CC_ARM == 1) // ARM5 compiler - #include "profiles/armv5.h" + #include "etl/profiles/armv5.h" #else // ARM6 compiler - #include "profiles/armv6.h" + #include "etl/profiles/armv6.h" #endif #endif diff --git a/examples/ArmTimerCallbacks - C++/main.cpp b/examples/ArmTimerCallbacks - C++/main.cpp index 05f19b17..d2d0e5a3 100644 --- a/examples/ArmTimerCallbacks - C++/main.cpp +++ b/examples/ArmTimerCallbacks - C++/main.cpp @@ -9,8 +9,23 @@ extern "C" #include "stm32f4xx.h" // Device header } -#include "function.h" -#include "callback_timer.h" +#include "etl/function.h" +#include "etl/callback_timer.h" +#include "etl/vector.h" + +struct FP +{ + void (*function)(); +}; + +static etl::vector power_callbacks; + +void register_poweroff_callback(void (*function)()) +{ + FP fp = { function }; + power_callbacks.push_back(fp); +} + const int N_TIMERS = 4; diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index a45f66cd..f808db86 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -617,7 +617,11 @@ namespace etl for (TIterator1 i = begin1; i != end1; ++i) { +#if ETL_CPP11_SUPPORTED + if (i == std::find_if(begin1, i, std::bind(predicate, *i, std::placeholders::_1))) +#else if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) +#endif { size_t n = std::count(begin2, end2, *i); @@ -650,7 +654,11 @@ namespace etl { for (TIterator1 i = begin1; i != end1; ++i) { +#if ETL_CPP11_SUPPORTED + if (i == std::find_if(begin1, i, std::bind(predicate, *i, std::placeholders::_1))) +#else if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) +#endif { size_t n = std::count(begin2, end2, *i); diff --git a/include/etl/array_view.h b/include/etl/array_view.h index cc0b6908..ec46d96c 100644 --- a/include/etl/array_view.h +++ b/include/etl/array_view.h @@ -124,8 +124,7 @@ namespace etl /// Construct from std::array or etl::array or other type that supports /// data() and size() member functions. //************************************************************************* - template ::value, void>::type> + template explicit array_view(TArray& a) : mbegin(a.data()), mend(a.data() + a.size()) @@ -135,8 +134,7 @@ namespace etl //************************************************************************* /// Construct from iterators //************************************************************************* - template ::value, void>::type> + template array_view(TIterator begin_, TIterator end_) : mbegin(etl::addressof(*begin_)), mend(etl::addressof(*begin_) + std::distance(begin_, end_)) @@ -147,8 +145,7 @@ namespace etl /// Construct from C array //************************************************************************* template ::value, void>::type> + typename TSize> array_view(TIterator begin_, TSize size_) : mbegin(etl::addressof(*begin_)), mend(etl::addressof(*begin_) + size_) @@ -355,24 +352,22 @@ namespace etl //************************************************************************* /// Assign from iterators //************************************************************************* - template ::value, void>::type> + template void assign(TIterator begin_, TIterator end_) { mbegin = etl::addressof(*begin_); - mend = etl::addressof(*begin_) + std::distance(begin_, end_); + mend = etl::addressof(*begin_) + std::distance(begin_, end_); } //************************************************************************* /// Assign from iterator and size. //************************************************************************* template ::value, void>::type> + typename TSize> void assign(TIterator begin_, TSize size_) { mbegin = etl::addressof(*begin_); - mend = etl::addressof(*begin_) + size_; + mend = etl::addressof(*begin_) + size_; } //************************************************************************* @@ -519,8 +514,7 @@ namespace etl /// Construct from std::array or etl::array or other type that supports /// data() and size() member functions. //************************************************************************* - template ::value, void>::type> + template explicit const_array_view(TArray& a) : mbegin(a.data()), mend(a.data() + a.size()) @@ -530,8 +524,7 @@ namespace etl //************************************************************************* /// Construct from iterators //************************************************************************* - template ::value, void>::type> + template const_array_view(TIterator begin_, TIterator end_) : mbegin(etl::addressof(*begin_)), mend(etl::addressof(*begin_) + std::distance(begin_, end_)) @@ -542,7 +535,7 @@ namespace etl /// Construct from C array //************************************************************************* template ::value, void>::type> + typename TSize> const_array_view(TIterator begin_, TSize size_) : mbegin(etl::addressof(*begin_)), mend(etl::addressof(*begin_) + size_) @@ -706,8 +699,7 @@ namespace etl //************************************************************************* /// Assign from iterators //************************************************************************* - template ::value, void>::type> + template void assign(TIterator begin_, TIterator end_) { mbegin = etl::addressof(*begin_); @@ -718,8 +710,7 @@ namespace etl /// Assign from iterator and size. //************************************************************************* template ::value, void>::type> + typename TSize> void assign(TIterator begin_, TSize size_) { mbegin = etl::addressof(*begin_); @@ -834,7 +825,7 @@ namespace etl size_t operator()(const etl::array_view& view) const { return etl::private_hash::generic_hash(reinterpret_cast(&view[0]), - reinterpret_cast(&view[view.size()])); + reinterpret_cast(&view[view.size()])); } }; @@ -844,7 +835,7 @@ namespace etl size_t operator()(const etl::const_array_view& view) const { return etl::private_hash::generic_hash(reinterpret_cast(&view[0]), - reinterpret_cast(&view[view.size()])); + reinterpret_cast(&view[view.size()])); } }; #endif diff --git a/include/etl/atomic/atomic_gcc_sync.h b/include/etl/atomic/atomic_gcc_sync.h index ca55af77..725c44ac 100644 --- a/include/etl/atomic/atomic_gcc_sync.h +++ b/include/etl/atomic/atomic_gcc_sync.h @@ -34,7 +34,7 @@ SOFTWARE. #include "../static_assert.h" #include "../nullptr.h" -#include +//#include #include #pragma GCC diagnostic push @@ -222,12 +222,12 @@ namespace etl } // Load - T load(etl::memory_order order = etl::memory_order_seq_cst) + T load(etl::memory_order order = etl::memory_order_seq_cst) const { return __sync_fetch_and_add(&value, 0); } - T load(etl::memory_order order = etl::memory_order_seq_cst) volatile + T load(etl::memory_order order = etl::memory_order_seq_cst) const volatile { return __sync_fetch_and_add(&value, 0); } @@ -429,7 +429,7 @@ namespace etl atomic& operator =(const atomic&); atomic& operator =(const atomic&) volatile; - volatile T value; + mutable volatile T value; }; template @@ -562,12 +562,12 @@ namespace etl } // Load - T* load(etl::memory_order order = etl::memory_order_seq_cst) + T* load(etl::memory_order order = etl::memory_order_seq_cst) const { return __sync_fetch_and_add(&value, 0); } - T* load(etl::memory_order order = etl::memory_order_seq_cst) volatile + T* load(etl::memory_order order = etl::memory_order_seq_cst) const volatile { return __sync_fetch_and_add(&value, 0); } @@ -736,7 +736,7 @@ namespace etl atomic& operator =(const atomic&); atomic& operator =(const atomic&) volatile; - volatile T* value; + mutable volatile T* value; }; typedef etl::atomic atomic_char; diff --git a/include/etl/atomic/atomic_std.h b/include/etl/atomic/atomic_std.h index 3a8aeab7..eb3cd146 100644 --- a/include/etl/atomic/atomic_std.h +++ b/include/etl/atomic/atomic_std.h @@ -210,12 +210,12 @@ namespace etl } // Load - T load(etl::memory_order order = etl::memory_order_seq_cst) + T load(etl::memory_order order = etl::memory_order_seq_cst) const { return value.load(order); } - T load(etl::memory_order order = etl::memory_order_seq_cst) volatile + T load(etl::memory_order order = etl::memory_order_seq_cst) const volatile { return value.load(order); } diff --git a/include/etl/debug_count.h b/include/etl/debug_count.h index b603b00c..d5ecaf44 100644 --- a/include/etl/debug_count.h +++ b/include/etl/debug_count.h @@ -41,12 +41,12 @@ SOFTWARE. #if defined(ETL_DEBUG_COUNT) -#define ETL_DECLARE_DEBUG_COUNT etl::debug_count etl_debug_count -#define ETL_INCREMENT_DEBUG_COUNT ++etl_debug_count -#define ETL_DECREMENT_DEBUG_COUNT --etl_debug_count -#define ETL_ADD_DEBUG_COUNT(n) etl_debug_count += (n) -#define ETL_SUBTRACT_DEBUG_COUNT(n) etl_debug_count -= (n) -#define ETL_RESET_DEBUG_COUNT etl_debug_count.clear() +#define ETL_DECLARE_DEBUG_COUNT etl::debug_count etl_debug_count; +#define ETL_INCREMENT_DEBUG_COUNT ++etl_debug_count; +#define ETL_DECREMENT_DEBUG_COUNT --etl_debug_count; +#define ETL_ADD_DEBUG_COUNT(n) etl_debug_count += (n); +#define ETL_SUBTRACT_DEBUG_COUNT(n) etl_debug_count -= (n); +#define ETL_RESET_DEBUG_COUNT etl_debug_count.clear(); namespace etl { @@ -84,25 +84,15 @@ namespace etl return *this; } - inline debug_count& operator +=(int32_t n) - { - count += n; - return *this; - } - - inline debug_count& operator -=(int32_t n) - { - count -= n; - return *this; - } - - inline debug_count& operator +=(size_t n) + template + inline debug_count& operator +=(T n) { count += int32_t(n); return *this; } - inline debug_count& operator -=(size_t n) + template + inline debug_count& operator -=(T n) { count -= int32_t(n); return *this; @@ -135,4 +125,3 @@ namespace etl #endif // ETL_DEBUG_COUNT #endif - diff --git a/include/etl/deque.h b/include/etl/deque.h index a9ed9301..98e2feef 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -214,7 +214,7 @@ namespace etl size_type current_size; ///< The current number of elements in the deque. const size_type CAPACITY; ///< The maximum number of elements in the deque. const size_type BUFFER_SIZE; ///< The number of elements in the buffer. - ETL_DECLARE_DEBUG_COUNT; ///< Internal debugging. + ETL_DECLARE_DEBUG_COUNT ///< Internal debugging. }; //*************************************************************************** @@ -935,7 +935,7 @@ namespace etl --_begin; p = etl::addressof(*_begin); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _begin; } else if (insert_position == end()) @@ -943,7 +943,7 @@ namespace etl p = etl::addressof(*_end); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _end - 1; } else @@ -1000,7 +1000,7 @@ namespace etl --_begin; p = etl::addressof(*_begin); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _begin; } else if (insert_position == end()) @@ -1008,7 +1008,7 @@ namespace etl p = etl::addressof(*_end); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _end - 1; } else @@ -1065,7 +1065,7 @@ namespace etl --_begin; p = etl::addressof(*_begin); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _begin; } else if (insert_position == end()) @@ -1073,7 +1073,7 @@ namespace etl p = etl::addressof(*_end); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _end - 1; } else @@ -1130,7 +1130,7 @@ namespace etl --_begin; p = etl::addressof(*_begin); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _begin; } else if (insert_position == end()) @@ -1138,7 +1138,7 @@ namespace etl p = etl::addressof(*_end); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT position = _end - 1; } else @@ -1538,7 +1538,7 @@ namespace etl ::new (&(*_end)) T(value1); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1555,7 +1555,7 @@ namespace etl ::new (&(*_end)) T(value1, value2); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1572,7 +1572,7 @@ namespace etl ::new (&(*_end)) T(value1, value2, value3); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1589,7 +1589,7 @@ namespace etl ::new (&(*_end)) T(value1, value2, value3, value4); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1645,7 +1645,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(value1); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1662,7 +1662,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(value1, value2); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1679,7 +1679,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(value1, value2, value3); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1696,7 +1696,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(value1, value2, value3, value4); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -1811,7 +1811,7 @@ namespace etl if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::value) { current_size = 0; - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT } else { @@ -1850,7 +1850,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -1882,7 +1882,7 @@ namespace etl ::new (&(*item++)) T(*from); ++from; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } while (n-- != 0); } @@ -1894,7 +1894,7 @@ namespace etl ::new (&(*_end)) T(); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -1905,7 +1905,7 @@ namespace etl --_begin; ::new (&(*_begin)) T(value); ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -1916,7 +1916,7 @@ namespace etl ::new (&(*_end)) T(value); ++_end; ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -1926,7 +1926,7 @@ namespace etl { (*_begin).~T(); --current_size; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT ++_begin; } @@ -1938,7 +1938,7 @@ namespace etl --_end; (*_end).~T(); --current_size; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* diff --git a/include/etl/factory.h b/include/etl/factory.h index 6c4e46f0..57f83eca 100644 --- a/include/etl/factory.h +++ b/include/etl/factory.h @@ -40,7 +40,7 @@ SOFTWARE. #include "alignment.h" #include "static_assert.h" #include "type_lookup.h" -#include +#include "pool.h" #if defined(ETL_COMPILER_GCC) #warning THIS CLASS IS DEPRECATED!USE VARIANT_POOL INSTEAD. diff --git a/include/etl/flat_map.h b/include/etl/flat_map.h index d2c78810..7184590c 100644 --- a/include/etl/flat_map.h +++ b/include/etl/flat_map.h @@ -101,13 +101,15 @@ namespace etl bool operator ()(const value_type& element, key_type key) const { - return key_compare()(element.first, key); + return comp(element.first, key); } bool operator ()(key_type key, const value_type& element) const { - return key_compare()(key, element.first); + return comp(key, element.first); } + + key_compare comp; }; public: @@ -234,7 +236,7 @@ namespace etl { value_type* pvalue = storage.allocate(); ::new (pvalue) value_type(); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT std::pair result = refmap_t::insert_at(i_element, *pvalue); i_element->second = result.first->second; @@ -300,13 +302,13 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (i_element->first != value.first))) + if ((i_element == end()) || compare(i_element->first, value.first) || compare(value.first, i_element->first)) { ETL_ASSERT(!refmap_t::full(), ETL_ERROR(flat_map_full)); value_type* pvalue = storage.allocate(); ::new (pvalue) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } @@ -367,7 +369,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (i_element->first != key))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } else @@ -399,7 +401,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (i_element->first != key))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } else @@ -431,7 +433,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (i_element->first != key))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } else @@ -463,7 +465,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (i_element->first != key))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } else @@ -495,7 +497,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (i_element->first != key))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); } else @@ -525,7 +527,7 @@ namespace etl i_element->~value_type(); storage.release(etl::addressof(*i_element)); refmap_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return 1; } } @@ -539,7 +541,7 @@ namespace etl i_element->~value_type(); storage.release(etl::addressof(*i_element)); refmap_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //********************************************************************* @@ -558,7 +560,7 @@ namespace etl itr->~value_type(); storage.release(etl::addressof(*itr)); ++itr; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } refmap_t::erase(first, last); @@ -585,7 +587,7 @@ namespace etl } } - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT refmap_t::clear(); } @@ -764,8 +766,10 @@ namespace etl storage_t& storage; + TKeyCompare compare; + /// Internal debugging. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/flat_multimap.h b/include/etl/flat_multimap.h index e2b9a8c4..d6c3aefc 100644 --- a/include/etl/flat_multimap.h +++ b/include/etl/flat_multimap.h @@ -103,13 +103,15 @@ namespace etl bool operator ()(const value_type& element, key_type key) const { - return key_compare()(element.first, key); + return comp(element.first, key); } bool operator ()(key_type key, const value_type& element) const { - return key_compare()(key, element.first); + return comp(key, element.first); } + + key_compare comp; }; public: @@ -260,7 +262,7 @@ namespace etl value_type* pvalue = storage.allocate(); ::new (pvalue) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refmap_t::insert_at(i_element, *pvalue); return result; @@ -313,7 +315,7 @@ namespace etl ::new ((void*)etl::addressof(pvalue->first)) key_type(key); ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value); iterator i_element = lower_bound(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return refmap_t::insert_at(i_element, *pvalue); } @@ -331,7 +333,7 @@ namespace etl ::new ((void*)etl::addressof(pvalue->first)) key_type(key); ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1); iterator i_element = lower_bound(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return refmap_t::insert_at(i_element, *pvalue); } @@ -349,7 +351,7 @@ namespace etl ::new ((void*)etl::addressof(pvalue->first)) key_type(key); ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2); iterator i_element = lower_bound(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return refmap_t::insert_at(i_element, *pvalue); } @@ -367,7 +369,7 @@ namespace etl ::new ((void*)etl::addressof(pvalue->first)) key_type(key); ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3); iterator i_element = lower_bound(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return refmap_t::insert_at(i_element, *pvalue); } @@ -385,7 +387,7 @@ namespace etl ::new ((void*)etl::addressof(pvalue->first)) key_type(key); ::new ((void*)etl::addressof(pvalue->second)) mapped_type(value1, value2, value3, value4); iterator i_element = lower_bound(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return refmap_t::insert_at(i_element, *pvalue); } @@ -420,7 +422,7 @@ namespace etl i_element->~value_type(); storage.release(etl::addressof(*i_element)); refmap_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //********************************************************************* @@ -439,7 +441,7 @@ namespace etl itr->~value_type(); storage.release(etl::addressof(*itr)); ++itr; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } refmap_t::erase(first, last); @@ -466,7 +468,7 @@ namespace etl } } - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT refmap_t::clear(); } @@ -646,7 +648,7 @@ namespace etl storage_t& storage; /// Internal debugging. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/flat_multiset.h b/include/etl/flat_multiset.h index 023a526a..27d232a7 100644 --- a/include/etl/flat_multiset.h +++ b/include/etl/flat_multiset.h @@ -232,11 +232,11 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(flat_multiset_full)); - iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); + iterator i_element = std::lower_bound(begin(), end(), value, compare); value_type* pvalue = storage.allocate(); ::new (pvalue) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); return result; @@ -292,7 +292,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return std::pair(refset_t::insert_at(i_element, *pvalue)); } @@ -310,7 +310,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return std::pair(refset_t::insert_at(i_element, *pvalue)); } @@ -328,7 +328,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return std::pair(refset_t::insert_at(i_element, *pvalue)); } @@ -346,7 +346,7 @@ namespace etl iterator i_element = lower_bound(*pvalue); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return std::pair(refset_t::insert_at(i_element, *pvalue)); } @@ -380,7 +380,7 @@ namespace etl etl::destroy_at(etl::addressof(*i_element)); storage.release(etl::addressof(*i_element)); refset_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //********************************************************************* @@ -399,7 +399,7 @@ namespace etl etl::destroy_at(etl::addressof(*itr)); storage.release(etl::addressof(*itr)); ++itr; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } refset_t::erase(first, last); @@ -426,7 +426,7 @@ namespace etl } } - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT refset_t::clear(); } @@ -605,8 +605,10 @@ namespace etl storage_t& storage; + TKeyCompare compare; + /// Internal debugging. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/flat_set.h b/include/etl/flat_set.h index d4dd28c0..bb1b4dbe 100644 --- a/include/etl/flat_set.h +++ b/include/etl/flat_set.h @@ -233,13 +233,13 @@ namespace etl std::pair result(i_element, false); // Doesn't already exist? - if ((i_element == end() || (*i_element != value))) + if ((i_element == end()) || compare(*i_element, value) || compare(value, *i_element)) { ETL_ASSERT(!refset_t::full(), ETL_ERROR(flat_set_full)); value_type* pvalue = storage.allocate(); ::new (pvalue) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); } @@ -300,7 +300,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (*i_element != *pvalue))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); } else @@ -333,7 +333,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (*i_element != *pvalue))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); } else @@ -366,7 +366,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (*i_element != *pvalue))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); } else @@ -399,7 +399,7 @@ namespace etl // Doesn't already exist? if ((i_element == end() || (*i_element != *pvalue))) { - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT result = refset_t::insert_at(i_element, *pvalue); } else @@ -431,7 +431,7 @@ namespace etl etl::destroy_at(etl::addressof(*i_element)); storage.release(etl::addressof(*i_element)); refset_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return 1; } } @@ -445,7 +445,7 @@ namespace etl etl::destroy_at(etl::addressof(*i_element)); storage.release(etl::addressof(*i_element)); refset_t::erase(i_element); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //********************************************************************* @@ -464,7 +464,7 @@ namespace etl etl::destroy_at(etl::addressof(*itr)); storage.release(etl::addressof(*itr)); ++itr; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } refset_t::erase(first, last); @@ -488,11 +488,11 @@ namespace etl etl::destroy_at(etl::addressof(*itr)); storage.release(etl::addressof(*itr)); ++itr; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } } - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT refset_t::clear(); } @@ -671,8 +671,10 @@ namespace etl storage_t& storage; + TKeyCompare compare; + /// Internal debugging. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 35d3a2d4..496d37a4 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -236,17 +236,17 @@ namespace etl //************************************************************************* /// Get the head node. //************************************************************************* - node_t& get_head() + node_t* get_head() { - return *start_node.next; + return start_node.next; } //************************************************************************* /// Get the head node. //************************************************************************* - const node_t& get_head() const + const node_t* get_head() const { - return *start_node.next; + return start_node.next; } //************************************************************************* @@ -278,7 +278,7 @@ namespace etl node_t start_node; ///< The node that acts as the forward_list start. etl::ipool* p_node_pool; ///< The pool of data nodes used in the list. const size_type MAX_SIZE; ///< The maximum size of the forward_list. - ETL_DECLARE_DEBUG_COUNT; ///< Internal debugging. + ETL_DECLARE_DEBUG_COUNT ///< Internal debugging. }; //*************************************************************************** @@ -329,8 +329,8 @@ namespace etl { } - iterator(node_t& node) - : p_node(&node) + iterator(node_t* node) + : p_node(node) { } @@ -417,13 +417,13 @@ namespace etl { } - const_iterator(node_t& node) - : p_node(&node) + const_iterator(node_t* node) + : p_node(node) { } - const_iterator(const node_t& node) - : p_node(&node) + const_iterator(const node_t* node) + : p_node(node) { } @@ -493,7 +493,7 @@ namespace etl //************************************************************************* iterator begin() { - return iterator(data_cast(get_head())); + return iterator(get_head()); } //************************************************************************* @@ -501,7 +501,7 @@ namespace etl //************************************************************************* const_iterator begin() const { - return const_iterator(data_cast(get_head())); + return const_iterator(get_head()); } //************************************************************************* @@ -509,7 +509,7 @@ namespace etl //************************************************************************* iterator before_begin() { - return iterator(static_cast(start_node)); + return iterator(&start_node); } //************************************************************************* @@ -517,7 +517,7 @@ namespace etl //************************************************************************* const_iterator before_begin() const { - return const_iterator(static_cast(start_node)); + return const_iterator(&start_node); } //************************************************************************* @@ -565,7 +565,7 @@ namespace etl //************************************************************************* reference front() { - return data_cast(get_head()).value; + return data_cast(*get_head()).value; } //************************************************************************* @@ -573,7 +573,7 @@ namespace etl //************************************************************************* const_reference front() const { - return data_cast(get_head()).value; + return data_cast(*get_head()).value; } //************************************************************************* @@ -658,7 +658,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); } @@ -673,7 +673,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); } @@ -688,7 +688,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); } @@ -703,7 +703,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); } @@ -780,7 +780,7 @@ namespace etl data_node_t& data_node = allocate_data_node(value); insert_node_after(*position.p_node, data_node); - return iterator(data_node); + return iterator(&data_node); } //************************************************************************* @@ -793,10 +793,10 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(*position.p_node, *p_data_node); - return iterator(*p_data_node); + return iterator(p_data_node); } //************************************************************************* @@ -809,10 +809,10 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(*position.p_node, *p_data_node); - return iterator(*p_data_node); + return iterator(p_data_node); } //************************************************************************* @@ -825,10 +825,10 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(*position.p_node, *p_data_node); - return iterator(*p_data_node); + return iterator(p_data_node); } //************************************************************************* @@ -841,10 +841,10 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node_after(*position.p_node, *p_data_node); - return iterator(*p_data_node); + return iterator(p_data_node); } //************************************************************************* @@ -931,7 +931,7 @@ namespace etl } else { - return iterator(*p_last); + return iterator(p_last); } } else @@ -1023,7 +1023,7 @@ namespace etl return; } - node_t* last = &get_head(); + node_t* last = get_head(); node_t* current = last->next; while (current != nullptr) @@ -1247,7 +1247,7 @@ namespace etl if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::value) { p_node_pool->release_all(); - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT } else { @@ -1326,7 +1326,7 @@ namespace etl { data_node_t* p_node = p_node_pool->allocate(); ::new (&(p_node->value)) T(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return *p_node; } @@ -1338,7 +1338,7 @@ namespace etl { node.value.~T(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Disable copy construction. diff --git a/include/etl/fsm.h b/include/etl/fsm.h index 3a837f39..8ba4b972 100644 --- a/include/etl/fsm.h +++ b/include/etl/fsm.h @@ -390,6 +390,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -451,6 +455,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -511,6 +519,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -570,6 +582,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -627,6 +643,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -683,6 +703,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -738,6 +762,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -792,6 +820,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -844,6 +876,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -895,6 +931,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -945,6 +985,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -994,6 +1038,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -1041,6 +1089,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -1087,6 +1139,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -1132,6 +1188,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -1176,6 +1236,10 @@ namespace etl } protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { @@ -1216,6 +1280,12 @@ namespace etl : ifsm_state(STATE_ID) { } + + protected: + + ~fsm_state() + { + } inline TContext& get_fsm_context() const { diff --git a/include/etl/fsm_generator.h b/include/etl/fsm_generator.h index a937542e..176fa60d 100644 --- a/include/etl/fsm_generator.h +++ b/include/etl/fsm_generator.h @@ -411,6 +411,10 @@ namespace etl cog.outl("") cog.outl("protected:") cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") cog.outl(" inline TContext& get_fsm_context() const") cog.outl(" {") cog.outl(" return static_cast(ifsm_state::get_fsm_context());") @@ -484,6 +488,10 @@ namespace etl cog.outl("") cog.outl("protected:") cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") cog.outl(" inline TContext& get_fsm_context() const") cog.outl(" {") cog.outl(" return static_cast(ifsm_state::get_fsm_context());") @@ -538,6 +546,12 @@ namespace etl cog.outl(" {") cog.outl(" }") cog.outl("") + cog.outl("protected:") + cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") cog.outl(" inline TContext& get_fsm_context() const") cog.outl(" {") cog.outl(" return static_cast(ifsm_state::get_fsm_context());") diff --git a/include/etl/intrusive_forward_list.h b/include/etl/intrusive_forward_list.h index 3f6394c3..49ec0e97 100644 --- a/include/etl/intrusive_forward_list.h +++ b/include/etl/intrusive_forward_list.h @@ -278,17 +278,17 @@ namespace etl //************************************************************************* /// Get the head link. //************************************************************************* - link_type& get_head() + link_type* get_head() { - return *start_link.etl_next; + return start_link.etl_next; } //************************************************************************* /// Get the head link. //************************************************************************* - const link_type& get_head() const + const link_type* get_head() const { - return *start_link.etl_next; + return start_link.etl_next; } //************************************************************************* @@ -338,8 +338,8 @@ namespace etl { } - iterator(value_type& value) - : p_value(&value) + iterator(value_type* value) + : p_value(value) { } @@ -428,8 +428,8 @@ namespace etl { } - const_iterator(const value_type& value) - : p_value(&value) + const_iterator(const value_type* value) + : p_value(value) { } @@ -526,7 +526,7 @@ namespace etl //************************************************************************* iterator begin() { - return iterator(static_cast(this->get_head())); + return iterator(static_cast(this->get_head())); } //************************************************************************* @@ -534,7 +534,7 @@ namespace etl //************************************************************************* const_iterator begin() const { - return const_iterator(static_cast(this->get_head())); + return const_iterator(static_cast(this->get_head())); } //************************************************************************* @@ -542,7 +542,7 @@ namespace etl //************************************************************************* iterator before_begin() { - return iterator(static_cast(this->start_link)); + return iterator(&(static_cast(this->start_link))); } //************************************************************************* @@ -550,7 +550,7 @@ namespace etl //************************************************************************* const_iterator before_begin() const { - return const_iterator(static_cast(this->start_link)); + return const_iterator(&(static_cast(this->start_link))); } //************************************************************************* @@ -558,7 +558,7 @@ namespace etl //************************************************************************* const_iterator cbegin() const { - return const_iterator(static_cast(this->get_head())); + return const_iterator(static_cast(this->get_head())); } //************************************************************************* @@ -590,7 +590,7 @@ namespace etl //************************************************************************* reference front() { - return static_cast(this->get_head()); + return static_cast(*(this->get_head())); } //************************************************************************* @@ -598,7 +598,7 @@ namespace etl //************************************************************************* const_reference front() const { - return static_cast(this->get_head());; + return static_cast(*(this->get_head()));; } //************************************************************************* @@ -607,7 +607,7 @@ namespace etl iterator insert_after(iterator position, value_type& value) { this->insert_link_after(*position.p_value, value); - return iterator(value); + return iterator(&value); } //************************************************************************* @@ -686,7 +686,7 @@ namespace etl return; } - link_type* last = &this->get_head(); + link_type* last = this->get_head(); link_type* current = last->etl_next; while (current != nullptr) @@ -886,7 +886,7 @@ namespace etl { if (!other.empty()) { - link_type& first = other.get_head(); + link_type& first = *other.get_head(); if (&other != this) { @@ -982,7 +982,7 @@ namespace etl ETL_ASSERT(etl::is_sorted(begin(), end(), compare), ETL_ERROR(intrusive_forward_list_unsorted)); #endif - value_type* other_begin = static_cast(&other.get_head()); + value_type* other_begin = static_cast(other.get_head()); value_type* other_terminal = nullptr; value_type* before = static_cast(&this->start_link); diff --git a/include/etl/list.h b/include/etl/list.h index a95e9f78..8d43b7e8 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -320,7 +320,7 @@ namespace etl etl::ipool* p_node_pool; ///< The pool of data nodes used in the list. node_t terminal_node; ///< The node that acts as the list start and end. const size_type MAX_SIZE; ///< The maximum size of the list. - ETL_DECLARE_DEBUG_COUNT; ///< Internal debugging. + ETL_DECLARE_DEBUG_COUNT ///< Internal debugging. }; //*************************************************************************** @@ -789,7 +789,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); } @@ -804,7 +804,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); } @@ -819,7 +819,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); } @@ -834,7 +834,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); } @@ -880,7 +880,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); } @@ -895,7 +895,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); } @@ -910,7 +910,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); } @@ -925,7 +925,7 @@ namespace etl #endif data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); } @@ -964,7 +964,7 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(*position.p_node, *p_data_node); return iterator(*p_data_node); @@ -980,7 +980,7 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(*position.p_node, *p_data_node); return iterator(*p_data_node); @@ -996,7 +996,7 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(*position.p_node, *p_data_node); return iterator(*p_data_node); @@ -1012,7 +1012,7 @@ namespace etl data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT insert_node(*position.p_node, *p_data_node); return iterator(*p_data_node); @@ -1456,7 +1456,7 @@ namespace etl if ETL_IF_CONSTEXPR(etl::is_trivially_destructible::value) { p_node_pool->release_all(); - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT } else { @@ -1549,7 +1549,7 @@ namespace etl { data_node_t* p_data_node = p_node_pool->allocate(); ::new (&(p_data_node->value)) T(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return *p_data_node; } @@ -1561,7 +1561,7 @@ namespace etl { node.value.~T(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Disable copy construction. diff --git a/include/etl/map.h b/include/etl/map.h index ea65fc9b..785e566f 100644 --- a/include/etl/map.h +++ b/include/etl/map.h @@ -452,14 +452,14 @@ namespace etl size_type current_size; ///< The number of the used nodes. const size_type CAPACITY; ///< The maximum size of the map. Node* root_node; ///< The node that acts as the map root. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT }; //*************************************************************************** /// A templated base for all etl::map types. ///\ingroup map //*************************************************************************** - template + template > class imap : public etl::map_base { public: @@ -481,7 +481,7 @@ namespace etl { bool operator ()(const key_type& key1, const key_type& key2) const { - return key_compare()(key1, key2); + return compare(key1, key2); } }; @@ -492,7 +492,7 @@ namespace etl { bool operator ()(const value_type& value1, const value_type& value2) const { - return key_compare()(value1.first, value2.first); + return compare(value1.first, value2.first); } }; @@ -524,15 +524,15 @@ namespace etl //************************************************************************* bool node_comp(const Data_Node& node1, const Data_Node& node2) const { - return key_compare()(node1.value.first, node2.value.first); + return compare(node1.value.first, node2.value.first); } bool node_comp(const Data_Node& node, key_parameter_t key) const { - return key_compare()(node.value.first, key); + return compare(node.value.first, key); } bool node_comp(key_parameter_t key, const Data_Node& node) const { - return key_compare()(key, node.value.first); + return compare(key, node.value.first); } private: @@ -540,6 +540,8 @@ namespace etl /// The pool of data nodes used in the map. ipool* p_node_pool; + key_compare compare; + //************************************************************************* /// Downcast a Node* to a Data_Node* //************************************************************************* @@ -1262,7 +1264,7 @@ namespace etl { Data_Node& node = *p_node_pool->allocate(); ::new (&node.value) const value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return node; } @@ -1273,7 +1275,7 @@ namespace etl { node.value.~value_type(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* diff --git a/include/etl/math_constants.h b/include/etl/math_constants.h new file mode 100644 index 00000000..1e26747d --- /dev/null +++ b/include/etl/math_constants.h @@ -0,0 +1,51 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2018 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +coPIes of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +coPIes or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_MATH_CONSTANTS_INCLUDED +#define ETL_MATH_CONSTANTS_INCLUDED + +#include "platform.h" + +namespace etl +{ + namespace math + { + const double pi = 3.14159265358979; + const double pi_reciprocal = 0.31830988618379; + const double pi_squared = 9.86960440108936; + const double e = 2.71828182845905; + const double e_reciprocal = 0.36787944117144; + const double e_squared = 7.38905609893065; + const double root2 = 1.41421356237310; + const double root2_reciprocal = 0.70710678118655; + const double euler = 0.57721566490153; + const double golden_ratio = 1.61803398874989; + }; +} + +#endif diff --git a/include/etl/memory.h b/include/etl/memory.h index 6474ab7d..de82cc95 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -5,7 +5,7 @@ The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl -http://www.etlcpp.com +https://www.etlcpp.com Copyright(c) 2017 jwellbelove @@ -31,13 +31,14 @@ SOFTWARE. #ifndef ETL_MEMORY_INCLUDED #define ETL_MEMORY_INCLUDED -#include "algorithm.h" - #include "platform.h" +#include "algorithm.h" #include "type_traits.h" #include "stl/iterator.h" +#include + ///\defgroup memory memory ///\ingroup etl namespace etl @@ -96,7 +97,7 @@ namespace etl count += int32_t(std::distance(o_begin, o_end)); std::fill(o_begin, o_end, value); - + return o_end; } @@ -121,7 +122,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value) + TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value) { return etl::uninitialized_fill(o_begin, o_begin + n, value); } @@ -132,7 +133,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count) + TOutputIterator uninitialized_fill_n(TOutputIterator o_begin, TSize n, const T& value, TCounter& count) { count += n; @@ -208,7 +209,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin) + TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin) { return etl::uninitialized_copy(i_begin, i_begin + n, o_begin); } @@ -219,7 +220,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count) + TOutputIterator uninitialized_copy_n(TInputIterator i_begin, TSize n, TOutputIterator o_begin, TCounter& count) { count += n; @@ -340,7 +341,7 @@ namespace etl /// Default initialises N objects to uninitialised memory. ///\ingroup memory //***************************************************************************** - template + template typename etl::enable_if::value_type>::value, TOutputIterator>::type uninitialized_default_construct_n(TOutputIterator o_begin, TSize n) { @@ -390,7 +391,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline void create_value_at(T* p) + void create_value_at(T* p) { ::new (p) T(); } @@ -400,7 +401,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline void create_value_at(T* p, TCounter& count) + void create_value_at(T* p, TCounter& count) { ::new (p) T(); ++count; @@ -411,7 +412,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline void create_copy_at(T* p, const T& value) + void create_copy_at(T* p, const T& value) { ::new (p) T(value); } @@ -421,7 +422,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline void create_copy_at(T* p, const T& value, TCounter& count) + void create_copy_at(T* p, const T& value, TCounter& count) { ::new (p) T(value); ++count; @@ -432,7 +433,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_default_at(T* p) + T& make_default_at(T* p) { ::new (p) T(); return *reinterpret_cast(p); @@ -443,7 +444,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_default_at(T* p, TCounter& count) + T& make_default_at(T* p, TCounter& count) { ::new (p) T(); ++count; @@ -455,7 +456,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_copy_at(T* p, const T& other) + T& make_copy_at(T* p, const T& other) { ::new (p) T(other); return *reinterpret_cast(p); @@ -466,7 +467,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_copy_at(T* p, const T& other, TCounter& count) + T& make_copy_at(T* p, const T& other, TCounter& count) { ::new (p) T(other); ++count; @@ -478,7 +479,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_value_at(T* p, const TParameter& value) + T& make_value_at(T* p, const TParameter& value) { ::new (p) T(value); return *reinterpret_cast(p); @@ -489,7 +490,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - inline T& make_value_at(T* p, const TParameter& value, TCounter& count) + T& make_value_at(T* p, const TParameter& value, TCounter& count) { ::new (p) T(value); ++count; @@ -768,6 +769,321 @@ namespace etl return *reinterpret_cast(p); } }; + + //***************************************************************************** + /// Default deleter. + ///\tparam T The pointed to type type. + ///\ingroup memory + //***************************************************************************** + template + struct default_delete + { + void operator()(T* p) const + { + delete p; + } + }; + + //***************************************************************************** + /// Default deleter for arrays. + ///\tparam T The pointed to type type. + ///\ingroup memory + //***************************************************************************** + template + struct default_delete + { + template + void operator()(U* p) const + { + delete[] p; + } + }; + + //***************************************************************************** + /// Unique pointer. + ///\tparam T The pointed to type type. + ///\ingroup memory + //***************************************************************************** + template > + class unique_ptr + { + public: + + typedef T element_type; + typedef T* pointer; + typedef T& reference; + + ETL_CONSTEXPR unique_ptr() + : p(nullptr) + { + } + + ETL_CONSTEXPR explicit unique_ptr (pointer p_) + : p(p_) + { + } + +#if ETL_CPP11_SUPPORTED + unique_ptr (unique_ptr&& p_) + : p(p_.release()) + { + } +#endif + + ~unique_ptr() + { + deleter(p); + } + + ETL_CONSTEXPR pointer get() const + { + return p; + } + + TDeleter& get_deleter() + { + return deleter; + } + + const TDeleter& get_deleter() const + { + return deleter; + } + + pointer release() + { + pointer value = p; + p = nullptr; + + return value; + } + + void reset(pointer p_ = pointer()) + { + assert(p_ != p); + + pointer value = p; + p = p_; + delete value; + } + + void swap(unique_ptr& value) + { + std::swap(p, value.p); + } + + ETL_CONSTEXPR explicit operator bool() const + { + return (p != nullptr); + } + + unique_ptr& operator =(pointer p_) + { + reset(p_); + + return *this; + } + +#if ETL_CPP11_SUPPORTED + unique_ptr& operator =(unique_ptr&& p_) + { + reset(p_.release()); + + return *this; + } +#endif + + ETL_CONSTEXPR reference operator *() const + { + return *get(); + } + + ETL_CONSTEXPR pointer operator ->() const + { + return get(); + } + + ETL_CONSTEXPR reference operator [](size_t i) const + { + return get()[i]; + } + + ETL_CONSTEXPR bool operator== (const pointer p_) const + { + return p == p_; + } + + ETL_CONSTEXPR bool operator== (const unique_ptr& p_) const + { + return p == p_.p; + } + + ETL_CONSTEXPR bool operator< (const unique_ptr& p_) const + { + return p < p_.p; + } + + private: + + // Deleted. + unique_ptr(const unique_ptr&); + unique_ptr& operator =(const unique_ptr&); + + TDeleter deleter; + + pointer p; + }; + + //***************************************************************************** + /// Unique pointer for arrays. + ///\tparam T The pointed to type type. + ///\ingroup memory + //***************************************************************************** + template + class unique_ptr + { + public: + + typedef T element_type; + typedef T* pointer; + typedef T& reference; + + ETL_CONSTEXPR unique_ptr() + : p(nullptr) + { + } + + ETL_CONSTEXPR explicit unique_ptr(pointer p_) + : p(p_) + { + } + +#if ETL_CPP11_SUPPORTED + unique_ptr(unique_ptr&& p_) + : p(p_.release()) + { + } +#endif + + ~unique_ptr() + { + deleter(p); + } + + ETL_CONSTEXPR pointer get() const + { + return p; + } + + TDeleter& get_deleter() + { + return deleter; + } + + const TDeleter& get_deleter() const + { + return deleter; + } + + pointer release() + { + pointer value = p; + p = nullptr; + return value; + } + + void reset(pointer p_) + { + assert(p_ != p); + + pointer value = p; + p = p_; + delete[] value; + } + + void swap(unique_ptr& v) + { + std::swap(p, v.p); + } + + ETL_CONSTEXPR explicit operator bool() const + { + return (p != nullptr); + } + + unique_ptr& operator =(pointer p_) + { + reset(p_); + + return *this; + } + +#if ETL_CPP11_SUPPORTED + unique_ptr& operator =(unique_ptr&& p_) + { + reset(p_.release()); + + return *this; + } +#endif + + ETL_CONSTEXPR reference operator *() const + { + return *p; + } + + ETL_CONSTEXPR pointer operator ->() const + { + return p; + } + + ETL_CONSTEXPR reference operator [](size_t i) const + { + return p[i]; + } + + ETL_CONSTEXPR bool operator ==(const pointer p_) const + { + return (p == p_); + } + + ETL_CONSTEXPR bool operator ==(const unique_ptr& p_) const + { + return (p == p_.p); + } + + ETL_CONSTEXPR bool operator <(const unique_ptr& p_) const + { + return (p < p_.p); + } + + private: + + // Deleted. + unique_ptr(const unique_ptr&); + unique_ptr& operator =(const unique_ptr&); + + TDeleter deleter; + + pointer p; + }; + + //***************************************************************************** + /// Base class for objects that require their memory to be wiped after use. + /// Erases the object's memory to zero. + /// Note: This must be the last destructor called for the derived object. + ///\tparam T The derived type. + ///\ingroup memory + //***************************************************************************** + template + struct wipe_on_destruct + { + ~wipe_on_destruct() + { + char* pobject = reinterpret_cast(static_cast(this)); + memset(pobject, 0, sizeof(T)); + } + }; } #endif diff --git a/include/etl/memory_model.h b/include/etl/memory_model.h index 07bfc73f..5b474597 100644 --- a/include/etl/memory_model.h +++ b/include/etl/memory_model.h @@ -32,14 +32,44 @@ SOFTWARE. #define ETL_MEMORY_MODEL_INCLUDED #include "user_type.h" +#include +#include "type_lookup.h" namespace etl { ETL_DECLARE_USER_TYPE(memory_model, int) - ETL_USER_TYPE(MM_SMALL, 0) - ETL_USER_TYPE(MM_MEDIUM, 1) - ETL_USER_TYPE(MM_LARGE, 2) + ETL_USER_TYPE(MEMORY_MODEL_SMALL, 0) + ETL_USER_TYPE(MEMORY_MODEL_MEDIUM, 1) + ETL_USER_TYPE(MEMORY_MODEL_LARGE, 2) + ETL_USER_TYPE(MEMORY_MODEL_HUGE, 3) ETL_END_USER_TYPE(memory_model) + + template + struct size_type_lookup; + + template <> + struct size_type_lookup + { + typedef uint_least8_t type; + }; + + template <> + struct size_type_lookup + { + typedef uint_least16_t type; + }; + + template <> + struct size_type_lookup + { + typedef uint_least32_t type; + }; + + template <> + struct size_type_lookup + { + typedef uint_least64_t type; + }; } #endif diff --git a/include/etl/multimap.h b/include/etl/multimap.h index 87317786..8f151884 100644 --- a/include/etl/multimap.h +++ b/include/etl/multimap.h @@ -609,14 +609,14 @@ namespace etl size_type current_size; ///< The number of the used nodes. const size_type CAPACITY; ///< The maximum size of the map. Node* root_node; ///< The node that acts as the multimap root. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT }; //*************************************************************************** /// A templated base for all etl::multimap types. ///\ingroup map //*************************************************************************** - template + template > class imultimap : public etl::multimap_base { public: @@ -638,7 +638,7 @@ namespace etl { bool operator ()(const key_type& key1, const key_type& key2) const { - return key_compare()(key1, key2); + return compare(key1, key2); } }; @@ -649,7 +649,7 @@ namespace etl { bool operator ()(const value_type& value1, const value_type& value2) const { - return key_compare()(value1.first, value2.first); + return compare(value1.first, value2.first); } }; @@ -676,17 +676,17 @@ namespace etl //************************************************************************* bool node_comp(const Data_Node& node1, const Data_Node& node2) const { - return key_compare()(node1.value.first, node2.value.first); + return compare(node1.value.first, node2.value.first); } bool node_comp(const Data_Node& node, key_parameter_t key) const { - return key_compare()(node.value.first, key); + return compare(node.value.first, key); } bool node_comp(key_parameter_t key, const Data_Node& node) const { - return key_compare()(key, node.value.first); + return compare(key, node.value.first); } private: @@ -694,6 +694,8 @@ namespace etl /// The pool of data nodes used in the multimap. ipool* p_node_pool; + key_compare compare; + //************************************************************************* /// Downcast a Node* to a Data_Node* //************************************************************************* @@ -1356,7 +1358,7 @@ namespace etl { Data_Node& node = *p_node_pool->allocate(); ::new (&node.value) const value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return node; } @@ -1367,7 +1369,7 @@ namespace etl { node.value.~value_type(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* diff --git a/include/etl/multiset.h b/include/etl/multiset.h index 1c7c194b..8f78dc7f 100644 --- a/include/etl/multiset.h +++ b/include/etl/multiset.h @@ -609,14 +609,14 @@ namespace etl size_type current_size; ///< The number of the used nodes. const size_type CAPACITY; ///< The maximum size of the set. Node* root_node; ///< The node that acts as the multiset root. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT }; //*************************************************************************** /// A templated base for all etl::multiset types. ///\ingroup set //*************************************************************************** - template + template > class imultiset : public etl::multiset_base { public: @@ -636,7 +636,7 @@ namespace etl { bool operator ()(key_type& key1, key_type& key2) const { - return key_compare()(key1, key2); + return compare(key1, key2); } }; @@ -647,7 +647,7 @@ namespace etl { bool operator ()(value_type& value1, value_type& value2) const { - return value_compare()(value1, value2); + return compare(value1, value2); } }; @@ -674,15 +674,15 @@ namespace etl //************************************************************************* bool node_comp(const Data_Node& node1, const Data_Node& node2) const { - return key_compare()(node1.value, node2.value); + return compare(node1.value, node2.value); } bool node_comp(const Data_Node& node, key_parameter_t key) const { - return key_compare()(node.value, key); + return compare(node.value, key); } bool node_comp(key_parameter_t key, const Data_Node& node) const { - return key_compare()(key, node.value); + return compare(key, node.value); } private: @@ -690,6 +690,8 @@ namespace etl /// The pool of data nodes used in the multiset. ipool* p_node_pool; + key_compare compare; + //************************************************************************* /// Downcast a Node* to a Data_Node* //************************************************************************* @@ -1337,7 +1339,7 @@ namespace etl { Data_Node& node = *p_node_pool->allocate(); ::new ((void*)&node.value) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return node; } @@ -1348,7 +1350,7 @@ namespace etl { node.value.~value_type(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* diff --git a/include/etl/observer.h b/include/etl/observer.h index 5a344fbe..06d07dfc 100644 --- a/include/etl/observer.h +++ b/include/etl/observer.h @@ -133,8 +133,9 @@ namespace etl //***************************************************************** /// Remove a particular observer from the list. ///\param observer A reference to the observer. + ///\return true if the observer was removed, false if not. //***************************************************************** - void remove_observer(TObserver& observer) + bool remove_observer(TObserver& observer) { // See if we have it in our list. typename Observer_List::iterator i_observer = std::find(observer_list.begin(), @@ -146,6 +147,11 @@ namespace etl { // Erase it. observer_list.erase(i_observer); + return true; + } + else + { + return false; } } @@ -179,6 +185,12 @@ namespace etl } } + protected: + + ~observable() + { + } + private: /// The list of observers. diff --git a/include/etl/priority_queue.h b/include/etl/priority_queue.h index 1e5b4e34..02eb6922 100644 --- a/include/etl/priority_queue.h +++ b/include/etl/priority_queue.h @@ -115,7 +115,7 @@ namespace etl /// \tparam TContainer to hold the T queue values /// \tparam TCompare to use in comparing T values //*************************************************************************** - template + template > class ipriority_queue { public: @@ -165,7 +165,7 @@ namespace etl // Put element at end container.push_back(value); // Make elements in container into heap - std::push_heap(container.begin(), container.end(), TCompare()); + std::push_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -182,7 +182,7 @@ namespace etl // Put element at end container.emplace_back(value1); // Make elements in container into heap - std::push_heap(container.begin(), container.end(), TCompare()); + std::push_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -199,7 +199,7 @@ namespace etl // Put element at end container.emplace_back(value1, value2); // Make elements in container into heap - std::push_heap(container.begin(), container.end(), TCompare()); + std::push_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -216,7 +216,7 @@ namespace etl // Put element at end container.emplace_back(value1, value2, value3); // Make elements in container into heap - std::push_heap(container.begin(), container.end(), TCompare()); + std::push_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -233,7 +233,7 @@ namespace etl // Put element at end container.emplace_back(value1, value2, value3, value4); // Make elements in container into heap - std::push_heap(container.begin(), container.end(), TCompare()); + std::push_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -256,7 +256,7 @@ namespace etl clear(); container.assign(first, last); - std::make_heap(container.begin(), container.end(), TCompare()); + std::make_heap(container.begin(), container.end(), compare); } //************************************************************************* @@ -266,7 +266,7 @@ namespace etl void pop() { // Move largest element to end - std::pop_heap(container.begin(), container.end(), TCompare()); + std::pop_heap(container.begin(), container.end(), compare); // Actually remove largest element at end container.pop_back(); } @@ -319,7 +319,7 @@ namespace etl /// Returns the remaining capacity. ///\return The remaining capacity. //************************************************************************* - size_t available() const + size_type available() const { return container.max_size() - container.size(); } @@ -356,6 +356,8 @@ namespace etl /// The container specified at instantiation of the priority_queue TContainer container; + + TCompare compare; }; //*************************************************************************** @@ -370,7 +372,9 @@ namespace etl { public: - static const size_t MAX_SIZE = SIZE; + typedef typename TContainer::size_type size_type; + + static const size_type MAX_SIZE = size_type(SIZE); //************************************************************************* /// Default constructor. diff --git a/include/etl/private/ivectorpointer.h b/include/etl/private/ivectorpointer.h index 9ef26977..4a24a186 100644 --- a/include/etl/private/ivectorpointer.h +++ b/include/etl/private/ivectorpointer.h @@ -50,12 +50,12 @@ namespace etl public: typedef T* value_type; - typedef T*& reference; - typedef const T* const & const_reference; - typedef T** pointer; - typedef const T* const * const_pointer; - typedef T** iterator; - typedef const T* const * const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef size_t size_type; @@ -452,12 +452,12 @@ namespace etl public: typedef const T* value_type; - typedef const T*& reference; - typedef const T* const & const_reference; - typedef const T** pointer; - typedef const T* const * const_pointer; - typedef const T** iterator; - typedef const T* const * const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef size_t size_type; diff --git a/include/etl/private/pvoidvector.h b/include/etl/private/pvoidvector.h index 952c568c..07692a61 100644 --- a/include/etl/private/pvoidvector.h +++ b/include/etl/private/pvoidvector.h @@ -61,12 +61,12 @@ namespace etl public: typedef void* value_type; - typedef void*& reference; - typedef const void*& const_reference; - typedef void** pointer; - typedef const void** const_pointer; - typedef void** iterator; - typedef const void** const_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type* iterator; + typedef const value_type* const_iterator; typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; typedef size_t size_type; @@ -74,246 +74,41 @@ namespace etl public: - //********************************************************************* - /// Returns an iterator to the beginning of the vector. - ///\return An iterator to the beginning of the vector. - //********************************************************************* - iterator begin() - { - return p_buffer; - } + iterator begin(); + const_iterator begin() const; - //********************************************************************* - /// Returns a const_iterator to the beginning of the vector. - ///\return A const iterator to the beginning of the vector. - //********************************************************************* - const_iterator begin() const - { - return const_iterator(p_buffer); - } + iterator end(); + const_iterator end() const; - //********************************************************************* - /// Returns an iterator to the end of the vector. - ///\return An iterator to the end of the vector. - //********************************************************************* - iterator end() - { - return p_end; - } + const_iterator cbegin() const; + const_iterator cend() const; - //********************************************************************* - /// Returns a const_iterator to the end of the vector. - ///\return A const iterator to the end of the vector. - //********************************************************************* - const_iterator end() const - { - return const_iterator(p_end); - } + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; - //********************************************************************* - /// Returns a const_iterator to the beginning of the vector. - ///\return A const iterator to the beginning of the vector. - //********************************************************************* - const_iterator cbegin() const - { - return const_iterator(p_buffer); - } + reverse_iterator rend(); + const_reverse_iterator rend() const; - //********************************************************************* - /// Returns a const_iterator to the end of the vector. - ///\return A const iterator to the end of the vector. - //********************************************************************* - const_iterator cend() const - { - return const_iterator(p_end); - } + const_reverse_iterator crbegin() const; + const_reverse_iterator crend() const; - //********************************************************************* - /// Returns an reverse iterator to the reverse beginning of the vector. - ///\return Iterator to the reverse beginning of the vector. - //********************************************************************* - reverse_iterator rbegin() - { - return reverse_iterator(end()); - } + void resize(size_t new_size); + void resize(size_t new_size, value_type value); - //********************************************************************* - /// Returns a const reverse iterator to the reverse beginning of the vector. - ///\return Const iterator to the reverse beginning of the vector. - //********************************************************************* - const_reverse_iterator rbegin() const - { - return const_reverse_iterator(end()); - } + reference operator [](size_t i); + const_reference operator [](size_t i) const; - //********************************************************************* - /// Returns a reverse iterator to the end + 1 of the vector. - ///\return Reverse iterator to the end + 1 of the vector. - //********************************************************************* - reverse_iterator rend() - { - return reverse_iterator(begin()); - } + reference at(size_t i); + const_reference at(size_t i) const; - //********************************************************************* - /// Returns a const reverse iterator to the end + 1 of the vector. - ///\return Const reverse iterator to the end + 1 of the vector. - //********************************************************************* - const_reverse_iterator rend() const - { - return const_reverse_iterator(begin()); - } + reference front(); + const_reference front() const; - //********************************************************************* - /// Returns a const reverse iterator to the reverse beginning of the vector. - ///\return Const reverse iterator to the reverse beginning of the vector. - //********************************************************************* - const_reverse_iterator crbegin() const - { - return const_reverse_iterator(cend()); - } + reference back(); + const_reference back() const; - //********************************************************************* - /// Returns a const reverse iterator to the end + 1 of the vector. - ///\return Const reverse iterator to the end + 1 of the vector. - //********************************************************************* - const_reverse_iterator crend() const - { - return const_reverse_iterator(cbegin()); - } - - //********************************************************************* - /// Resizes the vector. - /// If asserts or exceptions are enabled and the new size is larger than the - /// maximum then a vector_full is thrown. - ///\param new_size The new size. - //********************************************************************* - void resize(size_t new_size) - { - ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full)); - - p_end = p_buffer + new_size; - } - - //********************************************************************* - /// Resizes the vector. - /// If asserts or exceptions are enabled and the new size is larger than the - /// maximum then a vector_full is thrown. - ///\param new_size The new size. - ///\param value The value to fill new elements with. Default = default constructed value. - //********************************************************************* - void resize(size_t new_size, value_type value) - { - ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full)); - - pointer p_new_end = p_buffer + new_size; - - // Size up if necessary. - if (p_end < p_new_end) - { - std::fill(p_end, p_new_end, value); - } - - p_end = p_new_end; - } - - //********************************************************************* - /// Returns a reference to the value at index 'i' - ///\param i The index. - ///\return A reference to the value at index 'i' - //********************************************************************* - reference operator [](size_t i) - { - return p_buffer[i]; - } - - //********************************************************************* - /// Returns a const reference to the value at index 'i' - ///\param i The index. - ///\return A const reference to the value at index 'i' - //********************************************************************* - const_reference operator [](size_t i) const - { - return const_reference(p_buffer[i]); - } - - //********************************************************************* - /// Returns a reference to the value at index 'i' - /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. - ///\param i The index. - ///\return A reference to the value at index 'i' - //********************************************************************* - reference at(size_t i) - { - ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); - return p_buffer[i]; - } - - //********************************************************************* - /// Returns a const reference to the value at index 'i' - /// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. - ///\param i The index. - ///\return A const reference to the value at index 'i' - //********************************************************************* - const_reference at(size_t i) const - { - ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); - return const_reference(p_buffer[i]); - } - - //********************************************************************* - /// Returns a reference to the first element. - ///\return A reference to the first element. - //********************************************************************* - reference front() - { - return p_buffer[0]; - } - - //********************************************************************* - /// Returns a const reference to the first element. - ///\return A const reference to the first element. - //********************************************************************* - const_reference front() const - { - return const_reference(p_buffer[0]); - } - - //********************************************************************* - /// Returns a reference to the last element. - ///\return A reference to the last element. - //********************************************************************* - reference back() - { - return *(p_end -1); - } - - //********************************************************************* - /// Returns a const reference to the last element. - ///\return A const reference to the last element. - //********************************************************************* - const_reference back() const - { - return const_reference(*(p_end - 1)); - } - - //********************************************************************* - /// Returns a pointer to the beginning of the vector data. - ///\return A pointer to the beginning of the vector data. - //********************************************************************* - pointer data() - { - return p_buffer; - } - - //********************************************************************* - /// Returns a const pointer to the beginning of the vector data. - ///\return A const pointer to the beginning of the vector data. - //********************************************************************* - const_pointer data() const - { - return const_pointer(p_buffer); - } + pointer data(); + const_pointer data() const; //********************************************************************* /// Assigns values to the vector. @@ -338,110 +133,17 @@ namespace etl } } - //********************************************************************* - /// Assigns values to the vector. - /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. - ///\param n The number of elements to add. - ///\param value The value to insert for each element. - //********************************************************************* - void assign(size_t n, value_type value) - { - initialise(); + void assign(size_t n, value_type value); - ETL_ASSERT(n <= CAPACITY, ETL_ERROR(vector_full)); + void clear(); - for (size_t current_size = 0; current_size < n; ++current_size) - { - *p_end++ = value; - } - } + void push_back(); + void push_back(value_type value); - //************************************************************************* - /// Clears the vector. - //************************************************************************* - void clear() - { - initialise(); - } + void pop_back(); - //************************************************************************* - /// Increases the size of the vector by one, but does not initialise the new element. - /// If asserts or exceptions are enabled, throws a vector_full if the vector is already full. - //************************************************************************* - void push_back() - { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif - - ++p_end; - } - - //********************************************************************* - /// Inserts a value at the end of the vector. - /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. - ///\param value The value to add. - //********************************************************************* - void push_back(value_type value) - { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif - *p_end++ = value; - } - - //************************************************************************* - /// Removes an element from the end of the vector. - /// Does nothing if the vector is empty. - //************************************************************************* - void pop_back() - { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty)); -#endif - --p_end; - } - - //********************************************************************* - /// Inserts a value to the vector. - /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. - ///\param position The position to insert before. - ///\param value The value to insert. - //********************************************************************* - iterator insert(iterator position, value_type value) - { - ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full)); - - if (position != end()) - { - ++p_end; - std::copy_backward(position, end() - 1, end()); - *position = value; - } - else - { - *p_end++ = value; - } - - return position; - } - - //********************************************************************* - /// Inserts 'n' values to the vector. - /// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. - ///\param position The position to insert before. - ///\param n The number of elements to add. - ///\param value The value to insert. - //********************************************************************* - void insert(iterator position, size_t n, value_type value) - { - ETL_ASSERT((size() + 1) <= CAPACITY, ETL_ERROR(vector_full)); - - std::copy_backward(position, p_end, p_end + n); - std::fill_n(position, n, value); - - p_end += n; - } + iterator insert(iterator position, value_type value); + void insert(iterator position, size_t n, value_type value); //********************************************************************* /// Inserts a range of values to the vector. @@ -463,117 +165,26 @@ namespace etl p_end += count; } - //********************************************************************* - /// Erases an element. - ///\param i_element Iterator to the element. - ///\return An iterator pointing to the element that followed the erased element. - //********************************************************************* - iterator erase(iterator i_element) - { - std::copy(i_element + 1, end(), i_element); - --p_end; + iterator erase(iterator i_element); + iterator erase(iterator first, iterator last); - return i_element; - } + pvoidvector& operator = (const pvoidvector& rhs); - //********************************************************************* - /// Erases a range of elements. - /// The range includes all the elements between first and last, including the - /// element pointed by first, but not the one pointed by last. - ///\param first Iterator to the first element. - ///\param last Iterator to the last element. - ///\return An iterator pointing to the element that followed the erased element. - //********************************************************************* - iterator erase(iterator first, iterator last) - { - std::copy(last, end(), first); - size_t n_delete = std::distance(first, last); + size_type size() const; - // Just adjust the count. - p_end -= n_delete; + bool empty() const; - return first; - } + bool full() const; - //************************************************************************* - /// Assignment operator. - //************************************************************************* - pvoidvector& operator = (const pvoidvector& rhs) - { - if (&rhs != this) - { - assign(rhs.cbegin(), rhs.cend()); - } - - return *this; - } - - //************************************************************************* - /// Gets the current size of the vector. - ///\return The current size of the vector. - //************************************************************************* - size_type size() const - { - return size_t(p_end - p_buffer); - } - - //************************************************************************* - /// Checks the 'empty' state of the vector. - ///\return true if empty. - //************************************************************************* - bool empty() const - { - return (p_end == p_buffer); - } - - //************************************************************************* - /// Checks the 'full' state of the vector. - ///\return true if full. - //************************************************************************* - bool full() const - { - return size() == CAPACITY; - } - - //************************************************************************* - /// Returns the remaining capacity. - ///\return The remaining capacity. - //************************************************************************* - size_t available() const - { - return max_size() - size(); - } + size_t available() const; protected: - //********************************************************************* - /// Constructor. - //********************************************************************* - pvoidvector(void** p_buffer_, size_t MAX_SIZE) - : vector_base(MAX_SIZE), - p_buffer(p_buffer_), - p_end(p_buffer_) - { - } + pvoidvector(void** p_buffer_, size_t MAX_SIZE); - //********************************************************************* - /// Initialise the vector. - //********************************************************************* - void initialise() - { - p_end = p_buffer; - } + void initialise(); - //************************************************************************* - /// Fix the internal pointers after a low level memory copy. - //************************************************************************* - void repair(void** p_buffer_) - { - uintptr_t length = p_end - p_buffer; - - p_buffer = p_buffer_; - p_end = p_buffer_ + length; - } + void repair(void** p_buffer_); void** p_buffer; void** p_end; diff --git a/include/etl/private/vector_base.h b/include/etl/private/vector_base.h index d34b4f68..2b68f481 100644 --- a/include/etl/private/vector_base.h +++ b/include/etl/private/vector_base.h @@ -162,7 +162,7 @@ namespace etl } const size_type CAPACITY; /// class queue_base { public: - typedef size_t size_type; ///< The type used for determining the size of queue. + /// The type used for determining the size of queue. + typedef typename etl::size_type_lookup::type size_type; //************************************************************************* /// Returns the current number of items in the queue. @@ -154,7 +158,7 @@ namespace etl /// Returns the remaining capacity. ///\return The remaining capacity. //************************************************************************* - size_t available() const + size_type available() const { return max_size() - size(); } @@ -190,7 +194,7 @@ namespace etl } ++current_size; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -203,7 +207,7 @@ namespace etl out = 0; } --current_size; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* @@ -214,14 +218,14 @@ namespace etl in = 0; out = 0; current_size = 0; - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT } - size_type in; ///< Where to input new data. - size_type out; ///< Where to get the oldest data. + size_type in; ///< Where to input new data. + size_type out; ///< Where to get the oldest data. size_type current_size; ///< The number of items in the queue. const size_type CAPACITY; ///< The maximum number of items in the queue. - ETL_DECLARE_DEBUG_COUNT; ///< For internal debugging purposes. + ETL_DECLARE_DEBUG_COUNT ///< For internal debugging purposes. }; @@ -236,25 +240,32 @@ namespace etl /// \warning This queue cannot be used for concurrent access from multiple threads. /// \tparam T The type of value that the queue holds. //*************************************************************************** - template - class iqueue : public etl::queue_base + template + class iqueue : public etl::queue_base { - public: - - typedef T value_type; ///< The type stored in the queue. - typedef T& reference; ///< A reference to the type used in the queue. - typedef const T& const_reference; ///< A const reference to the type used in the queue. - typedef T* pointer; ///< A pointer to the type used in the queue. - typedef const T* const_pointer; ///< A const pointer to the type used in the queue. - typedef queue_base::size_type size_type; ///< The type used for determining the size of the queue. - private: - typedef typename etl::parameter_type::type parameter_t; - typedef typename etl::queue_base base_t; + typedef typename etl::parameter_type::type parameter_t; + typedef typename etl::queue_base base_t; public: + typedef T value_type; ///< The type stored in the queue. + typedef T& reference; ///< A reference to the type used in the queue. + typedef const T& const_reference; ///< A const reference to the type used in the queue. + typedef T* pointer; ///< A pointer to the type used in the queue. + typedef const T* const_pointer; ///< A const pointer to the type used in the queue. + typedef typename base_t::size_type size_type; ///< The type used for determining the size of the queue. + + using base_t::in; + using base_t::out; + using base_t::CAPACITY; + using base_t::current_size; + using base_t::full; + using base_t::empty; + using base_t::add_in; + using base_t::del_out; + //************************************************************************* /// Gets a reference to the value at the front of the queue.
/// \return A reference to the value at the front of the queue. @@ -302,7 +313,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif ::new (&p_buffer[in]) T(value); - base_t::add_in(); + add_in(); } //************************************************************************* @@ -319,7 +330,7 @@ namespace etl #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif - base_t::add_in(); + add_in(); return p_buffer[next]; } @@ -336,7 +347,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif ::new (&p_buffer[in]) T(value1); - base_t::add_in(); + add_in(); } //************************************************************************* @@ -351,7 +362,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif ::new (&p_buffer[in]) T(value1, value2); - base_t::add_in(); + add_in(); } //************************************************************************* @@ -366,7 +377,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif ::new (&p_buffer[in]) T(value1, value2, value3); - base_t::add_in(); + add_in(); } //************************************************************************* @@ -381,7 +392,7 @@ namespace etl ETL_ASSERT(!full(), ETL_ERROR(queue_full)); #endif ::new (&p_buffer[in]) T(value1, value2, value3, value4); - base_t::add_in(); + add_in(); } //************************************************************************* @@ -398,7 +409,7 @@ namespace etl while (current_size > 0) { p_buffer[out].~T(); - base_t::del_out(); + del_out(); } in = 0; @@ -417,7 +428,7 @@ namespace etl ETL_ASSERT(!empty(), ETL_ERROR(queue_empty)); #endif p_buffer[out].~T(); - base_t::del_out(); + del_out(); } //************************************************************************* @@ -466,9 +477,9 @@ namespace etl { clear(); - size_t index = other.out; + size_type index = other.out; - for (size_t i = 0; i < other.size(); ++i) + for (size_type i = 0; i < other.size(); ++i) { push(other.p_buffer[index]); index = (index == (CAPACITY - 1)) ? 0 : index + 1; @@ -479,7 +490,7 @@ namespace etl /// The constructor that is called from derived classes. //************************************************************************* iqueue(T* p_buffer_, size_type max_size_) - : queue_base(max_size_), + : base_t(max_size_), p_buffer(p_buffer_) { } @@ -511,21 +522,30 @@ namespace etl ///\ingroup queue /// A fixed capacity queue. /// This queue does not support concurrent access by different threads. - /// \tparam T The type this queue should support. - /// \tparam SIZE The maximum capacity of the queue. + /// \tparam T The type this queue should support. + /// \tparam SIZE The maximum capacity of the queue. + /// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables. //*************************************************************************** - template - class queue : public etl::iqueue + template + class queue : public etl::iqueue { + private: + + typedef etl::iqueue base_t; + public: - static const size_t MAX_SIZE = SIZE; + typedef typename base_t::size_type size_type; + + ETL_STATIC_ASSERT((SIZE <= etl::integral_limits::max), "Size too large for memory model"); + + static const size_type MAX_SIZE = size_type(SIZE); //************************************************************************* /// Default constructor. //************************************************************************* queue() - : etl::iqueue(reinterpret_cast(&buffer[0]), SIZE) + : base_t(reinterpret_cast(&buffer[0]), SIZE) { } @@ -533,9 +553,9 @@ namespace etl /// Copy constructor //************************************************************************* queue(const queue& rhs) - : etl::iqueue(reinterpret_cast(&buffer[0]), SIZE) + : base_t(reinterpret_cast(&buffer[0]), SIZE) { - etl::iqueue::clone(rhs); + base_t::clone(rhs); } //************************************************************************* @@ -543,7 +563,7 @@ namespace etl //************************************************************************* ~queue() { - etl::iqueue::clear(); + base_t::clear(); } //************************************************************************* @@ -553,7 +573,7 @@ namespace etl { if (&rhs != this) { - etl::iqueue::clone(rhs); + base_t::clone(rhs); } return *this; diff --git a/include/etl/queue_mpmc_mutex.h b/include/etl/queue_mpmc_mutex.h index f6951406..16ec5e53 100644 --- a/include/etl/queue_mpmc_mutex.h +++ b/include/etl/queue_mpmc_mutex.h @@ -38,20 +38,26 @@ SOFTWARE. #include "alignment.h" #include "parameter_type.h" #include "mutex.h" +#include "memory_model.h" +#include "integral_limits.h" #undef ETL_FILE #define ETL_FILE "48" namespace etl { + template class queue_mpmc_mutex_base { public: + /// The type used for determining the size of queue. + typedef typename etl::size_type_lookup::type size_type; + //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t capacity() const + size_type capacity() const { return MAX_SIZE; } @@ -59,14 +65,14 @@ namespace etl //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t max_size() const + size_type max_size() const { return MAX_SIZE; } protected: - queue_mpmc_mutex_base(size_t max_size_) + queue_mpmc_mutex_base(size_type max_size_) : write_index(0), read_index(0), current_size(0), @@ -77,7 +83,7 @@ namespace etl //************************************************************************* /// Calculate the next index. //************************************************************************* - static size_t get_next_index(size_t index, size_t maximum) + static size_type get_next_index(size_type index, size_type maximum) { ++index; @@ -89,10 +95,10 @@ namespace etl return index; } - size_t write_index; ///< Where to input new data. - size_t read_index; ///< Where to get the oldest data. - size_t current_size; ///< The current size of the queue. - const size_t MAX_SIZE; ///< The maximum number of items in the queue. + size_type write_index; ///< Where to input new data. + size_type read_index; ///< Where to get the oldest data. + size_type current_size; ///< The current size of the queue. + const size_type MAX_SIZE; ///< The maximum number of items in the queue. //************************************************************************* /// Destructor. @@ -121,19 +127,26 @@ namespace etl /// This queue supports concurrent access by one producer and one consumer. /// \tparam T The type of value that the queue_mpmc_mutex holds. //*************************************************************************** - template - class iqueue_mpmc_mutex : public queue_mpmc_mutex_base + template + class iqueue_mpmc_mutex : public queue_mpmc_mutex_base { - protected: + private: - typedef typename etl::parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; + typedef etl::queue_mpmc_mutex_base base_t; public: - typedef T value_type; ///< The type stored in the queue. - typedef T& reference; ///< A reference to the type used in the queue. - typedef const T& const_reference; ///< A const reference to the type used in the queue. - typedef size_t size_type; ///< The type used for determining the size of the queue. + typedef T value_type; ///< The type stored in the queue. + typedef T& reference; ///< A reference to the type used in the queue. + typedef const T& const_reference; ///< A const reference to the type used in the queue. + typedef typename base_t::size_type size_type; ///< The type used for determining the size of the queue. + + using base_t::write_index; + using base_t::read_index; + using base_t::current_size; + using base_t::MAX_SIZE; + using base_t::get_next_index; //************************************************************************* /// Push a value to the queue. @@ -199,7 +212,7 @@ namespace etl { access.lock(); - size_t result = (current_size == 0); + size_type result = (current_size == 0); access.unlock(); @@ -213,7 +226,7 @@ namespace etl { access.lock(); - size_t result = (current_size == MAX_SIZE); + size_type result = (current_size == MAX_SIZE); access.unlock(); @@ -223,11 +236,11 @@ namespace etl //************************************************************************* /// How many items in the queue? //************************************************************************* - size_t size() const + size_type size() const { access.lock(); - size_t result = current_size; + size_type result = current_size; access.unlock(); @@ -237,11 +250,11 @@ namespace etl //************************************************************************* /// How much free space available in the queue. //************************************************************************* - size_t available() const + size_type available() const { access.lock(); - size_t result = MAX_SIZE - current_size; + size_type result = MAX_SIZE - current_size; access.unlock(); @@ -254,7 +267,7 @@ namespace etl /// The constructor that is called from derived classes. //************************************************************************* iqueue_mpmc_mutex(T* p_buffer_, size_type max_size_) - : queue_mpmc_mutex_base(max_size_), + : base_t(max_size_), p_buffer(p_buffer_) { } @@ -335,17 +348,24 @@ namespace etl ///\ingroup queue_mpmc /// A fixed capacity mpmc queue. /// This queue supports concurrent access by one producer and one consumer. - /// \tparam T The type this queue should support. - /// \tparam SIZE The maximum capacity of the queue. + /// \tparam T The type this queue should support. + /// \tparam SIZE The maximum capacity of the queue. + /// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables. //*************************************************************************** - template - class queue_mpmc_mutex : public etl::iqueue_mpmc_mutex + template + class queue_mpmc_mutex : public etl::iqueue_mpmc_mutex { - typedef etl::iqueue_mpmc_mutex base_t; + private: + + typedef etl::iqueue_mpmc_mutex base_t; public: - static const size_t MAX_SIZE = SIZE; + typedef typename base_t::size_type size_type; + + ETL_STATIC_ASSERT((SIZE <= etl::integral_limits::max), "Size too large for memory model"); + + static const size_type MAX_SIZE = size_type(SIZE); //************************************************************************* /// Default constructor. diff --git a/include/etl/queue_spsc_atomic.h b/include/etl/queue_spsc_atomic.h index dfe32fc0..44eeb918 100644 --- a/include/etl/queue_spsc_atomic.h +++ b/include/etl/queue_spsc_atomic.h @@ -38,16 +38,22 @@ SOFTWARE. #include "alignment.h" #include "parameter_type.h" #include "atomic.h" +#include "memory_model.h" +#include "integral_limits.h" #undef ETL_FILE #define ETL_FILE "47" namespace etl { + template class queue_spsc_atomic_base { public: + /// The type used for determining the size of queue. + typedef typename etl::size_type_lookup::type size_type; + //************************************************************************* /// Is the queue empty? /// Accurate from the 'pop' thread. @@ -65,7 +71,7 @@ namespace etl //************************************************************************* bool full() const { - size_t next_index = get_next_index(write.load(etl::memory_order_acquire), RESERVED); + size_type next_index = get_next_index(write.load(etl::memory_order_acquire), RESERVED); return (next_index == read.load(etl::memory_order_acquire)); } @@ -74,12 +80,12 @@ namespace etl /// How many items in the queue? /// Due to concurrency, this is a guess. //************************************************************************* - size_t size() const + size_type size() const { - size_t write_index = write.load(etl::memory_order_acquire); - size_t read_index = read.load(etl::memory_order_acquire); + size_type write_index = write.load(etl::memory_order_acquire); + size_type read_index = read.load(etl::memory_order_acquire); - size_t n; + size_type n; if (write_index >= read_index) { @@ -97,7 +103,7 @@ namespace etl /// How much free space available in the queue. /// Due to concurrency, this is a guess. //************************************************************************* - size_t available() const + size_type available() const { return RESERVED - size() - 1; } @@ -105,7 +111,7 @@ namespace etl //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t capacity() const + size_type capacity() const { return RESERVED - 1; } @@ -113,14 +119,14 @@ namespace etl //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t max_size() const + size_type max_size() const { return RESERVED - 1; } protected: - queue_spsc_atomic_base(size_t reserved_) + queue_spsc_atomic_base(size_type reserved_) : write(0), read(0), RESERVED(reserved_) @@ -130,7 +136,7 @@ namespace etl //************************************************************************* /// Calculate the next index. //************************************************************************* - static size_t get_next_index(size_t index, size_t maximum) + static size_type get_next_index(size_type index, size_type maximum) { ++index; @@ -142,9 +148,9 @@ namespace etl return index; } - etl::atomic_size_t write; ///< Where to input new data. - etl::atomic_size_t read; ///< Where to get the oldest data. - const size_t RESERVED; ///< The maximum number of items in the queue. + etl::atomic write; ///< Where to input new data. + etl::atomic read; ///< Where to get the oldest data. + const size_type RESERVED; ///< The maximum number of items in the queue. private: @@ -163,7 +169,7 @@ namespace etl } #endif }; - + //*************************************************************************** ///\ingroup queue_spsc_atomic ///\brief This is the base for all queue_spscs that contain a particular type. @@ -175,27 +181,33 @@ namespace etl /// This queue supports concurrent access by one producer and one consumer. /// \tparam T The type of value that the queue_spsc_atomic holds. //*************************************************************************** - template - class iqueue_spsc_atomic : public queue_spsc_atomic_base + template + class iqueue_spsc_atomic : public queue_spsc_atomic_base { private: - typedef typename etl::parameter_type::type parameter_t; + typedef typename etl::parameter_type::type parameter_t; + typedef typename etl::queue_spsc_atomic_base base_t; public: - typedef T value_type; ///< The type stored in the queue. - typedef T& reference; ///< A reference to the type used in the queue. - typedef const T& const_reference; ///< A const reference to the type used in the queue. - typedef size_t size_type; ///< The type used for determining the size of the queue. + typedef T value_type; ///< The type stored in the queue. + typedef T& reference; ///< A reference to the type used in the queue. + typedef const T& const_reference; ///< A const reference to the type used in the queue. + typedef typename base_t::size_type size_type; ///< The type used for determining the size of the queue. + + using base_t::write; + using base_t::read; + using base_t::RESERVED; + using base_t::get_next_index; //************************************************************************* /// Push a value to the queue. //************************************************************************* bool push(parameter_t value) { - size_t write_index = write.load(etl::memory_order_relaxed); - size_t next_index = get_next_index(write_index, RESERVED); + size_type write_index = write.load(etl::memory_order_relaxed); + size_type next_index = get_next_index(write_index, RESERVED); if (next_index != read.load(etl::memory_order_acquire)) { @@ -205,7 +217,7 @@ namespace etl return true; } - + // Queue is full. return false; } @@ -214,16 +226,16 @@ namespace etl /// Pop a value from the queue. //************************************************************************* bool pop(reference value) - { - size_t read_index = read.load(etl::memory_order_relaxed); - - if (read_index == write.load(etl::memory_order_acquire)) + { + size_type read_index = read.load(etl::memory_order_relaxed); + + if (read_index == write.load(etl::memory_order_acquire)) { // Queue is empty return false; } - size_t next_index = get_next_index(read_index, RESERVED); + size_type next_index = get_next_index(read_index, RESERVED); value = p_buffer[read_index]; p_buffer[read_index].~T(); @@ -238,7 +250,7 @@ namespace etl //************************************************************************* bool pop() { - size_t read_index = read.load(etl::memory_order_relaxed); + size_type read_index = read.load(etl::memory_order_relaxed); if (read_index == write.load(etl::memory_order_acquire)) { @@ -246,7 +258,7 @@ namespace etl return false; } - size_t next_index = get_next_index(read_index, RESERVED); + size_type next_index = get_next_index(read_index, RESERVED); p_buffer[read_index].~T(); @@ -274,7 +286,7 @@ namespace etl /// The constructor that is called from derived classes. //************************************************************************* iqueue_spsc_atomic(T* p_buffer_, size_type reserved_) - : queue_spsc_atomic_base(reserved_), + : base_t(reserved_), p_buffer(p_buffer_) { } @@ -292,19 +304,30 @@ namespace etl ///\ingroup queue_spsc /// A fixed capacity spsc queue. /// This queue supports concurrent access by one producer and one consumer. - /// \tparam T The type this queue should support. - /// \tparam SIZE The maximum capacity of the queue. + /// \tparam T The type this queue should support. + /// \tparam SIZE The maximum capacity of the queue. + /// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables. //*************************************************************************** - template - class queue_spsc_atomic : public iqueue_spsc_atomic + template + class queue_spsc_atomic : public iqueue_spsc_atomic { - typedef etl::iqueue_spsc_atomic base_t; + private: - static const size_t RESERVED_SIZE = SIZE + 1; + typedef typename etl::iqueue_spsc_atomic base_t; public: - static const size_t MAX_SIZE = SIZE; + typedef typename base_t::size_type size_type; + + private: + + static const size_type RESERVED_SIZE = size_type(SIZE + 1); + + public: + + ETL_STATIC_ASSERT((SIZE <= (etl::integral_limits::max - 1)), "Size too large for memory model"); + + static const size_type MAX_SIZE = size_type(SIZE); //************************************************************************* /// Default constructor. @@ -329,4 +352,4 @@ namespace etl }; }; -#endif \ No newline at end of file +#endif diff --git a/include/etl/queue_spsc_isr.h b/include/etl/queue_spsc_isr.h index 2b89603d..dc5922cb 100644 --- a/include/etl/queue_spsc_isr.h +++ b/include/etl/queue_spsc_isr.h @@ -37,13 +37,15 @@ SOFTWARE. #include "platform.h" #include "alignment.h" #include "parameter_type.h" +#include "memory_model.h" +#include "integral_limits.h" #undef ETL_FILE #define ETL_FILE "46" namespace etl { - template + template class queue_spsc_isr_base { protected: @@ -52,10 +54,12 @@ namespace etl public: + /// The type used for determining the size of queue. + typedef typename etl::size_type_lookup::type size_type; + typedef T value_type; ///< The type stored in the queue. typedef T& reference; ///< A reference to the type used in the queue. typedef const T& const_reference; ///< A const reference to the type used in the queue. - typedef size_t size_type; ///< The type used for determining the size of the queue. //************************************************************************* /// Push a value to the queue from an ISR. @@ -85,7 +89,7 @@ namespace etl /// How much free space available in the queue. /// Called from ISR. //************************************************************************* - size_t available_from_isr() const + size_type available_from_isr() const { return MAX_SIZE - current_size; } @@ -123,7 +127,7 @@ namespace etl /// How many items in the queue? /// Called from ISR. //************************************************************************* - size_t size_from_isr() const + size_type size_from_isr() const { return current_size; } @@ -131,7 +135,7 @@ namespace etl //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t capacity() const + size_type capacity() const { return MAX_SIZE; } @@ -139,7 +143,7 @@ namespace etl //************************************************************************* /// How many items can the queue hold. //************************************************************************* - size_t max_size() const + size_type max_size() const { return MAX_SIZE; } @@ -219,7 +223,7 @@ namespace etl //************************************************************************* /// Calculate the next index. //************************************************************************* - static size_t get_next_index(size_t index, size_t maximum) + static size_type get_next_index(size_type index, size_type maximum) { ++index; @@ -266,19 +270,20 @@ namespace etl /// This queue supports concurrent access by one producer and one consumer. /// \tparam T The type of value that the queue_spsc_isr holds. //*************************************************************************** - template - class iqueue_spsc_isr : public queue_spsc_isr_base + template + class iqueue_spsc_isr : public queue_spsc_isr_base { private: - typedef typename queue_spsc_isr_base::parameter_t parameter_t; + typedef queue_spsc_isr_base base_t; + typedef typename base_t::parameter_t parameter_t; public: - typedef typename queue_spsc_isr_base::value_type value_type; ///< The type stored in the queue. - typedef typename queue_spsc_isr_base::reference reference; ///< A reference to the type used in the queue. - typedef typename queue_spsc_isr_base::const_reference const_reference; ///< A const reference to the type used in the queue. - typedef typename queue_spsc_isr_base::size_type size_type; ///< The type used for determining the size of the queue. + typedef typename base_t::value_type value_type; ///< The type stored in the queue. + typedef typename base_t::reference reference; ///< A reference to the type used in the queue. + typedef typename base_t::const_reference const_reference; ///< A const reference to the type used in the queue. + typedef typename base_t::size_type size_type; ///< The type used for determining the size of the queue. //************************************************************************* /// Push a value to the queue. @@ -344,7 +349,7 @@ namespace etl { TAccess::lock(); - size_t result = (this->current_size == 0); + size_type result = (this->current_size == 0); TAccess::unlock(); @@ -358,7 +363,7 @@ namespace etl { TAccess::lock(); - size_t result = (this->current_size == this->MAX_SIZE); + size_type result = (this->current_size == this->MAX_SIZE); TAccess::unlock(); @@ -368,11 +373,11 @@ namespace etl //************************************************************************* /// How many items in the queue? //************************************************************************* - size_t size() const + size_type size() const { TAccess::lock(); - size_t result = this->current_size; + size_type result = this->current_size; TAccess::unlock(); @@ -382,11 +387,11 @@ namespace etl //************************************************************************* /// How much free space available in the queue. //************************************************************************* - size_t available() const + size_type available() const { TAccess::lock(); - size_t result = this->MAX_SIZE - this->current_size; + size_type result = this->MAX_SIZE - this->current_size; TAccess::unlock(); @@ -399,7 +404,7 @@ namespace etl /// The constructor that is called from derived classes. //************************************************************************* iqueue_spsc_isr(T* p_buffer_, size_type max_size_) - : queue_spsc_isr_base(p_buffer_, max_size_) + : base_t(p_buffer_, max_size_) { } @@ -416,18 +421,25 @@ namespace etl ///\ingroup queue_spsc /// A fixed capacity spsc queue. /// This queue supports concurrent access by one producer and one consumer. - /// \tparam T The type this queue should support. - /// \tparam SIZE The maximum capacity of the queue. - /// \tparam TAccess The type that will lock and unlock interrupts. + /// \tparam T The type this queue should support. + /// \tparam SIZE The maximum capacity of the queue. + /// \tparam TAccess The type that will lock and unlock interrupts. + /// \tparam MEMORY_MODEL The memory model for the queue. Determines the type of the internal counter variables. //*************************************************************************** - template - class queue_spsc_isr : public etl::iqueue_spsc_isr + template + class queue_spsc_isr : public etl::iqueue_spsc_isr { - typedef etl::iqueue_spsc_isr base_t; + private: + + typedef etl::iqueue_spsc_isr base_t; public: - static const size_t MAX_SIZE = SIZE; + typedef typename base_t::size_type size_type; + + ETL_STATIC_ASSERT((SIZE <= etl::integral_limits::max), "Size too large for memory model"); + + static const size_type MAX_SIZE = size_type(SIZE); //************************************************************************* /// Default constructor. diff --git a/include/etl/reference_flat_map.h b/include/etl/reference_flat_map.h index 339a8fb3..840b7497 100644 --- a/include/etl/reference_flat_map.h +++ b/include/etl/reference_flat_map.h @@ -329,19 +329,21 @@ namespace etl //********************************************************************* /// How to compare elements and keys. //********************************************************************* - class compare + class Compare { public: bool operator ()(const value_type& element, key_type key) const { - return key_compare()(element.first, key); + return comp(element.first, key); } bool operator ()(key_type key, const value_type& element) const { - return key_compare()(key, element.first); + return comp(key, element.first); } + + key_compare comp; }; public: @@ -690,7 +692,7 @@ namespace etl //********************************************************************* iterator lower_bound(key_parameter_t key) { - return std::lower_bound(begin(), end(), key, compare()); + return std::lower_bound(begin(), end(), key, compare); } //********************************************************************* @@ -700,7 +702,7 @@ namespace etl //********************************************************************* const_iterator lower_bound(key_parameter_t key) const { - return std::lower_bound(cbegin(), cend(), key, compare()); + return std::lower_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -710,7 +712,7 @@ namespace etl //********************************************************************* iterator upper_bound(key_parameter_t key) { - return std::upper_bound(begin(), end(), key, compare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -720,7 +722,7 @@ namespace etl //********************************************************************* const_iterator upper_bound(key_parameter_t key) const { - return std::upper_bound(begin(), end(), key, compare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -730,9 +732,9 @@ namespace etl //********************************************************************* std::pair equal_range(key_parameter_t key) { - iterator i_lower = std::lower_bound(begin(), end(), key, compare()); + iterator i_lower = std::lower_bound(begin(), end(), key, compare); - return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare())); + return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare)); } //********************************************************************* @@ -742,9 +744,9 @@ namespace etl //********************************************************************* std::pair equal_range(key_parameter_t key) const { - const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare()); + const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare); - return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare())); + return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare)); } //************************************************************************* @@ -835,7 +837,7 @@ namespace etl result.first = i_element; // Existing element? - if (value.first != i_element->first) + if (TKeyCompare()(value.first, i_element->first) || TKeyCompare()(i_element->first, value.first)) { // A new one. ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_map_full)); @@ -855,6 +857,8 @@ namespace etl lookup_t& lookup; + Compare compare; + //************************************************************************* /// Destructor. //************************************************************************* diff --git a/include/etl/reference_flat_multimap.h b/include/etl/reference_flat_multimap.h index 3088aa75..88adde96 100644 --- a/include/etl/reference_flat_multimap.h +++ b/include/etl/reference_flat_multimap.h @@ -304,19 +304,21 @@ namespace etl //********************************************************************* /// How to compare elements and keys. //********************************************************************* - class compare + class Compare { public: bool operator ()(const value_type& element, key_type key) const { - return key_compare()(element.first, key); + return comp(element.first, key); } bool operator ()(key_type key, const value_type& element) const { - return key_compare()(key, element.first); + return comp(key, element.first); } + + key_compare comp; }; public: @@ -612,7 +614,7 @@ namespace etl //********************************************************************* iterator lower_bound(key_parameter_t key) { - return std::lower_bound(begin(), end(), key, compare()); + return std::lower_bound(begin(), end(), key, compare); } //********************************************************************* @@ -622,7 +624,7 @@ namespace etl //********************************************************************* const_iterator lower_bound(key_parameter_t key) const { - return std::lower_bound(cbegin(), cend(), key, compare()); + return std::lower_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -632,7 +634,7 @@ namespace etl //********************************************************************* iterator upper_bound(key_parameter_t key) { - return std::upper_bound(begin(), end(), key, compare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -642,7 +644,7 @@ namespace etl //********************************************************************* const_iterator upper_bound(key_parameter_t key) const { - return std::upper_bound(begin(), end(), key, compare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -652,9 +654,9 @@ namespace etl //********************************************************************* std::pair equal_range(key_parameter_t key) { - iterator i_lower = std::lower_bound(begin(), end(), key, compare()); + iterator i_lower = std::lower_bound(begin(), end(), key, compare); - return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare())); + return std::make_pair(i_lower, std::upper_bound(i_lower, end(), key, compare)); } //********************************************************************* @@ -664,9 +666,9 @@ namespace etl //********************************************************************* std::pair equal_range(key_parameter_t key) const { - const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare()); + const_iterator i_lower = std::lower_bound(cbegin(), cend(), key, compare); - return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare())); + return std::make_pair(i_lower, std::upper_bound(i_lower, cend(), key, compare)); } //************************************************************************* @@ -768,6 +770,8 @@ namespace etl lookup_t& lookup; + Compare compare; + //************************************************************************* /// Destructor. //************************************************************************* diff --git a/include/etl/reference_flat_multiset.h b/include/etl/reference_flat_multiset.h index 11f89c8f..1cf5ca32 100644 --- a/include/etl/reference_flat_multiset.h +++ b/include/etl/reference_flat_multiset.h @@ -460,9 +460,9 @@ namespace etl { std::pair result(end(), false); - ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full)); + ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_multiset_full)); - iterator i_element = std::lower_bound(begin(), end(), value, TKeyCompare()); + iterator i_element = std::lower_bound(begin(), end(), value, compare); if (i_element == end()) { @@ -566,7 +566,7 @@ namespace etl //********************************************************************* iterator find(parameter_t key) { - iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + iterator itr = std::lower_bound(begin(), end(), key, compare); if (itr != end()) { @@ -590,7 +590,7 @@ namespace etl //********************************************************************* const_iterator find(parameter_t key) const { - const_iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + const_iterator itr = std::lower_bound(begin(), end(), key, compare); if (itr != end()) { @@ -626,7 +626,7 @@ namespace etl //********************************************************************* iterator lower_bound(parameter_t key) { - return std::lower_bound(begin(), end(), key, TKeyCompare()); + return std::lower_bound(begin(), end(), key, compare); } //********************************************************************* @@ -636,7 +636,7 @@ namespace etl //********************************************************************* const_iterator lower_bound(parameter_t key) const { - return std::lower_bound(cbegin(), cend(), key, TKeyCompare()); + return std::lower_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -646,7 +646,7 @@ namespace etl //********************************************************************* iterator upper_bound(parameter_t key) { - return std::upper_bound(begin(), end(), key, TKeyCompare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -656,7 +656,7 @@ namespace etl //********************************************************************* const_iterator upper_bound(parameter_t key) const { - return std::upper_bound(cbegin(), cend(), key, TKeyCompare()); + return std::upper_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -666,7 +666,7 @@ namespace etl //********************************************************************* std::pair equal_range(parameter_t key) { - return std::equal_range(begin(), end(), key, TKeyCompare()); + return std::equal_range(begin(), end(), key, compare); } //********************************************************************* @@ -676,7 +676,7 @@ namespace etl //********************************************************************* std::pair equal_range(parameter_t key) const { - return std::equal_range(begin(), end(), key, TKeyCompare()); + return std::equal_range(begin(), end(), key, compare); } //************************************************************************* @@ -783,6 +783,8 @@ namespace etl lookup_t& lookup; + TKeyCompare compare; + //************************************************************************* /// Destructor. //************************************************************************* diff --git a/include/etl/reference_flat_set.h b/include/etl/reference_flat_set.h index bcb5a5df..cfbc4793 100644 --- a/include/etl/reference_flat_set.h +++ b/include/etl/reference_flat_set.h @@ -546,7 +546,7 @@ namespace etl //********************************************************************* iterator find(parameter_t key) { - iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + iterator itr = std::lower_bound(begin(), end(), key, compare); if (itr != end()) { @@ -570,7 +570,7 @@ namespace etl //********************************************************************* const_iterator find(parameter_t key) const { - const_iterator itr = std::lower_bound(begin(), end(), key, TKeyCompare()); + const_iterator itr = std::lower_bound(begin(), end(), key, compare); if (itr != end()) { @@ -604,7 +604,7 @@ namespace etl //********************************************************************* iterator lower_bound(parameter_t key) { - return std::lower_bound(begin(), end(), key, TKeyCompare()); + return std::lower_bound(begin(), end(), key, compare); } //********************************************************************* @@ -614,7 +614,7 @@ namespace etl //********************************************************************* const_iterator lower_bound(parameter_t key) const { - return std::lower_bound(cbegin(), cend(), key, TKeyCompare()); + return std::lower_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -624,7 +624,7 @@ namespace etl //********************************************************************* iterator upper_bound(parameter_t key) { - return std::upper_bound(begin(), end(), key, TKeyCompare()); + return std::upper_bound(begin(), end(), key, compare); } //********************************************************************* @@ -634,7 +634,7 @@ namespace etl //********************************************************************* const_iterator upper_bound(parameter_t key) const { - return std::upper_bound(cbegin(), cend(), key, TKeyCompare()); + return std::upper_bound(cbegin(), cend(), key, compare); } //********************************************************************* @@ -644,7 +644,7 @@ namespace etl //********************************************************************* std::pair equal_range(parameter_t key) { - return std::equal_range(begin(), end(), key, TKeyCompare()); + return std::equal_range(begin(), end(), key, compare); } //********************************************************************* @@ -654,7 +654,7 @@ namespace etl //********************************************************************* std::pair equal_range(parameter_t key) const { - return std::upper_bound(cbegin(), cend(), key, TKeyCompare()); + return std::upper_bound(cbegin(), cend(), key, compare); } //************************************************************************* @@ -745,7 +745,7 @@ namespace etl result.first = i_element; // Existing element? - if (value != *i_element) + if (compare(value, *i_element) || compare(*i_element, value)) { // A new one. ETL_ASSERT(!lookup.full(), ETL_ERROR(flat_set_full)); @@ -765,6 +765,8 @@ namespace etl lookup_t& lookup; + TKeyCompare compare; + //************************************************************************* /// Destructor. //************************************************************************* diff --git a/include/etl/set.h b/include/etl/set.h index 163aca97..9736b005 100644 --- a/include/etl/set.h +++ b/include/etl/set.h @@ -446,7 +446,7 @@ namespace etl size_type current_size; ///< The number of the used nodes. const size_type CAPACITY; ///< The maximum size of the set. Node* root_node; ///< The node that acts as the set root. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT }; @@ -454,7 +454,7 @@ namespace etl /// A templated base for all etl::set types. ///\ingroup set //*************************************************************************** - template + template > class iset : public etl::set_base { public: @@ -474,7 +474,7 @@ namespace etl { bool operator ()(key_type& key1, key_type& key2) const { - return key_compare()(key1, key2); + return compare(key1, key2); } }; @@ -485,7 +485,7 @@ namespace etl { bool operator ()(value_type& value1, value_type& value2) const { - return value_compare()(value1, value2); + return compare(value1, value2); } }; @@ -512,17 +512,17 @@ namespace etl //************************************************************************* bool node_comp(const Data_Node& node1, const Data_Node& node2) const { - return key_compare()(node1.value, node2.value); + return compare(node1.value, node2.value); } bool node_comp(const Data_Node& node, key_parameter_t key) const { - return key_compare()(node.value, key); + return compare(node.value, key); } bool node_comp(key_parameter_t key, const Data_Node& node) const { - return key_compare()(key, node.value); + return compare(key, node.value); } private: @@ -530,6 +530,8 @@ namespace etl /// The pool of data nodes used in the set. etl::ipool* p_node_pool; + key_compare compare; + //************************************************************************* /// Downcast a Node* to a Data_Node* //************************************************************************* @@ -1185,7 +1187,7 @@ namespace etl { Data_Node& node = *p_node_pool->allocate(); ::new ((void*)&node.value) value_type(value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT return node; } @@ -1196,7 +1198,7 @@ namespace etl { node.value.~value_type(); p_node_pool->release(&node); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* diff --git a/include/etl/stack.h b/include/etl/stack.h index e085a231..db0f124e 100644 --- a/include/etl/stack.h +++ b/include/etl/stack.h @@ -180,7 +180,7 @@ namespace etl void add_in() { top_index = current_size++; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -190,7 +190,7 @@ namespace etl { --top_index; --current_size; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } //************************************************************************* @@ -200,13 +200,13 @@ namespace etl { top_index = 0; current_size = 0; - ETL_RESET_DEBUG_COUNT; + ETL_RESET_DEBUG_COUNT } size_type top_index; ///< The index of the top of the stack. size_type current_size; ///< The number of items in the stack. const size_type CAPACITY; ///< The maximum number of items in the stack. - ETL_DECLARE_DEBUG_COUNT; ///< For internal debugging purposes. + ETL_DECLARE_DEBUG_COUNT ///< For internal debugging purposes. }; //*************************************************************************** diff --git a/include/etl/stl/alternate/limits.h b/include/etl/stl/alternate/limits.h index b8bf99a4..680cf7f9 100644 --- a/include/etl/stl/alternate/limits.h +++ b/include/etl/stl/alternate/limits.h @@ -34,6 +34,7 @@ SOFTWARE. #include "../../platform.h" #include "../../type_traits.h" #include "../../char_traits.h" +#include "../../integral_limits.h" #include #include diff --git a/include/etl/stl/iterator.h b/include/etl/stl/iterator.h index 91299a26..56f2e5d6 100644 --- a/include/etl/stl/iterator.h +++ b/include/etl/stl/iterator.h @@ -40,4 +40,4 @@ SOFTWARE. #include #endif -#endif \ No newline at end of file +#endif diff --git a/include/etl/unordered_map.h b/include/etl/unordered_map.h index 5dc63314..86890a0f 100644 --- a/include/etl/unordered_map.h +++ b/include/etl/unordered_map.h @@ -659,7 +659,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key_value_pair) value_type(key, T()); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT pbucket->insert_after(pbucket->before_begin(), node); @@ -781,15 +781,13 @@ namespace etl bucket_t* pbucket = pbuckets + index; bucket_t& bucket = *pbucket; - size_t s = pbuckets->size(); - // The first one in the bucket? if (bucket.empty()) { // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key_value_pair) value_type(key_value_pair); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); @@ -823,7 +821,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key_value_pair) value_type(key_value_pair); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); @@ -843,7 +841,7 @@ namespace etl ///\param position The position to insert at. ///\param value The value to insert. //********************************************************************* - iterator insert(const_iterator position, const value_type& key_value_pair) + iterator insert(const_iterator, const value_type& key_value_pair) { return insert(key_value_pair).first; } @@ -893,7 +891,7 @@ namespace etl icurrent->key_value_pair.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. n = 1; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } return n; @@ -922,7 +920,7 @@ namespace etl bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key_value_pair.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return inext; } @@ -957,7 +955,7 @@ namespace etl local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. icurrent->key_value_pair.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT icurrent = inext; @@ -1225,7 +1223,7 @@ namespace etl { // Destroy the value contents. it->key_value_pair.~value_type(); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT ++it; } @@ -1283,7 +1281,7 @@ namespace etl key_equal key_equal_function; /// For library debugging purposes only. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/unordered_multimap.h b/include/etl/unordered_multimap.h index 4db58e5a..e1222b41 100644 --- a/include/etl/unordered_multimap.h +++ b/include/etl/unordered_multimap.h @@ -678,7 +678,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key_value_pair) value_type(key_value_pair); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); @@ -708,7 +708,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key_value_pair) value_type(key_value_pair); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); @@ -726,7 +726,7 @@ namespace etl ///\param position The position to insert at. ///\param value The value to insert. //********************************************************************* - iterator insert(const_iterator position, const value_type& key_value_pair) + iterator insert(const_iterator, const value_type& key_value_pair) { return insert(key_value_pair); } @@ -771,7 +771,7 @@ namespace etl pnodepool->release(&*icurrent); // Release it back to the pool. ++n; icurrent = iprevious; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } else { @@ -807,7 +807,7 @@ namespace etl bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key_value_pair.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return inext; } @@ -842,7 +842,7 @@ namespace etl local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. icurrent->key_value_pair.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT icurrent = inext; @@ -1137,7 +1137,7 @@ namespace etl // Destroy the value contents. it->key_value_pair.~value_type(); ++it; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Now it's safe to clear the bucket. @@ -1193,7 +1193,7 @@ namespace etl key_equal key_equal_function; /// For library debugging purposes only. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/unordered_multiset.h b/include/etl/unordered_multiset.h index 8e3bcd29..c6e57901 100644 --- a/include/etl/unordered_multiset.h +++ b/include/etl/unordered_multiset.h @@ -670,7 +670,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key) value_type(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); @@ -701,7 +701,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key) value_type(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); @@ -765,7 +765,7 @@ namespace etl pnodepool->release(&*icurrent); // Release it back to the pool. ++n; icurrent = iprevious; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } else { @@ -801,7 +801,7 @@ namespace etl bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return inext; } @@ -836,7 +836,7 @@ namespace etl local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. icurrent->key.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT icurrent = inext; @@ -1131,7 +1131,7 @@ namespace etl // Destroy the value contents. it->key.~value_type(); ++it; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Now it's safe to clear the bucket. @@ -1187,7 +1187,7 @@ namespace etl key_equal key_equal_function; /// For library debugging purposes only. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/unordered_set.h b/include/etl/unordered_set.h index b1541ee5..fb208cb4 100644 --- a/include/etl/unordered_set.h +++ b/include/etl/unordered_set.h @@ -671,7 +671,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key) value_type(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Just add the pointer to the bucket; bucket.insert_after(bucket.before_begin(), node); @@ -705,7 +705,7 @@ namespace etl // Get a new node. node_t& node = *pnodepool->allocate(); ::new (&node.key) value_type(key); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT // Add the node to the end of the bucket; bucket.insert_after(inode_previous, node); @@ -725,7 +725,7 @@ namespace etl ///\param position The position to insert at. ///\param value The value to insert. //********************************************************************* - iterator insert(const_iterator position, const value_type& key) + iterator insert(const_iterator, const value_type& key) { return insert(key).first; } @@ -775,7 +775,7 @@ namespace etl icurrent->key.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. n = 1; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } return n; @@ -804,7 +804,7 @@ namespace etl bucket.erase_after(iprevious); // Unlink from the bucket. icurrent->key.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT return inext; } @@ -839,7 +839,7 @@ namespace etl local_iterator inext = pbucket->erase_after(iprevious); // Unlink from the bucket. icurrent->key.~value_type(); // Destroy the value. pnodepool->release(&*icurrent); // Release it back to the pool. - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT icurrent = inext; @@ -1108,7 +1108,7 @@ namespace etl // Destroy the value contents. it->key.~value_type(); ++it; - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Now it's safe to clear the bucket. @@ -1164,7 +1164,7 @@ namespace etl key_equal key_equal_function; /// For library debugging purposes only. - ETL_DECLARE_DEBUG_COUNT; + ETL_DECLARE_DEBUG_COUNT //************************************************************************* /// Destructor. diff --git a/include/etl/variant.h b/include/etl/variant.h index a539fe3f..26e9c124 100644 --- a/include/etl/variant.h +++ b/include/etl/variant.h @@ -874,18 +874,18 @@ namespace etl /// Calls the supplied reader instance. /// The 'read' function appropriate to the current type is called with the stored value. //*************************************************************************** - void call(reader& reader) + void call(reader& r) { switch (type_id) { - case 0: reader.read(static_cast(data)); break; - case 1: reader.read(static_cast(data)); break; - case 2: reader.read(static_cast(data)); break; - case 3: reader.read(static_cast(data)); break; - case 4: reader.read(static_cast(data)); break; - case 5: reader.read(static_cast(data)); break; - case 6: reader.read(static_cast(data)); break; - case 7: reader.read(static_cast(data)); break; + case 0: r.read(static_cast(data)); break; + case 1: r.read(static_cast(data)); break; + case 2: r.read(static_cast(data)); break; + case 3: r.read(static_cast(data)); break; + case 4: r.read(static_cast(data)); break; + case 5: r.read(static_cast(data)); break; + case 6: r.read(static_cast(data)); break; + case 7: r.read(static_cast(data)); break; default: break; } } diff --git a/include/etl/variant_pool.h b/include/etl/variant_pool.h index 068d0d3a..e5b6f295 100644 --- a/include/etl/variant_pool.h +++ b/include/etl/variant_pool.h @@ -64,7 +64,7 @@ SOFTWARE. #include "alignment.h" #include "static_assert.h" #include "type_lookup.h" -#include +#include "pool.h" #undef ETL_FILE #define ETL_FILE "40" diff --git a/include/etl/vector.h b/include/etl/vector.h index 50b3ee30..2d5f2fb2 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -234,12 +234,12 @@ namespace etl if (current_size < new_size) { etl::uninitialized_fill_n(p_end, delta, value); - ETL_ADD_DEBUG_COUNT(delta); + ETL_ADD_DEBUG_COUNT(delta) } else { etl::destroy_n(p_end - delta, delta); - ETL_SUBTRACT_DEBUG_COUNT(delta); + ETL_SUBTRACT_DEBUG_COUNT(delta) } p_end = p_buffer + new_size; @@ -370,7 +370,7 @@ namespace etl initialise(); p_end = etl::uninitialized_copy(first, last, p_buffer); - ETL_ADD_DEBUG_COUNT(uint32_t(std::distance(first, last))); + ETL_ADD_DEBUG_COUNT(uint32_t(std::distance(first, last))) } //********************************************************************* @@ -386,7 +386,7 @@ namespace etl initialise(); p_end = etl::uninitialized_fill_n(p_buffer, n, value); - ETL_ADD_DEBUG_COUNT(uint32_t(n)); + ETL_ADD_DEBUG_COUNT(uint32_t(n)) } //************************************************************************* @@ -436,7 +436,7 @@ namespace etl #endif ::new (p_end) T(value1); ++p_end; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -452,7 +452,7 @@ namespace etl #endif ::new (p_end) T(value1, value2); ++p_end; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -468,7 +468,7 @@ namespace etl #endif ::new (p_end) T(value1, value2, value3); ++p_end; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //********************************************************************* @@ -484,7 +484,7 @@ namespace etl #endif ::new (p_end) T(value1, value2, value3, value4); ++p_end; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } //************************************************************************* @@ -536,7 +536,7 @@ namespace etl if (position == end()) { p = p_end++; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } else { @@ -564,7 +564,7 @@ namespace etl if (position == end()) { p = p_end++; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } else { @@ -592,7 +592,7 @@ namespace etl if (position == end()) { p = p_end++; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } else { @@ -620,7 +620,7 @@ namespace etl if (position == end()) { p = p_end++; - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT } else { @@ -673,14 +673,14 @@ namespace etl // Construct old. etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); - ETL_ADD_DEBUG_COUNT(construct_old_n); + ETL_ADD_DEBUG_COUNT(construct_old_n) // Copy old. etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); // Construct new. etl::uninitialized_fill_n(p_end, construct_new_n, value); - ETL_ADD_DEBUG_COUNT(construct_new_n); + ETL_ADD_DEBUG_COUNT(construct_new_n) // Copy new. std::fill_n(p_buffer + insert_begin, copy_new_n, value); @@ -730,14 +730,14 @@ namespace etl // Construct old. etl::uninitialized_copy_n(p_end - construct_old_n, construct_old_n, p_construct_old); - ETL_ADD_DEBUG_COUNT(construct_old_n); + ETL_ADD_DEBUG_COUNT(construct_old_n) // Copy old. etl::copy_n(p_buffer + insert_begin, copy_old_n, p_buffer + insert_end); // Construct new. etl::uninitialized_copy_n(first + copy_new_n, construct_new_n, p_end); - ETL_ADD_DEBUG_COUNT(construct_new_n); + ETL_ADD_DEBUG_COUNT(construct_new_n) // Copy new. etl::copy_n(first, copy_new_n, p_buffer + insert_begin); @@ -779,7 +779,7 @@ namespace etl // Destroy the elements left over at the end. etl::destroy(p_end - n_delete, p_end); - ETL_SUBTRACT_DEBUG_COUNT(n_delete); + ETL_SUBTRACT_DEBUG_COUNT(n_delete) p_end -= n_delete; } @@ -860,7 +860,7 @@ namespace etl void initialise() { etl::destroy(p_buffer, p_end); - ETL_SUBTRACT_DEBUG_COUNT(int32_t(std::distance(p_buffer, p_end))); + ETL_SUBTRACT_DEBUG_COUNT(int32_t(std::distance(p_buffer, p_end))) p_end = p_buffer; } @@ -886,7 +886,7 @@ namespace etl inline void create_back() { etl::create_value_at(p_end); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT ++p_end; } @@ -897,7 +897,7 @@ namespace etl inline void create_back(parameter_t value) { etl::create_copy_at(p_end, value); - ETL_INCREMENT_DEBUG_COUNT; + ETL_INCREMENT_DEBUG_COUNT ++p_end; } @@ -910,7 +910,7 @@ namespace etl --p_end; etl::destroy_at(p_end); - ETL_DECREMENT_DEBUG_COUNT; + ETL_DECREMENT_DEBUG_COUNT } // Disable copy construction. diff --git a/include/etl/version.h b/include/etl/version.h index fb81796b..a89a8969 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -37,10 +37,14 @@ SOFTWARE. /// Definitions of the ETL version ///\ingroup utilities -#define ETL_VERSION "11.12.0" +#define ETL_VERSION "11.15.1" +#define ETL_VERSION_W L"11.15.1" +#define ETL_VERSION_U16 u"11.15.1" +#define ETL_VERSION_U32 U"11.15.1" #define ETL_VERSION_MAJOR 11 -#define ETL_VERSION_MINOR 12 +#define ETL_VERSION_MINOR 15 #define ETL_VERSION_PATCH 0 +#define ETL_VERSION_VALUE ((ETL_VERSION_MAJOR * 10000) + (ETL_VERSION_MINOR * 100) + ETL_VERSION_PATCH) #endif diff --git a/library.properties b/library.properties index c9913f89..78d54048 100644 --- a/library.properties +++ b/library.properties @@ -2,6 +2,7 @@ name=Embedded Template Library version=10.21.2 author= John Wellbelove maintainer=John Wellbelove +license=MIT sentence=A C++ template library tailored for embedded systems. paragraph=Requires some support from STL. See http://andybrown.me.uk/2011/01/15/the-standard-template-library-stl-for-avr-with-c-streams/ or https://github.com/mike-matera/ArduinoSTL.git for Arduino. category=Other diff --git a/src/binary.cpp b/src/binary.cpp index 7f676070..0024e56e 100644 --- a/src/binary.cpp +++ b/src/binary.cpp @@ -28,8 +28,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include "platform.h" -#include "binary.h" +#include "etl/platform.h" +#include "etl/binary.h" namespace etl { diff --git a/src/crc16.cpp b/src/crc16.cpp index 734d379b..9ac1d710 100644 --- a/src/crc16.cpp +++ b/src/crc16.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc16_ccitt.cpp b/src/crc16_ccitt.cpp index 443873a9..12b79a76 100644 --- a/src/crc16_ccitt.cpp +++ b/src/crc16_ccitt.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc16_kermit.cpp b/src/crc16_kermit.cpp index 93836b02..3c44e043 100644 --- a/src/crc16_kermit.cpp +++ b/src/crc16_kermit.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc32.cpp b/src/crc32.cpp index 6ef84f49..c9217577 100644 --- a/src/crc32.cpp +++ b/src/crc32.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc32_c.cpp b/src/crc32_c.cpp index 22700a32..1c54c3f6 100644 --- a/src/crc32_c.cpp +++ b/src/crc32_c.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc64_ecma.cpp b/src/crc64_ecma.cpp index 82a92b0e..f818611e 100644 --- a/src/crc64_ecma.cpp +++ b/src/crc64_ecma.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "platform.h" +#include "etl/platform.h" namespace etl { diff --git a/src/crc8_ccitt.cpp b/src/crc8_ccitt.cpp index 15b80cc9..5a224aff 100644 --- a/src/crc8_ccitt.cpp +++ b/src/crc8_ccitt.cpp @@ -30,8 +30,8 @@ SOFTWARE. #include -#include "platform.h" -#include "static_assert.h" +#include "etl/platform.h" +#include "etl/static_assert.h" ETL_STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); diff --git a/src/error_handler.cpp b/src/error_handler.cpp index 2107e0b5..7f3f3e0c 100644 --- a/src/error_handler.cpp +++ b/src/error_handler.cpp @@ -28,9 +28,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include "platform.h" -#include "error_handler.h" -#include "nullptr.h" +#include "etl/platform.h" +#include "etl/error_handler.h" +#include "etl/nullptr.h" //***************************************************************************** /// The error function callback pointer. diff --git a/src/pearson.cpp b/src/pearson.cpp index 0852c7e5..7051d254 100644 --- a/src/pearson.cpp +++ b/src/pearson.cpp @@ -30,8 +30,8 @@ SOFTWARE. #include -#include "platform.h" -#include "static_assert.h" +#include "etl/platform.h" +#include "etl/static_assert.h" ETL_STATIC_ASSERT(ETL_8BIT_SUPPORT, "This file does not currently support targets with no 8bit type"); diff --git a/src/private/pvoidvector.cpp b/src/private/pvoidvector.cpp index 5b000adf..814abbd4 100644 --- a/src/private/pvoidvector.cpp +++ b/src/private/pvoidvector.cpp @@ -31,6 +31,462 @@ SOFTWARE. #include "../../include/etl/platform.h" #include "../../include/etl/private/pvoidvector.h" +//********************************************************************* +/// Returns an iterator to the beginning of the vector. +///\return An iterator to the beginning of the vector. +//********************************************************************* +etl::pvoidvector::iterator etl::pvoidvector::begin() +{ + return p_buffer; +} + +//********************************************************************* +/// Returns a const_iterator to the beginning of the vector. +///\return A const iterator to the beginning of the vector. +//********************************************************************* +etl::pvoidvector::const_iterator etl::pvoidvector::begin() const +{ + return const_iterator(p_buffer); +} + +//********************************************************************* +/// Returns an iterator to the end of the vector. +///\return An iterator to the end of the vector. +//********************************************************************* +etl::pvoidvector::iterator etl::pvoidvector::end() +{ + return p_end; +} + +//********************************************************************* +/// Returns a const_iterator to the end of the vector. +///\return A const iterator to the end of the vector. +//********************************************************************* +etl::pvoidvector::const_iterator etl::pvoidvector::end() const +{ + return const_iterator(p_end); +} + +//********************************************************************* +/// Returns a const_iterator to the beginning of the vector. +///\return A const iterator to the beginning of the vector. +//********************************************************************* +etl::pvoidvector::const_iterator etl::pvoidvector::cbegin() const +{ + return const_iterator(p_buffer); +} + +//********************************************************************* +/// Returns a const_iterator to the end of the vector. +///\return A const iterator to the end of the vector. +//********************************************************************* +etl::pvoidvector::const_iterator etl::pvoidvector::cend() const +{ + return const_iterator(p_end); +} + +//********************************************************************* +/// Returns an reverse iterator to the reverse beginning of the vector. +///\return Iterator to the reverse beginning of the vector. +//********************************************************************* +etl::pvoidvector::reverse_iterator etl::pvoidvector::rbegin() +{ + return reverse_iterator(end()); +} + +//********************************************************************* +/// Returns a const reverse iterator to the reverse beginning of the vector. +///\return Const iterator to the reverse beginning of the vector. +//********************************************************************* +etl::pvoidvector::const_reverse_iterator etl::pvoidvector::rbegin() const +{ + return const_reverse_iterator(end()); +} + +//********************************************************************* +/// Returns a reverse iterator to the end + 1 of the vector. +///\return Reverse iterator to the end + 1 of the vector. +//********************************************************************* +etl::pvoidvector::reverse_iterator etl::pvoidvector::rend() +{ + return reverse_iterator(begin()); +} + +//********************************************************************* +/// Returns a const reverse iterator to the end + 1 of the vector. +///\return Const reverse iterator to the end + 1 of the vector. +//********************************************************************* +etl::pvoidvector::const_reverse_iterator etl::pvoidvector::rend() const +{ + return const_reverse_iterator(begin()); +} + +//********************************************************************* +/// Returns a const reverse iterator to the reverse beginning of the vector. +///\return Const reverse iterator to the reverse beginning of the vector. +//********************************************************************* +etl::pvoidvector::const_reverse_iterator etl::pvoidvector::crbegin() const +{ + return const_reverse_iterator(cend()); +} + +//********************************************************************* +/// Returns a const reverse iterator to the end + 1 of the vector. +///\return Const reverse iterator to the end + 1 of the vector. +//********************************************************************* +etl::pvoidvector::const_reverse_iterator etl::pvoidvector::crend() const +{ + return const_reverse_iterator(cbegin()); +} + +//********************************************************************* +/// Resizes the vector. +/// If asserts or exceptions are enabled and the new size is larger than the +/// maximum then a vector_full is thrown. +///\param new_size The new size. +//********************************************************************* +void etl::pvoidvector::resize(size_t new_size) +{ + ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full)); + + p_end = p_buffer + new_size; +} + +//********************************************************************* +/// Resizes the vector. +/// If asserts or exceptions are enabled and the new size is larger than the +/// maximum then a vector_full is thrown. +///\param new_size The new size. +///\param value The value to fill new elements with. Default = default constructed value. +//********************************************************************* +void etl::pvoidvector::resize(size_t new_size, etl::pvoidvector::value_type value) +{ + ETL_ASSERT(new_size <= CAPACITY, ETL_ERROR(vector_full)); + + pointer p_new_end = p_buffer + new_size; + + // Size up if necessary. + if (p_end < p_new_end) + { + std::fill(p_end, p_new_end, value); + } + + p_end = p_new_end; +} + +//********************************************************************* +/// Returns a reference to the value at index 'i' +///\param i The index. +///\return A reference to the value at index 'i' +//********************************************************************* +etl::pvoidvector::reference etl::pvoidvector::operator [](size_t i) +{ + return reference(p_buffer[i]); +} + +//********************************************************************* +/// Returns a const reference to the value at index 'i' +///\param i The index. +///\return A const reference to the value at index 'i' +//********************************************************************* +etl::pvoidvector::const_reference etl::pvoidvector::operator [](size_t i) const +{ + return const_reference(p_buffer[i]); +} + +//********************************************************************* +/// Returns a reference to the value at index 'i' +/// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. +///\param i The index. +///\return A reference to the value at index 'i' +//********************************************************************* +etl::pvoidvector::reference etl::pvoidvector::at(size_t i) +{ + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); + return reference(p_buffer[i]); +} + +//********************************************************************* +/// Returns a const reference to the value at index 'i' +/// If asserts or exceptions are enabled, emits an etl::vector_out_of_bounds if the index is out of range. +///\param i The index. +///\return A const reference to the value at index 'i' +//********************************************************************* +etl::pvoidvector::const_reference etl::pvoidvector::at(size_t i) const +{ + ETL_ASSERT(i < size(), ETL_ERROR(vector_out_of_bounds)); + return const_reference(p_buffer[i]); +} + +//********************************************************************* +/// Returns a reference to the first element. +///\return A reference to the first element. +//********************************************************************* +etl::pvoidvector::reference etl::pvoidvector::front() +{ + return reference(p_buffer[0]); +} + +//********************************************************************* +/// Returns a const reference to the first element. +///\return A const reference to the first element. +//********************************************************************* +etl::pvoidvector::const_reference etl::pvoidvector::front() const +{ + return const_reference(p_buffer[0]); +} + +//********************************************************************* +/// Returns a reference to the last element. +///\return A reference to the last element. +//********************************************************************* +etl::pvoidvector::reference etl::pvoidvector::back() +{ + return reference(*(p_end - 1)); +} + +//********************************************************************* +/// Returns a const reference to the last element. +///\return A const reference to the last element. +//********************************************************************* +etl::pvoidvector::const_reference etl::pvoidvector::back() const +{ + return const_reference(*(p_end - 1)); +} + +//********************************************************************* +/// Returns a pointer to the beginning of the vector data. +///\return A pointer to the beginning of the vector data. +//********************************************************************* +etl::pvoidvector::pointer etl::pvoidvector::data() +{ + return pointer(p_buffer); +} + +//********************************************************************* +/// Returns a const pointer to the beginning of the vector data. +///\return A const pointer to the beginning of the vector data. +//********************************************************************* +etl::pvoidvector::const_pointer etl::pvoidvector::data() const +{ + return const_pointer(p_buffer); +} + +//********************************************************************* +/// Assigns values to the vector. +/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. +///\param n The number of elements to add. +///\param value The value to insert for each element. +//********************************************************************* +void etl::pvoidvector::assign(size_t n, etl::pvoidvector::value_type value) +{ + initialise(); + + ETL_ASSERT(n <= CAPACITY, ETL_ERROR(vector_full)); + + for (size_t current_size = 0; current_size < n; ++current_size) + { + *p_end++ = value; + } +} + +//************************************************************************* +/// Clears the vector. +//************************************************************************* +void etl::pvoidvector::clear() +{ + initialise(); +} + +//************************************************************************* +/// Increases the size of the vector by one, but does not initialise the new element. +/// If asserts or exceptions are enabled, throws a vector_full if the vector is already full. +//************************************************************************* +void etl::pvoidvector::push_back() +{ +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + + ++p_end; +} + +//********************************************************************* +/// Inserts a value at the end of the vector. +/// If asserts or exceptions are enabled, emits vector_full if the vector is already full. +///\param value The value to add. +//********************************************************************* +void etl::pvoidvector::push_back(etl::pvoidvector::value_type value) +{ +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); +#endif + *p_end++ = value; +} + +//************************************************************************* +/// Removes an element from the end of the vector. +/// Does nothing if the vector is empty. +//************************************************************************* +void etl::pvoidvector::pop_back() +{ +#if defined(ETL_CHECK_PUSH_POP) + ETL_ASSERT(size() > 0, ETL_ERROR(vector_empty)); +#endif + --p_end; +} + +//********************************************************************* +/// Inserts a value to the vector. +/// If asserts or exceptions are enabled, emits vector_full if the vector is already full. +///\param position The position to insert before. +///\param value The value to insert. +//********************************************************************* +etl::pvoidvector::iterator etl::pvoidvector::insert(etl::pvoidvector::iterator position, etl::pvoidvector::value_type value) +{ + ETL_ASSERT(size() + 1 <= CAPACITY, ETL_ERROR(vector_full)); + + if (position != end()) + { + ++p_end; + std::copy_backward(position, end() - 1, end()); + *position = value; + } + else + { + *p_end++ = value; + } + + return position; +} + +//********************************************************************* +/// Inserts 'n' values to the vector. +/// If asserts or exceptions are enabled, emits vector_full if the vector does not have enough free space. +///\param position The position to insert before. +///\param n The number of elements to add. +///\param value The value to insert. +//********************************************************************* +void etl::pvoidvector::insert(etl::pvoidvector::iterator position, size_t n, etl::pvoidvector::value_type value) +{ + ETL_ASSERT((size() + 1) <= CAPACITY, ETL_ERROR(vector_full)); + + std::copy_backward(position, p_end, p_end + n); + std::fill_n(position, n, value); + + p_end += n; +} + +//********************************************************************* +/// Erases an element. +///\param i_element Iterator to the element. +///\return An iterator pointing to the element that followed the erased element. +//********************************************************************* +etl::pvoidvector::iterator etl::pvoidvector::erase(etl::pvoidvector::iterator i_element) +{ + std::copy(i_element + 1, end(), i_element); + --p_end; + + return i_element; +} + +//********************************************************************* +/// Erases a range of elements. +/// The range includes all the elements between first and last, including the +/// element pointed by first, but not the one pointed by last. +///\param first Iterator to the first element. +///\param last Iterator to the last element. +///\return An iterator pointing to the element that followed the erased element. +//********************************************************************* +etl::pvoidvector::iterator etl::pvoidvector::erase(etl::pvoidvector::iterator first, etl::pvoidvector::iterator last) +{ + std::copy(last, end(), first); + size_t n_delete = std::distance(first, last); + + // Just adjust the count. + p_end -= n_delete; + + return first; +} + +//************************************************************************* +/// Assignment operator. +//************************************************************************* +etl::pvoidvector& etl::pvoidvector::operator = (const etl::pvoidvector& rhs) +{ + if (&rhs != this) + { + assign(rhs.cbegin(), rhs.cend()); + } + + return *this; +} + +//************************************************************************* +/// Gets the current size of the vector. +///\return The current size of the vector. +//************************************************************************* +etl::pvoidvector::size_type etl::pvoidvector::size() const +{ + return size_t(p_end - p_buffer); +} + +//************************************************************************* +/// Checks the 'empty' state of the vector. +///\return true if empty. +//************************************************************************* +bool etl::pvoidvector::empty() const +{ + return (p_end == p_buffer); +} + +//************************************************************************* +/// Checks the 'full' state of the vector. +///\return true if full. +//************************************************************************* +bool etl::pvoidvector::full() const +{ + return size() == CAPACITY; +} + +//************************************************************************* +/// Returns the remaining capacity. +///\return The remaining capacity. +//************************************************************************* +size_t etl::pvoidvector::available() const +{ + return max_size() - size(); +} + +//********************************************************************* +/// Constructor. +//********************************************************************* +etl::pvoidvector::pvoidvector(void** p_buffer_, size_t MAX_SIZE) + : vector_base(MAX_SIZE), + p_buffer(p_buffer_), + p_end(p_buffer_) +{ +} + +//********************************************************************* +/// Initialise the vector. +//********************************************************************* +void etl::pvoidvector::initialise() +{ + p_end = p_buffer; +} + +//************************************************************************* +/// Fix the internal pointers after a low level memory copy. +//************************************************************************* +void etl::pvoidvector::repair(void** p_buffer_) +{ + uintptr_t length = p_end - p_buffer; + + p_buffer = p_buffer_; + p_end = p_buffer_ + length; +} + namespace etl { //*************************************************************************** diff --git a/src/random.cpp b/src/random.cpp index 4edb6188..ba1b0ba9 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -28,8 +28,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#include "platform.h" -#include "random.h" +#include "etl/platform.h" +#include "etl/random.h" namespace etl { diff --git a/support/Release notes.txt b/support/Release notes.txt index fc86ae10..f977f9d7 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,57 @@ +=============================================================================== +11.15.1 +io_port_test Fixed unaligned access error. +debug_count Removed typed += & -= operators and replaced with templates. + +=============================================================================== +11.15.0 +Added 'memory model' selection for queues to allow more efficient implementations. + +Maximum queue sizes: +MEMORY_MODEL_SMALL 255 (254 for queue_spsc_atomic) +MEMORY_MODEL_MEDIUM 65535 +MEMORY_MODEL_LARGE 2147483647 +MEMORY_MODEL_HUGE 9223372036854775807 + +Fixed syntax errors highlighted by GCC v8 + +=============================================================================== +11.14.2 +Removed reference_flat_set & reference_flat_map reliance on equality. + +=============================================================================== +11.14.1 +Removed flat_set & flat_map reliance on equality. + +=============================================================================== +11.14.0 +Added tests for limited support for self insert for strings. +Added 'wipe_on_destruct' template class for secure wiping of objects on destruction. +Updated unique_ptr API. + +=============================================================================== +11.13.2 +Protected destructor for some FSM classes. +Observer's remove_observer returns bool. + +=============================================================================== +11.13.1 +Fixed vector of pointer typedefs + +=============================================================================== +11.13.0 +Added specialisation for vector + +=============================================================================== +11.12.2 +Remove SFINAE from array_view. +Added default etl::less compare type appropriate map and set classes. +Moved non-template code in pvoidvector to cpp file. + +=============================================================================== +11.12.1 +Made atomic load const for non STL vesions + =============================================================================== 11.12.0 Renamed STATIC_ASSERT to ETL_STATIC_ASSERT diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index 7a3eee9d..cbbcc3ec 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -61,18 +61,18 @@ - - - - + + + + - + @@ -406,9 +406,13 @@ + + + + diff --git a/test/data.h b/test/data.h index 0fbf9ed6..c43769e8 100644 --- a/test/data.h +++ b/test/data.h @@ -31,7 +31,7 @@ SOFTWARE. #include -#include "instance_count.h" +#include "etl/instance_count.h" //***************************************************************************** // Default constructor. diff --git a/test/etl_profile.h b/test/etl_profile.h index 213e99ea..e5cc186b 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -77,9 +77,9 @@ SOFTWARE. //#define ETL_NO_STL #ifdef _MSC_VER - #include "profiles/msvc_x86.h" + #include "etl/profiles/msvc_x86.h" #else - #include "profiles/gcc_windows_x86.h" + #include "etl/profiles/gcc_windows_x86.h" #endif #endif diff --git a/test/murmurhash3.cpp b/test/murmurhash3.cpp index 39663531..31d812e1 100644 --- a/test/murmurhash3.cpp +++ b/test/murmurhash3.cpp @@ -7,7 +7,7 @@ // compile and run any of them on any platform, but your performance with the // non-native version will be less than optimal. -#include "platform.h" +#include "etl/platform.h" #ifdef ETL_COMPILER_GCC #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" diff --git a/test/murmurhash3.h b/test/murmurhash3.h index 42f8ef74..46ac322a 100644 --- a/test/murmurhash3.h +++ b/test/murmurhash3.h @@ -10,7 +10,7 @@ // Microsoft Visual Studio -#include "platform.h" +#include "etl/platform.h" #if defined(ETL_COMPILER_MICROSOFT) && (_MSC_VER < 1600) diff --git a/test/test_algorithm.cpp b/test/test_algorithm.cpp index 52984cc9..f7eea553 100644 --- a/test/test_algorithm.cpp +++ b/test/test_algorithm.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "algorithm.h" -#include "container.h" +#include "etl/algorithm.h" +#include "etl/container.h" #include #include diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index ba0b25ab..7a03a248 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "alignment.h" -#include "type_traits.h" +#include "etl/alignment.h" +#include "etl/type_traits.h" #include #include diff --git a/test/test_array.cpp b/test/test_array.cpp index 993be93b..28024f19 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -28,13 +28,13 @@ SOFTWARE. #include "UnitTest++.h" -#include "array.h" +#include "etl/array.h" #include #include #include -#include "integral_limits.h" +#include "etl/integral_limits.h" namespace { diff --git a/test/test_array_view.cpp b/test/test_array_view.cpp index 875b4bb7..1ada4ddc 100644 --- a/test/test_array_view.cpp +++ b/test/test_array_view.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "array_view.h" -#include "array.h" +#include "etl/array_view.h" +#include "etl/array.h" #include #include diff --git a/test/test_array_wrapper.cpp b/test/test_array_wrapper.cpp index b803575a..461f3190 100644 --- a/test/test_array_wrapper.cpp +++ b/test/test_array_wrapper.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "array_wrapper.h" +#include "etl/array_wrapper.h" namespace { diff --git a/test/test_atomic_gcc_sync.cpp b/test/test_atomic_gcc_sync.cpp index 9af9c77e..8f26a827 100644 --- a/test/test_atomic_gcc_sync.cpp +++ b/test/test_atomic_gcc_sync.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "platform.h" -#include "atomic/atomic_std.h" +#include "etl/platform.h" +#include "etl/atomic/atomic_std.h" #include diff --git a/test/test_atomic_std.cpp b/test/test_atomic_std.cpp index d89872a9..f1655549 100644 --- a/test/test_atomic_std.cpp +++ b/test/test_atomic_std.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "platform.h" -#include "atomic/atomic_std.h" +#include "etl/platform.h" +#include "etl/atomic/atomic_std.h" #include diff --git a/test/test_binary.cpp b/test/test_binary.cpp index 35cd1c53..6923a0f7 100644 --- a/test/test_binary.cpp +++ b/test/test_binary.cpp @@ -31,10 +31,10 @@ SOFTWARE. #include #include -#include "binary.h" -#include "bitset.h" -#include "fnv_1.h" -#include "integral_limits.h" +#include "etl/binary.h" +#include "etl/bitset.h" +#include "etl/fnv_1.h" +#include "etl/integral_limits.h" // Count bits the easy way. template diff --git a/test/test_bitset.cpp b/test/test_bitset.cpp index b3991918..6e7ea3fc 100644 --- a/test/test_bitset.cpp +++ b/test/test_bitset.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "bitset.h" +#include "etl/bitset.h" namespace { diff --git a/test/test_bloom_filter.cpp b/test/test_bloom_filter.cpp index 7a275768..77853300 100644 --- a/test/test_bloom_filter.cpp +++ b/test/test_bloom_filter.cpp @@ -31,14 +31,14 @@ SOFTWARE. #include #include -#include "bloom_filter.h" +#include "etl/bloom_filter.h" -#include "fnv_1.h" -#include "crc16.h" -#include "crc16_ccitt.h" -#include "crc32.h" +#include "etl/fnv_1.h" +#include "etl/crc16.h" +#include "etl/crc16_ccitt.h" +#include "etl/crc32.h" -#include "char_traits.h" +#include "etl/char_traits.h" struct hash1_t { diff --git a/test/test_bsd_checksum.cpp b/test/test_bsd_checksum.cpp index 0f4cadef..0197d3cf 100644 --- a/test/test_bsd_checksum.cpp +++ b/test/test_bsd_checksum.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "checksum.h" +#include "etl/checksum.h" namespace { diff --git a/test/test_c_timer_framework.cpp b/test/test_c_timer_framework.cpp index 00e98536..d332f41f 100644 --- a/test/test_c_timer_framework.cpp +++ b/test/test_c_timer_framework.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "platform.h" +#include "etl/platform.h" extern "C" { diff --git a/test/test_callback_timer.cpp b/test/test_callback_timer.cpp index d5197d3a..b0ad6fa9 100644 --- a/test/test_callback_timer.cpp +++ b/test/test_callback_timer.cpp @@ -29,8 +29,8 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "callback_timer.h" -#include "function.h" +#include "etl/callback_timer.h" +#include "etl/function.h" #include #include diff --git a/test/test_checksum.cpp b/test/test_checksum.cpp index f7a45d9d..60add3e0 100644 --- a/test/test_checksum.cpp +++ b/test/test_checksum.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "checksum.h" +#include "etl/checksum.h" namespace { diff --git a/test/test_compare.cpp b/test/test_compare.cpp index 3c2d65f5..b09d3c8d 100644 --- a/test/test_compare.cpp +++ b/test/test_compare.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "compare.h" +#include "etl/compare.h" namespace { diff --git a/test/test_constant.cpp b/test/test_constant.cpp index 6cd1587a..4f18979d 100644 --- a/test/test_constant.cpp +++ b/test/test_constant.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "constant.h" -#include "integral_limits.h" +#include "etl/constant.h" +#include "etl/integral_limits.h" #include #include diff --git a/test/test_container.cpp b/test/test_container.cpp index 3c441f95..d78e460b 100644 --- a/test/test_container.cpp +++ b/test/test_container.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "container.h" +#include "etl/container.h" #include diff --git a/test/test_crc.cpp b/test/test_crc.cpp index a376e02d..9cb3bc5b 100644 --- a/test/test_crc.cpp +++ b/test/test_crc.cpp @@ -33,12 +33,12 @@ SOFTWARE. #include #include -#include "crc8_ccitt.h" -#include "crc16.h" -#include "crc16_ccitt.h" -#include "crc16_kermit.h" -#include "crc32.h" -#include "crc64_ecma.h" +#include "etl/crc8_ccitt.h" +#include "etl/crc16.h" +#include "etl/crc16_ccitt.h" +#include "etl/crc16_kermit.h" +#include "etl/crc32.h" +#include "etl/crc64_ecma.h" namespace { diff --git a/test/test_cyclic_value.cpp b/test/test_cyclic_value.cpp index 14a9ab94..ce92742c 100644 --- a/test/test_cyclic_value.cpp +++ b/test/test_cyclic_value.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "cyclic_value.h" +#include "etl/cyclic_value.h" namespace { diff --git a/test/test_debounce.cpp b/test/test_debounce.cpp index bab33073..8424e77e 100644 --- a/test/test_debounce.cpp +++ b/test/test_debounce.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "debounce.h" +#include "etl/debounce.h" namespace { diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 869bdfcd..06a1975f 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "deque.h" +#include "etl/deque.h" #include "data.h" diff --git a/test/test_embedded_compile.cpp b/test/test_embedded_compile.cpp index 12b78f7d..4d589371 100644 --- a/test/test_embedded_compile.cpp +++ b/test/test_embedded_compile.cpp @@ -1,30 +1,30 @@ -#include "algorithm.h" -#include "alignment.h" -#include "array.h" -#include "bitset.h" -#include "container.h" -#include "crc8_ccitt.h" -#include "crc16.h" -#include "crc16_ccitt.h" -#include "crc16_kermit.h" -#include "crc32.h" -#include "crc64_ecma.h" -#include "cyclic_value.h" -#include "deque.h" -#include "io_port.h" -#include "vector.h" -#include "variant.h" -#include "list.h" -#include "map.h" -#include "integral_limits.h" -#include "constant.h" +#include "etl/algorithm.h" +#include "etl/alignment.h" +#include "etl/array.h" +#include "etl/bitset.h" +#include "etl/container.h" +#include "etl/crc8_ccitt.h" +#include "etl/crc16.h" +#include "etl/crc16_ccitt.h" +#include "etl/crc16_kermit.h" +#include "etl/crc32.h" +#include "etl/crc64_ecma.h" +#include "etl/cyclic_value.h" +#include "etl/deque.h" +#include "etl/io_port.h" +#include "etl/vector.h" +#include "etl/variant.h" +#include "etl/list.h" +#include "etl/map.h" +#include "etl/integral_limits.h" +#include "etl/constant.h" #include #if !defined(ETL_COMPILER_IAR) & !defined(ETL_COMPILER_TI) -#include "stm32f4xx.h" +#include "etl/stm32f4xx.h" #endif #if defined(COMPILER_KEIL) diff --git a/test/test_endian.cpp b/test/test_endian.cpp index 4028eb3e..fa174a85 100644 --- a/test/test_endian.cpp +++ b/test/test_endian.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include -#include "endianness.h" +#include "etl/endianness.h" namespace { diff --git a/test/test_enum_type.cpp b/test/test_enum_type.cpp index 5db8bd18..e59e8ff5 100644 --- a/test/test_enum_type.cpp +++ b/test/test_enum_type.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include -#include "enum_type.h" +#include "etl/enum_type.h" struct enum_test { diff --git a/test/test_error_handler.cpp b/test/test_error_handler.cpp index b50ce2dd..9dc07f9d 100644 --- a/test/test_error_handler.cpp +++ b/test/test_error_handler.cpp @@ -33,8 +33,8 @@ SOFTWARE. #include #include -#include "error_handler.h" -#include "exception.h" +#include "etl/error_handler.h" +#include "etl/exception.h" bool error_received; diff --git a/test/test_exception.cpp b/test/test_exception.cpp index 4fa95c34..333842c3 100644 --- a/test/test_exception.cpp +++ b/test/test_exception.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include -#include "exception.h" +#include "etl/exception.h" namespace { diff --git a/test/test_factory.cpp b/test/test_factory.cpp index 70d6a824..e11b6ef0 100644 --- a/test/test_factory.cpp +++ b/test/test_factory.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "factory.h" +#include "etl/factory.h" #include #include diff --git a/test/test_fixed_iterator.cpp b/test/test_fixed_iterator.cpp index ae580c92..4905739e 100644 --- a/test/test_fixed_iterator.cpp +++ b/test/test_fixed_iterator.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include #include -#include "fixed_iterator.h" +#include "etl/fixed_iterator.h" template std::ostream& operator << (std::ostream& os, const etl::fixed_iterator& fi) diff --git a/test/test_flat_map.cpp b/test/test_flat_map.cpp index c290da7f..456bf688 100644 --- a/test/test_flat_map.cpp +++ b/test/test_flat_map.cpp @@ -40,7 +40,7 @@ SOFTWARE. #include "data.h" -#include "flat_map.h" +#include "etl/flat_map.h" namespace { @@ -309,6 +309,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), SIZE); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_flat_multimap.cpp b/test/test_flat_multimap.cpp index 2c2486cb..7a7a3380 100644 --- a/test/test_flat_multimap.cpp +++ b/test/test_flat_multimap.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "flat_multimap.h" +#include "etl/flat_multimap.h" namespace { @@ -286,6 +286,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), SIZE); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_flat_multiset.cpp b/test/test_flat_multiset.cpp index e9bccba0..00cac75d 100644 --- a/test/test_flat_multiset.cpp +++ b/test/test_flat_multiset.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "flat_multiset.h" +#include "etl/flat_multiset.h" namespace { @@ -255,6 +255,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), SIZE); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_flat_set.cpp b/test/test_flat_set.cpp index 1e0e9982..a5983cf3 100644 --- a/test/test_flat_set.cpp +++ b/test/test_flat_set.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "flat_set.h" +#include "etl/flat_set.h" namespace { @@ -267,6 +267,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), SIZE); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_fnv_1.cpp b/test/test_fnv_1.cpp index fd6d6c27..a852dce9 100644 --- a/test/test_fnv_1.cpp +++ b/test/test_fnv_1.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "fnv_1.h" +#include "etl/fnv_1.h" namespace { diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 98827bb3..cb795c93 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -31,7 +31,7 @@ SOFTWARE. #include "data.h" -#include "forward_list.h" +#include "etl/forward_list.h" #include #include @@ -87,6 +87,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_fsm.cpp b/test/test_fsm.cpp index cbc6d376..0418a862 100644 --- a/test/test_fsm.cpp +++ b/test/test_fsm.cpp @@ -28,11 +28,11 @@ SOFTWARE. #include "UnitTest++.h" -#include "fsm.h" -#include "enum_type.h" -#include "container.h" -#include "packet.h" -#include "queue.h" +#include "etl/fsm.h" +#include "etl/enum_type.h" +#include "etl/container.h" +#include "etl/packet.h" +#include "etl/queue.h" #include diff --git a/test/test_function.cpp b/test/test_function.cpp index d82e3cae..cc92263c 100644 --- a/test/test_function.cpp +++ b/test/test_function.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "function.h" +#include "etl/function.h" //***************************************************************************** const int VALUE = 1; diff --git a/test/test_functional.cpp b/test/test_functional.cpp index 8a3ce993..8e2cd1a5 100644 --- a/test/test_functional.cpp +++ b/test/test_functional.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "functional.h" +#include "etl/functional.h" #include #include diff --git a/test/test_hash.cpp b/test/test_hash.cpp index c9fbc425..1a4e024d 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "hash.h" +#include "etl/hash.h" namespace { diff --git a/test/test_instance_count.cpp b/test/test_instance_count.cpp index 72e5512c..6a0b817b 100644 --- a/test/test_instance_count.cpp +++ b/test/test_instance_count.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "instance_count.h" +#include "etl/instance_count.h" #include #include diff --git a/test/test_integral_limits.cpp b/test/test_integral_limits.cpp index 8a23abf8..d461053f 100644 --- a/test/test_integral_limits.cpp +++ b/test/test_integral_limits.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "integral_limits.h" +#include "etl/integral_limits.h" namespace { diff --git a/test/test_intrusive_forward_list.cpp b/test/test_intrusive_forward_list.cpp index 982e6e74..b2d3f9d0 100644 --- a/test/test_intrusive_forward_list.cpp +++ b/test/test_intrusive_forward_list.cpp @@ -31,7 +31,7 @@ SOFTWARE. #include "data.h" -#include "intrusive_forward_list.h" +#include "etl/intrusive_forward_list.h" #include #include diff --git a/test/test_intrusive_links.cpp b/test/test_intrusive_links.cpp index d98570be..b9304ca8 100644 --- a/test/test_intrusive_links.cpp +++ b/test/test_intrusive_links.cpp @@ -31,7 +31,7 @@ SOFTWARE. #include "data.h" -#include "intrusive_links.h" +#include "etl/intrusive_links.h" namespace { diff --git a/test/test_intrusive_list.cpp b/test/test_intrusive_list.cpp index 4d85c00a..382c771c 100644 --- a/test/test_intrusive_list.cpp +++ b/test/test_intrusive_list.cpp @@ -31,7 +31,7 @@ SOFTWARE. #include "data.h" -#include "intrusive_list.h" +#include "etl/intrusive_list.h" #include #include diff --git a/test/test_intrusive_queue.cpp b/test/test_intrusive_queue.cpp index 3c6f5849..ebd37ad8 100644 --- a/test/test_intrusive_queue.cpp +++ b/test/test_intrusive_queue.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "intrusive_queue.h" -#include "intrusive_links.h" +#include "etl/intrusive_queue.h" +#include "etl/intrusive_links.h" #include diff --git a/test/test_intrusive_stack.cpp b/test/test_intrusive_stack.cpp index f6340479..5b752a87 100644 --- a/test/test_intrusive_stack.cpp +++ b/test/test_intrusive_stack.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "intrusive_stack.h" -#include "intrusive_links.h" +#include "etl/intrusive_stack.h" +#include "etl/intrusive_links.h" #include diff --git a/test/test_io_port.cpp b/test/test_io_port.cpp index 398c5bc8..4634e8da 100644 --- a/test/test_io_port.cpp +++ b/test/test_io_port.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "io_port.h" +#include "etl/io_port.h" #include #include @@ -95,7 +95,14 @@ namespace //************************************************************************* TEST(test_dynamic_io_port) { - uint8_t memory[7]; + union U + { + uint16_t dummy; + uint8_t memory[7]; + } u; + + uint8_t* memory = &u.memory[0]; + memory[0] = 0x12; memory[1] = 0x00; memory[2] = 0x00; @@ -104,7 +111,7 @@ namespace memory[5] = 0x9A; memory[6] = 0x00; - dynamic_serial_port port(memory); + dynamic_serial_port port(&u.memory[0]); uint8_t rxdata = port.rxdata; CHECK_EQUAL(memory[0], rxdata); diff --git a/test/test_iterator.cpp b/test/test_iterator.cpp index 1505b972..728fb09b 100644 --- a/test/test_iterator.cpp +++ b/test/test_iterator.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "iterator.h" +#include "etl/iterator.h" //#include diff --git a/test/test_jenkins.cpp b/test/test_jenkins.cpp index 1f6aa80e..3b2f8647 100644 --- a/test/test_jenkins.cpp +++ b/test/test_jenkins.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "jenkins.h" +#include "etl/jenkins.h" template uint32_t jenkins(TIterator begin, TIterator end) diff --git a/test/test_largest.cpp b/test/test_largest.cpp index 48eec18a..f420ede1 100644 --- a/test/test_largest.cpp +++ b/test/test_largest.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "largest.h" +#include "etl/largest.h" #include diff --git a/test/test_list.cpp b/test/test_list.cpp index a96e1127..02305747 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "list.h" +#include "etl/list.h" #include "data.h" @@ -98,6 +98,7 @@ namespace CHECK_EQUAL(data.size(), size_t(0)); CHECK(data.empty()); CHECK_EQUAL(data.max_size(), SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_map.cpp b/test/test_map.cpp index 1881f0e2..c1cdedec 100644 --- a/test/test_map.cpp +++ b/test/test_map.cpp @@ -36,7 +36,7 @@ SOFTWARE. #include #include -#include "map.h" +#include "etl/map.h" static const size_t MAX_SIZE = 10; @@ -181,6 +181,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), MAX_SIZE); CHECK_EQUAL(data.max_size(), MAX_SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_maths.cpp b/test/test_maths.cpp index 4d42f3c6..636fe335 100644 --- a/test/test_maths.cpp +++ b/test/test_maths.cpp @@ -28,13 +28,13 @@ SOFTWARE. #include "UnitTest++.h" -#include "log.h" -#include "power.h" -#include "fibonacci.h" -#include "factorial.h" -#include "sqrt.h" -#include "permutations.h" -#include "combinations.h" +#include "etl/log.h" +#include "etl/power.h" +#include "etl/fibonacci.h" +#include "etl/factorial.h" +#include "etl/sqrt.h" +#include "etl/permutations.h" +#include "etl/combinations.h" namespace { diff --git a/test/test_memory.cpp b/test/test_memory.cpp index 0f5f0f4e..a0448891 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -28,8 +28,8 @@ SOFTWARE. #include "UnitTest++.h" -#include "memory.h" -#include "debug_count.h" +#include "etl/memory.h" +#include "etl/debug_count.h" #include #include @@ -528,5 +528,47 @@ namespace CHECK_EQUAL(test_item_trivial, etl::make_copy_at(pn, test_item_trivial, count)); CHECK_EQUAL(3U, count); } + + //************************************************************************* + TEST(test_wipe_on_destruct) + { + struct Data : public etl::wipe_on_destruct + { + Data(int a_, char b_, double c_) + : a(a_), + b(b_), + c(c_) + { + } + + bool operator ==(const Data& other) const + { + return (a == other.a) && (b == other.b) && (c == other.c); + } + + int a; + char b; + double c; + }; + + std::array buffer; + buffer.fill(0); + + // Construct in-place. + ::new (buffer.data()) Data(1, 'b', 3.4); + + Data& other = *reinterpret_cast(buffer.data()); + CHECK(other == Data(1, 'b', 3.4)); + + // Cleared compare buffer. + std::array clear; + clear.fill(0); + + // Destruct; + other.~Data(); + + // Storage should be wiped. + CHECK(buffer == clear); + } }; } diff --git a/test/test_message_bus.cpp b/test/test_message_bus.cpp index 42ad6118..2bf23e94 100644 --- a/test/test_message_bus.cpp +++ b/test/test_message_bus.cpp @@ -29,11 +29,11 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "message_router.h" -#include "message_bus.h" -#include "queue.h" -#include "largest.h" -#include "packet.h" +#include "etl/message_router.h" +#include "etl/message_bus.h" +#include "etl/queue.h" +#include "etl/largest.h" +#include "etl/packet.h" //*************************************************************************** // The set of messages. diff --git a/test/test_message_router.cpp b/test/test_message_router.cpp index 45598673..60f19273 100644 --- a/test/test_message_router.cpp +++ b/test/test_message_router.cpp @@ -29,10 +29,10 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "message_router.h" -#include "queue.h" -#include "largest.h" -#include "packet.h" +#include "etl/message_router.h" +#include "etl/queue.h" +#include "etl/largest.h" +#include "etl/packet.h" //*************************************************************************** // The set of messages. diff --git a/test/test_message_timer.cpp b/test/test_message_timer.cpp index 392cd31a..c457e759 100644 --- a/test/test_message_timer.cpp +++ b/test/test_message_timer.cpp @@ -29,9 +29,9 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "message_router.h" -#include "message_bus.h" -#include "message_timer.h" +#include "etl/message_router.h" +#include "etl/message_bus.h" +#include "etl/message_timer.h" #include #include diff --git a/test/test_multimap.cpp b/test/test_multimap.cpp index 9954afbc..018ff277 100644 --- a/test/test_multimap.cpp +++ b/test/test_multimap.cpp @@ -35,7 +35,7 @@ SOFTWARE. #include #include -#include "multimap.h" +#include "etl/multimap.h" static const size_t MAX_SIZE = 10; @@ -181,6 +181,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), MAX_SIZE); CHECK_EQUAL(data.max_size(), MAX_SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_multiset.cpp b/test/test_multiset.cpp index 03813ba0..14982819 100644 --- a/test/test_multiset.cpp +++ b/test/test_multiset.cpp @@ -35,7 +35,7 @@ SOFTWARE. #include #include -#include "multiset.h" +#include "etl/multiset.h" static const size_t MAX_SIZE = 10; @@ -173,6 +173,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), MAX_SIZE); CHECK_EQUAL(data.max_size(), MAX_SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_murmur3.cpp b/test/test_murmur3.cpp index d1185459..a4a61a5c 100644 --- a/test/test_murmur3.cpp +++ b/test/test_murmur3.cpp @@ -35,7 +35,7 @@ SOFTWARE. #include #include -#include "murmur3.h" +#include "etl/murmur3.h" namespace { diff --git a/test/test_no_stl_algorithm.cpp b/test/test_no_stl_algorithm.cpp index f29b4f9d..23ae4ef9 100644 --- a/test/test_no_stl_algorithm.cpp +++ b/test/test_no_stl_algorithm.cpp @@ -31,7 +31,7 @@ SOFTWARE. #undef min #undef max -#include "../include/etl/stl/alternate/algorithm.h" +#include "etl/stl/alternate/algorithm.h" #include #include diff --git a/test/test_no_stl_functional.cpp b/test/test_no_stl_functional.cpp index 8b92a715..90eb26e1 100644 --- a/test/test_no_stl_functional.cpp +++ b/test/test_no_stl_functional.cpp @@ -31,7 +31,7 @@ SOFTWARE. #undef min #undef max -#include "../include/etl/stl/alternate/functional.h" +#include "etl/stl/alternate/functional.h" namespace { diff --git a/test/test_no_stl_limits.cpp b/test/test_no_stl_limits.cpp index 4035020b..21df7ce4 100644 --- a/test/test_no_stl_limits.cpp +++ b/test/test_no_stl_limits.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "../include/etl/stl/alternate/limits.h" +#include "etl/stl/alternate/limits.h" #include diff --git a/test/test_no_stl_utility.cpp b/test/test_no_stl_utility.cpp index 441ef930..d4d10d67 100644 --- a/test/test_no_stl_utility.cpp +++ b/test/test_no_stl_utility.cpp @@ -31,7 +31,7 @@ SOFTWARE. #undef min #undef max -#include "../include/etl/stl/alternate/utility.h" +#include "etl/stl/alternate/utility.h" namespace { diff --git a/test/test_numeric.cpp b/test/test_numeric.cpp index 761e4f87..a594de23 100644 --- a/test/test_numeric.cpp +++ b/test/test_numeric.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "numeric.h" +#include "etl/numeric.h" #include #include diff --git a/test/test_observer.cpp b/test/test_observer.cpp index f6efc6b4..3f8d62f6 100644 --- a/test/test_observer.cpp +++ b/test/test_observer.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "observer.h" +#include "etl/observer.h" //***************************************************************************** // Notification1 @@ -424,7 +424,11 @@ namespace CHECK_THROW(observable.add_observer(observer5), etl::observer_list_full); - observable.remove_observer(observer3); + CHECK(observable.remove_observer(observer3)); + CHECK_EQUAL(size_t(3), observable.number_of_observers()); + + // Try again. + CHECK(!observable.remove_observer(observer3)); CHECK_EQUAL(size_t(3), observable.number_of_observers()); observable.clear_observers(); diff --git a/test/test_optional.cpp b/test/test_optional.cpp index a8b2d665..35884641 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -31,8 +31,8 @@ SOFTWARE. #include #include -#include "optional.h" -#include "vector.h" +#include "etl/optional.h" +#include "etl/vector.h" #include "data.h" typedef TestDataNDC Data; diff --git a/test/test_packet.cpp b/test/test_packet.cpp index 010754a7..5ccecf13 100644 --- a/test/test_packet.cpp +++ b/test/test_packet.cpp @@ -29,10 +29,10 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "packet.h" -#include "largest.h" -#include "queue.h" -#include "pool.h" +#include "etl/packet.h" +#include "etl/largest.h" +#include "etl/queue.h" +#include "etl/pool.h" namespace { diff --git a/test/test_parameter_type.cpp b/test/test_parameter_type.cpp index add018ba..f4c445ae 100644 --- a/test/test_parameter_type.cpp +++ b/test/test_parameter_type.cpp @@ -31,7 +31,7 @@ SOFTWARE. #include #include -#include "parameter_type.h" +#include "etl/parameter_type.h" namespace { diff --git a/test/test_pearson.cpp b/test/test_pearson.cpp index 5ab1df1b..c4416764 100644 --- a/test/test_pearson.cpp +++ b/test/test_pearson.cpp @@ -34,7 +34,7 @@ SOFTWARE. #include #include -#include "pearson.h" +#include "etl/pearson.h" const size_t HASH_SIZE = 8; typedef etl::pearson::value_type hash_t; diff --git a/test/test_pool.cpp b/test/test_pool.cpp index 8f14c5f2..fbd98816 100644 --- a/test/test_pool.cpp +++ b/test/test_pool.cpp @@ -35,8 +35,8 @@ SOFTWARE. #include #include -#include "pool.h" -#include "largest.h" +#include "etl/pool.h" +#include "etl/largest.h" #if defined(ETL_COMPILER_GCC) #pragma GCC diagnostic push diff --git a/test/test_priority_queue.cpp b/test/test_priority_queue.cpp index c8fd99e6..84aa1ee8 100644 --- a/test/test_priority_queue.cpp +++ b/test/test_priority_queue.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "priority_queue.h" +#include "etl/priority_queue.h" namespace { diff --git a/test/test_queue.cpp b/test/test_queue.cpp index 09333a5c..0369f46b 100644 --- a/test/test_queue.cpp +++ b/test/test_queue.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "queue.h" +#include "etl/queue.h" namespace { diff --git a/test/test_queue_memory_model_small.cpp b/test/test_queue_memory_model_small.cpp new file mode 100644 index 00000000..e60e9181 --- /dev/null +++ b/test/test_queue_memory_model_small.cpp @@ -0,0 +1,589 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2018 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "UnitTest++.h" + +#include + +#include "etl/queue.h" + +namespace +{ + struct Item + { + Item(char c_, int i_, double d_) + : c(c_), + i(i_), + d(d_) + { + } + + char c; + int i; + double d; + }; + + bool operator == (const Item& lhs, const Item& rhs) + { + return (lhs.c == rhs.c) && (lhs.i == rhs.i) && (lhs.d == rhs.d); + } + + struct ItemNTD + { + ItemNTD() + { + p = new char; + } + + ItemNTD(const ItemNTD&) + : p(new char) + { + } + + ~ItemNTD() + { + delete p; + } + + char* p; + }; + + typedef etl::queue QueueInt; + typedef etl::iqueue IQueueInt; + + typedef etl::queue QueueItemNTD; + typedef etl::iqueue IQueueItemNTD; + + typedef etl::queue QueueInt255; + + SUITE(test_queue) + { + //************************************************************************* + TEST(test_copy_constructor) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + QueueInt queue2(queue); + + CHECK(queue.size() == queue2.size()); + + while (!queue.empty()) + { + CHECK_EQUAL(queue.front(), queue2.front()); + queue.pop(); + queue2.pop(); + } + } + + //************************************************************************* + TEST(test_delete_via_iqueue) + { + QueueInt* pqueue = new QueueInt; + + IQueueInt* piqueue = pqueue; + + piqueue->push(1); + piqueue->push(2); + piqueue->push(3); + piqueue->push(4); + + delete piqueue; + } + + //************************************************************************* + TEST(test_size) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + + CHECK_EQUAL(3U, queue.size()); + } + + //************************************************************************* + TEST(test_clear) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + + // Do it again to check that clear() didn't screw up the internals. + queue.push(1); + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + } + + //************************************************************************* + TEST(test_clear_non_pod) + { + QueueItemNTD queue; + + queue.push(ItemNTD()); + queue.push(ItemNTD()); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + + // Do it again to check that clear() didn't screw up the internals. + queue.push(ItemNTD()); + queue.push(ItemNTD()); + CHECK_EQUAL(2U, queue.size()); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + } + + //************************************************************************* + TEST(test_empty) + { + QueueInt queue; + + CHECK(queue.empty()); + + queue.push(1); + + CHECK(!queue.empty()); + } + + //************************************************************************* + TEST(test_full) + { + QueueInt queue; + + CHECK(!queue.full()); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + CHECK(queue.full()); + } + + //************************************************************************* + TEST(test_front) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + + CHECK_EQUAL(1, queue.front()); + + queue.pop(); + CHECK_EQUAL(2, queue.front()); + + queue.pop(); + CHECK_EQUAL(3, queue.front()); + } + + //************************************************************************* + TEST(test_front_const) + { + QueueInt queue; + const QueueInt& constQueue = queue; + + queue.push(1); + queue.push(2); + queue.push(3); + + CHECK_EQUAL(1, constQueue.front()); + + queue.pop(); + CHECK_EQUAL(2, constQueue.front()); + + queue.pop(); + CHECK_EQUAL(3, constQueue.front()); + } + + //************************************************************************* + TEST(test_back) + { + QueueInt queue; + + queue.push(1); + CHECK_EQUAL(1, queue.back()); + + queue.push(2); + CHECK_EQUAL(2, queue.back()); + + queue.push(3); + CHECK_EQUAL(3, queue.back()); + } + + //************************************************************************* + TEST(test_back_const) + { + QueueInt queue; + const QueueInt& constQueue = queue; + + queue.push(1); + CHECK_EQUAL(1, constQueue.back()); + + queue.push(2); + CHECK_EQUAL(2, constQueue.back()); + + queue.push(3); + CHECK_EQUAL(3, constQueue.back()); + } + + //************************************************************************* + TEST(test_push) + { + QueueInt queue; + + queue.push(1); + CHECK_EQUAL(1U, queue.size()); + + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + + CHECK_EQUAL(1, queue.front()); + + queue.pop(); + CHECK_EQUAL(2, queue.front()); + } + + //************************************************************************* + TEST(test_push_255) + { + QueueInt255 queue; + + for (int i = 0; i < 255; ++i) + { + queue.push(i); + } + + CHECK_EQUAL(255U, queue.size()); + } + + //************************************************************************* + TEST(test_push_void) + { + QueueInt queue; + + queue.push() = 1; + CHECK_EQUAL(1U, queue.size()); + + queue.push() = 2; + CHECK_EQUAL(2U, queue.size()); + + CHECK_EQUAL(1, queue.front()); + + queue.pop(); + CHECK_EQUAL(2, queue.front()); + } + + //************************************************************************* + TEST(test_push_excess) + { + QueueInt queue; + + for (size_t i = 0; i < queue.max_size(); ++i) + { + queue.push(1); + } + + CHECK_THROW(queue.push(1), etl::queue_full); + } + + //************************************************************************* + TEST(test_multiple_push) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + + bool pass = true; + + if (queue.front() != 1) + { + pass = false; + } + + queue.pop(); + + if (queue.front() != 2) + { + pass = false; + } + + queue.pop(); + + if (queue.front() != 3) + { + pass = false; + } + + CHECK(pass); + } + + //************************************************************************* + TEST(test_multiple_emplace) + { + etl::queue queue; + + queue.emplace('a', 1, 1.2); + queue.emplace('b', 2, 3.4); + queue.emplace('c', 3, 5.6); + queue.emplace('d', 4, 7.8); + + CHECK(queue.front() == Item('a', 1, 1.2)); + queue.pop(); + CHECK(queue.front() == Item('b', 2, 3.4)); + queue.pop(); + CHECK(queue.front() == Item('c', 3, 5.6)); + queue.pop(); + CHECK(queue.front() == Item('d', 4, 7.8)); + queue.pop(); + } + + //************************************************************************* + TEST(test_multiple_push_void) + { + QueueInt queue; + + queue.push() = 1; + queue.push() = 2; + queue.push() = 3; + + bool pass = true; + + if (queue.front() != 1) + { + pass = false; + } + + queue.pop(); + + if (queue.front() != 2) + { + pass = false; + } + + queue.pop(); + + if (queue.front() != 3) + { + pass = false; + } + + CHECK(pass); + } + + //************************************************************************* + TEST(test_pop) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.pop(); + CHECK_EQUAL(1U, queue.size()); + } + + //************************************************************************* + TEST(test_pop_into) + { + QueueInt queue; + + int i; + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + queue.pop_into(i); + CHECK_EQUAL(1, i); + CHECK_EQUAL(3U, queue.size()); + + queue.pop_into(i); + CHECK_EQUAL(2, i); + CHECK_EQUAL(2U, queue.size()); + + queue.pop_into(i); + CHECK_EQUAL(3, i); + CHECK_EQUAL(1U, queue.size()); + + queue.pop_into(i); + CHECK_EQUAL(4, i); + CHECK_EQUAL(0U, queue.size()); + } + + //************************************************************************* + TEST(test_pop_into_queue) + { + QueueInt queue1; + QueueInt queue2; + + queue1.push(1); + queue1.push(2); + queue1.push(3); + queue1.push(4); + + queue1.pop_into(queue2); + CHECK_EQUAL(1U, queue2.size()); + CHECK_EQUAL(1, queue2.front()); + CHECK_EQUAL(1, queue2.back()); + + queue1.pop_into(queue2); + CHECK_EQUAL(2U, queue2.size()); + CHECK_EQUAL(1, queue2.front()); + CHECK_EQUAL(2, queue2.back()); + + queue1.pop_into(queue2); + CHECK_EQUAL(3U, queue2.size()); + CHECK_EQUAL(1, queue2.front()); + CHECK_EQUAL(3, queue2.back()); + + queue1.pop_into(queue2); + CHECK_EQUAL(4U, queue2.size()); + CHECK_EQUAL(1, queue2.front()); + CHECK_EQUAL(4, queue2.back()); + + int i; + + queue2.pop_into(i); + CHECK_EQUAL(1, i); + + queue2.pop_into(i); + CHECK_EQUAL(2, i); + + queue2.pop_into(i); + CHECK_EQUAL(3, i); + + queue2.pop_into(i); + CHECK_EQUAL(4, i); + } + + //************************************************************************* + TEST(test_pop_exception) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.pop(); + queue.pop(); + + CHECK_THROW(queue.pop(), etl::queue_empty); + } + + //************************************************************************* + TEST(test_assignment) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + QueueInt queue2; + + queue2 = queue; + + CHECK(queue.size() == queue2.size()); + + while (!queue.empty()) + { + CHECK_EQUAL(queue.front(), queue2.front()); + queue.pop(); + queue2.pop(); + } + } + + //************************************************************************* + TEST(test_assignment_interface) + { + QueueInt queue1; + + queue1.push(1); + queue1.push(2); + queue1.push(3); + queue1.push(4); + + QueueInt queue2; + + IQueueInt& iqueue1 = queue1; + IQueueInt& iqueue2 = queue2; + + iqueue2 = iqueue1; + + CHECK(queue1.size() == queue2.size()); + + while (!queue1.empty()) + { + CHECK_EQUAL(queue1.front(), queue2.front()); + queue1.pop(); + queue2.pop(); + } + } + + //************************************************************************* + TEST(test_self_assignment) + { + QueueInt queue; + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + queue = queue; + + CHECK(queue.max_size() == queue.size()); + + CHECK_EQUAL(1, queue.front()); + queue.pop(); + + CHECK_EQUAL(2, queue.front()); + queue.pop(); + + CHECK_EQUAL(3, queue.front()); + queue.pop(); + + CHECK_EQUAL(4, queue.front()); + queue.pop(); + } + }; +} diff --git a/test/test_queue_mpmc_mutex.cpp b/test/test_queue_mpmc_mutex.cpp index 9b8b7bee..75c1be5c 100644 --- a/test/test_queue_mpmc_mutex.cpp +++ b/test/test_queue_mpmc_mutex.cpp @@ -35,7 +35,7 @@ SOFTWARE. #include #include -#include "queue_mpmc_mutex.h" +#include "etl/queue_mpmc_mutex.h" #if defined(ETL_COMPILER_MICROSOFT) #include @@ -69,17 +69,17 @@ namespace int d; }; - bool operator ==(const Data& lhs, const Data& rhs) - { - return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d); - } +// bool operator ==(const Data& lhs, const Data& rhs) +// { +// return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d); +// } - std::ostream& operator <<(std::ostream& os, const Data& data) - { - os << data.a << " " << data.b << " " << data.c << " " << data.d; - - return os; - } +// std::ostream& operator <<(std::ostream& os, const Data& data) +// { +// os << data.a << " " << data.b << " " << data.c << " " << data.d; +// +// return os; +// } SUITE(test_queue_mpmc_mutex) { diff --git a/test/test_queue_mpmc_mutex_small.cpp b/test/test_queue_mpmc_mutex_small.cpp new file mode 100644 index 00000000..0c57c332 --- /dev/null +++ b/test/test_queue_mpmc_mutex_small.cpp @@ -0,0 +1,460 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2018 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "UnitTest++.h" + +#include +#include +#include +#include +#include +#include + +#include "etl/queue_mpmc_mutex.h" + +#if defined(ETL_COMPILER_MICROSOFT) + #include +#endif + +#define REALTIME_TEST 1 + +namespace +{ + struct Data + { + Data(int a_, int b_ = 2, int c_ = 3, int d_ = 4) + : a(a_), + b(b_), + c(c_), + d(d_) + { + } + + Data() + : a(0), + b(0), + c(0), + d(0) + { + } + + int a; + int b; + int c; + int d; + }; + + typedef etl::queue_mpmc_mutex QueueInt; + typedef etl::iqueue_mpmc_mutex IQueueInt; + + typedef etl::queue_mpmc_mutex QueueInt255; + +// bool operator ==(const Data& lhs, const Data& rhs) +// { +// return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d); +// } + +// std::ostream& operator <<(std::ostream& os, const Data& data) +// { +// os << data.a << " " << data.b << " " << data.c << " " << data.d; +// +// return os; +// } + + SUITE(test_queue_mpmc_mutex) + { + //************************************************************************* + TEST(test_constructor) + { + QueueInt queue; + + CHECK_EQUAL(4U, queue.max_size()); + CHECK_EQUAL(4U, queue.capacity()); + } + + //************************************************************************* + TEST(test_size_push_pop) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + CHECK_EQUAL(4U, queue.available()); + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + CHECK_EQUAL(1U, queue.size()); + CHECK_EQUAL(3U, queue.available()); + + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + CHECK_EQUAL(2U, queue.available()); + + queue.push(3); + CHECK_EQUAL(3U, queue.size()); + CHECK_EQUAL(1U, queue.available()); + + queue.push(4); + CHECK_EQUAL(4U, queue.size()); + CHECK_EQUAL(0U, queue.available()); + + CHECK(!queue.push(5)); + CHECK(!queue.push(5)); + + int i; + + CHECK(queue.pop(i)); + CHECK_EQUAL(1, i); + CHECK_EQUAL(3U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(2, i); + CHECK_EQUAL(2U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(3, i); + CHECK_EQUAL(1U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(4, i); + CHECK_EQUAL(0U, queue.size()); + + CHECK(!queue.pop(i)); + CHECK(!queue.pop(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_iqueue) + { + QueueInt queue; + + IQueueInt& iqueue = queue; + + CHECK_EQUAL(0U, iqueue.size()); + + iqueue.push(1); + CHECK_EQUAL(1U, iqueue.size()); + + iqueue.push(2); + CHECK_EQUAL(2U, iqueue.size()); + + iqueue.push(3); + CHECK_EQUAL(3U, iqueue.size()); + + iqueue.push(4); + CHECK_EQUAL(4U, iqueue.size()); + + CHECK(!iqueue.push(5)); + CHECK(!iqueue.push(5)); + + int i; + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(1, i); + CHECK_EQUAL(3U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(2, i); + CHECK_EQUAL(2U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(3, i); + CHECK_EQUAL(1U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(4, i); + CHECK_EQUAL(0U, iqueue.size()); + + CHECK(!iqueue.pop(i)); + CHECK(!iqueue.pop(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_void) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + CHECK_EQUAL(1U, queue.size()); + + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + + queue.push(3); + CHECK_EQUAL(3U, queue.size()); + + queue.push(4); + CHECK_EQUAL(4U, queue.size()); + + CHECK(!queue.push(5)); + CHECK(!queue.push(5)); + + CHECK(queue.pop()); + CHECK_EQUAL(3U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(2U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(1U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(0U, queue.size()); + + CHECK(!queue.pop()); + CHECK(!queue.pop()); + } + + //************************************************************************* + TEST(test_push_255) + { + QueueInt255 queue; + + for (int i = 0; i < 255; ++i) + { + queue.push(i); + } + + CHECK_EQUAL(255U, queue.size()); + } + + //************************************************************************* + TEST(test_clear) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + queue.push(2); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + + // Do it again to check that clear() didn't screw up the internals. + queue.push(1); + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + } + + //************************************************************************* + TEST(test_empty) + { + QueueInt queue; + CHECK(queue.empty()); + + queue.push(1); + CHECK(!queue.empty()); + + queue.clear(); + CHECK(queue.empty()); + + queue.push(1); + CHECK(!queue.empty()); + } + + //************************************************************************* + TEST(test_full) + { + QueueInt queue; + CHECK(!queue.full()); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + CHECK(queue.full()); + + queue.clear(); + CHECK(!queue.full()); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + CHECK(queue.full()); + } + + //========================================================================= +#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT) + #if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported + #define SET_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL) + #define FIX_PROCESSOR_AFFINITY1 SetThreadAffinityMask(GetCurrentThread(), 1); + #define FIX_PROCESSOR_AFFINITY2 SetThreadAffinityMask(GetCurrentThread(), 2); + #define FIX_PROCESSOR_AFFINITY3 SetThreadAffinityMask(GetCurrentThread(), 4); + #define FIX_PROCESSOR_AFFINITY4 SetThreadAffinityMask(GetCurrentThread(), 8); + #else + #error No thread priority modifier defined + #endif + + etl::queue_mpmc_mutex queue; + + const size_t LENGTH = 100000; + + std::vector push1; + std::vector push2; + + std::vector pop1; + std::vector pop2; + + volatile std::atomic_bool start; + + void push_thread1() + { + FIX_PROCESSOR_AFFINITY1; + SET_THREAD_PRIORITY; + + size_t count = 0; + int value = 0; + + while (!start.load()); + + while (count < (LENGTH / 2)) + { + if (queue.push(value)) + { + push1.push_back(value); + ++count; + ++value; + } + } + } + + void push_thread2() + { + FIX_PROCESSOR_AFFINITY2; + SET_THREAD_PRIORITY; + + size_t count = 0; + int value = LENGTH / 2; + + while (!start.load()); + + while (count < (LENGTH / 2)) + { + if (queue.push(value)) + { + push2.push_back(value); + ++count; + ++value; + } + } + } + + void pop_thread1() + { + FIX_PROCESSOR_AFFINITY3; + SET_THREAD_PRIORITY; + + size_t count = 0; + + while (!start.load()); + + while (count < (LENGTH / 2)) + { + int i; + + if (queue.pop(i)) + { + pop1.push_back(i); + ++count; + } + } + } + + void pop_thread2() + { + FIX_PROCESSOR_AFFINITY4; + SET_THREAD_PRIORITY; + + size_t count = 0; + + while (!start.load()); + + while (count < (LENGTH / 2)) + { + int i; + + if (queue.pop(i)) + { + pop2.push_back(i); + ++count; + } + } + } + + TEST(queue_threads) + { + push1.reserve(LENGTH / 2); + push2.reserve(LENGTH / 2);; + + pop1.reserve(LENGTH / 2);; + pop2.reserve(LENGTH / 2);; + + start = false; + + std::thread t1(push_thread1); + std::thread t2(push_thread2); + std::thread t3(pop_thread1); + std::thread t4(pop_thread2); + + start.store(true); + + // Join the threads with the main thread + t1.join(); + t2.join(); + t3.join(); + t4.join(); + + // Combine input vectors. + std::vector push; + push.insert(push.end(), push1.begin(), push1.end()); + push.insert(push.end(), push2.begin(), push2.end()); + std::sort(push.begin(), push.end()); + + // Combine output vectors. + std::vector pop; + pop.insert(pop.end(), pop1.begin(), pop1.end()); + pop.insert(pop.end(), pop2.begin(), pop2.end()); + std::sort(pop.begin(), pop.end()); + + CHECK_EQUAL(LENGTH, push.size()); + CHECK_EQUAL(LENGTH, pop.size()); + + for (size_t i = 0; i < LENGTH; ++i) + { + CHECK_EQUAL(push[i], pop[i]); + CHECK_EQUAL(i, pop[i]); + } + } +#endif + }; +} diff --git a/test/test_queue_spsc_atomic.cpp b/test/test_queue_spsc_atomic.cpp index 4e5542a4..1d49cca4 100644 --- a/test/test_queue_spsc_atomic.cpp +++ b/test/test_queue_spsc_atomic.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "queue_spsc_atomic.h" +#include "etl/queue_spsc_atomic.h" #if defined(ETL_COMPILER_MICROSOFT) #include diff --git a/test/test_queue_spsc_atomic_small.cpp b/test/test_queue_spsc_atomic_small.cpp new file mode 100644 index 00000000..fd8a5274 --- /dev/null +++ b/test/test_queue_spsc_atomic_small.cpp @@ -0,0 +1,330 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2018 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "UnitTest++.h" + +#include +#include +#include + +#include "etl/queue_spsc_atomic.h" + +#if defined(ETL_COMPILER_MICROSOFT) + #include +#endif + +#define REALTIME_TEST 0 + +namespace +{ + typedef etl::queue_spsc_atomic QueueInt; + typedef etl::iqueue_spsc_atomic IQueueInt; + + typedef etl::queue_spsc_atomic QueueInt254; + + SUITE(test_queue_atomic) + { + //************************************************************************* + TEST(test_constructor) + { + QueueInt queue; + + CHECK_EQUAL(4U, queue.max_size()); + CHECK_EQUAL(4U, queue.capacity()); + } + + //************************************************************************* + TEST(test_size_push_pop) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + CHECK_EQUAL(4U, queue.available()); + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + CHECK_EQUAL(1U, queue.size()); + CHECK_EQUAL(3U, queue.available()); + + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + CHECK_EQUAL(2U, queue.available()); + + queue.push(3); + CHECK_EQUAL(3U, queue.size()); + CHECK_EQUAL(1U, queue.available()); + + queue.push(4); + CHECK_EQUAL(4U, queue.size()); + CHECK_EQUAL(0U, queue.available()); + + CHECK(!queue.push(5)); + CHECK(!queue.push(5)); + + int i; + + CHECK(queue.pop(i)); + CHECK_EQUAL(1, i); + CHECK_EQUAL(3U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(2, i); + CHECK_EQUAL(2U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(3, i); + CHECK_EQUAL(1U, queue.size()); + + CHECK(queue.pop(i)); + CHECK_EQUAL(4, i); + CHECK_EQUAL(0U, queue.size()); + + CHECK(!queue.pop(i)); + CHECK(!queue.pop(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_iqueue) + { + QueueInt queue; + + IQueueInt& iqueue = queue; + + CHECK_EQUAL(0U, iqueue.size()); + + iqueue.push(1); + CHECK_EQUAL(1U, iqueue.size()); + + iqueue.push(2); + CHECK_EQUAL(2U, iqueue.size()); + + iqueue.push(3); + CHECK_EQUAL(3U, iqueue.size()); + + iqueue.push(4); + CHECK_EQUAL(4U, iqueue.size()); + + CHECK(!iqueue.push(5)); + CHECK(!iqueue.push(5)); + + int i; + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(1, i); + CHECK_EQUAL(3U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(2, i); + CHECK_EQUAL(2U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(3, i); + CHECK_EQUAL(1U, iqueue.size()); + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(4, i); + CHECK_EQUAL(0U, iqueue.size()); + + CHECK(!iqueue.pop(i)); + CHECK(!iqueue.pop(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_void) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + CHECK_EQUAL(1U, queue.size()); + + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + + queue.push(3); + CHECK_EQUAL(3U, queue.size()); + + queue.push(4); + CHECK_EQUAL(4U, queue.size()); + + CHECK(!queue.push(5)); + CHECK(!queue.push(5)); + + CHECK(queue.pop()); + CHECK_EQUAL(3U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(2U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(1U, queue.size()); + + CHECK(queue.pop()); + CHECK_EQUAL(0U, queue.size()); + + CHECK(!queue.pop()); + CHECK(!queue.pop()); + } + + //************************************************************************* + TEST(test_push_254) + { + QueueInt254 queue; + + for (int i = 0; i < 254; ++i) + { + queue.push(i); + } + + CHECK_EQUAL(254U, queue.size()); + } + + //************************************************************************* + TEST(test_clear) + { + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + queue.push(2); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + + // Do it again to check that clear() didn't screw up the internals. + queue.push(1); + queue.push(2); + CHECK_EQUAL(2U, queue.size()); + queue.clear(); + CHECK_EQUAL(0U, queue.size()); + } + + //************************************************************************* + TEST(test_empty) + { + QueueInt queue; + CHECK(queue.empty()); + + queue.push(1); + CHECK(!queue.empty()); + + queue.clear(); + CHECK(queue.empty()); + + queue.push(1); + CHECK(!queue.empty()); + } + + //************************************************************************* + TEST(test_full) + { + QueueInt queue; + CHECK(!queue.full()); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + CHECK(queue.full()); + + queue.clear(); + CHECK(!queue.full()); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + CHECK(queue.full()); + } + + //========================================================================= +#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT) + #if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported + #define FIX_PROCESSOR_AFFINITY1 SetThreadAffinityMask(GetCurrentThread(), 1); + #define FIX_PROCESSOR_AFFINITY2 SetThreadAffinityMask(GetCurrentThread(), 2); + #else + #error No thread priority modifier defined + #endif + + size_t ticks = 0; + + etl::queue_spsc_atomic queue; + + const size_t LENGTH = 1000000; + + void timer_event() + { + FIX_PROCESSOR_AFFINITY1; + + const size_t TICK = 1; + size_t tick = TICK; + ticks = 1; + + while (ticks <= LENGTH) + { + if (queue.push(ticks)) + { + ++ticks; + } + } + } + + TEST(queue_threads) + { + FIX_PROCESSOR_AFFINITY2; + + std::vector tick_list; + tick_list.reserve(LENGTH); + + std::thread t1(timer_event); + + while (tick_list.size() < LENGTH) + { + int i; + + if (queue.pop(i)) + { + tick_list.push_back(i); + } + } + + // Join the thread with the main thread + t1.join(); + + CHECK_EQUAL(LENGTH, tick_list.size()); + + for (size_t i = 0; i < LENGTH; ++i) + { + CHECK_EQUAL(i + 1, tick_list[i]); + } + } +#endif + }; +} diff --git a/test/test_queue_spsc_isr.cpp b/test/test_queue_spsc_isr.cpp index 91667eb9..00623103 100644 --- a/test/test_queue_spsc_isr.cpp +++ b/test/test_queue_spsc_isr.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "queue_spsc_isr.h" +#include "etl/queue_spsc_isr.h" #include #include diff --git a/test/test_queue_spsc_isr_small.cpp b/test/test_queue_spsc_isr_small.cpp new file mode 100644 index 00000000..3895b3d0 --- /dev/null +++ b/test/test_queue_spsc_isr_small.cpp @@ -0,0 +1,587 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2018 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "UnitTest++.h" + +#include "etl/queue_spsc_isr.h" + +#include +#include +#include + +#if defined(ETL_COMPILER_MICROSOFT) +#include +#endif + +#define REALTIME_TEST 0 + +namespace +{ + class Access + { + public: + + static void clear() + { + called_lock = false; + called_unlock = false; + } + + static void lock() + { + called_lock = true; + } + + static void unlock() + { + called_unlock = true; + } + + static bool called_lock; + static bool called_unlock; + }; + + bool Access::called_lock; + bool Access::called_unlock; + + typedef etl::queue_spsc_isr QueueInt; + typedef etl::iqueue_spsc_isr IQueueInt; + + typedef etl::queue_spsc_isr QueueInt255; + + SUITE(test_queue_isr) + { + //************************************************************************* + TEST(test_constructor) + { + Access::clear(); + + QueueInt queue; + + CHECK_EQUAL(4U, queue.max_size()); + CHECK_EQUAL(4U, queue.capacity()); + + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + } + + //************************************************************************* + TEST(test_size_push_pop) + { + Access::clear(); + + QueueInt queue; + + CHECK_EQUAL(0U, queue.size_from_isr()); + + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + Access::clear(); + + CHECK_EQUAL(4U, queue.available_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + Access::clear(); + + CHECK_EQUAL(0U, queue.size()); + + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + Access::clear(); + + CHECK_EQUAL(4U, queue.available()); + + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + Access::clear(); + + queue.push_from_isr(1); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, queue.size_from_isr()); + CHECK_EQUAL(3U, queue.available_from_isr()); + + Access::clear(); + + queue.push(2); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(2U, queue.size_from_isr()); + CHECK_EQUAL(2U, queue.available_from_isr()); + + Access::clear(); + + queue.push(3); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, queue.size_from_isr()); + CHECK_EQUAL(1U, queue.available_from_isr()); + + Access::clear(); + + queue.push(4); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(4U, queue.size_from_isr()); + CHECK_EQUAL(0U, queue.available_from_isr()); + + Access::clear(); + + CHECK(!queue.push(5)); + CHECK(!queue.push_from_isr(5)); + + Access::clear(); + + int i; + + CHECK(queue.pop(i)); + CHECK_EQUAL(1, i); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr(i)); + CHECK_EQUAL(2, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(2U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr(i)); + CHECK_EQUAL(3, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr(i)); + CHECK_EQUAL(4, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(0U, queue.size_from_isr()); + + Access::clear(); + + CHECK(!queue.pop(i)); + CHECK(!queue.pop_from_isr(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_iqueue) + { + Access::clear(); + + QueueInt queue; + + IQueueInt& iqueue = queue; + + CHECK_EQUAL(0U, iqueue.size_from_isr()); + + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + Access::clear(); + + CHECK_EQUAL(0U, iqueue.size()); + + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + Access::clear(); + + iqueue.push_from_isr(1); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, iqueue.size_from_isr()); + + Access::clear(); + + iqueue.push(2); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(2U, iqueue.size_from_isr()); + + Access::clear(); + + iqueue.push(3); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, iqueue.size_from_isr()); + + Access::clear(); + + iqueue.push(4); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(4U, iqueue.size_from_isr()); + + Access::clear(); + + CHECK(!iqueue.push(5)); + CHECK(!iqueue.push_from_isr(5)); + + Access::clear(); + + int i; + + CHECK(iqueue.pop(i)); + CHECK_EQUAL(1, i); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, iqueue.size_from_isr()); + + Access::clear(); + + CHECK(iqueue.pop_from_isr(i)); + CHECK_EQUAL(2, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(2U, iqueue.size_from_isr()); + + Access::clear(); + + CHECK(iqueue.pop_from_isr(i)); + CHECK_EQUAL(3, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, iqueue.size_from_isr()); + + Access::clear(); + + CHECK(iqueue.pop_from_isr(i)); + CHECK_EQUAL(4, i); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(0U, iqueue.size_from_isr()); + + Access::clear(); + + CHECK(!iqueue.pop(i)); + CHECK(!iqueue.pop_from_isr(i)); + } + + //************************************************************************* + TEST(test_size_push_pop_void) + { + Access::clear(); + + QueueInt queue; + + CHECK_EQUAL(0U, queue.size_from_isr()); + + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + Access::clear(); + + CHECK_EQUAL(0U, queue.size()); + + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + Access::clear(); + + queue.push_from_isr(1); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, queue.size_from_isr()); + + Access::clear(); + + queue.push(2); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(2U, queue.size_from_isr()); + + Access::clear(); + + queue.push(3); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, queue.size_from_isr()); + + Access::clear(); + + queue.push(4); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(4U, queue.size_from_isr()); + + Access::clear(); + + CHECK(!queue.push(5)); + CHECK(!queue.push_from_isr(5)); + + Access::clear(); + + CHECK(queue.pop()); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(3U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(2U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(1U, queue.size_from_isr()); + + Access::clear(); + + CHECK(queue.pop_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + CHECK_EQUAL(0U, queue.size_from_isr()); + + Access::clear(); + + CHECK(!queue.pop()); + CHECK(!queue.pop_from_isr()); + } + + //************************************************************************* + TEST(test_push_255) + { + QueueInt255 queue; + + for (int i = 0; i < 255; ++i) + { + queue.push(i); + } + + CHECK_EQUAL(255U, queue.size()); + } + + //************************************************************************* + TEST(test_clear) + { + Access::clear(); + + QueueInt queue; + + CHECK_EQUAL(0U, queue.size()); + + queue.push(1); + queue.push(2); + queue.clear(); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + CHECK_EQUAL(0U, queue.size()); + + Access::clear(); + + // Do it again to check that clear() didn't screw up the internals. + queue.push_from_isr(1); + queue.push_from_isr(2); + CHECK_EQUAL(2U, queue.size_from_isr()); + queue.clear_from_isr(); + CHECK_EQUAL(0U, queue.size_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + } + + //************************************************************************* + TEST(test_empty) + { + Access::clear(); + + QueueInt queue; + + CHECK(queue.empty()); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + queue.push(1); + + Access::clear(); + + CHECK(!queue.empty()); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + queue.clear(); + Access::clear(); + + CHECK(queue.empty_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + queue.push(1); + + Access::clear(); + + CHECK(!queue.empty_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + } + + //************************************************************************* + TEST(test_full) + { + Access::clear(); + + QueueInt queue; + + CHECK(!queue.full()); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + Access::clear(); + + CHECK(queue.full()); + CHECK(Access::called_lock); + CHECK(Access::called_unlock); + + queue.clear(); + Access::clear(); + + CHECK(!queue.full_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + + Access::clear(); + + CHECK(queue.full_from_isr()); + CHECK(!Access::called_lock); + CHECK(!Access::called_unlock); + } + + //========================================================================= +#if REALTIME_TEST && defined(ETL_COMPILER_MICROSOFT) + #if defined(ETL_TARGET_OS_WINDOWS) // Only Windows priority is currently supported + #define RAISE_THREAD_PRIORITY SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) + #define FIX_PROCESSOR_AFFINITY SetThreadAffinityMask(GetCurrentThread(), 1); + #else + #error No thread priority modifier defined + #endif + + size_t ticks = 0; + + struct ThreadLock + { + static void lock() + { + mutex.lock(); + } + + static void unlock() + { + mutex.unlock(); + } + + static std::mutex mutex; + }; + + std::mutex ThreadLock::mutex; + + etl::queue_spsc_isr queue; + + const size_t LENGTH = 1000; + + void timer_thread() + { + RAISE_THREAD_PRIORITY; + FIX_PROCESSOR_AFFINITY; + + const size_t TICK = 1; + size_t tick = TICK; + ticks = 1; + + while (ticks <= LENGTH) + { + if (ThreadLock::mutex.try_lock()) + { + if (queue.push_from_isr(ticks)) + { + ++ticks; + } + + ThreadLock::mutex.unlock(); + } + + Sleep(0); + } + } + + TEST(queue_threads) + { + FIX_PROCESSOR_AFFINITY; + + std::vector tick_list; + tick_list.reserve(LENGTH); + + std::thread t1(timer_thread); + + while (tick_list.size() < LENGTH) + { + int i; + + if (queue.pop(i)) + { + tick_list.push_back(i); + } + } + + // Join the thread with the main thread + t1.join(); + + CHECK_EQUAL(LENGTH, tick_list.size()); + + for (size_t i = 0; i < LENGTH; ++i) + { + CHECK_EQUAL(i + 1, tick_list[i]); + } + } +#endif + }; +} diff --git a/test/test_random.cpp b/test/test_random.cpp index 738e2a90..4c77912b 100644 --- a/test/test_random.cpp +++ b/test/test_random.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "random.h" +#include "etl/random.h" #include #include diff --git a/test/test_reference_flat_map.cpp b/test/test_reference_flat_map.cpp index bfcd7cda..4e0988a7 100644 --- a/test/test_reference_flat_map.cpp +++ b/test/test_reference_flat_map.cpp @@ -40,7 +40,7 @@ SOFTWARE. #include "data.h" -#include "reference_flat_map.h" +#include "etl/reference_flat_map.h" namespace { diff --git a/test/test_reference_flat_multimap.cpp b/test/test_reference_flat_multimap.cpp index c9bc8e55..58d7fc71 100644 --- a/test/test_reference_flat_multimap.cpp +++ b/test/test_reference_flat_multimap.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "reference_flat_multimap.h" +#include "etl/reference_flat_multimap.h" namespace { diff --git a/test/test_reference_flat_multiset.cpp b/test/test_reference_flat_multiset.cpp index 72c1511b..056e6a80 100644 --- a/test/test_reference_flat_multiset.cpp +++ b/test/test_reference_flat_multiset.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "reference_flat_multiset.h" +#include "etl/reference_flat_multiset.h" namespace { diff --git a/test/test_reference_flat_set.cpp b/test/test_reference_flat_set.cpp index ff943446..a38b3b4e 100644 --- a/test/test_reference_flat_set.cpp +++ b/test/test_reference_flat_set.cpp @@ -38,7 +38,7 @@ SOFTWARE. #include "data.h" -#include "reference_flat_set.h" +#include "etl/reference_flat_set.h" namespace { diff --git a/test/test_set.cpp b/test/test_set.cpp index 773aeea5..57bfc7ea 100644 --- a/test/test_set.cpp +++ b/test/test_set.cpp @@ -36,7 +36,7 @@ SOFTWARE. #include #include -#include "set.h" +#include "etl/set.h" static const size_t MAX_SIZE = 10; @@ -184,6 +184,7 @@ namespace CHECK(data.empty()); CHECK_EQUAL(data.capacity(), MAX_SIZE); CHECK_EQUAL(data.max_size(), MAX_SIZE); + CHECK(data.begin() == data.end()); } //************************************************************************* diff --git a/test/test_smallest.cpp b/test/test_smallest.cpp index 3a9a4aad..aa27cd45 100644 --- a/test/test_smallest.cpp +++ b/test/test_smallest.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "smallest.h" +#include "etl/smallest.h" #include diff --git a/test/test_stack.cpp b/test/test_stack.cpp index 74a1a164..ea7f1685 100644 --- a/test/test_stack.cpp +++ b/test/test_stack.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include "data.h" -#include "stack.h" +#include "etl/stack.h" namespace { diff --git a/test/test_string_char.cpp b/test/test_string_char.cpp index 3d9aab80..ff90ca11 100644 --- a/test/test_string_char.cpp +++ b/test/test_string_char.cpp @@ -32,8 +32,8 @@ SOFTWARE. #include #include -#include "cstring.h" -#include "fnv_1.h" +#include "etl/cstring.h" +#include "etl/fnv_1.h" #undef STR #define STR(x) x @@ -48,6 +48,7 @@ namespace typedef etl::istring IText; typedef std::string Compare_Text; typedef Text::value_type value_t; + typedef etl::string<52> TextL; Compare_Text initial_text; Compare_Text less_text; @@ -93,6 +94,7 @@ namespace CHECK(text.empty()); CHECK_EQUAL(text.capacity(), SIZE); CHECK_EQUAL(text.max_size(), SIZE); + CHECK(text.begin() == text.end()); } //************************************************************************* @@ -867,6 +869,24 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = TextL::MAX_SIZE / 2; + + for (size_t offset = 10; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10); + compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) { diff --git a/test/test_string_u16.cpp b/test/test_string_u16.cpp index 62de9237..da37ee5d 100644 --- a/test/test_string_u16.cpp +++ b/test/test_string_u16.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "u16string.h" +#include "etl/u16string.h" #undef STR #define STR(x) u##x @@ -47,6 +47,7 @@ namespace typedef etl::iu16string IText; typedef std::u16string Compare_Text; typedef Text::value_type value_t; + typedef etl::u16string<52> TextL; Compare_Text initial_text; Compare_Text less_text; @@ -92,6 +93,7 @@ namespace CHECK(text.empty()); CHECK_EQUAL(text.capacity(), SIZE); CHECK_EQUAL(text.max_size(), SIZE); + CHECK(text.begin() == text.end()); } //************************************************************************* @@ -866,6 +868,24 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = TextL::MAX_SIZE / 2; + + for (size_t offset = 10; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10); + compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) { diff --git a/test/test_string_u32.cpp b/test/test_string_u32.cpp index 4cfd43f9..0df0425a 100644 --- a/test/test_string_u32.cpp +++ b/test/test_string_u32.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "u32string.h" +#include "etl/u32string.h" #undef STR #define STR(x) U##x @@ -47,6 +47,7 @@ namespace typedef etl::iu32string IText; typedef std::u32string Compare_Text; typedef Text::value_type value_t; + typedef etl::u32string<52> TextL; Compare_Text initial_text; Compare_Text less_text; @@ -92,6 +93,7 @@ namespace CHECK(text.empty()); CHECK_EQUAL(text.capacity(), SIZE); CHECK_EQUAL(text.max_size(), SIZE); + CHECK(text.begin() == text.end()); } //************************************************************************* @@ -583,8 +585,6 @@ namespace CHECK(is_equal); } - - //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back) { @@ -866,6 +866,24 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = TextL::MAX_SIZE / 2; + + for (size_t offset = 10; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10); + compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) { diff --git a/test/test_string_view.cpp b/test/test_string_view.cpp index 7d2f796c..353f8031 100644 --- a/test/test_string_view.cpp +++ b/test/test_string_view.cpp @@ -28,12 +28,12 @@ SOFTWARE. #include "UnitTest++.h" -#include "string_view.h" -#include "cstring.h" -#include "wstring.h" -#include "u16string.h" -#include "u32string.h" -#include "hash.h" +#include "etl/string_view.h" +#include "etl/cstring.h" +#include "etl/wstring.h" +#include "etl/u16string.h" +#include "etl/u32string.h" +#include "etl/hash.h" #include #include diff --git a/test/test_string_wchar_t.cpp b/test/test_string_wchar_t.cpp index ff538896..f347c5d5 100644 --- a/test/test_string_wchar_t.cpp +++ b/test/test_string_wchar_t.cpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include -#include "wstring.h" +#include "etl/wstring.h" #undef STR #define STR(x) L##x @@ -47,6 +47,7 @@ namespace typedef etl::iwstring IText; typedef std::wstring Compare_Text; typedef Text::value_type value_t; + typedef etl::wstring<52> TextL; Compare_Text initial_text; Compare_Text less_text; @@ -92,6 +93,7 @@ namespace CHECK(text.empty()); CHECK_EQUAL(text.capacity(), SIZE); CHECK_EQUAL(text.max_size(), SIZE); + CHECK(text.begin() == text.end()); } //************************************************************************* @@ -866,6 +868,24 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_insert_position_range_self) + { + size_t length = TextL::MAX_SIZE / 2; + + for (size_t offset = 10; offset < length; ++offset) + { + Compare_Text compare_text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + TextL text = STR("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + + text.insert(text.begin() + offset, text.begin() + 5, text.begin() + 10); + compare_text.insert(compare_text.begin() + offset, compare_text.begin() + 5, compare_text.begin() + 10); + + bool is_equal = Equal(compare_text, text); + CHECK(is_equal); + } + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_size_t_position_string) { diff --git a/test/test_task_scheduler.cpp b/test/test_task_scheduler.cpp index 38f505c6..7772857d 100644 --- a/test/test_task_scheduler.cpp +++ b/test/test_task_scheduler.cpp @@ -32,9 +32,9 @@ SOFTWARE. #include #include -#include "task.h" -#include "scheduler.h" -#include "container.h" +#include "etl/task.h" +#include "etl/scheduler.h" +#include "etl/container.h" typedef std::vector WorkList_t; diff --git a/test/test_type_def.cpp b/test/test_type_def.cpp index deaa90a9..dbeb32dd 100644 --- a/test/test_type_def.cpp +++ b/test/test_type_def.cpp @@ -30,7 +30,7 @@ SOFTWARE. #include -#include "type_def.h" +#include "etl/type_def.h" namespace { diff --git a/test/test_type_lookup.cpp b/test/test_type_lookup.cpp index c944a9bd..1d6a2015 100644 --- a/test/test_type_lookup.cpp +++ b/test/test_type_lookup.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "type_lookup.h" +#include "etl/type_lookup.h" #include diff --git a/test/test_type_select.cpp b/test/test_type_select.cpp index 7ea7ecff..dec01aea 100644 --- a/test/test_type_select.cpp +++ b/test/test_type_select.cpp @@ -29,8 +29,8 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "type_select.h" -#include "null_type.h" +#include "etl/type_select.h" +#include "etl/null_type.h" #include diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index cd57f45d..25304d95 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -38,7 +38,7 @@ namespace std } #endif -#include "type_traits.h" +#include "etl/type_traits.h" #include namespace diff --git a/test/test_unordered_map.cpp b/test/test_unordered_map.cpp index 470fbecd..c5f5c73c 100644 --- a/test/test_unordered_map.cpp +++ b/test/test_unordered_map.cpp @@ -39,7 +39,7 @@ SOFTWARE. #include "data.h" -#include "unordered_map.h" +#include "etl/unordered_map.h" namespace { diff --git a/test/test_unordered_multimap.cpp b/test/test_unordered_multimap.cpp index d04dc25f..65106b71 100644 --- a/test/test_unordered_multimap.cpp +++ b/test/test_unordered_multimap.cpp @@ -39,7 +39,7 @@ SOFTWARE. #include "data.h" -#include "unordered_multimap.h" +#include "etl/unordered_multimap.h" namespace { diff --git a/test/test_unordered_multiset.cpp b/test/test_unordered_multiset.cpp index 0fddfcee..71f069dd 100644 --- a/test/test_unordered_multiset.cpp +++ b/test/test_unordered_multiset.cpp @@ -39,8 +39,8 @@ SOFTWARE. #include "data.h" -#include "unordered_multiset.h" -#include "checksum.h" +#include "etl/unordered_multiset.h" +#include "etl/checksum.h" namespace { diff --git a/test/test_unordered_set.cpp b/test/test_unordered_set.cpp index e658451c..55f28f82 100644 --- a/test/test_unordered_set.cpp +++ b/test/test_unordered_set.cpp @@ -38,8 +38,8 @@ SOFTWARE. #include "data.h" -#include "unordered_set.h" -#include "checksum.h" +#include "etl/unordered_set.h" +#include "etl/checksum.h" namespace { diff --git a/test/test_user_type.cpp b/test/test_user_type.cpp index 0e3e5da7..c7eb5a6d 100644 --- a/test/test_user_type.cpp +++ b/test/test_user_type.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include -#include "user_type.h" +#include "etl/user_type.h" ETL_DECLARE_USER_TYPE(CompassDirection, int) ETL_USER_TYPE(North, 0) diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 08700fe0..ac29ed19 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "utility.h" +#include "etl/utility.h" namespace { diff --git a/test/test_variant.cpp b/test/test_variant.cpp index 07a96cdb..305fda0d 100644 --- a/test/test_variant.cpp +++ b/test/test_variant.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "variant.h" +#include "etl/variant.h" #include #include diff --git a/test/test_variant_pool.cpp b/test/test_variant_pool.cpp index 4578c8d3..65a5bc4b 100644 --- a/test/test_variant_pool.cpp +++ b/test/test_variant_pool.cpp @@ -29,7 +29,7 @@ SOFTWARE. #include "UnitTest++.h" #include "ExtraCheckMacros.h" -#include "variant_pool.h" +#include "etl/variant_pool.h" #include #include diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 9b753a15..b740f328 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "vector.h" +#include "etl/vector.h" namespace { diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index 2d1d89e3..bfd099b0 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -32,7 +32,7 @@ #include #include -#include "vector.h" +#include "etl/vector.h" #include "data.h" namespace diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index eeac0e8c..dc5a5a33 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "vector.h" +#include "etl/vector.h" namespace { @@ -1813,5 +1813,33 @@ namespace CHECK(!is_equal); } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_ivector_of_pointer_to_pointer) + { + int i1 = 1; + etl::vector consttest; + consttest.push_back(&i1); + const etl::ivector& ct = consttest; + + int* i2 = ct[0]; + + CHECK(i1 == *i2); + CHECK(&i1 == i2); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_const_ivector_of_pointer_to_const_pointer) + { + int i1 = 1; + etl::vector consttest; + consttest.push_back(&i1); + const etl::ivector& ct = consttest; + + const int* i2 = ct[0]; + + CHECK(i1 == *i2); + CHECK(&i1 == i2); + } }; } diff --git a/test/test_visitor.cpp b/test/test_visitor.cpp index 325a0622..befc438d 100644 --- a/test/test_visitor.cpp +++ b/test/test_visitor.cpp @@ -28,7 +28,7 @@ SOFTWARE. #include "UnitTest++.h" -#include "visitor.h" +#include "etl/visitor.h" //***************************************************************************** // Pre-declare the data types. diff --git a/test/test_xor_checksum.cpp b/test/test_xor_checksum.cpp index 1d451064..207d2699 100644 --- a/test/test_xor_checksum.cpp +++ b/test/test_xor_checksum.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "checksum.h" +#include "etl/checksum.h" namespace { diff --git a/test/test_xor_rotate_checksum.cpp b/test/test_xor_rotate_checksum.cpp index 43f50436..485f9972 100644 --- a/test/test_xor_rotate_checksum.cpp +++ b/test/test_xor_rotate_checksum.cpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include -#include "checksum.h" +#include "etl/checksum.h" namespace { diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index 8bcbeb96..98db3d12 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -39,7 +39,7 @@ Win32Proj unittest etl - 10.0.16299.0 + 10.0.17134.0 @@ -161,7 +161,7 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ../../../unittest-cpp/UnitTest++/;../../include/etl;../../include/etl/c;../../test + ../../../unittest-cpp/UnitTest++/;../../include;../../include/etl/c;../../test false @@ -203,7 +203,7 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ../../../unittest-cpp\UnitTest++;../../include/etl;../../include/etl/c;../../test + ../../../unittest-cpp\UnitTest++;../../include;../../include/etl/c;../../test false @@ -245,7 +245,7 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - ../../../unittest-cpp/UnitTest++/;../../include/etl;../../include/etl/c;../../test + ../../../unittest-cpp/UnitTest++/;../../include;../../include/etl/c;../../test @@ -370,6 +370,7 @@ + @@ -704,9 +705,13 @@ + + + + true true diff --git a/test/vs2017/etl.vcxproj.filters b/test/vs2017/etl.vcxproj.filters index 52458239..5acf6a32 100644 --- a/test/vs2017/etl.vcxproj.filters +++ b/test/vs2017/etl.vcxproj.filters @@ -684,6 +684,9 @@ ETL\STL + + ETL\Maths + @@ -1109,6 +1112,18 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files +