Itasca C++ Interface
ivariant.h
1 #pragma once
2 
3 #include "base/src/basei.h"
4 #include <variant>
5 
6 class IVariant;
7 class QVariant;
8 using IVariantBase = std::variant<uint8,char,bool,int32,uint32,int64,uint64,double,IString,IList<IVariant>,
9  IVect2,DVect2,IVect3,DVect3,DAVect2,DAVect3,SymTensor,Variant,std::vector<bool>,std::vector<int>,
10  std::vector<int64>,std::vector<double>,std::vector<IString>,std::vector<DVect2>,std::vector<DVect3>,
11  std::vector<DAVect2>,std::vector<DAVect3>,std::vector<SymTensor>,std::vector<string>,
12  FVect2,FVect3,UVect2,UVect3,IAVect2,IAVect3,FAVect2,FAVect3,UAVect2,UAVect3>;
13 
14 class IVariant : public IVariantBase {
15 public:
16  using IVariantBase::variant;
17 
18  enum Type { Invalid, Char, Bool, Int, UInt, LongLong, ULongLong, Double, String, List, UserType };
19  static constexpr int uinvalid = 0;
20  static constexpr int uivect2 = 10;
21  static constexpr int udvect2 = 11;
22  static constexpr int uivect3 = 12;
23  static constexpr int udvect3 = 13;
24  static constexpr int uavect2 = 14;
25  static constexpr int uavect3 = 15;
26  static constexpr int utensor = 16;
27  static constexpr int uvariant = 17;
28  static constexpr int uvbool = 18;
29  static constexpr int uvint = 19;
30  static constexpr int uvint64 = 20;
31  static constexpr int uvdouble = 21;
32  static constexpr int uvistring = 22;
33  static constexpr int uvdvect2 = 23;
34  static constexpr int uvdvect3 = 24;
35  static constexpr int uvdavect2 = 25;
36  static constexpr int uvdavect3 = 26;
37  static constexpr int uvtensor = 27;
38  static constexpr int uvstring = 28;
39  static constexpr int ufvect2 = 29;
40  static constexpr int ufvect3 = 30;
41  static constexpr int uuvect2 = 31;
42  static constexpr int uuvect3 = 32;
43  static constexpr int uiavect2 = 33;
44  static constexpr int uiavect3 = 34;
45  static constexpr int ufavect2 = 35;
46  static constexpr int ufavect3 = 36;
47  static constexpr int uuavect2 = 37;
48  static constexpr int uuavect3 = 38;
49 
50  Type type() const;
51  IVariant(const string &s) : IVariant(IString(s)) { }
52  BASE_EXPORT bool operator==(const IVariant &v);
53  bool isNull() const { return index()==0; }
54 
55  // QVariant conversion (remove fromt his class someday?)
56  BASE_EXPORT IVariant(const QVariant &q);
57  BASE_EXPORT operator QVariant() const;
58 
59 
60  char toChar() const { return std::get<char>(*this); }
61  bool toBool() const { return std::get<bool>(*this); }
62  int32 toInt() const { return std::get<int32>(*this); }
63  uint32 toUInt() const { return std::get<uint32>(*this); }
64  int64 toLongLong() const { return std::get<int64>(*this); }
65  uint64 toULongLong() const { return std::get<uint64>(*this); }
66  BASE_EXPORT double toDouble(bool *ok=nullptr) const;
67  IString toString() const { return std::get<IString>(*this); }
68  IList<IVariant> toList() const { return std::get<IList<IVariant>>(*this); }
69 
70  IString typeName() const { return base::ts(index()); }
71 
72  int userType() const;
73 
74  template <typename T> T value() const { return std::get<T>(*this); }
75 
76  template <typename T> void setValue(const T &t) { *this = t; }
77 
78  template <typename T> bool canConvert() const { static_assert(sizeof(T)<0); return false; }
79 
80  template <typename T>
81  static IVariant fromValue(const T &t) { IVariant v(t); return v; }
82 };
83 
84 template <> BASE_EXPORT bool IVariant::canConvert<bool>() const;
85 template <> BASE_EXPORT bool IVariant::canConvert<int32>() const;
86 template <> BASE_EXPORT bool IVariant::canConvert<uint32>() const;
87 template <> BASE_EXPORT bool IVariant::canConvert<int64>() const;
88 template <> BASE_EXPORT bool IVariant::canConvert<uint64>() const;
89 template <> BASE_EXPORT bool IVariant::canConvert<double>() const;
90 template <> BASE_EXPORT bool IVariant::canConvert<string>() const;
91 template <> BASE_EXPORT bool IVariant::canConvert<IString>() const;
92 template <> BASE_EXPORT bool IVariant::canConvert<IVect2>() const;
93 template <> BASE_EXPORT bool IVariant::canConvert<DVect2>() const;
94 template <> BASE_EXPORT bool IVariant::canConvert<IVect3>() const;
95 template <> BASE_EXPORT bool IVariant::canConvert<DVect3>() const;
96 template <> BASE_EXPORT bool IVariant::canConvert<DAVect2>() const;
97 template <> BASE_EXPORT bool IVariant::canConvert<DAVect3>() const;
98 template <> BASE_EXPORT bool IVariant::canConvert<SymTensor>() const;
99 
100 template <typename T>
101 IVariant toIVariant(const T &t) { IVariant v; v.setValue(t); return v; }
102 
103 template <typename T> int getIVariantUserType() { static_assert(sizeof(T)<0); return 0; }
104 template <> inline int getIVariantUserType<IString>() { return static_cast<int>(IVariant::String); }
105 template <> inline int getIVariantUserType<Variant>() { return IVariant::uvariant; }
106 template <> inline int getIVariantUserType<IVect2>() { return IVariant::uivect2; }
107 template <> inline int getIVariantUserType<DVect2>() { return IVariant::udvect2; }
108 template <> inline int getIVariantUserType<IVect3>() { return IVariant::uivect3; }
109 template <> inline int getIVariantUserType<DVect3>() { return IVariant::udvect3; }
110 template <> inline int getIVariantUserType<FVect2>() { return IVariant::ufvect2; }
111 template <> inline int getIVariantUserType<FVect3>() { return IVariant::ufvect3; }
112 template <> inline int getIVariantUserType<UVect2>() { return IVariant::uuvect2; }
113 template <> inline int getIVariantUserType<UVect3>() { return IVariant::uuvect3; }
114 template <> inline int getIVariantUserType<DAVect2>() { return IVariant::uavect2; }
115 template <> inline int getIVariantUserType<DAVect3>() { return IVariant::uavect3; }
116 template <> inline int getIVariantUserType<IAVect2>() { return IVariant::uiavect2; }
117 template <> inline int getIVariantUserType<IAVect3>() { return IVariant::uiavect3; }
118 template <> inline int getIVariantUserType<FAVect2>() { return IVariant::ufavect2; }
119 template <> inline int getIVariantUserType<FAVect3>() { return IVariant::ufavect3; }
120 template <> inline int getIVariantUserType<UAVect2>() { return IVariant::uuavect2; }
121 template <> inline int getIVariantUserType<UAVect3>() { return IVariant::uuavect3; }
122 template <> inline int getIVariantUserType<SymTensor>() { return IVariant::utensor; }
123 template <> inline int getIVariantUserType<std::vector<bool>>() { return IVariant::uvbool; }
124 template <> inline int getIVariantUserType<std::vector<int>>() { return IVariant::uvint; }
125 template <> inline int getIVariantUserType<std::vector<int64>>() { return IVariant::uvint64; }
126 template <> inline int getIVariantUserType<std::vector<double>>() { return IVariant::uvdouble; }
127 template <> inline int getIVariantUserType<std::vector<IString>>() { return IVariant::uvistring; }
128 template <> inline int getIVariantUserType<std::vector<DVect2>>() { return IVariant::uvdvect2; }
129 template <> inline int getIVariantUserType<std::vector<DVect3>>() { return IVariant::uvdvect3; }
130 template <> inline int getIVariantUserType<std::vector<DAVect2>>() { return IVariant::uvdavect2; }
131 template <> inline int getIVariantUserType<std::vector<DAVect3>>() { return IVariant::uvdavect3; }
132 template <> inline int getIVariantUserType<std::vector<SymTensor>>() { return IVariant::uvtensor; }
133 template <> inline int getIVariantUserType<std::vector<string>>() { return IVariant::uvstring; }
134 
135 // This allows you to send IVariant to a fmt::format
136 template <> struct fmt::formatter<IVariant> : public fmt::formatter<string> {
137  template <typename ParseContext> constexpr auto parse(ParseContext& ctx) {
138  return fmt::formatter<string>::parse(ctx);
139  }
140 
141  template <typename FormatContext> auto format(IVariant const& val, FormatContext& ctx) {
142  string out;
143  switch (val.type()) {
144  case IVariant::Bool:
145  out = base::ts(val.toBool());
146  break;
147  case IVariant::Int:
148  out = base::ts(val.toInt());
149  break;
150  case IVariant::UInt:
151  out = base::ts(val.toUInt());
152  break;
153  case IVariant::LongLong:
154  out = base::ts(val.toLongLong());
155  break;
156  case IVariant::ULongLong:
157  out = base::ts(val.toULongLong());
158  break;
159  case IVariant::Double:
160  out = base::ts(val.toDouble());
161  break;
162  case IVariant::String:
163  out = base::ts(val.toString());
164  break;
165  case IVariant::UserType: {
166  switch (val.userType()) {
167  case IVariant::uivect2:
168  out = base::ts(val.value<IVect2>());
169  break;
170  case IVariant::udvect2:
171  out = base::ts(val.value<DVect2>());
172  break;
173  case IVariant::uivect3:
174  out = base::ts(val.value<IVect3>());
175  break;
176  case IVariant::udvect3:
177  out = base::ts(val.value<DVect3>());
178  break;
179  case IVariant::uavect2:
180  out = base::ts(val.value<DAVect2>());
181  break;
182  case IVariant::uavect3:
183  out = base::ts(val.value<DAVect3>());
184  break;
185  }
186  break;
187  }
188  default:
189  throw Exception("Unable to format IVariant type {}.", val.typeName());
190  }
191  return fmt::formatter<string>::format(out, ctx);
192  }
193 };
194 
195 
196 
197 // EoF
Base exception class for all Itasca code.
Definition: baseexception.h:10
Definition: idef.h:53
Definition: istring.h:14
Definition: ivariant.h:14
A simpler (and slightly faster) version of a QVariant, added for interfaces that do not use Qt.
Definition: variant.h:32
#define BASE_EXPORT
Definition: basedef.h:24