diff --git a/applications/test/FixedList/Test-FixedList.C b/applications/test/FixedList/Test-FixedList.C index c501b77bc4cf70cd10b8eec4a14f1907653d7a25..1e3703b2b818dc426358a684bff021aa0228087f 100644 --- a/applications/test/FixedList/Test-FixedList.C +++ b/applications/test/FixedList/Test-FixedList.C @@ -25,7 +25,7 @@ Application Test-FixedList Description - Simple tests and examples of use of FixedList + Simple tests and examples for FixedList See also Foam::FixedList @@ -42,47 +42,72 @@ See also using namespace Foam; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -// Main program: +template<class T, unsigned Size> +Ostream& printInfo(const FixedList<List<T>, Size>& list) +{ + Info<< list << " addresses:"; + for (unsigned i = 0; i < Size; ++i) + { + Info<< " " << long(list[i].cdata()); + } + Info<< nl; + return Info; +} -int main(int argc, char *argv[]) + +template<class T, unsigned Size> +Ostream& printInfo +( + const FixedList<List<T>, Size>& list1, + const FixedList<List<T>, Size>& list2 +) { - argList args(argc, argv); + Info<< "llist1:"; printInfo(list1); + Info<< "llist2:"; printInfo(list2); + return Info; +} - if (false) - { - FixedList<string, 1> ident; - auto iter = ident.begin(); +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: - Info << iter->size() << endl; +int main(int argc, char *argv[]) +{ + argList::addBoolOption("assign"); + argList::addBoolOption("iter"); + argList::addBoolOption("swap"); + argList::addBoolOption("default", "reinstate default tests"); + argList::addNote("runs default tests or specified ones only"); - auto riter = ident.rbegin(); - Info << riter->size() << endl; + #include "setRootCase.H" - auto iter2 = ident.rbegin(); + // Run default tests, unless only specific tests are requested + const bool defaultTests = + args.found("default") || args.options().empty(); - iter2 = iter; - } + if (defaultTests || args.found("iter")) { + Info<< nl + << "Test iterators" << nl; + FixedList<label, 15> ident; std::iota(ident.begin(), ident.end(), 0); // auto iter = ident.begin(); // // iter += 5; - // Info << *iter << "< " << endl; + // Info << *iter << "< " << nl; // iter -= 2; - // Info << *iter << "< " << endl; + // Info << *iter << "< " << nl; // Don't yet bother with making reverse iterators random access // auto riter = ident.crbegin(); // riter += 5; - // Info << *riter << "< " << endl; + // Info << *riter << "< " << nl; // riter += 2; - // Info << *riter << "< " << endl; + // Info << *riter << "< " << nl; Info<<"Ident:"; forAllConstIters(ident, iter) @@ -106,65 +131,121 @@ int main(int argc, char *argv[]) Info<< nl; } + if (defaultTests || args.found("swap")) { - FixedList<label, 4> list1{1, 2, 3, 4}; + Info<< nl + << "Test swap" << nl; + + FixedList<label, 4> list1{2, 3, 4, 5}; Info<< "list1:" << list1 - << " hash:" << FixedList<label, 4>::Hash<>()(list1) << endl; + << " hash:" << FixedList<label, 4>::Hash<>()(list1) << nl; label a[4] = {0, 1, 2, 3}; FixedList<label, 4> list2(a); Info<< "list2:" << list2 - << " hash:" << FixedList<label, 4>::Hash<>()(list2) << endl; + << " hash:" << FixedList<label, 4>::Hash<>()(list2) << nl; // Using FixedList for content too { List<FixedList<label, 4>> twolists{list1, list2}; - Info<<"List of FixedList: " << flatOutput(twolists) << endl; + Info<<"List of FixedList: " << flatOutput(twolists) << nl; sort(twolists); // outer-sort only - Info<<"sorted FixedList : " << flatOutput(twolists) << endl; + Info<<"sorted FixedList : " << flatOutput(twolists) << nl; } Info<< "====" << nl << "Test swap" << nl; Info<< "list1: " << list1 << nl - << "list2: " << list2 << endl; + << "list2: " << list2 << nl; + + // Addresses don't change with swap + Info<< "mem: " << long(list1.data()) << " " << long(list2.data()) << nl; + list1.swap(list2); - Info<< "The swap() method" << endl; + Info<< "The swap() method" << nl; Info<< "list1: " << list1 << nl - << "list2: " << list2 << endl; + << "list2: " << list2 << nl; + + Info<< "mem: " << long(list1.data()) << " " << long(list2.data()) << nl; Swap(list1, list2); - Info<< "The Swap() function" << endl; + Info<< "The Swap() function" << nl; Info<< "list1: " << list1 << nl - << "list2: " << list2 << endl; + << "list2: " << list2 << nl; + + Info<< "mem: " << long(list1.data()) << " " << long(list2.data()) << nl; Info<< "====" << nl; + + + Info<< nl + << "Test of swap with other container content" << nl; + + FixedList<labelList, 4> llist1; + FixedList<labelList, 4> llist2; + + { + label i = 1; + for (auto& item : llist1) + { + item = identity(1 + 1.5*i); + ++i; + } + } + + Info<< nl + << "initial lists" << nl; + printInfo(llist1, llist2); + + llist2.transfer(llist1); + Info<< nl + << "After transfer" << nl; + printInfo(llist1, llist2); + + llist2.swap(llist1); + Info<< nl + << "After swap" << nl; + printInfo(llist1, llist2); + + llist2 = llist1; + Info<< nl + << "After copy assignment" << nl; + printInfo(llist1, llist2); + + llist2 = std::move(llist1); + Info<< nl + << "After move assignment" << nl; + printInfo(llist1, llist2); } + Info<< nl + << "Test construct and assignment" << nl; + + List<label> list3{0, 1, 2, 3}; FixedList<label, 4> list4(list3.begin(), list3.end()); Info<< "list3: " << list3 << nl - << "list4: " << list4 << endl; + << "list4: " << list4 << nl; list4 = {1, 2, 3, 5}; Info<< "list4: " << list4 << nl; FixedList<label, 5> list5{0, 1, 2, 3, 4}; - Info<< "list5: " << list5 << endl; + Info<< "list5: " << list5 << nl; List<FixedList<label, 2>> list6{{0, 1}, {2, 3}}; - Info<< "list6: " << list6 << endl; + Info<< "list6: " << list6 << nl; if (Pstream::parRun()) { if (Pstream::myProcNo() != Pstream::masterNo()) { Serr<< "slave sending to master " - << Pstream::masterNo() << endl; + << Pstream::masterNo() << nl; OPstream toMaster ( diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C index 2a10efe4116ad07673afde138ab08ec778c8b188..e0cd4afae6e22df3dae0e77c6fcdb2e05f4713e3 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.C +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.C @@ -52,13 +52,6 @@ Foam::label Foam::FixedList<T, Size>::find } -template<class T, unsigned Size> -void Foam::FixedList<T, Size>::swap(FixedList<T, Size>& lst) -{ - Foam::Swap(v_, lst.v_); -} - - template<class T, unsigned Size> void Foam::FixedList<T, Size>::moveFirst(const label i) { @@ -112,72 +105,74 @@ void Foam::FixedList<T, Size>::swapLast(const label i) // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator==(const FixedList<T, Size>& a) const +bool Foam::FixedList<T, Size>::operator==(const FixedList<T, Size>& list) const { - bool equal = true; - - List_CONST_ACCESS(T, (*this), vp); - List_CONST_ACCESS(T, (a), ap); + List_CONST_ACCESS(T, *this, lhs); + List_CONST_ACCESS(T, (list), rhs); + // List sizes are identical by definition (template parameter) for (unsigned i = 0; i < Size; ++i) { - equal = (vp[i] == ap[i]); - if (!equal) break; + if (!(lhs[i] == rhs[i])) + { + return false; + } } - return equal; + // Contents appear to be identical. + return true; } template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator!=(const FixedList<T, Size>& a) const +bool Foam::FixedList<T, Size>::operator<(const FixedList<T, Size>& list) const { - return !operator==(a); -} - - -template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator<(const FixedList<T, Size>& a) const -{ - List_CONST_ACCESS(T, *this, ptr1); - List_CONST_ACCESS(T, a, ptr2); + List_CONST_ACCESS(T, *this, lhs); + List_CONST_ACCESS(T, (list), rhs); + // List sizes are identical by definition (template parameter) for (unsigned i=0; i<Size; ++i) { - if (ptr1[i] < ptr2[i]) + if (lhs[i] < rhs[i]) { return true; } - else if (ptr1[i] > ptr2[i]) + else if (rhs[i] < lhs[i]) { return false; } } - // Contents look to be identical. - // The sizes are identical by definition (template parameter) + // Contents appear to be identical. return false; } template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator>(const FixedList<T, Size>& a) const +bool Foam::FixedList<T, Size>::operator!=(const FixedList<T, Size>& list) const +{ + return !operator==(list); +} + + +template<class T, unsigned Size> +bool Foam::FixedList<T, Size>::operator>(const FixedList<T, Size>& list) const { - return a.operator<(*this); + return list.operator<(*this); } template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator<=(const FixedList<T, Size>& a) const +bool Foam::FixedList<T, Size>::operator<=(const FixedList<T, Size>& list) const { - return !operator>(a); + return !list.operator<(*this); } template<class T, unsigned Size> -bool Foam::FixedList<T, Size>::operator>=(const FixedList<T, Size>& a) const +bool Foam::FixedList<T, Size>::operator>=(const FixedList<T, Size>& list) const { - return !operator<(a); + return !operator<(list); } diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H index b0955a3d166274930c28d9b1e30a36615054f26b..ea43d305f31948b96e03c53b9177218e87319e95 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H @@ -47,6 +47,7 @@ SourceFiles #include <type_traits> #include <initializer_list> +#include <iterator> // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -95,6 +96,42 @@ protected: public: + // STL type definitions + + //- The value type the FixedList contains + typedef T value_type; + + //- The pointer type for non-const access to value_type items + typedef T* pointer; + + //- The pointer type for const access to value_type items + typedef const T* const_pointer; + + //- The type used for storing into value_type objects + typedef T& reference; + + //- The type used for reading from constant value_type objects. + typedef const T& const_reference; + + //- Random access iterator for traversing FixedList + typedef T* iterator; + + //- Random access iterator for traversing FixedList + typedef const T* const_iterator; + + //- The type to represent the size of a FixedList + typedef label size_type; + + //- The difference between iterator objects + typedef label difference_type; + + //- Reverse iterator (non-const access) + typedef std::reverse_iterator<iterator> reverse_iterator; + + //- Reverse iterator (const access) + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + + //- Hashing function class. // Use Hasher directly for contiguous data. Otherwise hash incrementally. template<class HashT=Hash<T>> @@ -102,7 +139,7 @@ public: { inline unsigned operator() ( - const FixedList<T, Size>&, + const FixedList<T, Size>& lst, unsigned seed = 0 ) const; }; @@ -117,7 +154,7 @@ public: // Constructors //- Null constructor - inline FixedList(); + inline FixedList() = default; //- Construct from value explicit inline FixedList(const T& val); @@ -128,7 +165,8 @@ public: //- Copy constructor inline FixedList(const FixedList<T, Size>& lst); - //- Move constructor + //- Move construct by using move assignment for the individual + //- list elements inline FixedList(FixedList<T, Size>&& lst); //- Construct given begin/end iterators @@ -227,11 +265,11 @@ public: //- Dummy resize function // needed to make FixedList consistent with List - inline void resize(const label s); + inline void resize(const label n); //- Dummy setSize function // needed to make FixedList consistent with List - inline void setSize(const label s); + inline void setSize(const label n); //- Move element to the first position. void moveFirst(const label i); @@ -245,9 +283,9 @@ public: //- Swap element with the last element. void swapLast(const label i); - //- Copy (not transfer) the argument contents - // needed to make FixedList consistent with List - void transfer(const FixedList<T, Size>& lst); + //- Transfer by swapping using a move assignment for the content + //- of the individual list elements + inline void transfer(FixedList<T, Size>& lst); // Member operators @@ -280,29 +318,7 @@ public: inline void operator=(FixedList<T, Size>&& lst); - // STL type definitions - - //- Type of values the FixedList contains - typedef T value_type; - - //- The type used for storing into value_type objects - typedef T& reference; - - //- The type used for reading from constant value_type objects. - typedef const T& const_reference; - - //- The type that can represent the difference between any two - //- FixedList iterator objects - typedef label difference_type; - - //- The type that can represent the size of a FixedList - typedef label size_type; - - - // STL iterator - - //- Random access iterator for traversing FixedList - typedef T* iterator; + // Random access iterator (non-const) //- Return an iterator to begin traversing the FixedList inline iterator begin(); @@ -311,10 +327,7 @@ public: inline iterator end(); - // STL const_iterator - - //- Random access iterator for traversing FixedList - typedef const T* const_iterator; + // Random access iterator (const) //- Return const_iterator to begin traversing the constant FixedList inline const_iterator cbegin() const; @@ -329,86 +342,7 @@ public: inline const_iterator end() const; - // Reverse iterators - - //- Generic const/non-const reverse iterator - template<bool Const> - class reverse_iterator_base - { - public: - //- The const/non-const type for entries - typedef typename std::conditional - <Const, const T, T>::type value_type; - - //- A pointer to a const/non-const entry - typedef value_type* pointer; - - //- A reference to a const/non-const entry - typedef value_type& reference; - - - private: - - //- The element pointer - pointer ptr_; - - public: - - //- Construct null or from list element pointer - inline reverse_iterator_base(pointer ptr = nullptr) - : - ptr_(ptr) - {} - - //- Copy construct - inline reverse_iterator_base(const reverse_iterator_base& iter) - : - ptr_(iter.ptr_) - {} - - - //- Reverse increment - inline void operator++() - { - --ptr_; - } - - //- Reverse increment - inline reverse_iterator_base operator++(int) - { - reverse_iterator_base old(*this); - --ptr_; - return old; - } - - //- Dereference iterator - reference operator*() const - { - return *ptr_; - } - - //- Dereference iterator - pointer operator->() const - { - return ptr_; - } - - //- Equality - bool operator==(const reverse_iterator_base& iter) const - { - return ptr_ == iter.ptr_; - } - - //- inequality - bool operator!=(const reverse_iterator_base& iter) const - { - return ptr_ != iter.ptr_; - } - }; - - - //- STL reverse_iterator - typedef reverse_iterator_base<false> reverse_iterator; + // Reverse iterator (non-const) //- Return reverse_iterator to begin reverse traversing the FixedList inline reverse_iterator rbegin(); @@ -417,8 +351,7 @@ public: inline reverse_iterator rend(); - //- STL const reverse iterator - typedef reverse_iterator_base<true> const_reverse_iterator; + // Reverse iterator (const) //- Return const_reverse_iterator to begin reverse traversing FixedList inline const_reverse_iterator crbegin() const; @@ -444,31 +377,31 @@ public: //- Always false since zero-sized FixedList is compile-time disabled. inline bool empty() const; - //- Swap content with another FixedList of the same type. - void swap(FixedList<T, Size>& lst); + //- Swap lists by swapping the content of the individual list elements + inline void swap(FixedList<T, Size>& lst); // STL member operators //- Equality operation on FixedLists of the same type. // Returns true when the FixedLists are element-wise equal - // (using FixedList::value_type::operator==). Takes linear time - bool operator==(const FixedList<T, Size>& a) const; + // (using FixedList::value_type::operator==). Takes linear time + bool operator==(const FixedList<T, Size>& list) const; //- The opposite of the equality operation. Takes linear time - bool operator!=(const FixedList<T, Size>& a) const; + bool operator!=(const FixedList<T, Size>& list) const; //- Compare two FixedLists lexicographically. Takes linear time - bool operator<(const FixedList<T, Size>& a) const; + bool operator<(const FixedList<T, Size>& list) const; //- Compare two FixedLists lexicographically. Takes linear time - bool operator>(const FixedList<T, Size>& a) const; + bool operator>(const FixedList<T, Size>& list) const; //- Return true if !(a > b). Takes linear time - bool operator<=(const FixedList<T, Size>& a) const; + bool operator<=(const FixedList<T, Size>& list) const; //- Return true if !(a < b). Takes linear time - bool operator>=(const FixedList<T, Size>& a) const; + bool operator>=(const FixedList<T, Size>& list) const; // Writing @@ -484,14 +417,14 @@ public: // IOstream operators - //- Read List from Istream, discarding contents of existing List + //- Read from Istream, discarding contents of existing List friend Istream& operator>> <T, Size> ( Istream& is, FixedList<T, Size>& lst ); - //- Write List to Ostream, as per writeList() with shortListLen=10 + //- Write to Ostream, as per writeList() with shortListLen=10 friend Ostream& operator<< <T, Size> ( Ostream& os, @@ -502,9 +435,10 @@ public: // Global Functions -// Exchange contents of lists - see FixedList::swap(). +//- Swap FixedList contents - see FixedList::swap(). +// Internally this actually swaps the individual list elements template<class T, unsigned Size> -inline void Swap(FixedList<T,Size>& a, FixedList<T,Size>& b); +inline void Swap(FixedList<T,Size>& lhs, FixedList<T,Size>& rhs); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H index 258eb38046a8d263af03fb720ed0575a04ad12ab..e24527b27df94e533c3363aa5a578a015b97828c 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H @@ -32,11 +32,6 @@ License // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -template<class T, unsigned Size> -inline Foam::FixedList<T, Size>::FixedList() -{} - - template<class T, unsigned Size> inline Foam::FixedList<T, Size>::FixedList(const T& val) { @@ -62,7 +57,7 @@ inline Foam::FixedList<T, Size>::FixedList(const FixedList<T, Size>& lst) { for (unsigned i=0; i<Size; ++i) { - v_[i] = lst[i]; + v_[i] = lst.v_[i]; } } @@ -70,9 +65,6 @@ inline Foam::FixedList<T, Size>::FixedList(const FixedList<T, Size>& lst) template<class T, unsigned Size> inline Foam::FixedList<T, Size>::FixedList(FixedList<T, Size>&& lst) { - // No significant speedup observed for copy assignment on simple types, - // use move assignment for generality with more complex types - for (unsigned i=0; i<Size; ++i) { v_[i] = std::move(lst.v_[i]); @@ -82,7 +74,7 @@ inline Foam::FixedList<T, Size>::FixedList(FixedList<T, Size>&& lst) template<class T, unsigned Size> template<class InputIterator> -Foam::FixedList<T, Size>::FixedList +inline Foam::FixedList<T, Size>::FixedList ( InputIterator begIter, InputIterator endIter @@ -130,7 +122,7 @@ inline Foam::FixedList<T, Size>::FixedList(const SLList<T>& lst) { checkSize(lst.size()); - typename SLList<T>::const_iterator iter = lst.begin(); + auto iter = lst.begin(); for (unsigned i=0; i<Size; ++i) { v_[i] = *iter; @@ -246,28 +238,38 @@ inline bool Foam::FixedList<T, Size>::found template<class T, unsigned Size> -inline void Foam::FixedList<T, Size>::resize(const label s) +inline void Foam::FixedList<T, Size>::resize(const label n) { #ifdef FULLDEBUG - checkSize(s); + checkSize(n); #endif } template<class T, unsigned Size> -inline void Foam::FixedList<T, Size>::setSize(const label s) +inline void Foam::FixedList<T, Size>::setSize(const label n) { #ifdef FULLDEBUG - checkSize(s); + checkSize(n); #endif } template<class T, unsigned Size> -inline void Foam::FixedList<T, Size>::transfer(const FixedList<T, Size>& lst) +inline void Foam::FixedList<T, Size>::swap(FixedList<T, Size>& lst) { for (unsigned i=0; i<Size; ++i) { - v_[i] = lst[i]; + Foam::Swap(v_[i], lst.v_[i]); + } +} + + +template<class T, unsigned Size> +inline void Foam::FixedList<T, Size>::transfer(FixedList<T, Size>& lst) +{ + for (unsigned i=0; i<Size; ++i) + { + v_[i] = std::move(lst[i]); } } @@ -444,7 +446,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::iterator Foam::FixedList<T, Size>::end() { - return &v_[Size]; + return (v_ + Size); } @@ -452,7 +454,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_iterator Foam::FixedList<T, Size>::end() const { - return &v_[Size]; + return (v_ + Size); } @@ -460,7 +462,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_iterator Foam::FixedList<T, Size>::cend() const { - return &v_[Size]; + return (v_ + Size); } @@ -468,7 +470,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::reverse_iterator Foam::FixedList<T, Size>::rbegin() { - return reverse_iterator(&v_[Size-1]); + return reverse_iterator(end()); } @@ -476,7 +478,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_reverse_iterator Foam::FixedList<T, Size>::rbegin() const { - return const_reverse_iterator(&v_[Size-1]); + return const_reverse_iterator(end()); } @@ -484,7 +486,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_reverse_iterator Foam::FixedList<T, Size>::crbegin() const { - return const_reverse_iterator(&v_[Size-1]); + return const_reverse_iterator(end()); } @@ -492,7 +494,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::reverse_iterator Foam::FixedList<T, Size>::rend() { - return reverse_iterator(&v_[-1]); + return reverse_iterator(begin()); } @@ -500,7 +502,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_reverse_iterator Foam::FixedList<T, Size>::rend() const { - return const_reverse_iterator(&v_[-1]); + return const_reverse_iterator(begin()); } @@ -508,7 +510,7 @@ template<class T, unsigned Size> inline typename Foam::FixedList<T, Size>::const_reverse_iterator Foam::FixedList<T, Size>::crend() const { - return const_reverse_iterator(&v_[-1]); + return const_reverse_iterator(begin()); } @@ -562,9 +564,9 @@ inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator() // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // template<class T, unsigned Size> -void Foam::Swap(FixedList<T, Size>& a, FixedList<T, Size>& b) +inline void Foam::Swap(FixedList<T, Size>& lhs, FixedList<T, Size>& rhs) { - a.swap(b); + lhs.swap(rhs); }