Bond
 
Loading...
Searching...
No Matches
protocol.h
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#pragma once
5
6#include <bond/core/config.h>
7
8#include "customize.h"
9#include "detail/any.h"
10#include "detail/mpl.h"
11#include "detail/odr.h"
12#include "detail/visit_any.h"
13#include "traits.h"
14
15#include <bond/protocol/compact_binary.h>
16#include <bond/protocol/fast_binary.h>
17#include <bond/protocol/simple_binary.h>
18#include <bond/protocol/simple_json_reader.h>
19#include <bond/stream/input_buffer.h>
20
21#include <boost/make_shared.hpp>
22#include <boost/optional.hpp>
23#include <boost/ref.hpp>
24
25
26namespace bond
27{
28
29#ifdef BOND_COMPACT_BINARY_PROTOCOL
30template <typename Buffer> struct
31is_protocol_enabled<CompactBinaryReader<Buffer> >
32 : std::true_type {};
33#endif
34
35#ifdef BOND_SIMPLE_BINARY_PROTOCOL
36template <typename Buffer, typename MarshaledBondedProtocols> struct
37is_protocol_enabled<SimpleBinaryReader<Buffer, MarshaledBondedProtocols> >
38 : std::true_type {};
39#endif
40
41#ifdef BOND_SIMPLE_JSON_PROTOCOL
42template <typename Buffer> struct
43is_protocol_enabled<SimpleJsonReader<Buffer> >
44 : std::true_type {};
45#endif
46
47#ifdef BOND_FAST_BINARY_PROTOCOL
48template <typename Buffer> struct
49is_protocol_enabled<FastBinaryReader<Buffer> >
50 : std::true_type {};
51#endif
52
53// uses_dynamic_parser
54template <typename Reader, typename Enable = void> struct
55uses_dynamic_parser
56 : std::false_type {};
57
58template <typename Reader> struct
59uses_dynamic_parser<Reader, typename boost::enable_if<
60 std::is_same<typename Reader::Parser, DynamicParser<Reader&> > >::type>
61 : std::true_type {};
62
63template <typename Reader> struct
64uses_dynamic_parser<Reader&>
65 : uses_dynamic_parser<Reader> {};
66
67// uses_dom_parser
68template <typename Reader, typename Enable = void> struct
69uses_dom_parser
70 : std::false_type {};
71
72template <typename Reader> struct
73uses_dom_parser<Reader, typename boost::enable_if<
74 std::is_same<typename Reader::Parser, DOMParser<Reader&> > >::type>
75 : std::true_type {};
76
77template <typename Reader> struct
78uses_dom_parser<Reader&>
79 : uses_dom_parser<Reader> {};
80
81
82template <typename Reader, typename Unused> struct
83uses_marshaled_bonded
84 : uses_static_parser<Reader> {};
85
86
87template <typename... T>
88struct Protocols
89{
90private:
91 template <typename Buffer>
92 struct FilterBufferHelper;
93
94public:
95 using type = detail::mpl::list<T...>;
96
97 template <typename... U>
98 using Append = typename Protocols<detail::mpl::append_t<type, U...> >::type;
99
100 using FilterEnabled = typename Protocols<detail::mpl::filter_t<type, is_protocol_enabled> >::type;
101
102 template <typename Buffer>
103 using FilterBuffer = typename FilterBufferHelper<Buffer>::type;
104
105private:
106 template <typename Buffer>
107 struct FilterBufferHelper
108 {
109 template <typename U>
110 using check_buffer = std::is_same<typename std::remove_reference<typename U::Buffer>::type, Buffer>;
111
112 using type = typename Protocols<detail::mpl::filter_t<typename FilterEnabled::type, check_buffer> >::type;
113 };
114};
115
116
117template <typename... T>
118struct Protocols<detail::mpl::list<T...> >
119{
120 using type = Protocols<T...>;
121};
122
123
124// Deriving from Protocols<> instead of using an alias to avoid
125// binary size increase due to much longer type/function names on VC.
126struct BuiltInProtocols
127 : Protocols<
128 CompactBinaryReader<InputBuffer>,
129 SimpleBinaryReader<InputBuffer>,
130 FastBinaryReader<InputBuffer>,
131 SimpleJsonReader<InputBuffer> > {};
132
133
134struct ValueReader
135{
136 BOOST_STATIC_CONSTEXPR uint16_t magic = 0x5256 /*VR*/;
137 using Buffer = void;
138
139 ValueReader() BOND_NOEXCEPT
140 : pointer(NULL)
141 {}
142
143 template <typename U>
144 ValueReader(boost::reference_wrapper<U> value) BOND_NOEXCEPT
145 : pointer(&static_cast<const U&>(value))
146 {}
147
148 template <typename U>
149 ValueReader(const U& value)
150 : instance(boost::make_shared<U>(value)),
151 pointer(instance.get())
152 {}
153
154 template <typename U>
155 ValueReader(boost::shared_ptr<U> value) BOND_NOEXCEPT
156 : instance(boost::static_pointer_cast<const void>(value)),
157 pointer(instance.get())
158 {}
159
160 ValueReader(const ValueReader& value) BOND_NOEXCEPT
161 : instance(value.instance),
162 pointer(value.pointer)
163 {}
164
165 bool operator==(const ValueReader& rhs) const
166 {
167 return instance == rhs.instance
168 && pointer == rhs.pointer;
169 }
170
171 boost::shared_ptr<const void> instance;
172 const void* pointer;
173};
174
175
176BOND_DEFINE_BUFFER_MAGIC(ValueReader::Buffer, 0);
177
178
179namespace detail
180{
181#ifdef _MSC_VER
182#pragma warning(push)
183#pragma warning(disable: 4296) // C4296: '<' : expression is always false
184#endif // _MSC_VER
185
186 // Avoid std::max due to a bug in Visual C++ 2017.
187 template <std::size_t V0, std::size_t V1>
188 struct max_of
189 : std::integral_constant<std::size_t, (V0 < V1 ? V1 : V0)> {};
190
191#ifdef _MSC_VER
192#pragma warning(pop)
193#endif // _MSC_VER
194
195 template <typename List> struct
196 max_size;
197
198 template <> struct
199 max_size<detail::mpl::list<> >
200 : std::integral_constant<std::size_t, 0> {};
201
202 template <typename T, typename... U> struct
203 max_size<detail::mpl::list<T, U...> >
204 : max_of<sizeof(T), max_size<detail::mpl::list<U...> >::value> {};
205
206 using protocol_max_size = max_size<BuiltInProtocols::Append<ValueReader>::type>;
207
208} // namespace detail
209
210
211class ProtocolReader
212{
213public:
214 using Parser = void;
215 using Writer = void;
216
217 ProtocolReader(const ValueReader& reader = {})
218 : _value(reader)
219 {}
220
221 template <typename Reader, typename boost::enable_if<is_reader<Reader> >::type* = nullptr>
222 ProtocolReader(const Reader& reader)
223 : _value(reader)
224 {}
225
226 bool operator==(const ProtocolReader& rhs) const
227 {
228 return _value == rhs._value;
229 }
230
231#if !defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) && !defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
232 template <typename Protocols, typename Visitor>
233 auto Visit(Visitor&& visitor)
234#else
235 template <typename Protocols, typename Result, typename Visitor>
236 typename detail::visitor_result<Result>::type Visit(Visitor&& visitor)
237#endif
238 {
239 return detail::visit_any<typename Protocols::template Append<ValueReader>::type
240#if defined(BOND_NO_CXX14_RETURN_TYPE_DEDUCTION) || defined(BOND_NO_CXX14_GENERIC_LAMBDAS)
241 , Result
242#endif
243 >(std::forward<Visitor>(visitor), _value);
244 }
245
246private:
247 template <typename Reader> struct
248 reader_id
249 : std::integral_constant<uint32_t, Reader::magic | (buffer_magic<typename Reader::Buffer>::value << 16)> {};
250
251
252 detail::any<reader_id, detail::protocol_max_size::value> _value;
253};
254
255
256} // namespace bond
namespace bond
Definition: apply.h:17
boost::enable_if< is_signed_int_or_enum< SignedT >, bool >::type operator==(const Variant &variant, SignedT value)
Compares variant for equality against the provided signed integer or enum value.
Definition: metadata.h:24