framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
protocol_buffers.hpp
Go to the documentation of this file.
1 // Copyright (C) 2013 iwg molw5
2 // For conditions of distribution and use, see copyright notice in COPYING
3 
13 #pragma once
14 
15 #include <bitset>
16 #include <atomic>
17 
27 
28 namespace framework
29 {
30  namespace protocol_buffers
31  {
35  template <typename... Types>
36  class message :
37  public serializable::custom_serializable <message <Types...>, Types...>,
38  public serializable::comparable <message <Types...>>,
39  public wire_type_base <e_wire_type::length_delimited>
40  {
41  private:
42  DEFINE_BASE_TEMPLATE(message <Types...>);
43  using serializable_base = serializable::custom_serializable <message <Types...>, Types...>;
44 
45  public:
46  message () = default;
47  message (message const&) = default;
48  message (message&&) = default;
49  message& operator= (message const&) = default;
50  message& operator= (message&&) = default;
51 
55  template <typename... Args>
56  message (Args&&... args)
57  : serializable_base(std::forward <Args> (args)...)
58  {
59  }
60 
64  message (std::tuple <>)
65  : message ()
66  {
67  }
68 
72  template <typename... Args>
73  message (std::tuple <Args...>&& args)
74  : message (
75  std::forward <std::tuple <Args...>> (args),
76  static_cast <make_indices <sizeof... (Args)>*> (nullptr))
77  {
78  }
79 
80  private:
81  template <typename... Args, typename... Indices>
82  message (std::tuple <Args...> args, pack_container <Indices...>*)
83  : serializable_base(std::forward <Args> (std::get <Indices::value> (args))...)
84  {
85  }
86 
87  public:
91  template <typename Name, typename... Args>
92  auto get (Args&&... args) const ->
93  decltype(std::declval <base <Name>> ().get(std::forward <Args> (args)...))
94  {
95  return base <Name>::get(std::forward <Args> (args)...);
96  }
97 
101  template <typename Name, typename... Args>
102  auto set (Args&&... args) ->
103  decltype(std::declval <base <Name>> ().set(std::forward <Args> (args)...))
104  {
105  return base <Name>::set(std::forward <Args> (args)...);
106  }
107 
111  template <typename Name, typename... Args>
112  auto check (Args&&... args) const ->
113  decltype(std::declval <base <Name>> ().check(std::forward <Args> (args)...))
114  {
115  return base <Name>::check(std::forward <Args> (args)...);
116  }
117 
121  template <typename Name, typename... Args>
122  auto clear (Args&&... args) ->
123  decltype(std::declval <base <Name>> ().clear(std::forward <Args> (args)...))
124  {
125  return base <Name>::clear(std::forward <Args> (args)...);
126  }
127 
131  template <typename Name, typename... Args>
132  auto mutate (Args&&... args) ->
133  decltype(std::declval <base <Name>> ().mutate(std::forward <Args> (args)...))
134  {
135  return base <Name>::mutate(std::forward <Args> (args)...);
136  }
137  };
138 
142  template <typename... Types>
143  class group :
144  public serializable::custom_serializable <group <Types...>, Types...>,
145  public serializable::comparable <group <Types...>>,
146  public wire_type_base <e_wire_type::start_group>
147  {
148  private:
149  DEFINE_BASE_TEMPLATE(group <Types...>);
150  using serializable_base = serializable::custom_serializable <group <Types...>, Types...>;
151 
152  public:
153  group () = default;
154  group (group const&) = default;
155  group (group&&) = default;
156  group& operator= (group const&) = default;
157  group& operator= (group&&) = default;
158 
162  template <typename... Args>
163  group (Args&&... args)
164  : serializable_base(std::forward <Args> (args)...)
165  {
166  }
167 
171  group (std::tuple <>)
172  : group ()
173  {
174  }
175 
179  template <typename... Args>
180  group (std::tuple <Args...>&& args)
181  : group (
182  std::forward <std::tuple <Args...>> (args),
183  static_cast <make_indices <sizeof... (Args)>*> (nullptr))
184  {
185  }
186 
187  private:
188  template <typename... Args, typename... Indices>
189  group (std::tuple <Args...> args, pack_container <Indices...>*)
190  : serializable_base(std::forward <Args> (std::get <Indices::value> (args))...)
191  {
192  }
193 
194  public:
198  template <typename Name, typename... Args>
199  auto get (Args&&... args) const ->
200  decltype(std::declval <base <Name>> ().get(std::forward <Args> (args)...))
201  {
202  return base <Name>::get(std::forward <Args> (args)...);
203  }
204 
208  template <typename Name, typename... Args>
209  auto set (Args&&... args) ->
210  decltype(std::declval <base <Name>> ().set(std::forward <Args> (args)...))
211  {
212  return base <Name>::set(std::forward <Args> (args)...);
213  }
214 
218  template <typename Name, typename... Args>
219  auto check (Args&&... args) const ->
220  decltype(std::declval <base <Name>> ().check(std::forward <Args> (args)...))
221  {
222  return base <Name>::check(std::forward <Args> (args)...);
223  }
224 
228  template <typename Name, typename... Args>
229  auto clear (Args&&... args) ->
230  decltype(std::declval <base <Name>> ().clear(std::forward <Args> (args)...))
231  {
232  return base <Name>::clear(std::forward <Args> (args)...);
233  }
234 
238  template <typename Name, typename... Args>
239  auto mutate (Args&&... args) ->
240  decltype(std::declval <base <Name>> ().mutate(std::forward <Args> (args)...))
241  {
242  return base <Name>::mutate(std::forward <Args> (args)...);
243  }
244  };
245 
256  template <typename SizeFrame, typename Input, typename Output>
257  bool write_to_string (Input&& in, Output&& out)
258  {
259  using type = typename std::remove_cv <typename std::remove_reference <Input>::type>::type;
260 
261  SizeFrame size;
262  if (FRAMEWORK_EXPECT_FALSE(!serializable::write(in, size)))
263  return false;
264 
265  out.resize(static_cast <std::size_t> (size));
266  auto const begin = &out[0];
267  auto const end = &out[out.size()];
268  auto it = begin;
269  if (FRAMEWORK_EXPECT_FALSE(!serializable::dispatch_write <type> (in, begin, end, it)))
270  return false;
271 
272  out.resize(static_cast <std::size_t> (it - begin));
273  return true;
274  }
275 
286  template <typename SizeFrame, typename Input, typename Output>
287  bool write_to_frame (Input&& in, Output&& out)
288  {
289  SizeFrame size;
290  if (FRAMEWORK_EXPECT_FALSE(!serializable::write(in, size)))
291  return false;
292 
293  std::size_t serialized_size;
294  out.resize(static_cast <std::size_t> (size));
295 
296  // Destroy the frame before invalidating the iterators
297  {
298 #ifdef NDEBUG
299  raw_output_frame <false> frame {&out[0], &out[out.size()]};
300 #else
301  raw_output_frame <true> frame {&out[0], &out[out.size()]};
302 #endif
303  auto const begin = frame.tellp();
304  if (FRAMEWORK_EXPECT_FALSE(!serializable::write(in, frame)))
305  return false;
306  auto const end = frame.tellp();
307  serialized_size = static_cast <std::size_t> (end - begin);
308  }
309 
310  out.resize(serialized_size);
311  return true;
312  }
313 
325  template <typename Input, typename Output>
326  bool write_to_string_fast (Input&& in, Output&& out)
327  {
328  return write_to_string <max_size_frame> (std::forward <Input> (in), std::forward <Output> (out));
329  }
330 
342  template <typename Input, typename Output>
343  bool write_to_string_tight (Input&& in, Output&& out)
344  {
345  return write_to_string <size_frame> (std::forward <Input> (in), std::forward <Output> (out));
346  }
347 
361  template <typename Input, typename Output>
362  bool write_to_frame_fast (Input&& in, Output&& out)
363  {
364  return write_to_frame <max_size_frame> (std::forward <Input> (in), std::forward <Output> (out));
365  }
366 
380  template <typename Input, typename Output>
381  bool write_to_frame_tight (Input&& in, Output&& out)
382  {
383  return write_to_frame <size_frame> (std::forward <Input> (in), std::forward <Output> (out));
384  }
385 
396  template <typename Input>
397  bool write_to_array (Input&& in, char* s, std::size_t& n)
398  {
399  using type = typename std::remove_cv <typename std::remove_reference <Input>::type>::type;
400 
401  max_size_frame max_size;
402  if (FRAMEWORK_EXPECT_FALSE(!write(in, max_size)))
403  return false;
404  if (FRAMEWORK_EXPECT_FALSE(static_cast <std::size_t> (max_size) > n))
405  {
406  size_frame size;
407  if (FRAMEWORK_EXPECT_FALSE(!write(in, size)))
408  return false;
409  if (FRAMEWORK_EXPECT_FALSE(static_cast <std::size_t> (size) > n))
410  return false;
411  }
412 
413  char* const begin = &s[0];
414  char* const end = &s[n];
415  char* it = begin;
416  if (FRAMEWORK_EXPECT_FALSE(!serializable::dispatch_write <type> (in, begin, end, it)))
417  return false;
418 
419  n = static_cast <std::size_t> (it - begin);
420  return true;
421  }
422 
433  template <typename Input>
434  bool write_to_ostream (Input&& in, std::ostream& out)
435  {
436  return serializable::write(std::forward <Input> (in), out);
437  }
438 
449  template <typename Output>
450  bool read_from_array (char const* s, std::size_t n, Output&& out)
451  {
452  using type = typename std::remove_cv <typename std::remove_reference <Output>::type>::type;
453 
454  char const* const begin = s;
455  char const* const end = s+n;
456  char const* it = begin;
457 
458  return serializable::dispatch_read <type> (begin, end, it, std::forward <Output> (out));
459  }
460 
470  template <typename Input, typename Output>
471  bool read_from_string (Input&& in, Output&& out)
472  {
473  return read_from_array(&in[0], in.size(), std::forward <Output> (out));
474  }
475 
486  template <typename Input, typename Output>
487  bool read_from_frame (Input&& in, Output&& out)
488  {
489  raw_input_frame frame {&in[0], &in[in.size()]};
490  return serializable::read(frame, out);
491  }
492 
503  template <typename Output>
504  bool read_from_istream (std::istream& in, Output&& out)
505  {
506  return serializable::read(in, std::forward <Output> (out));
507  }
508  }
509 }
510 
511 #include <framework/protocol_buffers/protocol_buffers.inl>