Itasca C++ Interface
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 
16 namespace base {
17  using PropBase = std::variant<int64, double, bool, string, DVect2,
18  DVect3, I64Vect2, I64Vect3, itasca::Mat, DAVect2,
19  DAVect3, Quat2, Quat3, SymTensor>;
20  class Property : public PropBase {
21  public:
22  using PropBase::PropBase;
23 
24  enum class Type { Int, Double, Bool, String, DVect2,
25  DVect3, I64Vect2, I64Vect3, Matrix, DAVect2,
26  DAVect3, Quat2 , Quat3, Tensor };
27 
28  Type type() const { return static_cast<Type>(index()); }
29  BASE_EXPORT std::tuple<Type,UVect2> desc() const;
30  BASE_EXPORT const Property &reset(); // Keep type but set value to default construction.
31 
32  // Returns TRUE if the type can be converted to the provided type. Does minimal computation.
33  // In theory we can add more type specializations (int, float, etc) based on existing.
34  template <typename T>
35  bool canConvert() const { static_assert(sizeof(T)==0); return false; } // Default
36  BASE_EXPORT bool canConvert(Type type) const; // Runtime type conversion query
37 
38  // Same as canConvert but takes a Type enum as a template argument.
39  template <Type t>
40  bool canConvertType() const { return canConvert<decltype(std::get<static_cast<int>(t)>(*this))>(); }
41 
42  // Converts to the type - throws exeption if not able to convert.
43  template <typename T>
44  T to() const { static_assert(sizeof(T)==0); return false; } // DEFAULT
45 
46  // Save as to<>() but uses the Type enum as the template argument.
47  template <Type t>
48  auto toType() const { return to<decltype(std::get<static_cast<int>(t)>(*this))>(); }
49 
50  // Single call test, returns both value and success boolean. Value is default init if
51  // success is false.
52  template <typename T>
53  typename std::tuple<T,bool> toTest() const;
54 
55  // Same as toTest<>() but using Type enum.
56  template <Type t>
57  typename std::variant_alternative_t<static_cast<int>(t),Property> toTestType() const;
58 
59  BASE_EXPORT static string nameFromType(Type t);
60 
61  };
62 
63  template <> BASE_EXPORT bool Property::canConvert<int64>() const;
64  template <> BASE_EXPORT bool Property::canConvert<double>() const;
65  template <> BASE_EXPORT bool Property::canConvert<bool>() const;
66  template <> BASE_EXPORT bool Property::canConvert<string>() const;
67  template <> BASE_EXPORT bool Property::canConvert<DVect2>() const;
68  template <> BASE_EXPORT bool Property::canConvert<DVect3>() const;
69  template <> BASE_EXPORT bool Property::canConvert<I64Vect2>() const;
70  template <> BASE_EXPORT bool Property::canConvert<I64Vect3>() const;
71  template <> BASE_EXPORT bool Property::canConvert<itasca::Mat>() const;
72  template <> BASE_EXPORT bool Property::canConvert<DAVect2>() const;
73  template <> BASE_EXPORT bool Property::canConvert<DAVect3>() const;
74  template <> BASE_EXPORT bool Property::canConvert<Quat2>() const;
75  template <> BASE_EXPORT bool Property::canConvert<Quat3>() const;
76  template <> BASE_EXPORT bool Property::canConvert<SymTensor>() const;
77 
78  template <> BASE_EXPORT int64 Property::to<int64>() const;
79  template <> BASE_EXPORT double Property::to<double>() const;
80  template <> BASE_EXPORT bool Property::to<bool>() const;
81  template <> BASE_EXPORT string Property::to<string>() const;
82  template <> BASE_EXPORT DVect2 Property::to<DVect2>() const;
83  template <> BASE_EXPORT DVect3 Property::to<DVect3>() const;
84  template <> BASE_EXPORT I64Vect2 Property::to<I64Vect2>() const;
85  template <> BASE_EXPORT I64Vect3 Property::to<I64Vect3>() const;
86  template <> BASE_EXPORT itasca::Mat Property::to<itasca::Mat>() const;
87  template <> BASE_EXPORT DAVect2 Property::to<DAVect2>() const;
88  template <> BASE_EXPORT DAVect3 Property::to<DAVect3>() const;
89  template <> BASE_EXPORT Quat2 Property::to<Quat2>() const;
90  template <> BASE_EXPORT Quat3 Property::to<Quat3>() const;
91  template <> BASE_EXPORT SymTensor Property::to<SymTensor>() const;
92 
93 
94 
95  template <typename T>
96  typename std::tuple<T,bool> Property::toTest() const {
97  bool b = canConvert<T>();
98  if (b)
99  return {to<T>(),b};
100  return {T{},false};
101  }
102 
103  template <Property::Type t>
104  typename std::variant_alternative_t<static_cast<int>(t),Property> Property::toTestType() const {
105  using target_type = decltype(std::get<static_cast<int>(t)>(*this));
106  using return_type = std::tuple<target_type,bool>;
107  bool b = canConvert<target_type>();
108  if (b) return return_type(to<target_type>(),true);
109  return return_type(target_type{},false);
110  }
111 
112  //template <typename T>
113  //T Property::to() const {
114  // auto [val,ok] = is<T>();
115  // if (ok==false)
116  // throw Exception("Unable to convert Property index {} to type {}.",index(),typeid(T).name());
117  // return val;
118  //}
119 
120  // This allows using the Type enum as a selector in a get, so
121  // get<Property::Bool>(p);
122  template <Property::Type t>
123  const auto &get(const Property &v) { return std::get<static_cast<int>(t)>(v); }
124 
125  // String conversion, using the base::ts standard
126  template <>
127  BASE_EXPORT string ts<base::Property>(const base::Property &p, int width, char notation, int precision, char fill);
128 
129  // Description of a property type. The information necessary to parse.
130  struct PropDesc {
131  PropDesc() { }
132  PropDesc(const string &name,Property::Type type,UVect2 size) : name_(name), type_(type), size_(size) { }
133  BASE_EXPORT PropDesc(const string &name,const Property &prop);
134  string name_;
135  Property::Type type_ = Property::Type::Int;
136  UVect2 size_ = UVect2(0);
137  BASE_EXPORT bool operator<(const PropDesc &p) const;
138  };
139 } // namespace base
140 // EoF
141 
QString helper functions, plus some additions.
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:109
Definition: property.h:20
Definition: mat.h:28
#define BASE_EXPORT
Definition: basedef.h:24
2D and 3D quaternion utility classes.
Definition: property.h:130
2D and 3D vector utility classes.