diff --git a/.gitignore b/.gitignore index 1561cf00..2bdcfb1c 100644 --- a/.gitignore +++ b/.gitignore @@ -386,3 +386,4 @@ test/vs2022/Debug MSVC C++20 - No virtual messages examples/MutexMessageRouter/.vs support/time remaining test.xlsx test/vs2022/Debug MSVC C++20 - Force C++03 +test/vs2022/Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser diff --git a/cmake/GetGitRevisionDescription.cmake b/cmake/GetGitRevisionDescription.cmake index 0a203502..07ec5faf 100644 --- a/cmake/GetGitRevisionDescription.cmake +++ b/cmake/GetGitRevisionDescription.cmake @@ -59,7 +59,7 @@ get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) # function returns an empty string via _git_dir_var. # # Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and -# neither foo nor bar contain a file/directory .git. This wil return +# neither foo nor bar contain a file/directory .git. This will return # C:/bla/.git # function(_git_find_closest_git_dir _start_dir _git_dir_var) diff --git a/examples/FunctionInterruptSimulation-Delegates/FunctionInterruptSimulation.cpp b/examples/FunctionInterruptSimulation-Delegates/FunctionInterruptSimulation.cpp index 2fb61c92..bbf6debf 100644 --- a/examples/FunctionInterruptSimulation-Delegates/FunctionInterruptSimulation.cpp +++ b/examples/FunctionInterruptSimulation-Delegates/FunctionInterruptSimulation.cpp @@ -119,7 +119,7 @@ Uart uart1(0, USART1_IRQ_HANDLER); Uart uart2(1, USART2_IRQ_HANDLER); // Declare a global callback for the timer. -// Uses the most efficient callback type for a class, as everthing is known at compile time. +// Uses the most efficient callback type for a class, as everything is known at compile time. etl::delegate timer_member_callback = etl::delegate::create(); // Declare the callbacks for the free functions. diff --git a/examples/FunctionInterruptSimulation/FunctionInterruptSimulation.cpp b/examples/FunctionInterruptSimulation/FunctionInterruptSimulation.cpp index cee73877..9eb6cb98 100644 --- a/examples/FunctionInterruptSimulation/FunctionInterruptSimulation.cpp +++ b/examples/FunctionInterruptSimulation/FunctionInterruptSimulation.cpp @@ -119,7 +119,7 @@ Uart uart1(0, USART1_IRQ_HANDLER); Uart uart2(1, USART2_IRQ_HANDLER); // Declare a global callback for the timer. -// Uses the most efficient callback type for a class, as everthing is known at compile time. +// Uses the most efficient callback type for a class, as everything is known at compile time. etl::function_imp timer_member_callback; // Declare the callbacks for the free functions. diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index cc989d15..313a2c87 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -169,6 +169,18 @@ namespace etl return first2; } + //*************************************************************************** + // generate + template + ETL_CONSTEXPR14 + void generate(TIterator db, TIterator de, TFunction funct) + { + while (db != de) + { + *db++ = funct(); + } + } + //*************************************************************************** // copy #if ETL_USING_STL && ETL_USING_CPP20 @@ -2009,9 +2021,7 @@ namespace etl template ETL_CONSTEXPR14 TIterator remove(TIterator first, TIterator last, const T& value) - { - first = etl::find(first, last, value); - + { if (first != last) { TIterator itr = first; @@ -2039,8 +2049,6 @@ namespace etl ETL_CONSTEXPR14 TIterator remove_if(TIterator first, TIterator last, TUnaryPredicate predicate) { - first = etl::find_if(first, last, predicate); - if (first != last) { TIterator itr = first; @@ -2177,7 +2185,7 @@ namespace etl //*************************************************************************** /// copy_if /// A safer form of copy_if where it terminates when the first end iterator is reached. - /// There is currently no STL equivelent. + /// There is currently no STL equivalent. ///\ingroup algorithm //*************************************************************************** template + ETL_CONSTEXPR14 + typename etl::enable_if::value, TIterator>::type + partition(TIterator first, TIterator last, TPredicate predicate) + { + first = etl::find_if_not(first, last, predicate); + + if (first == last) + { + return first; + } + + for (TIterator i = etl::next(first); i != last; ++i) + { + if (predicate(*i)) + { + using ETL_OR_STD::swap; + swap(*i, *first); + ++first; + } + } + + return first; + } + + //*************************************************************************** + /// partition + /// For iterators that support bidirectional iteration. + /// Does at most (etl::distance(first, last) / 2) swaps. + //*************************************************************************** + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, TIterator>::type + partition(TIterator first, TIterator last, TPredicate predicate) + { + while (first != last) + { + first = etl::find_if_not(first, last, predicate); + + if (first == last) + { + break; + } + + last = etl::find_if(etl::reverse_iterator(last), + etl::reverse_iterator(first), + predicate).base(); + + if (first == last) + { + break; + } + + --last; + using ETL_OR_STD::swap; + swap(*first, *last); + ++first; + } + + return first; + } + + //********************************************************* + namespace private_algorithm + { + using ETL_OR_STD::swap; + + template +#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)) + constexpr +#endif + TIterator nth_partition(TIterator first, TIterator last, TCompare compare) + { + typedef typename etl::iterator_traits::value_type value_type; + + TIterator pivot = last; // Maybe find a better pivot choice? + value_type pivot_value = *pivot; + + // Swap the pivot with the last, if necessary. + if (pivot != last) + { + swap(*pivot, *last); + } + + TIterator i = first; + + for (TIterator j = first; j < last; ++j) + { + if (!compare(pivot_value, *j)) // Hack to get '*j <= pivot_value' in terms of 'pivot_value < *j' + { + swap(*i, *j); + ++i; + } + } + + swap(*i, *last); + + return i; + } + } + + //********************************************************* + /// nth_element + /// see https://en.cppreference.com/w/cpp/algorithm/nth_element + //********************************************************* +#if ETL_USING_CPP11 + template ::value_type> > +#else + template +#endif +#if (ETL_USING_CPP20 && ETL_USING_STL) || (ETL_USING_CPP14 && ETL_NOT_USING_STL && !defined(ETL_IN_UNIT_TEST)) + constexpr +#endif + typename etl::enable_if::value, void>::type + nth_element(TIterator first, TIterator nth, TIterator last, TCompare compare = TCompare()) + { + if (first == last) + { + return; + } + + // 'last' must point to the actual last value. + --last; + + while (first <= last) + { + TIterator p = private_algorithm::nth_partition(first, last, compare); + + if (p == nth) + { + return; + } + else if (p > nth) + { + last = p - 1; + } + else + { + first = p + 1; + } + } + } } #include "private/minmax_pop.h" diff --git a/include/etl/array.h b/include/etl/array.h index 52f0f654..caca9e7e 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -94,15 +94,15 @@ namespace etl static ETL_CONSTANT size_t SIZE = SIZE_; - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef T* iterator; - typedef const T* const_iterator; + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef T* iterator; + typedef const T* const_iterator; typedef ETL_OR_STD::reverse_iterator reverse_iterator; typedef ETL_OR_STD::reverse_iterator const_reverse_iterator; @@ -386,11 +386,12 @@ namespace etl /// If the range is smaller than the array then the unused array elements are left unmodified. ///\param first The iterator to the first item in the range. ///\param last The iterator to one past the final item in the range. + ///\return An iterator to the first unassigned array element, or end(). //************************************************************************* template - void assign(TIterator first, const TIterator last) + iterator assign(TIterator first, const TIterator last) { - etl::copy_s(first, last, begin(), end()); + return etl::copy_s(first, last, begin(), end()); } //************************************************************************* @@ -398,15 +399,18 @@ namespace etl /// If the range is smaller than the array then the unused array elements are initialised with the supplied value. ///\param first The iterator to the first item in the range. ///\param last The iterator to one past the final item in the range. + ///\return An iterator to the first array element set to 'value', or end(). //************************************************************************* template - void assign(TIterator first, const TIterator last, parameter_t value) + iterator assign(TIterator first, const TIterator last, parameter_t value) { // Copy from the range. - iterator p = etl::copy(first, last, begin()); + iterator p = etl::copy_s(first, last, begin(), end()); // Initialise any that are left. etl::fill(p, end(), value); + + return p; } //************************************************************************* diff --git a/include/etl/atomic/atomic_gcc_sync.h b/include/etl/atomic/atomic_gcc_sync.h index 152279dd..9e7399aa 100644 --- a/include/etl/atomic/atomic_gcc_sync.h +++ b/include/etl/atomic/atomic_gcc_sync.h @@ -167,7 +167,7 @@ namespace etl T operator --(int) volatile { - return __atomic_fetch_sub(&value, 1), etl::memory_order_seq_cst; + return __atomic_fetch_sub(&value, 1, etl::memory_order_seq_cst); } // Add diff --git a/include/etl/basic_format_spec.h b/include/etl/basic_format_spec.h index 90a48c1a..36c2d74c 100644 --- a/include/etl/basic_format_spec.h +++ b/include/etl/basic_format_spec.h @@ -172,10 +172,10 @@ namespace etl static ETL_CONSTANT private_basic_format_spec::base_spec hex(16U); //********************************* - static ETL_CONSTANT private_basic_format_spec::left_spec left; + static ETL_CONSTANT private_basic_format_spec::left_spec left = private_basic_format_spec::left_spec(); //********************************* - static ETL_CONSTANT private_basic_format_spec::right_spec right; + static ETL_CONSTANT private_basic_format_spec::right_spec right = private_basic_format_spec::right_spec(); //********************************* static ETL_CONSTANT private_basic_format_spec::boolalpha_spec boolalpha(true); diff --git a/include/etl/basic_string.h b/include/etl/basic_string.h index 8afdf18a..6b01c61f 100644 --- a/include/etl/basic_string.h +++ b/include/etl/basic_string.h @@ -1262,7 +1262,7 @@ namespace etl /// Erases a sequence. ///\param position Position to start from. ///\param length Number of characters. - ///\return A refernce to this string. + ///\return A reference to this string. //********************************************************************* etl::ibasic_string& erase(size_type position, size_type length_ = npos) { diff --git a/include/etl/basic_string_stream.h b/include/etl/basic_string_stream.h index e91ee1fe..2b466055 100644 --- a/include/etl/basic_string_stream.h +++ b/include/etl/basic_string_stream.h @@ -58,28 +58,28 @@ namespace etl } //************************************************************************* - /// Construct from text and format spec. + /// Construct from text and format fmt. //************************************************************************* basic_string_stream(TIString& text_, const TFormat& spec_) : text(text_) - , spec(spec_) + , format(spec_) { } //************************************************************************* - /// Set the format spec. + /// Set the format fmt. //************************************************************************* void set_format(const TFormat& spec_) { - spec = spec_; + format = spec_; } //************************************************************************* - /// Get a const reference to the format spec. + /// Get a const reference to the format fmt. //************************************************************************* const TFormat& get_format() const { - return spec; + return format; } //************************************************************************* @@ -121,27 +121,27 @@ namespace etl //********************************* /// TFormat //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, const TFormat& spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, const TFormat& fmt) { - ss.spec = spec; + ss.format = fmt; return ss; } //********************************* /// etl::base_spec from etl::setbase, etl::bin, etl::oct, etl::dec & etl::hex stream manipulators //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::base_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::base_spec fmt) { - ss.spec.base(spec.base); + ss.format.base(fmt.base); return ss; } //********************************* /// etl::width_spec from etl::setw stream manipulator //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::width_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::width_spec fmt) { - ss.spec.width(spec.width); + ss.format.width(fmt.width); return ss; } @@ -149,63 +149,63 @@ namespace etl /// etl::fill_spec from etl::setfill stream manipulator //********************************* template - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::fill_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::fill_spec fmt) { - ss.spec.fill(spec.fill); + ss.format.fill(fmt.fill); return ss; } //********************************* /// etl::precision_spec from etl::setprecision stream manipulator //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::precision_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::precision_spec fmt) { - ss.spec.precision(spec.precision); + ss.format.precision(fmt.precision); return ss; } //********************************* /// etl::boolalpha_spec from etl::boolalpha & etl::noboolalpha stream manipulators //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::boolalpha_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::boolalpha_spec fmt) { - ss.spec.boolalpha(spec.boolalpha); + ss.format.boolalpha(fmt.boolalpha); return ss; } //********************************* /// etl::uppercase_spec from etl::uppercase & etl::nouppercase stream manipulators //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::uppercase_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::uppercase_spec fmt) { - ss.spec.upper_case(spec.upper_case); + ss.format.upper_case(fmt.upper_case); return ss; } //********************************* /// etl::showbase_spec from etl::showbase & etl::noshowbase stream manipulators //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::showbase_spec spec) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::showbase_spec fmt) { - ss.spec.show_base(spec.show_base); + ss.format.show_base(fmt.show_base); return ss; } //********************************* /// etl::left_spec from etl::left stream manipulator //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::left_spec /*spec*/) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::left_spec /*fmt*/) { - ss.spec.left(); + ss.format.left(); return ss; } //********************************* /// etl::right_spec from etl::left stream manipulator //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::right_spec /*spec*/) + friend basic_string_stream& operator <<(basic_string_stream& ss, etl::private_basic_format_spec::right_spec /*fmt*/) { - ss.spec.right(); + ss.format.right(); return ss; } @@ -214,7 +214,7 @@ namespace etl //********************************* friend basic_string_stream& operator <<(basic_string_stream& ss, TStringView view) { - etl::to_string(view, ss.text, ss.spec, true); + etl::to_string(view, ss.text, ss.format, true); return ss; } @@ -241,9 +241,9 @@ namespace etl //********************************* /// From a string interface //********************************* - friend basic_string_stream& operator <<(basic_string_stream& ss, const TIString& text) + friend basic_string_stream& operator <<(basic_string_stream& ss, const TIString& t) { - etl::to_string(text, ss.text, ss.spec, true); + etl::to_string(t, ss.text, ss.format, true); return ss; } @@ -251,9 +251,9 @@ namespace etl /// From a string //********************************* template