| helics 3.6.1

HelicsPrimaryTypes.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2017-2025,
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
ValueConverter.hpp
helics::NamedPoint
Definition: helicsTypes.hpp:110
helics::ValueConverter
Definition: ValueConverter.hpp:113
helics::ValueConverter::interpret
static X interpret(const data_view &block)
Definition: ValueConverter.hpp:147
helics::data_view
Definition: data_view.hpp:22
helicsTypes.hpp
helics
the main namespace for the helics co-simulation library User functions will be in the helics namespac...
Definition: AsyncFedCallInfo.hpp:14
helics::DataType
DataType
Definition: helicsTypes.hpp:273
helics::isTrueString
bool isTrueString(const std::string_view str)
Definition: helicsPrimaryTypes.cpp:47
helics::getIntFromString
std::int64_t getIntFromString(std::string_view val)
Definition: helicsTypes.cpp:492
helics::valueExtract
void valueExtract(const defV &data, std::string &val)
Definition: helicsPrimaryTypes.cpp:174
helics::TypeLocation
TypeLocation
Definition: HelicsPrimaryTypes.hpp:40
helics::getDoubleFromString
double getDoubleFromString(std::string_view val)
Definition: helicsTypes.cpp:503
helics::vectorNorm
double vectorNorm(const std::vector< double > &vec)
Definition: helicsTypes.cpp:109
helics::make_valid
int64_t make_valid(bool obj)
Definition: HelicsPrimaryTypes.hpp:68
helics::invalidValue
X invalidValue()
Definition: helicsTypes.hpp:493
helics::changeDetected
bool changeDetected(const defV &prevValue, const std::string &val, double)
Definition: helicsPrimaryTypes.cpp:20
helics::Time
TimeRepresentation< count_time< 9 > > Time
Definition: helicsTime.hpp:27
helics::defV
std::variant< double, int64_t, std::string, std::complex< double >, std::vector< double >, std::vector< std::complex< double > >, NamedPoint > defV
Definition: HelicsPrimaryTypes.hpp:37