0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
directory.h
Go to the documentation of this file.
1 /* -*- c++ -*-
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3
9  * of the License.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 
27 #ifndef Common_directory_h
28 #define Common_directory_h
29 
30 // remove me!
31 #include <iostream>
32 
33 #include <cassert>
34 #include <iomanip>
35 #include <iterator>
36 #include <memory>
37 #include <set>
38 #include <stack>
39 #include <type_traits>
40 #include <vector>
41 
42 namespace Hypertable {
43 
44  namespace __detail {
45 
46  struct __any {
47  __any(...);
48  };
49 
50  struct __nat { };
51 
53 
54  template <class _Tp>
55  struct __swappable
56  {
57  typedef decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>())) type;
58  static const bool value = !std::is_same<type, __nat>::value;
59  };
60 
61  }
62 
63  template <class _Tp>
65  : public std::integral_constant<bool, __detail::__swappable<_Tp>::value>
66  {
67  };
68 
69  template <bool, class _Tp>
71  : public std::integral_constant<bool, noexcept(swap(std::declval<_Tp&>(),
72  std::declval<_Tp&>()))>
73  {
74  };
75 
76  template <class _Tp>
77  struct __is_nothrow_swappable_imp<false, _Tp>
78  : public std::false_type
79  {
80  };
81 
82  template <class _Tp>
84  : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>
85  {
86  };
87 
88 
91 
92  template <class _Key, class _Tp>
94  public:
96  directory_entry(int level, _Key key) : level(level), key(key) {}
97  directory_entry(int level, _Key key, _Tp value) : level(level), key(key), value(value), isset_value(true) {}
98  void set_value(_Tp val) { value = val; isset_value = true; }
99  friend inline std::ostream &operator<<(std::ostream &os, const directory_entry &de) {
100  os << std::setw(2) << de.level << " " << de.key;
101  if (de.isset_value)
102  os << "=" << de.value;
103  return os;
104  }
105  size_t level {};
106  _Key key {};
107  _Tp value {};
108  bool isset_value {};
109  };
110 
111  template <class _Key, class _Tp>
112  inline bool operator== (const directory_entry<_Key, _Tp>& lhs,
113  const directory_entry<_Key, _Tp>& rhs) {
114  if (lhs.level == rhs.level &&
115  lhs.key == rhs.key &&
116  lhs.isset_value == rhs.isset_value)
117  return !lhs.isset_value || lhs.value == rhs.value;
118  return false;
119  }
120 
121  template <class _Key, class _Tp>
122  inline bool operator!= (const directory_entry<_Key, _Tp>& lhs,
123  const directory_entry<_Key, _Tp>& rhs) {
124  return !(lhs == rhs);
125  }
126 
127  template <class _Key, class _Tp>
128  inline bool operator< (const directory_entry<_Key, _Tp>& lhs,
129  const directory_entry<_Key, _Tp>& rhs) {
130  if (lhs.level != rhs.level)
131  return lhs.level < rhs.level;
132  if (lhs.key != rhs.key)
133  return lhs.key < rhs.key;
134  if (lhs.isset_value != rhs.isset_value)
135  return !lhs.isset_value;
136  if (lhs.isset_value)
137  return lhs.value < rhs.value;
138  return false;
139  }
140 
141  template <class _Value, class _Compare, class _Allocator>
143  public:
144 
146  typedef std::allocator_traits<_Allocator> __alloc_traits;
147 
148  typedef typename __alloc_traits::template rebind_alloc<__directory_node_internal> __node_allocator;
149  typedef std::allocator_traits<__node_allocator> __node_traits;
150 
151 
153  : public std::binary_function<pointer, pointer, bool> {
154  public:
155  pointer_compare() : comp() {}
156  pointer_compare(_Compare c) : comp(c) {}
157  bool operator()(const pointer __x, const pointer __y) const
158  {return comp(__x->entry, __y->entry);}
159  protected:
160  _Compare comp;
161  };
162 
163  using children_set = std::set<pointer, pointer_compare, _Allocator>;
164 
166  __directory_node_internal(_Compare &comp, _Allocator &alloc)
167  : m_value_allocator(alloc), children(pointer_compare(comp), alloc) {}
169  : m_value_allocator(__alloc_traits::select_on_container_copy_construction(other.m_value_allocator)),
170  entry(other.entry), children(other.children.key_comp(), other.m_value_allocator) {}
171  __directory_node_internal(_Value value, _Compare &comp, _Allocator &alloc)
172  : m_value_allocator(alloc), entry(value), children(pointer_compare(comp), alloc) {}
173 
175  for (auto &np : children)
176  __destroy_node(np);
177  }
178 
179  std::pair<typename children_set::iterator, bool> insert_child(pointer child) {
180  child->parent = this;
181  return children.insert(child);
182  }
183 
184  size_t size() const noexcept {
185  size_t sz {1};
186  for (const auto &child : children)
187  sz += child->size();
188  return sz;
189  }
190 
191  private:
192 
193  void __destroy_node(pointer np) {
194  __node_allocator __na(m_value_allocator);
195  __node_traits::destroy(__na, np);
196  __node_traits::deallocate(__na, np, 1);
197  }
198 
199  _Allocator m_value_allocator;
200 
201  public:
202  pointer parent {};
203  _Value entry;
205  };
206 
207  template <class _Tp, class _NodePtr, class _DiffType>
209 
210  typedef _NodePtr __node_pointer;
211  typedef typename std::pointer_traits<_NodePtr>::element_type __node;
212 
213  public:
214  typedef std::bidirectional_iterator_tag iterator_category;
215  typedef _Tp value_type;
216  typedef _DiffType difference_type;
217  typedef value_type& reference;
218  typedef typename std::pointer_traits<__node_pointer>::template rebind<value_type> pointer;
219 
220  __directory_iterator() noexcept { }
221 
222  __directory_iterator(__node_pointer root) noexcept : __root_(root) { }
223 
224  __directory_iterator(__node_pointer root, __node_pointer np) : __root_(root) {
225  if (np)
226  __iters_.push_back(__subdirectory_iterator(np, np->children.begin()));
227  }
228 
229  reference operator*() const {return __iters_.back().np->entry;}
230 
231  pointer operator->() const {
232  return std::pointer_traits<pointer>::pointer_to(__iters_.back().np->entry);
233  }
234 
236  if (__iters_.back().iter != __iters_.back().np->children.end()) {
237  __node_pointer np = *__iters_.back().iter;
238  __iters_.push_back(__subdirectory_iterator(np, np->children.begin()));
239  }
240  else {
241  while (!__iters_.empty()) {
242  if (__iters_.back().iter == __iters_.back().np->children.end())
243  __iters_.pop_back();
244  else {
245  ++__iters_.back().iter;
246  if (__iters_.back().iter == __iters_.back().np->children.end())
247  continue;
248  __node_pointer np = *__iters_.back().iter;
249  __iters_.push_back(__subdirectory_iterator(np, np->children.begin()));
250  break;
251  }
252  }
253  }
254  return *this;
255  }
256 
258  __directory_iterator __before(*this); ++(*this); return __before;
259  }
260 
262  if (__iters_.empty())
263  __iters_.push_back(__subdirectory_iterator(__root_, __root_->children.end()));
264  else if (__iters_.back().iter == __iters_.back().np->children.begin())
265  __iters_.pop_back();
266 
267  if (__iters_.back().iter != __iters_.back().np->children.begin()) {
268  __node_pointer np;
269  do {
270  --__iters_.back().iter;
271  np = *__iters_.back().iter;
272  __iters_.push_back(__subdirectory_iterator(np, np->children.end()));
273  } while (!np->children.empty());
274  }
275  return *this;
276  }
277 
279  __directory_iterator __before(*this); --(*this); return __before;
280  }
281 
282  friend bool operator==(const __directory_iterator& __x, const __directory_iterator& __y) {
283  return __x.__iters_ == __y.__iters_;
284  }
285 
286  friend bool operator!=(const __directory_iterator& __x, const __directory_iterator& __y) {
287  return !(__x == __y);
288  }
289 
290  void push(__node_pointer np,
291  typename __node::children_set::iterator iter) {
292  __iters_.push_back(__subdirectory_iterator(np, iter));
293  }
294 
295  __node_pointer node() {
296  return __iters_.back().np;
297  }
298 
299  operator bool() const {
300  return !__iters_.empty();
301  }
302 
303  friend inline std::ostream &operator<<(std::ostream &os, const __directory_iterator &di) {
304  os << "[directory_iterator]" << std::endl;
305  for (const auto &si : di.__iters_)
306  os << si.np->entry << std::endl;
307  return os;
308  }
309 
310  private:
311 
313  public:
314  __subdirectory_iterator(__node_pointer np,
315  typename __node::children_set::iterator iter)
316  : np(np), iter(iter) {}
317  __node_pointer np;
318  typename __node::children_set::iterator iter;
319 
320  friend bool operator==(const __subdirectory_iterator& __x, const __subdirectory_iterator& __y) {
321  return __x.np == __y.np && __x.iter == __y.iter;
322  }
323 
324  friend bool operator!=(const __subdirectory_iterator& __x, const __subdirectory_iterator& __y) {
325  return !(__x == __y);
326  }
327 
328  };
329 
330  __node_pointer __root_ {};
331  std::vector<__subdirectory_iterator> __iters_;
332  };
333 
334 
341  template <class _Key, class _Tp, class _Compare = std::less<_Key>,
342  class _Allocator = std::allocator<directory_entry<const _Key, _Tp> > >
343  class directory {
344 
345  public:
346 
348  typedef _Key key_type;
349 
351  typedef _Tp mapped_type;
352 
355 
357  typedef _Compare key_compare;
358 
360  typedef _Allocator allocator_type;
361 
362  typedef std::allocator_traits<allocator_type> __alloc_traits;
363 
364  typedef typename __alloc_traits::pointer pointer;
365  typedef typename __alloc_traits::const_pointer const_pointer;
366  typedef typename __alloc_traits::size_type size_type;
367  typedef typename __alloc_traits::difference_type difference_type;
368 
370  typedef value_type& reference;
371 
373  typedef const value_type& const_reference;
374 
375 
378  : public std::binary_function<value_type, value_type, bool> {
379  friend class directory;
380  protected:
381  key_compare key_comp;
382 
383  value_compare(key_compare c) : key_comp(c) {}
384  public:
385  bool operator()(const value_type& __x, const value_type& __y) const
386  {return key_comp(__x.key, __y.key);}
387  };
388 
390  typedef typename __alloc_traits::template rebind_alloc<__node> __node_allocator;
391  typedef std::allocator_traits<__node_allocator> __node_traits;
392  typedef typename __node_traits::pointer __node_pointer;
393  typedef typename __node_traits::pointer __node_const_pointer;
394 
396  // fix me!
398 
399  typedef std::reverse_iterator<iterator> reverse_iterator;
400  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
401 
405  noexcept(std::is_nothrow_default_constructible<allocator_type>::value &&
406  std::is_nothrow_default_constructible<key_compare>::value &&
407  std::is_nothrow_copy_constructible<key_compare>::value)
408  : m_value_compare(key_compare()) {
409  }
410 
411  explicit directory(const key_compare& __comp)
412  noexcept(std::is_nothrow_default_constructible<allocator_type>::value &&
413  std::is_nothrow_copy_constructible<key_compare>::value);
414 
415  explicit directory(const allocator_type& __a);
416 
417  directory(const key_compare& __comp, const allocator_type& __a);
418 
419  template <class _InputIterator>
420  directory(_InputIterator __f, _InputIterator __l,
421  const key_compare& __comp = key_compare())
422  : m_value_compare(__comp) {
423  insert(__f, __l);
424  }
425 
426  template <class _InputIterator>
427  directory(_InputIterator __f, _InputIterator __l,
428  const key_compare& __comp, const allocator_type& __a)
429  : m_value_allocator(__a), m_value_compare(__comp) {
430  insert(__f, __l);
431  }
432 
433  template <class _InputIterator>
434  directory(_InputIterator __f, _InputIterator __l, const allocator_type& __a)
435  : directory(__f, __l, key_compare(), __a) {}
436 
437  directory(const directory &__d);
438 
439  directory(directory &&__d)
440  noexcept(std::is_nothrow_move_constructible<allocator_type>::value &&
441  std::is_nothrow_move_constructible<value_compare>::value);
442 
443  virtual ~directory() {
444  __destroy_node(m_root);
445  }
446 
448  if (this != &__d) {
449  clear();
450  m_value_compare = __d.value_comp();
451  __copy_assign_alloc(__d);
452  insert(__d.begin(), __d.end());
453  }
454  return *this;
455  }
456 
458  noexcept(__node_traits::propagate_on_container_move_assignment::value &&
459  std::is_nothrow_move_assignable<value_compare>::value &&
460  std::is_nothrow_move_assignable<allocator_type>::value) {
461 
462  __move_assign(__d, std::integral_constant<bool,
463  __node_traits::propagate_on_container_move_assignment::value>());
464  return *this;
465  }
466 
467 
473  key_compare key_comp() const {
474  return m_value_compare.key_comp;
475  }
476 
485  return value_compare(m_value_compare.key_comp);
486  }
487 
488  iterator begin() noexcept { return iterator(m_root, m_root); }
489  const_iterator begin() const noexcept { return const_iterator(m_root, m_root); }
490  iterator end() noexcept { return iterator(m_root); }
491  const_iterator end() const noexcept { return const_iterator(m_root); }
492 
493  reverse_iterator rbegin() noexcept {return reverse_iterator(end());}
494  const_reverse_iterator rbegin() const noexcept
495  {return const_reverse_iterator(end());}
496  reverse_iterator rend() noexcept {return reverse_iterator(begin());}
497  const_reverse_iterator rend() const noexcept
498  {return const_reverse_iterator(begin());}
499 
500  bool empty() const noexcept { return m_root == nullptr; }
501 
502  size_type size() const noexcept {
503  return m_root ? m_root->size() : 0;
504  }
505 
506  size_type max_size() const noexcept
507  {return __node_traits::max_size(m_value_allocator); }
508 
509  std::pair<iterator, bool>
510  insert(const std::vector<key_type> &keys, const mapped_type &val) {
511  assert(!keys.empty());
512  std::pair<iterator, bool> ret;
513  ret.second = false;
514  if (!m_root)
515  m_root = __create_node();
516  __node *node = m_root;
517  for (size_t i=0; i<keys.size(); ++i) {
518  __node child(value_type(i+1, keys[i]), m_value_compare, m_value_allocator);
519  auto child_iter = node->children.find(&child);
520  if (child_iter == node->children.end()) {
521  if (i == keys.size()-1) {
522  ret.second = true;
523  child.entry.set_value(val);
524  }
525  __node *new_node = __create_node(child);
526 
527  ret.first.push(node, node->insert_child(new_node).first);
528  node = new_node;
529  }
530  else {
531  ret.first.push(node, child_iter);
532  node = *child_iter;
533  }
534  }
535  return ret;
536  }
537 
538  template <class InputIterator>
539  void insert(const_iterator pos, InputIterator first, InputIterator last);
540 
541  template <class InputIterator>
542  void insert(InputIterator first, InputIterator last);
543 
544  void clear() noexcept {
545  if (m_root) {
546  __destroy_node(m_root);
547  m_root = nullptr;
548  }
549  }
550 
551  void swap(directory& __d)
553  (!__node_traits::propagate_on_container_swap::value ||
555 
556  iterator find(const std::vector<key_type> &keys) {
557  if (keys.empty() || !m_root)
558  return end();
559  iterator iter;
560  auto np = m_root;
561  for (auto key_iter = keys.begin(); key_iter != keys.end(); ++key_iter) {
562  __node child(value_type(0, *key_iter), m_value_compare, m_value_allocator);
563  auto child_iter = np->children.find(&child);
564  if (child_iter == np->children.end())
565  return end();
566  iter.push(np, child_iter);
567  np = *child_iter;
568  }
569  iter.push(np, np->children.begin());
570  return iter;
571  }
572 
573  const_iterator find(const std::vector<key_type> &keys) const {
574  if (keys.empty() || !m_root)
575  return end();
576  const_iterator iter;
577  auto np = m_root;
578  for (auto key_iter = keys.begin(); key_iter != keys.end(); ++key_iter) {
579  __node child(value_type(0, *key_iter), m_value_compare, m_value_allocator);
580  auto child_iter = np->children.find(&child);
581  if (child_iter == np->children.end())
582  return end();
583  iter.push(np, child_iter);
584  np = *child_iter;
585  }
586  iter.push(np, np->children.begin());
587  return iter;
588  }
589 
590  private:
591 
593  typename __node::pointer tmp = m_root;
594  m_root = nullptr;
595  return tmp;
596  }
597 
598  __node_pointer __create_node();
599 
600  __node_pointer __create_node(__node &other);
601 
602  __node_pointer __create_node(value_type &value);
603 
604  template <class ..._Args>
605  __node_pointer __create_node(_Args&& ...__args);
606 
607  void __destroy_node(__node *np);
608 
610  { __copy_assign_alloc(__d, std::integral_constant<bool,
611  __node_traits::propagate_on_container_copy_assignment::value>());}
612  void __copy_assign_alloc(const directory& __d, std::true_type)
613  { m_value_allocator = __d.m_value_allocator; }
614  void __copy_assign_alloc(const directory& __d, std::false_type) {}
615 
616 
618  noexcept(!__node_traits::propagate_on_container_move_assignment::value ||
619  std::is_nothrow_move_assignable<__node_allocator>::value) {
620  __move_assign_alloc(__d, std::integral_constant<bool,
621  __node_traits::propagate_on_container_move_assignment::value>());
622  }
623 
624  void __move_assign_alloc(directory& __d, std::true_type)
625  noexcept(std::is_nothrow_move_assignable<allocator_type>::value)
626  { m_value_allocator = std::move(__d.m_value_allocator); }
627 
628  void __move_assign_alloc(directory& __d, std::false_type) noexcept {}
629 
630  void __move_assign(directory& __d, std::true_type)
631  noexcept(std::is_nothrow_move_assignable<value_compare>::value &&
632  std::is_nothrow_move_assignable<allocator_type>::value) {
633  __destroy_node(m_root);
634  m_root = __d.release_root();
635  __move_assign_alloc(__d);
636  m_value_compare = std::move(m_value_compare);
637  }
638 
639  void __move_assign(directory& __d, std::false_type) {
640  if (m_value_allocator == __d.m_value_allocator)
641  __move_assign(__d, std::true_type());
642  else {
643  m_value_compare = std::move(m_value_compare);
644  clear();
645  insert(__d.begin(), __d.end());
646  __d.clear();
647  }
648  }
649 
650  typename __node::pointer m_root {};
651 
652  allocator_type m_value_allocator;
654  };
655 
656  template <class _Key, class _Tp, class _Compare, class _Allocator>
658  noexcept(std::is_nothrow_default_constructible<allocator_type>::value &&
659  std::is_nothrow_copy_constructible<key_compare>::value)
660  : m_value_compare(__comp) {
661  }
662 
663  template <class _Key, class _Tp, class _Compare, class _Allocator>
665  : m_value_allocator(__a), m_value_compare(key_compare()) {
666  }
667 
668  template <class _Key, class _Tp, class _Compare, class _Allocator>
670  const allocator_type& __a)
671  : m_value_allocator(__a), m_value_compare(__comp) {
672  }
673 
674  template <class _Key, class _Tp, class _Compare, class _Allocator>
676  : m_value_allocator(__alloc_traits::select_on_container_copy_construction(__d.m_value_allocator)),
677  m_value_compare(__d.value_comp()) {
678  insert(__d.begin(), __d.end());
679  }
680 
681  template <class _Key, class _Tp, class _Compare, class _Allocator>
683  noexcept(std::is_nothrow_move_constructible<allocator_type>::value &&
684  std::is_nothrow_move_constructible<value_compare>::value)
685  : m_root(__d.release_root()),
686  m_value_allocator(std::move(__d.m_value_allocator)),
687  m_value_compare(std::move(__d.m_value_compare)) {
688  }
689 
690 
691  template <class _Key, class _Tp, class _Compare, class _Allocator>
692  template <class _InputIterator>
693  void directory<_Key, _Tp, _Compare, _Allocator>::insert(const_iterator pos, _InputIterator __f, _InputIterator __l) {
694  __node_pointer parent;
695 
696  if (__f == __l)
697  return;
698 
699 
700  if (!pos) {
701  if (!m_root)
702  m_root = __create_node();
703  parent = m_root;
704  }
705  else
706  parent = pos.node();
707 
708  if (__f->level == 0 && parent->entry.level == 0)
709  ++__f;
710 
711  size_t previous_level = __f->level;
712  __node_pointer previous_node {};
713 
714  for ( ; __f != __l; ++__f) {
715 
716  if (__f->level < previous_level) {
717  parent = parent->parent;
718  if (parent == 0)
719  return;
720  }
721  else if (__f->level > previous_level && previous_node)
722  parent = previous_node;
723 
724  __node child(*__f, m_value_compare, m_value_allocator);
725  auto child_iter = parent->children.find(&child);
726  if (child_iter == parent->children.end()) {
727  __node *new_node = __create_node(child);
728  new_node->entry.level = parent->entry.level + 1;
729  parent->insert_child(new_node);
730  previous_node = new_node;
731  }
732  else {
733  (*child_iter)->entry.value = __f->value;
734  previous_node = *child_iter;
735  }
736 
737  previous_level = __f->level;
738  }
739  }
740 
741  template <class _Key, class _Tp, class _Compare, class _Allocator>
744  (!__node_traits::propagate_on_container_swap::value ||
746  {
747  using std::swap;
748  swap(m_root, __d.m_root);
749  swap(m_value_compare, __d.m_value_compare);
750  swap(m_value_allocator, __d.m_value_allocator);
751  }
752 
753 
754  template <class _Key, class _Tp, class _Compare, class _Allocator>
755  template <class _InputIterator>
756  void directory<_Key, _Tp, _Compare, _Allocator>::insert(_InputIterator __f, _InputIterator __l) {
757  insert(const_iterator(m_root, m_root), __f, __l);
758  }
759 
760  /*
761  * PRIVATE
762  */
763 
764  template <class _Key, class _Tp, class _Compare, class _Allocator>
767  __node_allocator __na(m_value_allocator);
769  = __node_traits::allocate(__na, 1);
770  __node_traits::construct(__na, node, m_value_compare, m_value_allocator);
771  return node;
772  }
773 
774 
775  template <class _Key, class _Tp, class _Compare, class _Allocator>
778  __node_allocator __na(m_value_allocator);
780  = __node_traits::allocate(__na, 1);
781  __node_traits::construct(__na, node, other);
782  return node;
783  }
784 
785  template <class _Key, class _Tp, class _Compare, class _Allocator>
786  typename directory<_Key, _Tp, _Compare, _Allocator>::__node_pointer
787  directory<_Key, _Tp, _Compare, _Allocator>::__create_node(typename directory<_Key, _Tp, _Compare, _Allocator>::value_type &value) {
788  __node_allocator __na(m_value_allocator);
789  typename directory<_Key, _Tp, _Compare, _Allocator>::__node_pointer node
790  = __node_traits::allocate(__na, 1);
791  __node_traits::construct(__na, node, value, m_value_compare, m_value_allocator);
792  return node;
793  }
794 
795  template <class _Key, class _Tp, class _Compare, class _Allocator>
796  template <class ..._Args>
797  typename directory<_Key, _Tp, _Compare, _Allocator>::__node_pointer
799  __node_allocator __na(m_value_allocator);
801  = __node_traits::allocate(__na, 1);
802  __node_traits::construct(__na, node, std::forward<_Args>(__args)...);
803  return node;
804  }
805 
806  template <class _Key, class _Tp, class _Compare, class _Allocator>
808  if (np) {
809  __node_allocator __na(m_value_allocator);
810  __node_traits::destroy(__na, np);
811  __node_traits::deallocate(__na, np, 1);
812  }
813  }
814 
815  template <class _Key, class _Tp, class _Compare, class _Allocator>
816  inline
819  {
820  return __x.size() == __y.size() && std::equal(__x.begin(), __x.end(), __y.begin());
821  }
822 
823  template <class _Key, class _Tp, class _Compare, class _Allocator>
824  inline
827  {
828  return !(__x == __y);
829  }
830 
831  template <class _Key, class _Tp, class _Compare, class _Allocator>
832  inline
833  bool
834  operator< (const directory<_Key, _Tp, _Compare, _Allocator>& __x,
836  {
837  auto iter_x = __x.begin();
838  auto iter_y = __y.begin();
839  while (iter_x != __x.end() && iter_y != __y.end()) {
840  if (*iter_x != *iter_y)
841  return *iter_x < *iter_y;
842  ++iter_x;
843  ++iter_y;
844  }
845  if (iter_x == __x.end())
846  return iter_y != __y.end();
847  return false;
848  }
849 
850  template <class _Key, class _Tp, class _Compare, class _Allocator>
851  inline
854  {
855  return __y < __x;
856  }
857 
858  template <class _Key, class _Tp, class _Compare, class _Allocator>
859  inline
862  {
863  return !(__x < __y);
864  }
865 
866  template <class _Key, class _Tp, class _Compare, class _Allocator>
867  inline
868  bool operator<=(const directory<_Key, _Tp, _Compare, _Allocator>& __x,
870  {
871  return !(__y < __x);
872  }
873 
874  template <class _Key, class _Tp, class _Compare, class _Allocator>
875  inline
878  noexcept(noexcept(__x.swap(__y)))
879  {
880  __x.swap(__y);
881  }
882 
884 
885 }
886 
887 #endif // Common_directory_h
__directory_node_internal(_Compare &comp, _Allocator &alloc)
Definition: directory.h:166
friend bool operator!=(const __directory_iterator &__x, const __directory_iterator &__y)
Definition: directory.h:286
__node::pointer release_root()
Definition: directory.h:592
reference operator*() const
Definition: directory.h:229
friend std::ostream & operator<<(std::ostream &os, const __directory_iterator &di)
Definition: directory.h:303
directory_entry(int level, _Key key, _Tp value)
Definition: directory.h:97
directory & operator=(const directory &__d)
Definition: directory.h:447
void push(__node_pointer np, typename __node::children_set::iterator iter)
Definition: directory.h:290
iterator begin() noexcept
Definition: directory.h:488
__alloc_traits::template rebind_alloc< __directory_node_internal > __node_allocator
Definition: directory.h:148
value_type & reference
Reference to value type.
Definition: directory.h:370
_Tp value
Definition: directory.h:107
__directory_node_internal(const __directory_node_internal &other)
Definition: directory.h:168
directory_entry()
Definition: directory.h:95
directory(_InputIterator __f, _InputIterator __l, const key_compare &__comp, const allocator_type &__a)
Definition: directory.h:427
std::allocator_traits< __node_allocator > __node_traits
Definition: directory.h:391
void __destroy_node(__node *np)
Definition: directory.h:807
bool operator()(const value_type &__x, const value_type &__y) const
Definition: directory.h:385
STL namespace.
void __copy_assign_alloc(const directory &__d, std::false_type)
Definition: directory.h:614
const_reverse_iterator rend() const noexcept
Definition: directory.h:497
__directory_iterator & operator++()
Definition: directory.h:235
_Allocator allocator_type
Memory allocator type.
Definition: directory.h:360
directory(_InputIterator __f, _InputIterator __l, const key_compare &__comp=key_compare())
Definition: directory.h:420
directory_entry< const key_type, mapped_type > value_type
Value type.
Definition: directory.h:354
std::allocator_traits< allocator_type > __alloc_traits
Definition: directory.h:362
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: directory.h:400
void swap(directory< _Key, _Tp, _Compare, _Allocator > &__x, directory< _Key, _Tp, _Compare, _Allocator > &__y) noexcept(noexcept(__x.swap(__y)))
Definition: directory.h:876
const value_type & const_reference
Const reference to value type.
Definition: directory.h:373
_Key key
Definition: directory.h:106
std::bidirectional_iterator_tag iterator_category
Definition: directory.h:214
const_iterator find(const std::vector< key_type > &keys) const
Definition: directory.h:573
std::pair< typename children_set::iterator, bool > insert_child(pointer child)
Definition: directory.h:179
decltype(swap(std::declval< _Tp & >(), std::declval< _Tp & >())) typedef type
Definition: directory.h:57
__node_pointer __create_node()
Definition: directory.h:766
std::pointer_traits< _NodePtr >::element_type __node
Definition: directory.h:211
key_compare key_comp() const
Returns a copy of the key comparison object from which the container was constructed.
Definition: directory.h:473
__alloc_traits::template rebind_alloc< __node > __node_allocator
Definition: directory.h:390
Directory container class.
Definition: directory.h:343
friend bool operator==(const __directory_iterator &__x, const __directory_iterator &__y)
Definition: directory.h:282
bool isset_value
Definition: directory.h:108
void clear() noexcept
Definition: directory.h:544
bool empty() const noexcept
Definition: directory.h:500
void __move_assign(directory &__d, std::false_type)
Definition: directory.h:639
__directory_node_internal * pointer
Definition: directory.h:145
void set_value(_Tp val)
Definition: directory.h:98
directory_entry(int level, _Key key)
Definition: directory.h:96
const_iterator end() const noexcept
Definition: directory.h:491
__alloc_traits::pointer pointer
Definition: directory.h:364
__alloc_traits::size_type size_type
Definition: directory.h:366
std::pair< iterator, bool > insert(const std::vector< key_type > &keys, const mapped_type &val)
Definition: directory.h:510
__directory_iterator(__node_pointer root, __node_pointer np)
Definition: directory.h:224
void __move_assign(directory &__d, std::true_type) noexcept(std::is_nothrow_move_assignable< value_compare >::value &&std::is_nothrow_move_assignable< allocator_type >::value)
Definition: directory.h:630
__alloc_traits::const_pointer const_pointer
Definition: directory.h:365
bool operator==(const directory_entry< _Key, _Tp > &lhs, const directory_entry< _Key, _Tp > &rhs)
Definition: directory.h:112
__alloc_traits::difference_type difference_type
Definition: directory.h:367
Definition: directory.h:93
reverse_iterator rend() noexcept
Definition: directory.h:496
bool operator!=(const directory_entry< _Key, _Tp > &lhs, const directory_entry< _Key, _Tp > &rhs)
Definition: directory.h:122
__nat swap(__any, __any)
std::reverse_iterator< iterator > reverse_iterator
Definition: directory.h:399
Hypertable definitions
friend std::ostream & operator<<(std::ostream &os, const directory_entry &de)
Definition: directory.h:99
bool operator>=(const directory< _Key, _Tp, _Compare, _Allocator > &__x, const directory< _Key, _Tp, _Compare, _Allocator > &__y)
Definition: directory.h:860
_Tp mapped_type
Mapped value type.
Definition: directory.h:351
__node_traits::pointer __node_pointer
Definition: directory.h:392
const_iterator begin() const noexcept
Definition: directory.h:489
value_compare m_value_compare
Definition: directory.h:653
bool operator()(const pointer __x, const pointer __y) const
Definition: directory.h:157
void __copy_assign_alloc(const directory &__d)
Definition: directory.h:609
std::pointer_traits< __node_pointer >::template rebind< value_type > pointer
Definition: directory.h:218
size_type max_size() const noexcept
Definition: directory.h:506
iterator find(const std::vector< key_type > &keys)
Definition: directory.h:556
bool equal(double a, double b)
Compare doubles that may have been serialized and unserialized.
allocator_type m_value_allocator
Definition: directory.h:652
__subdirectory_iterator(__node_pointer np, typename __node::children_set::iterator iter)
Definition: directory.h:314
__directory_iterator(__node_pointer root) noexcept
Definition: directory.h:222
void swap(directory &__d) noexcept(__is_nothrow_swappable< value_compare >::value &&(!__node_traits::propagate_on_container_swap::value||__is_nothrow_swappable< __node_allocator >::value))
Definition: directory.h:742
__directory_iterator operator++(int)
Definition: directory.h:257
directory(_InputIterator __f, _InputIterator __l, const allocator_type &__a)
Definition: directory.h:434
std::allocator_traits< _Allocator > __alloc_traits
Definition: directory.h:146
std::allocator_traits< __node_allocator > __node_traits
Definition: directory.h:149
__directory_node_internal(_Value value, _Compare &comp, _Allocator &alloc)
Definition: directory.h:171
Ordering relation on value_type.
Definition: directory.h:377
reverse_iterator rbegin() noexcept
Definition: directory.h:493
void __copy_assign_alloc(const directory &__d, std::true_type)
Definition: directory.h:612
std::vector< __subdirectory_iterator > __iters_
Definition: directory.h:331
iterator end() noexcept
Definition: directory.h:490
size_type size() const noexcept
Definition: directory.h:502
value_compare value_comp() const
Returns an object of type #value_compare constructed from the key comparison object.
Definition: directory.h:484
std::set< pointer, pointer_compare, _Allocator > children_set
Definition: directory.h:163
const_reverse_iterator rbegin() const noexcept
Definition: directory.h:494
size_t level
Definition: directory.h:105
_Key key_type
Key type.
Definition: directory.h:348
void __move_assign_alloc(directory &__d, std::true_type) noexcept(std::is_nothrow_move_assignable< allocator_type >::value)
Definition: directory.h:624
void __move_assign_alloc(directory &__d, std::false_type) noexcept
Definition: directory.h:628
__directory_iterator & operator--()
Definition: directory.h:261
bool operator>(const directory< _Key, _Tp, _Compare, _Allocator > &__x, const directory< _Key, _Tp, _Compare, _Allocator > &__y)
Definition: directory.h:852
__node_traits::pointer __node_const_pointer
Definition: directory.h:393
void __move_assign_alloc(directory &__d) noexcept(!__node_traits::propagate_on_container_move_assignment::value||std::is_nothrow_move_assignable< __node_allocator >::value)
Definition: directory.h:617
__directory_iterator & operator--(int)
Definition: directory.h:278
friend bool operator!=(const __subdirectory_iterator &__x, const __subdirectory_iterator &__y)
Definition: directory.h:324
directory & operator=(directory &&__d) noexcept(__node_traits::propagate_on_container_move_assignment::value &&std::is_nothrow_move_assignable< value_compare >::value &&std::is_nothrow_move_assignable< allocator_type >::value)
Definition: directory.h:457
__directory_node_internal< value_type, value_compare, allocator_type > __node
Definition: directory.h:389
friend bool operator==(const __subdirectory_iterator &__x, const __subdirectory_iterator &__y)
Definition: directory.h:320
directory() noexcept(std::is_nothrow_default_constructible< allocator_type >::value &&std::is_nothrow_default_constructible< key_compare >::value &&std::is_nothrow_copy_constructible< key_compare >::value)
Default constructor.
Definition: directory.h:404
_Compare key_compare
Key comparison type
Definition: directory.h:357
size_t size() const noexcept
Definition: directory.h:184