remotemono
RMonoAPIDispatcher_Def.h
1 /*
2  Copyright 2020 David "Alemarius Nexus" Lerch
3 
4  This file is part of RemoteMono.
5 
6  RemoteMono is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  RemoteMono is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with RemoteMono. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #pragma once
21 
22 #include "../config.h"
23 
24 #include <tuple>
25 #include <type_traits>
26 #include <cstdlib>
27 #include "abi/RMonoABI.h"
28 #include "RMonoAPIBackend_Def.h"
29 
30 
31 
32 
33 namespace remotemono
34 {
35 
36 
37 
39 {
40 public:
44  template <typename ABI>
45  struct ABIEntry
46  {
47  typedef ABI ABIType;
48 
49  ABIEntry() : api(&abi) {}
50 
54  ABI abi;
55 
60  };
61 
62 protected:
63  static auto genABIEntryTupleDummy()
64  {
65  return std::apply([](auto... ts) {
66  return std::tuple<ABIEntry<decltype(ts)>...>();
67  }, RMonoSupportedABITuple());
68  }
69 };
70 
71 
72 
78 {
79 public:
80  typedef decltype(RMonoAPIDispatcherBase::genABIEntryTupleDummy()) ABIEntryTuple;
81 
82 public:
83  RMonoAPIDispatcher() : selectedABIIdx(std::tuple_size_v<ABIEntryTuple>) {}
84  ~RMonoAPIDispatcher() {}
85 
86  ABIEntryTuple& getABIEntries() { return abis; }
87 
88 
92  bool hasSelectedABI() const
93  {
94  return selectedABIIdx < std::tuple_size_v<ABIEntryTuple>;
95  }
96 
100  template <typename ABI>
101  void selectABI()
102  {
103  selectedABIIdx = abiIndexOf<ABI>();
104  }
105 
106 
110  template <typename FuncT, size_t idx = 0>
111  typename std::enable_if_t<idx < std::tuple_size_v<ABIEntryTuple>, void> foreach(FuncT f)
112  {
113  f(std::get<idx>(abis));
114  foreach<FuncT, idx+1>(f);
115  }
116 
120  template <typename FuncT, size_t idx = 0>
121  typename std::enable_if_t<idx == std::tuple_size_v<ABIEntryTuple>, void> foreach(FuncT f) {}
122 
123 
124 
129  template <typename FuncT>
130  auto apply(FuncT f) -> decltype(applyInternal<FuncT, 0>(f))
131  {
132  return applyInternal<FuncT, 0>(f);
133  }
134 
135 private:
136  template<typename ABI, size_t idx = 0>
137  constexpr std::enable_if_t<idx < std::tuple_size_v<ABIEntryTuple>, size_t> abiIndexOf()
138  {
139  if constexpr(std::is_same_v<typename std::tuple_element_t<idx, ABIEntryTuple>::ABIType, ABI>) {
140  return idx;
141  } else {
142  return abiIndexOf<ABI, idx+1>();
143  }
144  }
145 
146  template<typename ABI, size_t idx = 0>
147  constexpr std::enable_if_t<idx == std::tuple_size_v<ABIEntryTuple>, size_t> abiIndexOf() { static_assert(false); return 0; }
148 
149  template <typename FuncT, size_t idx>
150  auto applyInternal(FuncT f) -> decltype(f(std::get<0>(abis)))
151  {
152  if constexpr(idx < std::tuple_size_v<ABIEntryTuple>) {
153  if (idx == selectedABIIdx) {
154  return f(std::get<idx>(abis));
155  } else {
156  return applyInternal<FuncT, idx+1>(f);
157  }
158  } else {
159  assert(false);
160  return f(std::get<0>(abis)); // Should never happen, but needed to please the compiler
161  }
162  }
163 
164 
165 private:
166  ABIEntryTuple abis;
167  size_t selectedABIIdx;
168 };
169 
170 
171 
172 }
remotemono::RMonoAPIDispatcher::hasSelectedABI
bool hasSelectedABI() const
Definition: RMonoAPIDispatcher_Def.h:92
remotemono::RMonoAPIDispatcherBase::ABIEntry
Definition: RMonoAPIDispatcher_Def.h:46
remotemono::RMonoAPIDispatcher
Definition: RMonoAPIDispatcher_Def.h:78
remotemono::RMonoAPIDispatcher::selectABI
void selectABI()
Definition: RMonoAPIDispatcher_Def.h:101
remotemono::RMonoAPIDispatcherBase::ABIEntry::api
RMonoAPIBackend< ABI > api
Definition: RMonoAPIDispatcher_Def.h:59
remotemono::RMonoAPIDispatcherBase::ABIEntry::abi
ABI abi
Definition: RMonoAPIDispatcher_Def.h:54
remotemono::RMonoAPIDispatcherBase
Definition: RMonoAPIDispatcher_Def.h:39
remotemono::RMonoAPIBackend
Definition: RMonoAPIBackend_Def.h:388