mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Issue #114 Add CSetBuilder and CMapBuilder
This commit is contained in:
74
src/blackmisc/mapbuilder.h
Normal file
74
src/blackmisc/mapbuilder.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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_MAPBUILDER_H
|
||||
#define BLACKMISC_MAPBUILDER_H
|
||||
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/range.h"
|
||||
#include <QMap>
|
||||
#include <QHash>
|
||||
#include <QList>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
/*!
|
||||
* Build a QMap more efficiently when calling insert() in a for loop.
|
||||
*/
|
||||
template <typename K, typename V>
|
||||
class CMapBuilder
|
||||
{
|
||||
public:
|
||||
//! Add an key/value pair to the map. Runs in amortized constant time.
|
||||
template <typename... Ts>
|
||||
void insert(Ts &&... keyAndValue) { m_list.push_back(std::make_pair(std::forward<Ts>(keyAndValue)...)); }
|
||||
|
||||
//! True if no pairs have been inserted.
|
||||
bool isEmpty() const { return m_list.isEmpty(); }
|
||||
|
||||
//! Return a container with unique keys. Runs in log-linear time.
|
||||
//! @{
|
||||
operator QMap<K, V>() const & { return convertToMap(sortAndDeduplicate(m_list)); }
|
||||
operator QMap<K, V>() && { return convertToMap(sortAndDeduplicate(std::move(m_list))); }
|
||||
operator QHash<K, V>() const & { return convertTo<QHash>(sortAndDeduplicate(m_list)); }
|
||||
operator QHash<K, V>() && { return convertTo<QHash>(sortAndDeduplicate(std::move(m_list))); }
|
||||
operator std::map<K, V>() const & { return convertTo<std::map>(sortAndDeduplicate(m_list)); }
|
||||
operator std::map<K, V>() && { return convertTo<std::map>(sortAndDeduplicate(std::move(m_list))); }
|
||||
//! @}
|
||||
|
||||
private:
|
||||
QList<std::pair<K, V>> m_list;
|
||||
|
||||
static QList<std::pair<K, V>> sortAndDeduplicate(QList<std::pair<K, V>> list)
|
||||
{
|
||||
std::sort(list.begin(), list.end(), [](auto &&a, auto &&b) { return std::less<>()(a.first, b.first); });
|
||||
list.erase(std::unique(list.begin(), list.end(), [](auto &&a, auto &&b) { return a.first == b.first; }), list.end());
|
||||
return list;
|
||||
}
|
||||
|
||||
template <template <typename...> class C>
|
||||
static C<K, V> convertTo(QList<std::pair<K, V>> &&list)
|
||||
{
|
||||
return C<K, V>(std::make_move_iterator(list.begin()), std::make_move_iterator(list.end()));
|
||||
}
|
||||
|
||||
static QMap<K, V> convertToMap(QList<std::pair<K, V>> &&list)
|
||||
{
|
||||
QMap<K, V> map;
|
||||
for (auto &pair : makeRange(list).reverse()) { map.insert(map.cbegin(), std::move(pair.first), std::move(pair.second)); }
|
||||
return map;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -65,6 +65,10 @@ namespace BlackMisc
|
||||
//! By QList of type T.
|
||||
CSequence(const QList<T> &list) : m_impl(list.toVector()) {}
|
||||
|
||||
//! Range constructor.
|
||||
template <typename It>
|
||||
CSequence(It first, It last) : m_impl(first, last) {}
|
||||
|
||||
//! Copy constructor.
|
||||
CSequence(const CSequence &other) = default;
|
||||
|
||||
|
||||
78
src/blackmisc/setbuilder.h
Normal file
78
src/blackmisc/setbuilder.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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
|
||||
Reference in New Issue
Block a user