orbtree
orbtree.h
1 /* -*- C++ -*-
2  * orbtree.h -- generalized order statistic red-black tree implementation
3  * main interface
4  *
5  * Copyright 2019 Daniel Kondor <kondor.dani@gmail.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following disclaimer
15  * in the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of the nor the names of its
18  * contributors may be used to endorse or promote products derived from
19  * this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *
34  */
35 
36 
37 #ifndef ORBTREE_H
38 #define ORBTREE_H
39 
40 #include "orbtree_base.h"
41 #include <type_traits>
42 #include <limits>
43 #include <stdexcept>
44 #include <vector>
45 #include <math.h>
46 
47 /* constexpr if support only for c++17 or newer */
48 #if __cplusplus >= 201703L
49 #define CONSTEXPR constexpr
50 #else
51 #define CONSTEXPR
52 #endif
53 
54 
55 namespace orbtree {
56 
57  /* main class with public interface */
79  template<class NodeAllocator, class Compare, class NVFunc, bool multi, bool simple = false>
80  class orbtree : public orbtree_base<NodeAllocator, Compare, NVFunc, multi> {
81  protected:
83  typedef typename orbtree_base<NodeAllocator, Compare, NVFunc, multi>::KeyValue KeyValue;
84 
85  public:
86 /* typedefs */
89  typedef typename NodeAllocator::KeyValue::ValueType value_type;
91  typedef typename NodeAllocator::KeyValue::KeyType key_type;
93  typedef typename NodeAllocator::NVType NVType;
94  /* conditionally define mapped_type ?? */
95  typedef size_t size_type;
96  typedef size_t difference_type; /* note: unsigned difference_type not standard?
97  -- since iterators are InputIterators, only unsigned differences are possible */
98 
99 
100  explicit orbtree(const NVFunc& f_ = NVFunc(), const Compare& c_ = Compare())
101  : orbtree_base<NodeAllocator, Compare, NVFunc, multi>(f_,c_) {
102  if CONSTEXPR (simple) if(this->f.get_nr() != 1) {
103  throw std::runtime_error("For simple tree, weight function can only return one component!\n");
104  }
105  }
106  explicit orbtree(NVFunc&& f_,const Compare& c_ = Compare())
108  if CONSTEXPR (simple) if(this->f.get_nr() != 1) {
109  throw std::runtime_error("For simple tree, weight function can only return one component!\n");
110  }
111  }
112  template<class T>
113  explicit orbtree(const T& t, const Compare& c_ = Compare())
115  if CONSTEXPR (simple) if(this->f.get_nr() != 1) {
116  throw std::runtime_error("For simple tree, weight function can only return one component!\n");
117  }
118  }
119 
120 
121 
122 
123  /* iterators -- note: set should only have const iterators */
125  template<bool is_const>
126  struct iterator_base {
127  protected:
128  typedef typename NodeAllocator::KeyValue::ValueType value_base;
129  typedef typename std::conditional<is_const, const orbtree, orbtree>::type orbtree_t;
130  public:
131  /* typedefs */
132  typedef std::bidirectional_iterator_tag iterator_category;
133  /* note: value type is always const, value cannot be changed
134  * by dereferincing the iterator since rank function might depend on it
135  * need to call set_value() explicitely */
137 
145  typedef const value_base value_type;
146  typedef const value_base* pointer;
147  typedef const value_base& reference;
148 
149  friend class iterator_base<!is_const>;
150  friend class orbtree<NodeAllocator,Compare,NVFunc,multi,simple>;
151  protected:
152  orbtree_t& t; /* has to be const reference for const iterator */
153  NodeHandle n;
154  iterator_base() = delete;
155  /* create iterator (by orbtree class) */
156  iterator_base(orbtree_t& t_, NodeHandle n_):t(t_),n(n_) { }
157  /* convert const iterator to non-const -- protected, might be needed internally ? */
158  template<bool is_const_ = is_const>
159  explicit iterator_base(const iterator_base<true>& it, typename std::enable_if<!is_const_>::type* = 0)
160  :t(const_cast<orbtree>(it.t)),n(it.n) { }
161  public:
162 
163  /* any iterator can be copied from non-const iterator;
164  * this is not explicit so comparison operators can auto-convert */
165  iterator_base(const iterator_base<false>& it):t(it.t),n(it.n) { }
166  /* only const iterator can be copied from const iterator */
167  template<bool is_const_ = is_const>
168  iterator_base(const iterator_base<true>& it, typename std::enable_if<is_const_>::type* = 0 ):t(it.t),n(it.n) { }
169 
171 
178  reference operator * () {
179  if(n == NodeAllocator::Invalid) throw std::runtime_error("Attempt to dereference invalid orbtree::iterator!\n");
180  return t.get_node(n).get_key_value().keyvalue();
181  }
183  pointer operator -> () {
184  if(n == NodeAllocator::Invalid) throw std::runtime_error("Attempt to dereference invalid orbtree::iterator!\n");
185  return &(t.get_node(n).get_key_value().keyvalue());
186  }
188  template<bool is_const_ = is_const, class KeyValue_ = typename NodeAllocator::KeyValue>
189  typename std::enable_if<!is_const_>::type set_value(typename KeyValue_::MappedType&& v) {
190  t.update_value(n,std::move(v));
191  }
193  template<bool is_const_ = is_const, class KeyValue_ = typename NodeAllocator::KeyValue>
194  typename std::enable_if<!is_const_>::type set_value(typename KeyValue_::MappedType const& v) {
195  t.update_value(n,v);
196  }
197 
199  const key_type& key() const { return t.get_node(n).get_key_value().key(); }
200 
202 
204  template<bool is_const2> bool operator == (const iterator_base<is_const2>& i) const { return n == i.n; }
206 
208  template<bool is_const2> bool operator != (const iterator_base<is_const2>& i) const { return n != i.n; }
209 
211  iterator_base& operator ++() { n = t.next(n); return *this; }
213  iterator_base operator ++(int) { iterator_base<is_const> i(*this); n = t.next(n); return i; }
215  iterator_base& operator --() { n = t.previous(n); return *this; }
217  iterator_base operator --(int) { iterator_base<is_const> i(*this); n = t.previous(n); return i; }
218  };
219 
221  typedef iterator_base<true> const_iterator;
223  typedef typename std::conditional<NodeAllocator::KeyValue::keyonly, iterator_base<true>, iterator_base<false> >::type iterator;
224 
225  iterator begin() { return iterator(*this,this->first()); }
226  const_iterator begin() const { return const_iterator(*this,this->first()); }
227  const_iterator cbegin() const { return const_iterator(*this,this->first()); }
228 
229  iterator end() { return iterator(*this,this->nil()); }
230  const_iterator end() const { return const_iterator(*this,this->nil()); }
231  const_iterator cend() const { return const_iterator(*this,this->nil()); }
232 
233  bool empty() const { return this->size1 == 0; }
234  size_t size() const { return this->size1; }
235  constexpr size_t max_size() const {
237  return NodeAllocator::max_nodes ? NodeAllocator::max_nodes : std::numeric_limits<size_t>::max();
238  }
239 
240 /* 2. add / remove */
241  //~ void clear(); -- defined in orbtree_base already, no need to add functionality
242 
243  /* for insert, we need to distinguish between map and multimap
244  * create a return typedef which is either an iterator or a pair */
246  typedef typename std::conditional<multi, iterator, std::pair<iterator, bool> >::type insert_type;
247 
248  protected:
249  template<bool multi_ = multi>
250  typename std::enable_if<multi_,insert_type>::type insert_helper(const value_type& v) {
252  }
253  template<bool multi_ = multi>
254  typename std::enable_if<!multi_,insert_type>::type insert_helper(const value_type& v) {
256  return std::pair<iterator,bool>(iterator(*this,x.first),x.second);
257  }
258  template<bool multi_ = multi>
259  typename std::enable_if<multi_,insert_type>::type insert_helper(value_type&& v) {
261  }
262  template<bool multi_ = multi>
263  typename std::enable_if<!multi_,insert_type>::type insert_helper(value_type&& v) {
265  return std::pair<iterator,bool>(iterator(*this,x.first),x.second);
266  }
267 
268 
269  template<class... Args, bool multi_ = multi>
270  typename std::enable_if<multi_,insert_type>::type emplace_helper(Args&... args) {
271  return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::emplace(std::forward<Args...>(args...)).first);
272  }
273  template<class... Args, bool multi_ = multi>
274  typename std::enable_if<!multi_,insert_type>::type emplace_helper(Args&... args) {
275  auto x = orbtree_base<NodeAllocator, Compare, NVFunc, multi>::emplace(std::forward<Args...>(args...));
276  return std::pair<iterator,bool>(iterator(*this,x.first),x.second);
277  }
278 
279 
280  public:
281 
292  insert_type insert(const value_type& v) { return insert_helper(v); }
294  insert_type insert(value_type&& v) { return insert_helper(std::move(v)); }
295 
296 
297 
313  iterator insert(const_iterator hint, const value_type& v) {
314  if(hint.n == this->nil()) return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::insert(v).first);
316  }
318  iterator insert(const_iterator hint, value_type&& v) {
319  if(hint.n == this->nil()) return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::insert(std::move(v)).first);
320  else return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::insert(hint.n,std::move(v)));
321  }
322 
323 
325  template<class InputIt> void insert(InputIt first, InputIt last) {
326  for(;first!=last;++first) orbtree::insert(*first);
327  }
328 
330  template<class... Args> insert_type emplace(Args&&... args) { return emplace_helper(std::forward<Args...>(args...)); }
332  template<class... Args> iterator emplace_hint(const_iterator hint, Args&&... args) {
333  if(hint.n == this->nil()) return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::emplace(std::forward<Args...>(args...)).first);
334  else return iterator(*this, orbtree_base<NodeAllocator, Compare, NVFunc, multi>::emplace_hint(hint, std::forward<Args...>(args...)));
335  }
336 
337 
338  //~ iterator erase(iterator pos) { return iterator(*this,orbtree_base<NodeAllocator, Compare, NVFunc, multi>::erase(pos.n)); }
340  iterator erase(const_iterator pos) { return iterator(*this,orbtree_base<NodeAllocator, Compare, NVFunc, multi>::erase(pos.n)); }
342  iterator erase(const_iterator first, const_iterator last) {
343  if(first == last) return iterator(*this,first.n);
344  iterator x = erase(first);
345  while(x != last) x = erase(x);
346  return x;
347  }
348 
350  size_t erase(const key_type& k) {
351  size_t r = 0;
353  n != this->nil() && n != this->Invalid && this->compare_key_equals(n,k);
355  return r;
356  }
357 
359  size_t count(const key_type& k) const {
360  size_t r = 0;
362  n != this->nil() && n != this->Invalid && this->compare_key_equals(n,k); n = this->next(n)) r++;
363  return r;
364  }
366  template<class K>
367  size_t count(const K& k) const {
368  size_t r = 0;
370  n != this->nil() && n != this->Invalid && this->compare_key_equals(n,k); n = this->next(n)) r++;
371  return r;
372  }
373 
374 /* 3. search based on key */
375 
376 
385  iterator find(const key_type& k) {
387  }
390  const_iterator find(const key_type& k) const {
392  }
395  template<class K> iterator find(const K& k) {
397  }
402  template<class K> const_iterator find(const K& k) const {
404  }
405 
406 
408  iterator lower_bound(const key_type& k) {
410  }
412  const_iterator lower_bound(const key_type& k) const {
414  }
416  template<class K> iterator lower_bound(const K& k) {
418  }
420  template<class K> const_iterator lower_bound(const K& k) const {
422  }
424  iterator upper_bound(const key_type& k) {
426  }
428  const_iterator upper_bound(const key_type& k) const {
430  }
432  template<class K> iterator upper_bound(const K& k) {
434  }
436  template<class K> const_iterator upper_bound(const K& k) const {
438  }
439 
441  std::pair<iterator,iterator> equal_range(const key_type& k) {
442  return std::pair<iterator,iterator>(lower_bound(k),upper_bound(k));
443  }
445  std::pair<const_iterator,const_iterator> equal_range(const key_type& k) const {
446  return std::pair<const_iterator,const_iterator>(lower_bound(k),upper_bound(k));
447  }
449  template<class K> std::pair<iterator,iterator> equal_range(const K& k) {
450  return std::pair<iterator,iterator>(lower_bound(k),upper_bound(k));
451  }
453  template<class K> std::pair<const_iterator,const_iterator> equal_range(const K& k) const {
454  return std::pair<const_iterator,const_iterator>(lower_bound(k),upper_bound(k));
455  }
456 
458  bool contains(const key_type& k) const {
460  }
462  template<class K> bool contains(const K& k) const {
464  }
465 
466 
467  public:
475  template<bool simple_ = simple>
476  void get_sum_node(const_iterator it, typename std::enable_if<!simple_,NVType*>::type res) const {
477  if(it == cend()) this->get_norm_fv(res);
478  this->get_sum_fv_node(it.n,res);
479  }
487  template<bool simple_ = simple>
488  NVType get_sum_node(typename std::enable_if<simple_,const_iterator>::type it) const {
489  NVType res;
490  if(it == cend()) this->get_norm_fv(&res);
491  this->get_sum_fv_node(it.n,&res);
492  return res;
493  }
494 
495 
502  template<bool simple_ = simple>
503  void get_sum(const key_type& k, typename std::enable_if<!simple_,NVType*>::type res) const {
504  auto it = lower_bound(k);
505  get_sum_node(it,res);
506  }
513  template<bool simple_ = simple>
514  NVType get_sum(typename std::enable_if<simple_,const key_type&>::type k) const {
515  auto it = lower_bound(k);
516  return get_sum_node(it);
517  }
518 
525  template<class K, bool simple_ = simple>
526  void get_sum(const K& k, typename std::enable_if<!simple_,NVType*>::type res) const {
527  auto it = lower_bound(k);
528  get_sum_node(it,res);
529  }
536  template<class K, bool simple_ = simple>
537  NVType get_sum(typename std::enable_if<simple_,const K&>::type k) const {
538  auto it = lower_bound(k);
539  return get_sum_node(it);
540  }
541 
543  template<bool simple_ = simple>
544  void get_norm(typename std::enable_if<!simple_,NVType*>::type res) const { this->get_norm_fv(res); }
546  template<bool simple_ = simple> NVType get_norm(typename std::enable_if<simple_,void*>::type k = 0) const {
547  NVType res;
548  this->get_norm_fv(&res);
549  return res;
550  }
551 
552 
553  };
554 
555 
563  template<class NVFunc>
566  typedef typename NVFunc::result_type result_type;
568 
572  constexpr unsigned int get_nr() const { return 1; }
574 
581  void operator ()(const typename NVFunc::argument_type& node_value, result_type* res) const {
582  *res = f(node_value);
583  }
584  NVFunc f;
587  explicit NVFunc_Adapter_Simple(const NVFunc& f_):f(f_) { }
588  explicit NVFunc_Adapter_Simple(NVFunc&& f_):f(f_) { }
589  template<class T>
590  explicit NVFunc_Adapter_Simple(const T& t):f(t) { }
591  };
592 
593 
594  /* basic classes */
595 
596  /* general set and multiset -- needs to be given a node value type and function */
597  /* function has to have a defined return type */
608  template<class Key, class NVFunc, class Compare = std::less<Key> >
609  using orbset = orbtree< NodeAllocatorPtr< KeyOnly<Key>, typename NVFunc::result_type >, Compare, NVFunc, false >;
610 
622  template<class Key, class NVFunc, class Compare = std::less<Key> >
623  using simple_set = orbtree< NodeAllocatorPtr< KeyOnly<Key>, typename NVFunc::result_type, true >,
624  Compare, NVFunc_Adapter_Simple<NVFunc>, false, true >;
625 
626 
637  template<class Key, class NVFunc, class Compare = std::less<Key> >
638  using orbmultiset = orbtree< NodeAllocatorPtr< KeyOnly<Key>, typename NVFunc::result_type >, Compare, NVFunc, true >;
639 
651  template<class Key, class NVFunc, class Compare = std::less<Key> >
652  using simple_multiset = orbtree< NodeAllocatorPtr< KeyOnly<Key>, typename NVFunc::result_type, true >,
653  Compare, NVFunc_Adapter_Simple<NVFunc>, true, true >;
654 
655 
681  template<class Key, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
682  using orbsetC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, typename NVFunc::result_type, IndexType >, Compare, NVFunc, false >;
683 
711  template<class Key, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
712  using simple_setC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, typename NVFunc::result_type, IndexType >,
713  Compare, NVFunc_Adapter_Simple<NVFunc>, false, true >;
714 
715 
716 
742  template<class Key, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
743  using orbmultisetC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, typename NVFunc::result_type, IndexType >, Compare, NVFunc, true >;
744 
772  template<class Key, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
773  using simple_multisetC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, typename NVFunc::result_type, IndexType >,
774  Compare, NVFunc_Adapter_Simple<NVFunc>, true, true >;
775 
776 
777  /* more specialized version: order statistic set / multiset with compact nodes (i.e. calculates ranks, either 32-bit or 64-bit) */
779  template<class KeyValueType, class NVType = uint32_t> struct RankFunc {
780  static_assert(std::is_integral<NVType>::value, "rank variable must be integral!\n");
782  typedef KeyValueType argument_type;
784  NVType operator ()(const KeyValueType& k) const { return (NVType)1; }
785  typedef NVType result_type;
786  };
787 
788 
790 
792  template<class NVFunc>
794  NVFunc f;
796  const std::vector<typename NVFunc::ParType> pars;
798  typedef typename NVFunc::result_type result_type;
800  unsigned int get_nr() const { return pars.size(); }
802  void operator ()(const typename NVFunc::argument_type& node_value, result_type* res) const {
803  for(size_t i=0;i<pars.size();i++) res[i] = f(node_value,pars[i]);
804  }
805  NVFunc_Adapter_Vec() = delete; /* need parameter vector at least */
807  explicit NVFunc_Adapter_Vec(const std::vector<typename NVFunc::ParType>& pars_, const NVFunc& f_ = NVFunc()):f(f_),pars(pars_) { }
809  explicit NVFunc_Adapter_Vec(std::vector<typename NVFunc::ParType>&& pars_, const NVFunc& f_ = NVFunc()):f(f_),pars(std::move(pars_)) { }
811  explicit NVFunc_Adapter_Vec(const std::vector<typename NVFunc::ParType>& pars_, NVFunc&& f_):f(std::move(f_)),pars(pars_) { }
813  explicit NVFunc_Adapter_Vec(std::vector<typename NVFunc::ParType>&& pars_, NVFunc&& f_):f(std::move(f_)),pars(std::move(pars_)) { }
814  };
815 
816 
818  template<class KeyType> struct NVPower {
820  double operator () (const KeyType& k, double a) const {
821  double x = (double)k;
822  return pow(x,a);
823  }
825  typedef double result_type;
827  typedef KeyType argument_type;
829  typedef double ParType;
830  };
831 
833  template<class KeyType> struct NVPowerMulti {
835  double operator () (const KeyType& k, double a) const {
836  double x = (double)(k.first);
837  double n = (double)(k.second);
838  return n*pow(x,a);
839  }
841  typedef double result_type;
843  typedef KeyType argument_type;
845  typedef double ParType;
846  };
847 
848  template<class KeyType> using NVPower2 = NVFunc_Adapter_Vec<NVPower<KeyType> >;
849  template<class KeyType> using NVPowerMulti2 = NVFunc_Adapter_Vec<NVPowerMulti<KeyType> >;
850 
859  template<class Key, class NVType = uint32_t, class Compare = std::less<Key> >
860  using rankset = orbtree< NodeAllocatorPtr< KeyOnly<Key>, NVType, true >, Compare,
862 
870  template<class Key, class NVType = uint32_t, class Compare = std::less<Key> >
871  using rankmultiset = orbtree< NodeAllocatorPtr< KeyOnly<Key>, NVType, true >, Compare,
872  NVFunc_Adapter_Simple<RankFunc<Key, NVType> >, true, true >;
873 
888  template<class Key, class NVType = uint32_t, class IndexType = uint32_t, class Compare = std::less<Key> >
889  using ranksetC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, NVType, IndexType >, Compare,
890  NVFunc_Adapter_Simple<RankFunc<Key, NVType> >, false, true >;
891 
906  template<class Key, class NVType = uint32_t, class IndexType = uint32_t, class Compare = std::less<Key> >
907  using rankmultisetC = orbtree< NodeAllocatorCompact< KeyOnly<Key>, NVType, IndexType >, Compare,
908  NVFunc_Adapter_Simple<RankFunc<Key, NVType> >, true, true >;
909 
910 
911  /* map types -- extra step in adding accessor functions (only for map, multimap does not have them)
912  * note: this definition does not explicitely require KeyValue to have value, but the extra functions rely on Value being present
913  *
914  * note: only const values are supported since modifying the value might modify the rank function as well */
928  template<class NodeAllocator, class Compare, class NVFunc, bool simple = false>
929  class orbtreemap : public orbtree<NodeAllocator, Compare, NVFunc, false, simple> {
930  protected:
933 
934  public:
935  /* typedefs */
943  typedef typename NodeAllocator::KeyValue::MappedType mapped_type;
944 
945  explicit orbtreemap(const NVFunc& f_ = NVFunc(), const Compare& c_ = Compare()) :
946  orbtree<NodeAllocator, Compare, NVFunc, false, simple>(f_,c_) { }
947  explicit orbtreemap(NVFunc&& f_,const Compare& c_ = Compare()) : orbtree<NodeAllocator, Compare, NVFunc, false, simple>(f_,c_) { }
948  template <class T>
949  explicit orbtreemap(const T& t, const Compare& c_ = Compare()) : orbtree<NodeAllocator, Compare, NVFunc, false, simple>(t,c_) { }
950 
952 
956  const mapped_type& at(const key_type& k) const {
958  if(n == this->nil()) throw std::out_of_range("orbtreemap::at(): key not present in map!\n");
959  return get_node(n).get_key_value().value();
960  }
962 
966  template<class K> const mapped_type& at(const K& k) const {
968  if(n == this->nil()) throw std::out_of_range("orbtreemap::at(): key not present in map!\n");
969  return get_node(n).get_key_value().value();
970  }
971 
973 
977  const mapped_type& operator[](const key_type& k) {
979  if(n == this->nil()) n = orbtree_base<NodeAllocator, Compare, NVFunc, false>::insert(value_type(k,mapped_type()));
980  return get_node(n).get_key_value().value();
981  }
982 
987  bool set_value(const key_type& k, const mapped_type& v) {
988  std::pair<iterator,bool> tmp = orbtree<NodeAllocator, Compare, NVFunc, false, simple>::insert(value_type(k,v));
989  if(tmp.second == false) tmp.first.set_value(v);
990  return tmp.second;
991  }
996  bool set_value(key_type&& k, const mapped_type& v) {
997  std::pair<iterator,bool> tmp = orbtree<NodeAllocator, Compare, NVFunc, false, simple>::insert(value_type(std::move(k),v));
998  if(tmp.second == false) tmp.first.set_value(v);
999  return tmp.second;
1000  }
1005  bool set_value(const key_type& k, mapped_type&& v) {
1009  return true;
1010  }
1011  it.set_value(std::move(v));
1012  return false;
1013  }
1018  bool set_value(key_type&& k, mapped_type&& v) {
1021  orbtree<NodeAllocator, Compare, NVFunc, false, simple>::insert(value_type(std::move(k),std::move(v)));
1022  return true;
1023  }
1024  it.set_value(std::move(v));
1025  return false;
1026  }
1027 
1029  void update_value(const key_type& k, const mapped_type& v) {
1031  if(n == this->nil()) throw std::out_of_range("orbtreemap::at(): key not present in map!\n");
1033  }
1035  void update_value(const key_type& k, mapped_type&& v) {
1037  if(n == this->nil()) throw std::out_of_range("orbtreemap::at(): key not present in map!\n");
1039  }
1040  };
1041 
1053  template<class Key, class Value, class NVFunc, class Compare = std::less<Key> >
1054  using orbmap = orbtreemap< NodeAllocatorPtr< KeyValue<Key,Value>, typename NVFunc::result_type >, Compare, NVFunc >;
1055 
1068  template<class Key, class Value, class NVFunc, class Compare = std::less<Key> >
1069  using simple_map = orbtreemap< NodeAllocatorPtr< KeyValue<Key,Value>, typename NVFunc::result_type, true >,
1070  Compare, NVFunc_Adapter_Simple<NVFunc>, true >;
1071 
1072 
1084  template<class Key, class Value, class NVFunc, class Compare = std::less<Key> >
1085  using orbmultimap = orbtree< NodeAllocatorPtr< KeyValue<Key,Value>, typename NVFunc::result_type >, Compare, NVFunc, true >;
1086 
1099  template<class Key, class Value, class NVFunc, class Compare = std::less<Key> >
1100  using simple_multimap = orbtree< NodeAllocatorPtr< KeyValue<Key,Value>, typename NVFunc::result_type, true >,
1101  Compare, NVFunc_Adapter_Simple<NVFunc>, true, true>;
1102 
1103 
1124  template<class Key, class Value, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
1125  using orbmapC = orbtreemap< NodeAllocatorCompact< KeyValue<Key,Value>, typename NVFunc::result_type, IndexType>, Compare, NVFunc >;
1126 
1148  template<class Key, class Value, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
1149  using simple_mapC = orbtreemap< NodeAllocatorCompact< KeyValue<Key,Value>, typename NVFunc::result_type, IndexType>,
1150  Compare, NVFunc_Adapter_Simple<NVFunc>, true >;
1151 
1152 
1172  template<class Key, class Value, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
1173  using orbmultimapC = orbtree< NodeAllocatorCompact< KeyValue<Key,Value>, typename NVFunc::result_type, IndexType>, Compare, NVFunc, true >;
1174 
1196  template<class Key, class Value, class NVFunc, class IndexType = uint32_t, class Compare = std::less<Key> >
1197  using simple_multimapC = orbtree< NodeAllocatorCompact< KeyValue<Key,Value>, typename NVFunc::result_type, IndexType>,
1198  Compare, NVFunc_Adapter_Simple<NVFunc>, true, true >;
1199 
1200 
1210  template<class Key, class Value, class NVType, class Compare = std::less<Key> >
1211  using rankmap = orbtreemap< NodeAllocatorPtr< KeyValue<Key,Value>, NVType, true >, Compare,
1213 
1223  template<class Key, class Value, class NVType, class Compare = std::less<Key> >
1224  using rankmultimap = orbtree< NodeAllocatorPtr< KeyValue<Key,Value>, NVType, true >, Compare,
1225  NVFunc_Adapter_Simple< RankFunc<NVType,KeyValue<Key,Value> > >, true, true >;
1226 
1245  template<class Key, class Value, class NVType, class IndexType = uint32_t, class Compare = std::less<Key> >
1246  using rankmapC = orbtreemap< NodeAllocatorCompact< KeyValue<Key,Value>, NVType, IndexType >, Compare,
1247  NVFunc_Adapter_Simple< RankFunc<NVType,KeyValue<Key,Value> > >, true >;
1248 
1267  template<class Key, class Value, class NVType, class IndexType = uint32_t, class Compare = std::less<Key> >
1268  using rankmultimapC = orbtree< NodeAllocatorCompact< KeyValue<Key,Value>, NVType, IndexType >, Compare,
1269  NVFunc_Adapter_Simple< RankFunc<NVType,KeyValue<Key,Value> > >, true, true >;
1270 
1271 }
1272 
1273 #undef CONSTEXPR
1274 
1275 #endif
1276 
void update_value(const key_type &k, mapped_type &&v)
update the value of an existing element – throws exception if the key does not exist ...
Definition: orbtree.h:1035
const_iterator find(const key_type &k) const
iteraror that allows the modification of the stored value (for maps) find(const key_type& k) ...
Definition: orbtree.h:390
NVFunc_Adapter_Simple(const NVFunc &f_)
Create a new instance storing the given function.
Definition: orbtree.h:587
pointer operator->()
read-only access to values
Definition: orbtree.h:183
void insert(InputIt first, InputIt last)
insert all elements in the range [first,last)
Definition: orbtree.h:325
void get_sum_node(const_iterator it, typename std::enable_if<!simple_, NVType *>::type res) const
Calculate partial sum of the weights of nodes that come before the one pointed to by it...
Definition: orbtree.h:476
NodeHandle nil() const
handle of nil sentinel
Definition: orbtree_base.h:110
iterator lower_bound(const K &k)
return an iterator to the first element with key not less than k
Definition: orbtree.h:416
double ParType
exponent is double
Definition: orbtree.h:845
Order statistic multimap with compact storage, calculates the rank of elements. See orbtree for descr...
const_iterator end() const
get the past-the-end iterator
Definition: orbtree.h:230
void get_sum(const key_type &k, typename std::enable_if<!simple_, NVType *>::type res) const
Calculate partial sum of weights for keys that come before k.
Definition: orbtree.h:503
std::pair< const_iterator, const_iterator > equal_range(const K &k) const
return a pair of iterators corresponding to the range of all elements with keys that compares equal t...
Definition: orbtree.h:453
NVType get_sum(typename std::enable_if< simple_, const K &>::type k) const
Calculate partial sum of weights for keys that come before k.
Definition: orbtree.h:537
void update_value(NodeHandle n, typename KeyValue_::MappedType const &v)
update value in a node – only if this is a map; update sum recursively based on it as well ...
Definition: orbtree_base.h:273
bool set_value(const key_type &k, const mapped_type &v)
set value associated with the given key or insert new element
Definition: orbtree.h:987
iterator find(const key_type &k)
Find an element with the given key and return an iterator to it.
Definition: orbtree.h:385
KeyType argument_type
function argument is the key stored in the tree
Definition: orbtree.h:827
double ParType
exponent is double
Definition: orbtree.h:829
constexpr unsigned int get_nr() const
Dimension of result. In case of a simple function, it is one.
Definition: orbtree.h:572
bool operator==(const iterator_base< is_const2 > &i) const
compare iterators
Definition: orbtree.h:204
std::enable_if<!is_const_ >::type set_value(typename KeyValue_::MappedType const &v)
change value stored in map or multimap
Definition: orbtree.h:194
NodeAllocator::KeyValue::KeyType key_type
Key type of nodes that determines ordering.
Definition: orbtree.h:91
size_t count(const key_type &k) const
count number of elements with key
Definition: orbtree.h:359
Map implementation with compact storage. Simple version for weight functions that return one componen...
NVFunc_Adapter_Vec(std::vector< typename NVFunc::ParType > &&pars_, const NVFunc &f_=NVFunc())
this adapter can only be constructed with a parameter vector
Definition: orbtree.h:809
size_t count(const K &k) const
count the number of elements whose key compares equal to k
Definition: orbtree.h:367
const_iterator lower_bound(const K &k) const
return an iterator to the first element with key not less than k
Definition: orbtree.h:420
iterator upper_bound(const key_type &k)
return an iterator to the first element with key greater than k
Definition: orbtree.h:424
bool contains(const key_type &k) const
returns if an element with key equivalent to k exists in this tree
Definition: orbtree.h:458
Adapter for functions that return only one result. This class also describes the interface expected f...
Definition: orbtree.h:564
bool operator!=(const iterator_base< is_const2 > &i) const
compare iterators
Definition: orbtree.h:208
General map implementation. See orbtree and orbtreemap for description of members.
std::pair< iterator, iterator > equal_range(const K &k)
return a pair of iterators corresponding to the range of all elements with keys that compares equal t...
Definition: orbtree.h:449
NVFunc_Adapter_Vec(const std::vector< typename NVFunc::ParType > &pars_, const NVFunc &f_=NVFunc())
this adapter can only be constructed with a parameter vector
Definition: orbtree.h:807
iterator lower_bound(const key_type &k)
return an iterator to the first element with key not less than k
Definition: orbtree.h:408
iterator_base & operator++()
increment: move to the next stored node
Definition: orbtree.h:211
void get_norm(typename std::enable_if<!simple_, NVType *>::type res) const
Calculate normalization, i.e. sum of all weights. Equivalent to get_sum(cend(),res).
Definition: orbtree.h:544
NodeAllocator::NVType NVType
Type of values associated by nodes (calculated by NVFunc)
Definition: orbtree.h:93
STL namespace.
bool set_value(key_type &&k, mapped_type &&v)
set value associated with the given key or insert new element
Definition: orbtree.h:1018
iterator find(const K &k)
iteraror that allows the modification of the stored value (for maps) find(const key_type& k) ...
Definition: orbtree.h:395
bool set_value(const key_type &k, mapped_type &&v)
set value associated with the given key or insert new element
Definition: orbtree.h:1005
iterator emplace_hint(const_iterator hint, Args &&... args)
construct new element in-place, using the given hint in a same way as insert() with a hint ...
Definition: orbtree.h:332
Generalized order statistic tree main interface. It is recommended to use the templates orbset...
Definition: orbtree.h:80
std::pair< NodeHandle, bool > emplace(T &&... t)
Construct new element in place.
const_iterator begin() const
get an iterator to the beginning (node with the lowest key value)
Definition: orbtree.h:226
General multiset, i.e. storing a collection of elements allowing duplicates. See orbtree for descript...
void get_sum_fv_node(NodeHandle x, NVType *res) const
get the generalized rank for a given node, i.e. the sum of NVFunv for all nodes before it in order ...
Definition: orbtree_base.h:419
NVFunc::result_type result_type
Type of the result of this function.
Definition: orbtree.h:566
KeyType argument_type
function argument is the key stored in the tree
Definition: orbtree.h:843
iterator_base & operator--()
decrement: move to the previous stored node
Definition: orbtree.h:215
Specialized set with compact storage. See orbtree for description of members.
const std::vector< typename NVFunc::ParType > pars
copy of the parameters
Definition: orbtree.h:796
void update_value(const key_type &k, const mapped_type &v)
update the value of an existing element – throws exception if the key does not exist ...
Definition: orbtree.h:1029
insert_type insert(const value_type &v)
Insert new element.
Definition: orbtree.h:292
General map implementation. Simple version for weight functions that return one component (i...
auto find(const K &key) const -> NodeHandle
find any node with the given key
Definition: orbtree_base.h:328
std::enable_if<!is_const_ >::type set_value(typename KeyValue_::MappedType &&v)
change value stored in map or multimap
Definition: orbtree.h:189
Specialized set with compact storage. Simple version for weight functions that return one component (...
const_iterator cbegin() const
get an iterator to the beginning (node with the lowest key value)
Definition: orbtree.h:227
NodeHandle last() const
get last node (or nil)
Definition: orbtree_base.h:475
General multiset, i.e. storing a collection of elements allowing duplicates. Simple version for weigh...
NVType get_sum_node(typename std::enable_if< simple_, const_iterator >::type it) const
Calculate partial sum of nodes that come before the one pointed to by it.
Definition: orbtree.h:488
iterator erase(const_iterator first, const_iterator last)
erase elements in the range [first,last); returns last
Definition: orbtree.h:342
iterator_base< true > const_iterator
iterator that does not allow modification
Definition: orbtree.h:221
Multimap implementation with compact storage. See orbtree for description of members.
const mapped_type & at(const key_type &k) const
Access mapped value for a given key, throws an exception if key is not found.
Definition: orbtree.h:956
const mapped_type & at(const K &k) const
Access mapped value for a key that compares equal to k, throws an exception if not such key is found...
Definition: orbtree.h:966
bool compare_key_equals(NodeHandle n, const KeyType &k) const
helper for erase to compare elements
Definition: orbtree_base.h:217
const mapped_type & operator[](const key_type &k)
Access mapped value for a given key, inserts a new element with the default value if not found...
Definition: orbtree.h:977
bool contains(const K &k) const
returns if an element with key equivalent to k exists in this tree
Definition: orbtree.h:462
iterator end()
get an iterator to the beginning (node with the lowest key value)
Definition: orbtree.h:229
size_t erase(const key_type &k)
erase all elements with the given key; returns the number of elements erased
Definition: orbtree.h:350
General multimap implementation (i.e. map allowing duplicate keys). Simple version for weight functio...
simple function to use for standard order statistic trees; returns 1 for any key, so sum of values ca...
Definition: orbtree.h:779
const_iterator lower_bound(const key_type &k) const
return an iterator to the first element with key not less than k
Definition: orbtree.h:412
NVFunc_Adapter_Vec(std::vector< typename NVFunc::ParType > &&pars_, NVFunc &&f_)
this adapter can only be constructed with a parameter vector
Definition: orbtree.h:813
NVFunc_Adapter_Vec(const std::vector< typename NVFunc::ParType > &pars_, NVFunc &&f_)
this adapter can only be constructed with a parameter vector
Definition: orbtree.h:811
NVFunc::result_type result_type
definition of result for the tree class to use
Definition: orbtree.h:798
size_t size1
keep track of the number of inserted elements
Definition: orbtree_base.h:85
std::conditional< NodeAllocator::KeyValue::keyonly, iterator_base< true >, iterator_base< false > >::type iterator
iteraror that allows the modification of the stored value (for maps)
Definition: orbtree.h:223
Order statistic set, calculates the rank of elements, compact version. See orbtree for description of...
Iterators.
Definition: orbtree.h:126
NodeHandle erase(NodeHandle n)
remove the given node – return the next node (i.e. next(n) before deleting n)
Definition: orbtree_base.h:828
std::pair< NodeHandle, bool > insert(ValueType &&kv)
Insert new element.
Definition: orbtree_base.h:687
bool empty() const
get the past-the-end iterator
Definition: orbtree.h:233
Map implementation with compact storage. See orbtree and orbtreemap for description of members...
std::pair< const_iterator, const_iterator > equal_range(const key_type &k) const
return a pair of iterators corresponding to the range of all elements with key equal to k ...
Definition: orbtree.h:445
KeyValueType argument_type
type of argument this function takes; same as the key / value type supplied
Definition: orbtree.h:780
const_iterator find(const K &k) const
iteraror that allows the modification of the stored value (for maps) find(const key_type& k) ...
Definition: orbtree.h:402
NodeAllocator::KeyValue::ValueType value_type
Values stored in this tree. Either the key (for sets) or an std::pair or orbtree::trivial_pair of key...
Definition: orbtree.h:89
Order statistic map, calculates the rank of elements. See orbtree and orbtreemap for description of m...
adapter for functions that take one parameter from a vector of parameters
Definition: orbtree.h:793
General set, i.e. storing a collection of elements without duplicates. Simple version for weight func...
unsigned int get_nr() const
number of component values returned is the same as the number of parameters
Definition: orbtree.h:800
reference operator*()
read-only access to values
Definition: orbtree.h:178
Definition: orbtree.h:55
base class for both map and set – should not be used directly
Definition: orbtree_base.h:63
NodeHandle next(NodeHandle n) const
get node after n (or nil) – note: next(nil) == nil
Definition: orbtree_base.h:484
std::conditional< multi, iterator, std::pair< iterator, bool > >::type insert_type
return type of insert functions
Definition: orbtree.h:246
Multimap implementation with compact storage. Simple version for weight functions that return one com...
iterator insert(const_iterator hint, value_type &&v)
iteraror that allows the modification of the stored value (for maps) insert(const_iterator hint...
Definition: orbtree.h:318
Order statistic set, calculates the rank of elements. See orbtree for description of members...
insert_type emplace(Args &&... args)
construct new element in-place
Definition: orbtree.h:330
Order statistic multiset, calculates the rank of elements, compact version. See orbtree for descripti...
constexpr size_t max_size() const
return the maximum possible number of elements
Definition: orbtree.h:236
double result_type
result is double
Definition: orbtree.h:841
General set, i.e. storing a collection of elements without duplicates. See orbtree for description of...
Order statistic multiset, calculates the rank of elements.
double result_type
result is double
Definition: orbtree.h:825
const_iterator upper_bound(const key_type &k) const
return an iterator to the first element with key greater than k
Definition: orbtree.h:428
example function: key^, i.e. raise the key for a given power; version for a map, where the mapped val...
Definition: orbtree.h:833
const_iterator upper_bound(const K &k) const
return an iterator to the first element with key greater than k
Definition: orbtree.h:436
NodeHandle first() const
get first node (or nil)
Definition: orbtree_base.h:466
iterator insert(const_iterator hint, const value_type &v)
Insert new element with hint.
Definition: orbtree.h:313
void get_sum(const K &k, typename std::enable_if<!simple_, NVType *>::type res) const
Calculate partial sum of weights for keys that come before k.
Definition: orbtree.h:526
NVType get_sum(typename std::enable_if< simple_, const key_type &>::type k) const
Calculate partial sum of weights for keys that come before k.
Definition: orbtree.h:514
Order statistic map with compact storage, calculates the rank of elements. See orbtree and orbtreemap...
insert_type insert(value_type &&v)
Insert new element.
Definition: orbtree.h:294
Specialized multiset with compact storage. See orbtree for description of members.
std::pair< iterator, iterator > equal_range(const key_type &k)
return a pair of iterators corresponding to the range of all elements with key equal to k ...
Definition: orbtree.h:441
iterator erase(const_iterator pos)
erase element pointed to by the given iterator; returns the element after it (in order) ...
Definition: orbtree.h:340
size_t size() const
check if the tree is empty
Definition: orbtree.h:234
bool set_value(key_type &&k, const mapped_type &v)
set value associated with the given key or insert new element
Definition: orbtree.h:996
example function: key^, i.e. raise the key for a given power
Definition: orbtree.h:818
const value_base value_type
Type of value pointed to by iterator.
Definition: orbtree.h:145
General multimap implementation (i.e. map allowing duplicate keys). See orbtree for description of me...
NodeAllocator::KeyValue::MappedType mapped_type
type of values stored in this map
Definition: orbtree.h:943
const_iterator cend() const
get the past-the-end iterator
Definition: orbtree.h:231
iterator upper_bound(const K &k)
return an iterator to the first element with key greater than k
Definition: orbtree.h:432
const key_type & key() const
convenience function to return the key (for both set and map)
Definition: orbtree.h:199
Order statistic multimap, calculates the rank of elements. See orbtree for description of members...
void get_norm_fv(NVType *res) const
get the normalization factor, i.e. the sum of all keys
Definition: orbtree_base.h:452
Specialized multiset with compact storage. Simple version for weight functions that return one compon...
Base class with map-specific function. It is recommended to use the specializations simple_map...
Definition: orbtree.h:929
NodeAllocator::NodeHandle NodeHandle
handle to refer nodes to (pointer or integer)
Definition: orbtree_base.h:71
NVType get_norm(typename std::enable_if< simple_, void *>::type k=0) const
Calculate normalization, i.e. sum of all weights. Equivalent to get_sum(cend()).
Definition: orbtree.h:546