blob: fa399d62d3c426d1573a7c485d5b3db78e525469 [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
2
Ed Tanousc94ad492019-10-10 15:39:33 -07003#include "http_request.h"
4#include "http_response.h"
5#include "utility.h"
Ed Tanous7045c8d2017-04-03 10:04:37 -07006
Ed Tanous1abe55e2018-09-05 08:30:59 -07007namespace crow
8{
9namespace detail
10{
Ed Tanous7045c8d2017-04-03 10:04:37 -070011template <typename... Middlewares>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050012struct PartialContext :
13 public black_magic::PopBack<Middlewares...>::template rebind<
14 PartialContext>,
15 public black_magic::LastElementType<Middlewares...>::type::Context
Ed Tanous1abe55e2018-09-05 08:30:59 -070016{
17 using parent_context = typename black_magic::PopBack<
18 Middlewares...>::template rebind<::crow::detail::PartialContext>;
Ed Tanous271584a2019-07-09 16:24:22 -070019 template <size_t N>
Ed Tanous1abe55e2018-09-05 08:30:59 -070020 using partial = typename std::conditional<
21 N == sizeof...(Middlewares) - 1, PartialContext,
22 typename parent_context::template partial<N>>::type;
Ed Tanous7045c8d2017-04-03 10:04:37 -070023
Gunnar Mills1214b7e2020-06-04 10:11:30 -050024 template <typename T>
25 typename T::Context& get()
Ed Tanous1abe55e2018-09-05 08:30:59 -070026 {
27 return static_cast<typename T::Context&>(*this);
28 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070029};
30
Gunnar Mills1214b7e2020-06-04 10:11:30 -050031template <>
32struct PartialContext<>
Ed Tanous1abe55e2018-09-05 08:30:59 -070033{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050034 template <size_t>
35 using partial = PartialContext;
Ed Tanous7045c8d2017-04-03 10:04:37 -070036};
37
Ed Tanous271584a2019-07-09 16:24:22 -070038template <size_t N, typename Context, typename Container, typename CurrentMW,
Ed Tanous7045c8d2017-04-03 10:04:37 -070039 typename... Middlewares>
Ed Tanous55c7b7a2018-05-22 15:27:24 -070040bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
41 Context& ctx);
Ed Tanous7045c8d2017-04-03 10:04:37 -070042
43template <typename... Middlewares>
Ed Tanous55c7b7a2018-05-22 15:27:24 -070044struct Context : private PartialContext<Middlewares...>
45// struct Context : private Middlewares::context... // simple but less type-safe
Ed Tanous7045c8d2017-04-03 10:04:37 -070046{
Ed Tanous271584a2019-07-09 16:24:22 -070047 template <size_t N, typename Context, typename Container>
Ed Tanous1abe55e2018-09-05 08:30:59 -070048 friend typename std::enable_if<(N == 0)>::type
49 afterHandlersCallHelper(Container& middlewares, Context& ctx,
50 Request& req, Response& res);
Ed Tanous271584a2019-07-09 16:24:22 -070051 template <size_t N, typename Context, typename Container>
Ed Tanous1abe55e2018-09-05 08:30:59 -070052 friend typename std::enable_if<(N > 0)>::type
53 afterHandlersCallHelper(Container& middlewares, Context& ctx,
54 Request& req, Response& res);
Ed Tanous7045c8d2017-04-03 10:04:37 -070055
Ed Tanous271584a2019-07-09 16:24:22 -070056 template <size_t N, typename Context, typename Container,
57 typename CurrentMW, typename... Middlewares2>
Ed Tanous1abe55e2018-09-05 08:30:59 -070058 friend bool middlewareCallHelper(Container& middlewares, Request& req,
59 Response& res, Context& ctx);
Ed Tanous7045c8d2017-04-03 10:04:37 -070060
Gunnar Mills1214b7e2020-06-04 10:11:30 -050061 template <typename T>
62 typename T::Context& get()
Ed Tanous1abe55e2018-09-05 08:30:59 -070063 {
64 return static_cast<typename T::Context&>(*this);
65 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070066
Ed Tanous271584a2019-07-09 16:24:22 -070067 template <size_t N>
Ed Tanous1abe55e2018-09-05 08:30:59 -070068 using partial =
69 typename PartialContext<Middlewares...>::template partial<N>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070070};
Ed Tanous1abe55e2018-09-05 08:30:59 -070071} // namespace detail
72} // namespace crow