67# ifndef TPL_DYNSKIPLIST_H
68# define TPL_DYNSKIPLIST_H
73# include <initializer_list>
74# include <gsl/gsl_rng.h>
110template <
typename Key,
class Compare = std::less<Key>>
148 for (
int i = 0; i <
lvl; ++i)
155 for (
int i = 0; i <
lvl; ++i)
163 for (
int i = 0; i <
lvl; ++i)
243 for (
auto it =
other.begin(); it.has_curr(); it.next())
259 other.current_level = 1;
282 for (
auto it =
other.begin(); it.has_curr(); it.next())
309 other.current_level = 1;
331 while (curr !=
nullptr)
396 for (
int i = 0; i <
lvl; ++i)
399 update[i]->
forward[i] = new_node;
403 return &new_node->
key;
440 for (
int i = 0; i <
lvl; ++i)
443 update[i]->
forward[i] = new_node;
447 return &new_node->
key;
461 <<
"DynSkipList::insert_unique: key already exists";
476 Key * ptr =
insert(std::move(key));
515 return const_cast<Key*
>(&x->
key);
523 return search(key) !=
nullptr;
542 <<
"DynSkipList::find: key not found";
551 <<
"DynSkipList::find: key not found";
579 if (update[i]->forward[i] != x)
614 <<
"DynSkipList::del: key not found";
620 if (update[i]->forward[i] != x)
650 while (x->
forward[0] !=
nullptr)
670 for (
auto it =
other.begin(); it.has_curr(); it.next())
671 result.
insert(it.get_curr());
683 for (
auto it =
begin(); it.has_curr(); it.next())
684 if (
other.has(it.get_curr()))
685 result.
insert(it.get_curr());
697 for (
auto it =
begin(); it.has_curr(); it.next())
699 result.
insert(it.get_curr());
775 return curr == it.curr;
780 return curr != it.curr;
810 template <
class Operation>
813 for (
auto it =
begin(); it.has_curr(); it.next())
814 if (
not op(it.get_curr()))
819 template <
class Operation>
825 template <
class Operation>
828 for (
auto it =
begin(); it.has_curr(); it.next())
832 template <
class Operation>
838 template <
class Pred>
841 for (
auto it =
begin(); it.has_curr(); it.next())
847 template <
class Pred>
853 template <
class Pred>
856 for (
auto it =
begin(); it.has_curr(); it.next())
857 if (
pred(it.get_curr()))
862 template <
class Pred>
868 template <
class Pred>
874 template <
class Pred>
880 template <
typename T>
884 for (
auto it =
begin(); it.has_curr(); it.next())
885 acc = op(
acc, it.get_curr());
889 template <
typename T,
class Operation>
893 for (
auto it =
begin(); it.has_curr(); it.next())
894 acc = op(
acc, it.get_curr());
898 template <
typename T,
class Operation>
Variadic constructor macros for containers.
Container traversal and functional operation mixins.
Exception handling system with formatted messages for Aleph-w.
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
#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.
STL-compatible iterator adapters for Aleph containers.
DRY (Don't Repeat Yourself) utilities and macros.
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Functional programming utilities for Aleph-w containers.
Iterator traits and STL-compatible iterator wrappers.
Forward iterator for DynSkipList.
Iterator & operator=(const Iterator &) noexcept=default
bool operator!=(const Iterator &it) const noexcept
bool is_last() const noexcept
const Key * operator->() const
const Key & get_curr_ne() const noexcept
Iterator operator++(int) noexcept
const Key & get_curr() const
Iterator() noexcept=default
void reset_first() noexcept
const Key & get_key() const
const DynSkipList * list_ptr
bool operator==(const Iterator &it) const noexcept
const Key & operator*() const
bool has_curr() const noexcept
Iterator & operator++() noexcept
Dynamic ordered set implemented with a Skip List.
Key & append(const Key &key)
Append method for Special_Ctors compatibility (aliases to insert)
bool none(Pred &&pred=Pred()) const
Key * search_or_insert(const Key &key)
Search and insert if not found.
void set_seed(unsigned long seed) noexcept
Set the random number generator seed.
size_t remove(const Key &key)
Remove a key from the set.
void empty() noexcept
Remove all elements from the set.
void swap(DynSkipList &other) noexcept
Swap contents with another DynSkipList.
static constexpr int maxLevel
Maximum number of levels (supports up to 2^32 elements efficiently)
DynSkipList(const DynSkipList &other)
Copy constructor.
bool traverse(Operation &&op=Operation()) const
Iterator begin() const noexcept
DynSkipList(DynSkipList &&other) noexcept
Move constructor.
static constexpr double defaultProbability
Default probability for level generation (0.5 = geometric distribution)
bool exists(Pred &&pred=Pred()) const
bool exist(const Key &key) const noexcept
Alias for has()
void clear() noexcept
Alias for empty() for STL compatibility.
T foldl(const T &init, std::function< T(const T &, const Key &)> op) const
Key * insert(Key &&key)
Insert an element into the set (move version).
Key del(const Key &key)
Remove and return a key.
bool exists(Pred &pred) const
Key Item_Type
The type of element that stores the container.
Iterator get_it() const noexcept
Alias for begin() - for generic programming.
Compare & get_compare() noexcept
Get the comparison functor.
bool traverse(Operation &op) const
bool contains(const Key &key) const noexcept
Alias for has() for STL-like interface.
T foldl(const T &init, Operation &&op) const
DynSkipList(double p=defaultProbability)
Construct a DynSkipList with time-based seed.
DynSkipList & operator=(const DynSkipList &other)
Copy assignment operator.
DynSkipList & operator=(DynSkipList &&other) noexcept
Move assignment operator.
~DynSkipList()
Destructor - frees all nodes and GSL random number generator.
Key & find(const Key &key)
Find a key, throwing if not found.
void for_each(Operation &&op=Operation()) const
DynSkipList intersect(const DynSkipList &other) const
Compute the intersection of two sets.
bool all(Pred &&pred=Pred()) const
DynSkipList diff(const DynSkipList &other) const
Compute the difference of two sets.
gsl_rng * gsl_rng_object() noexcept
Get a pointer to the GSL random number generator.
const Key & min() const
Return the minimum element (first in sorted order)
const Compare & get_compare() const noexcept
Get the comparison functor (const version)
Key * insert(const Key &key)
Insert an element into the set.
Key & insert_unique(const Key &key)
Insert an element, throwing if it already exists.
DynSkipList join(const DynSkipList &other) const
Compute the union of two sets.
Iterator end() const noexcept
bool is_empty() const noexcept
Return true if the set is empty.
const Key & find(const Key &key) const
Const version of find()
size_t size() const noexcept
Return the number of elements in the set.
bool keys_equal(const Key &k1, const Key &k2) const noexcept
DynSkipList(unsigned long seed, double p=defaultProbability)
Construct a DynSkipList with given seed and probability.
bool all(Pred &pred) const
bool has(const Key &key) const noexcept
Return true if the key exists in the set.
const Key & get_first() const
Alias for min()
const Key & max() const
Return the maximum element (last in sorted order)
void for_each(Operation &op) const
Key * search(const Key &key) const noexcept
Search for a key in the set.
void init(unsigned long seed)
const Key & get_last() const
Alias for max()
int random_level() const noexcept
bool none(Pred &pred) const
T foldl(const T &init, Operation &op) const
Key Key_Type
The type of element that stores the container.
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 begin() noexcept
Return an STL-compatible iterator to the first element.
Freq_Node * pred
Predecessor node in level-order traversal.
Main namespace for Aleph-w library functions.
std::decay_t< typename HeadC::Item_Type > T
void next()
Advance all underlying iterators (bounds-checked).
Node(const Key &k, int lvl)
Generic list of items stored in a container.
Generic traversal of the container through its iterator.
Special constructors common to Aleph-w ( ) containers.