Itasca C++ Interface
Loading...
Searching...
No Matches
property.h
1#pragma once
2
3// This is intended to replace Variant as a property container in constitutive models
4// in a way that makes more use of modern C++ (and is also less complex)
5
6#include "basestring.h"
7#include "mat.h"
8#include "quat.h"
9#include "vect.h"
10#include <variant>
11#include <vector>
12
13#ifdef INTELCOMP
14#pragma warning(disable:2586) // Disable warning about name length
15#endif
16
17namespace std {
18 class any;
19}
20
21namespace base {
22 class Property;
23
24 class PropArray : public std::vector<Property> {
25 public:
26 using std::vector<Property>::vector;
27 };
28
29 BASE_EXPORT UVect2 size(const PropArray &p);
30 template <> string ts(const PropArray &p, int width, char notation, int precision, char fill);
31
32 using PropBase = std::variant<int64, double, bool, string, DVect2,
33 DVect3, I64Vect2, I64Vect3, itasca::Mat, DAVect2,
34 DAVect3, Quat2, Quat3, SymTensor, std::nullptr_t,
35 PropArray>;
36
37 class Property : public PropBase {
38 public:
39 using PropBase::PropBase;
40
41 enum class Type { Int, Double, Bool, String, DVect2,
42 DVect3, I64Vect2, I64Vect3, Matrix, DAVect2,
43 DAVect3, Quat2 , Quat3, Tensor, Null,
44 Array };
45
46 Property() : PropBase(nullptr) { }
47 BASE_EXPORT std::partial_ordering operator<=>(const Property &p) const;
48
49 inline Type type() const;
50 BASE_EXPORT std::tuple<Type,UVect2> desc() const;
51 BASE_EXPORT const Property &reset(); // Keep type but set value to default construction.
52 inline bool isNull() const { return type()==Type::Null; }
53 inline bool isValid() const { return not isNull(); }
54
55 // Returns TRUE if the type can be converted to the provided type. Does minimal computation.
56 // In theory we can add more type specializations (int, float, etc) based on existing.
57 template <typename T>
58 bool canConvert() const { static_assert(sizeof(T)==0); return false; } // Default
59 BASE_EXPORT bool canConvert(Type type) const; // Runtime type conversion query
60
61 template <typename T>
62 bool canConvertVec() const;
63
64 // Same as canConvert but takes a Type enum as a template argument.
65 template <Type t>
66 bool canConvertType() const { return canConvert<decltype(std::get<static_cast<int>(t)>(*this))>(); }
67
68 // Converts to the type - throws exeption if not able to convert.
69 template <typename T>
70 T to() const { static_assert(sizeof(T)==0); return false; } // DEFAULT
71 template <typename T>
72 std::vector<T> toVec() const;
73
74 // Save as to<>() but uses the Type enum as the template argument.
75 template <Type t>
76 auto toType() const { return to<decltype(std::get<static_cast<int>(t)>(*this))>(); }
77
78 // Single call test, returns both value and success boolean. Value is default init if
79 // success is false.
80 template <typename T>
81 typename std::tuple<T,bool> toTest() const;
82
83 // Same as toTest<>() but using Type enum.
84 template <Type t>
85 typename std::variant_alternative_t<static_cast<int>(t),Property> toTestType() const;
86
87 template <typename T>
88 void setValue(const T &t) { *this = t; }
89 template <typename T>
90 void setVec(const std::vector<T> &v);
91
92 template <typename T>
93 T value() const { return to<T>(); }
94
95 BASE_EXPORT static string nameFromType(Type t);
96 inline double toDouble() const;
97 inline string toString() const;
98 inline int64 toInt() const;
99 inline uint32 toUInt() const;
100 inline double toDouble(bool *ok) const;
101 inline int64 toInt(bool *ok) const;
102
103 static constexpr Type DVectType(uint32 dim) { return dim==2 ? Type::DVect2 : Type::DVect3; }
104 static constexpr Type DAVectType(uint32 dim) { return dim==2 ? Type::DAVect2 : Type::DAVect3; }
105 static constexpr Type IVectType(uint32 dim) { return dim==2 ? Type::I64Vect2 : Type::I64Vect3; }
106 };
107
108 Property::Type Property::type() const {
109 return static_cast<Type>(index());
110 }
111
112 constexpr auto operator<=>(const base::PropArray &lhs,const base::PropArray &rhs) {
113 auto &vl = static_cast<const std::vector<base::Property> &>(lhs);
114 auto &vr = static_cast<const std::vector<base::Property> &>(rhs);
115 return vl <=> vr;
116 }
117
118 template <> BASE_EXPORT bool Property::canConvert<int64>() const;
119 template <> BASE_EXPORT bool Property::canConvert<double>() const;
120 template <> BASE_EXPORT bool Property::canConvert<bool>() const;
121 template <> BASE_EXPORT bool Property::canConvert<string>() const;
122 template <> BASE_EXPORT bool Property::canConvert<DVect2>() const;
123 template <> BASE_EXPORT bool Property::canConvert<DVect3>() const;
124 template <> BASE_EXPORT bool Property::canConvert<I64Vect2>() const;
125 template <> BASE_EXPORT bool Property::canConvert<I64Vect3>() const;
126 template <> BASE_EXPORT bool Property::canConvert<itasca::Mat>() const;
127 template <> BASE_EXPORT bool Property::canConvert<DAVect2>() const;
128 template <> BASE_EXPORT bool Property::canConvert<DAVect3>() const;
129 template <> BASE_EXPORT bool Property::canConvert<Quat2>() const;
130 template <> BASE_EXPORT bool Property::canConvert<Quat3>() const;
131 template <> BASE_EXPORT bool Property::canConvert<SymTensor>() const;
132 template <> BASE_EXPORT bool Property::canConvert<PropArray>() const;
133
134 template <> BASE_EXPORT int64 Property::to<int64>() const;
135 template <> BASE_EXPORT double Property::to<double>() const;
136 template <> BASE_EXPORT bool Property::to<bool>() const;
137 template <> BASE_EXPORT string Property::to<string>() const;
138 template <> BASE_EXPORT DVect2 Property::to<DVect2>() const;
139 template <> BASE_EXPORT DVect3 Property::to<DVect3>() const;
140 template <> BASE_EXPORT I64Vect2 Property::to<I64Vect2>() const;
141 template <> BASE_EXPORT I64Vect3 Property::to<I64Vect3>() const;
142 template <> BASE_EXPORT itasca::Mat Property::to<itasca::Mat>() const;
143 template <> BASE_EXPORT DAVect2 Property::to<DAVect2>() const;
144 template <> BASE_EXPORT DAVect3 Property::to<DAVect3>() const;
145 template <> BASE_EXPORT Quat2 Property::to<Quat2>() const;
146 template <> BASE_EXPORT Quat3 Property::to<Quat3>() const;
147 template <> BASE_EXPORT SymTensor Property::to<SymTensor>() const;
148 template <> BASE_EXPORT PropArray Property::to<PropArray>() const;
149
151 public:
152 PropertyConvertException(Property::Type from,Property::Type to) :
153 Exception("Error converting Property from {} to {}.",
154 Property::nameFromType(from),Property::nameFromType(to)) {
155 }
156 };
157
158 template <typename T>
159 void Property::setVec(const std::vector<T> &v) {
160 PropArray pa;
161 Type t{};
162 for (size_t i=0;i<v.size();++i) {
163 pa.push_back({});
164 pa.back().setValue(v[0]);
165 if (not i) t = pa.back().type();
166 else if (t!=pa.back().type()) throw Exception("All elements of a property array must be of the same type.");
167 }
168 operator=(pa);
169 }
170
171 double Property::toDouble() const { return to<double>(); }
172 string Property::toString() const { return to<string>(); }
173 int64 Property::toInt() const { return to<int64>();}
174 uint32 Property::toUInt() const { return static_cast<uint32>(to<int64>()); }
175
176 double Property::toDouble(bool *ok) const {
177 *ok = canConvert<double>();
178 if (*ok) return to<double>();
179 return 0.0;
180 }
181
182 int64 Property::toInt(bool *ok) const {
183 *ok = canConvert<int64>();
184 if (*ok) return to<int64>();
185 return 0;
186 }
187
188 template <typename T>
189 typename std::tuple<T,bool> Property::toTest() const {
190 bool b = canConvert<T>();
191 if (b)
192 return {to<T>(),b};
193 return {T{},false};
194 }
195
196 template <Property::Type t>
197 typename std::variant_alternative_t<static_cast<int>(t),Property> Property::toTestType() const {
198 using target_type = decltype(std::get<static_cast<int>(t)>(*this));
199 using return_type = std::tuple<target_type,bool>;
200 bool b = canConvert<target_type>();
201 if (b) return return_type(to<target_type>(),true);
202 return return_type(target_type{},false);
203 }
204
205 template <typename T>
206 bool Property::canConvertVec() const {
207 if (type()!=Type::Array) return false;
208 auto &a = std::get<PropArray>(*this);
209 if (not a.size()) return true;
210 return a[0].canConvert<T>();
211 }
212
213 template <typename T>
214 std::vector<T> Property::toVec() const {
215 if (type()!=Type::Array) throw PropertyConvertException(type(),Type::Array);
216 auto &a = std::get<PropArray>(*this);
217 if (not a.size()) return {};
218 std::vector<T> ret;
219 for (auto &v : a)
220 ret.push_back(v.to<T>());
221 return ret;
222 }
223
224 // This allows using the Type enum as a selector in a get, so
225 // get<Property::Bool>(p);
226 template <Property::Type t>
227 const auto &get(const Property &v) { return std::get<static_cast<int>(t)>(v); }
228
229 // String conversion, using the base::ts standard
230 template <>
231 BASE_EXPORT string ts<base::Property>(const base::Property &p, int width, char notation, int precision, char fill);
232
233 // Description of a property type. The information necessary to parse.
234 struct PropDesc {
235 PropDesc() { }
236 PropDesc(const string &name,Property::Type type,UVect2 size) : name_(name), type_(type), size_(size) { }
237 BASE_EXPORT PropDesc(const string &name,const Property &prop);
238 string name_;
239 Property::Type type_ = Property::Type::Int;
240 UVect2 size_ = UVect2(0);
241 auto operator<=>(const PropDesc &p) const = default;
242 };
243
244 BASE_EXPORT Property toProperty(const std::any &a);
245 BASE_EXPORT std::any toAny(const Property &p);
246
247} // namespace base
248
249// This allows you to send Properties to a std::format
250template <>
251struct std::formatter<base::Property> : public std::formatter<string> {
252 template <typename ParseContext>
253 constexpr auto parse(ParseContext &ctx) { return std::formatter<string>::parse(ctx); }
254
255 template <typename FormatContext>
256 constexpr auto format(base::Property const &val, FormatContext &ctx) const {
257 return std::formatter<string>::format(val.to<string>(), ctx);
258 }
259};
260
261// EoF
262
includes std::string and additional functions not included in the standard.
Base exception class for all Itasca code.
Definition baseexception.h:10
A template-based matrix class, size fixed at compile time. Defaults to symmetric sized matrix.
Definition matrix.h:22
2D quaternion-like utility class. In this case only the angle (in radians) is stored as opposed to th...
Definition quat.h:20
3D quaternion utility class.
Definition quat.h:111
A symmetric 2nd order tensor.
Definition symtensor.h:22
Definition property.h:24
Definition property.h:150
Definition property.h:37
Definition mat.h:28
std::basic_string< char8 > String
std::string of type Char
Definition basebool.h:9
#define BASE_EXPORT
Definition basedef.h:25
constexpr D to(const T &t)
This template function serves as an alternative to static_cast<T>().
Definition to.h:28
2D and 3D quaternion utility classes.
Definition property.h:234
2D and 3D vector utility classes.