helics  3.5.2
HelicsPrimaryTypes.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2024,
3 Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable
4 Energy, LLC. See the top-level NOTICE for additional details. All rights reserved.
5 SPDX-License-Identifier: BSD-3-Clause
6 */
7 #pragma once
8 
9 #include "ValueConverter.hpp"
10 #include "helics/helics-config.h"
11 #include "helicsTypes.hpp"
12 #include "helics_cxx_export.h"
13 
14 #include <cmath>
15 #include <complex>
16 #include <cstdint>
17 #include <string>
18 #include <utility>
19 #include <variant>
20 #include <vector>
25 namespace helics {
26 
28 HELICS_CXX_EXPORT bool isTrueString(std::string_view str);
29 
31 using defV = std::variant<double,
32  int64_t,
33  std::string,
34  std::complex<double>,
35  std::vector<double>,
36  std::vector<std::complex<double>>,
37  NamedPoint>;
38 
40 enum TypeLocation : decltype(std::declval<defV>().index()) {
41  double_loc = 0U,
42  int_loc = 1U,
43  string_loc = 2U,
44  complex_loc = 3U,
45  vector_loc = 4U,
46  complex_vector_loc = 5U,
47  named_point_loc = 6U
48 };
50 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, const std::string& val, double deltaV);
51 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, std::string_view val, double deltaV);
52 HELICS_CXX_EXPORT bool
53  changeDetected(const defV& prevValue, const std::vector<double>& val, double deltaV);
54 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue,
55  const std::vector<std::complex<double>>& val,
56  double deltaV);
57 HELICS_CXX_EXPORT bool
58  changeDetected(const defV& prevValue, const double* vals, size_t size, double deltaV);
59 HELICS_CXX_EXPORT bool
60  changeDetected(const defV& prevValue, const std::complex<double>& val, double deltaV);
61 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, double val, double deltaV);
62 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, int64_t val, double deltaV);
63 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, Time val, double deltaV);
64 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, const NamedPoint& val, double deltaV);
65 HELICS_CXX_EXPORT bool changeDetected(const defV& prevValue, bool val, double deltaV);
66 
68 inline int64_t make_valid(bool obj)
69 {
70  return (obj) ? 1LL : 0LL;
71 }
72 
74 inline int64_t make_valid(uint64_t val)
75 {
76  return static_cast<int64_t>(val);
77 }
78 inline int64_t make_valid(int16_t val)
79 {
80  return static_cast<int64_t>(val);
81 }
82 inline int64_t make_valid(uint16_t val)
83 {
84  return static_cast<int64_t>(val);
85 }
86 inline int64_t make_valid(char val)
87 {
88  return static_cast<int64_t>(val);
89 }
90 inline int64_t make_valid(unsigned char val)
91 {
92  return static_cast<int64_t>(val);
93 }
94 inline int64_t make_valid(int32_t val)
95 {
96  return static_cast<int64_t>(val);
97 }
98 inline int64_t make_valid(uint32_t val)
99 {
100  return static_cast<int64_t>(val);
101 }
102 inline int64_t make_valid(Time val)
103 {
104  return val.getBaseTimeCode();
105 }
106 
107 inline double make_valid(float val)
108 {
109  return static_cast<double>(val);
110 }
111 
112 inline std::complex<double> make_valid(const std::complex<float>& val)
113 {
114  return {val.real(), val.imag()};
115 }
116 
118 template<class X>
119 decltype(auto) make_valid(X&& obj)
120 {
121  return std::forward<X>(obj);
122 }
124 HELICS_CXX_EXPORT void valueExtract(const defV& data, std::string& val);
125 
127 HELICS_CXX_EXPORT void valueExtract(const defV& data, std::complex<double>& val);
128 
130 HELICS_CXX_EXPORT void valueExtract(const defV& data, std::vector<double>& val);
131 
133 HELICS_CXX_EXPORT void valueExtract(const defV& data, std::vector<std::complex<double>>& val);
134 
136 HELICS_CXX_EXPORT void valueExtract(const defV& data, NamedPoint& val);
137 
139 HELICS_CXX_EXPORT void valueExtract(const defV& data, Time& val);
140 
142 HELICS_CXX_EXPORT void valueExtract(const defV& data, char& val);
143 
145 HELICS_CXX_EXPORT void valueExtract(const defV& data, bool& val);
146 
147 HELICS_CXX_EXPORT defV readJsonValue(const data_view& data);
148 
149 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, std::string& val);
150 
151 HELICS_CXX_EXPORT void
152  valueExtract(const data_view& data, DataType baseType, std::vector<double>& val);
153 
154 HELICS_CXX_EXPORT void
155  valueExtract(const data_view& data, DataType baseType, std::complex<double>& val);
156 
157 HELICS_CXX_EXPORT void
158  valueExtract(const data_view& data, DataType baseType, std::vector<std::complex<double>>& val);
159 
160 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, NamedPoint& val);
161 
162 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, Time& val);
163 
164 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, bool& val);
165 
166 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, defV& val);
167 
168 HELICS_CXX_EXPORT void valueExtract(const data_view& data, DataType baseType, char& val);
169 
171 template<class X>
172 std::enable_if_t<std::is_arithmetic<X>::value && (!std::is_same<X, char>::value)>
173  valueExtract(const defV& data, X& val)
174 {
175  switch (data.index()) {
176  case double_loc: // double
177  val = static_cast<X>(std::get<double>(data));
178  break;
179  case int_loc: // int64_t
180  val = static_cast<X>(std::get<int64_t>(data));
181  break;
182  case string_loc: // string
183  default: {
184  const auto& v = std::get<std::string>(data);
185  if (v.find_first_of(".eE[]") == std::string::npos) {
186  val = static_cast<X>(getIntFromString(v));
187  } else {
188  val = static_cast<X>(getDoubleFromString(v));
189  }
190  }
191 
192  break;
193  case complex_loc: // complex
194  {
195  auto& cv = std::get<std::complex<double>>(data);
196  val = static_cast<X>((cv.imag() != 0.0) ? std::abs(cv) : cv.real());
197  }
198 
199  break;
200  case vector_loc: // vector
201  {
202  const auto& vec = std::get<std::vector<double>>(data);
203  val = static_cast<X>((vec.size() == 1) ? vec[0] : vectorNorm(vec));
204  break;
205  }
206  case complex_vector_loc: // complex vector
207  {
208  const auto& vec = std::get<std::vector<std::complex<double>>>(data);
209  double vald{0.0};
210  if (vec.size() == 1) {
211  if (vec[0].imag() == 0.0) {
212  vald = vec[0].real();
213  } else {
214  vald = std::abs(vec[0]);
215  }
216  } else {
217  vald = vectorNorm(vec);
218  }
219  val = static_cast<X>(vald);
220  break;
221  }
222  case named_point_loc: {
223  const auto& np = std::get<NamedPoint>(data);
224  if (std::isnan(np.value)) {
225  if (np.name.find_first_of(".eE[]") == std::string::npos) {
226  val = static_cast<X>(getIntFromString(np.name));
227  } else {
228  val = static_cast<X>(getDoubleFromString(np.name));
229  }
230  } else {
231  val = static_cast<X>(np.value);
232  }
233  break;
234  }
235  }
236 }
237 
239 template<class X>
240 std::enable_if_t<std::is_arithmetic<X>::value && (!std::is_same<X, char>::value)>
241  valueExtract(const data_view& data, DataType baseType, X& val)
242 {
243  switch (baseType) {
244  case DataType::HELICS_ANY: {
245  defV val_dv;
246  valueExtract(data, baseType, val_dv);
247  valueExtract(val_dv, val);
248  break;
249  }
250  case DataType::HELICS_STRING:
251  case DataType::HELICS_CHAR:
252  default: {
253  const auto v = ValueConverter<std::string_view>::interpret(data);
254  if (v.find_first_of(".eE[]") == std::string_view::npos) {
255  val = static_cast<X>(getIntFromString(v));
256  } else {
257  val = static_cast<X>(getDoubleFromString(v));
258  }
259  }
260 
261  break;
262  case DataType::HELICS_BOOL:
263  val = static_cast<X>((ValueConverter<std::string_view>::interpret(data) != "0"));
264  break;
265  case DataType::HELICS_NAMED_POINT: {
266  auto npval = ValueConverter<NamedPoint>::interpret(data);
267  if (std::isnan(npval.value)) {
268  try {
269  if (npval.name.find_first_of(".eE[]") == std::string::npos) {
270  val = static_cast<X>(getIntFromString(npval.name));
271  } else {
272  val = static_cast<X>(getDoubleFromString(npval.name));
273  }
274  }
275  catch (const std::invalid_argument&) {
276  val = static_cast<X>(
277  invalidValue<
278  std::conditional_t<std::is_integral<X>::value, int64_t, double>>());
279  }
280  } else {
281  val = static_cast<X>(npval.value);
282  }
283 
284  break;
285  }
286  case DataType::HELICS_DOUBLE: {
287  auto V = ValueConverter<double>::interpret(data);
288  val = static_cast<X>(V);
289  break;
290  }
291  case DataType::HELICS_INT: {
292  auto V = ValueConverter<int64_t>::interpret(data);
293  val = static_cast<X>(V);
294  break;
295  }
296  case DataType::HELICS_TIME: {
297  Time vtime;
298  vtime.setBaseTimeCode(ValueConverter<int64_t>::interpret(data));
299  val = std::is_integral<X>::value ? static_cast<X>(vtime.getBaseTimeCode()) :
300  static_cast<X>(static_cast<double>(vtime));
301  break;
302  }
303  case DataType::HELICS_VECTOR: {
304  auto V = ValueConverter<std::vector<double>>::interpret(data);
305  if (V.size() == 1) {
306  val = static_cast<X>(V[0]);
307  } else {
308  val = static_cast<X>(vectorNorm(V));
309  }
310  break;
311  }
312  case DataType::HELICS_COMPLEX: {
313  auto V = ValueConverter<std::complex<double>>::interpret(data);
314 
315  val = static_cast<X>((V.imag() != 0) ? std::abs(V) : V.real());
316  break;
317  }
318  case DataType::HELICS_COMPLEX_VECTOR: {
319  auto V = ValueConverter<std::vector<std::complex<double>>>::interpret(data);
320  if (V.size() == 1) {
321  if (V[0].imag() == 0) {
322  val = static_cast<X>(V[0].real());
323  } else {
324  val = static_cast<X>(std::abs(V[0]));
325  }
326  } else {
327  val = static_cast<X>(vectorNorm(V));
328  }
329 
330  break;
331  }
332  case DataType::HELICS_JSON:
333  valueExtract(readJsonValue(data), val);
334  break;
335  case DataType::HELICS_CUSTOM:
336  throw(std::invalid_argument("unrecognized helics type"));
337  }
338 }
339 
340 HELICS_CXX_EXPORT void valueConvert(defV& val, DataType newType);
341 
342 HELICS_CXX_EXPORT SmallBuffer typeConvertDefV(DataType type, const defV& val);
343 HELICS_CXX_EXPORT SmallBuffer typeConvertDefV(const defV& val);
344 } // namespace helics
Definition: helicsTypes.hpp:110
Definition: ValueConverter.hpp:113
static X interpret(const data_view &block)
Definition: ValueConverter.hpp:147
Definition: data_view.hpp:22
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
DataType
Definition: helicsTypes.hpp:273
bool isTrueString(const std::string_view str)
Definition: helicsPrimaryTypes.cpp:43
std::int64_t getIntFromString(std::string_view val)
Definition: helicsTypes.cpp:481
void valueExtract(const defV &data, std::string &val)
Definition: helicsPrimaryTypes.cpp:170
TypeLocation
Definition: HelicsPrimaryTypes.hpp:40
double getDoubleFromString(std::string_view val)
Definition: helicsTypes.cpp:492
double vectorNorm(const std::vector< double > &vec)
Definition: helicsTypes.cpp:103
int64_t make_valid(bool obj)
Definition: HelicsPrimaryTypes.hpp:68
X invalidValue()
Definition: helicsTypes.hpp:493
bool changeDetected(const defV &prevValue, const std::string &val, double)
Definition: helicsPrimaryTypes.cpp:16
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27
std::variant< double, int64_t, std::string, std::complex< double >, std::vector< double >, std::vector< std::complex< double > >, NamedPoint > defV
Definition: HelicsPrimaryTypes.hpp:37