MIRA
RecursiveMemberReflector.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_RECURSIVEMEMBERREFLECTOR_H_
48 #define _MIRA_RECURSIVEMEMBERREFLECTOR_H_
49 
50 #include <type_traits>
51 
52 #ifndef Q_MOC_RUN
53 #include <boost/mpl/eval_if.hpp>
54 #include <boost/mpl/identity.hpp>
55 #endif
56 
57 #include <error/LoggingCore.h>
58 
59 #include <factory/Factory.h>
60 
61 #include <serialization/Accessor.h>
62 
66 
67 #include <serialization/Array.h>
68 
73 
75 
76 #include <serialization/VoidCast.h>
77 
78 #include <utils/Singleton.h>
79 #include <utils/ToString.h>
80 
81 namespace mira {
82 
84 
85 namespace serialization {
86 
88 
100 template <typename T, typename Reflector>
102  ReflectedAsPointer() : value(false) {}
103  bool value;
104 };
105 
106 template <typename T, typename Reflector>
109  LazySingleton<ReflectedAsPointer<T,Reflector>>::instance().value = true;
110  }
111 };
112 
114 
115 } // namespace
116 
121 MIRA_DEFINE_SERIALIZABLE_EXCEPTION(XMemberNotFound, XIO)
122 
123 
128 class XMemberNotFound_NoDefault : public XMemberNotFound
129 {
131 protected:
132  friend class ClassFactoryDefaultConstClassBuilder;
134 
135 public:
137  XMemberNotFound(ex) {}
138 
139  virtual void raise(bool recursive = false) { throw *this; }
140 };
141 
143 
233 template <typename Derived>
235 {
237 public:
238 
241  mCurrentMemberMeta(NULL) {}
242 
243 protected:
244 
250  static constexpr auto MIRA_REFLECTOR_TOPLEVEL_NAME = "@value";
251 
252 public:
253 
258 
268  template<typename T>
269  void atomic(T& member) {}
270 
281  template<typename T>
282  void enumeration(T& member) {
283  int32 val;
284  if(Derived::isReadOnly::value) {
285  val = static_cast<int32>(member);
286  this->This()->atomic(val);
287  } else {
288  this->This()->atomic(val);
289  member = static_cast<T>(val);
290  }
291  }
292 
301  template<typename T>
302  void object(T& member) {
303  this->This()->invoke(member); // invoke us recursively on the object
304  }
305 
311  template<typename T>
312  void collection(T& member) {
313  this->This()->object(member); // default impl calls object()
314  }
315 
316 
317  template<typename T>
318  void trackObject(T& member) {}
319 
325  template<typename T>
326  void pointer(T* &pointer) {
327  // this will instantiate the SetReflectedAsPointer during startup
328  // which will set ReflectedAsPointer<T,Derived>::value to true,
329  // and mark that T was reflected as pointer by Derived at least once.
331 
332  // Selects the correct pointer ReflectPointerXXX struct using boost::mpl.
333  typedef typename
334  boost::mpl::eval_if<std::is_base_of<mira::Object, T>,
335  boost::mpl::identity< ReflectPointerPolymorphic >, // T is a polymorphic class derived from Object
336  //else
337  boost::mpl::eval_if<std::is_abstract<T>,
338  boost::mpl::identity< ReflectPointerAbstract >, // T is abstract
339  //else
340  boost::mpl::identity< ReflectPointerNormal > // T is a "normal" class (maybe polymorphic but not derived from Object)
341  >
342  >::type type;
343 
344  type::invoke(*this->This(), pointer);
345  }
346 
354  template<typename T>
355  void pointerNormal(T* &pointer, int typeId) {
356  if(pointer!=NULL) // delegate serialization of the actual object recursively
357  this->This()->invokePointerObject(*pointer);
358  }
359 
368  template<typename T>
370  if(pointer!=NULL) { // delegate serialization of the actual object recursively
371 
372  // obtain a special polymorph pointer serializer for the derived type
373  typedef serialization::PolymorphicPointerReflectorRegistrar<Derived> OurRegistrar;
374 
375  typename OurRegistrar::ReflectorPtr r =
376  OurRegistrar::instance().getPolymorphicPointerReflector(typeId);
377 
378  if(r==NULL) {
379  const ReflectMemberMeta& meta = getCurrentMemberMeta();
380  const Class& c = pointer->getClass();
381  MIRA_THROW(XIO, "Cannot reflect the polymorphic member pointer '"
382  << meta.name << "'. The class '" << c.getIdentifier()
383  << "' was not registered with this serializer '"
384  << typeName<Derived>());
385  }
386 
387  // deserialize the content recursively
388  r->invoke(*this->This(), serialization::void_upcast(pointer));
389  }
390  }
391 
398  template<typename T>
399  void pointerAbstract(T* &pointer, int typeId) {
400  if(pointer!=NULL) // delegate serialization of the actual object recursively
401  this->This()->invokePointerObject(*pointer);
402  }
403 
405 
406 public:
407 
420  template<typename T>
421  static void registerClass()
422  {
423  typedef serialization::PolymorphicPointerReflectorRegistrar<Derived> OurRegistrar;
424 
425  if(!OurRegistrar::isDestroyed())
426  OurRegistrar::instance().template registerClass<T>();
427  }
428 
439  template<typename T>
440  static void unregisterClass()
441  {
442  typedef serialization::PolymorphicPointerReflectorRegistrar<Derived> OurRegistrar;
443  if(!OurRegistrar::isDestroyed())
444  OurRegistrar::instance().template unregisterClass<T>();
445  }
446 public:
447 
452  {
453  assert(mCurrentMemberMeta!=NULL);
454  return *mCurrentMemberMeta;
455  }
456 
462  const std::string& getCurrentMemberFullID() const
463  {
464  assert(this->usesHumanReadableIDs());
465  return mCurrentMemberFullID;
466  }
467 
468 public:
469 
475  template <typename T>
476  static bool isReflectedAsPointer() {
478  }
479 
480 protected:
481 
483  template<typename T>
485  {
487  this->This()->trackObject(member);
488  }
489 
490 
491  // The following structs implement different invoke methods for each of
492  // the member types (A1-3, B1-2, C). The member types are detected in
493  // the invoke method above which delegates to the invoke method
494  // of the correct struct below.
495 
496  struct ReflectUnknown {
497  template<typename T>
498  static void invoke(Derived& r, T& member) {
499  static_assert(sizeof(T)==0, "Trying to reflect unknown type.");
500  }
501  };
502 
504  struct ReflectAtomic {
505  template<typename T>
506  static void invoke(Derived& r, T& member) {
507  r.invokeTrackObject(member);
508  r.atomic(member);
509  }
510  };
511 
514  template<typename T>
515  static void invoke(Derived& r, T& member) {
516  r.invokeTrackObject(member);
517  r.enumeration(member);
518  }
519  };
520 
522  struct ReflectArray {
523  template<typename T>
524  static void invoke(Derived& r, T& member) {
525  r.invokeTrackObject(member);
526  std::size_t size = sizeof(member) /
527  (static_cast<const char *>(static_cast<const void *>(&member[1]))
528  - static_cast<const char *>(static_cast<const void *>(&member[0])) );
529 
530  typedef typename std::remove_extent<T>::type ItemType;
531  serialization::Array<ItemType> array(member, size);
532  //r.collection(array);
533  ReflectCollection::invoke(r, array);
534  }
535  };
536 
538  struct ReflectComplex {
539  template<typename T>
540  static void invoke(Derived& r, T& member) {
541  r.invokeTrackObject(member);
542  typedef typename std::remove_cv<T>::type Type;
543  static_assert(!IsCollection<Type>::value,
544  "Trying to call ReflectComplex::invoke<T>() with IsCollection<T> == true - something is wrong.");
546  r.invoke(member);
547  else
548  r.object(member);
549  }
550  };
551 
554  template<typename T>
555  static void invoke(Derived& r, T& member) {
556  r.invokeTrackObject(member);
557  typedef typename std::remove_cv<T>::type Type;
558  typedef IsTransparentSerializableHelper<Type,Derived> isTransparent;
559  static_assert(!isTransparent::value,
560  "Trying to call ReflectCollection::invoke<T>() with IsTransparentSerializable<T> == true - something is wrong.");
561  r.collection(member);
562  }
563  };
564 
566  struct ReflectPointer {
567  template<typename T>
568  static void invoke(Derived& r, T& member) {
569  // clear the inline flag
570  r.pointer(member);
571  }
572  };
573 
574  // The following ReflectPointerXXX structs are used by our pointer() method
575 
578  template<typename T>
579  static void invoke(Derived& r, T* &pointer) {
580  r.pointerNormal(pointer, typeId<T>());
581  }
582  };
583 
584 
587  template<typename T>
588  static void invoke(Derived& r, T* &pointer) {
589  int typeId = -1;
590 
591  if(pointer!=NULL) {
592  // we have an object, so we can obtain its class information
593  const Class& c = pointer->getClass();
594  typeId = c.getTypeId();
595  }
596 
597  // call pointerPolymorphic()
598  r.pointerPolymorphic(pointer, typeId);
599  }
600  };
601 
607  template<typename T>
608  static void invoke(Derived& r, T* &pointer) {
609  r.pointerAbstract(pointer, typeId<T>());
610  }
611  };
612 
613 
618  template<typename T>
619  struct ChooseReflect {
620 
621  typedef typename std::remove_cv<T>::type Type;
622  typedef typename
623  boost::mpl::eval_if<std::is_pointer<Type>,
624  boost::mpl::identity<ReflectPointer>, // T is a pointer (Type C)
625  //else
626  boost::mpl::eval_if<IsAtomicSerializable<Type>,
627  boost::mpl::identity<ReflectAtomic>, // atomic (Type A1)
628  // else // T is not atomic
629  boost::mpl::eval_if<std::is_class<Type>,
630  boost::mpl::eval_if<IsCollection<Type>,
631  boost::mpl::identity<ReflectCollection>, // T is a collection (Type B?c)
632  // else
633  boost::mpl::identity<ReflectComplex>>, // T is a complex class (Type B1/B2)
634  //else // T is no pointer, no class --> must be atomic or enum
635  boost::mpl::eval_if<std::is_enum<Type>,
636  boost::mpl::identity<ReflectEnumeration>, // enum (Type A2)
637  // else
638  boost::mpl::eval_if<std::is_array<Type>,
639  boost::mpl::identity<ReflectArray>, // array (Type A3)
640  // ELSE unknown
641  boost::mpl::identity<ReflectUnknown>
642  >
643  >
644  >
645  >
647  };
648 
649 public:
650 
661  template<typename T>
662  void invokeMember(T& member, const ReflectMemberMeta& meta)
663  {
664  this->This()->invokeMemberOverwrite(member, meta);
665  }
666 
673  template<typename T>
675  {
676  // store previous meta (it is restored at the end of this method
677  // and therefore implements a stack, where mCurrentMemberMeta is
678  // the top element in the stack)
679  const ReflectMemberMeta* prevMeta = mCurrentMemberMeta;
680 
681  // do the same to create a stack of the full human readable object
682  // id (however, only do it, if our final reflector supports human
683  // readable id's, otherwise skip this step since it hurts the
684  // performance
685  std::string prevFullID;
686  if(this->usesHumanReadableIDs()) {
687  prevFullID = mCurrentMemberFullID;
688 
689  // "push" new full id
690  if(mCurrentMemberFullID.empty()) {
691  if(meta.id==NULL)
692  MIRA_THROW(XLogical, "Top-level member cannot be 'inline'. "
693  "It must have an ID != NULL!");
694  mCurrentMemberFullID=meta.id;
695  } else if(meta.id!=NULL)
696  mCurrentMemberFullID = mCurrentMemberFullID + "." + meta.id;
697  }
698 
699  // "push" current meta (but only if member is not transparent, which is
700  // indicated by an id of NULL)
701  if(meta.id != NULL)
702  mCurrentMemberMeta = &meta;
703 
704  // Choose the type of the member and select the
705  // correct ReflectXYZ struct for that type at compile type.
706  // Then call the invoke method of that struct.
707  // (The different structures and their invoke methods are defined
708  // above)
709  try
710  {
711  ChooseReflect<T>::type::invoke(*this->This(), member);
712  }
713  catch(...)
714  {
715  // "pop" our id
716  if(this->usesHumanReadableIDs())
717  mCurrentMemberFullID=prevFullID;
718  // "pop" our meta data stack.
719  mCurrentMemberMeta = prevMeta;
720  // and throw
721  throw;
722  }
723 
724  // "pop" our id
725  if(this->usesHumanReadableIDs())
726  mCurrentMemberFullID=prevFullID;
727  // "pop" our meta data stack.
728  mCurrentMemberMeta = prevMeta;
729  }
730 
735  template<typename T>
737  {
738  ChooseReflect<T>::type::invoke(*this->This(), member);
739  }
740 
741 
746  template<typename T>
748  {
749  try {
750  this->invokeMember(member,meta);
751  } catch (XMemberNotFound& ex) {
752  throw XMemberNotFound_NoDefault(ex);
753  // transform exception to avoid catching it
754  // in upper levels, where it might be shadowed
755  // if a default value is given there (see #685)
756  } catch(Exception& ex) {
757  if (meta.getName() == MIRA_REFLECTOR_TOPLEVEL_NAME) // no extra info
758  throw;
759 
760  MIRA_RETHROW(ex, "while " <<
761  (Derived::isReadOnly::value ? "serializing" : "deserializing") <<
762  " '" << meta.getName() << "'");
763  }
764  }
765 
771  template<typename T, typename U>
773  const U& defaultValue)
774  {
775  try {
776  this->invokeMember(member,meta);
777  } catch (XMemberNotFound_NoDefault&) {
778  throw; // must not handle this
779  } catch (XMemberNotFound&) {
780  if(!Derived::isReadOnly::value) {
781  MIRA_LOG(NOTICE) << "No value given for '" << meta.name << "', "
782  "using the default value instead.";
783 
784  // #############################################################
785  // If you get a compiler error here, your default value does not
786  // match to your member type and cannot be casted. Make sure
787  // that the data type of your default value can be casted to
788  // the data type of your member!
789  // #############################################################
790  try {
791  member=defaultValue;
792  } catch(Exception& ex) {
793  MIRA_RETHROW(ex, "while default-initializing '" << meta.getName() << "'");
794  }
795  }
796  } catch(Exception& ex) {
797  if (meta.getName() == MIRA_REFLECTOR_TOPLEVEL_NAME) // no extra info
798  throw;
799 
800  MIRA_RETHROW(ex, "while " <<
801  (Derived::isReadOnly::value ? "serializing" : "deserializing") <<
802  " '" << meta.getName() << "'");
803  }
804  }
805 
812  template<typename T>
814  const serialization::IgnoreMissing& defaultValue)
815  {
816  try {
817  this->invokeMember(member,meta);
818  } catch (XMemberNotFound_NoDefault&) {
819  throw; // must not handle this
820  } catch (XMemberNotFound&) {
821  // IGNORE
822  } catch(Exception& ex) {
823  if (meta.getName() == MIRA_REFLECTOR_TOPLEVEL_NAME) // no extra info
824  throw;
825 
826  MIRA_RETHROW(ex, "while " <<
827  (Derived::isReadOnly::value ? "serializing" : "deserializing") <<
828  " '" << meta.getName() << "'");
829  }
830  }
831 
833 
834 private:
835 
836  const ReflectMemberMeta* mCurrentMemberMeta;
837  std::string mCurrentMemberFullID;
838 
839 };
840 
842 
861 template <typename Derived>
863 {
864 public:
865 
866  // implement our supported visiting methods of the ReflectorInterface
867  // note: the documentation of the following methods is inherited from
868  // ReflectorInterface by Doxygen
869 
870  template<typename T>
871  void member(const char* name, T& member, const char* comment,
873  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
874  this->This()->pushObjectTrackingStore();
875  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, name, comment) );
876  this->This()->popObjectTrackingStore();
877  } else
878  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, name, comment) );
879  }
880 
881  template<typename T>
882  void member(const char* name, const std::string& id, T& member,
883  const char* comment, ReflectCtrlFlags flags = REFLECT_CTRLFLAG_NONE) {
884  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
885  this->This()->pushObjectTrackingStore();
886  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, id.c_str(),
887  comment) );
888  this->This()->popObjectTrackingStore();
889  } else
890  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, id.c_str(),
891  comment) );
892  }
893 
894  template<typename T>
895  void member(const char* name, const T& member, Setter<T> setter,
896  const char* comment, ReflectCtrlFlags flags = REFLECT_CTRLFLAG_NONE) {
897  auto a = makeAccessor(member, setter);
898  this->This()->pushObjectTrackingStore();
899  this->invokeMemberWithoutDefault(a, ReflectMemberMeta(name, name, comment) );
900  this->This()->popObjectTrackingStore();
901  }
902 
903  template<typename T>
904  void member(const char* name, Getter<T> getter, Setter<T> setter,
905  const char* comment, ReflectCtrlFlags flags = REFLECT_CTRLFLAG_NONE) {
906  auto a = makeAccessor(getter, setter);
907  this->This()->pushObjectTrackingStore();
908  this->invokeMemberWithoutDefault(a, ReflectMemberMeta(name, name, comment) );
909  this->This()->popObjectTrackingStore();
910  }
911 
912  // avoid member("MyMember", member, "my member", {}) (most probably meant to
913  // set default-initialized object as deserialization default) unambiguously matching
914  // Reflector::member(name, member, comment, flags). see #910
915  template<typename T>
916  void member(const char* name, T& member, const char* comment,
917  const T& defaultValue, ReflectCtrlFlags flags = REFLECT_CTRLFLAG_NONE) {
918  this->template member<T, T>(name, member, comment, defaultValue, flags);
919  }
920 
921  template<typename T, typename U>
922  void member(const char* name, T& member, const char* comment,
923  const U& defaultValue, ReflectCtrlFlags flags = REFLECT_CTRLFLAG_NONE) {
924  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
925  this->This()->pushObjectTrackingStore();
926  this->invokeMemberWithDefault(member, ReflectMemberMeta(name, name, comment),
927  defaultValue);
928  this->This()->popObjectTrackingStore();
929  } else
930  this->invokeMemberWithDefault(member, ReflectMemberMeta(name, name, comment),
931  defaultValue);
932  }
933 
934  // see above. see #910
935  template<typename T>
936  void member(const char* name, const T& member, Setter<T> setter,
937  const char* comment, const T& defaultValue,
939  this->template member<T, T>(name, member, setter, comment, defaultValue, flags);
940  }
941 
942  template<typename T, typename U>
943  void member(const char* name, const T& member, Setter<T> setter,
944  const char* comment, const U& defaultValue,
946  auto a = makeAccessor(member, setter);
947  this->This()->pushObjectTrackingStore();
948  this->invokeMemberWithDefault(a, ReflectMemberMeta(name, name, comment),
949  defaultValue );
950  this->This()->popObjectTrackingStore();
951  }
952 
953  // see above. see #910
954  template<typename T>
955  void member(const char* name, Getter<T> getter, Setter<T> setter,
956  const char* comment, const T& defaultValue,
958  this->template member<T, T>(name, getter, setter, comment, defaultValue, flags);
959  }
960 
961  template<typename T, typename U>
962  void member(const char* name, Getter<T> getter, Setter<T> setter,
963  const char* comment, const U& defaultValue,
965  auto a = makeAccessor(getter, setter);
966  this->This()->pushObjectTrackingStore();
967  this->invokeMemberWithDefault(a, ReflectMemberMeta(name, name, comment),
968  defaultValue );
969  this->This()->popObjectTrackingStore();
970  }
971 
972  template<typename T>
973  void property(const char* name, T& member, const char* comment,
974  PropertyHint&& hint = PropertyHint(),
976  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
977  this->This()->pushObjectTrackingStore();
978  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, name, comment) );
979  this->This()->popObjectTrackingStore();
980  } else
981  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, name, comment) );
982  }
983 
984  template<typename T>
985  void property(const char* name, const std::string& id, T& member,
986  const char* comment, PropertyHint&& hint = PropertyHint(),
988  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
989  this->This()->pushObjectTrackingStore();
990  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, id.c_str(), comment) );
991  this->This()->popObjectTrackingStore();
992  } else
993  this->invokeMemberWithoutDefault(member, ReflectMemberMeta(name, id.c_str(), comment) );
994  }
995 
996  template<typename T>
997  void property(const char* name, const T& member, Setter<T> setter,
998  const char* comment, PropertyHint&& hint = PropertyHint(),
1000  auto a = makeAccessor(member, setter);
1001  this->This()->pushObjectTrackingStore();
1002  this->invokeMemberWithoutDefault(a, ReflectMemberMeta(name, name, comment) );
1003  this->This()->popObjectTrackingStore();
1004  }
1005 
1006  template<typename T>
1007  void property(const char* name, Getter<T> getter, Setter<T> setter,
1008  const char* comment, PropertyHint&& hint = PropertyHint(),
1010  auto a = makeAccessor(getter, setter);
1011  this->This()->pushObjectTrackingStore();
1012  this->invokeMemberWithoutDefault(a, ReflectMemberMeta(name, name, comment) );
1013  this->This()->popObjectTrackingStore();
1014  }
1015 
1016  // see above. see #910
1017  template<typename T>
1018  void property(const char* name, T& member, const char* comment,
1019  const T& defaultValue, PropertyHint&& hint = PropertyHint(),
1021  this->template property<T, T>(name, member, comment, defaultValue, std::move(hint), flags);
1022  }
1023 
1024  template<typename T, typename U>
1025  void property(const char* name, T& member, const char* comment,
1026  const U& defaultValue, PropertyHint&& hint = PropertyHint(),
1028  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
1029  this->This()->pushObjectTrackingStore();
1030  this->invokeMemberWithDefault(member, ReflectMemberMeta(name, name, comment),
1031  defaultValue);
1032  this->This()->popObjectTrackingStore();
1033  } else
1034  this->invokeMemberWithDefault(member, ReflectMemberMeta(name, name, comment),
1035  defaultValue);
1036  }
1037 
1038  // see above. see #910
1039  template<typename T>
1040  void property(const char* name, const T& member, Setter<T> setter,
1041  const char* comment, const T& defaultValue,
1042  PropertyHint&& hint = PropertyHint(),
1044  this->template property<T, T>(name, member, setter, comment, defaultValue, std::move(hint), flags);
1045  }
1046 
1047  template<typename T, typename U>
1048  void property(const char* name, const T& member, Setter<T> setter,
1049  const char* comment, const U& defaultValue,
1050  PropertyHint&& hint = PropertyHint(),
1052  auto a = makeAccessor(member, setter);
1053  this->This()->pushObjectTrackingStore();
1054  this->invokeMemberWithDefault(a, ReflectMemberMeta(name, name, comment),
1055  defaultValue );
1056  this->This()->popObjectTrackingStore();
1057  }
1058 
1059  // see above. see #910
1060  template<typename T>
1061  void property(const char* name, Getter<T> getter, Setter<T> setter,
1062  const char* comment, const T& defaultValue,
1063  PropertyHint&& hint = PropertyHint(),
1065  this->template property<T, T>(name, getter, setter, comment, defaultValue, std::move(hint), flags);
1066  }
1067 
1068  template<typename T, typename U>
1069  void property(const char* name, Getter<T> getter, Setter<T> setter,
1070  const char* comment, const U& defaultValue,
1071  PropertyHint&& hint = PropertyHint(),
1073  auto a = makeAccessor(getter, setter);
1074  this->This()->pushObjectTrackingStore();
1075  this->invokeMemberWithDefault(a, ReflectMemberMeta(name, name, comment),
1076  defaultValue );
1077  this->This()->popObjectTrackingStore();
1078  }
1079 
1086  template<typename T>
1088  if (flags & REFLECT_CTRLFLAG_TEMP_TRACKING) {
1089  this->This()->pushObjectTrackingStore();
1090  this->invokeMember(member, ReflectMemberMeta(NULL, NULL, "") );
1091  this->This()->popObjectTrackingStore();
1092  } else
1093  this->invokeMember(member, ReflectMemberMeta(NULL, NULL, "") );
1094  }
1095 
1102  template<typename T>
1105  auto a = makeAccessor(member, setter);
1106  this->This()->pushObjectTrackingStore();
1107  this->invokeMember(a, ReflectMemberMeta(NULL, NULL, "") );
1108  this->This()->popObjectTrackingStore();
1109  }
1110 
1117  template<typename T>
1120  auto a = makeAccessor(getter, setter);
1121  this->This()->pushObjectTrackingStore();
1122  this->invokeMember(a, ReflectMemberMeta(NULL, NULL, "") );
1123  this->This()->popObjectTrackingStore();
1124  }
1125 
1126 };
1127 
1129 
1130 }
1131 
1132 #endif
TypeId typeId()
Generates unique IDs for different types.
Definition: TypeId.h:94
This object can use object tracking internally, but the object tracking system&#39;s state remains unchan...
Definition: ReflectControlFlags.h:82
Type trait that indicates whether pointer tracking can be enabled for this type.
Definition: IsObjectTrackable.h:68
void object(T &member)
Is called for each complex object.
Definition: RecursiveMemberReflector.h:302
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:506
std::string getName() const
Definition: ReflectMemberMeta.h:82
Provides safe casts for casting from a pointer to void* and vice versa while taking care of polymorph...
std::remove_cv< T >::type Type
Definition: RecursiveMemberReflector.h:621
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:515
void property(const char *name, T &member, const char *comment, const U &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1025
Type C3: for members that are pointers to abstract classes not derived from mira::Object.
Definition: RecursiveMemberReflector.h:606
void property(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1007
boost::mpl::eval_if< std::is_pointer< Type >, boost::mpl::identity< ReflectPointer >, boost::mpl::eval_if< IsAtomicSerializable< Type >, boost::mpl::identity< ReflectAtomic >, boost::mpl::eval_if< std::is_class< Type >, boost::mpl::eval_if< IsCollection< Type >, boost::mpl::identity< ReflectCollection >, boost::mpl::identity< ReflectComplex > >, boost::mpl::eval_if< std::is_enum< Type >, boost::mpl::identity< ReflectEnumeration >, boost::mpl::eval_if< std::is_array< Type >, boost::mpl::identity< ReflectArray >, boost::mpl::identity< ReflectUnknown > > > > > >::type type
Definition: RecursiveMemberReflector.h:646
void member(const char *name, const T &member, Setter< T > setter, const char *comment, const U &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:943
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
void member(const char *name, const T &member, Setter< T > setter, const char *comment, const T &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:936
Abstract base class for most Reflectors.
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:540
const std::string & getCurrentMemberFullID() const
Returns the full human readable object id / name of the current member being reflected.
Definition: RecursiveMemberReflector.h:462
void member(const char *name, T &member, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:871
Type A3: for arrays.
Definition: RecursiveMemberReflector.h:522
void property(const char *name, T &member, const char *comment, const T &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1018
Type C1: for members that are pointers to normal classes.
Definition: RecursiveMemberReflector.h:577
#define MIRA_LOG(level)
Use this macro to log data.
Definition: LoggingCore.h:528
void trackObject(T &member)
Definition: RecursiveMemberReflector.h:318
Class object which supports some kind of class reflection.
Definition: Class.h:97
#define MIRA_RETHROW(ex, msg)
Macro for rethrowing an exception with file and line information and for adding additional informatio...
Definition: Exception.h:144
Contains toString and fromString functions for converting data types to strings and the other way rou...
#define MIRA_DEFINE_SERIALIZABLE_EXCEPTION(Ex, Base)
Macro for easily defining a new serializable exception class.
Definition: Exceptions.h:66
Setter< T > setter(void(*f)(const T &))
Creates a Setter for global or static class methods taking the argument by const reference.
Definition: GetterSetter.h:443
Holds a boost::function object to a special setter function that must meet the signature "void method...
Definition: GetterSetter.h:395
Stores meta information for each member.
Definition: ReflectMemberMeta.h:64
Type B?c: for collection types.
Definition: RecursiveMemberReflector.h:553
const char * name
The name (as specified in the XML file).
Definition: ReflectMemberMeta.h:67
void property(const char *name, T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:973
Type A1: for atomic members (float,int,etc.)
Definition: RecursiveMemberReflector.h:504
Provided for convenience.
Definition: Singleton.h:564
Provides type trait that indicates whether a type should be serialized "transparently".
Provides type trait that indicates whether pointer/object tracking should be enabled for a certain ty...
Contains internal accessor class that abstracts from the underlying getter and setter classes or dire...
void invokeMemberWithDefault(T &member, const ReflectMemberMeta &meta, const U &defaultValue)
Delegates to invokeMember() and handles any occurring XMemberNotFound exception by setting the member...
Definition: RecursiveMemberReflector.h:772
void pointerAbstract(T *&pointer, int typeId)
Is called if a reflected pointer is a pointer to an abstract class.
Definition: RecursiveMemberReflector.h:399
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
Marker for indicating parameters that should be ignored if they are missing in the config file...
void property(const char *name, const T &member, Setter< T > setter, const char *comment, const U &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1048
A property hint gives optional instructions to the property editor, i.e.
Definition: PropertyHint.h:82
Derived * This()
"Curiously recurring template pattern" (CRTP).
Definition: AbstractReflector.h:251
Type B1/B2: for complex types.
Definition: RecursiveMemberReflector.h:538
Wrapper class for reflecting arrays.
XMemberNotFound_NoDefault() MIRA_NOEXCEPT_OR_NOTHROW
Definition: RecursiveMemberReflector.h:133
const ReflectMemberMeta & getCurrentMemberMeta() const
Returns the meta-information of the current member that is reflected.
Definition: RecursiveMemberReflector.h:451
void property(const char *name, const std::string &id, T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:985
Abstract base class for most Reflectors.
Definition: AbstractReflector.h:165
static bool usesHumanReadableIDs()
Returns true, if the concrete derived Reflector supports human readable IDs.
Definition: ReflectorInterface.h:845
Marker for indicating parameters that should be ignored if they are missing in the config file...
Definition: IgnoreMissing.h:73
Can be thrown by subclasses of RecursiveMemberReflectorBase to indicate that they did not find a cert...
Definition: RecursiveMemberReflector.h:128
$Header file containing base classes to enable class creation using a class factory$ ...
Implementation of the InstantiationPolicy that is used by the Singleton template. ...
Definition: Singleton.h:339
void pointerPolymorphic(T *&pointer, int typeId)
Is called if a reflected pointer is a polymorphic pointer to an object that is derived from mira::Obj...
Definition: RecursiveMemberReflector.h:369
void delegate(Getter< T > getter, Setter< T > setter, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Delegates the serialization directly to the specified member, without creating a separate compound fo...
Definition: RecursiveMemberReflector.h:1118
Struct to take meta information for each reflected member.
Type A2: for enums.
Definition: RecursiveMemberReflector.h:513
static bool isReflectedAsPointer()
For internal use only: Returns true, if the type T is ever reflected as pointer within the current tr...
Definition: RecursiveMemberReflector.h:476
SetReflectedAsPointer()
Definition: RecursiveMemberReflector.h:108
A singleton template class that can be freely configured using policies that control the instantiatio...
Definition: Singleton.h:531
void pointerNormal(T *&pointer, int typeId)
Is called if a reflected pointer is a "normal" pointer.
Definition: RecursiveMemberReflector.h:355
No flags.
Definition: ReflectControlFlags.h:65
A singleton class that can be freely configured using policies that control the creation, instantiation, lifetime and thread-safety.
static void invoke(Derived &r, T *&pointer)
Definition: RecursiveMemberReflector.h:608
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
void invokeTrackObject(T &member)
tracks the given object (if pointer tracking is enabled for type T)
Definition: RecursiveMemberReflector.h:484
Core class of the logging library.
void delegate(T &member, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Delegates the serialization directly to the specified member, without creating a separate compound fo...
Definition: RecursiveMemberReflector.h:1087
void invokePointerObject(T &member)
Is called to reflect objects of pointers.
Definition: RecursiveMemberReflector.h:736
bool value
Definition: RecursiveMemberReflector.h:103
void property(const char *name, const T &member, Setter< T > setter, const char *comment, const T &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1040
Getter< T > getter(T(*f)())
Creates a Getter for global or static class methods returning the result by value.
Definition: GetterSetter.h:136
The RecursiveMemberReflectorBase is a base class for all Reflectors that are used to visit the reflec...
Definition: RecursiveMemberReflector.h:234
static void unregisterClass()
Unregisters the class.
Definition: RecursiveMemberReflector.h:440
Provides type trait that indicates whether a type is a collection.
void property(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, const U &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1069
void property(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, const T &defaultValue, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:1061
void invokeMemberWithoutDefault(T &member, const ReflectMemberMeta &meta)
Delegates to invokeMember() and rethrows any occurring XMemberNotFound exception as XIO exception...
Definition: RecursiveMemberReflector.h:747
void member(const char *name, T &member, const char *comment, const U &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:922
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:524
virtual std::string const & getIdentifier() const
Return identifier for the class.
void member(const char *name, const std::string &id, T &member, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:882
RecursiveMemberReflectorBase()
The constructor.
Definition: RecursiveMemberReflector.h:240
#define MIRA_NOEXCEPT_OR_NOTHROW
Definition: NoExcept.h:99
#define MIRA_OBJECT(classIdentifier)
Use this MACRO if you like the factory to automatically extract the class name from the given identif...
Definition: FactoryMacros.h:183
XMemberNotFound_NoDefault(XMemberNotFound &ex) MIRA_NOEXCEPT_OR_NOTHROW
Definition: RecursiveMemberReflector.h:136
Implementation of the CreationPolicy that is used by the Singleton template.
Definition: Singleton.h:190
Base class for exceptions.
Definition: Exception.h:194
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:568
void member(const char *name, const T &member, Setter< T > setter, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:895
void member(const char *name, T &member, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Specifies a class member for reflection/serialization.
Definition: ReflectorInterface.h:375
Definition: RecursiveMemberReflector.h:496
Type C: for members that are pointers.
Definition: RecursiveMemberReflector.h:566
static void invoke(Derived &r, T *&pointer)
Definition: RecursiveMemberReflector.h:579
Holds a boost::function object to a special getter function that must meet the signature "T method()"...
Definition: GetterSetter.h:87
For internal use only: Holds value=true, if the type T is ever reflected as pointer with Reflector wi...
Definition: RecursiveMemberReflector.h:101
void member(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, const T &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:955
void invokeMember(T &member, const ReflectMemberMeta &meta)
Is called to invoke this Reflector on the member with the specified meta information.
Definition: RecursiveMemberReflector.h:662
Provides type trait that indicates whether a type can be serialized as atomic value.
void property(const char *name, const T &member, Setter< T > setter, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:997
void pointer(T *&pointer)
Is called if the member is a pointer.
Definition: RecursiveMemberReflector.h:326
void delegate(const T &member, Setter< T > setter, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Delegates the serialization directly to the specified member, without creating a separate compound fo...
Definition: RecursiveMemberReflector.h:1103
static constexpr auto MIRA_REFLECTOR_TOPLEVEL_NAME
Use this when a reflector needs to choose a name for serializing an object.
Definition: RecursiveMemberReflector.h:250
void invokeMemberOverwrite(T &member, const ReflectMemberMeta &meta)
The actual invokeMember implementation that is called from invokeMember().
Definition: RecursiveMemberReflector.h:674
void enumeration(T &member)
Is called by the if the member is an enumeration.
Definition: RecursiveMemberReflector.h:282
ReflectCtrlFlags
Control Flags that can modify the behavior of certain reflectors.
Definition: ReflectControlFlags.h:63
ReflectedAsPointer()
Definition: RecursiveMemberReflector.h:102
void collection(T &member)
Is called for each complex object or array, where the IsCollection<T> trait is true_type.
Definition: RecursiveMemberReflector.h:312
Type trait that indicates whether a type is a collection.
Definition: IsCollection.h:63
void member(const char *name, T &member, const char *comment, const T &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:916
void member(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:904
Detect the members type (A1,A2,A3,B1,B2,C) and choose the appropriate struct ReflectAtomic, etc.
Definition: RecursiveMemberReflector.h:619
static void registerClass()
Registers a new polymorphic class at the PolymorphPointerReflector.
Definition: RecursiveMemberReflector.h:421
void member(const char *name, Getter< T > getter, Setter< T > setter, const char *comment, const U &defaultValue, ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:962
Definition: IsTransparentSerializable.h:84
Accessor< Getter, Setter > makeAccessor(const Getter &getter, const Setter &setter)
Helper method that creates an accessor from a different combination of either direct access to a vari...
Definition: Accessor.h:300
The RecursiveMemberReflector extents the RecursiveMemberReflectorBase class and implements the member...
Definition: RecursiveMemberReflector.h:862
void * void_upcast(T *pointer)
Safe cast for casting from a pointer upwards to void* while taking care of polymorphism and multiple ...
Definition: VoidCast.h:117
const char * id
The id (used for containers where the name is identical, in all other cases the id usually is equal t...
Definition: ReflectMemberMeta.h:73
Definition: RecursiveMemberReflector.h:107
For internal use by RecursiveMemberReflector.h!
void atomic(T &member)
Is called if the member is an atomic type (int, float, etc).
Definition: RecursiveMemberReflector.h:269
Type C2: for members that are pointers to polymorphic classes derived from mira::Object.
Definition: RecursiveMemberReflector.h:586
Definition: LoggingCore.h:76
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:555
static void invoke(Derived &r, T *&pointer)
Definition: RecursiveMemberReflector.h:588
static void invoke(Derived &r, T &member)
Definition: RecursiveMemberReflector.h:498
void invokeMemberWithDefault(T &member, const ReflectMemberMeta &meta, const serialization::IgnoreMissing &defaultValue)
Delegates to invokeMember() and handles any occurring XMemberNotFound exception by ignoring the excep...
Definition: RecursiveMemberReflector.h:813
virtual int getTypeId() const =0
Return unique id for the class.