OGLplus  (0.59.0) a C++ wrapper for rendering APIs

decay_modes.hpp
1 #ifndef EAGINE_EXAMPLE_ECS_DECAY_MODES_HPP // NOLINT(llvm-header-guard)
9 #define EAGINE_EXAMPLE_ECS_DECAY_MODES_HPP
10 
11 #include "entity.hpp"
12 #include <eagine/flat_map.hpp>
13 #include <eagine/identifier.hpp>
14 #include <eagine/mp_list.hpp>
15 #include <type_traits>
16 
17 namespace eagine {
18 //------------------------------------------------------------------------------
19 enum class decay_part {
20  alpha,
21  beta_p,
22  beta_m,
23  proton_emi,
24  neutron_emi,
25  electron_cap,
26  fission,
27  transition
28 };
29 //------------------------------------------------------------------------------
30 template <decay_part... M>
31 using decay_mode_t = std::integer_sequence<decay_part, M...>;
32 //------------------------------------------------------------------------------
33 template <decay_part... M>
34 constexpr auto is_fission_v = (false || ... || (M == decay_part::fission));
35 //------------------------------------------------------------------------------
36 struct decay_mode_info {
37  std::string symbol;
38  int proton_count_diff{0};
39  int neutron_count_diff{0};
40  bool is_fission{false};
41 };
42 //------------------------------------------------------------------------------
43 template <typename T>
44 struct decay_mode_traits;
45 //------------------------------------------------------------------------------
46 template <decay_part... M>
47 static inline auto mode_info(decay_mode_t<M...> = {})
48  -> const decay_mode_info& {
49  return decay_mode_traits<decay_mode_t<M...>>::info();
50 }
51 //------------------------------------------------------------------------------
52 template <>
53 struct decay_mode_traits<decay_mode_t<decay_part::alpha>> {
54  static auto info() noexcept -> const auto& {
55  static const decay_mode_info i{"α", -2, -2, false};
56  return i;
57  }
58 };
59 //------------------------------------------------------------------------------
60 template <>
61 struct decay_mode_traits<decay_mode_t<decay_part::beta_p>> {
62  static auto info() noexcept -> const auto& {
63  static const decay_mode_info i{"β⁺", -1, 1, false};
64  return i;
65  }
66 };
67 //------------------------------------------------------------------------------
68 template <>
69 struct decay_mode_traits<decay_mode_t<decay_part::beta_m>> {
70  static auto info() noexcept -> const auto& {
71  static const decay_mode_info i{"β⁻", 1, -1, false};
72  return i;
73  }
74 };
75 //------------------------------------------------------------------------------
76 template <>
77 struct decay_mode_traits<decay_mode_t<decay_part::proton_emi>> {
78  static auto info() noexcept -> const auto& {
79  static const decay_mode_info i{"p⁺", -1, 0, false};
80  return i;
81  }
82 };
83 //------------------------------------------------------------------------------
84 template <>
85 struct decay_mode_traits<decay_mode_t<decay_part::neutron_emi>> {
86  static auto info() noexcept -> const auto& {
87  static const decay_mode_info i{"n⁰", 0, -1, false};
88  return i;
89  }
90 };
91 //------------------------------------------------------------------------------
92 template <>
93 struct decay_mode_traits<decay_mode_t<decay_part::electron_cap>> {
94  static auto info() noexcept -> const auto& {
95  static const decay_mode_info i{"+e⁻", -1, 1, false};
96  return i;
97  }
98 };
99 //------------------------------------------------------------------------------
100 template <>
101 struct decay_mode_traits<decay_mode_t<decay_part::fission>> {
102  static auto info() noexcept -> const auto& {
103  static const decay_mode_info i{"≺", 0, 0, true};
104  return i;
105  }
106 };
107 //------------------------------------------------------------------------------
108 template <>
109 struct decay_mode_traits<decay_mode_t<decay_part::transition>> {
110  static auto info() noexcept -> const auto& {
111  static const decay_mode_info i{"IT", 0, 0, false};
112  return i;
113  }
114 };
115 //------------------------------------------------------------------------------
116 template <decay_part... P>
117 struct decay_mode_traits<decay_mode_t<P...>> {
118 private:
119  template <decay_part H>
120  static void _append_symbol(decay_mode_t<H> m, std::string& s) {
121  s.append(mode_info(m).symbol);
122  }
123 
124  template <decay_part H, decay_part N, decay_part... T>
125  static void _append_symbol(decay_mode_t<H, N, T...>, std::string& s) {
126  s.append(mode_info(decay_mode_t<H>{}).symbol);
127  s.append(",");
128  _append_symbol(decay_mode_t<N, T...>{}, s);
129  }
130 
131  static auto _make_symbol() noexcept {
132  std::string s;
133  _append_symbol(decay_mode_t<P...>{}, s);
134  return s;
135  }
136 
137 public:
138  static auto info() noexcept -> const auto& {
139  static const decay_mode_info i{
140  _make_symbol(),
141  (0 + ... + mode_info(decay_mode_t<P>{}).proton_count_diff),
142  (0 + ... + mode_info(decay_mode_t<P>{}).neutron_count_diff),
143  is_fission_v<P...>};
144  return i;
145  }
146 };
147 //------------------------------------------------------------------------------
148 template <typename DecayMode>
149 struct decay_mode_id;
150 
151 template <>
152 struct decay_mode_id<decay_mode_t<decay_part::alpha>>
153  : selector<EAGINE_ID_V(AlphaDcy)> {};
154 
155 template <>
156 struct decay_mode_id<decay_mode_t<decay_part::proton_emi>>
157  : selector<EAGINE_ID_V(PrtnEmissn)> {};
158 
159 template <>
160 struct decay_mode_id<decay_mode_t<decay_part::neutron_emi>>
161  : selector<EAGINE_ID_V(NtrnEmissn)> {};
162 
163 template <>
164 struct decay_mode_id<decay_mode_t<decay_part::electron_cap>>
165  : selector<EAGINE_ID_V(ElnCapDcy)> {};
166 
167 template <>
168 struct decay_mode_id<
169  decay_mode_t<decay_part::electron_cap, decay_part::electron_cap>>
170  : selector<EAGINE_ID_V(2ElnCapDcy)> {};
171 
172 template <>
173 struct decay_mode_id<decay_mode_t<decay_part::electron_cap, decay_part::fission>>
174  : selector<EAGINE_ID_V(ElnCapFisn)> {};
175 
176 template <>
177 struct decay_mode_id<decay_mode_t<decay_part::beta_m>>
178  : selector<EAGINE_ID_V(BetaMDcy)> {};
179 
180 template <>
181 struct decay_mode_id<decay_mode_t<decay_part::beta_m, decay_part::beta_m>>
182  : selector<EAGINE_ID_V(BetaM2Dcy)> {};
183 
184 template <>
185 struct decay_mode_id<decay_mode_t<decay_part::beta_m, decay_part::alpha>>
186  : selector<EAGINE_ID_V(BtaMAlpDcy)> {};
187 
188 template <>
189 struct decay_mode_id<decay_mode_t<decay_part::beta_m, decay_part::neutron_emi>>
190  : selector<EAGINE_ID_V(BetaMNDcy)> {};
191 
192 template <>
193 struct decay_mode_id<decay_mode_t<
194  decay_part::beta_m,
195  decay_part::neutron_emi,
196  decay_part::neutron_emi>> : selector<EAGINE_ID_V(BetaMN2Dcy)> {};
197 
198 template <>
199 struct decay_mode_id<decay_mode_t<decay_part::beta_p>>
200  : selector<EAGINE_ID_V(BetaPDcy)> {};
201 
202 template <>
203 struct decay_mode_id<decay_mode_t<decay_part::beta_p, decay_part::beta_p>>
204  : selector<EAGINE_ID_V(BetaP2Dcy)> {};
205 
206 template <>
207 struct decay_mode_id<decay_mode_t<decay_part::beta_p, decay_part::alpha>>
208  : selector<EAGINE_ID_V(BtaPAlpDcy)> {};
209 
210 template <>
211 struct decay_mode_id<decay_mode_t<decay_part::fission>>
212  : selector<EAGINE_ID_V(Fission)> {};
213 
214 template <>
215 struct decay_mode_id<decay_mode_t<decay_part::transition>>
216  : selector<EAGINE_ID_V(Transition)> {};
217 //------------------------------------------------------------------------------
218 struct known_decay_modes {
219  using m = decay_part;
220  using list = mp_list<
221  decay_mode_t<m::alpha>,
222  decay_mode_t<m::proton_emi>,
223  decay_mode_t<m::neutron_emi>,
224  decay_mode_t<m::electron_cap>,
225  decay_mode_t<m::electron_cap, m::electron_cap>,
226  decay_mode_t<m::electron_cap, m::fission>,
227  decay_mode_t<m::beta_m>,
228  decay_mode_t<m::beta_m, m::beta_m>,
229  decay_mode_t<m::beta_m, m::alpha>,
230  decay_mode_t<m::beta_m, m::neutron_emi>,
231  decay_mode_t<m::beta_m, m::neutron_emi, m::neutron_emi>,
232  decay_mode_t<m::beta_p>,
233  decay_mode_t<m::beta_p, m::beta_p>,
234  decay_mode_t<m::beta_p, m::alpha>,
235  decay_mode_t<m::fission>,
236  decay_mode_t<m::transition>>;
237 
238  template <decay_part... M>
239  static auto get_id(decay_mode_t<M...> = {}) noexcept {
240  return decay_mode_id<decay_mode_t<M...>>::value;
241  }
242 
243  static auto get_id(string_view symbol) -> identifier_t {
244  return _get_id(symbol, list{});
245  }
246 
247  static auto get_info(identifier_t mode_id) -> const decay_mode_info* {
248  return _get_info(mode_id, list{});
249  }
250 
251  static auto proton_count_diff(identifier_t mode_id) noexcept -> int {
252  if(auto i{get_info(mode_id)}) {
253  return extract(i).proton_count_diff;
254  }
255  return 0;
256  }
257 
258  static auto neutron_count_diff(identifier_t mode_id) noexcept -> int {
259  if(auto i{get_info(mode_id)}) {
260  return extract(i).neutron_count_diff;
261  }
262  return 0;
263  }
264 
265 private:
266  static auto _get_info(identifier_t, mp_list<>) noexcept
267  -> const decay_mode_info* {
268  return nullptr;
269  }
270 
271  template <typename H, typename... T>
272  static auto _get_info(identifier_t id, mp_list<H, T...>)
273  -> const decay_mode_info* {
274  if(decay_mode_id<H>::value == id) {
275  return &mode_info(H{});
276  }
277  return _get_info(id, mp_list<T...>{});
278  }
279 
280  static auto _get_id(string_view, mp_list<>) noexcept -> identifier_t {
281  return 0;
282  }
283 
284  template <typename H, typename... T>
285  static auto _get_id(string_view symbol, mp_list<H, T...>) -> identifier_t {
286  if(are_equal(string_view(mode_info(H{}).symbol), symbol)) {
287  return get_id(H{});
288  }
289  return _get_id(symbol, mp_list<T...>{});
290  }
291 };
292 //------------------------------------------------------------------------------
293 } // namespace eagine
294 
295 #endif
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
@ info
Informational log entries.
std::uint64_t identifier_t
The underlying integer type for eagine::identifier.
Definition: identifier_t.hpp:19

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).