blob: fbe1d80e968f2f3b6102f4c757d3757903ccda9c [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>
Ed Tanous55c7b7a2018-05-22 15:27:24 -070012struct PartialContext
13 : public black_magic::PopBack<Middlewares...>::template rebind<
14 PartialContext>,
Ed Tanous1abe55e2018-09-05 08:30:59 -070015 public black_magic::LastElementType<Middlewares...>::type::Context
16{
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
Ed Tanous1abe55e2018-09-05 08:30:59 -070024 template <typename T> typename T::Context& get()
25 {
26 return static_cast<typename T::Context&>(*this);
27 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070028};
29
Ed Tanous1abe55e2018-09-05 08:30:59 -070030template <> struct PartialContext<>
31{
Ed Tanous271584a2019-07-09 16:24:22 -070032 template <size_t> using partial = PartialContext;
Ed Tanous7045c8d2017-04-03 10:04:37 -070033};
34
Ed Tanous271584a2019-07-09 16:24:22 -070035template <size_t N, typename Context, typename Container, typename CurrentMW,
Ed Tanous7045c8d2017-04-03 10:04:37 -070036 typename... Middlewares>
Ed Tanous55c7b7a2018-05-22 15:27:24 -070037bool middlewareCallHelper(Container& middlewares, Request& req, Response& res,
38 Context& ctx);
Ed Tanous7045c8d2017-04-03 10:04:37 -070039
40template <typename... Middlewares>
Ed Tanous55c7b7a2018-05-22 15:27:24 -070041struct Context : private PartialContext<Middlewares...>
42// struct Context : private Middlewares::context... // simple but less type-safe
Ed Tanous7045c8d2017-04-03 10:04:37 -070043{
Ed Tanous271584a2019-07-09 16:24:22 -070044 template <size_t N, typename Context, typename Container>
Ed Tanous1abe55e2018-09-05 08:30:59 -070045 friend typename std::enable_if<(N == 0)>::type
46 afterHandlersCallHelper(Container& middlewares, Context& ctx,
47 Request& req, Response& res);
Ed Tanous271584a2019-07-09 16:24:22 -070048 template <size_t N, typename Context, typename Container>
Ed Tanous1abe55e2018-09-05 08:30:59 -070049 friend typename std::enable_if<(N > 0)>::type
50 afterHandlersCallHelper(Container& middlewares, Context& ctx,
51 Request& req, Response& res);
Ed Tanous7045c8d2017-04-03 10:04:37 -070052
Ed Tanous271584a2019-07-09 16:24:22 -070053 template <size_t N, typename Context, typename Container,
54 typename CurrentMW, typename... Middlewares2>
Ed Tanous1abe55e2018-09-05 08:30:59 -070055 friend bool middlewareCallHelper(Container& middlewares, Request& req,
56 Response& res, Context& ctx);
Ed Tanous7045c8d2017-04-03 10:04:37 -070057
Ed Tanous1abe55e2018-09-05 08:30:59 -070058 template <typename T> typename T::Context& get()
59 {
60 return static_cast<typename T::Context&>(*this);
61 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070062
Ed Tanous271584a2019-07-09 16:24:22 -070063 template <size_t N>
Ed Tanous1abe55e2018-09-05 08:30:59 -070064 using partial =
65 typename PartialContext<Middlewares...>::template partial<N>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070066};
Ed Tanous1abe55e2018-09-05 08:30:59 -070067} // namespace detail
68} // namespace crow