From 4bc785386320112b50339dbc4eb6e82b267f2856 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 30 Apr 2024 11:58:24 +0100 Subject: [PATCH 1/7] Full constexpr for etl::array --- include/etl/array.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/etl/array.h b/include/etl/array.h index caca9e7e..0a41faed 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -115,6 +115,7 @@ namespace etl ///\param i The index of the element to access. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reference at(size_t i) { ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); @@ -141,6 +142,7 @@ namespace etl ///\param i The index of the element to access. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reference operator[](size_t i) { return _buffer[i]; @@ -161,6 +163,7 @@ namespace etl /// Returns a reference to the first element. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reference front() { return _buffer[0]; @@ -179,6 +182,7 @@ namespace etl /// Returns a reference to the last element. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reference back() { return _buffer[SIZE - 1]; @@ -197,6 +201,7 @@ namespace etl /// Returns a pointer to the first element of the internal buffer. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 pointer data() ETL_NOEXCEPT { return &_buffer[0]; @@ -219,6 +224,7 @@ namespace etl /// Returns an iterator to the beginning of the array. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 iterator begin() ETL_NOEXCEPT { return &_buffer[0]; @@ -246,6 +252,7 @@ namespace etl /// Returns an iterator to the end of the array. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 iterator end() ETL_NOEXCEPT { return _buffer + SIZE; @@ -273,6 +280,7 @@ namespace etl // Returns an reverse iterator to the reverse beginning of the array. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reverse_iterator rbegin() ETL_NOEXCEPT { return reverse_iterator(end()); @@ -300,6 +308,7 @@ namespace etl /// Returns a reverse iterator to the end of the array. //************************************************************************* ETL_NODISCARD + ETL_CONSTEXPR14 reverse_iterator rend() ETL_NOEXCEPT { return reverse_iterator(begin()); From 17a4e8d934df29ca90451b7e06bee5c178f489f5 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 09:06:35 +0100 Subject: [PATCH 2/7] Added ETL_NODISCARD, ETL_CONSTEXPR14 and ETL_NOEXCEPT --- include/etl/absolute.h | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/include/etl/absolute.h b/include/etl/absolute.h index 5812f86b..7bc5ea66 100644 --- a/include/etl/absolute.h +++ b/include/etl/absolute.h @@ -40,8 +40,10 @@ namespace etl // For signed types. //*************************************************************************** template - ETL_CONSTEXPR typename etl::enable_if::value, T>::type - absolute(T value) + ETL_NODISCARD + ETL_CONSTEXPR + typename etl::enable_if::value, T>::type + absolute(T value) ETL_NOEXCEPT { return (value < T(0)) ? -value : value; } @@ -50,8 +52,10 @@ namespace etl // For unsigned types. //*************************************************************************** template - ETL_CONSTEXPR typename etl::enable_if::value, T>::type - absolute(T value) + ETL_NODISCARD + ETL_CONSTEXPR + typename etl::enable_if::value, T>::type + absolute(T value) ETL_NOEXCEPT { return value; } @@ -65,8 +69,10 @@ namespace etl #else template #endif - ETL_CONSTEXPR typename etl::enable_if::value, TReturn>::type - absolute_unsigned(T value) + ETL_NODISCARD + ETL_CONSTEXPR + typename etl::enable_if::value, TReturn>::type + absolute_unsigned(T value) ETL_NOEXCEPT { return (value == etl::integral_limits::min) ? (etl::integral_limits::max / 2U) + 1U : (value < T(0)) ? TReturn(-value) : TReturn(value); @@ -77,8 +83,10 @@ namespace etl // Returns the result as the unsigned type. //*************************************************************************** template - ETL_CONSTEXPR typename etl::enable_if::value, T>::type - absolute_unsigned(T value) + ETL_NODISCARD + ETL_CONSTEXPR + typename etl::enable_if::value, T>::type + absolute_unsigned(T value) ETL_NOEXCEPT { return etl::absolute(value); } From 384c08f25b2e9d67f57239fd32171265cbf5ed9a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 09:07:30 +0100 Subject: [PATCH 3/7] Added specialisations of etl::rotate for different iterator types --- include/etl/algorithm.h | 106 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 9 deletions(-) diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index 43ec1668..ff785df4 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -43,6 +43,7 @@ SOFTWARE. #include "iterator.h" #include "functional.h" #include "utility.h" +#include "gcd.h" #include #include @@ -1157,20 +1158,94 @@ namespace etl namespace private_algorithm { //********************************* + // For random access iterators template ETL_CONSTEXPR14 - TIterator rotate_general(TIterator first, TIterator middle, TIterator last) + typename etl::enable_if::value, TIterator>::type + rotate_general(TIterator first, TIterator middle, TIterator last) { + if (first == middle || middle == last) + { + return first; + } + + int n = last - first; + int m = middle - first; + int gcd_nm = etl::gcd(n, m); + + TIterator result = first + (last - middle); + + for (int i = 0; i < gcd_nm; i++) + { + auto temp = *(first + i); + int j = i; + + while (true) + { + int k = j + m; + + if (k >= n) + { + k = k - n; + } + + if (k == i) + { + break; + } + + *(first + j) = *(first + k); + j = k; + } + + *(first + j) = temp; + } + + return result; + } + + //********************************* + // For bidirectional iterators + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, TIterator>::type + rotate_general(TIterator first, TIterator middle, TIterator last) + { + if (first == middle || middle == last) + { + return first; + } + + TIterator result = first; + etl::advance(result, etl::distance(middle, last)); + + reverse(first, middle); + reverse(middle, last); + reverse(first, last); + + return result; + } + + //********************************* + // For forward iterators + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, TIterator>::type + rotate_general(TIterator first, TIterator middle, TIterator last) + { + if (first == middle || middle == last) + { + return first; + } + TIterator next = middle; + TIterator result = first; + std::advance(result, std::distance(middle, last)); while (first != next) { - using ETL_OR_STD::swap; // Allow ADL - - swap(*first, *next); - - ++first; - ++next; + using ETL_OR_STD::swap; + swap(*first++, *next++); if (next == last) { @@ -1182,10 +1257,11 @@ namespace etl } } - return first; + return result; } //********************************* + // Simplified algorithm for rotate left by one template ETL_CONSTEXPR14 TIterator rotate_left_by_one(TIterator first, TIterator last) @@ -1206,6 +1282,7 @@ namespace etl } //********************************* + // Simplified for algorithm rotate right by one template ETL_CONSTEXPR14 TIterator rotate_right_by_one(TIterator first, TIterator last) @@ -1239,7 +1316,18 @@ namespace etl if (etl::next(middle) == last) { - return private_algorithm::rotate_right_by_one(first, last); +#if ETL_USING_CPP20 + if ETL_IF_CONSTEXPR(etl::is_forward_iterator::value) + { + return private_algorithm::rotate_general(first, middle, last); + } + else + { + return private_algorithm::rotate_right_by_one(first, last); + } +#else + return private_algorithm::rotate_general(first, middle, last); +#endif } return private_algorithm::rotate_general(first, middle, last); From 8528ed2b80e0fbc72f44ff4e864c787ab7d30451 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 09:08:02 +0100 Subject: [PATCH 4/7] Added GCD and LCM algorithms --- include/etl/gcd.h | 139 +++++++++++++++++++++++++++++++ include/etl/lcm.h | 141 ++++++++++++++++++++++++++++++++ test/test_math_functions.cpp | 42 ++++++++++ test/vs2022/etl.vcxproj | 2 + test/vs2022/etl.vcxproj.filters | 6 ++ 5 files changed, 330 insertions(+) create mode 100644 include/etl/gcd.h create mode 100644 include/etl/lcm.h diff --git a/include/etl/gcd.h b/include/etl/gcd.h new file mode 100644 index 00000000..b99a9d3a --- /dev/null +++ b/include/etl/gcd.h @@ -0,0 +1,139 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2024 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_GDC_INCLUDED +#define ETL_GDC_INCLUDED + +#include "type_traits.h" +#include "absolute.h" +#include "static_assert.h" + +namespace etl +{ + //*************************************************************************** + // Greatest Common Divisor. + // For unsigned types. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + gcd(T a, T b) ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Integral type required"); + + while (b != 0) + { + T t = b; + b = a % b; + a = t; + } + + return a; + } + + //*************************************************************************** + // Greatest Common Divisor. + // For signed types. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + gcd(T a, T b) ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Integral type required"); + + typedef typename etl::make_unsigned::type utype; + + utype ua = etl::absolute_unsigned(a); + utype ub = etl::absolute_unsigned(b); + + return static_cast(gcd(ua, ub)); + } + +#if ETL_USING_CPP11 + #if ETL_HAS_INITIALIZER_LIST + //*************************************************************************** + // Greatest Common Divisor. + // Non-recursive, using an initializer_list. + // Top level variadic function. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + T gcd(T first, TRest... rest) ETL_NOEXCEPT + { + T result = first; + + for (T value : {rest...}) + { + result = gcd(result, value); + + if (result == 1) + { + // Early termination: if the GCD is one, it will remain one + // no matter what other numbers are processed. + return 1; + } + } + + return result; + } + #else + //*************************************************************************** + // Greatest Common Divisor. + // Recursive. + // Top level variadic function. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + T gcd(T a, T b, TRest... rest) ETL_NOEXCEPT + { + T gcd_ab = gcd(a, b); + + if (gcd_ab == 1) + { + // Early termination: if the GCD is one, it will remain one + // no matter what other numbers are processed. + return 1; + } + else + { + return gcd(gcd_ab, rest...); + } + } + #endif +#endif +} + +#endif + diff --git a/include/etl/lcm.h b/include/etl/lcm.h new file mode 100644 index 00000000..43bb0021 --- /dev/null +++ b/include/etl/lcm.h @@ -0,0 +1,141 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2024 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_LCM_INCLUDED +#define ETL_LCM_INCLUDED + +#include "type_traits.h" +#include "absolute.h" +#include "static_assert.h" +#include "gcd.h" + +namespace etl +{ + //*************************************************************************** + // Least Common Multiple. + // For unsigned types. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + lcm(T a, T b) ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Integral type required"); + + // Early termination: if either number is zero, the LCM is zero. + if (a == 0 || b == 0) + { + return 0; + } + else + { + return a * (b / gcd(a, b)); + } + } + + //*************************************************************************** + // Least Common Multiple. + // For signed types. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + typename etl::enable_if::value, T>::type + lcm(T a, T b) ETL_NOEXCEPT + { + ETL_STATIC_ASSERT(etl::is_integral::value, "Integral type required"); + + typedef typename etl::make_unsigned::type utype; + + utype ua = etl::absolute_unsigned(a); + utype ub = etl::absolute_unsigned(b); + + return static_cast(lcm(ua, ub)); + } + +#if ETL_USING_CPP11 + #if ETL_HAS_INITIALIZER_LIST + //*************************************************************************** + // Least Common Multiple. + // Non-recursive, using an initializer_list. + // Top level variadic function. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + T lcm(T first, TRest... rest) ETL_NOEXCEPT + { + T result = first; + + for (T value : {rest...}) + { + result = lcm(result, value); + + if (result == 0) + { + // Early termination: if the LCM is zero, it will remain zero + // no matter what other numbers are processed. + return 0; + } + } + + return result; + } + #else + //*************************************************************************** + // Least Common Multiple. + // Recursive + // Top level variadic function. + //*************************************************************************** + template + ETL_NODISCARD + ETL_CONSTEXPR14 + T lcm(T a, T b, TRest... rest) ETL_NOEXCEPT + { + T lcm_ab = lcm(a, b); + + if (lcm_ab == 0) + { + // Early termination: if the LCM is zero, it will remain zero + // no matter what other numbers are processed. + return 0; + } + else + { + return lcm(lcm_ab, rest...); + } + } + #endif +#endif +} + +#endif + diff --git a/test/test_math_functions.cpp b/test/test_math_functions.cpp index 95cb9575..c4255a5a 100644 --- a/test/test_math_functions.cpp +++ b/test/test_math_functions.cpp @@ -35,6 +35,8 @@ SOFTWARE. #include "etl/sqrt.h" #include "etl/permutations.h" #include "etl/combinations.h" +#include "etl/gcd.h" +#include "etl/lcm.h" namespace { @@ -457,5 +459,45 @@ namespace CHECK_EQUAL((combinations(13, 9)), (actual = etl::combinations<13, 9>::value)); CHECK_EQUAL((combinations(14, 10)), (actual = etl::combinations<14, 10>::value)); } + + //************************************************************************* + TEST(test_gdc_for_positive_integers) + { + CHECK_EQUAL(1, etl::gcd( 3, 5, 7)); + CHECK_EQUAL(2, etl::gcd( 4, 6, 8)); + CHECK_EQUAL(3, etl::gcd( 9, 6, 3)); + CHECK_EQUAL(4, etl::gcd( 8, 4, 12)); + CHECK_EQUAL(5, etl::gcd(10, 5, 15)); + } + + //************************************************************************* + TEST(test_gdc_for_negative_integers) + { + CHECK_EQUAL(1, etl::gcd( -3, -5, -7)); + CHECK_EQUAL(2, etl::gcd( -4, -6, -8)); + CHECK_EQUAL(3, etl::gcd( -9, -6, -3)); + CHECK_EQUAL(4, etl::gcd( -8, -4, -12)); + CHECK_EQUAL(5, etl::gcd(-10, -5, -15)); + } + + //************************************************************************* + TEST(test_lcm_for_positive_integers) + { + CHECK_EQUAL(12, etl::lcm(3, 4, 6)); + CHECK_EQUAL(30, etl::lcm(3, 5, 10)); + CHECK_EQUAL(20, etl::lcm(2, 5, 4)); + CHECK_EQUAL(0, etl::lcm(0, 5, 7)); + CHECK_EQUAL(5, etl::lcm(5, 5, 5)); + } + + //************************************************************************* + TEST(test_lcm_for_negative_integers) + { + CHECK_EQUAL(12, etl::lcm(-3, -4, -6)); + CHECK_EQUAL(30, etl::lcm(-3, -5, -10)); + CHECK_EQUAL(20, etl::lcm(-2, -5, -4)); + CHECK_EQUAL(0, etl::lcm(-0, -5, -7)); + CHECK_EQUAL(5, etl::lcm(-5, -5, -5)); + } }; } diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index c95a0d70..d8a6e7a1 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3082,6 +3082,8 @@ + + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index c4825d0a..641f479f 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1395,6 +1395,12 @@ ETL\Maths\CRC + + ETL\Maths + + + ETL\Maths + From 4f64c83a470047cd5c12644e09d04fd902c1e930 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 10:56:54 +0100 Subject: [PATCH 5/7] Added specialisations of etl::rotate for different iterator types --- include/etl/algorithm.h | 57 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index ff785df4..fb394f8f 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -1157,6 +1157,7 @@ namespace etl //*************************************************************************** namespace private_algorithm { +#if ETL_USING_CPP11 //********************************* // For random access iterators template @@ -1169,15 +1170,17 @@ namespace etl return first; } + typedef typename etl::iterator_traits::value_type value_type; + int n = last - first; int m = middle - first; - int gcd_nm = etl::gcd(n, m); + int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m); TIterator result = first + (last - middle); for (int i = 0; i < gcd_nm; i++) { - auto temp = *(first + i); + value_type temp = etl::move(*(first + i)); int j = i; while (true) @@ -1194,6 +1197,55 @@ namespace etl break; } + *(first + j) = etl::move(*(first + k)); + j = k; + } + + *(first + j) = etl::move(temp); + } + + return result; + } +#else + //********************************* + // For random access iterators + template + ETL_CONSTEXPR14 + typename etl::enable_if::value, TIterator>::type + rotate_general(TIterator first, TIterator middle, TIterator last) + { + if (first == middle || middle == last) + { + return first; + } + + typedef typename etl::iterator_traits::value_type value_type; + + int n = last - first; + int m = middle - first; + int gcd_nm = (n == 0 || m == 0) ? n + m : etl::gcd(n, m); + + TIterator result = first + (last - middle); + + for (int i = 0; i < gcd_nm; i++) + { + value_type temp = *(first + i); + int j = i; + + while (true) + { + int k = j + m; + + if (k >= n) + { + k = k - n; + } + + if (k == i) + { + break; + } + *(first + j) = *(first + k); j = k; } @@ -1203,6 +1255,7 @@ namespace etl return result; } +#endif //********************************* // For bidirectional iterators From c6bfa2873d8d9c851e0a7979ab1dc7b242e8fdc8 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 10:57:03 +0100 Subject: [PATCH 6/7] Added GCD and LCM algorithms --- include/etl/gcd.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/etl/gcd.h b/include/etl/gcd.h index b99a9d3a..aea495e5 100644 --- a/include/etl/gcd.h +++ b/include/etl/gcd.h @@ -49,6 +49,11 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_integral::value, "Integral type required"); + if ((a == 0 || b == 0)) + { + return (a + b); + } + while (b != 0) { T t = b; From 42e6ee25169f1f871494eea109452faedce6343c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 May 2024 13:28:06 +0100 Subject: [PATCH 7/7] Updated version and release notes --- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 8 ++++++++ version.txt | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/etl/version.h b/include/etl/version.h index cb82de2c..cad37c11 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -40,7 +40,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 20 #define ETL_VERSION_MINOR 38 -#define ETL_VERSION_PATCH 13 +#define ETL_VERSION_PATCH 14 #define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index f430b374..f023e4e7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.38.13", + "version": "20.38.14", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 13fa5074..0bda19ae 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.38.13 +version=20.38.14 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index be294d8d..2403404b 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,4 +1,12 @@ =============================================================================== +20.38.14 + +Features: +Added GCD and LCM algorithms. etl::gcd and etl::lcm +Added specialisations of etl::rotate for different iterator types +Added ETL_NODISCARD, ETL_CONSTEXPR14 and ETL_NOEXCEPT to etl::absolute and etl::absolute_unsigned + +=============================================================================== 20.38.13 Fixes: diff --git a/version.txt b/version.txt index af6f145e..7c35c656 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.38.13 +20.38.14