guit  0.1
 All Classes Functions Variables Typedefs Enumerations Friends
gpropspec.hpp
1 //
2 // Prop Component
3 // guit GUI Toolkit
4 // Copyright © 2019/2020 Eric Lecolinet. All rights reserved.
5 // http://www.telecom-paris.fr/~elc
6 //
7 
8 #ifndef Guit_PropComp_hpp
9 #define Guit_PropComp_hpp
10 #include <sstream>
11 #include <gtypes.hpp>
12 namespace guit {
13 
14 class GFieldSpec {
15 public:
16  using Value = void;
17  bool isoptional_{};
18 
19  virtual ~GFieldSpec() = default;
20  virtual bool toValue(GString const& from, Value* to) = 0;
21  virtual bool toString(const Value* from, GString& to) = 0;
22 };
23 
24 
25 class GPropSpec {
26 protected:
27  std::vector<GFieldSpec*> fields_;
28 public:
29  using Value = void;
30 
31  GPropSpec(std::initializer_list<GFieldSpec*> fields);
32  int toValue(GString const& str, Value*);
33  GString toString(const Value*);
34 };
35 
36 
37 // - - - specializations
38 
39 template <class T, class Var>
40 class GNumFieldSpec : public GFieldSpec {
41  Var T::* var_{};
42 public:
43  GNumFieldSpec(Var T::* var, bool isoptional = false)
44  : var_(var) {isoptional_ = isoptional;}
45 
46  bool toValue(GString const& from, Value* to) override {
47  return gconvert(from, ((T*)to)->*var_);
48  }
49 
50  bool toString(const Value* from, GString& to) override {
51  return gconvert(((const T*)from)->*var_, to);
52  }
53 };
54 
55 // - - - - -
56 
57 class GFieldSpecValue {
58 public:
59  GString name_;
60  int type_{};
61  bool isalias_{};
62  float value_{};
63  uint64_t nameid_{};
64  bool islabel_{};
65 };
66 
67 class GFieldSpecValues {
68 public:
69  std::vector<GFieldSpecValue> list_;
70 
71  GFieldSpecValues(std::initializer_list<GFieldSpecValue> values);
72  GFieldSpecValue const* find1(GString const& str) const;
73  GFieldSpecValue const* find2(GString const& str, float&) const;
74  bool find1(int type, GString& to) const;
75  bool find2(int type, float val, GString& to) const;
76 };
77 
78 
79 template <class T, class Var>
80 class GListFieldSpec : public GFieldSpec {
81  Var T::* var_{};
82  GFieldSpecValues const& values_;
83 
84 public:
85  // NOTE: values are not copied!
86  GListFieldSpec(Var T::* var, GFieldSpecValues const& values)
87  : var_(var), values_(values) {}
88 
89  bool toValue(GString const& str, Value* to) override {
90  if (auto* it = values_.find1(str)) {
91  ((T*)to)->*var_ = (Var) it->type_;
92  return true;
93  }
94  else return false;
95  }
96 
97  bool toString(const Value* from, GString& to) override {
98  return values_.find1(((const T*)from)->*var_, to);
99  }
100 };
101 
102 
103 template <class T1, class T2, class Var1, class Var2>
104 class GListFieldSpec2 : public GFieldSpec {
105  Var1 T1::* var1_{};
106  Var2 T2::* var2_{};
107  GFieldSpecValues const& values_;
108 
109 public:
110  // NOTE: values are not coped!
111  GListFieldSpec2(Var1 T1::* var1, Var2 T2::* var2, GFieldSpecValues const& values)
112  : var1_(var1), var2_(var2), values_(values) {}
113 
114  bool toValue(GString const& str, Value* to) override {
115  float val{};
116  if (auto* it = values_.find2(str, val)) {
117  ((T1*)to)->*var1_ = Var1(it->type_);
118  ((T2*)to)->*var2_ = Var2(val);
119  return true;
120  }
121  else return false;
122  }
123 
124  bool toString(const Value* from, GString& to) override {
125  return values_.find2(((const T1*)from)->*var1_, ((T2*)from)->*var2_, to);
126  }
127 };
128 
129 }
130 #endif