4#ifndef QMULTIMEDIA_RANGES_P_H
5#define QMULTIMEDIA_RANGES_P_H
18#include <QtCore/qtconfigmacros.h>
20#include <QtMultimedia/private/qiteratorfacade_p.h>
22#ifdef __cpp_lib_ranges
36#if defined(__cpp_lib_ranges) && (!defined(_GLIBCXX_RELEASE
) || _GLIBCXX_RELEASE
>= 12
)
75inline constexpr auto all_of = [](
auto &&range,
auto predicate) {
76 return std::all_of(
std::begin(range),
std::end(range),
std::move(predicate));
79inline constexpr auto any_of = [](
auto &&range,
auto predicate) {
80 return std::any_of(
std::begin(range),
std::end(range),
std::move(predicate));
83inline constexpr auto none_of = [](
auto &&range,
auto predicate) {
84 return std::none_of(
std::begin(range),
std::end(range),
std::move(predicate));
87inline constexpr auto for_each = [](
auto &&range,
auto func) {
88 return std::for_each(
std::begin(range),
std::end(range),
std::move(func));
91inline constexpr auto copy = [](
auto &&in,
auto out) {
92 return std::copy(
std::begin(in),
std::end(in),
std::move(out));
95inline constexpr auto fill = [](
auto &&range,
const auto &value) {
96 return std::fill(
std::begin(range),
std::end(range), value);
99inline constexpr auto find = [](
auto &&range,
const auto &value) {
100 return std::find(
std::begin(range),
std::end(range), value);
103inline constexpr auto find_if = [](
auto &&range,
auto predicate) {
104 return std::find_if(
std::begin(range),
std::end(range),
std::move(predicate));
107template <
typename Iterator>
120 template <
typename Range,
typename T,
typename Comp =
std::
less<>>
121 auto operator()(Range &&range,
const T &value, Comp comp = {})
const
123 return std::lower_bound(
std::begin(range),
std::end(range), value,
std::move(comp));
129 template <
typename Range,
typename T,
typename Comp =
std::
less<>>
130 auto operator()(Range &&range,
const T &value, Comp comp = {})
const
132 return std::upper_bound(
std::begin(range),
std::end(range), value,
std::move(comp));
138 template <
typename Range,
typename T,
typename Comp =
std::
less<>>
139 auto operator()(Range &&range,
const T &value, Comp comp = {})
const
141 auto [b, e] =
std::equal_range(
std::begin(range),
std::end(range), value,
std::move(comp));
142 return subrange<
decltype(b)>{ b, e };
148 template <
typename Range,
typename Comp =
std::
less<>>
151 auto it =
std::max_element(
std::begin(range),
std::end(range),
std::move(comp));
155 template <
typename Range>
158 auto it =
std::max_element(
std::begin(range),
std::end(range));
165 template <
typename Range,
typename Comp =
std::
less<>>
168 return std::max_element(
std::begin(range),
std::end(range),
std::move(comp));
171 template <
typename Range>
174 return std::max_element(
std::begin(range),
std::end(range));
180 template <
typename Range,
typename Comp =
std::
less<>>
183 auto it =
std::min_element(
std::begin(range),
std::end(range),
std::move(comp));
187 template <
typename Range>
190 auto it =
std::min_element(
std::begin(range),
std::end(range));
197 template <
typename Range,
typename Comp =
std::
less<>>
200 return std::min_element(
std::begin(range),
std::end(range),
std::move(comp));
203 template <
typename Range>
206 return std::min_element(
std::begin(range),
std::end(range));
212 template <
typename Range,
typename Comp =
std::
less<>>
215 std::sort(
std::begin(range),
std::end(range),
std::move(comp));
218 template <
typename Range>
221 std::sort(
std::begin(range),
std::end(range));
227 template <
typename Range,
typename Comp =
std::
less<>>
230 std::stable_sort(
std::begin(range),
std::end(range),
std::move(comp));
233 template <
typename Range>
236 std::stable_sort(
std::begin(range),
std::end(range));
242 template <
typename Range1,
typename Range2,
typename Pred =
std::
equal_to<>>
243 bool operator()(Range1 &&lhs, Range2 &&rhs, Pred pred = {})
const
245 return std::equal(
std::begin(lhs),
std::end(lhs),
std::begin(rhs),
std::end(rhs),
262inline constexpr auto transform = [](
auto &&range,
auto output,
auto op) {
263 return std::transform(
std::begin(range),
std::end(range),
std::move(output),
264 [op =
std::move(op)](
const auto &x) {
265 return std::invoke(op, x);
271#if __cpp_lib_ranges_contains >= 202207L
275inline constexpr auto contains = [](
auto &&range,
const auto &value) {
276 return std::find(
std::begin(range),
std::end(range), value) !=
std::end(range);
281#if __cpp_lib_ranges_to_container >= 202202L
287template <
typename Container>
292template <
typename Container,
typename Range>
295 return Container(
std::begin(range),
std::end(range));
298template <
template <
class...>
class Container>
303template <
template <
class...>
class Container,
class Range>
306 return Container<ranges::range_value_t<Range>>(std::begin(range), std::end(range));
311template <
typename Container,
typename Range>
312Container
to(Range &&range)
314 return Container(
std::begin(range),
std::end(range));
317template <
typename Container>
323template <
template <
class...>
class Container>
326 return impl::to_adaptor_template_template<Container>{};
335#if defined(__cpp_lib_ranges) && (!defined(_GLIBCXX_RELEASE
) || _GLIBCXX_RELEASE
>= 12
)
344template <
typename Range>
347 using BaseIt =
decltype(
std::begin(
std::declval<Range &>()));
348 using KeyReference =
decltype((*
std::declval<BaseIt>()).first);
352 :
public IteratorFacade<iterator, KeyValue, std::input_iterator_tag, KeyReference>
357 constexpr explicit iterator(BaseIt it) : m_it(
std::move(it)) { }
359 using reference = KeyReference;
360 constexpr reference dereference()
const {
return (*m_it).first; }
361 constexpr void increment() { ++m_it; }
362 constexpr bool equals(
const iterator &o)
const {
return m_it == o.m_it; }
368 constexpr explicit KeysView(Range &range) : m_range(range) { }
369 constexpr iterator
begin()
const {
return iterator{
std::begin(m_range) }; }
370 constexpr iterator
end()
const {
return iterator{
std::end(m_range) }; }
373template <
typename Range>
376 using BaseIt =
decltype(
std::begin(
std::declval<Range &>()));
377 using ValueReference =
decltype((*
std::declval<BaseIt>()).second);
381 :
public IteratorFacade<iterator, MappedValue, std::input_iterator_tag, ValueReference>
386 constexpr explicit iterator(BaseIt it) : m_it(
std::move(it)) { }
388 using reference = ValueReference;
389 constexpr reference dereference()
const {
return (*m_it).second; }
390 constexpr void increment() { ++m_it; }
391 constexpr bool equals(
const iterator &o)
const {
return m_it == o.m_it; }
397 constexpr explicit ValuesView(Range &range) : m_range(range) { }
398 constexpr iterator
begin()
const {
return iterator{
std::begin(m_range) }; }
399 constexpr iterator
end()
const {
return iterator{
std::end(m_range) }; }
405template <
typename Range>
408template <
typename Range>
411template <
typename Container,
typename Predicate>
414 using BaseIt =
decltype(
std::begin(
std::declval<Container &>()));
415 using ElementReference =
decltype(*
std::declval<BaseIt>());
419 :
public IteratorFacade<iterator, ElementValue, std::input_iterator_tag, ElementReference>
425 constexpr void advance()
427 while (m_it != m_end && !m_pred(*m_it))
432 using reference = ElementReference;
434 constexpr iterator(BaseIt it, BaseIt end, Predicate pred)
435 : m_it(
std::move(it)), m_end(
std::move(end)), m_pred(
std::move(pred))
440 constexpr reference dereference()
const {
return *m_it; }
441 constexpr void increment()
446 constexpr bool equals(
const iterator &o)
const {
return m_it == o.m_it; };
449 Container &m_container;
454 : m_container(container), m_pred(
std::move(pred))
461 std::begin(m_container),
462 std::end(m_container),
467 constexpr iterator
end()
const
470 std::end(m_container),
471 std::end(m_container),
477template <
typename Predicate>
486template <
typename Container,
typename Predicate>
489 return FilterView<
const Container, Predicate>(container,
std::move(adaptor.pred));
492template <
typename Range,
typename Transform>
495 using BaseIt =
decltype(
std::begin(
std::declval<Range &>()));
499 class iterator :
public IteratorFacade<iterator, TransformedValue, std::input_iterator_tag,
503 Transform m_transform;
506 using reference = TransformedValue;
508 constexpr iterator(BaseIt it, Transform transform)
509 : m_it(
std::move(it)), m_transform(
std::move(transform))
513 constexpr reference dereference()
const {
return std::invoke(m_transform, *m_it); }
514 constexpr void increment() { ++m_it; }
515 constexpr void decrement() { --m_it; }
516 constexpr bool equals(
const iterator &o)
const {
return m_it == o.m_it; }
520 Transform m_transform;
524 : m_range(range), m_transform(
std::move(transform))
528 constexpr iterator
begin()
const {
return iterator{
std::begin(m_range), m_transform }; }
529 constexpr iterator
end()
const {
return iterator{
std::end(m_range), m_transform }; }
532template <
typename Transform>
538template <
typename Container,
typename Transform>
541 return TransformView<
const Container, Transform>(container,
std::move(adaptor.transform));
546template <
typename Container,
typename Predicate>
547constexpr auto filter(
const Container &container, Predicate pred)
552template <
typename Predicate>
558template <
typename Container,
typename Transform>
559constexpr auto transform(
const Container &container, Transform t)
564template <
typename Transform>
575#if __cpp_lib_ranges_stride >= 202207L
588template <
typename Range>
594 constexpr explicit ref_view(Range &range) : m_range(range) { }
596 constexpr auto begin()
const {
return std::begin(m_range); }
597 constexpr auto end()
const {
return std::end(m_range); }
598 constexpr auto data()
const {
return std::data(m_range); }
599 constexpr auto size()
const {
return std::size(m_range); }
600 constexpr bool empty()
const {
return std::empty(m_range); }
603template <
typename Range>
606 using BaseIt =
decltype(
std::begin(
std::declval<
const Range &>()));
607 using StrideReference =
decltype(*
std::declval<BaseIt>());
611 :
public IteratorFacade<iterator, StrideValue, std::input_iterator_tag, StrideReference>
615 std::ptrdiff_t m_stride;
618 using reference = StrideReference;
620 constexpr iterator(BaseIt it, BaseIt end,
std::ptrdiff_t stride)
621 : m_it(
std::move(it)), m_end(
std::move(end)), m_stride(stride)
625 constexpr reference dereference()
const {
return *m_it; }
627 constexpr void increment()
629 for (
std::ptrdiff_t i = 0; i < m_stride && m_it != m_end; ++i)
633 constexpr bool equals(
const iterator &o)
const {
return m_it == o.m_it; }
640 constexpr StrideView(Range range,
std::ptrdiff_t n) : m_range(
std::move(range)), m_n(n) { }
642 constexpr iterator
begin()
const {
return {
std::begin(m_range),
std::end(m_range), m_n }; }
643 constexpr iterator
end()
const {
return {
std::end(m_range),
std::end(m_range), m_n }; }
647 const std::ptrdiff_t total =
std::ptrdiff_t(
std::size(m_range));
648 return (total + m_n - 1) / m_n;
650 constexpr bool empty()
const {
return std::empty(m_range); }
653 ->
decltype(*
std::begin(
std::declval<
const Range &>()))
655 return *(
std::begin(m_range) + n * m_n);
662template <
typename Range>
665 if constexpr (
std::is_lvalue_reference_v<Range>) {
666 using Container = std::remove_reference_t<Range>;
667 return StrideView<ref_view<Container>>{ ref_view<Container>{ range }, n };
674template <
typename Range>
677 return make_stride_view(
std::forward<Range>(range), adaptor
.n);
682template <
typename Range>
685 return impl::make_stride_view(
std::forward<Range>(range), n);
Combined button and popup list for selecting options.