mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-03 15:45:46 +08:00
refs #715 Support implicit conversion from CRange to QSet.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#define BLACKMISC_ITERATOR_H
|
||||
|
||||
#include "optional.h"
|
||||
#include "typetraits.h"
|
||||
#include <QScopedPointer>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
@@ -26,6 +27,72 @@ namespace BlackMisc
|
||||
{
|
||||
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.
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace BlackMisc
|
||||
T to() const
|
||||
{
|
||||
T container;
|
||||
std::copy(begin(), end(), std::back_inserter(container));
|
||||
std::copy(begin(), end(), Iterators::makeInsertIterator(container));
|
||||
return container;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,32 @@ namespace BlackMisc
|
||||
//! \endcond
|
||||
|
||||
#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
|
||||
{
|
||||
struct HasGetLogCategoriesHelper
|
||||
|
||||
Reference in New Issue
Block a user