| 1 | // Copyright (C) 2020 Mikhail Svetkin <[email protected]> | 
|---|
| 2 | // Copyright (C) 2019 The Qt Company Ltd. | 
|---|
| 3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only | 
|---|
| 4 |  | 
|---|
| 5 | #ifndef QHTTPSERVERROUTERVIEWTRAITS_H | 
|---|
| 6 | #define QHTTPSERVERROUTERVIEWTRAITS_H | 
|---|
| 7 |  | 
|---|
| 8 | #include <QtHttpServer/qhttpserverviewtraits_impl.h> | 
|---|
| 9 |  | 
|---|
| 10 | QT_BEGIN_NAMESPACE | 
|---|
| 11 |  | 
|---|
| 12 | class QHttpServerRequest; | 
|---|
| 13 | class QHttpServerResponder; | 
|---|
| 14 |  | 
|---|
| 15 | namespace QtPrivate { | 
|---|
| 16 |  | 
|---|
| 17 | template<typename ViewHandler, bool DisableStaticAssert> | 
|---|
| 18 | struct RouterViewTraitsHelper : ViewTraits<ViewHandler, DisableStaticAssert> { | 
|---|
| 19 | using VTraits = ViewTraits<ViewHandler, DisableStaticAssert>; | 
|---|
| 20 | using FunctionTraits = typename VTraits::FTraits; | 
|---|
| 21 |  | 
|---|
| 22 | template<int I> | 
|---|
| 23 | struct ArgumentChecker : FunctionTraits::template Arg<I> { | 
|---|
| 24 | using IsRequest = typename VTraits::template Special<I, const QHttpServerRequest &>; | 
|---|
| 25 | static_assert(IsRequest::AssertCondition, | 
|---|
| 26 | "ViewHandler arguments error: " | 
|---|
| 27 | "QHttpServerRequest can only be passed as a const reference"); | 
|---|
| 28 |  | 
|---|
| 29 | using IsResponder = typename VTraits::template Special<I, QHttpServerResponder &>; | 
|---|
| 30 | static_assert(IsResponder::AssertCondition, | 
|---|
| 31 | "ViewHandler arguments error: " | 
|---|
| 32 | "QHttpServerResponder can only be passed as a reference"); | 
|---|
| 33 |  | 
|---|
| 34 | using IsSpecial = CheckAny<IsRequest, IsResponder>; | 
|---|
| 35 |  | 
|---|
| 36 | struct IsSimple { | 
|---|
| 37 | static constexpr bool Value = !IsSpecial::Value && | 
|---|
| 38 | I < FunctionTraits::ArgumentCount && | 
|---|
| 39 | FunctionTraits::ArgumentIndexMax != -1; | 
|---|
| 40 | static constexpr bool Valid = FunctionTraits::template Arg<I>::CopyConstructible; | 
|---|
| 41 |  | 
|---|
| 42 | static constexpr bool StaticAssert = | 
|---|
| 43 | DisableStaticAssert || !Value || Valid; | 
|---|
| 44 |  | 
|---|
| 45 |  | 
|---|
| 46 | static_assert(StaticAssert, | 
|---|
| 47 | "ViewHandler arguments error: " | 
|---|
| 48 | "Type is not copy constructible"); | 
|---|
| 49 | }; | 
|---|
| 50 |  | 
|---|
| 51 | using CheckOk = CheckAny<IsSimple, IsSpecial>; | 
|---|
| 52 |  | 
|---|
| 53 | static constexpr bool Valid = CheckOk::Valid; | 
|---|
| 54 | static constexpr bool StaticAssert = CheckOk::StaticAssert; | 
|---|
| 55 | }; | 
|---|
| 56 |  | 
|---|
| 57 |  | 
|---|
| 58 | struct Arguments { | 
|---|
| 59 | template<int ... I> | 
|---|
| 60 | struct ArgumentsReturn { | 
|---|
| 61 | template<int Idx> | 
|---|
| 62 | using Arg = ArgumentChecker<Idx>; | 
|---|
| 63 |  | 
|---|
| 64 | template<int Idx> | 
|---|
| 65 | static constexpr QMetaType metaType() noexcept | 
|---|
| 66 | { | 
|---|
| 67 | using Type = typename FunctionTraits::template Arg<Idx>::CleanType; | 
|---|
| 68 |  | 
|---|
| 69 | if constexpr (std::conjunction_v<std::is_copy_constructible<Type>, std::is_copy_assignable<Type>>) | 
|---|
| 70 | return QMetaType::fromType<Type>(); | 
|---|
| 71 | else | 
|---|
| 72 | return QMetaType::fromType<void>(); | 
|---|
| 73 | } | 
|---|
| 74 |  | 
|---|
| 75 | static constexpr std::size_t Count = FunctionTraits::ArgumentCount; | 
|---|
| 76 | static constexpr std::size_t CapturableCount = | 
|---|
| 77 | (0 + ... + static_cast<std::size_t>(FunctionTraits::template Arg<I>::CopyConstructible)); | 
|---|
| 78 |  | 
|---|
| 79 | static constexpr std::size_t PlaceholdersCount = Count - CapturableCount; | 
|---|
| 80 |  | 
|---|
| 81 | static constexpr bool Valid = (Arg<I>::Valid && ...); | 
|---|
| 82 | static constexpr bool StaticAssert = (Arg<I>::StaticAssert && ...); | 
|---|
| 83 |  | 
|---|
| 84 | using Indexes = typename QtPrivate::IndexesList<I...>; | 
|---|
| 85 |  | 
|---|
| 86 | using CapturableIndexes = | 
|---|
| 87 | typename QtPrivate::Indexes<CapturableCount>::Value; | 
|---|
| 88 |  | 
|---|
| 89 | using PlaceholdersIndexes = | 
|---|
| 90 | typename QtPrivate::Indexes<PlaceholdersCount>::Value; | 
|---|
| 91 |  | 
|---|
| 92 | using Last = Arg<FunctionTraits::ArgumentIndexMax>; | 
|---|
| 93 | }; | 
|---|
| 94 |  | 
|---|
| 95 | template<int ... I> | 
|---|
| 96 | static constexpr ArgumentsReturn<I...> eval(QtPrivate::IndexesList<I...>) noexcept; | 
|---|
| 97 | }; | 
|---|
| 98 |  | 
|---|
| 99 | template<int CaptureOffset> | 
|---|
| 100 | struct BindType { | 
|---|
| 101 | template<typename ... Args> | 
|---|
| 102 | struct FunctionWrapper { | 
|---|
| 103 | using Type = std::function<typename FunctionTraits::ReturnType (Args...)>; | 
|---|
| 104 | }; | 
|---|
| 105 |  | 
|---|
| 106 | template<int Id> | 
|---|
| 107 | using OffsetArg = typename FunctionTraits::template Arg<CaptureOffset + Id>::Type; | 
|---|
| 108 |  | 
|---|
| 109 | template<int ... Idx> | 
|---|
| 110 | static constexpr typename FunctionWrapper<OffsetArg<Idx>...>::Type | 
|---|
| 111 | eval(QtPrivate::IndexesList<Idx...>) noexcept; | 
|---|
| 112 | }; | 
|---|
| 113 | }; | 
|---|
| 114 |  | 
|---|
| 115 |  | 
|---|
| 116 | } // namespace QtPrivate | 
|---|
| 117 |  | 
|---|
| 118 | template <typename ViewHandler, bool DisableStaticAssert = false> | 
|---|
| 119 | struct QHttpServerRouterViewTraits | 
|---|
| 120 | { | 
|---|
| 121 | using Helpers = typename QtPrivate::RouterViewTraitsHelper<ViewHandler, DisableStaticAssert>; | 
|---|
| 122 | using ReturnType = typename Helpers::FunctionTraits::ReturnType; | 
|---|
| 123 | using Arguments = decltype(Helpers::Arguments::eval(typename Helpers::ArgumentIndexes{})); | 
|---|
| 124 | using BindableType = decltype( | 
|---|
| 125 | Helpers::template BindType<Arguments::CapturableCount>::eval( | 
|---|
| 126 | typename Arguments::PlaceholdersIndexes{})); | 
|---|
| 127 | }; | 
|---|
| 128 |  | 
|---|
| 129 |  | 
|---|
| 130 | QT_END_NAMESPACE | 
|---|
| 131 |  | 
|---|
| 132 | #endif  // QHTTPSERVERROUTERVIEWTRAITS_H | 
|---|
| 133 |  | 
|---|