ClassMemberInfoEntry.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package RobotAPI::RobotUnit
17  * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * @date 2017
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 #pragma once
23 
24 #include "DataFieldsInfo.h"
25 
26 namespace armarx::introspection
27 {
28 
29  template <class CommonBaseT, class ClassT>
30  struct ClassMemberInfo;
31  template <class CommonBaseT, class ClassT>
33 
34  template <class CommonBaseT>
36  {
37  public:
38  using CommonBaseType = CommonBaseT;
39 
44 
45  template <class ClassType, class MemberType>
46  ClassMemberInfoEntry(const std::string& memberName, MemberType ClassType::*ptr) :
47  className{GetTypeString<ClassType>()},
48  memberName{memberName},
49  memberTypeName{GetTypeString<MemberType>()},
50  numberOfFields{DataFieldsInfo<MemberType>::GetNumberOfFields()},
51  fieldToType{MakeFieldToTypeFunctors<ClassType>(numberOfFields, ptr)},
52  toVariants_{MakeToVariantsFunctor<ClassType>(ptr)}
53  {
54  ARMARX_CHECK_NOT_EQUAL(0, numberOfFields);
55  //field names
56  {
57  fieldNames.reserve(numberOfFields);
58  if (numberOfFields == 1)
59  {
60  fieldNames.emplace_back(memberName);
61  }
62  else
63  {
64  for (auto& name : DataFieldsInfo<MemberType>::GetFieldNames())
65  {
66  fieldNames.emplace_back(memberName + "." + std::move(name));
67  }
68  }
69  }
70  }
71 
72  //general
73  const std::string&
74  getClassName() const
75  {
76  return className;
77  }
78 
79  const std::string&
80  getMemberName() const
81  {
82  return memberName;
83  }
84 
85  const std::string&
87  {
88  return memberTypeName;
89  }
90 
91  //fields
92  std::size_t
94  {
95  return numberOfFields;
96  }
97 
98  const std::string&
99  getFieldName(std::size_t i) const
100  {
101  ARMARX_CHECK_LESS(i, numberOfFields);
102  return fieldNames.at(i);
103  }
104 
105  void
106  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, bool& out) const
107  {
109  ARMARX_CHECK_LESS(i, numberOfFields);
110  return fieldToType.at(i).toBool(ptr, out);
111  }
112 
113  void
114  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Byte& out) const
115  {
117  ARMARX_CHECK_LESS(i, numberOfFields);
118  return fieldToType.at(i).toByte(ptr, out);
119  }
120 
121  void
122  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Short& out) const
123  {
125  ARMARX_CHECK_LESS(i, numberOfFields);
126  return fieldToType.at(i).toShort(ptr, out);
127  }
128 
129  void
130  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Int& out) const
131  {
133  ARMARX_CHECK_LESS(i, numberOfFields);
134  return fieldToType.at(i).toInt(ptr, out);
135  }
136 
137  void
138  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Long& out) const
139  {
141  ARMARX_CHECK_LESS(i, numberOfFields);
142  return fieldToType.at(i).toLong(ptr, out);
143  }
144 
145  void
146  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Float& out) const
147  {
149  ARMARX_CHECK_LESS(i, numberOfFields);
150  return fieldToType.at(i).toFloat(ptr, out);
151  }
152 
153  void
154  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, Ice::Double& out) const
155  {
157  ARMARX_CHECK_LESS(i, numberOfFields);
158  return fieldToType.at(i).toDouble(ptr, out);
159  }
160 
161  void
162  getDataFieldAs(std::size_t i, const CommonBaseType* ptr, std::string& out) const
163  {
165  ARMARX_CHECK_LESS(i, numberOfFields);
166  return fieldToType.at(i).toString(ptr, out);
167  }
168 
169  const std::type_info&
170  getFieldTypeId(std::size_t i) const
171  {
172  ARMARX_CHECK_LESS(i, numberOfFields);
173  return *fieldToType.at(i).typeId;
174  }
175 
176  //variants
177  std::map<std::string, VariantBasePtr>
178  toVariants(const IceUtil::Time& timestamp, const CommonBaseType* ptr) const
179  {
180  return toVariants_(this, timestamp, ptr);
181  }
182 
183  private:
184  using ToVariantsFunctorType =
185  std::function<std::map<std::string, VariantBasePtr>(const ClassMemberInfoEntry* thisptr,
186  const IceUtil::Time&,
187  const CommonBaseType*)>;
188 
189  struct FieldToType
190  {
191  template <class T>
192  using FieldToFunctorType = std::function<void(const CommonBaseType*, T&)>;
193  FieldToFunctorType<bool> toBool;
194  FieldToFunctorType<Ice::Byte> toByte;
195  FieldToFunctorType<Ice::Short> toShort;
196  FieldToFunctorType<Ice::Int> toInt;
197  FieldToFunctorType<Ice::Long> toLong;
198  FieldToFunctorType<Ice::Float> toFloat;
199  FieldToFunctorType<Ice::Double> toDouble;
200  FieldToFunctorType<std::string> toString;
201  const std::type_info* typeId;
202  };
203 
204  template <class ClassType, class MemberType, class MemberPtrClassType>
205  static std::vector<FieldToType>
206  MakeFieldToTypeFunctors(std::size_t numberOfFields, MemberType MemberPtrClassType::*ptr)
207  {
208  std::vector<FieldToType> result;
209  result.reserve(numberOfFields);
210  for (std::size_t i = 0; i < numberOfFields; ++i)
211  {
212  result.emplace_back();
213  auto& fieldData = result.back();
214 
215 #define make_getter(Type) \
216  [i, ptr](const CommonBaseType* ptrBase, Type& out) \
217  { \
218  const ClassType* cptr = dynamic_cast<const ClassType*>(ptrBase); \
219  ARMARX_CHECK_NOT_NULL(cptr); \
220  DataFieldsInfo<MemberType>::GetDataFieldAs(i, cptr->*ptr, out); \
221  }
222  fieldData.toBool = make_getter(bool);
223  fieldData.toByte = make_getter(Ice::Byte);
224  fieldData.toShort = make_getter(Ice::Short);
225  fieldData.toInt = make_getter(Ice::Int);
226  fieldData.toLong = make_getter(Ice::Long);
227  fieldData.toFloat = make_getter(Ice::Float);
228  fieldData.toDouble = make_getter(Ice::Double);
229  fieldData.toString = make_getter(std::string);
230 #undef make_getter
231  fieldData.typeId = &DataFieldsInfo<MemberType>::GetDataFieldType(i);
232  }
233  return result;
234  }
235 
236  template <class ClassType, class MemberType, class MemberPtrClassType>
237  static ToVariantsFunctorType
238  MakeToVariantsFunctor(MemberType MemberPtrClassType::*ptr)
239  {
240  return [ptr](const ClassMemberInfoEntry* thisptr,
241  const IceUtil::Time& timestamp,
242  const CommonBaseType* ptrBase)
243  {
244  const ClassType* cptr = dynamic_cast<const ClassType*>(ptrBase);
245  ARMARX_CHECK_NOT_NULL(cptr);
246  return DataFieldsInfo<MemberType>::ToVariants(cptr->*ptr,
247  thisptr->getMemberName(),
248  timestamp,
249  thisptr->variantReportFrame(),
250  thisptr->variantReportAgent());
251  };
252  }
253 
254  template <class BaseType, class ClassT>
255  friend class ClassMemberInfo;
256  template <class BaseType, class ClassT>
258 
259  const std::string className;
260  const std::string memberName;
261  const std::string memberTypeName;
262  //elementar subparts
263  const std::size_t numberOfFields;
264  const std::vector<FieldToType> fieldToType;
265  std::vector<std::string> fieldNames;
266  //variants
267  ToVariantsFunctorType toVariants_;
268  bool setVariantReportFrame_{false};
269  std::function<std::string()> variantReportFrame{[] { return ""; }};
270  std::function<std::string()> variantReportAgent{[] { return ""; }};
271  };
272 
273  template <class CommonBaseT, class ClassT>
274  struct ClassMemberInfoEntryConfigurator
275  {
276  using ClassType = ClassT;
277  using CommonBaseType = CommonBaseT;
279 
281  setFieldNames(std::vector<std::string> fieldNames)
282  {
283  ARMARX_CHECK_EQUAL(fieldNames.size(), e.numberOfFields);
284  e.fieldNames = std::move(fieldNames);
285  return *this;
286  }
287 
289  setVariantReportFrame(const std::string& agent, const std::string& frame)
290  {
291  e.setVariantReportFrame_ = true;
292  e.variantReportFrame = [frame] { return frame; };
293  e.variantReportAgent = [agent] { return agent; };
294  return *this;
295  }
296 
298  setVariantReportFrame(const std::string& agent, std::function<std::string()> frame)
299  {
300  e.setVariantReportFrame_ = true;
301  e.variantReportFrame = std::move(frame);
302  e.variantReportAgent = [agent] { return agent; };
303  return *this;
304  }
305 
307  setVariantReportFrame(std::function<std::string()> agent, const std::string& frame)
308  {
309  e.setVariantReportFrame_ = true;
310  e.variantReportFrame = [frame] { return frame; };
311  e.variantReportAgent = std::move(agent);
312  return *this;
313  }
314 
316  setVariantReportFrame(std::function<std::string()> agent,
317  std::function<std::string()> frame)
318  {
319  e.setVariantReportFrame_ = true;
320  e.variantReportFrame = std::move(frame);
321  e.variantReportAgent = std::move(agent);
322  return *this;
323  }
324 
327  std::function<std::map<std::string, VariantBasePtr>(const IceUtil::Time&,
328  const ClassType*)> f)
329  {
330  e.toVariants_ = [f](const ClassMemberInfoEntry<CommonBaseType>* thisptr,
331  const IceUtil::Time& timestamp,
332  const CommonBaseType* ptrBase)
333  {
334  const ClassType* ptr = dynamic_cast<const ClassType*>(ptrBase);
336  return f(timestamp, ptr);
337  };
338  return *this;
339  }
340 
341  private:
343 
345  {
346  }
347 
348  Entry& e;
349  };
350 } // namespace armarx::introspection
armarx::introspection::ClassMemberInfoEntry::ClassMemberInfoEntry
ClassMemberInfoEntry(const std::string &memberName, MemberType ClassType::*ptr)
Definition: ClassMemberInfoEntry.h:46
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Long &out) const
Definition: ClassMemberInfoEntry.h:138
armarx::introspection::ClassMemberInfoEntryConfigurator::Entry
ClassMemberInfoEntry< CommonBaseType > Entry
Definition: ClassMemberInfoEntry.h:278
ARMARX_CHECK_NOT_EQUAL
#define ARMARX_CHECK_NOT_EQUAL(lhs, rhs)
This macro evaluates whether lhs is inequal (!=) rhs and if it turns out to be false it will throw an...
Definition: ExpressionException.h:137
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::toInt
int toInt(const std::string &input)
Definition: StringHelpers.cpp:108
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, std::string &out) const
Definition: ClassMemberInfoEntry.h:162
armarx::introspection::ClassMemberInfoEntryConfigurator::setVariantReportFrame
ClassMemberInfoEntryConfigurator & setVariantReportFrame(std::function< std::string()> agent, std::function< std::string()> frame)
Definition: ClassMemberInfoEntry.h:316
armarx::introspection::ClassMemberInfoEntryConfigurator::ClassType
ClassT ClassType
Definition: ClassMemberInfoEntry.h:276
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
DataFieldsInfo.h
armarx::toFloat
float toFloat(const std::string &input)
Converts a string to float and uses always dot as seperator.
Definition: StringHelpers.cpp:97
ARMARX_CHECK_LESS
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
Definition: ExpressionException.h:102
armarx::introspection::ClassMemberInfo
Definition: ClassMemberInfo.h:34
toByte
int toByte(float f)
Definition: PointCloudSegmentsTable.cpp:11
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Double &out) const
Definition: ClassMemberInfoEntry.h:154
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, bool &out) const
Definition: ClassMemberInfoEntry.h:106
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Short &out) const
Definition: ClassMemberInfoEntry.h:122
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::introspection::ClassMemberInfoEntryConfigurator::setVariantReportFrame
ClassMemberInfoEntryConfigurator & setVariantReportFrame(std::function< std::string()> agent, const std::string &frame)
Definition: ClassMemberInfoEntry.h:307
armarx::introspection::ClassMemberInfoEntry::getMemberTypeName
const std::string & getMemberTypeName() const
Definition: ClassMemberInfoEntry.h:86
armarx::introspection::ClassMemberInfoEntry
Definition: ClassMemberInfoEntry.h:35
armarx::introspection::ClassMemberInfoEntry::getNumberOfFields
std::size_t getNumberOfFields() const
Definition: ClassMemberInfoEntry.h:93
armarx::introspection::ClassMemberInfoEntryConfigurator::setFieldNames
ClassMemberInfoEntryConfigurator & setFieldNames(std::vector< std::string > fieldNames)
Definition: ClassMemberInfoEntry.h:281
armarx::introspection::ClassMemberInfoEntry::getFieldTypeId
const std::type_info & getFieldTypeId(std::size_t i) const
Definition: ClassMemberInfoEntry.h:170
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Int &out) const
Definition: ClassMemberInfoEntry.h:130
make_getter
#define make_getter(Type)
armarx::introspection::ClassMemberInfoEntryConfigurator::setVariantReportFrame
ClassMemberInfoEntryConfigurator & setVariantReportFrame(const std::string &agent, const std::string &frame)
Definition: ClassMemberInfoEntry.h:289
armarx::introspection::ClassMemberInfoEntry::getFieldName
const std::string & getFieldName(std::size_t i) const
Definition: ClassMemberInfoEntry.h:99
armarx::introspection::ClassMemberInfoEntry::operator=
ClassMemberInfoEntry & operator=(ClassMemberInfoEntry &&)=default
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::introspection::ClassMemberInfoEntryConfigurator::CommonBaseType
CommonBaseT CommonBaseType
Definition: ClassMemberInfoEntry.h:277
armarx::introspection::ClassMemberInfoEntryConfigurator::setVariantReportFrame
ClassMemberInfoEntryConfigurator & setVariantReportFrame(const std::string &agent, std::function< std::string()> frame)
Definition: ClassMemberInfoEntry.h:298
armarx::introspection::ClassMemberInfoEntry::toVariants
std::map< std::string, VariantBasePtr > toVariants(const IceUtil::Time &timestamp, const CommonBaseType *ptr) const
Definition: ClassMemberInfoEntry.h:178
armarx::introspection::ClassMemberInfoEntry::ClassMemberInfoEntry
ClassMemberInfoEntry(ClassMemberInfoEntry &&)=default
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Float &out) const
Definition: ClassMemberInfoEntry.h:146
armarx::introspection::ClassMemberInfoEntryConfigurator
Definition: ClassMemberInfoEntry.h:32
armarx::armem::Time
armarx::core::time::DateTime Time
Definition: forward_declarations.h:13
armarx::introspection::GetDataFieldType
const std::type_info & GetDataFieldType(std::size_t i)
Definition: DataFieldsInfo.cpp:355
armarx::introspection::ClassMemberInfoEntry::getClassName
const std::string & getClassName() const
Definition: ClassMemberInfoEntry.h:74
armarx::introspection::ClassMemberInfoEntry::getMemberName
const std::string & getMemberName() const
Definition: ClassMemberInfoEntry.h:80
armarx::viz::toString
const char * toString(InteractionFeedbackType type)
Definition: Interaction.h:27
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::introspection::ClassMemberInfoEntry::getDataFieldAs
void getDataFieldAs(std::size_t i, const CommonBaseType *ptr, Ice::Byte &out) const
Definition: ClassMemberInfoEntry.h:114
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
armarx::introspection::ClassMemberInfoEntry::CommonBaseType
CommonBaseT CommonBaseType
Definition: ClassMemberInfoEntry.h:38
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::introspection::ClassMemberInfoEntryConfigurator::setVariantReportFunction
ClassMemberInfoEntryConfigurator & setVariantReportFunction(std::function< std::map< std::string, VariantBasePtr >(const IceUtil::Time &, const ClassType *)> f)
Definition: ClassMemberInfoEntry.h:326
armarx::introspection
Definition: ClassMemberInfo.h:28