7#pragma qt_sync_skip_header_check
8#pragma qt_sync_stop_processing
11#ifndef QCONTAINERTOOLS_IMPL_H
12#define QCONTAINERTOOLS_IMPL_H
14#include <QtCore/qglobal.h>
15#include <QtCore/qtypeinfo.h>
17#include <QtCore/qxptype_traits.h>
35template<
typename T,
typename Cmp = std::less<>>
37 Cmp less = {})
noexcept
39 return !less(
p,
b) && less(
p,
e);
48template <
typename C,
typename T>
51 static_assert(std::is_same_v<
decltype(std::data(
c)), T>);
56 std::data(
c) + std::distance(std::begin(
c), std::end(
c)));
62template <typename T, typename N>
65 if constexpr (std::is_nothrow_move_constructible_v<T> || !std::is_copy_constructible_v<T>)
71template <
typename T,
typename N>
76 std::memcpy(
static_cast<void *
>(
out),
77 static_cast<const void *
>(
first),
102 const auto cast = [](T *
p) {
return reinterpret_cast<uchar*
>(
p); };
103 std::rotate(cast(
first), cast(mid), cast(last));
105 std::rotate(
first, mid, last);
121template <
typename T,
typename Predicate>
124 static_assert(std::is_nothrow_destructible_v<T>,
125 "This algorithm requires that T has a non-throwing destructor");
130 while (
first != last) {
132 new (std::addressof(*
out)) T(*
first);
138 std::destroy(std::reverse_iterator(
out), std::reverse_iterator(dest_begin));
144template<
typename iterator,
typename N>
154 using T =
typename std::iterator_traits<iterator>::value_type;
167 iterator intermediate;
169 Destructor(iterator &
it) noexcept :
iter(std::addressof(
it)),
end(
it) { }
171 void freeze()
noexcept
173 intermediate = *
iter;
174 iter = std::addressof(intermediate);
176 ~Destructor()
noexcept
179 std::advance(*
iter, step);
183 } destroyer(d_first);
185 const iterator d_last = d_first +
n;
190 auto pair = std::minmax(d_last,
first);
194 iterator overlapBegin = pair.first;
195 iterator overlapEnd = pair.second;
198 while (d_first != overlapBegin) {
200 new (std::addressof(*d_first)) T(std::move_if_noexcept(*
first));
210 while (d_first != d_last) {
211 *d_first = std::move_if_noexcept(*
first);
219 while (
first != overlapEnd)
233template<
typename T,
typename N>
236 static_assert(std::is_nothrow_destructible_v<T>,
237 "This algorithm requires that T has a non-throwing destructor");
239 if (
n == N(0) ||
first == d_first ||
first ==
nullptr || d_first ==
nullptr)
243 std::memmove(
static_cast<void *
>(d_first),
static_cast<const void *
>(
first),
n *
sizeof(T));
245 if (d_first <
first) {
248 auto rfirst = std::make_reverse_iterator(
first +
n);
249 auto rd_first = std::make_reverse_iterator(d_first +
n);
255template <
typename Iterator>
257 std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::input_iterator_tag>
::value,
260template <
typename Iterator>
262 std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>
::value,
265template <
typename Iterator>
267 !std::is_convertible<typename std::iterator_traits<Iterator>::iterator_category, std::forward_iterator_tag>
::value,
270template <
typename Container,
271 typename InputIterator,
277template <
typename Container,
278 typename ForwardIterator,
279 IfIsForwardIterator<ForwardIterator> =
true>
282 c->reserve(
static_cast<typename Container::size_type
>(std::distance(
f, l)));
285template <
typename Iterator>
287 std::declval<Iterator &>().key(),
288 std::declval<Iterator &>().value()
291template <
typename Iterator>
293 std::declval<Iterator &>()->first,
294 std::declval<Iterator &>()->second
297template <
typename Iterator>
299 std::enable_if_t<qxp::is_detected_v<KeyAndValueTest, Iterator>,
bool>;
301template <
typename Iterator>
303 std::enable_if_t<qxp::is_detected_v<FirstAndSecondTest, Iterator>,
bool>;
305template <
typename Iterator>
307 std::declval<Iterator &>().operator--()
310template <
typename Iterator>
312 std::enable_if_t<qxp::is_detected_v<MoveBackwardsTest, Iterator>,
bool>;
314template <
typename T,
typename U>
316 typename std::enable_if<!std::is_same<T, U>::value,
bool>
::type;
318template<
typename T,
typename U>
321template <
typename Container,
typename Predicate>
329 const auto cbegin =
c.cbegin();
330 const auto cend =
c.cend();
331 const auto t_it = std::find_if(cbegin, cend, pred);
332 auto result = std::distance(cbegin, t_it);
337 const auto e =
c.end();
348 *dest = std::move(*
it);
353 result = std::distance(dest,
e);
358template <
typename Container,
typename T>
362 auto cmp = [&](
auto &
e) {
return e ==
t; };
366template <
typename Container,
typename T>
369 using CopyProxy = std::conditional_t<std::is_copy_constructible_v<T>, T,
const T &>;
370 const T &tCopy = CopyProxy(
t);
374template <
typename Container,
typename T>
377 const auto cend =
c.cend();
378 const auto it = std::find(
c.cbegin(), cend,
t);
385template <
typename T,
typename Predicate>
389 auto it =
set.begin();
390 const auto e =
set.end();
404template <
typename R,
typename F,
typename ... ArgTypes>
410template <
typename R,
typename F,
typename ... ArgTypes>
412 std::is_invocable<F, ArgTypes...>,
416template <
typename Container,
typename Predicate>
421 using Iterator =
typename Container::iterator;
422 using Key =
typename Container::key_type;
423 using Value =
typename Container::mapped_type;
424 using KeyValuePair = std::pair<const Key &, Value &>;
426 typename Container::size_type
result = 0;
429 const auto e =
c.end();
431 if constexpr (is_invocable_explicit_r_v<bool, Predicate &, Iterator &>) {
438 }
else if constexpr (is_invocable_explicit_r_v<bool, Predicate &, KeyValuePair &&>) {
439 KeyValuePair
p(
it.key(),
it.value());
440 if (pred(std::move(
p))) {
447 static_assert(
sizeof(Container) == 0,
"Predicate has an incompatible signature");
iterator erase(const_iterator i)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
auto associative_erase_if(Container &c, Predicate &pred)
QT_WARNING_POP void q_rotate(T *first, T *mid, T *last)
void q_uninitialized_relocate_n(T *first, N n, T *out)
qsizetype qset_erase_if(QSet< T > &set, Predicate &pred)
QT_WARNING_PUSH void q_uninitialized_move_if_noexcept_n(T *first, N n, T *out)
decltype(std::declval< Iterator & >().operator--()) MoveBackwardsTest
static constexpr bool q_points_into_range(const T *p, const T *b, const T *e, Cmp less={}) noexcept
auto sequential_erase_one(Container &c, const T &t)
typename std::enable_if<!std::is_same< T, U >::value, bool >::type IfIsNotSame
typename std::enable_if<!std::is_convertible< T, U >::value, bool >::type IfIsNotConvertible
void q_relocate_overlap_n_left_move(iterator first, N n, iterator d_first)
typename std::enable_if< !std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::forward_iterator_tag >::value, bool >::type IfIsNotForwardIterator
auto sequential_erase_if(Container &c, Predicate &pred)
auto sequential_erase_with_copy(Container &c, const T &t)
std::enable_if_t< qxp::is_detected_v< KeyAndValueTest, Iterator >, bool > IfAssociativeIteratorHasKeyAndValue
auto sequential_erase(Container &c, const T &t)
T * q_uninitialized_remove_copy_if(T *first, T *last, T *out, Predicate &pred)
typename std::enable_if< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::input_iterator_tag >::value, bool >::type IfIsInputIterator
std::enable_if_t< qxp::is_detected_v< FirstAndSecondTest, Iterator >, bool > IfAssociativeIteratorHasFirstAndSecond
typename std::enable_if< std::is_convertible< typename std::iterator_traits< Iterator >::iterator_category, std::forward_iterator_tag >::value, bool >::type IfIsForwardIterator
void q_relocate_overlap_n(T *first, N n, T *d_first)
decltype(std::declval< Iterator & >() ->first, std::declval< Iterator & >() ->second) FirstAndSecondTest
std::enable_if_t< qxp::is_detected_v< MoveBackwardsTest, Iterator >, bool > IfIteratorCanMoveBackwards
void reserveIfForwardIterator(Container *, InputIterator, InputIterator)
constexpr bool is_invocable_explicit_r_v
decltype(std::declval< Iterator & >().key(), std::declval< Iterator & >().value()) KeyAndValueTest
#define QT_WARNING_DISABLE_GCC(text)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLsizei GLsizei GLsizei GLboolean commit
QFuture< QSet< QChar > > set
[10]
QTextStream out(stdout)
[7]