14#pragma warning(disable:2586)
30 template <>
string ts(
const PropArray &p,
int width,
char notation,
int precision,
char fill);
32 using PropBase = std::variant<int64, double, bool, string, DVect2,
37 namespace PropertyConcepts {
42 template <
class T,
class V>
44 std::holds_alternative<T>(std::declval<V>());
47 concept IntNoBool = std::integral<T> and (not std::same_as<T, bool>);
52 class Property :
public PropBase {
54 using PropBase::PropBase;
59 enum class Type { Int, Double, Bool,
String, DVect2,
60 DVect3, I64Vect2, I64Vect3,
Matrix, DAVect2,
64 Property(): PropBase(
nullptr) {}
67 BASE_EXPORT std::partial_ordering operator<=>(
const Property &p)
const;
71 inline Type type()
const;
74 inline bool isNull()
const {
return type()==Type::Null; }
75 inline bool isValid()
const {
return not isNull(); }
80 bool canConvert()
const {
static_assert(
sizeof(T)==0);
return false; }
84 bool canConvertVec()
const;
88 bool canConvertType()
const {
return canConvert<decltype(std::get<static_cast<int>(t)>(*this))>(); }
92 T to()
const {
static_assert(
sizeof(T)==0);
return false; }
94 std::vector<T> toVec()
const;
98 auto toType()
const {
return to<decltype(std::get<static_cast<int>(t)>(*this))>(); }
102 template <
typename T>
103 typename std::tuple<T,bool> toTest()
const;
107 typename std::variant_alternative_t<static_cast<int>(t),Property> toTestType()
const;
109 template <
typename T>
110 void setValue(
const T &t) { *
this = t; }
111 template <
typename T>
112 void setVec(
const std::vector<T> &v);
114 template <
typename T>
115 T value()
const {
return to<T>(); }
118 inline double toDouble()
const;
119 inline string toString()
const;
120 inline int64 toInt()
const;
121 inline uint32 toUInt()
const;
122 inline double toDouble(
bool *ok)
const;
123 inline int64 toInt(
bool *ok)
const;
125 static constexpr Type DVectType(uint32 dim) {
return dim==2 ? Type::DVect2 : Type::DVect3; }
126 static constexpr Type DAVectType(uint32 dim) {
return dim==2 ? Type::DAVect2 : Type::DAVect3; }
127 static constexpr Type IVectType(uint32 dim) {
return dim==2 ? Type::I64Vect2 : Type::I64Vect3; }
130 Property::Type Property::type()
const {
131 return static_cast<Type
>(index());
135 auto &vl =
static_cast<const std::vector<base::Property> &
>(lhs);
136 auto &vr =
static_cast<const std::vector<base::Property> &
>(rhs);
140 template <>
BASE_EXPORT bool Property::canConvert<int64>()
const;
141 template <>
BASE_EXPORT bool Property::canConvert<double>()
const;
142 template <>
BASE_EXPORT bool Property::canConvert<bool>()
const;
143 template <>
BASE_EXPORT bool Property::canConvert<string>()
const;
144 template <>
BASE_EXPORT bool Property::canConvert<DVect2>()
const;
145 template <>
BASE_EXPORT bool Property::canConvert<DVect3>()
const;
146 template <>
BASE_EXPORT bool Property::canConvert<I64Vect2>()
const;
147 template <>
BASE_EXPORT bool Property::canConvert<I64Vect3>()
const;
148 template <>
BASE_EXPORT bool Property::canConvert<itasca::Mat>()
const;
149 template <>
BASE_EXPORT bool Property::canConvert<DAVect2>()
const;
150 template <>
BASE_EXPORT bool Property::canConvert<DAVect3>()
const;
151 template <>
BASE_EXPORT bool Property::canConvert<Quat2>()
const;
152 template <>
BASE_EXPORT bool Property::canConvert<Quat3>()
const;
153 template <>
BASE_EXPORT bool Property::canConvert<SymTensor>()
const;
154 template <>
BASE_EXPORT bool Property::canConvert<PropArray>()
const;
156 template <>
BASE_EXPORT int64 Property::to<int64>()
const;
157 template <>
BASE_EXPORT double Property::to<double>()
const;
158 template <>
BASE_EXPORT bool Property::to<bool>()
const;
159 template <>
BASE_EXPORT string Property::to<string>()
const;
160 template <>
BASE_EXPORT DVect2 Property::to<DVect2>()
const;
161 template <>
BASE_EXPORT DVect3 Property::to<DVect3>()
const;
162 template <>
BASE_EXPORT I64Vect2 Property::to<I64Vect2>()
const;
163 template <>
BASE_EXPORT I64Vect3 Property::to<I64Vect3>()
const;
164 template <>
BASE_EXPORT itasca::Mat Property::to<itasca::Mat>()
const;
165 template <>
BASE_EXPORT DAVect2 Property::to<DAVect2>()
const;
166 template <>
BASE_EXPORT DAVect3 Property::to<DAVect3>()
const;
167 template <>
BASE_EXPORT Quat2 Property::to<Quat2>()
const;
168 template <>
BASE_EXPORT Quat3 Property::to<Quat3>()
const;
169 template <>
BASE_EXPORT SymTensor Property::to<SymTensor>()
const;
172 class PropertyConvertException :
public Exception {
174 PropertyConvertException(Property::Type from,Property::Type
to) :
175 Exception(
"Error converting Property from {} to {}.",
176 Property::nameFromType(from),Property::nameFromType(
to)) {
180 template <
typename T>
181 void Property::setVec(
const std::vector<T> &v) {
184 for (
size_t i=0;i<v.size();++i) {
186 pa.back().setValue(v[i]);
187 if (not i) t = pa.back().type();
188 else if (t!=pa.back().type())
throw Exception(
"All elements of a property array must be of the same type.");
193 double Property::toDouble()
const {
return to<double>(); }
194 string Property::toString()
const {
return to<string>(); }
195 int64 Property::toInt()
const {
return to<int64>();}
196 uint32 Property::toUInt()
const {
return static_cast<uint32
>(to<int64>()); }
198 double Property::toDouble(
bool *ok)
const {
199 *ok = canConvert<double>();
200 if (*ok)
return to<double>();
204 int64 Property::toInt(
bool *ok)
const {
205 *ok = canConvert<int64>();
206 if (*ok)
return to<int64>();
210 template <
typename T>
211 typename std::tuple<T,bool> Property::toTest()
const {
212 bool b = canConvert<T>();
218 template <Property::Type t>
219 typename std::variant_alternative_t<static_cast<int>(t),
Property> Property::toTestType()
const {
220 using target_type =
decltype(std::get<static_cast<int>(t)>(*this));
221 using return_type = std::tuple<target_type,bool>;
222 bool b = canConvert<target_type>();
223 if (b)
return return_type(to<target_type>(),
true);
224 return return_type(target_type{},
false);
227 template <
typename T>
228 bool Property::canConvertVec()
const {
229 if (type()!=Type::Array)
return false;
230 auto &a = std::get<PropArray>(*
this);
231 if (not a.size())
return true;
232 return a[0].canConvert<T>();
235 template <
typename T>
236 std::vector<T> Property::toVec()
const {
237 if (type()!=Type::Array)
throw PropertyConvertException(type(),Type::Array);
238 auto &a = std::get<PropArray>(*
this);
239 if (not a.size())
return {};
242 ret.push_back(v.to<T>());
248 template <Property::Type t>
249 const auto &get(
const Property &v) {
return std::get<static_cast<int>(t)>(v); }
253 BASE_EXPORT string ts<base::Property>(
const base::Property &p,
int width,
char notation,
int precision,
char fill);
258 PropDesc(
const string &name,Property::Type type,UVect2 size) : name_(name), type_(type), size_(size) { }
261 Property::Type type_ = Property::Type::Int;
262 UVect2 size_ = UVect2(0);
263 auto operator<=>(
const PropDesc &p)
const =
default;
273struct std::formatter<base::Property> :
public std::formatter<string> {
274 template <
typename ParseContext>
275 constexpr auto parse(ParseContext &ctx) {
return std::formatter<string>::parse(ctx); }
277 template <
typename FormatContext>
278 constexpr auto format(
base::Property const &val, FormatContext &ctx)
const {
279 return std::formatter<string>::format(val.to<
string>(), ctx);
includes std::string and additional functions not included in the standard.
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:112
A symmetric 2nd order tensor.
Definition symtensor.h:22
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.
2D and 3D vector utility classes.