CppWAMP
C++11 client library for the WAMP protocol
visitor.hpp
Go to the documentation of this file.
1 /*------------------------------------------------------------------------------
2  Copyright Butterfly Energy Systems 2014-2015, 2022.
3  Distributed under the Boost Software License, Version 1.0.
4  http://www.boost.org/LICENSE_1_0.txt
5 ------------------------------------------------------------------------------*/
6 
7 #ifndef CPPWAMP_VISITOR_HPP
8 #define CPPWAMP_VISITOR_HPP
9 
10 //------------------------------------------------------------------------------
14 //------------------------------------------------------------------------------
15 
16 #include <cassert>
17 #include <type_traits>
18 #include <utility>
19 #include "api.hpp"
20 
21 namespace wamp
22 {
23 
24 //------------------------------------------------------------------------------
27 //------------------------------------------------------------------------------
28 template <typename TResult = void>
29 class CPPWAMP_API Visitor
30 {
31 public:
33  using Result = TResult;
34 };
35 
38 
39 //------------------------------------------------------------------------------
41 //------------------------------------------------------------------------------
42 template <typename TVisitor>
43 using ResultTypeOf = typename std::remove_reference<TVisitor>::type::Result;
44 
45 //------------------------------------------------------------------------------
50 //------------------------------------------------------------------------------
51 template <typename V, typename T>
52 CPPWAMP_API ResultTypeOf<V> apply(V&& visitor, T&& variant);
53 
54 //------------------------------------------------------------------------------
60 //------------------------------------------------------------------------------
61 template <typename V, typename L, typename R>
62 CPPWAMP_API ResultTypeOf<V> apply(V&& visitor, L&& leftVariant,
63  R&& rightVariant);
64 
65 //------------------------------------------------------------------------------
72 //------------------------------------------------------------------------------
73 template <typename V, typename T, typename O>
74 CPPWAMP_API ResultTypeOf<V> applyWithOperand(V&& visitor, T&& variant,
75  O&& operand);
76 
78 
79 
80 //******************************************************************************
81 // Visitation implementations
82 //******************************************************************************
83 
84 //------------------------------------------------------------------------------
85 template <typename V, typename T>
86 ResultTypeOf<V> apply(V&& visitor, T&& variant)
87 {
88  using std::forward;
89  using I = decltype(variant.typeId());
90  switch (variant.typeId())
91  {
92  case I::null: return forward<V>(visitor)(variant.template as<I::null>());
93  case I::boolean: return forward<V>(visitor)(variant.template as<I::boolean>());
94  case I::integer: return forward<V>(visitor)(variant.template as<I::integer>());
95  case I::uint: return forward<V>(visitor)(variant.template as<I::uint>());
96  case I::real: return forward<V>(visitor)(variant.template as<I::real>());
97  case I::string: return forward<V>(visitor)(variant.template as<I::string>());
98  case I::blob: return forward<V>(visitor)(variant.template as<I::blob>());
99  case I::array: return forward<V>(visitor)(variant.template as<I::array>());
100  case I::object: return forward<V>(visitor)(variant.template as<I::object>());
101  default: assert(false);
102  }
103 
104  // Unreachable. Return null case to silence warning.
105  return visitor(variant.template as<I::null>());
106 }
107 
108 //------------------------------------------------------------------------------
109 template <typename V, typename L, typename R>
110 ResultTypeOf<V> apply(V&& v, L&& l, R&& r)
111 {
112  using std::forward;
113  using I = decltype(l.typeId());
114 
115  switch(r.typeId())
116  {
117  case I::null: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::null>());
118  case I::boolean: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::boolean>());
119  case I::integer: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::integer>());
120  case I::uint: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::uint>());
121  case I::real: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::real>());
122  case I::string: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::string>());
123  case I::blob: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::blob>());
124  case I::array: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::array>());
125  case I::object: return applyWithOperand(forward<V>(v), forward<L>(l), r.template as<I::object>());
126  default: assert(false);
127  }
128 
129  // Unreachable. Return null case to silence warning.
130  return applyWithOperand(forward<V>(v), forward<L>(l),
131  r.template as<I::null>());
132 }
133 
134 //------------------------------------------------------------------------------
135 template <typename V, typename T, typename O>
136 ResultTypeOf<V> applyWithOperand(V&& v, T&& l, O&& o)
137 {
138  using std::forward;
139  using I = decltype(l.typeId());
140 
141  switch(l.typeId())
142  {
143  case I::null: return forward<V>(v)(l.template as<I::null>(), forward<O>(o));
144  case I::boolean: return forward<V>(v)(l.template as<I::boolean>(), forward<O>(o));
145  case I::integer: return forward<V>(v)(l.template as<I::integer>(), forward<O>(o));
146  case I::uint: return forward<V>(v)(l.template as<I::uint>(), forward<O>(o));
147  case I::real: return forward<V>(v)(l.template as<I::real>(), forward<O>(o));
148  case I::string: return forward<V>(v)(l.template as<I::string>(), forward<O>(o));
149  case I::blob: return forward<V>(v)(l.template as<I::blob>(), forward<O>(o));
150  case I::array: return forward<V>(v)(l.template as<I::array>(), forward<O>(o));
151  case I::object: return forward<V>(v)(l.template as<I::object>(), forward<O>(o));
152  default: assert(false);
153  }
154 
155  // Unreachable. Return null case to silence warning.
156  return forward<V>(v)(l.template as<I::null>(), forward<O>(o));
157 }
158 
159 } // namespace wamp
160 
161 #endif // CPPWAMP_VISITOR_HPP
wamp::Visitor< Variant::SizeType >::Result
Variant::SizeType Result
The return type for all of the visitor's dispatch functions.
Definition: visitor.hpp:33
api.hpp
Defines macros related to exporting/importing APIs.
wamp::null
constexpr Null null
Constant Null object that can be assigned to, or compared with a Variant.
Definition: null.hpp:68
wamp::Visitor
Convenience base class used to meet the result type requirements of a StaticVisitor.
Definition: visitor.hpp:29
wamp
Definition: anyhandler.hpp:36
wamp::ResultTypeOf
typename std::remove_reference< TVisitor >::type::Result ResultTypeOf
Metafunction used to obtain the return type of a static visitor.
Definition: visitor.hpp:43