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
16QT_BEGIN_NAMESPACE
17
18namespace QtPrivate {
19
20template<typename ReturnT, typename... Args>
21struct 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
37template<typename T>
38struct FunctionTraitsImpl;
39
40template<typename T>
41struct FunctionTraitsImpl : public FunctionTraitsImpl<decltype(&T::operator())>
42{
43};
44
45template<typename ReturnT, typename... Args>
46struct FunctionTraitsImpl<ReturnT (*)(Args...)> : public FunctionTraitsHelper<ReturnT, Args...>
47{
48};
49
50template<class ReturnT, class ClassT, class... Args>
51struct FunctionTraitsImpl<ReturnT (ClassT::*)(Args...) const>
52 : public FunctionTraitsHelper<ReturnT, Args...>
53{
54};
55
56template<typename T>
57using FunctionTraits = FunctionTraitsImpl<std::decay_t<T>>;
58
59template<typename ... T>
60struct CheckAny {
61 static constexpr bool Value = (T::Value || ...);
62 static constexpr bool Valid = (T::Valid || ...);
63 static constexpr bool StaticAssert = (T::StaticAssert || ...);
64};
65
66template<typename ViewHandler, bool DisableStaticAssert>
67struct 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
110QT_END_NAMESPACE
111
112#endif // QHTTPSERVERVIEWTRAITS_IMPL_H
113

source code of qthttpserver/src/httpserver/qhttpserverviewtraits_impl.h