From 1606ae3dcce4a3ae0e70f57210dfd48f80d25e1e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 27 Aug 2018 13:22:04 +0100 Subject: [PATCH] Added missing algorithms. Fixed namespace selection. --- include/etl/stl/alternate/algorithm.h | 214 +++++++++++++++---------- include/etl/stl/alternate/functional.h | 14 +- include/etl/stl/alternate/iterator.h | 88 +++++++--- include/etl/stl/alternate/limits.h | 12 +- include/etl/stl/alternate/utility.h | 21 ++- test/codeblocks/ETL.cbp | 1 + test/no_stl_test_iterators.h | 206 ++++++++++++++++++++++++ test/test_no_stl_algorithm.cpp | 136 +++++++++------- test/test_no_stl_iterator.cpp | 96 +++++++++++ test/vs2017/etl.vcxproj | 2 + test/vs2017/etl.vcxproj.filters | 6 + 11 files changed, 606 insertions(+), 190 deletions(-) create mode 100644 test/no_stl_test_iterators.h create mode 100644 test/test_no_stl_iterator.cpp diff --git a/include/etl/stl/alternate/algorithm.h b/include/etl/stl/alternate/algorithm.h index 74291034..02566915 100644 --- a/include/etl/stl/alternate/algorithm.h +++ b/include/etl/stl/alternate/algorithm.h @@ -39,70 +39,30 @@ SOFTWARE. #include "iterator.h" #include "functional.h" +#include "utility.h" #if defined(ETL_IN_UNIT_TEST) -#define ETLSTD etlstd -namespace etlstd + #if !defined(ETLSTD) + #define ETLSTD etlstd + #endif + namespace etlstd #else -#define ETLSTD std -namespace std + #if !defined(ETLSTD) + #define ETLSTD std + #endif + namespace std #endif { - //*************************************************************************** - // distance - template - typename etl::enable_if::iterator_category, std::random_access_iterator_tag>::value, - typename std::iterator_traits::difference_type>::type - distance(TIterator first, TIterator last) - { - typename std::iterator_traits::difference_type count = 0; - - while (first != last) - { - ++count; - ++first; - } - - return count; - } - - template - typename etl::enable_if::iterator_category, std::random_access_iterator_tag>::value, - typename std::iterator_traits::difference_type>::type - distance(TIterator first, TIterator last) - { - return last - first; - } - - //*************************************************************************** - // advance - template - typename etl::enable_if::iterator_tag, std::random_access_iterator_tag>::value, void>::type - advance(TIterator itr, TDistance distance) - { - while (distance-- != 0) - { - ++itr; - } - } - - template - typename etl::enable_if::iterator_tag, std::random_access_iterator_tag>::value, void>::type - advance(TIterator itr, TDistance distance) - { - return itr += distance; - } - //*************************************************************************** // copy // Pointer template typename etl::enable_if::value && etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_pod::value_type>::value, TIterator2>::type copy(TIterator1 sb, TIterator1 se, TIterator2 db) { - typedef typename std::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; return TIterator2(memcpy(db, sb, sizeof(value_t) * (se - sb))); } @@ -111,7 +71,7 @@ namespace std template typename etl::enable_if::value || !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_pod::value_type>::value, TIterator2>::type copy(TIterator1 sb, TIterator1 se, TIterator2 db) { while (sb != se) @@ -128,10 +88,10 @@ namespace std template typename etl::enable_if::value && etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_pod::value_type>::value, TIterator2>::type copy_n(TIterator1 sb, TSize count, TIterator2 db) { - typedef typename std::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; return TIterator2(memcpy(db, sb, sizeof(value_t) * count)); } @@ -140,7 +100,7 @@ namespace std template typename etl::enable_if::value || !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_pod::value_type>::value, TIterator2>::type copy_n(TIterator1 sb, TSize count, TIterator2 db) { while (count != 0) @@ -158,10 +118,10 @@ namespace std template typename etl::enable_if::value && etl::is_pointer::value && - etl::is_pod::value_type>::value, TIterator2>::type + etl::is_pod::value_type>::value, TIterator2>::type copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de) { - typedef typename std::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; const size_t length = (se - sb); @@ -172,7 +132,7 @@ namespace std template typename etl::enable_if::value || !etl::is_pointer::value || - !etl::is_pod::value_type>::value, TIterator2>::type + !etl::is_pod::value_type>::value, TIterator2>::type copy_backward(TIterator1 sb, TIterator1 se, TIterator2 de) { while (se != sb) @@ -188,16 +148,16 @@ namespace std template TIterator lower_bound(TIterator first, TIterator last, const TValue& value, TCompare compare) { - typedef typename std::iterator_traits::difference_type difference_t; + typedef typename ETLSTD::iterator_traits::difference_type difference_t; - difference_t count = std::distance(first, last); + difference_t count = ETLSTD::distance(first, last); while (count > 0) { TIterator itr = first; difference_t step = count / 2; - std::advance(itr, step); + ETLSTD::advance(itr, step); if (compare(*itr, value)) { @@ -216,7 +176,7 @@ namespace std template TIterator lower_bound(TIterator first, TIterator last, const TValue& value) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; return ETLSTD::lower_bound(first, last, value, compare()); } @@ -226,16 +186,16 @@ namespace std template TIterator upper_bound(TIterator first, TIterator last, const TValue& value, TCompare compare) { - typedef typename std::iterator_traits::difference_type difference_t; + typedef typename ETLSTD::iterator_traits::difference_type difference_t; - difference_t count = std::distance(first, last); + difference_t count = ETLSTD::distance(first, last); while (count > 0) { TIterator itr = first; difference_t step = count / 2; - std::advance(itr, step); + ETLSTD::advance(itr, step); if (!compare(value, *itr)) { @@ -254,7 +214,7 @@ namespace std template TIterator upper_bound(TIterator first, TIterator last, const TValue& value) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; return ETLSTD::upper_bound(first, last, value, compare()); } @@ -262,19 +222,55 @@ namespace std //*************************************************************************** // equal_range template - std::pair equal_range(TIterator first, TIterator last, const TValue& value, TCompare compare) + ETLSTD::pair equal_range(TIterator first, TIterator last, const TValue& value, TCompare compare) { - return std::make_pair(ETLSTD::lower_bound(first, last, value, compare), + return ETLSTD::make_pair(ETLSTD::lower_bound(first, last, value, compare), ETLSTD::upper_bound(first, last, value, compare)); } template - std::pair equal_range(TIterator first, TIterator last, const TValue& value) + ETLSTD::pair equal_range(TIterator first, TIterator last, const TValue& value) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; - return std::make_pair(ETLSTD::lower_bound(first, last, value, compare()), - ETLSTD::upper_bound(first, last, value, compare())); + return ETLSTD::make_pair(ETLSTD::lower_bound(first, last, value, compare()), + ETLSTD::upper_bound(first, last, value, compare())); + } + + //*************************************************************************** + // find_if + template + TIterator find_if(TIterator first, TIterator last, TUnaryPredicate predicate) + { + while (first != last) + { + if (predicate(*first)) + { + return first; + } + + ++first; + } + + return last; + } + + //*************************************************************************** + // find + template + TIterator find(TIterator first, TIterator last, const T& value) + { + while (first != last) + { + if (*first == value) + { + return first; + } + + ++first; + } + + return last; } //*************************************************************************** @@ -296,6 +292,46 @@ namespace std memset(first, value, last - first); } + //*************************************************************************** + // count + template + typename iterator_traits::difference_type count(TIterator first, TIterator last, const T& value) + { + typename iterator_traits::difference_type n = 0; + + while (first != last) + { + if (*first == value) + { + ++n; + } + + ++first; + } + + return n; + } + + //*************************************************************************** + // count + template + typename iterator_traits::difference_type count_if(TIterator first, TIterator last, TUnaryPredicate predicate) + { + typename iterator_traits::difference_type n = 0; + + while (first != last) + { + if (predicate(*first)) + { + ++n; + } + + ++first; + } + + return n; + } + //*************************************************************************** // swap template @@ -311,7 +347,7 @@ namespace std template void iter_swap(TIterator1 a, TIterator2 b) { - typename std::iterator_traits::value_type c = *a; + typename ETLSTD::iterator_traits::value_type c = *a; *a = *b; *b = c; } @@ -319,7 +355,7 @@ namespace std //*************************************************************************** // equal template - typename etl::enable_if::value || !etl::is_pointer::value || !etl::is_pod::value_type>::value, bool>::type + typename etl::enable_if::value || !etl::is_pointer::value || !etl::is_pod::value_type>::value, bool>::type equal(TIterator1 first1, TIterator1 last1, TIterator2 first2) { while (first1 != last1) @@ -334,10 +370,10 @@ namespace std } template - typename etl::enable_if::value && etl::is_pointer::value && etl::is_pod::value_type>::value, bool>::type + typename etl::enable_if::value && etl::is_pointer::value && etl::is_pod::value_type>::value, bool>::type equal(TIterator1 first1, TIterator1 last1, TIterator2 first2) { - typedef typename std::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; return (memcmp(first1, first2, sizeof(value_t) * (last1 - last1)) == 0); } @@ -374,7 +410,7 @@ namespace std bool lexicographical_compare(TIterator1 first1, TIterator1 last1, TIterator2 first2, TIterator2 last2) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; return ETLSTD::lexicographical_compare(first1, last1, first2, last2, compare()); } @@ -390,7 +426,7 @@ namespace std template const T& min(const T& a, const T& b) { - typedef std::less compare; + typedef ETLSTD::less compare; return ETLSTD::min(a, b, compare()); } @@ -406,7 +442,7 @@ namespace std template const T& max(const T& a, const T& b) { - typedef std::less compare; + typedef ETLSTD::less compare; return ETLSTD::max(a, b, compare()); } @@ -486,8 +522,8 @@ namespace std template void pop_heap(TIterator first, TIterator last, TCompare compare) { - typedef typename std::iterator_traits::value_type value_t; - typedef typename std::iterator_traits::difference_type distance_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::difference_type distance_t; value_t value = last[-1]; last[-1] = first[0]; @@ -499,7 +535,7 @@ namespace std template void pop_heap(TIterator first, TIterator last) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; ETLSTD::pop_heap(first, last, compare()); } @@ -508,8 +544,8 @@ namespace std template void push_heap(TIterator first, TIterator last, TCompare compare) { - typedef typename std::iterator_traits::difference_type difference_t; - typedef typename std::iterator_traits::value_type value_t; + typedef typename ETLSTD::iterator_traits::difference_type difference_t; + typedef typename ETLSTD::iterator_traits::value_type value_t; private_heap::push_heap(first, difference_t(last - first - 1), difference_t(0), value_t(*(last - 1)), compare); } @@ -518,7 +554,7 @@ namespace std template void push_heap(TIterator first, TIterator last) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; ETLSTD::push_heap(first, last, compare()); } @@ -527,7 +563,7 @@ namespace std template void make_heap(TIterator first, TIterator last, TCompare compare) { - typedef typename std::iterator_traits::difference_type difference_t; + typedef typename ETLSTD::iterator_traits::difference_type difference_t; if ((last - first) < 2) { @@ -554,7 +590,7 @@ namespace std template void make_heap(TIterator first, TIterator last) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; ETLSTD::make_heap(first, last, compare()); } @@ -563,7 +599,7 @@ namespace std template bool is_heap(TIterator first, TIterator last) { - typedef std::less::value_type> compare; + typedef ETLSTD::less::value_type> compare; return private_heap::is_heap(first, last - first, compare()); } @@ -615,7 +651,7 @@ namespace std template TIterator1 search(TIterator1 first, TIterator1 last, TIterator2 search_first, TIterator2 search_last) { - typedef std::equal_to::value_type> compare; + typedef ETLSTD::equal_to::value_type> compare; return ETLSTD::search(first, last, search_first, search_last, compare()); } diff --git a/include/etl/stl/alternate/functional.h b/include/etl/stl/alternate/functional.h index 5ba390a3..01d9c0a7 100644 --- a/include/etl/stl/alternate/functional.h +++ b/include/etl/stl/alternate/functional.h @@ -5,9 +5,15 @@ #include "../../platform.h" #if defined(ETL_IN_UNIT_TEST) -namespace etlstd + #if !defined(ETLSTD) + #define ETLSTD etlstd + #endif + namespace etlstd #else -namespace std + #if !defined(ETLSTD) + #define ETLSTD std + #endif + namespace std #endif { //*************************************************************************** @@ -72,7 +78,7 @@ namespace std //*************************************************************************** template - class binder1st : public etlstd::unary_function + class binder1st : public ETLSTD::unary_function { protected: @@ -106,7 +112,7 @@ namespace std //*************************************************************************** template - class binder2nd : public etlstd::unary_function + class binder2nd : public ETLSTD::unary_function { protected: TFunction operation; diff --git a/include/etl/stl/alternate/iterator.h b/include/etl/stl/alternate/iterator.h index 45ea129a..13b128ce 100644 --- a/include/etl/stl/alternate/iterator.h +++ b/include/etl/stl/alternate/iterator.h @@ -38,8 +38,14 @@ SOFTWARE. #include "../../type_traits.h" #if defined(ETL_IN_UNIT_TEST) + #if !defined(ETLSTD) + #define ETLSTD etlstd + #endif namespace etlstd #else + #if !defined(ETLSTD) + #define ETLSTD std + #endif namespace std #endif { @@ -82,7 +88,7 @@ namespace std typedef T value_type; typedef T* pointer; typedef T& reference; - typedef random_access_iterator_tag iterator_category ; + typedef random_access_iterator_tag iterator_category; }; template @@ -92,14 +98,19 @@ namespace std typedef T value_type; typedef T* pointer; typedef T& reference; - typedef random_access_iterator_tag iterator_category ; + typedef random_access_iterator_tag iterator_category; }; //*************************************************************************** // advance template - typename etl::enable_if::iterator_catagory, input_iterator_tag>::value, void>::type - advance(TIterator& itr, TDistance n) + void advance(TIterator& itr, TDistance n) + { + advance_helper(itr, n, typename ETLSTD::iterator_traits::iterator_category()); + } + + template + void advance_helper(TIterator& itr, TDistance n, ETLSTD::input_iterator_tag) { while (n--) { @@ -108,8 +119,7 @@ namespace std } template - typename etl::enable_if::iterator_catagory, output_iterator_tag>::value, void>::type - advance(TIterator& itr, TDistance n) + void advance_helper(TIterator& itr, TDistance n, ETLSTD::output_iterator_tag) { while (n--) { @@ -118,8 +128,7 @@ namespace std } template - typename etl::enable_if::iterator_catagory, forward_iterator_tag>::value, void>::type - advance(TIterator& itr, TDistance n) + void advance_helper(TIterator& itr, TDistance n, ETLSTD::forward_iterator_tag) { while (n--) { @@ -128,8 +137,7 @@ namespace std } template - typename etl::enable_if::iterator_catagory, bidirectional_iterator_tag>::value, void>::type - advance(TIterator& itr, TDistance n) + void advance_helper(TIterator& itr, TDistance n, ETLSTD::bidirectional_iterator_tag) { if (n > 0) { @@ -140,7 +148,7 @@ namespace std } else { - while (n--) + while (n++) { --itr; } @@ -148,8 +156,7 @@ namespace std } template - typename etl::enable_if::iterator_catagory, random_access_iterator_tag>::value, void>::type - advance(TIterator& itr, TDistance n) + void advance_helper(TIterator& itr, TDistance n, ETLSTD::random_access_iterator_tag) { itr += n; } @@ -157,24 +164,55 @@ namespace std //*************************************************************************** // distance template - typename etl::enable_if::iterator_catagory, random_access_iterator_tag>::value, - typename iterator_traits::difference_type>::type - distance(TIterator first, TIterator last) + typename ETLSTD::iterator_traits::difference_type distance(TIterator first, TIterator last) { - typename iterator_traits::difference_type d = 0; + return distance_helper(first, last, typename ETLSTD::iterator_traits::iterator_category()); + } + + template + typename ETLSTD::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETLSTD::input_iterator_tag) + { + typename ETLSTD::iterator_traits::difference_type d = 0; while (first != last) { ++d; + ++first; } return d; } template - typename etl::enable_if::iterator_catagory, random_access_iterator_tag>::value, - typename iterator_traits::difference_type>::type - distance(TIterator first, TIterator last) + typename ETLSTD::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETLSTD::forward_iterator_tag) + { + typename ETLSTD::iterator_traits::difference_type d = 0; + + while (first != last) + { + ++d; + ++first; + } + + return d; + } + + template + typename ETLSTD::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETLSTD::bidirectional_iterator_tag) + { + typename ETLSTD::iterator_traits::difference_type d = 0; + + while (first != last) + { + ++d; + ++first; + } + + return d; + } + + template + typename ETLSTD::iterator_traits::difference_type distance_helper(TIterator first, TIterator last, ETLSTD::random_access_iterator_tag) { return last - first; } @@ -186,11 +224,11 @@ namespace std { public: - typedef typename iterator_traits::difference_type difference_type; - typedef typename iterator_traits::value_type value_type; - typedef typename iterator_traits::pointer pointer; - typedef typename iterator_traits::reference reference; - typedef typename iterator_traits::iterator_category iterator_category; + typedef typename ETLSTD::iterator_traits::difference_type difference_type; + typedef typename ETLSTD::iterator_traits::value_type value_type; + typedef typename ETLSTD::iterator_traits::pointer pointer; + typedef typename ETLSTD::iterator_traits::reference reference; + typedef typename ETLSTD::iterator_traits::iterator_category iterator_category; reverse_iterator() { diff --git a/include/etl/stl/alternate/limits.h b/include/etl/stl/alternate/limits.h index 680cf7f9..231d7736 100644 --- a/include/etl/stl/alternate/limits.h +++ b/include/etl/stl/alternate/limits.h @@ -43,11 +43,15 @@ SOFTWARE. #define ETL_LOG2(x) (((x) * 301) / 1000) #if defined(ETL_IN_UNIT_TEST) -#define ETLSTD etlstd -namespace etlstd + #if !defined(ETLSTD) + #define ETLSTD etlstd + #endif + namespace etlstd #else -#define ETLSTD std -namespace std + #if !defined(ETLSTD) + #define ETLSTD std + #endif + namespace std #endif { template class numeric_limits; diff --git a/include/etl/stl/alternate/utility.h b/include/etl/stl/alternate/utility.h index 4fe77726..947b9109 100644 --- a/include/etl/stl/alternate/utility.h +++ b/include/etl/stl/alternate/utility.h @@ -32,14 +32,17 @@ SOFTWARE. #define ETL_STL_ALTERNATE_UTILITY_INCLUDED #include "../../platform.h" -#include "algorithm.h" #if defined(ETL_IN_UNIT_TEST) -#define ETLSTD etlstd -namespace etlstd + #if !defined(ETLSTD) + #define ETLSTD etlstd + #endif + namespace etlstd #else -#define ETLSTD std -namespace std + #if !defined(ETLSTD) + #define ETLSTD std + #endif + namespace std #endif { //****************************************************************************** @@ -79,8 +82,12 @@ namespace std void swap(pair& other) { - ETLSTD::swap(first, other.first); - ETLSTD::swap(second, other.second); + T1 temp1 = first; + T2 temp2 = second; + first = other.first; + second = other.second; + other.first = temp1; + other.second = temp2; } }; diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index 090872e2..e66e4acd 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -337,6 +337,7 @@ + diff --git a/test/no_stl_test_iterators.h b/test/no_stl_test_iterators.h new file mode 100644 index 00000000..69def7fc --- /dev/null +++ b/test/no_stl_test_iterators.h @@ -0,0 +1,206 @@ +///\file + +/****************************************************************************** +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_NO_STL_TEST_ITERATORS_INCLUDED +#define ETL_NO_STL_TEST_ITERATORS_INCLUDED + +#include "etl/stl/alternate/iterator.h" + +template +struct non_random_iterator : public etlstd::iterator +{ + non_random_iterator() + : ptr(nullptr) + { + } + + non_random_iterator(T* v) + : ptr(v) + { + } + + non_random_iterator(const non_random_iterator& other) + { + ptr = other.ptr; + } + + T& operator *() + { + return *ptr; + } + + const T& operator *() const + { + return *ptr; + } + + non_random_iterator& operator ++() + { + ++ptr; + return *this; + } + + non_random_iterator operator ++(int) + { + T* temp = ptr; + ++ptr; + return non_random_iterator(temp); + } + + non_random_iterator& operator --() + { + --ptr; + return *this; + } + + non_random_iterator operator --(int) + { + T* temp = ptr; + --ptr; + return non_random_iterator(temp); + } + + non_random_iterator& operator =(T* other) + { + ptr = other; + return *this; + } + + operator T*() + { + return ptr; + } + + operator const T*() + { + return ptr; + } + + T* ptr; +}; + +template +bool operator !=(const non_random_iterator& lhs, const non_random_iterator& rhs) +{ + return lhs.ptr != rhs.ptr; +} + +template +struct random_iterator : public etlstd::iterator +{ + random_iterator() + : ptr(nullptr) + { + } + + random_iterator(T* v) + : ptr(v) + { + } + + random_iterator(const random_iterator& other) + { + ptr = other.ptr; + } + + T& operator *() + { + return *ptr; + } + + const T& operator *() const + { + return *ptr; + } + + random_iterator& operator ++() + { + ++ptr; + return *this; + } + + random_iterator operator ++(int) + { + T* temp = ptr; + ++ptr; + return random_iterator(temp); + } + + random_iterator& operator --() + { + --ptr; + return *this; + } + + random_iterator operator --(int) + { + T* temp = ptr; + --ptr; + return random_iterator(temp); + } + + random_iterator& operator +=(int n) + { + ptr += n; + return *this; + } + + random_iterator& operator -=(int n) + { + ptr -= n; + return *this; + } + + random_iterator& operator =(T* other) + { + ptr = other; + return *this; + } + + operator T*() + { + return ptr; + } + + operator const T*() + { + return ptr; + } + + T* ptr; +}; + +template +ptrdiff_t operator -(const random_iterator& lhs, const random_iterator& rhs) +{ + return lhs.ptr - rhs.ptr; +} + +#endif \ No newline at end of file diff --git a/test/test_no_stl_algorithm.cpp b/test/test_no_stl_algorithm.cpp index 23ae4ef9..3a7d7442 100644 --- a/test/test_no_stl_algorithm.cpp +++ b/test/test_no_stl_algorithm.cpp @@ -37,15 +37,19 @@ SOFTWARE. #include #include +#include "no_stl_test_iterators.h" + namespace { - int dataEQ[10] = { 1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }; + const size_t SIZE = 10; + + int dataEQ[SIZE] = { 1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }; std::list dataEQL = { 1, 1, 3, 3, 5, 5, 7, 7, 9, 9 }; - int dataS[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + int dataS[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; std::list dataSL = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; - int dataA[10] = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; + int dataA[SIZE] = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; typedef std::vector Vector; Vector dataV = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; @@ -112,48 +116,6 @@ namespace SUITE(test_no_stl_algorithm) { - //************************************************************************* - TEST(distance_non_random) - { - ptrdiff_t d1 = std::distance(dataL.begin(), dataL.end()); - ptrdiff_t d2 = etlstd::distance(dataL.begin(), dataL.end()); - - CHECK_EQUAL(d1, d2); - } - - //************************************************************************* - TEST(distance_random) - { - ptrdiff_t d1 = std::distance(dataV.begin(), dataV.end()); - ptrdiff_t d2 = etlstd::distance(dataV.begin(), dataV.end()); - - CHECK_EQUAL(d1, d2); - } - - //************************************************************************* - TEST(advance_non_random) - { - List::const_iterator itr1 = dataL.begin(); - List::const_iterator itr2 = dataL.begin(); - - std::advance(itr1, 4); - std::advance(itr2, 4); - - CHECK_EQUAL(*itr1, *itr2); - } - - //************************************************************************* - TEST(advance_random) - { - Vector::const_iterator itr1 = dataV.begin(); - Vector::const_iterator itr2 = dataV.begin(); - - std::advance(itr1, 4); - std::advance(itr2, 4); - - CHECK_EQUAL(*itr1, *itr2); - } - //************************************************************************* TEST(min) { @@ -317,7 +279,7 @@ namespace for (int i = 0; i < 11; ++i) { int* lb1 = std::lower_bound(std::begin(dataS), std::end(dataS), i); - int* lb2 = etlstd::lower_bound(std::begin(dataS), std::end(dataS), i); + int* lb2 = etlstd::lower_bound(random_iterator(std::begin(dataS)), random_iterator(std::end(dataS)), i); CHECK_EQUAL(lb1, lb2); } @@ -328,10 +290,10 @@ namespace { for (int i = 0; i < 11; ++i) { - std::list::iterator lb1 = std::lower_bound(std::begin(dataSL), std::end(dataSL), i); - std::list::iterator lb2 = etlstd::lower_bound(std::begin(dataSL), std::end(dataSL), i); + int* lb1 = std::lower_bound(std::begin(dataS), std::end(dataS), i); + int* lb2 = etlstd::lower_bound(non_random_iterator(std::begin(dataS)), non_random_iterator(std::end(dataS)), i); - CHECK_EQUAL(std::distance(std::begin(dataSL), lb1), std::distance(std::begin(dataSL), lb2)); + CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } } @@ -341,7 +303,7 @@ namespace for (int i = 0; i < 11; ++i) { int* lb1 = std::upper_bound(std::begin(dataS), std::end(dataS), i); - int* lb2 = etlstd::upper_bound(std::begin(dataS), std::end(dataS), i); + int* lb2 = etlstd::upper_bound(random_iterator(std::begin(dataS)), random_iterator(std::end(dataS)), i); CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } @@ -352,10 +314,10 @@ namespace { for (int i = 0; i < 11; ++i) { - std::list::iterator lb1 = std::upper_bound(std::begin(dataSL), std::end(dataSL), i); - std::list::iterator lb2 = etlstd::upper_bound(std::begin(dataSL), std::end(dataSL), i); + int* lb1 = std::upper_bound(std::begin(dataS), std::end(dataS), i); + int* lb2 = etlstd::upper_bound(non_random_iterator(std::begin(dataS)), non_random_iterator(std::end(dataS)), i); - CHECK_EQUAL(std::distance(std::begin(dataSL), lb1), std::distance(std::begin(dataSL), lb2)); + CHECK_EQUAL(std::distance(std::begin(dataS), lb1), std::distance(std::begin(dataS), lb2)); } } @@ -364,11 +326,11 @@ namespace { for (int i = 0; i < 11; ++i) { - std::pair lb1 = std::equal_range(std::begin(dataEQ), std::end(dataEQ), i); - std::pair lb2 = etlstd::equal_range(std::begin(dataEQ), std::end(dataEQ), i); + std::pair lb1 = std::equal_range(std::begin(dataEQ), std::end(dataEQ), i); + etlstd::pair, random_iterator> lb2 = etlstd::equal_range(random_iterator(std::begin(dataEQ)), random_iterator(std::end(dataEQ)), i); - CHECK_EQUAL(std::distance(std::begin(dataEQ), lb1.first), std::distance(std::begin(dataEQ), lb2.first)); - CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); + CHECK_EQUAL(std::distance(std::begin(dataEQ), lb1.first), std::distance(std::begin(dataEQ), lb2.first)); + CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); } } @@ -377,11 +339,11 @@ namespace { for (int i = 0; i < 11; ++i) { - std::pair::iterator, std::list::iterator> lb1 = std::equal_range(std::begin(dataEQL), std::end(dataEQL), i); - std::pair::iterator, std::list::iterator> lb2 = etlstd::equal_range(std::begin(dataEQL), std::end(dataEQL), i); + std::pair lb1 = std::equal_range(std::begin(dataEQ), std::end(dataEQ), i); + etlstd::pair, non_random_iterator> lb2 = etlstd::equal_range(non_random_iterator(std::begin(dataEQ)), non_random_iterator(std::end(dataEQ)), i); - CHECK_EQUAL(std::distance(std::begin(dataEQL), lb1.first), std::distance(std::begin(dataEQL), lb2.first)); - CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); + CHECK_EQUAL(std::distance(std::begin(dataEQ), lb1.first), std::distance(std::begin(dataEQ), lb2.first)); + CHECK_EQUAL(std::distance(lb1.first, lb1.second), std::distance(lb2.first, lb2.second)); } } @@ -577,5 +539,57 @@ namespace isEqual = std::equal(std::begin(data1), std::end(data1), std::begin(data2)); CHECK(isEqual); } + + //************************************************************************* + TEST(find) + { + int* itr1 = std::find(std::begin(dataA), std::end(dataA), 5); + int* itr2 = etlstd::find(std::begin(dataA), std::end(dataA), 5); + + CHECK(itr1 == itr2); + } + + //************************************************************************* + TEST(find_if) + { + struct predicate + { + bool operator()(int i) const + { + return (i == 5); + } + }; + + int* itr1 = std::find_if(std::begin(dataA), std::end(dataA), predicate()); + int* itr2 = etlstd::find_if(std::begin(dataA), std::end(dataA), predicate()); + + CHECK(itr1 == itr2); + } + + //************************************************************************* + TEST(count) + { + size_t c1 = std::count(std::begin(dataEQ), std::end(dataEQ), 5); + size_t c2 = etlstd::count(std::begin(dataEQ), std::end(dataEQ), 5); + + CHECK(c1 == c2); + } + + //************************************************************************* + TEST(count_if) + { + struct predicate + { + bool operator()(int i) const + { + return (i == 5); + } + }; + + size_t c1 = std::count_if(std::begin(dataEQ), std::end(dataEQ), predicate()); + size_t c2 = etlstd::count_if(std::begin(dataEQ), std::end(dataEQ), predicate()); + + CHECK(c1 == c2); + } }; } diff --git a/test/test_no_stl_iterator.cpp b/test/test_no_stl_iterator.cpp new file mode 100644 index 00000000..74edfd1b --- /dev/null +++ b/test/test_no_stl_iterator.cpp @@ -0,0 +1,96 @@ +/****************************************************************************** +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" + +#undef min +#undef max + +#include "etl/stl/alternate/iterator.h" + +#include +#include +#include + +#include "no_stl_test_iterators.h" + +namespace +{ + const size_t SIZE = 10; + + int dataA[SIZE] = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 }; + + SUITE(test_no_stl_iterator) + { + //************************************************************************* + TEST(distance_non_random) + { + ptrdiff_t d = etlstd::distance(non_random_iterator(&dataA[0]), non_random_iterator(&dataA[SIZE])); + + CHECK_EQUAL(SIZE, d); + } + + //************************************************************************* + TEST(distance_random) + { + ptrdiff_t d = etlstd::distance(random_iterator(&dataA[0]), random_iterator(&dataA[SIZE])); + + CHECK_EQUAL(SIZE, d); + } + + //************************************************************************* + TEST(advance_non_random) + { + int* itr1 = std::begin(dataA); + non_random_iterator itr2 = std::begin(dataA); + + std::advance(itr1, 4); + etlstd::advance(itr2, 4); + CHECK_EQUAL(*itr1, *itr2); + + std::advance(itr1, -3); + etlstd::advance(itr2, -3); + CHECK_EQUAL(*itr1, *itr2); + } + + //************************************************************************* + TEST(advance_random) + { + int* itr1 = std::begin(dataA); + random_iterator itr2 = std::begin(dataA); + + std::advance(itr1, 4); + etlstd::advance(itr2, 4); + CHECK_EQUAL(*itr1, *itr2); + + std::advance(itr1, -3); + etlstd::advance(itr2, -3); + CHECK_EQUAL(*itr1, *itr2); + } + }; +} diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index e304e478..5ae6cd62 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -525,6 +525,7 @@ + @@ -688,6 +689,7 @@ + diff --git a/test/vs2017/etl.vcxproj.filters b/test/vs2017/etl.vcxproj.filters index 6ad8cfc2..26a9da1d 100644 --- a/test/vs2017/etl.vcxproj.filters +++ b/test/vs2017/etl.vcxproj.filters @@ -687,6 +687,9 @@ ETL\Maths + + Source Files + @@ -1127,6 +1130,9 @@ Source Files + + Source Files +