1 | // Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com> |
2 | // Copyright (C) 2019 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #ifndef QHTTPSERVERVIEWTRAITS_IMPL_H |
6 | #define QHTTPSERVERVIEWTRAITS_IMPL_H |
7 | |
8 | #include <QtCore/qglobal.h> |
9 | #include <QtCore/qmetatype.h> |
10 | #include <QtCore/qnamespace.h> |
11 | #include <QtCore/qobjectdefs.h> |
12 | |
13 | #include <tuple> |
14 | #include <type_traits> |
15 | |
16 | QT_BEGIN_NAMESPACE |
17 | |
18 | namespace QtPrivate { |
19 | |
20 | template<typename ReturnT, typename... Args> |
21 | struct FunctionTraitsHelper |
22 | { |
23 | static constexpr const int ArgumentCount = sizeof ... (Args); |
24 | static constexpr const int ArgumentIndexMax = ArgumentCount - 1; |
25 | using ReturnType = ReturnT; |
26 | |
27 | template <int I> |
28 | struct Arg { |
29 | using Type = typename std::tuple_element<I, std::tuple<Args...>>::type; |
30 | |
31 | using CleanType = q20::remove_cvref_t<Type>; |
32 | |
33 | static constexpr bool CopyConstructible = std::is_copy_constructible_v<CleanType>; |
34 | }; |
35 | }; |
36 | |
37 | template<typename T> |
38 | struct FunctionTraitsImpl; |
39 | |
40 | template<typename T> |
41 | struct FunctionTraitsImpl : public FunctionTraitsImpl<decltype(&T::operator())> |
42 | { |
43 | }; |
44 | |
45 | template<typename ReturnT, typename... Args> |
46 | struct FunctionTraitsImpl<ReturnT (*)(Args...)> : public FunctionTraitsHelper<ReturnT, Args...> |
47 | { |
48 | }; |
49 | |
50 | template<class ReturnT, class ClassT, class... Args> |
51 | struct FunctionTraitsImpl<ReturnT (ClassT::*)(Args...) const> |
52 | : public FunctionTraitsHelper<ReturnT, Args...> |
53 | { |
54 | }; |
55 | |
56 | template<typename T> |
57 | using FunctionTraits = FunctionTraitsImpl<std::decay_t<T>>; |
58 | |
59 | template<typename ... T> |
60 | struct CheckAny { |
61 | static constexpr bool Value = (T::Value || ...); |
62 | static constexpr bool Valid = (T::Valid || ...); |
63 | static constexpr bool StaticAssert = (T::StaticAssert || ...); |
64 | }; |
65 | |
66 | template<typename ViewHandler, bool DisableStaticAssert> |
67 | struct ViewTraits { |
68 | using FTraits = FunctionTraits<ViewHandler>; |
69 | using ArgumentIndexes = typename Indexes<FTraits::ArgumentCount>::Value; |
70 | |
71 | template<int I, typename Special> |
72 | struct SpecialHelper { |
73 | using Arg = typename FTraits::template Arg<I>; |
74 | using CleanSpecialT = q20::remove_cvref_t<Special>; |
75 | |
76 | static constexpr bool TypeMatched = std::is_same<typename Arg::CleanType, CleanSpecialT>::value; |
77 | static constexpr bool TypeCVRefMatched = std::is_same<typename Arg::Type, Special>::value; |
78 | |
79 | static constexpr bool ValidPosition = |
80 | (I == FTraits::ArgumentIndexMax || |
81 | I == FTraits::ArgumentIndexMax - 1); |
82 | static constexpr bool ValidAll = TypeCVRefMatched && ValidPosition; |
83 | |
84 | static constexpr bool AssertCondition = |
85 | DisableStaticAssert || !TypeMatched || TypeCVRefMatched; |
86 | |
87 | static constexpr bool AssertConditionOrder = |
88 | DisableStaticAssert || !TypeMatched || ValidPosition; |
89 | |
90 | static constexpr bool StaticAssert = AssertCondition && AssertConditionOrder; |
91 | |
92 | static_assert(AssertConditionOrder, |
93 | "ViewHandler arguments error: " |
94 | "QHttpServerRequest or QHttpServerResponder" |
95 | " can only be the last argument" ); |
96 | }; |
97 | |
98 | template<int I, typename T> |
99 | struct Special { |
100 | using Helper = SpecialHelper<I, T>; |
101 | static constexpr bool Value = Helper::TypeMatched; |
102 | static constexpr bool Valid = Helper::ValidAll; |
103 | static constexpr bool StaticAssert = Helper::StaticAssert; |
104 | static constexpr bool AssertCondition = Helper::AssertCondition; |
105 | }; |
106 | }; |
107 | |
108 | } // namespace QtPrivate |
109 | |
110 | QT_END_NAMESPACE |
111 | |
112 | #endif // QHTTPSERVERVIEWTRAITS_IMPL_H |
113 | |