MIRA
ExtensibleEnum.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017 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_EXTENSIBLEENUM_H_
48 #define _MIRA_EXTENSIBLEENUM_H_
49 
50 #include <type_traits>
51 
52 #include <boost/preprocessor/tuple/to_seq.hpp>
53 #include <boost/preprocessor/seq/for_each.hpp>
54 
55 #include <boost/thread/mutex.hpp>
56 
57 #include <utils/VariadicMacro.h>
58 
61 
62 namespace mira {
63 
65 
66 namespace detail {
67 // implementations of variants of extensible enum
68 
70 
71 // CRTP ensures we have no common base class between derived enum classes
72 // -> we can detect mixup at compile time
73 template<typename T>
75 {
76 public:
77  bool operator==(const NoValueEnum<T>& other) const { return ref == other.ref; }
78  bool operator!=(const NoValueEnum<T>& other) const { return ref != other.ref; }
79 
80 protected:
81  NoValueEnum<T>() : ref(this) {}
82 
83 private:
84  NoValueEnum<T> const * ref;
85 };
86 
88 
89 // we want one mutex per counter -> need all template parameters from
90 // AutoCountingEnum, even though we don't use all
91 template<typename T, typename CountType=int, bool UseMutex=false>
93 {
94  static void count(CountType& i, CountType& counter)
95  {
96  i = counter++;
97  }
98 };
99 
100 template<typename T, typename CountType>
101 struct AutoCountingHelper<T, CountType, true>
102 {
103  static void count(CountType& i, CountType& counter)
104  {
105  boost::mutex::scoped_lock lock(mutex);
106  i = counter++;
107  }
108 
109  static boost::mutex mutex;
110 };
111 
112 template<typename T, typename CountType>
114 
115 // CRTP additionally ensures we have one counter per direct subclass
116 template<typename T, typename CountType=int, bool UseMutex=false>
118 {
119 public:
120  bool operator==(const AutoCountingEnum<T, CountType, UseMutex>& other) const { return i == other.i; }
121  bool operator!=(const AutoCountingEnum<T, CountType, UseMutex>& other) const { return i != other.i; }
122 
123  static CountType count() { return counter; }
124 
125 protected:
127  {
129  }
130 
131 protected:
132  CountType i;
133  static CountType counter;
134 };
135 
136 template<typename T, typename CountType, bool UseMutex>
138 
140 
141 // for Counting = false it derives from NoValueEnum
142 template <typename T, bool Counting=false, typename CountType=int, bool UseMutex=false>
143 struct ExtensibleEnumBase : public NoValueEnum<T>
144 {
145 protected:
147 };
148 
149 // for Counting = true it derives from AutoCountingEnum
150 template <typename T, typename CountType, bool UseMutex>
151 struct ExtensibleEnumBase<T, true, CountType, UseMutex>
152  : public AutoCountingEnum<T, CountType, UseMutex>
153 {
154 protected:
156  {
157  static_assert(std::is_integral<CountType>::value, "Integral required for CountType template param.");
158  }
159 };
160 
162 
163 } // namespace
164 
166 
282 
284 template <typename T, bool UseID=false, bool Counting=false, typename CountType=int, bool UseMutex=false>
285 struct ExtensibleEnum : public detail::ExtensibleEnumBase<T, Counting, CountType, UseMutex>
286 {
287 protected:
288  // we take the string param so we have a uniform interface, but ignore it
290 };
291 
292 template <typename T, bool Counting, typename CountType, bool UseMutex>
293 struct ExtensibleEnum<T, true, Counting, CountType, UseMutex>
294  : public detail::ExtensibleEnumBase<T, Counting, CountType, UseMutex>
295 {
296 protected:
297  ExtensibleEnum<T, true, Counting, CountType, UseMutex>(const std::string& id = "") : ID(id) {}
298 
299 public:
300 
302 
305  {
306  r.property("id", ID, "");
307  }
308 
309  const std::string& id() const { return ID; }
310 
311 private:
312  std::string ID;
313 };
314 
316 
317 namespace detail {
318 
319 // helper to remove brackets within macro
320 // (which are needed to use template typenames including ',' as macro params)
321 template<typename> struct ExtEnum_RemoveBrackets;
322 template<typename T> struct ExtEnum_RemoveBrackets<void (T)> {
323  typedef T Result;
324 };
325 
326 }
327 
328 #define MIRA_EXTENUM_DECLARE_VALUE(R, ENUMNAME, VALUENAME) \
329  const static ENUMNAME VALUENAME;
330 
331 #define MIRA_EXTENSIBLE_ENUM_DECLARE(NAME, BASE, VALUES...) \
332  struct NAME : public mira::detail::ExtEnum_RemoveBrackets<void (BASE)>::Result \
333  { \
334  protected: \
335  NAME(const std::string& id = "") \
336  : mira::detail::ExtEnum_RemoveBrackets<void (BASE)>::Result(id) {} \
337  public: \
338  BOOST_PP_SEQ_FOR_EACH(MIRA_EXTENUM_DECLARE_VALUE, NAME, \
339  BOOST_PP_TUPLE_TO_SEQ(MIRA_VARIADIC_SIZE(VALUES), (VALUES)) ) \
340  };
341 
342 #define MIRA_EXTENUM_DEFINE_VALUE(R, ENUMNAME, VALUENAME) \
343  const ENUMNAME ENUMNAME::VALUENAME;
344 
345 #define MIRA_EXTENSIBLE_ENUM_DEFINE(NAME, VALUES...) \
346  BOOST_PP_SEQ_FOR_EACH(MIRA_EXTENUM_DEFINE_VALUE, NAME, \
347  BOOST_PP_TUPLE_TO_SEQ(MIRA_VARIADIC_SIZE(VALUES), (VALUES)) )
348 
350 
351 }
352 
353 #endif
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:93
Tools for handling variadic macros.
bool operator!=(const AutoCountingEnum< T, CountType, UseMutex > &other) const
Definition: ExtensibleEnum.h:121
bool operator==(const AutoCountingEnum< T, CountType, UseMutex > &other) const
Definition: ExtensibleEnum.h:120
static CountType count()
Definition: ExtensibleEnum.h:123
Definition: ExtensibleEnum.h:117
static void count(CountType &i, CountType &counter)
Definition: ExtensibleEnum.h:94
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
CountType i
Definition: ExtensibleEnum.h:132
#define MIRA_SPLIT_REFLECT_MEMBER
Macro that insert a class member reflect() method just splitting reflection into a reflectRead() and ...
Definition: SplitReflect.h:209
Definition: ExtensibleEnum.h:143
static CountType counter
Definition: ExtensibleEnum.h:133
void property(const char *name, T &member, const char *comment, PropertyHint &&hint=PropertyHint(), ReflectCtrlFlags flags=REFLECT_CTRLFLAG_NONE)
Definition: RecursiveMemberReflector.h:964
static void count(CountType &i, CountType &counter)
Definition: ExtensibleEnum.h:103
Provides MIRA_SPLIT_REFLECT macros.
MIRA_SPLIT_REFLECT_MEMBER void reflectRead(JSONSerializer &r)
only reflectRead(JSONSerializer&) is implemented, to be able to print()
Definition: ExtensibleEnum.h:304
Definition: ExtensibleEnum.h:74
Definition: ExtensibleEnum.h:321
const std::string & id() const
Definition: ExtensibleEnum.h:309
Definition: ExtensibleEnum.h:92
ExtensibleEnum is a base for derived classes that can be extensible &#39;replacements&#39; for enum types...
Definition: ExtensibleEnum.h:285
bool operator!=(const NoValueEnum< T > &other) const
Definition: ExtensibleEnum.h:78
T Result
Definition: ExtensibleEnum.h:323
bool operator==(const NoValueEnum< T > &other) const
Definition: ExtensibleEnum.h:77
Serializer and Deserializer for JSON format.
static boost::mutex mutex
Definition: ExtensibleEnum.h:109