Pretty Good Sum Type  1.0.0
recursive_union.hpp
Go to the documentation of this file.
1 #if !defined (RECURSIVE_UNION_93F14ED0_E99B_4CF3_8A9B_EBE084D9079C_H)
2 # define RECURSIVE_UNION_93F14ED0_E99B_4CF3_8A9B_EBE084D9079C_H
3 
10 
11 # include <pgs/logical.hpp>
12 # include <pgs/recursive_wrapper.hpp>
13 # include <pgs/type_traits.hpp>
14 
15 # include <stdexcept>
16 # include <type_traits>
17 # include <iostream>
18 
19 namespace pgs {
20 
22  template <class> struct constructor {};
23 
25  template <class...> struct recursive_union {};
26 
28  template <class T> struct overload_tag {};
29 
33  template <bool is_recursive_wrapper, class T, class... Ts>
35 
38  static constexpr T& ref (recursive_union<T, Ts...>& u) {
39  return u.v;
40  }
43  static constexpr T const& ref (recursive_union<T, Ts...> const& u) {
44  return u.v;
45  }
48  static constexpr T* ptr (recursive_union<T, Ts...>& u) {
49  return std::addressof (u.v);
50  }
53  static constexpr T const* ptr (recursive_union<T, Ts...> const& u) {
54  return std::addressof (u.v);
55  }
56  };
57 
61  template <class T, class... Ts>
62  struct recursive_union_dereference<true, T, Ts...> {
63 
66  static auto ref (recursive_union<T, Ts...>& u)
67  -> decltype (u.v.get ()) {
68  return u.v.get ();
69  }
72  static auto ref (recursive_union<T, Ts...> const& u)
73  -> decltype (u.v.get ()) {
74  return u.v.get ();
75  }
78  static constexpr auto ptr (recursive_union<T, Ts...>& u)
79  -> decltype (u.v.get_pointer ()) {
80  return u.v.get_pointer ();
81  }
84  static constexpr auto ptr (recursive_union<T, Ts...> const& u)
85  -> decltype (u.v.get_pointer ()) {
86  return u.v.get_pointer ();
87  }
88  };
89 
92  template<std::size_t I, class T, class... Ts>
94 
96  static constexpr auto ref (recursive_union<T, Ts...>& u)
98  {
100  }
102  static constexpr auto ref (recursive_union<T, Ts...> const& u)
104  {
106  }
108  static constexpr auto ptr (recursive_union<T, Ts...>& u)
109  -> decltype (recursive_union_indexer<I - 1, Ts...>::ptr (u.r)) {
111  }
113  static constexpr auto ptr (recursive_union<T, Ts...> const& u)
114  -> decltype (recursive_union_indexer<I - 1, Ts...>::ptr (u.r)) {
116  }
117  };
118 
121  template <class T, class... Ts>
122  struct recursive_union_indexer<0, T, Ts...> {
125  static constexpr auto ref (recursive_union<T, Ts...>& u)
126  -> decltype (recursive_union_dereference<is_recursive_wrapper<T>::value, T, Ts...>::ref (u)) {
128  }
131  static constexpr auto ref (recursive_union<T, Ts...> const& u)
132  -> decltype (recursive_union_dereference<is_recursive_wrapper<T>::value, T, Ts...>::ref (u)) {
134  }
137  static constexpr auto ptr (recursive_union<T, Ts...>& u)
138  -> decltype ((recursive_union_dereference<is_recursive_wrapper<T>::value, T, Ts...>::ptr (u))) {
140  }
143  static constexpr auto ptr (recursive_union<T, Ts...> const& u)
144  -> decltype (recursive_union_dereference<is_recursive_wrapper<T>::value, T, Ts...>::ptr (u)) {
146  }
147  };
148 
161  template <class R, class T, class... Ts>
163 
164  using result_type = R;
165 
167  template <
168  class O, class F, class... Fs,
169  class = pgs::enable_if_t<is_callable<F, T>::value, void>
170  >
171  static result_type visit (overload_tag<O>, T const& t, F&& f, Fs&&...) {
172  return std::forward<F>(f)(t);
173  }
176  template <
177  class F, class O, class... Fs,
178  class = pgs::enable_if_t<!is_callable<F, T>::value, void>
179  >
180  static result_type visit (overload_tag<O> o, T const& t, F&&, Fs&&... fs) {
181  return recursive_union_visitor::visit (o, t, std::forward<Fs>(fs)...);
182  }
184  template <
185  class O, class F, class... Fs,
186  class = pgs::enable_if_t<is_callable<F, T>::value, void>
187  >
188  static result_type visit (overload_tag<O>, T& t, F&& f, Fs&&...) {
189  return std::forward<F>(f)(t);
190  }
192  template <
193  class F, class O, class... Fs,
194  class = pgs::enable_if_t<!is_callable<F, T>::value, void>
195  >
196  static result_type visit (overload_tag<O> o, T& t, F&&, Fs&&...fs) {
197  return recursive_union_visitor::visit (o, t, std::forward<Fs>(fs)...);
198  }
199  };
200 
209  template <class T, class... Ts>
210  struct recursive_union_visitor<void, T, Ts...> {
211 
212  using result_type = void;
213 
215  template <
216  class O, class F, class... Fs,
217  class = pgs::enable_if_t<is_callable<F, T>::value, void>
218  >
219  static result_type visit (overload_tag<O>, T const& t, F&& f, Fs&&...) {
220  std::forward<F>(f)(t);
221  }
224  template <
225  class F, class O, class... Fs,
226  class = pgs::enable_if_t<!is_callable<F, T>::value, void>
227  >
228  static result_type visit (overload_tag<O> o, T const& t, F&&, Fs&&... fs) {
229  recursive_union_visitor::visit (o, t, std::forward<Fs>(fs)...);
230  }
232  template <
233  class O, class F, class... Fs,
234  class = pgs::enable_if_t<is_callable<F, T>::value, void>
235  >
236  static result_type visit (overload_tag<O>, T& t, F&& f, Fs&&...) {
237  std::forward<F>(f)(t);
238  }
240  template <
241  class F, class O, class... Fs,
242  class = pgs::enable_if_t<!is_callable<F, T>::value, void>
243  >
244  static result_type visit (overload_tag<O> o, T& t, F&&, Fs&&...fs) {
245  recursive_union_visitor::visit (o, t, std::forward<Fs>(fs)...);
246  }
247  };
248 
256  : std::logic_error {what}
257  {}
261  {}
263  explicit invalid_sum_type_access (char const* what)
264  : std::logic_error {what}
265  {}
266  };
267 
271  template <std::size_t...> struct range {};
272 
274  namespace detail {
275  template <std::size_t Z, std::size_t N, std::size_t... Ns>
276  struct mk_range : mk_range <Z, N - 1, N, Ns...>
277  {};
278 
279  template <std::size_t Z, std::size_t... Ns>
280  struct mk_range<Z, Z, Ns...> {
281  using type = range<Z, Ns...>;
282  };
283  }//namespace detail
285 
287  template <std::size_t Z, std::size_t N>
288  using range_t = typename detail::mk_range<Z, N>::type;
289 
296  template <class R, class... Ts>
297  struct recursive_union_visitor<R, range<>, Ts...> {
298 
299  using result_type = R;
300 
305  template <class... Fs>
307  recursive_union<Ts...> const&, std::size_t, Fs&&...) {
308  throw invalid_sum_type_access{""};
309  }
310 
315  template <class... Fs>
317  throw invalid_sum_type_access{""};
318  }
319  };
320 
329  template <class... Ts>
330  struct recursive_union_visitor<void, range<>, Ts...> {
331 
332  using result_type = void;
333 
338  template <class... Fs>
340  recursive_union<Ts...> const&, std::size_t, Fs&&...) {
341  throw invalid_sum_type_access{""};
342  }
343 
348  template <class... Fs>
350  recursive_union<Ts...>&, std::size_t, Fs&&...) {
351  throw invalid_sum_type_access{""};
352  }
353  };
354 
372  template <class R, std::size_t I, std::size_t... Is, class T, class... Ts>
373  struct recursive_union_visitor<R, range<I, Is...>, T, Ts...> {
374 
375  using type = T;
376  using result_type = R;
377 
379  template <class... Fs>
381  recursive_union<type, Ts...> const& u, std::size_t i, Fs&&... fs) {
382  if (i == I) {
383  //'u' is not a reference (no call 'get ()')
384  overload_tag<type> o{};
386  o, u.v, std::forward<Fs>(fs)...);
387  }
388  else {
389  return recursive_union_visitor<result_type, range<Is...>, Ts...>::visit(
390  u.r, i, std::forward<Fs>(fs)...);
391  }
392  }
393 
395  template <class... Fs>
397  recursive_union<T, Ts...>& u, std::size_t i, Fs&&... fs) {
398  if (i == I) {
399  //'u' is not a reference (no call 'get ()')
400  overload_tag<T> o{};
402  o, u.v, std::forward<Fs>(fs)...);
403  }
404  else {
405  return recursive_union_visitor<result_type, range<Is...>, Ts...>::visit(
406  u.r, i, std::forward<Fs>(fs)...);
407  }
408  }
409  };
410 
429  template <class R, std::size_t I, std::size_t... Is, class T, class... Ts>
430  struct recursive_union_visitor<R, range<I, Is...>, recursive_wrapper<T>, Ts...> {
431 
432  using type = T;
434  using result_type = R;
435 
437  template <class... Fs>
439  recursive_union<U, Ts...> const& u, std::size_t i, Fs&&... fs) {
440  if (i == I) {
441  //'u' is of type recursive_wrapper<type>, call 'get ()'
442  overload_tag<type> o{};
444  o, u.v.get (), std::forward<Fs>(fs)...);
445  }
446  else {
447  return recursive_union_visitor<result_type, range<Is...>, Ts...>::visit(
448  u.r, i, std::forward<Fs>(fs)...);
449  }
450  }
451 
453  template <class... Fs>
455  recursive_union<U, Ts...>& u, std::size_t i, Fs&&... fs) {
456  if (i == I) {
457  //'u' is of type recursive_wrapper<type>, call 'get ()'
458  overload_tag<type> o{};
460  o, u.v.get (), std::forward<Fs>(fs)...);
461  }
462  else {
463  return recursive_union_visitor<result_type, range<Is...>, Ts...>::visit(
464  u.r, i, std::forward<Fs>(fs)...);
465  }
466  }
467  };
468 
486  template <std::size_t I, std::size_t... Is, class T, class... Ts>
487  struct recursive_union_visitor<void, range<I, Is...>, T, Ts...> {
488 
489  using type = T;
490  using result_type = void;
491 
493  template <class... Fs>
494  static result_type
496  recursive_union<type, Ts...> const& u, std::size_t i, Fs&&... fs) {
497  if (i == I) {
498  //'u' is not a wrapper (no call 'get ()')
499  overload_tag<type> o{};
501  o, u.v, std::forward<Fs>(fs)...);
502  }
503  else {
505  u.r, i, std::forward<Fs>(fs)...);
506  }
507  }
508 
510  template <class... Fs>
511  static result_type
513  recursive_union<T, Ts...>& u, std::size_t i, Fs&&... fs) {
514  if (i == I) {
515  //'u' is not a wrapper (no call 'get ()')
516  overload_tag<type> o{};
518  o, u.v, std::forward<Fs>(fs)...);
519  }
520  else {
522  u.r, i, std::forward<Fs>(fs)...);
523  }
524  }
525 
526  };
527 
545  template <std::size_t I, std::size_t... Is, class T, class... Ts>
547  void, range<I, Is...>, recursive_wrapper<T>, Ts...> {
548 
549  //U='recursive_wrapper<T>', 'Ts', return type 'void'
550 
551  using type = T;
553  using result_type = void;
554 
556  template <class... Fs>
558  recursive_union<U, Ts...> const& u, std::size_t i, Fs&&... fs) {
559  if (i == I) {
560  //'u' is a reference (call 'get ()')
561  overload_tag<type> o{};
563  o, u.v.get (), std::forward<Fs>(fs)...);
564  }
565  else {
566  recursive_union_visitor<void, range<Is...>, Ts...>::visit (
567  u.r, i, std::forward<Fs>(fs)...);
568  }
569  }
570 
572  template <class... Fs>
574  recursive_union<U, Ts...>& u, std::size_t i, Fs&&... fs) {
575  if (i == I) {
576  //'u' is a reference (call 'get ()')
577  overload_tag<type> o{};
579  o, u.v.get (), std::forward<Fs>(fs)...);
580  }
581  else {
582  recursive_union_visitor<void, range<Is...>, Ts...>::visit(
583  u.r, i, std::forward<Fs>(fs)...);
584  }
585  }
586  };
587 
592  template <>
593  struct recursive_union<> {
595  void copy (std::size_t, recursive_union const&) {}
601  bool compare (std::size_t, recursive_union const&) const { return false; }
602  };
603 
604  # if defined(_MSC_VER)
605  # pragma warning(push)
606  # pragma warning(disable:4624)
607  # endif//defined (_MSC_VER)
608 
613  template <class T, class... Ts>
614  struct recursive_union<T, Ts...> {
615 
618  {}
619 
623  template <class... Args>
624  explicit recursive_union (constructor<T>, Args&&... args)
625  : v (std::forward<Args>(args)...)
626  {}
627 
632  template <class U, class... Args,
633  pgs::enable_if_t<
635  >
636  explicit recursive_union (constructor<U>, Args&&... args)
637  noexcept (std::is_nothrow_constructible<U, Args...>::value)
638  : v (std::forward<Args>(args)...)
639  {}
640 
645  template <class U, class... Args,
646  pgs::enable_if_t<
647  and_<
650  >
651  explicit recursive_union (constructor<U> t, Args&&... args)
652  noexcept(
653  std::is_nothrow_constructible<Ts..., constructor<U>, Args...>::value
654  )
655  : r (t, std::forward<Args>(args)...)
656  {}
657 
660  {}
661 
670  void copy (std::size_t i, recursive_union const& u)
671  noexcept(
673  && noexcept (std::declval<recursive_union>().r.copy (i - 1, u.r))
674  ) {
675  //std::cout << "recursive_union.copy ()\n";
676  if (i == 0) {
677  new (std::addressof (v)) T (u.v);
678  }
679  else {
680  r.copy (i - 1, u.r);
681  }
682  }
683 
693  noexcept (
694  std::is_nothrow_move_constructible<T>::value
695  && noexcept (std::declval<recursive_union>().r.move (
696  i - 1, std::move (u.r)))
697  ) {
698  //std::cout << "recursive_union.move ()\n";
699  if (i == 0) {
700  new (std::addressof (v)) T (std::move (u.v));
701  }
702  else {
703  r.move (i - 1, std::move (u.r));
704  }
705  }
706 
715  && noexcept (std::declval<recursive_union>().r.destruct (i - 1))) {
716  if (i == 0) {
717  v.~T ();
718  }
719  else {
720  r.destruct (i - 1);
721  }
722  }
723 
732  bool compare (size_t i, recursive_union const& rhs) const
733  noexcept {
734  return i == 0 ? v == rhs.v : r.compare (i - 1, rhs.r);
735  }
736 
741  union {
742  T v;
744  };
745  };
746 
747 # if defined(_MSC_VER)
748 # pragma warning(pop)
749 # endif//defined (_MSC_VER)
750 
751 }//namespace pgs
752 
753 #endif
static constexpr T const * ptr(recursive_union< T, Ts... > const &u)
Produce a const pointer to the value field of the provided union.
Definition: recursive_union.hpp:53
Primary template of a metafunction to classify a type as recursive_wrapper<> or not.
Definition: recursive_wrapper.hpp:29
invalid_sum_type_access(char const *what)
Construct from char const*
Definition: recursive_union.hpp:263
Parameter pack conjunction.
Definition: logical.hpp:83
recursive_union< Ts... > r
... recursive union
Definition: recursive_union.hpp:743
static result_type visit(recursive_union< T, Ts... > &u, std::size_t i, Fs &&...fs)
non-const overload (recursive_union&)
Definition: recursive_union.hpp:396
R result_type
The type returned by visit
Definition: recursive_union.hpp:434
static result_type visit(overload_tag< O >, T &t, F &&f, Fs &&...)
f is callable on t (of type T&)
Definition: recursive_union.hpp:236
static result_type visit(recursive_union< type, Ts... > const &u, std::size_t i, Fs &&...fs)
'const' overload ('recursive_union const& u')
Definition: recursive_union.hpp:495
void result_type
The type returned by visit
Definition: recursive_union.hpp:553
static constexpr auto ref(recursive_union< T, Ts... > const &u) -> decltype(recursive_union_indexer< I-1, Ts... >::ref(u.r))
Decrement I, strip off T and recurse.
Definition: recursive_union.hpp:102
static constexpr auto ptr(recursive_union< T, Ts... > &u) -> decltype(u.v.get_pointer())
Produce a non-const pointer to the object referred to by the value field of the provided union...
Definition: recursive_union.hpp:78
static result_type visit(recursive_union< U, Ts... > &u, std::size_t i, Fs &&...fs)
non-const overload (recursive_union&)
Definition: recursive_union.hpp:454
recursive_union(constructor< U >, Args &&...args) noexcept(std::is_nothrow_constructible< U, Args... >::value)
Construct (a recursive_wrapper) into v
Definition: recursive_union.hpp:636
void copy(std::size_t i, recursive_union const &u) noexcept( std::is_nothrow_copy_constructible< T >::value &&noexcept(std::declval< recursive_union >().r.copy(i-1, u.r)) )
Copy.
Definition: recursive_union.hpp:670
Primary template.
Definition: recursive_union.hpp:162
Definition: logical.hpp:13
static constexpr auto ptr(recursive_union< T, Ts... > const &u) -> decltype(recursive_union_dereference< is_recursive_wrapper< T >::value, T, Ts... >::ptr(u))
Dereference the value field to produce a const pointer.
Definition: recursive_union.hpp:143
invalid_sum_type_access(std::string const &what)
Construct from std::string const&
Definition: recursive_union.hpp:255
The purpose of this type is to walk a recursive_union<> and return the value field of the Ith union i...
Definition: recursive_union.hpp:93
~recursive_union()
Dtor.
Definition: recursive_union.hpp:659
recursive_union(constructor< U > t, Args &&...args) noexcept( std::is_nothrow_constructible< Ts..., constructor< U >, Args... >::value )
Construct into r
Definition: recursive_union.hpp:651
static result_type visit(overload_tag< O >, T const &t, F &&f, Fs &&...)
f is callable on t (of type T const&)
Definition: recursive_union.hpp:171
static result_type visit(overload_tag< O > o, T &t, F &&, Fs &&...fs)
f is not callable on t (of type T&)
Definition: recursive_union.hpp:196
static result_type visit(recursive_union< Ts... > const &, std::size_t, Fs &&...)
This definition applies when Ts... is empty.
Definition: recursive_union.hpp:339
R result_type
The return type of visit
Definition: recursive_union.hpp:164
static constexpr T * ptr(recursive_union< T, Ts... > &u)
Produce a non-const pointer to the value field of the provided union.
Definition: recursive_union.hpp:48
Dereference the value field in a recursive_union<>. This case handles values that are not recursive_w...
Definition: recursive_union.hpp:34
Partial specialization.
Definition: recursive_union.hpp:614
static result_type visit(recursive_union< Ts... > &, std::size_t, Fs &&...)
This definition applies when Ts... is empty.
Definition: recursive_union.hpp:316
recursive_union()
Default ctor.
Definition: recursive_union.hpp:617
R result_type
The return type of visit
Definition: recursive_union.hpp:299
Definition: type_traits.hpp:26
Conjunctions and disjunctions over predicate packs.
bool compare(size_t i, recursive_union const &rhs) const noexcept
Equality comparison.
Definition: recursive_union.hpp:732
void move(std::size_t i, recursive_union &&u) noexcept( std::is_nothrow_move_constructible< T >::value &&noexcept(std::declval< recursive_union >().r.move( i-1, std::move(u.r))) )
Move.
Definition: recursive_union.hpp:692
void destruct(std::size_t i) noexcept(std::is_nothrow_destructible< T >::value &&noexcept(std::declval< recursive_union >().r.destruct(i-1)))
Destruct.
Definition: recursive_union.hpp:713
static result_type visit(recursive_union< U, Ts... > const &u, std::size_t i, Fs &&...fs)
const overload (recursive_union const&)
Definition: recursive_union.hpp:557
void move(std::size_t, recursive_union &&)
move is a no-op
Definition: recursive_union.hpp:597
static constexpr auto ptr(recursive_union< T, Ts... > &u) -> decltype(recursive_union_indexer< I-1, Ts... >::ptr(u.r))
Decrement I, strip off T and recurse.
Definition: recursive_union.hpp:108
T what(T...args)
invalid_sum_type_access(std::string &&what)
Construct from std::string&&
Definition: recursive_union.hpp:259
A type to model an overload.
Definition: recursive_union.hpp:28
static result_type visit(overload_tag< O > o, T const &t, F &&, Fs &&...fs)
f is not callable on t (of type T const&), recurse
Definition: recursive_union.hpp:228
T type
The type held by the value.
Definition: recursive_union.hpp:432
bool compare(std::size_t, recursive_union const &) const
compare returns false
Definition: recursive_union.hpp:601
static auto ref(recursive_union< T, Ts... > &u) -> decltype(u.v.get())
Produce a non-const reference to the object referred to by the value field of the provided union...
Definition: recursive_union.hpp:66
T v
Value or...
Definition: recursive_union.hpp:742
R result_type
The return type of visit
Definition: recursive_union.hpp:376
T addressof(T...args)
static result_type visit(overload_tag< O > o, T &t, F &&, Fs &&...fs)
f is not callable on t (of type T&)
Definition: recursive_union.hpp:244
static constexpr auto ptr(recursive_union< T, Ts... > const &u) -> decltype(u.v.get_pointer())
Produce a const pointer to the object referred to by the value field of the provided union...
Definition: recursive_union.hpp:84
void result_type
The return type of visit
Definition: recursive_union.hpp:332
void result_type
return type of visit
Definition: recursive_union.hpp:212
static result_type visit(recursive_union< Ts... > &, std::size_t, Fs &&...)
This definition applies when Ts... is empty.
Definition: recursive_union.hpp:349
static result_type visit(recursive_union< type, Ts... > const &u, std::size_t i, Fs &&...fs)
const overload (recursive_union const&)
Definition: recursive_union.hpp:380
T type
The type of the value.
Definition: recursive_union.hpp:375
static constexpr auto ptr(recursive_union< T, Ts... > &u) -> decltype((recursive_union_dereference< is_recursive_wrapper< T >::value, T, Ts... >::ptr(u)))
Dereference the value field to produce a non-const pointer.
Definition: recursive_union.hpp:137
T move(T...args)
A workaround for the absence of recursive types.
static constexpr auto ref(recursive_union< T, Ts... > const &u) -> decltype(recursive_union_dereference< is_recursive_wrapper< T >::value, T, Ts... >::ref(u))
Dereference the value field to produce a const reference.
Definition: recursive_union.hpp:131
T type
The type held by the value.
Definition: recursive_union.hpp:551
Compile time sequence of integers.
Definition: recursive_union.hpp:271
Exception type raised on an invalid access into a recursive_union<>
Definition: recursive_union.hpp:253
A type to model a sum constructor.
Definition: recursive_union.hpp:22
At this time contains only a metafunction for determining if a given type F is "callable" on a parame...
types
Definition: recursive_wrapper.hpp:82
static result_type visit(recursive_union< T, Ts... > &u, std::size_t i, Fs &&...fs)
'non-const' overload ('recursive_union& u')
Definition: recursive_union.hpp:512
static result_type visit(recursive_union< U, Ts... > &u, std::size_t i, Fs &&...fs)
non-const overload (recursive_union&)
Definition: recursive_union.hpp:573
recursive union<> primary template
Definition: recursive_union.hpp:25
void result_type
The return type of visit
Definition: recursive_union.hpp:490
static result_type visit(overload_tag< O >, T &t, F &&f, Fs &&...)
f is callable on t (of type T&)
Definition: recursive_union.hpp:188
T type
The type of the value.
Definition: recursive_union.hpp:489
static auto ref(recursive_union< T, Ts... > const &u) -> decltype(u.v.get())
Produce a const reference to the object referred to by the value field of the provided union...
Definition: recursive_union.hpp:72
recursive_union(constructor< T >, Args &&...args)
Construct a T into v
Definition: recursive_union.hpp:624
static result_type visit(overload_tag< O >, T const &t, F &&f, Fs &&...)
f is callable on t (of type T const&)
Definition: recursive_union.hpp:219
static constexpr auto ref(recursive_union< T, Ts... > &u) -> decltype(recursive_union_dereference< is_recursive_wrapper< T >::value, T, Ts... >::ref(u))
Dereference the value field to produce a non-const reference.
Definition: recursive_union.hpp:125
static result_type visit(overload_tag< O > o, T const &t, F &&, Fs &&...fs)
f is not callable on t (of type T const&), recurse
Definition: recursive_union.hpp:180
static constexpr auto ref(recursive_union< T, Ts... > &u) -> decltype(recursive_union_indexer< I-1, Ts... >::ref(u.r))
Decrement I, strip off T and recurse.
Definition: recursive_union.hpp:96
static constexpr T const & ref(recursive_union< T, Ts... > const &u)
Produce a const reference to the value field of the provided union.
Definition: recursive_union.hpp:43
static result_type visit(recursive_union< Ts... > const &, std::size_t, Fs &&...)
This definition applies when Ts... is empty.
Definition: recursive_union.hpp:306
void copy(std::size_t, recursive_union const &)
copy is a no-op
Definition: recursive_union.hpp:595
void destruct(std::size_t)
destruct is a no-op
Definition: recursive_union.hpp:599
static constexpr T & ref(recursive_union< T, Ts... > &u)
Produce a non-const reference to the value field of the provided union.
Definition: recursive_union.hpp:38
static constexpr auto ptr(recursive_union< T, Ts... > const &u) -> decltype(recursive_union_indexer< I-1, Ts... >::ptr(u.r))
Decrement I, strip off T and recurse.
Definition: recursive_union.hpp:113
static result_type visit(recursive_union< U, Ts... > const &u, std::size_t i, Fs &&...fs)
const overload (recursive_union const&)
Definition: recursive_union.hpp:438