MIRA
SplitReflect.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_SPLITREFLECT_H_
48 #define _MIRA_SPLITREFLECT_H_
49 
50 #ifndef Q_MOC_RUN
51 #include <boost/mpl/eval_if.hpp>
52 #include <boost/mpl/identity.hpp>
53 #endif
54 
55 #include <platform/Typename.h>
57 
58 namespace mira {
59 
60 template <typename Derived>
61 class ReflectorInterface;
62 
64 
66 // default
67 template<typename DerivedReflector, typename T>
69 {
70  // #########################################################################
71  // If you get a compiler error here, you used the splitReflect() method
72  // or the MIRA_SPLIT_REFLECT macro, but forgot to specialize and implement
73  // the reflectRead() and reflectWrite() methods for your type. Additionally,
74  // make sure, that these functions are placed within the namespace "mira".
75  // #########################################################################
76  static_assert(sizeof(T)==0, "You must implement reflectRead() "
77  "if you use the MIRA_SPLIT_REFLECT macro");
78 }
79 
80 template<typename DerivedReflector, typename T>
82 {
83  // #########################################################################
84  // If you get a compiler error here, you used the splitReflect() method
85  // or the MIRA_SPLIT_REFLECT macro, but forgot to specialize and implement
86  // the reflectRead() and reflectWrite() methods for your type. Additionally,
87  // make sure, that these functions are placed within the namespace "mira".
88  // #########################################################################
89  static_assert(sizeof(T)==0, "You must implement reflectWrite() "
90  "if you use the MIRA_SPLIT_REFLECT macro");
91 }
92 
93 struct GlobalReflectRead {
94  template<typename Reflector, typename T>
95  static void invoke(mira::ReflectorInterface<Reflector>& r, T& value) {
96  Reflector& reflector = static_cast<Reflector&>(r);
97  reflectRead(reflector, value);
98  }
99 };
100 
101 struct GlobalReflectWrite {
102  template<typename Reflector, typename T>
103  static void invoke(Reflector& r, T& value) {
104  reflectWrite(r, value);
105  }
106 };
107 
108 template<typename GlobalReflectReadOrWrite, typename Reflector, typename T>
109 inline void splitReflectInvoke(Reflector& r, T& value)
110 {
111  GlobalReflectReadOrWrite::invoke(r, value);
112 }
113 
125 template<typename Reflector, typename T>
126 inline void splitReflect(mira::ReflectorInterface<Reflector>& r, T& value)
127 {
128  Reflector& reflector = static_cast<Reflector&>(r);
129  typedef typename boost::mpl::eval_if<
130  typename Reflector::isReadOnly,
131  boost::mpl::identity<GlobalReflectRead>,
132  boost::mpl::identity<GlobalReflectWrite>
133  >::type rwtype;
134 
135  /* proper use of reflect barrier enables to e.g. potentially add a version to
136  the splitting mechanism itself (--> in splitReflectMemberInvoke()) */
137  static const std::string context = typeName<T>() + " splitReflect";
138 
139  MIRA_REFLECT_CALL(Reflector, reflector, context.c_str(),
140  (splitReflectInvoke<rwtype>(reflector, value)));
141 }
143 
154 #define MIRA_SPLIT_REFLECT(Type) \
155  template<typename Reflector> \
156  void reflect(mira::ReflectorInterface<Reflector>& r, Type& value) \
157  { \
158  splitReflect(r, value); \
159  }
160 
161 template<typename __reflectReadOrWrite, typename Reflector, typename Class>
162 inline void splitReflectMemberInvoke(Reflector& r, Class* This)
163 {
164  __reflectReadOrWrite::invoke(r, This);
165 }
166 
168 
169 namespace serialization {
170 
171 template<typename Reflector>
173 {
174  struct __reflectRead {
175  template<typename Class>
176  static void invoke(Reflector& r, Class* This) {
177  This->reflectRead(r);
178  }
179  };
180 
181  struct __reflectWrite {
182  template<typename Class>
183  static void invoke(Reflector& r, Class* This) {
184  This->reflectWrite(r);
185  }
186  };
187 
188  typedef typename boost::mpl::eval_if<
189  typename Reflector::isReadOnly,
190  boost::mpl::identity<__reflectRead>,
191  boost::mpl::identity<__reflectWrite>
193 };
194 
195 } // namespace
196 
198 
210 template<typename Reflector, typename Class>
212 {
213  Reflector& reflector = static_cast<Reflector&>(r);
215 
216  /* proper use of reflect barrier enables to e.g.
217  potentially add a version to the splitting mechanism
218  itself (--> in splitReflectMemberInvoke()) */
219 
220  static const std::string context = typeName<Class>() + " splitReflectMember";
221 
222  MIRA_REFLECT_CALL(Reflector, reflector, context.c_str(),
223  (splitReflectMemberInvoke<rwtype>(reflector, This)));
224 }
225 
238 #define MIRA_SPLIT_REFLECT_MEMBER \
239  template<typename Reflector> \
240  void reflect(mira::ReflectorInterface<Reflector>& r) \
241  { \
242  Reflector& reflector = static_cast<Reflector&>(r); \
243  typedef typename serialization::SplitReflectMemberHelper<Reflector>::rwtype rwtype; \
244  \
245  /* proper use of reflect barrier enables to e.g. \
246  potentially add a version to the splitting mechanism \
247  itself (--> in splitReflectMemberInvoke()) */ \
248  \
249  typedef typename std::remove_reference<decltype(*this)>::type splitType; \
250  \
251  static const std::string context = typeName<splitType>() + " MIRA_SPLIT_REFLECT_MEMBER"; \
252  \
253  MIRA_REFLECT_CALL(Reflector, reflector, context.c_str(), \
254  (splitReflectMemberInvoke<rwtype>(reflector, this))); \
255  }
256 
258 
259 } // namespace
260 
261 #endif /* _MIRA_SPLITREFLECT_H_ */
void reflectWrite(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:581
static void invoke(Reflector &r, Class *This)
Definition: SplitReflect.h:176
void reflectWrite(Reflector &r)
Implementation of class member reflection.
Definition: Class.h:762
Macros for use with reflectors.
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
Class object which supports some kind of class reflection.
Definition: Class.h:97
Get compiler and platform independent typenames.
void splitReflectMember(mira::ReflectorInterface< Reflector > &r, Class *This)
This method is used to split reflection into a reflectRead() and reflectWrite() method.
Definition: SplitReflect.h:211
This is the public interface of all reflectors that are able to visit a class&#39; reflect() method...
Definition: ReflectorInterface.h:111
MIRA_SPLIT_REFLECT_MEMBER void reflectRead(Reflector &r)
Implementation of class member reflection.
#define MIRA_REFLECT_CALL(ReflectorType, reflector, context, COMMAND)
Whenever a reflection function calls another function that is independently maintained, the call should be marked to the reflector.
Definition: ReflectorMacros.h:115
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
void splitReflectMemberInvoke(Reflector &r, Class *This)
Definition: SplitReflect.h:162
Definition: SplitReflect.h:172
boost::mpl::eval_if< typename Reflector::isReadOnly, boost::mpl::identity< __reflectRead >, boost::mpl::identity< __reflectWrite > >::type rwtype
Definition: SplitReflect.h:192
static void invoke(Reflector &r, Class *This)
Definition: SplitReflect.h:183
void reflectRead(Reflector &r, Buffer< T, Allocator > &c)
Specialization of the non-intrusive reflect for Buffer.
Definition: Buffer.h:565