1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QMAKEARRAY_P_H
5#define QMAKEARRAY_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "QtCore/private/qglobal_p.h"
19
20#include <array>
21#include <type_traits>
22#include <utility>
23
24QT_BEGIN_NAMESPACE
25
26namespace QtPrivate {
27template<typename T>
28constexpr T &&Forward(typename std::remove_reference<T>::type &t) noexcept
29{
30 return static_cast<T &&>(t);
31}
32
33template<typename T>
34constexpr T &&Forward(typename std::remove_reference<T>::type &&t) noexcept
35{
36 static_assert(!std::is_lvalue_reference<T>::value,
37 "template argument substituting T is an lvalue reference type");
38 return static_cast<T &&>(t);
39}
40
41template <typename ManualType, typename ...>
42struct ArrayTypeHelper
43{
44 using type = ManualType;
45};
46
47template <typename ... Types>
48struct ArrayTypeHelper<void, Types...> : std::common_type<Types...> { };
49
50template <typename ManualType, typename... Types>
51using ArrayType = std::array<typename ArrayTypeHelper<ManualType, Types...>::type,
52 sizeof...(Types)>;
53
54template<typename ... Values>
55struct QuickSortData { };
56
57template <template <typename> class Predicate,
58 typename ... Values>
59struct QuickSortFilter;
60
61template <typename ... Right, typename ... Left>
62constexpr QuickSortData<Right..., Left...> quickSortConcat(
63 QuickSortData<Right...>, QuickSortData<Left...>) noexcept;
64
65template<typename ... Right, typename Middle, typename ... Left>
66constexpr QuickSortData<Right..., Middle, Left...> quickSortConcat(
67 QuickSortData<Right...>,
68 QuickSortData<Middle>,
69 QuickSortData<Left...>) noexcept;
70
71template <template <typename> class Predicate,
72 typename Head, typename ... Tail>
73struct QuickSortFilter<Predicate, QuickSortData<Head, Tail...>>
74{
75 using TailFilteredData = typename QuickSortFilter<
76 Predicate, QuickSortData<Tail...>>::Type;
77
78 using Type = typename std::conditional<
79 Predicate<Head>::value,
80 decltype(quickSortConcat(QuickSortData<Head> {}, TailFilteredData{})),
81 TailFilteredData>::type;
82};
83
84template <template <typename> class Predicate>
85struct QuickSortFilter<Predicate, QuickSortData<>>
86{
87 using Type = QuickSortData<>;
88};
89
90template <typename ... Values>
91struct QuickSort;
92
93template <typename Pivot, typename ... Values>
94struct QuickSort<QuickSortData<Pivot, Values...>>
95{
96 template <typename Left>
97 struct LessThan {
98 static constexpr const bool value = Left::data() <= Pivot::data();
99 };
100
101 template <typename Left>
102 struct MoreThan {
103 static constexpr const bool value = !(Left::data() <= Pivot::data());
104 };
105
106 using LeftSide = typename QuickSortFilter<LessThan, QuickSortData<Values...>>::Type;
107 using RightSide = typename QuickSortFilter<MoreThan, QuickSortData<Values...>>::Type;
108
109 using LeftQS = typename QuickSort<LeftSide>::Type;
110 using RightQS = typename QuickSort<RightSide>::Type;
111
112 using Type = decltype(quickSortConcat(LeftQS{}, QuickSortData<Pivot> {}, RightQS{}));
113
114};
115
116template <>
117struct QuickSort<QuickSortData<>>
118{
119 using Type = QuickSortData<>;
120};
121} // namespace QtPrivate
122
123template <typename ManualType = void, typename ... Types>
124constexpr QtPrivate::ArrayType<ManualType, Types...> qMakeArray(Types && ... t) noexcept
125{
126 return {{QtPrivate::Forward<typename QtPrivate::ArrayType<ManualType, Types...>::value_type>(t)...}};
127}
128
129template<typename ... Values>
130struct QSortedData {
131 using Data = typename QtPrivate::QuickSort<typename QtPrivate::QuickSortData<Values...>>::Type;
132};
133
134template<typename ... Values>
135constexpr auto qMakeArray(QtPrivate::QuickSortData<Values...>) noexcept -> decltype(qMakeArray(Values::data()...))
136{
137 return qMakeArray(Values::data() ...);
138}
139
140
141QT_END_NAMESPACE
142
143#endif // QMAKEARRAY_P_H
144

source code of qtbase/src/corelib/tools/qmakearray_p.h