mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-14 16:55:36 +08:00
refs #715 Support implicit conversion from CRange to QSet.
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#define BLACKMISC_ITERATOR_H
|
#define BLACKMISC_ITERATOR_H
|
||||||
|
|
||||||
#include "optional.h"
|
#include "optional.h"
|
||||||
|
#include "typetraits.h"
|
||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@@ -26,6 +27,72 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
namespace Iterators
|
namespace Iterators
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* Configurable output iterator using a provided functor to do the insertion.
|
||||||
|
*/
|
||||||
|
template <class F> class OutputIterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Constructor
|
||||||
|
//! @{
|
||||||
|
explicit OutputIterator(const F &func) : m_func(func) {}
|
||||||
|
explicit OutputIterator(F &&func) : m_func(std::move(func)) {}
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Advance the iterator (no-op)
|
||||||
|
//! @{
|
||||||
|
OutputIterator &operator ++() { return *this; }
|
||||||
|
OutputIterator operator ++(int) { return *this; }
|
||||||
|
//! @}
|
||||||
|
|
||||||
|
//! Dereference (no-op)
|
||||||
|
OutputIterator &operator *() { return *this; }
|
||||||
|
|
||||||
|
//! Assignment operator performs the output
|
||||||
|
template <typename T, std::enable_if_t<! std::is_convertible<T, OutputIterator>::value, int> = 0>
|
||||||
|
OutputIterator &operator =(T &&value) { m_func(std::forward<T>(value)); return *this; }
|
||||||
|
|
||||||
|
//! Copy assignment operator
|
||||||
|
OutputIterator &operator =(const OutputIterator &other)
|
||||||
|
{
|
||||||
|
// Work around lambda's deleted copy assignment operator
|
||||||
|
this->~OutputIterator();
|
||||||
|
return *new (this) OutputIterator(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
F m_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Return an output iterator of type deduced from the argument.
|
||||||
|
*/
|
||||||
|
template <class F> auto makeOutputIterator(F &&func)
|
||||||
|
{
|
||||||
|
return OutputIterator<std::decay_t<F>>(std::forward<F>(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
//! \private
|
||||||
|
template <class T> auto makeInsertIterator(T &container, std::true_type)
|
||||||
|
{
|
||||||
|
return makeOutputIterator([&container](auto &&v) { container.push_back(std::forward<decltype(v)>(v)); });
|
||||||
|
}
|
||||||
|
//! \private
|
||||||
|
template <class T> auto makeInsertIterator(T &container, std::false_type)
|
||||||
|
{
|
||||||
|
return makeOutputIterator([&container](auto &&v) { container.insert(std::forward<decltype(v)>(v)); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Return an insert iterator appropriate to the container type (uses push_back or insert).
|
||||||
|
*/
|
||||||
|
template <class T> auto makeInsertIterator(T &container)
|
||||||
|
{
|
||||||
|
return Private::makeInsertIterator(container, HasPushBack<T>());
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Iterator wrapper for Qt's STL-style associative container iterators, when dereferenced return the key instead of the value.
|
* Iterator wrapper for Qt's STL-style associative container iterators, when dereferenced return the key instead of the value.
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ namespace BlackMisc
|
|||||||
T to() const
|
T to() const
|
||||||
{
|
{
|
||||||
T container;
|
T container;
|
||||||
std::copy(begin(), end(), std::back_inserter(container));
|
std::copy(begin(), end(), Iterators::makeInsertIterator(container));
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,32 @@ namespace BlackMisc
|
|||||||
//! \endcond
|
//! \endcond
|
||||||
|
|
||||||
#ifdef Q_CC_MSVC // work around what seems to be an expression SFINAE bug in MSVC
|
#ifdef Q_CC_MSVC // work around what seems to be an expression SFINAE bug in MSVC
|
||||||
|
namespace Private
|
||||||
|
{
|
||||||
|
struct HasPushBackHelper
|
||||||
|
{
|
||||||
|
struct Base { int push_back; };
|
||||||
|
template <typename T> struct Derived : public T, public Base {};
|
||||||
|
template <typename T, T> struct TypeCheck {};
|
||||||
|
template <typename T> static std::false_type test(TypeCheck<decltype(&Base::push_back), &Derived<T>::push_back> *);
|
||||||
|
template <typename T> static std::true_type test(...);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
using HasPushBack = decltype(Private::HasPushBackHelper::test<T>(nullptr));
|
||||||
|
#else
|
||||||
|
/*!
|
||||||
|
* Trait which is true if the expression a.push_back(v) is valid when a and v are instances of T and T::value_type.
|
||||||
|
*/
|
||||||
|
template <typename T, typename = void_t<>>
|
||||||
|
struct HasPushBack : public std::false_type {};
|
||||||
|
//! \cond
|
||||||
|
template <typename T>
|
||||||
|
struct HasPushBack<T, void_t<decltype(std::declval<T>().push_back(std::declval<typename T::value_type>()))>> : public std::true_type {};
|
||||||
|
//! \endcond
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_CC_MSVC
|
||||||
namespace Private
|
namespace Private
|
||||||
{
|
{
|
||||||
struct HasGetLogCategoriesHelper
|
struct HasGetLogCategoriesHelper
|
||||||
|
|||||||
Reference in New Issue
Block a user