irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

key_value_proxy.hpp
Go to the documentation of this file.
1 #ifndef IRODS_KEY_VALUE_PROXY_HPP
2 #define IRODS_KEY_VALUE_PROXY_HPP
3 
4 #include "lifetime_manager.hpp"
5 #include "objInfo.h"
6 #include "rcMisc.h"
7 
8 #include <algorithm>
9 #include <limits>
10 
11 // TODO: take a pass over std::string allocations
12 
13 namespace irods::experimental {
28  {
29  public:
30  // Aliases for various types used in key_value_proxy
31  using key_type = std::string_view;
32  using value_type = std::string;
33  using kvp = keyValPair_t;
34  using size_type = int;
35  using pair_type = std::pair<key_type, value_type>;
36 
45  class handle {
46  friend class key_value_proxy;
47  private:
59  handle(key_type _key, kvp& _kvp)
60  : kvp_{&_kvp}
61  , index_{index_of(_key, _kvp)}
62  , val_{}
63  {
64  if (index_ < 0) {
65  addKeyVal(kvp_, _key.data(), "");
66  index_ = kvp_->len - 1;
67  }
68  else {
69  val_ = kvp_->value[index_];
70  }
71  }
72 
73  public:
81  auto key() const -> key_type
82  {
83  return kvp_->keyWord[index_];
84  }
85 
91  auto operator=(const value_type& _v) -> void
92  {
93  addKeyVal(kvp_, kvp_->keyWord[index_], _v.data());
94  val_ = _v;
95  }
96 
104  operator const std::string&() const { return val_; }
105 
112  friend auto operator==(const std::string& _s, const handle& _h) -> bool
113  {
114  return _s == _h.val_;
115  }
116 
123  friend auto operator==(const handle& _h, const std::string& _s) -> bool
124  {
125  return _s == _h.val_;
126  }
127 
128  private:
135 
142 
149 
158  static auto index_of(key_type _k, kvp& _kvp) -> size_type
159  {
160  for (size_type i = 0; i < _kvp.len; i++) {
161  if (_k == _kvp.keyWord[i]) {
162  return i;
163  }
164  }
165  return -1;
166  }
167  };
168 
176  class iterator {
177  public:
178  // iterator_traits: https://en.cppreference.com/w/cpp/iterator/iterator_traits
180  using pointer = const value_type*;
183  using iterator_category = std::forward_iterator_tag;
184 
193  : index_{-1}
194  , kvp_{}
195  {
196  }
197 
205  explicit iterator(kvp& _kvp)
206  : index_{0}
207  , kvp_{&_kvp}
208  {
209  }
210 
219  {
220  if (++index_ >= kvp_->len) {
221  index_ = -1;
222  }
223  return *this;
224  }
225 
233  auto operator++(int) -> iterator
234  {
235  iterator ret = *this;
236  ++(*this);
237  return ret;
238  }
239 
248  auto operator==(const iterator& _rhs) const -> bool
249  {
250  return index_ == _rhs.index_;
251  }
252 
261  auto operator!=(const iterator& _rhs) const -> bool
262  {
263  return !(*this == _rhs);
264  }
265 
273  auto operator*() -> handle
274  {
275  return {kvp_->keyWord[index_], *kvp_};
276  }
277 
285  auto operator*() const -> const handle
286  {
287  return {kvp_->keyWord[index_], *kvp_};
288  }
289 
290  private:
297 
304  };
305 
311  explicit key_value_proxy(kvp& _kvp)
312  : kvp_{&_kvp}
313  {
314  }
315 
316  // Element access
327  auto at(key_type _k) -> handle
328  {
329  if (contains(_k)) {
330  return {_k, *kvp_};
331  }
332  throw std::out_of_range{"key not found"};
333  }
334 
344  auto operator[](key_type _k) -> handle { return {_k, *kvp_}; }
345 
346  // Iterators
352  auto begin() -> iterator { return iterator{*kvp_}; }
353 
359  auto cbegin() const -> const iterator { return iterator{*kvp_}; }
360 
366  auto end() -> iterator { return {}; }
367 
373  auto cend() const -> const iterator { return {}; }
374 
375  // capacity
381  auto empty() const noexcept -> bool { return 0 == size(); }
382 
388  auto size() const noexcept -> size_type { return kvp_->len; }
389 
395  constexpr auto max_size() const noexcept -> size_type
396  {
397  return std::numeric_limits<size_type>::max();
398  }
399 
400  // Modifiers
406  auto clear() -> void { clearKeyVal(kvp_); }
407 
413  auto insert(pair_type&& _p) -> std::pair<iterator, bool>
414  {
415  const auto k = std::get<key_type>(_p);
416  if (const auto& elem = find(k); end() != elem) {
417  return {elem, false};
418  }
419  const auto& v = std::get<value_type>(_p);
420  addKeyVal(kvp_, k.data(), v.data());
421  return {find(k), true};
422  }
423 
429  auto insert_or_assign(pair_type&& _p) -> std::pair<iterator, bool>
430  {
431  const auto k = std::get<key_type>(_p);
432  const auto& v = std::get<value_type>(_p);
433  const bool insertion = !contains(k);
434  addKeyVal(kvp_, k.data(), v.data());
435  return {find(k), insertion};
436  }
437 
443  auto erase(key_type _k) -> void { rmKeyVal(kvp_, _k.data()); }
444 
445  // Lookup
451  auto find(key_type _k) -> iterator
452  {
453  if (empty()) {
454  return end();
455  }
456  return std::find_if(begin(), end(),
457  [&_k](const auto& _hndl)
458  {
459  return _k == _hndl.key();
460  });
461  }
462 
468  auto find(key_type _k) const -> iterator
469  {
470  if (empty()) {
471  return cend();
472  }
473  return std::find_if(cbegin(), cend(),
474  [&_k](const auto& _hndl)
475  {
476  return _k == _hndl.key();
477  });
478  }
479 
485  auto contains(key_type _k) const -> bool { return find(_k) != cend(); }
486 
497  auto get() -> kvp& { return *kvp_; }
498 
499  private:
506  }; // class key_value_proxy
507 
508  using key_value_pair = std::pair<std::string, std::string>;
509  using proxy_struct_pair = std::pair<key_value_proxy, lifetime_manager<keyValPair_t>>;
510 
526  auto make_key_value_proxy(std::initializer_list<key_value_pair> _kvps = {}) -> proxy_struct_pair
527  {
528  keyValPair_t* cond_input = (keyValPair_t*)malloc(sizeof(keyValPair_t));
529  std::memset(cond_input, 0, sizeof(keyValPair_t));
530  key_value_proxy proxy{*cond_input};
531  for (const auto& kvp : _kvps) {
532  const auto& key = std::get<0>(kvp);
533  const auto& val = std::get<1>(kvp);
534  proxy[key] = val;
535  }
536  return {proxy, lifetime_manager(*cond_input)};
537  }
538 } // namespace irods::experimental
539 
540 #endif // #ifndef IRODS_KEY_VALUE_PROXY_HPP
irods::experimental::key_value_proxy::kvp_
kvp * kvp_
Definition: key_value_proxy.hpp:505
addKeyVal
int addKeyVal(keyValPair_t *condInput, const char *keyWord, const char *value)
Definition: rcMisc.cpp:789
irods::experimental::key_value_proxy::key_value_proxy
key_value_proxy(kvp &_kvp)
Definition: key_value_proxy.hpp:311
irods::experimental::key_value_proxy::handle::operator==
friend auto operator==(const handle &_h, const std::string &_s) -> bool
Definition: key_value_proxy.hpp:123
irods::experimental::key_value_proxy::iterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: key_value_proxy.hpp:183
irods::experimental::key_value_proxy::iterator::difference_type
size_type difference_type
Definition: key_value_proxy.hpp:182
irods::experimental::key_value_proxy::iterator::operator!=
auto operator!=(const iterator &_rhs) const -> bool
Definition: key_value_proxy.hpp:261
irods::experimental::key_value_proxy::handle::index_
size_type index_
Definition: key_value_proxy.hpp:141
irods::experimental::key_value_proxy::max_size
constexpr auto max_size() const noexcept -> size_type
Definition: key_value_proxy.hpp:395
irods::experimental::key_value_proxy::iterator::operator==
auto operator==(const iterator &_rhs) const -> bool
Definition: key_value_proxy.hpp:248
irods::experimental::key_value_proxy::end
auto end() -> iterator
Definition: key_value_proxy.hpp:366
irods::experimental::key_value_proxy::handle
Definition: key_value_proxy.hpp:45
irods::experimental::key_value_proxy::clear
auto clear() -> void
Definition: key_value_proxy.hpp:406
irods::experimental::key_value_proxy::size_type
int size_type
Definition: key_value_proxy.hpp:34
rcMisc.h
irods::experimental::proxy_struct_pair
std::pair< key_value_proxy, lifetime_manager< keyValPair_t > > proxy_struct_pair
Definition: key_value_proxy.hpp:509
irods::experimental::key_value_proxy::iterator::value_type
handle value_type
Definition: key_value_proxy.hpp:179
irods::experimental::key_value_proxy::handle::handle
handle(key_type _key, kvp &_kvp)
Definition: key_value_proxy.hpp:59
irods::experimental::key_value_proxy::get
auto get() -> kvp &
Definition: key_value_proxy.hpp:497
irods::experimental::make_key_value_proxy
auto make_key_value_proxy(std::initializer_list< key_value_pair > _kvps={}) -> proxy_struct_pair
Definition: key_value_proxy.hpp:526
irods::experimental::key_value_proxy::iterator::operator*
auto operator*() const -> const handle
Definition: key_value_proxy.hpp:285
irods::experimental::key_value_proxy::iterator::kvp_
kvp * kvp_
Definition: key_value_proxy.hpp:303
irods::experimental::key_value_proxy::handle::index_of
static auto index_of(key_type _k, kvp &_kvp) -> size_type
Definition: key_value_proxy.hpp:158
irods::experimental::key_value_proxy::value_type
std::string value_type
Definition: key_value_proxy.hpp:32
KeyValPair::value
char ** value
Definition: objInfo.h:123
irods::experimental::key_value_proxy::cbegin
auto cbegin() const -> const iterator
Definition: key_value_proxy.hpp:359
irods::experimental::key_value_proxy::insert_or_assign
auto insert_or_assign(pair_type &&_p) -> std::pair< iterator, bool >
Definition: key_value_proxy.hpp:429
irods::experimental::key_value_proxy::empty
auto empty() const noexcept -> bool
Definition: key_value_proxy.hpp:381
irods::experimental::key_value_proxy::pair_type
std::pair< key_type, value_type > pair_type
Definition: key_value_proxy.hpp:35
irods::experimental::key_value_proxy::operator[]
auto operator[](key_type _k) -> handle
Definition: key_value_proxy.hpp:344
keyValPair_t
struct KeyValPair keyValPair_t
KeyValPair::keyWord
char ** keyWord
Definition: objInfo.h:122
irods::experimental::key_value_proxy::contains
auto contains(key_type _k) const -> bool
Definition: key_value_proxy.hpp:485
irods::experimental::key_value_proxy::size
auto size() const noexcept -> size_type
Definition: key_value_proxy.hpp:388
lifetime_manager.hpp
irods::experimental::key_value_proxy::handle::kvp_
kvp * kvp_
Definition: key_value_proxy.hpp:134
rmKeyVal
int rmKeyVal(keyValPair_t *condInput, const char *keyWord)
Definition: rcMisc.cpp:710
irods::experimental::key_value_proxy::iterator::operator++
auto operator++(int) -> iterator
Definition: key_value_proxy.hpp:233
irods::experimental::key_value_proxy::at
auto at(key_type _k) -> handle
Definition: key_value_proxy.hpp:327
irods::experimental::key_value_pair
std::pair< std::string, std::string > key_value_pair
Definition: key_value_proxy.hpp:508
irods::experimental::key_value_proxy::insert
auto insert(pair_type &&_p) -> std::pair< iterator, bool >
Definition: key_value_proxy.hpp:413
irods::experimental::key_value_proxy::handle::key
auto key() const -> key_type
Definition: key_value_proxy.hpp:81
int
typedef int((*funcPtr)())
irods::experimental::key_value_proxy::iterator::operator*
auto operator*() -> handle
Definition: key_value_proxy.hpp:273
irods::experimental::key_value_proxy::erase
auto erase(key_type _k) -> void
Definition: key_value_proxy.hpp:443
objInfo.h
irods::experimental::key_value_proxy::find
auto find(key_type _k) const -> iterator
Definition: key_value_proxy.hpp:468
irods::experimental::key_value_proxy::cend
auto cend() const -> const iterator
Definition: key_value_proxy.hpp:373
irods::experimental::key_value_proxy::handle::operator=
auto operator=(const value_type &_v) -> void
Definition: key_value_proxy.hpp:91
KeyValPair::len
int len
Definition: objInfo.h:121
irods::experimental::key_value_proxy::iterator::index_
size_type index_
Definition: key_value_proxy.hpp:296
irods::experimental::key_value_proxy::iterator::operator++
auto operator++() -> iterator
Definition: key_value_proxy.hpp:218
irods::experimental
Definition: dstream.hpp:16
irods::experimental::key_value_proxy::iterator::iterator
iterator(kvp &_kvp)
Definition: key_value_proxy.hpp:205
irods::experimental::key_value_proxy
Definition: key_value_proxy.hpp:28
irods::experimental::key_value_proxy::handle::operator==
friend auto operator==(const std::string &_s, const handle &_h) -> bool
Definition: key_value_proxy.hpp:112
irods::experimental::key_value_proxy::handle::val_
value_type val_
Definition: key_value_proxy.hpp:148
irods::experimental::key_value_proxy::iterator::iterator
iterator()
Definition: key_value_proxy.hpp:192
KeyValPair
Definition: objInfo.h:120
clearKeyVal
int clearKeyVal(keyValPair_t *condInput)
Definition: rcMisc.cpp:1047
irods::experimental::key_value_proxy::find
auto find(key_type _k) -> iterator
Definition: key_value_proxy.hpp:451
irods::experimental::key_value_proxy::key_type
std::string_view key_type
Definition: key_value_proxy.hpp:31
irods::experimental::key_value_proxy::begin
auto begin() -> iterator
Definition: key_value_proxy.hpp:352
irods::experimental::key_value_proxy::iterator
Definition: key_value_proxy.hpp:176