mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
79 lines
3.0 KiB
C++
79 lines
3.0 KiB
C++
/* Copyright (C) 2021
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated,
|
|
* or distributed except according to the terms contained in the LICENSE file.
|
|
*/
|
|
|
|
//! \file
|
|
|
|
#ifndef BLACKMISC_SETBUILDER_H
|
|
#define BLACKMISC_SETBUILDER_H
|
|
|
|
#include "blackmisc/blackmiscexport.h"
|
|
#include <QSet>
|
|
#include <QList>
|
|
#include <QVector>
|
|
#include <QStringList>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace BlackMisc
|
|
{
|
|
/*!
|
|
* Build a QSet more efficiently when calling insert() in a for loop.
|
|
*/
|
|
template <typename T>
|
|
class CSetBuilder
|
|
{
|
|
public:
|
|
//! Add an element to the set. Runs in amortized constant time.
|
|
//! @{
|
|
void insert(const T &value) { m_list.push_back(value); }
|
|
void insert(T &&value) { m_list.push_back(std::move(value)); }
|
|
//! @}
|
|
|
|
//! True if no elements have been inserted.
|
|
bool isEmpty() const { return m_list.isEmpty(); }
|
|
|
|
//! Return a container of unique elements. Runs in log-linear time.
|
|
//! @{
|
|
operator QList<T>() const & { return sortAndDeduplicate(m_list); }
|
|
operator QList<T>() && { return sortAndDeduplicate(std::move(m_list)); }
|
|
operator QSet<T>() const & { return convertTo<QSet>(sortAndDeduplicate(m_list)); }
|
|
operator QSet<T>() && { return convertTo<QSet>(sortAndDeduplicate(std::move(m_list))); }
|
|
operator std::set<T>() const & { return convertTo<std::set>(sortAndDeduplicate(m_list)); }
|
|
operator std::set<T>() && { return convertTo<std::set>(sortAndDeduplicate(std::move(m_list))); }
|
|
operator QVector<T>() const & { return convertTo<QVector>(sortAndDeduplicate(m_list)); }
|
|
operator QVector<T>() && { return convertTo<QVector>(sortAndDeduplicate(std::move(m_list))); }
|
|
operator std::vector<T>() const & { return convertTo<std::vector>(sortAndDeduplicate(m_list)); }
|
|
operator std::vector<T>() && { return convertTo<std::vector>(sortAndDeduplicate(std::move(m_list))); }
|
|
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, QString>>>
|
|
operator QStringList() const & { return sortAndDeduplicate(m_list); }
|
|
template <typename U = T, typename = std::enable_if_t<std::is_same_v<U, QString>>>
|
|
operator QStringList() && { return sortAndDeduplicate(std::move(m_list)); }
|
|
//! @}
|
|
|
|
private:
|
|
QList<T> m_list;
|
|
|
|
static QList<T> sortAndDeduplicate(QList<T> list)
|
|
{
|
|
std::sort(list.begin(), list.end());
|
|
list.erase(std::unique(list.begin(), list.end()), list.end());
|
|
return list;
|
|
}
|
|
|
|
template <template <typename...> class C>
|
|
static C<T> convertTo(QList<T> &&list)
|
|
{
|
|
return C<T>(std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()));
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif
|