File indexing completed on 2024-04-28 15:40:25
0001 /* 0002 SPDX-FileCopyrightText: 2006-2020 Tuomas Suutari <thsuut@utu.fi> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 0006 This program is distributed in the hope that it will be useful, but 0007 WITHOUT ANY WARRANTY; without even the implied warranty of 0008 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0009 General Public License for more details. 0010 0011 You should have received a copy of the GNU General Public License 0012 along with this program (see the file COPYING); if not, write to the 0013 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, 0014 MA 02110-1301 USA. 0015 */ 0016 0017 #include "List.h" 0018 0019 #include <DB/RawId.h> 0020 #include <kpabase/FileName.h> 0021 0022 #include <QList> 0023 #include <QStringList> 0024 #include <QTime> 0025 #include <algorithm> // std::swap 0026 #include <stdlib.h> // rand 0027 0028 template <class T> 0029 QList<T> Utilities::mergeListsUniqly(const QList<T> &l1, const QList<T> &l2) 0030 { 0031 QList<T> r = l1; 0032 for (const T &x : l2) 0033 if (!r.contains(x)) 0034 r.append(x); 0035 return r; 0036 } 0037 0038 namespace 0039 { 0040 template <class T> 0041 class AutoDeletedArray 0042 { 0043 public: 0044 AutoDeletedArray(uint size) 0045 : m_ptr(new T[size]) 0046 { 0047 } 0048 operator T *() const { return m_ptr; } 0049 ~AutoDeletedArray() { delete[] m_ptr; } 0050 0051 private: 0052 T *m_ptr; 0053 }; 0054 } 0055 0056 template <class T> 0057 QList<T> Utilities::shuffleList(const QList<T> &list) 0058 { 0059 static bool init = false; 0060 if (!init) { 0061 QTime midnight(0, 0, 0); 0062 srand(midnight.secsTo(QTime::currentTime())); 0063 init = true; 0064 } 0065 0066 // Take pointers from input list to an array for shuffling 0067 uint N = list.size(); 0068 AutoDeletedArray<const T *> deck(N); 0069 const T **p = deck; 0070 for (typename QList<T>::const_iterator i = list.begin(); 0071 i != list.end(); ++i) { 0072 *p = &(*i); 0073 ++p; 0074 } 0075 0076 // Shuffle the array of pointers 0077 for (uint i = 0; i < N; i++) { 0078 uint r = i + static_cast<uint>(static_cast<double>(N - i) * rand() / static_cast<double>(RAND_MAX)); 0079 std::swap(deck[r], deck[i]); 0080 } 0081 0082 // Create new list from the array 0083 QList<T> result; 0084 const T **const onePastLast = deck + N; 0085 for (p = deck; p != onePastLast; ++p) 0086 result.push_back(**p); 0087 0088 return result; 0089 } 0090 0091 #define INSTANTIATE_MERGELISTSUNIQLY(T) \ 0092 template QList<T> Utilities::mergeListsUniqly(const QList<T> &l1, const QList<T> &l2) 0093 0094 #define INSTANTIATE_SHUFFLELIST(T) \ 0095 template QList<T> Utilities::shuffleList(const QList<T> &list) 0096 0097 INSTANTIATE_MERGELISTSUNIQLY(DB::RawId); 0098 INSTANTIATE_MERGELISTSUNIQLY(QString); 0099 INSTANTIATE_SHUFFLELIST(DB::FileName); 0100 // vi:expandtab:tabstop=4 shiftwidth=4: