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