zookeeper-cpp
ZooKeeper Client for C++
multi.cpp
1 #include "multi.hpp"
2 
3 #include <new>
4 #include <ostream>
5 #include <sstream>
6 #include <stdexcept>
7 
8 namespace zk
9 {
10 
11 template <typename T>
12 static std::string to_string_generic(const T& self)
13 {
14  std::ostringstream os;
15  os << self;
16  return os.str();
17 }
18 
20 // op_type //
22 
23 std::ostream& operator<<(std::ostream& os, const op_type& self)
24 {
25  switch (self)
26  {
27  case op_type::check: return os << "check";
28  case op_type::create: return os << "create";
29  case op_type::erase: return os << "erase";
30  case op_type::set: return os << "set";
31  default: return os << "op_type(" << static_cast<int>(self) << ')';
32  }
33 }
34 
35 std::string to_string(const op_type& self)
36 {
37  return to_string_generic(self);
38 }
39 
41 // op //
43 
44 // check
45 
46 op::check_data::check_data(std::string path, version check_) :
47  path(std::move(path)),
48  check(check_)
49 { }
50 
51 std::ostream& operator<<(std::ostream& os, const op::check_data& self)
52 {
53  os << '{' << self.path;
54  os << ' ' << self.check;
55  return os << '}';
56 }
57 
58 op op::check(std::string path, version check_)
59 {
60  return op(check_data(std::move(path), check_));
61 }
62 
63 op::any_data::any_data(check_data&& src) noexcept :
64  check(std::move(src))
65 { }
66 
67 op::op(check_data&& src) noexcept :
68  _type(op_type::check),
69  _storage(std::move(src))
70 { }
71 
72 const op::check_data& op::as_check() const
73 {
74  if (_type != op_type::check)
75  throw std::logic_error("Invalid op type for as_check: " + to_string(_type));
76  else
77  return _storage.check;
78 }
79 
80 // create
81 
82 op::create_data::create_data(std::string path, buffer data, acl rules, create_mode mode) :
83  path(std::move(path)),
84  data(std::move(data)),
85  rules(std::move(rules)),
86  mode(mode)
87 { }
88 
89 std::ostream& operator<<(std::ostream& os, const op::create_data& self)
90 {
91  os << '{' << self.path;
92  os << ' ' << self.mode;
93  os << ' ' << self.rules;
94  return os << '}';
95 }
96 
97 op op::create(std::string path, buffer data, acl rules, create_mode mode)
98 {
99  return op(create_data(std::move(path), std::move(data), std::move(rules), mode));
100 }
101 
102 op op::create(std::string path, buffer data, create_mode mode)
103 {
104  return create(std::move(path), std::move(data), acls::open_unsafe(), mode);
105 }
106 
107 op::any_data::any_data(create_data&& src) noexcept :
108  create(std::move(src))
109 { }
110 
111 op::op(create_data&& src) noexcept :
112  _type(op_type::create),
113  _storage(std::move(src))
114 { }
115 
116 const op::create_data& op::as_create() const
117 {
118  if (_type != op_type::create)
119  throw std::logic_error("Invalid op type for as_create: " + to_string(_type));
120  else
121  return _storage.create;
122 }
123 
124 // erase
125 
126 op::erase_data::erase_data(std::string path, version check) :
127  path(std::move(path)),
128  check(check)
129 { }
130 
131 std::ostream& operator<<(std::ostream& os, const op::erase_data& self)
132 {
133  os << '{' << self.path;
134  os << ' ' << self.check;
135  return os << '}';
136 }
137 
138 op op::erase(std::string path, version check)
139 {
140  return op(erase_data(std::move(path), check));
141 }
142 
143 op::any_data::any_data(erase_data&& src) noexcept :
144  erase(std::move(src))
145 { }
146 
147 op::op(erase_data&& src) noexcept :
148  _type(op_type::erase),
149  _storage(std::move(src))
150 { }
151 
152 const op::erase_data& op::as_erase() const
153 {
154  if (_type != op_type::erase)
155  throw std::logic_error("Invalid op type for as_erase: " + to_string(_type));
156  else
157  return _storage.erase;
158 }
159 
160 // set
161 
162 op::set_data::set_data(std::string path, buffer data, version check) :
163  path(std::move(path)),
164  data(std::move(data)),
165  check(check)
166 { }
167 
168 std::ostream& operator<<(std::ostream& os, const op::set_data& self)
169 {
170  os << '{' << self.path;
171  os << ' ' << self.check;
172  return os << '}';
173 }
174 
175 op op::set(std::string path, buffer data, version check)
176 {
177  return op(set_data(std::move(path), std::move(data), check));
178 }
179 
180 op::any_data::any_data(set_data&& src) noexcept :
181  set(std::move(src))
182 { }
183 
184 op::op(set_data&& src) noexcept :
185  _type(op_type::set),
186  _storage(std::move(src))
187 { }
188 
189 const op::set_data& op::as_set() const
190 {
191  if (_type != op_type::set)
192  throw std::logic_error("Invalid op type for as_set: " + to_string(_type));
193  else
194  return _storage.set;
195 }
196 
197 // generic
198 
199 op::any_data::any_data(std::nullptr_t) noexcept
200 { }
201 
202 op::any_data::~any_data() noexcept
203 {
204  // handled by ~op
205 }
206 
207 template <typename T, typename... TArgs>
208 static void place_new(ptr<T> destination, TArgs&&... args)
209  noexcept(noexcept(T(std::forward<TArgs>(args)...)))
210 {
211  new (static_cast<ptr<void>>(destination)) T(std::forward<TArgs>(args)...);
212 }
213 
214 op::op(const op& src) :
215  _type(src._type),
216  _storage(nullptr)
217 {
218  switch (_type)
219  {
220  case op_type::check: place_new(&_storage.check, src._storage.check); break;
221  case op_type::create: place_new(&_storage.create, src._storage.create); break;
222  case op_type::erase: place_new(&_storage.erase, src._storage.erase); break;
223  case op_type::set: place_new(&_storage.set, src._storage.set); break;
224  }
225 }
226 
227 op::op(op&& src) noexcept :
228  _type(src._type),
229  _storage(nullptr)
230 {
231  switch (_type)
232  {
233  case op_type::check: place_new(&_storage.check, std::move(src._storage.check)); break;
234  case op_type::create: place_new(&_storage.create, std::move(src._storage.create)); break;
235  case op_type::erase: place_new(&_storage.erase, std::move(src._storage.erase)); break;
236  case op_type::set: place_new(&_storage.set, std::move(src._storage.set)); break;
237  }
238 }
239 
240 op::~op() noexcept
241 {
242  switch (_type)
243  {
244  case op_type::check: _storage.check.~auto(); break;
245  case op_type::create: _storage.create.~auto(); break;
246  case op_type::erase: _storage.erase.~auto(); break;
247  case op_type::set: _storage.set.~auto(); break;
248  }
249 }
250 
251 std::ostream& operator<<(std::ostream& os, const op& self)
252 {
253  os << self.type();
254  switch (self.type())
255  {
256  case op_type::check: return os << self.as_check();
257  case op_type::create: return os << self.as_create();
258  case op_type::erase: return os << self.as_erase();
259  case op_type::set: return os << self.as_set();
260  default: return os << "{ ??? }";
261  }
262 }
263 
264 std::string to_string(const op& self)
265 {
266  std::ostringstream os;
267  os << self;
268  return os.str();
269 }
270 
272 // multi_op //
274 
275 multi_op::multi_op(std::vector<op> ops) noexcept :
276  _ops(std::move(ops))
277 { }
278 
279 multi_op::~multi_op() noexcept
280 { }
281 
282 std::ostream& operator<<(std::ostream& os, const multi_op& self)
283 {
284  os << '[';
285  bool first = true;
286  for (const auto& x : self)
287  {
288  if (first)
289  first = false;
290  else
291  os << ", ";
292  os << x;
293  }
294  return os << ']';
295 }
296 
298 // multi_result //
300 
301 multi_result::any_result::any_result(std::nullptr_t) noexcept
302 { }
303 
304 multi_result::part::part(op_type type, std::nullptr_t) noexcept :
305  _type(type),
306  _storage(nullptr)
307 { }
308 
309 multi_result::any_result::any_result(create_result&& res) noexcept :
310  create(std::move(res))
311 { }
312 
313 multi_result::part::part(create_result res) noexcept :
314  _type(op_type::create),
315  _storage(std::move(res))
316 { }
317 
318 multi_result::any_result::any_result(set_result&& res) noexcept :
319  set(std::move(res))
320 { }
321 
322 multi_result::part::part(set_result res) noexcept :
323  _type(op_type::set),
324  _storage(std::move(res))
325 { }
326 
327 multi_result::any_result::~any_result() noexcept
328 {
329  // handled in ~part
330 }
331 
332 multi_result::part::part(const part& src) :
333  _type(src._type),
334  _storage(nullptr)
335 {
336  switch (_type)
337  {
338  case op_type::create: place_new(&_storage.create, src._storage.create); break;
339  case op_type::set: place_new(&_storage.set, src._storage.set); break;
340  default: break;
341  }
342 }
343 
344 multi_result::part::part(part&& src) noexcept :
345  _type(src._type),
346  _storage(nullptr)
347 {
348  switch (_type)
349  {
350  case op_type::create: place_new(&_storage.create, std::move(src._storage.create)); break;
351  case op_type::set: place_new(&_storage.set, std::move(src._storage.set)); break;
352  default: break;
353  }
354 }
355 
356 multi_result::part::~part() noexcept
357 {
358  switch (_type)
359  {
360  case op_type::create: _storage.create.~create_result(); break;
361  case op_type::set: _storage.set.~set_result(); break;
362  default: break;
363  }
364 }
365 
366 const create_result& multi_result::part::as_create() const
367 {
368  if (_type != op_type::create)
369  throw std::logic_error("Invalid part type for as_create: " + to_string(_type));
370  else
371  return _storage.create;
372 }
373 
374 const set_result& multi_result::part::as_set() const
375 {
376  if (_type != op_type::set)
377  throw std::logic_error("Invalid part type for as_set: " + to_string(_type));
378  else
379  return _storage.set;
380 }
381 
382 multi_result::multi_result(std::vector<part> parts) noexcept :
383  _parts(std::move(parts))
384 { }
385 
386 multi_result::~multi_result() noexcept
387 { }
388 
389 std::ostream& operator<<(std::ostream& os, const multi_result::part& self)
390 {
391  switch (self.type())
392  {
393  case op_type::create: return os << self.as_create();
394  case op_type::set: return os << self.as_set();
395  default: return os << self.type() << "_result{}";
396  }
397 }
398 
399 std::ostream& operator<<(std::ostream& os, const multi_result& self)
400 {
401  os << '[';
402  bool first = true;
403  for (const auto& x : self)
404  {
405  if (first)
406  first = false;
407  else
408  os << ", ";
409  os << x;
410  }
411  return os << ']';
412 }
413 
414 std::string to_string(const multi_result::part& self)
415 {
416  return to_string_generic(self);
417 }
418 
419 std::string to_string(const multi_result& self)
420 {
421  return to_string_generic(self);
422 }
423 
424 }
T * ptr
A simple, unowned pointer.
Definition: config.hpp:75
Definition: acl.cpp:8
Definition: multi.hpp:35
The result type of client::create.
Definition: results.hpp:101
STL namespace.
create_mode
When used in client::set, this value determines how the znode is created on the server.
Definition: types.hpp:252
You can create a child node.
The result type of client::set.
Definition: results.hpp:123
An access control list is a wrapper around acl_rule instances.
Definition: acl.hpp:124
You can erase a child node (but not necessarily this one).
A part of a result.
Definition: multi.hpp:211
Represents a version of the data.
Definition: types.hpp:131
ZKPP_BUFFER_TYPE buffer
The buffer type.
Definition: buffer.hpp:67