From d7ab20817e43bd18a3eaf13a62f3e9965e504ef1 Mon Sep 17 00:00:00 2001 From: Aregtech Date: Tue, 10 Dec 2024 19:49:54 +0100 Subject: [PATCH] Added sorting method for containers. Added unit tests. --- framework/areg/base/TEArrayList.hpp | 59 +++++++--- framework/areg/base/TEFixedArray.hpp | 60 ++++++++++ framework/areg/base/TEHashMap.hpp | 60 ++++++++++ framework/areg/base/TELinkedList.hpp | 64 +++++++++++ framework/areg/base/TEMap.hpp | 74 +++++++++++++ framework/areg/base/TESortedLinkedList.hpp | 32 +++++- framework/areg/base/TEStack.hpp | 103 +++++++++++++++++- .../console/private/OptionParser.cpp | 10 +- tests/units/TEArrayListTest.cpp | 38 +++++++ tests/units/TEFixedArrayTest.cpp | 38 +++++++ tests/units/TEHashMapTest.cpp | 14 +++ tests/units/TELinkedListTest.cpp | 38 +++++++ tests/units/TEStackTest.cpp | 38 +++++++ 13 files changed, 602 insertions(+), 26 deletions(-) diff --git a/framework/areg/base/TEArrayList.hpp b/framework/areg/base/TEArrayList.hpp index 14f5c061..559a619f 100644 --- a/framework/areg/base/TEArrayList.hpp +++ b/framework/areg/base/TEArrayList.hpp @@ -185,15 +185,6 @@ class TEArrayList : private Constless> template friend IEOutStream & operator << (IEOutStream & stream, const TEArrayList< V > & output); - /** - * \brief Sorts the array, compares the elements by given Compare functionality. - * \param list Array object to sort. - * \param comp The comparing method, similar to the method std::greater() - * \return Sorts and returns the 'list' object. - **/ - template - friend TEArrayList< V >& sortArray(TEArrayList< V >& list, Compare comp); - ////////////////////////////////////////////////////////////////////////// // Attributes ////////////////////////////////////////////////////////////////////////// @@ -424,6 +415,28 @@ class TEArrayList : private Constless> inline const VALUE & lastEntry( void ) const; inline VALUE & lastEntry( void ); + /** + * \brief Sorts the array, compares the elements by given Compare functionality. + * \param comp The comparing method, similar to the method std::greater() + * \return Sorts and returns the array object. + **/ + template + inline TEArrayList< VALUE >& sort(Compare comp); + + /** + * \brief Copies elements from the array into the provided pre-allocated buffer. + * If `elemCount` is less than the number of elements in the array, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the array are copied. No elements are copied if `elemCount` is 0. + * \param list [in, out] A pre-allocated buffer where the array elements + * will be copied. Must be large enough to hold at least + * `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the `list` buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied into the `list` buffer. + **/ + inline uint32_t getElements(VALUE* list, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Protected operations ////////////////////////////////////////////////////////////////////////// @@ -1068,6 +1081,26 @@ inline VALUE & TEArrayList::lastEntry( void ) return mValueList[ mValueList.size( ) - 1 ]; } +template +template +inline TEArrayList& TEArrayList::sort(Compare comp) +{ + std::sort(mValueList.begin(), mValueList.end(), comp); + return (*this); +} + +template +inline uint32_t TEArrayList::getElements(VALUE* list, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount) }; + for (uint32_t i = 0; i < result; ++i) + { + list[i] = mValueList[i]; + } + + return result; +} + template inline void TEArrayList< VALUE >::setSize(uint32_t elemCount) { @@ -1119,11 +1152,5 @@ IEOutStream & operator << ( IEOutStream& stream, const TEArrayList< V >& output return stream; } -template -TEArrayList< V >& sortArray(TEArrayList< V >& list, Compare comp) -{ - std::sort(list.mValueList.begin(), list.mValueList.end(), comp); - return list; -} - #endif // AREG_BASE_TEARRAYLIST_HPP + diff --git a/framework/areg/base/TEFixedArray.hpp b/framework/areg/base/TEFixedArray.hpp index 31336b04..f24e573d 100644 --- a/framework/areg/base/TEFixedArray.hpp +++ b/framework/areg/base/TEFixedArray.hpp @@ -89,6 +89,12 @@ class TEFixedArray * \param src The source to move data. **/ TEFixedArray( TEFixedArray && src ) noexcept; + /** + * \brief Compiles entries from the given array of objects. + * \param list The list of entries to copy. + * \param count The number of entries in the array. + **/ + TEFixedArray(const VALUE* list, uint32_t count); /** * \brief Destructor. **/ @@ -289,6 +295,28 @@ class TEFixedArray inline const VALUE & lastEntry( void ) const; inline VALUE & lastEntry( void ); + /** + * \brief Sorts the array, compares the elements by given Compare functionality. + * \param comp The comparing method, similar to the method std::greater() + * \return Sorts and returns the fixed array object. + **/ + template + inline TEFixedArray< VALUE >& sort(Compare comp); + + /** + * \brief Copies elements from the array into the provided pre-allocated buffer. + * If `elemCount` is less than the number of elements in the array, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the array are copied. No elements are copied if `elemCount` is 0 + * \param list [in, out] A pre-allocated buffer where the array elements + * will be copied. Must be large enough to hold at least + * `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the `list` buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied into the `list` buffer. + **/ + inline uint32_t getElements(VALUE* list, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Protected member variables ////////////////////////////////////////////////////////////////////////// @@ -335,6 +363,14 @@ TEFixedArray::TEFixedArray( TEFixedArray && src ) noexcept src.mElemCount = 0; } +template +TEFixedArray::TEFixedArray(const VALUE* list, uint32_t count) + : mValueList(count ? DEBUG_NEW VALUE[count] : nullptr) + , mElemCount(mValueList != nullptr ? count : 0) +{ + NEMemory::copyElems(mValueList, list, mElemCount); +} + template< typename VALUE > TEFixedArray::~TEFixedArray( void ) { @@ -555,6 +591,30 @@ inline VALUE & TEFixedArray::lastEntry( void ) return mValueList[ mElemCount - 1 ]; } +template +template +inline TEFixedArray& TEFixedArray::sort(Compare comp) +{ + if (mValueList != nullptr) + { + std::sort(mValueList, mValueList + mElemCount, comp); + } + + return (*this); +} + +template +inline uint32_t TEFixedArray::getElements(VALUE* list, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(mElemCount, elemCount) }; + for (uint32_t i = 0; i < result; ++i) + { + list[i] = mValueList[i]; + } + + return result; +} + ////////////////////////////////////////////////////////////////////////// // Friend function implementation ////////////////////////////////////////////////////////////////////////// diff --git a/framework/areg/base/TEHashMap.hpp b/framework/areg/base/TEHashMap.hpp index effa9889..d7822932 100644 --- a/framework/areg/base/TEHashMap.hpp +++ b/framework/areg/base/TEHashMap.hpp @@ -108,6 +108,17 @@ class TEHashMap : protected Constless> **/ TEHashMap( TEHashMap && src ) noexcept = default; + /** + * \brief Compiles entries from the given array of keys and values, + * where the amount of key and value entries are equal. + * If any key is repeating in the list, it will be replaced by new value. + * The number of entries in the hash-map is equal to 'count' only if all keys are unique. + * \param keys The list of keys to copy. + * \param values The list of values to pair with keys. + * \param count The number of entries in the key and value entries. + **/ + TEHashMap(const KEY* keys, const VALUE * values, uint32_t count); + /** * \brief Destructor. **/ @@ -487,6 +498,21 @@ class TEHashMap : protected Constless> **/ inline bool nextEntry(MAPPOS & IN OUT in_out_NextPosition, KEY & OUT out_NextKey, VALUE & OUT out_NextValue ) const; + /** + * \brief Copies elements from the hash-map into the provided pre-allocated buffer of keys and values. + * If `elemCount` is less than the number of elements in the hash-map, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the hash-map are copied. No elements are copied if `elemCount` is 0. + * \param keys [in, out] A pre-allocated buffer where the keys of the hash-map elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param values [in, out] A pre-allocated buffer where the values of the hash-map elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the keys and values buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied. + **/ + inline uint32_t getElements(KEY * keys, VALUE * values, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// //Hidden methods ////////////////////////////////////////////////////////////////////////// @@ -524,6 +550,18 @@ TEHashMap::TEHashMap(uint32_t hashSize /* = NECommon::MAP_DEFAULT_HA { } +template +TEHashMap::TEHashMap(const KEY* keys, const VALUE* values, uint32_t count) + : Constless>() + , mValueList() +{ + mValueList.reserve(count); + for (uint32_t i = 0; i < count; ++i) + { + mValueList[keys[i]] = values[i]; + } +} + template < typename KEY, typename VALUE > inline bool TEHashMap::operator == (const TEHashMap& other) const { @@ -941,6 +979,28 @@ inline bool TEHashMap::nextEntry(TEHashMap::MAPPOS & IN return result; } +template +inline uint32_t TEHashMap::getElements(KEY* keys, VALUE* values, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount)}; + if (result > 0) + { + uint32_t i = 0; + for (const auto & elem : mValueList) + { + keys[i] = elem.first; + values[i] = elem.second; + + if (++i == result) + { + break; + } + } + } + + return result; +} + template inline typename TEHashMap::MAPPOS TEHashMap::_citer2pos(typename std::unordered_map::const_iterator cit) const { diff --git a/framework/areg/base/TELinkedList.hpp b/framework/areg/base/TELinkedList.hpp index 635c4872..9cefa6c2 100644 --- a/framework/areg/base/TELinkedList.hpp +++ b/framework/areg/base/TELinkedList.hpp @@ -77,6 +77,13 @@ class TELinkedList : private Constless> **/ TELinkedList( TELinkedList && src ) noexcept = default; + /** + * \brief Compiles entries from the given array of objects. + * \param list The list of entries to copy. + * \param count The number of entries in the array. + **/ + TELinkedList(const VALUE* list, uint32_t count); + /** * \brief Destructor. **/ @@ -579,6 +586,27 @@ class TELinkedList : private Constless> inline void merge(TELinkedList & source); inline void merge(TELinkedList && source); + /** + * \brief Sorts the linked list, compares the elements by given Compare functionality. + * \param comp The comparing method, similar to the method std::greater() + * \return Sorts and returns the linked list object. + **/ + template + inline TELinkedList< VALUE >& sort(Compare comp); + + /** + * \brief Copies elements from the linked list into the provided pre-allocated buffer. + * If `elemCount` is less than the number of elements in the linked list, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the linked list are copied. No elements are copied if `elemCount` is 0. + * \param list [in, out] A pre-allocated buffer where the linked list elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the `list` buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied into the `list` buffer. + **/ + inline uint32_t getElements(VALUE* list, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Protected methods ////////////////////////////////////////////////////////////////////////// @@ -616,6 +644,17 @@ class TELinkedList : private Constless> // TELinkedList class template implementation ////////////////////////////////////////////////////////////////////////// +template +TELinkedList::TELinkedList(const VALUE* list, uint32_t count) + : Constless>() + , mValueList() +{ + for (uint32_t i = 0; i < count; ++i) + { + mValueList.push_back(list[i]); + } +} + template inline TELinkedList& TELinkedList::operator = (const TELinkedList& src) { @@ -1218,6 +1257,23 @@ inline void TELinkedList::merge(TELinkedList&& source) mValueList.merge(std::move(source.mValueList)); } +template +inline uint32_t TELinkedList::getElements(VALUE* list, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount) }; + uint32_t i = 0; + for (const auto& entry : mValueList) + { + list[i++] = entry; + if (i == result) + { + break; + } + } + + return result; +} + template inline typename TELinkedList::LISTPOS TELinkedList::getPosition(uint32_t index) const { @@ -1230,6 +1286,14 @@ inline typename TELinkedList::LISTPOS TELinkedList::getPosition(ui return _citer2pos(pos); } +template +template +inline TELinkedList& TELinkedList::sort(Compare comp) +{ + mValueList.sort(comp); + return (*this); +} + template inline typename TELinkedList::LISTPOS TELinkedList::_citer2pos(typename std::list::const_iterator cit) const { diff --git a/framework/areg/base/TEMap.hpp b/framework/areg/base/TEMap.hpp index 8099d0ea..ab39e7a2 100644 --- a/framework/areg/base/TEMap.hpp +++ b/framework/areg/base/TEMap.hpp @@ -26,6 +26,7 @@ #include "areg/base/NEMemory.hpp" #include +#include ////////////////////////////////////////////////////////////////////////// // TEMap class template declaration @@ -87,6 +88,12 @@ class TEMap : protected Constless< std::map > **/ TEMap( void ) = default; + /** + * \brief Creates empty map and using comparison function object 'comp'. + **/ + template + TEMap(Compare comp); + /** * \brief Copies entries from given source. * \param src The source to copy data. @@ -99,6 +106,17 @@ class TEMap : protected Constless< std::map > **/ TEMap( TEMap && src ) noexcept = default; + /** + * \brief Compiles entries from the given array of keys and values, + * where the amount of key and value entries are equal. + * If any key is repeating in the list, it will be replaced by new value. + * The number of entries in the map is equal to 'count' only if all keys are unique. + * \param keys The list of keys to copy. + * \param values The list of values to pair with keys. + * \param count The number of entries in the key and value entries. + **/ + TEMap(const KEY* keys, const VALUE* values, uint32_t count); + /** * \brief Destructor. **/ @@ -479,6 +497,21 @@ class TEMap : protected Constless< std::map > **/ inline bool nextEntry(MAPPOS & IN OUT in_out_NextPosition, KEY & OUT out_NextKey, VALUE & OUT out_NextValue ) const; + /** + * \brief Copies elements from the map into the provided pre-allocated buffer of keys and values. + * If `elemCount` is less than the number of elements in the map, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the map are copied. No elements are copied if `elemCount` is 0. + * \param keys [in, out] A pre-allocated buffer where the keys of the map elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param values [in, out] A pre-allocated buffer where the values of the map elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the keys and values buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied. + **/ + inline uint32_t getElements(KEY * keys, VALUE * values, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Member Variables ////////////////////////////////////////////////////////////////////////// @@ -497,6 +530,25 @@ class TEMap : protected Constless< std::map > // TEMap class template Implement ////////////////////////////////////////////////////////////////////////// +template +template +inline TEMap::TEMap(Compare comp) + : Constless< std::map >() + , mValueList(static_cast::key_compare>(comp)) +{ +} + +template +TEMap::TEMap(const KEY* keys, const VALUE* values, uint32_t count) + : Constless< std::map >() + , mValueList() +{ + for (uint32_t i = 0; i < count; ++i) + { + mValueList[keys[i]] = values[i]; + } +} + template < typename KEY, typename VALUE > inline bool TEMap::operator == (const TEMap& other) const { @@ -911,6 +963,28 @@ inline bool TEMap::nextEntry(TEMap::MAPPOS & IN OUT in_o return result; } +template +inline uint32_t TEMap::getElements(KEY* keys, VALUE* values, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount) }; + if (result > 0) + { + uint32_t i = 0; + for (const auto& elem : mValueList) + { + keys[i] = elem.first; + values[i] = elem.second; + + if (++i == result) + { + break; + } + } + } + + return result; +} + ////////////////////////////////////////////////////////////////////////// // TEMap class friend methods ////////////////////////////////////////////////////////////////////////// diff --git a/framework/areg/base/TESortedLinkedList.hpp b/framework/areg/base/TESortedLinkedList.hpp index 6565fdbf..5e5d9db6 100644 --- a/framework/areg/base/TESortedLinkedList.hpp +++ b/framework/areg/base/TESortedLinkedList.hpp @@ -550,11 +550,24 @@ class TESortedLinkedList : private Constless> * The elements from `*this` always precede the elements from `source`, * and the order of elements do not change, which means that the order * of elements in the result list remain either ascending or descending. - * \param source The source of linked list to merge. + * \param source The source of sorted linked list to merge. **/ inline void merge(TESortedLinkedList & source); inline void merge(TESortedLinkedList && source); + /** + * \brief Copies elements from the sorted linked list into the provided pre-allocated buffer. + * If `elemCount` is less than the number of elements in the sorted linked list, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the sorted linked list are copied. No elements are copied if `elemCount` is 0. + * \param list [in, out] A pre-allocated buffer where the sorted linked list elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the `list` buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied into the `list` buffer. + **/ + inline uint32_t getElements(VALUE* list, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Protected methods ////////////////////////////////////////////////////////////////////////// @@ -1158,6 +1171,23 @@ inline void TESortedLinkedList::merge(TESortedLinkedList&& source) } } +template +inline uint32_t TESortedLinkedList::getElements(VALUE* list, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount) }; + uint32_t i = 0; + for (const auto& entry : mValueList) + { + list[i++] = entry; + if (i == result) + { + break; + } + } + + return result; +} + template inline typename TESortedLinkedList::LISTPOS TESortedLinkedList::getPosition(uint32_t index) const { diff --git a/framework/areg/base/TEStack.hpp b/framework/areg/base/TEStack.hpp index 68e6f337..15b92ef7 100644 --- a/framework/areg/base/TEStack.hpp +++ b/framework/areg/base/TEStack.hpp @@ -89,6 +89,14 @@ class TEStack : private Constless> **/ TEStack( IEResourceLock & synchObject, TEStack && source ) noexcept; + /** + * \brief Compiles entries from the given array of objects. + * \param synchObject The instance of synchronization object + * \param list The list of entries to copy. + * \param count The number of entries in the array. + **/ + TEStack(IEResourceLock& synchObject, const VALUE* list, uint32_t count); + /** * \brief Destructor. Public **/ @@ -219,7 +227,7 @@ class TEStack : private Constless> inline bool checkPosition(const STACKPOS pos) const; /** - * \brief Checks whether given element exist in the linked list or not. The elements of type + * \brief Checks whether given element exist in the stack or not. The elements of type * VALUE should have comparing operators. * \param elemSearch The element to search. * \return Returns true if could find element starting at given position. @@ -227,7 +235,7 @@ class TEStack : private Constless> inline bool contains(const VALUE& elemSearch) const; /** - * \brief Checks whether given element exist in the linked list or not. The elements of type + * \brief Checks whether given element exist in the stack or not. The elements of type * VALUE should have comparing operators. * \param elemSearch The element to search. * \param startAt The position to start searching. @@ -354,7 +362,7 @@ class TEStack : private Constless> * to search at the beginning of stack. * \param Value The element value to search in the stack. * \param searchAfter If valid position, the searching starts from next element specified by position. - * If invalid position, the searching starts from the beginning of the linked list. + * If invalid position, the searching starts from the beginning of the stack. * \return If found element, returns valid position. Otherwise, it returns invalid position. **/ inline STACKPOS find(const VALUE& Value, STACKPOS searchAfter) const; @@ -375,7 +383,7 @@ class TEStack : private Constless> /** * \brief Returns value of element at the give position. - * \param atPosition The valid position in Linked List + * \param atPosition The valid position in stack **/ inline const VALUE& valueAtPosition( const STACKPOS atPosition ) const; inline VALUE& valueAtPosition( STACKPOS atPosition ); @@ -389,6 +397,27 @@ class TEStack : private Constless> **/ inline STACKPOS nextPosition( STACKPOS pos ) const; + /** + * \brief Sorts the stack, compares the elements by given Compare functionality. + * \param comp The comparing method, similar to the method std::greater() + * \return Sorts and returns the Stack object. + **/ + template + inline TEStack< VALUE >& sort(Compare comp); + + /** + * \brief Copies elements from the stack into the provided pre-allocated buffer. + * If `elemCount` is less than the number of elements in the stack, + * only the first `elemCount` elements are copied. Otherwise, all elements + * in the stack are copied. No elements are copied if `elemCount` is 0. + * \param list [in, out] A pre-allocated buffer where the stack elements will be copied. + * Must be large enough to hold at least `elemCount` elements. + * \param elemCount [in] The maximum number of elements to copy into the `list` buffer. + * If set to 0, no elements are copied. + * \return The number of elements successfully copied into the `list` buffer. + **/ + inline uint32_t getElements(VALUE* list, uint32_t elemCount); + ////////////////////////////////////////////////////////////////////////// // Member variables ////////////////////////////////////////////////////////////////////////// @@ -452,6 +481,13 @@ class TELockStack : public TEStack **/ TELockStack( TELockStack && source ) noexcept; + /** + * \brief Compiles entries from the given array of objects. + * \param list The list of entries to copy. + * \param count The number of entries in the array. + **/ + TELockStack(const VALUE* list, uint32_t count); + /** * \brief Destructor **/ @@ -548,6 +584,13 @@ class TENolockStack : public TEStack **/ TENolockStack( TENolockStack && source ) noexcept; + /** + * \brief Compiles entries from the given array of objects. + * \param list The list of entries to copy. + * \param count The number of entries in the array. + **/ + TENolockStack(const VALUE* list, uint32_t count); + /** * \brief Destructor **/ @@ -635,6 +678,19 @@ TEStack::TEStack( IEResourceLock & synchObject, TEStack && source mValueList = std::move(source.mValueList); } +template +TEStack::TEStack(IEResourceLock& synchObject, const VALUE* list, uint32_t count) + : Constless>() + , mValueList() + , mSynchObject(synchObject) +{ + mValueList.resize(count); + for (uint32_t i = 0; i < count; ++i) + { + mValueList[i] = list[i]; + } +} + template TEStack::~TEStack( void ) { @@ -952,6 +1008,31 @@ inline typename TEStack::STACKPOS TEStack::nextPosition( STACKPOS return (++pos); } +template +inline uint32_t TEStack::getElements(VALUE* list, uint32_t elemCount) +{ + uint32_t result{ MACRO_MIN(static_cast(mValueList.size()), elemCount) }; + uint32_t i = 0; + for (const auto& entry : mValueList) + { + list[i++] = entry; + if (i == result) + { + break; + } + } + + return result; +} + +template +template +inline TEStack& TEStack::sort(Compare comp) +{ + std::sort(mValueList.begin(), mValueList.end(), comp); + return (*this); +} + ////////////////////////////////////////////////////////////////////////// // TELockStack class template implementation ////////////////////////////////////////////////////////////////////////// @@ -991,6 +1072,13 @@ TELockStack::TELockStack( TELockStack && source ) noexcept { } +template +TELockStack::TELockStack(const VALUE* list, uint32_t count) + : TEStack(mLock, list, count) + , mLock() +{ +} + template inline TELockStack & TELockStack::operator = ( const TELockStack & source ) { @@ -1058,6 +1146,13 @@ TENolockStack::TENolockStack( TENolockStack && source ) noexcept { } +template +TENolockStack::TENolockStack(const VALUE* list, uint32_t count) + : TEStack(mNoLock, list, count) + , mNoLock() +{ +} + template inline TENolockStack & TENolockStack::operator = ( const TENolockStack & source ) { diff --git a/framework/aregextend/console/private/OptionParser.cpp b/framework/aregextend/console/private/OptionParser.cpp index 04ca40cf..ee851ac8 100644 --- a/framework/aregextend/console/private/OptionParser.cpp +++ b/framework/aregextend/console/private/OptionParser.cpp @@ -406,11 +406,11 @@ uint32_t OptionParser::findOption(int optId) const void OptionParser::sort(void) { - ::sortArray(mInputOptions, [](const OptionParser::sOption& opt1, const OptionParser::sOption& opt2) - { - return (opt1.inCommand > opt2.inCommand); - } - ); + mInputOptions.sort([](const OptionParser::sOption& opt1, const OptionParser::sOption& opt2) + { + // sort ascending + return (opt1.inCommand < opt2.inCommand); + }); } OptionParser::sOption OptionParser::_setupInput( bool isShort, String cmdLine, uint32_t refSetup ) diff --git a/tests/units/TEArrayListTest.cpp b/tests/units/TEArrayListTest.cpp index 4136fe2c..d5af599f 100644 --- a/tests/units/TEArrayListTest.cpp +++ b/tests/units/TEArrayListTest.cpp @@ -645,3 +645,41 @@ TEST(TEArrayListTest, TestStream) EXPECT_EQ(dst.getSize(), _len1); EXPECT_EQ(src, dst); } + +/** + * \brief Tests ascending sorting of array. + **/ +TEST(TEArrayListTest, TestSortAscending) +{ + using Array = TEArrayList; + + constexpr int _arr1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr int _res1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + Array arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 < elem2); }); + + EXPECT_NE(arr1, Array(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +} + +/** + * \brief Tests descending sorting of array. + **/ +TEST(TEArrayListTest, TestSortDescending) +{ + using Array = TEArrayList; + + constexpr int _arr1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr int _res1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + Array arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 > elem2); }); + + EXPECT_NE(arr1, Array(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +} diff --git a/tests/units/TEFixedArrayTest.cpp b/tests/units/TEFixedArrayTest.cpp index 9d3ffae8..5b8443ca 100644 --- a/tests/units/TEFixedArrayTest.cpp +++ b/tests/units/TEFixedArrayTest.cpp @@ -194,3 +194,41 @@ TEST(TEFixedArrayTest, TestElemPosition) EXPECT_EQ(notEmpty.firstEntry(), 0u); EXPECT_EQ(notEmpty.lastEntry(), elemCount - 1u); } + +/** + * \brief Tests ascending sorting of fixed array. + **/ +TEST(TEFixedArrayTest, TestSortAscending) +{ + using FixedArray = TEFixedArray; + + constexpr int _arr1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr int _res1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + FixedArray arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 < elem2); }); + + EXPECT_NE(arr1, FixedArray(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +} + +/** + * \brief Tests descending sorting of fixed array. + **/ +TEST(TEFixedArrayTest, TestSortDescending) +{ + using FixedArray = TEFixedArray; + + constexpr int _arr1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr int _res1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + FixedArray arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 > elem2); }); + + EXPECT_NE(arr1, FixedArray(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +} diff --git a/tests/units/TEHashMapTest.cpp b/tests/units/TEHashMapTest.cpp index 7e6bd748..292a22e0 100644 --- a/tests/units/TEHashMapTest.cpp +++ b/tests/units/TEHashMapTest.cpp @@ -59,6 +59,20 @@ TEST(TEHashMapTest, TestConstructors) EXPECT_TRUE(hashMap1.isEmpty()); EXPECT_EQ(hashMap3, hashMap4); EXPECT_EQ(hashMap1, hashMap2); + + // Step 3: initialize from array + constexpr int _keys[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + constexpr int _values[]{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_keys) }; + HashMap hashMap5(_keys, _values, _len); + + EXPECT_EQ(hashMap5.getSize(), _len); + + int _resKeys[_len]{ }; + int _resValues[_len]{ }; + hashMap5.getElements(_resKeys, _resValues, _len); + EXPECT_EQ(NEMemory::memCompare(_keys, _resKeys, _len), NEMath::eCompare::Equal); + EXPECT_EQ(NEMemory::memCompare(_values, _resValues, _len), NEMath::eCompare::Equal); } /** diff --git a/tests/units/TELinkedListTest.cpp b/tests/units/TELinkedListTest.cpp index 3acc0d99..e3ee3c1e 100644 --- a/tests/units/TELinkedListTest.cpp +++ b/tests/units/TELinkedListTest.cpp @@ -571,3 +571,41 @@ TEST(TELinkedListTest, TestStreaming) EXPECT_EQ(src, dst); } + +/** + * \brief Test TELinkedList streaming operators. + **/ +TEST(TELinkedListTest, TestSortAscending) +{ + using LinkedList = TELinkedList; + constexpr int _arr1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr int _res1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + int _dat1[_len]{}; + + LinkedList list1(_arr1, _len), res1(_res1, _len); + list1.sort([](const int elem1, const int elem2) { return (elem1 < elem2); }); + list1.getElements(_dat1, _len); + EXPECT_NE(NEMemory::memCompare(_dat1, _arr1, _len), NEMath::eCompare::Equal); + EXPECT_EQ(list1.getSize(), _len); + EXPECT_EQ(NEMemory::memCompare(_dat1, _res1, _len), NEMath::eCompare::Equal); +} + +/** + * \brief Test TELinkedList streaming operators. + **/ +TEST(TELinkedListTest, TestSortDescending) +{ + using LinkedList = TELinkedList; + constexpr int _arr1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr int _res1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + int _dat1[_len]{}; + + LinkedList list1(_arr1, _len), res1(_res1, _len); + list1.sort([](const int elem1, const int elem2) { return (elem1 > elem2); }); + list1.getElements(_dat1, _len); + EXPECT_NE(NEMemory::memCompare(_dat1, _arr1, _len), NEMath::eCompare::Equal); + EXPECT_EQ(list1.getSize(), _len); + EXPECT_EQ(NEMemory::memCompare(_dat1, _res1, _len), NEMath::eCompare::Equal); +} diff --git a/tests/units/TEStackTest.cpp b/tests/units/TEStackTest.cpp index 0e90afda..bcf06c38 100644 --- a/tests/units/TEStackTest.cpp +++ b/tests/units/TEStackTest.cpp @@ -453,3 +453,41 @@ TEST(TEStackTest, TestLockAndNolockStackStreaming) EXPECT_FALSE(nolock.isEmpty()); EXPECT_EQ(lock, nolock); } + +/** + * \brief Tests ascending sorting of stack. + **/ +TEST(TEStackTest, TestSortAscending) +{ + using Stack = TENolockStack; + + constexpr int _arr1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr int _res1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + Stack arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 < elem2); }); + + EXPECT_NE(arr1, Stack(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +} + +/** + * \brief Tests descending sorting of fixed array. + **/ +TEST(TEStackTest, TestSortDescending) +{ + using Stack = TENolockStack; + + constexpr int _arr1[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + constexpr int _res1[]{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + constexpr uint32_t _len{ MACRO_ARRAYLEN(_arr1) }; + + Stack arr1(_arr1, _len), res1(_res1, _len); + arr1.sort([](const int elem1, const int elem2) { return (elem1 > elem2); }); + + EXPECT_NE(arr1, Stack(_arr1, _len)); + EXPECT_EQ(arr1.getSize(), _len); + EXPECT_EQ(arr1, res1); +}