// Copyright (C) 2020 Mikhail Svetkin // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QHTTPSERVERROUTERVIEWTRAITS_H #define QHTTPSERVERROUTERVIEWTRAITS_H #include QT_BEGIN_NAMESPACE class QHttpServerRequest; class QHttpServerResponder; namespace QtPrivate { template struct RouterViewTraitsHelper : ViewTraits { using VTraits = ViewTraits; using FunctionTraits = typename VTraits::FTraits; template struct ArgumentChecker : FunctionTraits::template Arg { using IsRequest = typename VTraits::template Special; static_assert(IsRequest::AssertCondition, "ViewHandler arguments error: " "QHttpServerRequest can only be passed as a const reference"); using IsResponder = typename VTraits::template Special; static_assert(IsResponder::AssertCondition, "ViewHandler arguments error: " "QHttpServerResponder can only be passed as a reference"); using IsSpecial = CheckAny; struct IsSimple { static constexpr bool Value = !IsSpecial::Value && I < FunctionTraits::ArgumentCount && FunctionTraits::ArgumentIndexMax != -1; static constexpr bool Valid = !IsSpecial::Valid && FunctionTraits::template Arg::CopyConstructible; static constexpr bool StaticAssert = DisableStaticAssert || !Value || Valid; static_assert(StaticAssert, "ViewHandler arguments error: " "Type is not copy constructible"); }; using CheckOk = CheckAny; static constexpr bool Valid = CheckOk::Valid; static constexpr bool StaticAssert = CheckOk::StaticAssert; }; struct Arguments { template struct ArgumentsReturn { template using Arg = ArgumentChecker; template static constexpr QMetaType metaType() noexcept { using Type = typename FunctionTraits::template Arg::CleanType; constexpr bool Simple = Arg::IsSimple::Valid; if constexpr (Simple && std::is_copy_assignable_v) return QMetaType::fromType(); else return QMetaType::fromType(); } static constexpr std::size_t Count = FunctionTraits::ArgumentCount; static constexpr std::size_t CapturableCount = (0 + ... + static_cast(!Arg::IsSpecial::Value)); static constexpr std::size_t SpecialsCount = Count - CapturableCount; static constexpr bool Valid = (Arg::Valid && ...); static constexpr bool StaticAssert = (Arg::StaticAssert && ...); using Indexes = std::index_sequence; using CapturableIndexes = std::make_index_sequence; using SpecialIndexes = std::make_index_sequence; using Last = Arg; }; template static constexpr ArgumentsReturn eval(std::index_sequence) noexcept; }; template struct BindType { template struct FunctionWrapper { using Type = std::function; }; template using OffsetArg = typename FunctionTraits::template Arg::Type; template static constexpr typename FunctionWrapper...>::Type eval(std::index_sequence) noexcept; }; }; } // namespace QtPrivate template struct QHttpServerRouterViewTraits { using Helpers = typename QtPrivate::RouterViewTraitsHelper; using ReturnType = typename Helpers::FunctionTraits::ReturnType; using Arguments = decltype(Helpers::Arguments::eval(typename Helpers::ArgumentIndexes{})); using BindableType = decltype(Helpers::template BindType::eval( typename Arguments::SpecialIndexes{})); }; QT_END_NAMESPACE #endif // QHTTPSERVERROUTERVIEWTRAITS_H