45# ifndef TPL_DYNSETTREE_H
46# define TPL_DYNSETTREE_H
50# include <type_traits>
81 template <
typename Node>
96 template <
typename Node>
102 return new Node(key);
107 return new Node(std::forward<typename Node::key_type>(key));
118 template <
typename Node>
130 :
arena(base_addr, sz)
168 template <
typename Container,
typename T>
176 return item1 < item2;
264 template <
typename Key,
270 public GenericKeys<DynSetTree<Key, Tree, Compare>, Key>,
282 template <
typename T>
286 template <
typename U>
288 ->
decltype(std::declval<const U &>().select(std::declval<size_t>()),
295 template <
typename U>
297 ->
decltype(std::declval<U &>().select(std::declval<size_t>()),
303 template <
typename U>
305 ->
decltype(std::declval<U &>().remove_pos(std::declval<size_t>()),
311 template <
typename U>
313 ->
decltype(std::declval<U &>().split_pos(std::declval<size_t>(),
315 std::declval<U &>()),
322 template <
typename U>
324 ->
decltype(std::declval<const U &>().position(std::declval<const Key &>()),
331 template <
typename U>
333 ->
decltype(std::declval<U &>().position(std::declval<const Key &>()),
340 template <
typename U>
342 ->
decltype(std::declval<const U &>().find_position(std::declval<const Key &>()),
349 template <
typename U>
351 ->
decltype(std::declval<U &>().find_position(std::declval<const Key &>()),
358 std::is_same_v<decltype(test_select_const<T>(0)), std::true_type>
or
361 std::is_same_v<decltype(test_remove_pos<T>(0)), std::true_type>;
363 std::is_same_v<decltype(test_split_pos<T>(0)), std::true_type>;
365 std::is_same_v<decltype(test_position_const<T>(0)), std::true_type>
or
368 std::is_same_v<decltype(test_find_position_const<T>(0)), std::true_type>
or
373 template <
typename T>
375 ->
decltype(t.select(i))
381 template <
typename T>
383 ->
decltype(t.select(i))
388 template <
typename T>
395 template <
typename T>
402 template <
typename T>
404 ->
decltype(t.remove_pos(i))
406 return t.remove_pos(i);
409 template <
typename T>
416 template <
typename T>
418 ->
decltype(t.split_pos(pos,
l, r),
void())
420 t.split_pos(pos,
l, r);
423 template <
typename T>
429 template <
typename T>
431 ->
decltype(t.position(key))
433 return t.position(key);
436 template <
typename T>
440 return std::pair<long, Node *>(0,
nullptr);
443 template <
typename T>
445 ->
decltype(t.find_position(key))
447 return t.find_position(key);
450 template <
typename T>
453 ah_domain_error() <<
"find_position is not supported by underlying tree";
454 return std::pair<long, Node *>(0,
nullptr);
457 static constexpr size_t dim = 13;
467 return new Node(key);
474 return new Node(std::forward<Key>(key));
516 const Compare &
cmp = Compare())
525 const Compare &
cmp = Compare())
566 tree.getRoot() = Node::NullPtr;
572 tree.getRoot() = Node::NullPtr;
621 q =
tree.search_or_insert(p);
634 return &p->get_key();
650 if (
key_p ==
nullptr)
663 if (
key_p ==
nullptr)
679 return insert(std::forward<Key>(key));
688 q =
tree.search_or_insert(p);
701 return &q->get_key();
709 q =
tree.search_or_insert(p);
719 return std::pair<Node *, bool>(q,
true);
722 return std::pair<Node *, bool>(p,
false);
765 return std::pair<Key *, bool>(&p.first->get_key(), p.second);
771 return std::pair<Key *, bool>(&p.first->get_key(), p.second);
781 return &p->get_key();
801 Key *
put(
const Key & key)
808 return insert(std::forward<Key>(key));
845 <<
"DynSetTree::del key is not found in the tree";
863 <<
"remove_pos is not supported by underlying tree";
866 <<
"remove_pos index out of range";
870 <<
"remove_pos returned nullptr";
883 return search(key) !=
nullptr;
886 bool has(
const Key & key)
const
910 Key &
find(
const Key & key)
const
917 return node->get_key();
937 <<
"find_position is not supported by underlying tree";
940 return std::pair<long, Key *>(0,
nullptr);
943 if (p.second ==
nullptr)
944 return std::pair<long, Key *>(
static_cast<long>(p.first),
nullptr);
946 return std::pair<long, Key *>(
static_cast<long>(p.first),
947 &p.second->get_key());
971 return &(node->get_key());
1077 <<
"position is not supported by underlying tree";
1080 return static_cast<long>(p.first);
1091 <<
"select is not supported by underlying tree";
1094 <<
"select index out of range";
1099 <<
"select returned nullptr";
1100 return p->get_key();
1106 <<
"select is not supported by underlying tree";
1109 <<
"select index out of range";
1114 <<
"select returned nullptr";
1115 return p->get_key();
1144 template <
class Key_Op>
1190 template <
class Key_Op>
1207 template <
class Key_Op>
1237 template <
class Key_Op>
1254 template <
class Key_Op>
1284 template <
class Key_Op>
1301 template <
class Key_Op>
1322 t.
tree.getRoot() = Node::NullPtr;
1340 return join(t, dup);
1359 t.
tree.getRoot() = Node::NullPtr;
1384 tree.getRoot() = Node::NullPtr;
1407 <<
"split_pos is not supported by underlying tree";
1410 <<
"split_pos position out of range";
1415 tree.getRoot() = Node::NullPtr;
1435 tree.split_key_dup(key,
l.tree, r.
tree);
1436 tree.getRoot() = Node::NullPtr;
1457 return Base::get_curr_ne()->get_key();
1462 const Key &
get_curr()
const {
return Base::get_curr()->get_key(); }
1464 Key &
get_curr() {
return Base::get_curr()->get_key(); }
1481 template <
class Operation>
1486 return op(p->get_key());
1490 template <
class Operation>
1496 template <
class Operation>
1501 return op(p->get_key());
1505 template <
class Operation>
1513# define SETTREE_ITOR(Name, Key, Cmp) \
1514 class Iterator : public DynSetTree<Key, Name, Cmp>::Iterator \
1517 Iterator() : DynSetTree<Key, Name, Cmp>::Iterator() \
1520 Iterator(DynSetTree<Key, Name, Cmp> & tree) \
1521 : DynSetTree<Key, Name, Cmp>::Iterator(tree) \
1532 template <
typename Key,
class Compare = Aleph::less<Key>>
1547 template <
typename Key,
class Compare = Aleph::less<Key>>
1562 template <
typename Key,
class Compare = Aleph::less<Key>>
1584 template <
typename Key,
class Compare = Aleph::less<Key>>
1600 template <
typename Key,
class Compare = Aleph::less<Key>>
1628 template <
typename Key,
class Compare = Aleph::less<Key>>
1642 template <
typename Key,
class Compare = Aleph::less<Key>>
1660 template <
typename Key,
class Compare = Aleph::less<Key>>
1676 template <
typename Key,
class Compare = Aleph::less<Key>>
1695 template <
typename Key,
class Compare = Aleph::less<Key>>
1712 template <
typename Key,
class Compare = Aleph::less<Key>>
1731 template <
typename Key,
class Compare = Aleph::less<Key>>
1754 template <
typename Key,
class Compare = Aleph::less<Key>>
1777 template <
typename Key,
class Compare = Aleph::less<Key>>
1787 template <
typename T,
class Op,
class C>
1791 for (
auto it = c.get_it(); it.has_curr(); it.next_ne())
Memory arena for fast bulk allocations.
Variadic constructor macros for containers.
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error()
Throws std::domain_error unconditionally.
#define ah_domain_error_if_constexpr(C)
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_logic_error_if(C)
Throws std::logic_error if condition holds.
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
Zip iterators and functional operations for multiple containers.
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Iterator traits and STL-compatible iterator wrappers.
WeightedDigraph::Node Node
virtual void unalloc(Node *)=0
virtual Node * alloc_rval(typename Node::key_type &&key)=0
virtual Node * alloc_lval(const typename Node::key_type &key)=0
AbstractTreeNodeAllocator()=default
virtual ~AbstractTreeNodeAllocator()=default
Arena allocator for fast bump-pointer allocation.
size_t allocated_size() const noexcept
Get total bytes currently allocated.
size_t available_size() const noexcept
Get remaining bytes available.
~DftTreeNodeAllocator() override=default
Node * alloc_lval(const typename Node::key_type &key) override
Node * alloc_rval(typename Node::key_type &&key) override
void unalloc(Node *p) override
Dynamic singly linked list with functional programming support.
T & insert(const T &item)
Insert a new item by copy.
Dynamic set implemented using extended AVL binary search trees with rank support of type Avl_Tree_Rk<...
Dynamic set implemented using AVL binary search trees of type Avl_Tree<Key>.
Dynamic set implemented using binary search trees of type BinTree<Key>.
Dynamic set implemented using Hybrid Red-Black trees with rank support of type HtdRbTreeRk<Key>.
Dynamic set implemented using Hybrid Top-Down/Bottom-Up Red-Black trees of type HtdRbTree<Key>.
Iterator(DynSetTree< Key, Rand_Tree, Compare > &tree)
Dynamic set implemented using randomized binary search trees of type Rand_Tree<Key>.
Dynamic set implemented using extended Red-Black binary search trees with rank support of type Rb_Tre...
Dynamic set implemented using Red-Black binary search trees of type Rb_Tree<Key> (bottom-up implement...
Dynamic set implemented using splay trees with rank support of type Splay_Tree_Rk<Key>.
Dynamic set implemented using splay binary search trees of type Splay_Tree<Key>.
Dynamic set implemented using Top-Down Red-Black binary search trees with rank support of type TdRbTr...
Dynamic set implemented using Top-Down Red-Black binary search trees of type TdRbTree<Key>.
Dynamic set implemented using extended treap binary search trees with rank support of type Treap_Rk<K...
Dynamic set implemented using randomized treap binary search trees of type Treap<Key>.
Dynamic set backed by balanced binary search trees with automatic memory management.
const Key & get_first() const
size_t height() const
Calculates and returns the height of the binary search tree.
DynSetTree(const Compare &cmp=Compare())
Instantiate a dynamic set.
virtual ~DynSetTree()
Destroyer; all elements are released.
long position(const Key &key) const
Returns the infix (ordered) position of the key.
Key * append(const Key &key)
const Key & get_last() const
Key * __insert_dup(Node *q)
bool split_key(const Key &key, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on a key.
typename Tree< Key, Compare >::Node Node
Type of binary node used by the binary search tree internal.
std::pair< Key *, bool > contains_or_insert(Key &&key)
const Key & get_item() const
Returns any element of the set.
DynSetTree & join(DynSetTree &t, DynSetTree &&dup=DynSetTree())
This is an overloaded member function, provided for convenience. It differs from the above function o...
Key & operator()(size_t i)
const size_t & size() const
Returns the cardinality of the set.
Key remove_pos(const size_t i)
Removes a key from the dynamic set.
static auto call_select(const T &t, const size_t i, int) -> decltype(t.select(i))
Node * alloc_node(const Key &key)
static auto call_find_position(const T &t, const Key &key, int) -> decltype(t.find_position(key))
static auto call_split_pos(T &t, const size_t pos, T &l, T &r, int) -> decltype(t.split_pos(pos, l, r), void())
static constexpr size_t dim
Key del(const Key &key)
Deletes key and returns a full copy of stored key.
std::pair< long, Key * > find_position(const Key &key) const
Returns the infix (ordinate) position of the key key or whatever It would be your position of belongi...
DynSetTree(const DynSetTree &srcTree)
instantiates a dynamic copy of srcTree
Tree< Key, Compare > tree
const Key & operator[](const Key &key) const
Key * insert(const Key &key)
Inserts a key into the dynamic set.
bool exist(const Key &key) const
Returns true if key belongs to the dynamic set.
void split_key_dup(const Key &key, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on a key that may be present in the tree.
bool has(const Key &key) const
void swap(DynSetTree &dset) noexcept(noexcept(tree.swap(dset.tree)) and noexcept(std::swap(num_nodes, dset.num_nodes)) and noexcept(std::swap(arena_allocator, dset.arena_allocator)))
Exchange all elements of this set with dset in constant time (and extremely fast).
void for_each_postorder(Key_Op &key_op) const
Performs a postfix traversal over all keys in the set and invokes operation Op.
Key * put(const Key &key)
static std::pair< long, Node * > call_position(const T &, const Key &,...)
Key & find(const Key &key) const
Returns a modifiable reference to an element within the set.
size_t internal_path_length() const
Calculates and returns the length of the internal path of the tree search binary.
size_t remove(const Key &key)
Removes a key from the dynamic set.
std::unique_ptr< ArenaTreeAllocator< Node > > arena_allocator
bool traverse(Operation &&op=Operation()) const
const Key & min() const
Returns the smallest key contained in the set according to the criterion comparison given.
bool contains(const Key &key) const
const Key & get() const
Synonym of max.
const Key & get_root() const
DynSetTree(const size_t &arena_sz, const Compare &cmp=Compare())
Instantiate a dynamic set using an arena allocator with dynamic buffer.
Key * search_or_insert(Key &&key)
Node * alloc_node(Key &&key)
Key * insert_dup(const Key &key)
void for_each_preorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
DynSetTree(DynSetTree &&srcTree) noexcept
void split_pos(const size_t pos, DynSetTree &l, DynSetTree &r)
Partitions the binary search tree based on an infix position.
void for_each_postorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void for_each_in_preorder(void(*visitFct)(Node *, int, int))
Performs a prefix traversal over all nodes in the tree and invokes the visitFct operation on each vis...
DynSetTree(const char *base_addr, const size_t &sz, const Compare &cmp=Compare())
Instantiate a dynamic set using an arena allocator with external buffer.
static Node * call_select_nc(T &, const size_t,...)
static auto call_position(const T &t, const Key &key, int) -> decltype(t.position(key))
bool traverse(Operation &&op=Operation())
size_t arena_allocated_size() const noexcept
Returns the allocated size from the arena (0 if not using arena)
Key * search(const Key &key) const
Find an element in the set.
Key & select(size_t i)
Returns the ith node in infix position.
Key * __search_or_insert(Node *p)
static auto call_select_nc(T &t, const size_t i, int) -> decltype(t.select(i))
std::pair< Node *, bool > __contains_or_insert(Node *p)
void empty()
remove all elements from the set
bool uses_arena() const noexcept
Returns true if the set is using an arena allocator.
static auto call_remove_pos(T &t, const size_t i, int) -> decltype(t.remove_pos(i))
bool traverse(Operation &op)
Traverse all the set of pairs and for each key executes the operation op.
static Node * call_select(const T &, const size_t,...)
bool traverse(Operation &op) const
void for_each_inorder(Key_Op &&key_op=Key_Op()) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
const Key & select(size_t i) const
DynSetTree & operator=(const DynList< Key > &list)
Key * search_or_insert(const Key &key)
Look for the key in the binary search tree or inserts it if it is not found.
static void call_split_pos(T &, const size_t, T &, T &,...)
void for_each_preorder(Key_Op &key_op) const
Performs a prefix traversal over all keys in the set and invokes operation Op.
const Key & max() const
Returns the largest key contained in the set according to the criteria comparison given.
static Node * call_remove_pos(T &, const size_t,...)
void for_each_inorder(Key_Op &key_op) const
Performs an infix traversal over all keys in the set and invokes operation Op.
std::pair< Key *, bool > contains_or_insert(const Key &key)
bool is_empty() const
returns true if the set is empty
static std::pair< long, Node * > call_find_position(const T &, const Key &,...)
Key * insert_dup(Key &&key)
Node * get_root_node() const
size_t arena_available_size() const noexcept
Returns the available size in the arena (0 if not using arena)
Hybrid top-down/bottom-up red-black tree with rank support.
Hybrid top-down/bottom-up red-black tree.
Top-down red-black tree with rank (no virtual destructor).
Equality test for containers.
Common methods to the Aleph-w ( ) containers.
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Common sequential searching methods on containers.
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
iterator end() noexcept
Return an STL-compatible end iterator.
iterator begin() noexcept
Return an STL-compatible iterator to the first element.
__gmp_expr< T, __gmp_binary_expr< __gmp_expr< T, U >, unsigned long int, __gmp_root_function > > root(const __gmp_expr< T, U > &expr, unsigned long int l)
int cmp(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
size_t compute_cardinality_rec(Node *root) noexcept
Count the number of nodes of a binary tree.
DynSetTree & join(DynSetTree &t, DynSetTree &dup)
Union of two binary search trees.
int preOrderRec(Node *root, void(*visitFct)(Node *, int, int))
Traverse recursively in preorder a binary tree.
Node * find_min(Node *root) noexcept
Return the minimum key contained in a binary search tree.
Node * copyRec(Node *root)
Copy recursively a tree.
bool check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
DynSetTree & join_dup(DynSetTree &t)
Union of two binary search trees.
size_t internal_path_length(Node *p) noexcept
Compute the internal path length.
void destroyRec(Node *&root) noexcept
Free recursively all the memory occupied by the tree root
size_t computeHeightRec(Node *root) noexcept
Compute recursively the height of root
Node * find_max(Node *root) noexcept
Return the maximum key contained in a binary search tree.
Main namespace for Aleph-w library functions.
bool traverse(Node *root, Op op)
DynSetTree< T > set_unify(const C &c, Op op)
std::decay_t< typename HeadC::Item_Type > T
DynList< T > maps(const C &c, Op op)
Classic map operation.
void callKeyDestructorsRec(Node *&root) noexcept
Traverses recursively the tree and calls key's destructors.
Node * alloc_rval(typename Node::key_type &&key) override
ArenaTreeAllocator(const size_t &sz=1024 *1024)
size_t available_size() const noexcept
ArenaTreeAllocator(const char *base_addr, const size_t &sz)
size_t allocated_size() const noexcept
Node * alloc_lval(const typename Node::key_type &key) override
~ArenaTreeAllocator()=default
void unalloc(Node *p) override
AVL binary search tree with nodes without virtual destructor and with subtree counters for select/pos...
AVL binary search tree with nodes without virtual destructor.
bool operator()(const Container &c1, const Container &c2) const
static auto test_remove_pos(int) -> decltype(std::declval< U & >().remove_pos(std::declval< size_t >()), std::true_type())
static std::false_type test_remove_pos(...)
static auto test_position_const(int) -> decltype(std::declval< const U & >().position(std::declval< const Key & >()), std::true_type())
static constexpr bool has_select
static auto test_find_position_const(int) -> decltype(std::declval< const U & >().find_position(std::declval< const Key & >()), std::true_type())
static constexpr bool has_split_pos
static auto test_split_pos(int) -> decltype(std::declval< U & >().split_pos(std::declval< size_t >(), std::declval< U & >(), std::declval< U & >()), std::true_type())
static constexpr bool has_find_position
static std::false_type test_select_const(...)
static std::false_type test_find_position_nonconst(...)
static auto test_find_position_nonconst(int) -> decltype(std::declval< U & >().find_position(std::declval< const Key & >()), std::true_type())
static constexpr bool has_remove_pos
static std::false_type test_find_position_const(...)
static auto test_select_nonconst(int) -> decltype(std::declval< U & >().select(std::declval< size_t >()), std::true_type())
static std::false_type test_position_const(...)
static std::false_type test_split_pos(...)
static auto test_position_nonconst(int) -> decltype(std::declval< U & >().position(std::declval< const Key & >()), std::true_type())
static constexpr bool has_position
static auto test_select_const(int) -> decltype(std::declval< const U & >().select(std::declval< size_t >()), std::true_type())
static std::false_type test_position_nonconst(...)
static std::false_type test_select_nonconst(...)
const Key & get_curr_ne() const noexcept
typename Tree_Type::Iterator Base
Iterator() noexcept=default
Default constructor creates an "end" iterator.
const Key & get_curr() const
Key & get_curr_ne() noexcept
Node_Op(Key_Op &&__key_op)
Node_Op(Key_Op &__key_op)
void operator()(Node *root)
Iterator on nodes of the tree.
Red-Black binary search tree with nodes without virtual destructor and with subtree counters for sele...
Extended treap (a special type of randomized binary search tree) which manages selection and splittin...
Generic list of items stored in a container.
AVL tree with rank (order statistics).
AVL tree implementation (height-balanced BST).
Utility functions for binary tree operations.
Extended binary node with subtree count.
Generic unbalanced binary search tree.
#define SETTREE_ITOR(Name, Key, Cmp)
Hybrid top-down/bottom-up red-black tree with rank support.
Hybrid top-down/bottom-up red-black tree implementation.
Randomized binary search tree.
Red-Black tree with rank (order statistics).
Red-Black tree implementation (bottom-up balancing).
Top-down splay tree with rank support.
Top-down splay tree implementation (without rank support).
Top-down Red-Black tree with rank support.
Top-down Red-Black tree implementation.
Treap with rank (order statistics).
Treap: randomized BST combining tree and heap properties.