virthttp  0.0
libvirt http interface
dispatch.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <array>
3 #include <boost/beast/http/verb.hpp>
4 #include <gsl/gsl>
5 #include <rapidjson/document.h>
6 #include "handlers/hdl_ctx.hpp"
7 #include "cexpr_algs.hpp"
8 #include "depends.hpp"
9 
16 template <rapidjson::Type... Vs> struct JTypeList {
17  constexpr static std::array<rapidjson::Type, sizeof...(Vs)> values = {Vs...}; // note: cannot use CTAD because of the empty list case
18 };
19 
20 template <class S, class R = JTypeList<>> class JDispatchVals;
21 class JDispatch;
22 
27 
35 template <rapidjson::Type... Ss, rapidjson::Type... Rs> class JDispatchVals<JTypeList<Ss...>, JTypeList<Rs...>> {
36  friend JDispatch;
37  constexpr static auto singles = JTypeList<Ss...>{}.values;
38  constexpr static auto ranges = JTypeList<Rs...>{}.values;
39 
46  constexpr static bool has_one_in_both() noexcept {
47  for (auto s : singles) {
48  for (auto r : ranges) {
49  if (r == s)
50  return true;
51  }
52  }
53  return false;
54  }
55  static_assert(!has_one_in_both());
56 };
57 
62 class JDispatch {
63  gsl::span<const rapidjson::Type> singles; // C++2a use std::span
64  gsl::span<const rapidjson::Type> ranges; // C++2a use std::span
65 
66  public:
74  template <class JDV> explicit constexpr JDispatch(const JDV& jdv) noexcept : singles(jdv.singles), ranges(jdv.ranges) {}
75 
85  template <class Hdl> auto operator()(const rapidjson::Value& jval, Hdl&& hdl) const {
86  return [&, this, hdl = std::forward<Hdl>(hdl)](HandlerContext& hc) {
87  const auto jtype = jval.GetType();
88  if (!singles.empty() && static_cast<int>(singles[0]) == -1) {
89  return (void)hdl(jval);
90  } else {
91  if (cexpr::find(singles.begin(), singles.end(), jtype) != singles.end())
92  return (void)hdl(jval);
93  }
94  if (cexpr::find(ranges.begin(), ranges.end(), jtype) != ranges.end())
95  return handle_depends(jval, hc.json_res, hdl);
96  return hc.json_res.error(3);
97  };
98  }
99 };
100 
101 template <class... JDVs, std::size_t... I>
102 constexpr auto gen_jdispatchers_impl(const std::tuple<JDVs...>& tup, std::index_sequence<I...>) noexcept -> std::array<JDispatch, sizeof...(JDVs)> {
103  constexpr auto mk_jdisp = [](const auto& jdv) { return JDispatch{jdv}; };
104  return std::array{mk_jdisp(std::get<I>(tup))...};
105 }
106 
115 template <class... JDVs> constexpr auto gen_jdispatchers(const std::tuple<JDVs...>& tup) noexcept -> std::array<JDispatch, sizeof...(JDVs)> {
116  return gen_jdispatchers_impl(tup, std::index_sequence_for<JDVs...>{});
117 }
constexpr auto gen_jdispatchers(const std::tuple< JDVs... > &tup) noexcept-> std::array< JDispatch, sizeof...(JDVs)>
Definition: dispatch.hpp:115
void error(int code)
Definition: json_utils.hpp:57
STL namespace.
Definition: dispatch.hpp:62
Definition: dispatch.hpp:16
auto operator()(const rapidjson::Value &jval, Hdl &&hdl) const
Definition: dispatch.hpp:85
constexpr JDispatch(const JDV &jdv) noexcept
Definition: dispatch.hpp:74
Definition: dispatch.hpp:20
Definition: hdl_ctx.hpp:11
void handle_depends(const rapidjson::Value &json_req, JsonRes &json_res, Hdl &&hdl)
Definition: depends.hpp:33
JsonRes & json_res
the result of running the handlers to be sent to the client
Definition: hdl_ctx.hpp:13
static constexpr std::array< rapidjson::Type, sizeof...(Vs)> values
Definition: dispatch.hpp:17
constexpr InputIt find(InputIt first, InputIt last, const T &value)
Definition: cexpr_algs.hpp:4
constexpr auto gen_jdispatchers_impl(const std::tuple< JDVs... > &tup, std::index_sequence< I... >) noexcept-> std::array< JDispatch, sizeof...(JDVs)>
Definition: dispatch.hpp:102