RefleX
Build DDS Applications in Modern C++ without IDL
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
disc_union.h
Go to the documentation of this file.
1 /*********************************************************************************************
2 (c) 2005-2014 Copyright, Real-Time Innovations, Inc. All rights reserved.
3 RTI grants Licensee a license to use, modify, compile, and create derivative works
4 of the Software. Licensee has the right to distribute object form only for use with RTI
5 products. The Software is provided "as is", with no warranty of any type, including
6 any warranty for fitness for any purpose. RTI is under no obligation to maintain or
7 support the Software. RTI shall not be liable for any incidental or consequential
8 damages arising out of the use or inability to use the software.
9 **********************************************************************************************/
10 
11 #ifndef RTIREFLEX_DISC_UNION_H
12 #define RTIREFLEX_DISC_UNION_H
13 
14 #include <boost/variant.hpp>
15 #include <boost/optional.hpp>
16 #include <boost/utility/typed_in_place_factory.hpp>
17 #include <tuple>
18 #include <typeinfo>
19 #include "reflex/tuple_iterator.h"
20 #include "reflex/member_names.h"
21 
22 namespace reflex {
23 
24  namespace match {
25 
26  template <class... T>
27  struct Sparse
28  {
29  typedef std::tuple<boost::optional<T>...> tuple_type;
30  typedef std::tuple<T...> raw_tuple_type;
31 
32  const tuple_type & get_opt_tuple() const {
33  return val_;
34  }
35 
37  return val_;
38  }
39 
40  bool operator == (const Sparse & rhs) const {
41  return val_ == rhs.val_;
42  }
43 
44  private:
45  tuple_type val_;
46  };
47 
48  template <class T, int... Tags>
49  class Case;
50 
51  namespace detail {
52 
53  template <int... N>
54  struct Match;
55 
56  template <int Head, int... Tail>
57  struct Match<Head, Tail...>
58  {
59  static bool exec(int discriminator) {
60  return (Head == discriminator) ?
61  true : Match<Tail...>::exec(discriminator);
62  }
63  };
64 
65  template <int Last>
66  struct Match<Last>
67  {
68  static bool exec(int discriminator) {
69  return (Last == discriminator);
70  }
71  };
72 
73  template <>
74  struct Match<>
75  {
76  static bool exec(int discriminator) {
77  return (-1 == discriminator);
78  }
79  };
80 
81  template <class Case>
82  struct case_discriminator;
83 
84  template <class T, int Head, int... Tail>
85  struct case_discriminator<Case<T, Head, Tail...>>
86  {
87  // Take the first value out of many possible values
88  enum { value = Head };
89  };
90 
91  template <class T>
92  struct case_discriminator<Case<T>>
93  {
94  enum { value = -1 };
95  };
96 
97  } // namespace detail
98 
99  template <class T, int... Tags>
100  class Case
101  {
102  T val_;
103 
104  public:
105  typedef T * case_ptr_type;
106 
107  typedef T type;
108  enum { discriminator = detail::case_discriminator<Case>::value };
109 
110  static bool matches(int discriminator)
111  {
112  return detail::Match<Tags...>::exec(discriminator);
113  }
114 
115  Case() : val_() {}
116 
117  explicit Case(const T &t)
118  : val_(t)
119  {}
120 
121  Case(const Case &c)
122  : val_(c.val_)
123  {}
124 
125  Case & operator = (const Case & rhs) {
126  val_ = rhs.val_;
127  return *this;
128  }
129 
130  const T & get() const { return val_; }
131  T & get() { return val_; }
132 
133  friend bool operator == (const Case & lhs, const Case & rhs) {
134  return lhs.val_ == rhs.val_;
135  }
136  };
137 
138  template <class TagType, class... Cases>
139  struct Union
140  {
141  typedef void * Blank;
142  typedef TagType tag_type;
143  typedef std::tuple<Cases...> case_tuple_type;
144  typedef boost::variant<Blank, Cases...> variant_type;
145  typedef std::tuple<typename Cases::case_ptr_type...> caseptr_tuple_type;
146 
148  : var_(),
149  caseptr_tuple_(),
150  active_index_(-1)
151  {}
152 
153  Union(const Union & other)
154  : var_(other.var_),
155  caseptr_tuple_(other.caseptr_tuple_),
156  active_index_(other.active_index_)
157  {}
158 
159  Union & operator=(const Union & rhs)
160  {
161  Union(rhs).swap(*this);
162  return *this;
163  }
164 
165  Union(const variant_type &v)
166  : var_(v)
167  {}
168 
170  {
171  var_ = lhs;
172  return *this;
173  }
174 
175  template <typename CaseType, int... Tags>
177  : var_(c)
178  {}
179 
180  template <typename CaseType, int... Tags>
182  {
183  Union(rhs).swap(*this);
184  return *this;
185  }
186 
187  template <class Tag, class... C>
189  : var_(u)
190  {}
191 
192  template <typename Tag, class... C>
194  {
195  Union(rhs).swap(*this);
196  return *this;
197  }
198 
200  {
201  return var_;
202  }
203 
204  const variant_type & get_variant() const
205  {
206  return var_;
207  }
208 
209  void set_active_index(int i)
210  {
211  if (i == -1)
213  else {
214  active_index_ = i;
215  }
216  }
217 
219  {
220  active_index_ = -1;
221  }
222 
223  void set_caseptr_tuple_for_writing(const caseptr_tuple_type & caseptrs, int ai)
224  {
225  caseptr_tuple_ = caseptrs;
226  set_active_index(ai);
227  }
228 
230  {
231  caseptr_tuple_ = caseptrs;
232  }
233 
235  {
236  return caseptr_tuple_;
237  }
238 
240  {
241  return caseptr_tuple_;
242  }
243 
244  void swap(Union & other)
245  {
246  var_.swap(other.var_);
247  caseptr_tuple_.swap(other.caseptr_tuple_);
248  std::swap(active_index_, other.active_index_);
249  }
250 
251  int get_active_index() const
252  {
253  return active_index_;
254  }
255 
256  bool empty() const
257  {
258  return (active_index_ == -1) &&
259  (var_.which() == 0);
260  }
261 
262  const std::type_info & type() const
263  {
264  return var_.type();
265  }
266 
267  bool operator==(const Union &rhs) const
268  {
269  return var_ == rhs.var_;
270  }
271 
272  template<typename U>
273  bool operator==(const U &rhs) const
274  {
275  return var_ == rhs;
276  }
277 
278  bool operator<(const Union &rhs) const
279  {
280  return var_ < rhs.var_;
281  }
282 
283  template<typename U>
284  bool operator<(const U &rhs) const
285  {
286  return var_ < rhs;
287  }
288 
289  private:
290  variant_type var_;
291  caseptr_tuple_type caseptr_tuple_;
292  int active_index_;
293  };
294 
295  template <class... T>
296  std::tuple<T*...> make_caseptr_tuple(T&... args)
297  {
298  return make_tuple((&args)...);
299  }
300 
301  } // namespace match
302 } // namespace reflex
303 
304 #endif // RTIREFLEX_DISC_UNION_H
305 
void set_active_index(int i)
Definition: disc_union.h:209
Definition: disc_union.h:139
Definition: disc_union.h:27
std::tuple< boost::optional< T >...> tuple_type
Definition: disc_union.h:29
tuple_type & get_opt_tuple()
Definition: disc_union.h:36
Union & operator=(const variant_type &lhs)
Definition: disc_union.h:169
const caseptr_tuple_type & get_caseptr_tuple() const
Definition: disc_union.h:234
Union()
Definition: disc_union.h:147
const variant_type & get_variant() const
Definition: disc_union.h:204
friend bool operator==(const Case &lhs, const Case &rhs)
Definition: disc_union.h:133
const tuple_type & get_opt_tuple() const
Definition: disc_union.h:32
void set_caseptr_tuple_for_reading(const caseptr_tuple_type &caseptrs)
Definition: disc_union.h:229
bool operator==(const Union &rhs) const
Definition: disc_union.h:267
void swap(AutoDynamicData &lhs, AutoDynamicData &rhs)
Swap the contents of two AutoDynamicData instances. Never throws.
Definition: auto_dd.cxx:106
int get_active_index() const
Definition: disc_union.h:251
std::tuple< T...> raw_tuple_type
Definition: disc_union.h:30
Union(const variant_type &v)
Definition: disc_union.h:165
Union(const Case< CaseType, Tags...> &c)
Definition: disc_union.h:176
static bool matches(int discriminator)
Definition: disc_union.h:110
Case(const T &t)
Definition: disc_union.h:117
std::tuple< Cases...> case_tuple_type
Definition: disc_union.h:143
void swap(Union &other)
Definition: disc_union.h:244
void set_caseptr_tuple_for_writing(const caseptr_tuple_type &caseptrs, int ai)
Definition: disc_union.h:223
Case()
Definition: disc_union.h:115
bool operator==(const U &rhs) const
Definition: disc_union.h:273
variant_type & get_variant()
Definition: disc_union.h:199
std::tuple< T *...> make_caseptr_tuple(T &...args)
Definition: disc_union.h:296
Union & operator=(const Case< CaseType, Tags...> &rhs)
Definition: disc_union.h:181
Definition: disc_union.h:108
T type
Definition: disc_union.h:107
void * Blank
Definition: disc_union.h:141
Case & operator=(const Case &rhs)
Definition: disc_union.h:125
boost::variant< Blank, Cases...> variant_type
Definition: disc_union.h:144
bool empty() const
Definition: disc_union.h:256
std::tuple< typename Cases::case_ptr_type...> caseptr_tuple_type
Definition: disc_union.h:145
const std::type_info & type() const
Definition: disc_union.h:262
bool operator<(const Union &rhs) const
Definition: disc_union.h:278
Case(const Case &c)
Definition: disc_union.h:121
bool operator==(const Sparse &rhs) const
Definition: disc_union.h:40
Union(const Union &other)
Definition: disc_union.h:153
Union & operator=(const Union &rhs)
Definition: disc_union.h:159
Union(const Union< Tag, C...> &u)
Definition: disc_union.h:188
bool operator<(const U &rhs) const
Definition: disc_union.h:284
void reset_caseptr_tuple()
Definition: disc_union.h:218
TagType tag_type
Definition: disc_union.h:142
Union & operator=(const Union< Tag, C...> &rhs)
Definition: disc_union.h:193
Definition: disc_union.h:49
T * case_ptr_type
Definition: disc_union.h:105
caseptr_tuple_type & get_caseptr_tuple()
Definition: disc_union.h:239