58# ifndef TPL_INTERVAL_TREE_H
59# define TPL_INTERVAL_TREE_H
61# include <gsl/gsl_rng.h>
65# include <type_traits>
108 noexcept(std::is_nothrow_copy_constructible_v<T>)
117 noexcept(std::is_nothrow_move_constructible_v<T>)
126 noexcept(std::is_nothrow_copy_constructible_v<T>)
138 template <
class Compare = Aleph::less<T>>
140 const Compare &
cmp = Compare())
const
154 template <
class Compare = Aleph::less<T>>
156 const Compare &
cmp = Compare())
const
168 template <
class Compare = Aleph::less<T>>
181 noexcept(
noexcept(std::declval<const T &>() == std::declval<const T &>()))
192 noexcept(
noexcept(*
this ==
other))
204 template <
typename T,
class Compare = Aleph::less<T>>
224 noexcept(std::is_nothrow_invocable_v<const Compare &, const T &, const T &>)
226 if (
cmp(a.low, b.low))
228 if (
cmp(b.low, a.low))
230 return cmp(a.high, b.high);
237 template <
typename Key>
241 template <
typename T>
247 template <
typename Key>
258 template <
typename T>
270 noexcept(std::is_nothrow_default_constructible_v<T>)
292 template <
typename Key>
330 noexcept(std::is_nothrow_move_constructible_v<Key>)
344 noexcept(std::is_nothrow_move_constructible_v<Key>
and
345 std::is_nothrow_move_constructible_v<Data>)
375 template <
typename Key>
378 template <
typename Key>
386 template <
typename Key>
423 noexcept(std::is_nothrow_move_constructible_v<Key>)
437 noexcept(std::is_nothrow_move_constructible_v<Key>
and
438 std::is_nothrow_move_constructible_v<Data>)
470 template <
typename Key>
473 template <
typename Key>
478 template <
class Node>
481 template <
class Node>
484 return p->getMaxEndpoint();
509 template <
template <
typename>
class NodeType,
541 if (
LLINK(p) != Node::NullPtr)
544 if (
RLINK(p) != Node::NullPtr)
552 assert(p != Node::NullPtr);
564 assert(p != Node::NullPtr);
575 if (
root == Node::NullPtr)
581 Node *result =
nullptr;
585 if (result == Node::NullPtr)
586 return Node::NullPtr;
596 if (result == Node::NullPtr)
597 return Node::NullPtr;
605 return Node::NullPtr;
610 if (
root == Node::NullPtr)
634 if (
t1 == Node::NullPtr)
636 if (
t2 == Node::NullPtr)
652 if (
root == Node::NullPtr)
653 return Node::NullPtr;
670 return Node::NullPtr;
679 Op & op,
const Compare &
cmp)
681 if (
root == Node::NullPtr)
706 if (
root == Node::NullPtr)
725 if (
root == Node::NullPtr)
745 noexcept(
noexcept(std::swap(
tree_root, tree.tree_root))
and
746 noexcept(std::swap(
cmp, tree.cmp))
and
747 noexcept(std::swap(
r, tree.r))
and
748 noexcept(std::swap(
num_nodes, tree.num_nodes)))
751 std::swap(
cmp, tree.cmp);
752 std::swap(
r, tree.r);
762 const Compare &
_cmp = Compare())
830 assert(p != Node::NullPtr);
832 p->getMaxEndpoint() =
KEY(p).high;
834 if (result == Node::NullPtr)
848 assert(p != Node::NullPtr);
850 p->getMaxEndpoint() =
KEY(p).high;
881 while (x != Node::NullPtr)
883 if (
KEY(x).overlaps(query,
cmp))
929 void stab(
const T & p, Op && op)
const
978 template <
typename T,
class Compare = Aleph::less<T>>
993 template <
typename T,
class Compare = Aleph::less<T>>
1028 template <
typename T,
class Compare = Aleph::less<T>>
1033 public GenericKeys<DynIntervalTree<T, Compare>, Interval<T>>,
1068 const Compare &
cmp = Compare())
1115 noexcept(
noexcept(std::declval<Tree &>().swap(std::declval<Tree &>())))
1131 noexcept(
noexcept(std::declval<Tree &>().swap(std::declval<Tree &>())))
1148 <<
"Invalid interval: low > high";
1149 std::unique_ptr<Node> p(
new Node(
iv));
1151 if (result ==
nullptr)
1168 <<
"Invalid interval: low > high";
1169 std::unique_ptr<Node> p(
new Node(std::move(
iv)));
1171 if (result ==
nullptr)
1199 <<
"Invalid interval: low > high";
1200 std::unique_ptr<Node> p(
new Node(
iv));
1202 return KEY(p.release());
1246 return p !=
nullptr ? &
KEY(p) :
nullptr;
1258 return p !=
nullptr ? &
KEY(p) :
nullptr;
1314 tree.
stab(p, std::forward<Op>(op));
1358 template <
class Operation>
1363 return op(p->get_key());
1373 template <
class Operation>
1385 template <
class Operation>
1390 return op(p->get_key());
1400 template <
class Operation>
C++20 concepts for constraining comparison functors.
Container traversal and functional operation mixins.
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error()
Throws std::domain_error unconditionally.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_bad_alloc_if(C)
Throws std::bad_alloc if condition holds.
SentinelCtor
Tag type for sentinel node construction.
DRY (Don't Repeat Yourself) utilities and macros.
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Standard functor implementations and comparison objects.
WeightedDigraph::Node Node
Inorder iterator on the nodes of a binary tree.
Node * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
void next()
Move the iterator one position forward.
Node * get_curr() const
Return the current node. Throw overflow_error if there is no current.
bool has_curr() const noexcept
Return true the iterator has current node.
size_t get_pos() const
Return the current position of iterator. Only valid if has_curr() == true.
void reset_first() noexcept
Reset the iterator to the first node inorder.
Inorder iterator yielding Interval<T> keys.
bool has_curr() const noexcept
Check if there is a current element.
void end() noexcept
Move to the position after the last element.
size_t get_pos() const
Return the 0-indexed current position.
const Key & get_curr_ne() const noexcept
Return the current interval (no check).
void reset_first() noexcept
Reset to the first element in traversal order.
void next()
Advance to the next element.
Iterator() noexcept=default
Default constructor.
void prev()
Go back to the previous element.
void next_ne() noexcept
Advance to the next element (no check).
const Key & get_curr() const
Return the current interval.
High-level interval tree with automatic memory management.
Key & insert(const T &lo, const T &hi)
Insert an interval given endpoints (unique).
DynList< Key > find_all_overlaps(const Key &query) const
Find all overlapping intervals.
DynIntervalTree(const unsigned long seed, const Compare &cmp=Compare())
Construct with explicit seed for the internal RNG.
DynList< Key > find_stab(const T &p) const
Find all intervals containing point p.
DynList< Key > find_all_overlaps(const T &lo, const T &hi) const
Overload of find_all_overlaps() using endpoints.
bool is_empty() const noexcept
Return true if the tree contains no intervals.
Key & insert_dup(const Key &iv)
Insert interval, allowing duplicates.
void copy_from(const DynIntervalTree &src)
Key & insert(const Key &iv)
Insert an interval (unique).
const Key * overlap_search(const T &lo, const T &hi) const
Overload of overlap_search() using endpoints.
const Key * overlap_search(const Key &query) const
Find any interval overlapping query.
void all_overlaps(const Key &query, Op &&op) const
Apply op to every overlapping interval.
bool traverse(Operation &&op=Operation()) const
Const rvalue overload of traverse().
void swap(DynIntervalTree &other) noexcept(noexcept(std::declval< Tree & >().swap(std::declval< Tree & >())))
Swap state with another tree in O(1).
DynIntervalTree & operator=(const DynIntervalTree &src)
Copy assignment.
bool verify() const
Verify all tree invariants (BST, Treap, MaxEndpoint).
Key & append(const Key &iv)
Append an interval (alias for insert_dup).
DynIntervalTree(DynIntervalTree &&src)
Move constructor.
bool empty() const noexcept
Return true if the tree contains no intervals (STL compatible).
bool traverse(Operation &&op=Operation())
Overload of traverse() for rvalue callbacks.
bool traverse(Operation &op)
Traverse all intervals in inorder (sorted by low endpoint).
void stab(const T &p, Op &&op) const
Apply op to every interval containing point p.
size_t size() const noexcept
Return the number of intervals in the tree.
bool remove(const T &lo, const T &hi)
Remove an interval given endpoints.
bool traverse(Operation &op) const
Const overload of traverse().
Key & insert(Key &&iv)
Insert an interval (move version, unique).
bool remove(const Key &iv)
Remove an interval from the tree.
~DynIntervalTree()
Destructor.
typename Interval_Tree< T, Compare >::Node Node
DynIntervalTree(const Compare &cmp=Compare())
Default constructor.
DynIntervalTree(const DynIntervalTree &src)
Copy constructor.
const Key * search(const Key &iv) const noexcept
Search for an exact interval.
Dynamic singly linked list with functional programming support.
T & append(const T &item)
Augmented treap storing intervals with overlap/stabbing queries.
Node * insert(Node *root, Node *p)
Node * insert_dup(Node *p)
Insert a node (duplicates allowed).
DynList< Key > find_all_overlaps(const Key &query) const
Find all intervals overlapping query.
static void update_max(Node *p, const Compare &cmp)
Recalculate max_endpoint from node's own high and children.
size_t size() const noexcept
Return the number of nodes.
Gen_Interval_Tree(const unsigned long seed, const Compare &_cmp=Compare())
Construct with explicit seed and comparator.
bool verify() const
Verify BST, heap, and max_endpoint invariants.
const Node * search(const Key &key) const
Search for an exact interval in the tree.
void set_seed(const unsigned long seed) noexcept
Set the random number generator seed.
Interval_Less< T, Compare > IntervalCmp
const Compare & endpoint_comp() const noexcept
Return the endpoint comparison functor (const)
const Compare & get_compare() const noexcept
Backwards-compatible accessor for the endpoint comparator.
Node * remove(const Key &key)
Remove an interval from the tree.
void stab(const T &p, Op &&op) const
Apply op to every interval containing point p.
Node *& getRoot() noexcept
Return the tree's root.
static Node * rotate_to_left_it(Node *p, const Compare &cmp)
Rotate left with augmented field update.
void swap(Gen_Interval_Tree &tree) noexcept(noexcept(std::swap(tree_root, tree.tree_root)) and noexcept(std::swap(cmp, tree.cmp)) and noexcept(std::swap(r, tree.r)) and noexcept(std::swap(num_nodes, tree.num_nodes)))
Swap all state with tree in O(1)
IntervalCmp key_comp() const noexcept
Return the interval comparison functor (over Interval<T> keys)
static void all_overlaps(Node *root, const Key &query, Op &op, const Compare &cmp)
Recursive: find all intervals overlapping query.
Node * insert(Node *p)
Insert a node (no duplicates).
Gen_Interval_Tree(const Compare &_cmp=Compare())
Construct with default seed (from system time).
static Node * rotate_to_right_it(Node *p, const Compare &cmp)
Rotate right with augmented field update.
Gen_Interval_Tree & operator=(const Gen_Interval_Tree &)=delete
Deleted copy assignment.
void init(const unsigned int seed)
Gen_Interval_Tree(const Gen_Interval_Tree &)=delete
Deleted copy constructor.
bool is_empty() const noexcept
Return true if the tree is empty.
void reset_num_nodes() noexcept
Reset the node count (used after manual tree destruction)
const Node * overlap_search(const Key &query) const
Find any interval that overlaps with query (CLRS algorithm).
static bool check_max(Node *root, const Compare &cmp)
Verify max_endpoint invariant.
gsl_rng * gsl_rng_object() const noexcept
Get a pointer to the GSL random number generator.
static Node * join_exclusive(Node *t1, Node *t2, const Compare &cmp)
void all_overlaps(const Key &query, Op &&op) const
Apply op to every interval overlapping query.
Node * remove(Node *&root, const Key &key)
static size_t count_nodes(Node *root) noexcept
DynList< Key > find_stab(const T &p) const
Find all intervals containing point p.
Node * insert_dup(Node *root, Node *p)
Gen_Interval_Tree(Gen_Interval_Tree &&)=delete
Deleted move constructor.
const Node * getRoot() const
Return the tree's root (const)
Interval tree node with virtual destructor.
virtual ~Interval_Tree_NodeVtl()=default
Virtual destructor.
const Interval_Tree_NodeVtl * getL() const noexcept
interval_endpoint_t< Key > Endpoint
static Interval_Tree_NodeVtl *const NullPtr
const Key & get_key() const noexcept
Interval_Tree_NodeVtl(Key &&k) noexcept(std::is_nothrow_move_constructible_v< Key >)
Interval_Tree_NodeVtl *& getL() noexcept
Interval_Tree_NodeVtl * rLink
Interval_Tree_NodeVtl(const Interval_Tree_NodeVtl &node)
Interval_Tree_NodeVtl * lLink
Interval_Tree_NodeVtl *& getR() noexcept
static Interval_Tree_NodeVtl sentinel_node
The sentinel node instance (virtual version).
Interval_Tree_NodeVtl(const Key &k)
Interval_Tree_NodeVtl(Interval_Tree_NodeVtl &&node) noexcept(std::is_nothrow_move_constructible_v< Key > and std::is_nothrow_move_constructible_v< Data >)
const Interval_Tree_NodeVtl * getR() const noexcept
Interval_Tree_NodeVtl(SentinelCtor)
static constexpr size_t MaxHeight
Data portion of an interval tree node.
Interval_Tree_Node_Data() noexcept(std::is_nothrow_default_constructible_v< T >)
T & getMaxEndpoint() noexcept
const T & getMaxEndpoint() const noexcept
unsigned long & getPriority() noexcept
Interval_Tree_Node_Data(SentinelCtor) noexcept(std::is_nothrow_default_constructible_v< T >)
static void reset() noexcept
Interval tree node with sentinel support.
Interval_Tree_Node *& getR() noexcept
Interval_Tree_Node(const Key &k)
const Interval_Tree_Node * getR() const noexcept
const Key & get_key() const noexcept
Interval_Tree_Node(SentinelCtor)
static constexpr size_t MaxHeight
static Interval_Tree_Node *const NullPtr
interval_endpoint_t< Key > Endpoint
static Interval_Tree_Node sentinel_node
The sentinel node instance.
Interval_Tree_Node(Interval_Tree_Node &&node) noexcept(std::is_nothrow_move_constructible_v< Key > and std::is_nothrow_move_constructible_v< Data >)
Interval_Tree_Node(Key &&k) noexcept(std::is_nothrow_move_constructible_v< Key >)
Interval_Tree_Node * lLink
Interval_Tree_Node *& getL() noexcept
const Interval_Tree_Node * getL() const noexcept
Interval_Tree_Node(const Interval_Tree_Node &node)
Interval_Tree_Node * rLink
Equality test for containers.
Common methods to the Aleph-w ( ) containers.
void for_each(Operation &operation)
Traverse all the container and performs an operation on each element.
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
Strict weak ordering constraint for BST comparators.
__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)
bool check_bst(Node *p, const Compare &cmp=Compare())
Return true if p is a binary search tree.
void destroyRec(Node *&root) noexcept
Free recursively all the memory occupied by the tree root
Node * searchInBinTree(Node *root, const typename Node::key_type &key, const Compare &cmp=Compare()) noexcept
Search a key in a binary search tree.
unsigned long & PRIO(Node *p) noexcept
Access the priority of a treap node.
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
typename interval_endpoint< Key >::type interval_endpoint_t
auto & MAX_EP(Node *p) noexcept
Access max_endpoint of an interval tree node.
bool is_treap(Node *root) noexcept
Validate that a tree satisfies treap (heap) property.
bool traverse(Node *root, Op op)
static long & low(typename GT::Node *p)
Internal helper: low-link value stored directly in NODE_COOKIE(p).
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
const long Max_Priority
Maximum priority value (used for sentinel/leaves)
const long Min_Priority
Minimum priority value.
static std::atomic< bool > init
Inorder iterator over nodes.
Iterator() noexcept=default
BST comparator for intervals: order by (low, then high).
bool operator()(const Interval< T > &a, const Interval< T > &b) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Comparison operator.
Interval_Less(const Compare &c=Compare()) noexcept(std::is_nothrow_copy_constructible_v< Compare >)
Constructor.
Interval tree using nodes with virtual destructor.
Interval tree using nodes without virtual destructor.
Closed interval [low, high].
bool operator==(const Interval &other) const noexcept(noexcept(std::declval< const T & >()==std::declval< const T & >()))
Equality operator.
static Interval point(const T &p) noexcept(std::is_nothrow_copy_constructible_v< T >)
Construct a point interval [p, p].
Interval() noexcept(std::is_nothrow_default_constructible_v< T >)
Initializes the interval as [T{}, T{}].
bool contains(const T &p, const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if this interval contains the point p.
bool is_valid(const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if low <= high.
bool overlaps(const Interval &other, const Compare &cmp=Compare()) const noexcept(std::is_nothrow_invocable_v< const Compare &, const T &, const T & >)
Return true if this interval overlaps with other.
Interval(T &&lo, T &&hi) noexcept(std::is_nothrow_move_constructible_v< T >)
Construct interval [lo, hi] (move version).
bool operator!=(const Interval &other) const noexcept(noexcept(*this==other))
Inequality operator.
Interval(const T &lo, const T &hi) noexcept(std::is_nothrow_copy_constructible_v< T >)
Construct interval [lo, hi].
Trait to extract endpoint type from Interval<T>.
Generic list of items stored in a container.
Utility functions for binary tree operations.
Binary tree operations (split, join, rotate).
Treap node definition with BST key and heap priority.