zookeeper-cpp
ZooKeeper Client for C++
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Groups
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 op::op(any_data&& src) noexcept :
45  _storage(std::move(src))
46 { }
47 
48 op::op(const op& src) = default;
49 
50 op::op(op&& src) noexcept :
51  _storage(std::move(src._storage))
52 { }
53 
54 op::~op() noexcept = default;
55 
56 op_type op::type() const
57 {
58  return std::visit([] (const auto& x) { return x.type(); }, _storage);
59 }
60 
61 template <typename T>
62 const T& op::as(ptr<const char> operation) const
63 {
64  try
65  {
66  return std::get<T>(_storage);
67  }
68  catch (const std::bad_variant_access&)
69  {
70  throw std::logic_error( std::string("Invalid op type for op::")
71  + std::string(operation)
72  + std::string(": ")
73  + to_string(type())
74  );
75  }
76 }
77 
78 // check
79 
80 op::check_data::check_data(std::string path, version check_) :
81  path(std::move(path)),
82  check(check_)
83 { }
84 
85 std::ostream& operator<<(std::ostream& os, const op::check_data& self)
86 {
87  os << '{' << self.path;
88  os << ' ' << self.check;
89  return os << '}';
90 }
91 
92 op op::check(std::string path, version check_)
93 {
94  return op(check_data(std::move(path), check_));
95 }
96 
98 {
99  return as<check_data>("as_check");
100 }
101 
102 // create
103 
104 op::create_data::create_data(std::string path, buffer data, acl rules, create_mode mode) :
105  path(std::move(path)),
106  data(std::move(data)),
107  rules(std::move(rules)),
108  mode(mode)
109 { }
110 
111 std::ostream& operator<<(std::ostream& os, const op::create_data& self)
112 {
113  os << '{' << self.path;
114  os << ' ' << self.mode;
115  os << ' ' << self.rules;
116  return os << '}';
117 }
118 
119 op op::create(std::string path, buffer data, acl rules, create_mode mode)
120 {
121  return op(create_data(std::move(path), std::move(data), std::move(rules), mode));
122 }
123 
124 op op::create(std::string path, buffer data, create_mode mode)
125 {
126  return create(std::move(path), std::move(data), acls::open_unsafe(), mode);
127 }
128 
130 {
131  return as<create_data>("as_create");
132 }
133 
134 // erase
135 
136 op::erase_data::erase_data(std::string path, version check) :
137  path(std::move(path)),
138  check(check)
139 { }
140 
141 std::ostream& operator<<(std::ostream& os, const op::erase_data& self)
142 {
143  os << '{' << self.path;
144  os << ' ' << self.check;
145  return os << '}';
146 }
147 
148 op op::erase(std::string path, version check)
149 {
150  return op(erase_data(std::move(path), check));
151 }
152 
154 {
155  return as<erase_data>("as_erase");
156 }
157 
158 // set
159 
160 op::set_data::set_data(std::string path, buffer data, version check) :
161  path(std::move(path)),
162  data(std::move(data)),
163  check(check)
164 { }
165 
166 std::ostream& operator<<(std::ostream& os, const op::set_data& self)
167 {
168  os << '{' << self.path;
169  os << ' ' << self.check;
170  return os << '}';
171 }
172 
173 op op::set(std::string path, buffer data, version check)
174 {
175  return op(set_data(std::move(path), std::move(data), check));
176 }
177 
178 const op::set_data& op::as_set() const
179 {
180  return as<set_data>("as_set");
181 }
182 
183 // generic
184 
185 std::ostream& operator<<(std::ostream& os, const op& self)
186 {
187  os << self.type();
188  std::visit([&] (const auto& x) { os << x; }, self._storage);
189  return os;
190 }
191 
192 std::string to_string(const op& self)
193 {
194  std::ostringstream os;
195  os << self;
196  return os.str();
197 }
198 
200 // multi_op //
202 
203 multi_op::multi_op(std::vector<op> ops) noexcept :
204  _ops(std::move(ops))
205 { }
206 
207 multi_op::~multi_op() noexcept
208 { }
209 
210 std::ostream& operator<<(std::ostream& os, const multi_op& self)
211 {
212  os << '[';
213  bool first = true;
214  for (const auto& x : self)
215  {
216  if (first)
217  first = false;
218  else
219  os << ", ";
220  os << x;
221  }
222  return os << ']';
223 }
224 
226 // multi_result //
228 
229 multi_result::part::part(op_type type, std::nullptr_t) noexcept :
230  _type(type),
231  _storage(std::monostate())
232 { }
233 
234 multi_result::part::part(create_result res) noexcept :
235  _type(op_type::create),
236  _storage(std::move(res))
237 { }
238 
239 multi_result::part::part(set_result res) noexcept :
240  _type(op_type::set),
241  _storage(std::move(res))
242 { }
243 
244 multi_result::part::part(const part& src) = default;
245 
246 multi_result::part::part(part&& src) noexcept :
247  _type(src._type),
248  _storage(std::move(src._storage))
249 { }
250 
251 multi_result::part::~part() noexcept = default;
252 
253 template <typename T>
254 const T& multi_result::part::as(ptr<const char> operation) const
255 {
256  try
257  {
258  return std::get<T>(_storage);
259  }
260  catch (const std::bad_variant_access&)
261  {
262  throw std::logic_error( std::string("Invalid op type for multi_result::")
263  + std::string(operation)
264  + std::string(": ")
265  + to_string(type())
266  );
267  }
268 }
269 
271 {
272  return as<create_result>("as_create");
273 }
274 
276 {
277  return as<set_result>("as_set");
278 }
279 
280 multi_result::multi_result(std::vector<part> parts) noexcept :
281  _parts(std::move(parts))
282 { }
283 
284 multi_result::~multi_result() noexcept
285 { }
286 
287 std::ostream& operator<<(std::ostream& os, const multi_result::part& self)
288 {
289  switch (self.type())
290  {
291  case op_type::create: return os << self.as_create();
292  case op_type::set: return os << self.as_set();
293  default: return os << self.type() << "_result{}";
294  }
295 }
296 
297 std::ostream& operator<<(std::ostream& os, const multi_result& self)
298 {
299  os << '[';
300  bool first = true;
301  for (const auto& x : self)
302  {
303  if (first)
304  first = false;
305  else
306  os << ", ";
307  os << x;
308  }
309  return os << ']';
310 }
311 
312 std::string to_string(const multi_result::part& self)
313 {
314  return to_string_generic(self);
315 }
316 
317 std::string to_string(const multi_result& self)
318 {
319  return to_string_generic(self);
320 }
321 
322 }
T * ptr
A simple, unowned pointer.
Definition: config.hpp:37
Data for a op::set operation.
Definition: multi.hpp:92
const set_data & as_set() const
Get the set-specific data.
Definition: multi.cpp:178
const set_result & as_set() const
Get the set-specific result data.
Definition: multi.cpp:275
const create_result & as_create() const
Get the create-specific result data.
Definition: multi.cpp:270
Represents a single operation of a multi_op.
Definition: multi.hpp:37
The result type of client::create.
Definition: results.hpp:116
op_type
Describes the type of an op.
Definition: multi.hpp:24
const create_data & as_create() const
Get the create-specific data.
Definition: multi.cpp:129
create_mode
When used in client::set, this value determines how the entry is created on the server.
Definition: types.hpp:283
Data for a op::check operation.
Definition: multi.hpp:41
static const acl & open_unsafe()
This is a completely open ACL.
Definition: acl.cpp:161
op_type type() const
Get the underlying type of this operation.
Definition: multi.cpp:56
The result type of client::set.
Definition: results.hpp:141
An access control list is a wrapper around acl_rule instances.
Definition: acl.hpp:139
multi_op() noexcept
Create an empty operation set.
Definition: multi.hpp:171
const erase_data & as_erase() const
Get the erase-specific data.
Definition: multi.cpp:153
static op check(std::string path, version check=version::any())
Check that the given path exists with the provided version check (which can be version::any).
Definition: multi.cpp:92
static op create(std::string path, buffer data, acl rules, create_mode mode=create_mode::normal)
Definition: multi.cpp:119
Represents a version of the data.
Definition: types.hpp:158
ZKPP_BUFFER_TYPE buffer
The buffer type.
Definition: buffer.hpp:79
Data for a op::erase operation.
Definition: multi.hpp:76
const check_data & as_check() const
Get the check-specific data.
Definition: multi.cpp:97
Data for a op::create operation.
Definition: multi.hpp:55
static op erase(std::string path, version check=version::any())
Delete the entry at the given path if it matches the version check.
Definition: multi.cpp:148
static op set(std::string path, buffer data, version check=version::any())
Set the data for the entry at path if it matches the version check.
Definition: multi.cpp:173