add third-party range-map library

I have e-mailed the author for clarifcation on the license, will update this when they respond
This commit is contained in:
nikitalita 2025-03-02 14:49:28 -08:00
parent c63fa3015e
commit 2f1451e5eb
5 changed files with 1982 additions and 0 deletions

View file

@ -0,0 +1,160 @@
// (C) Beneficii. Released under Creative Commons license.
#ifndef BENEFICII_RANGE_MAP_RM_BASE_HPP
#define BENEFICII_RANGE_MAP_RM_BASE_HPP
#include <cstddef>
#include <utility>
#include <tuple>
namespace beneficii {
// for the piecewise constructor of range_map_item; used with emplace() in
// range_map; you would do emplace(encaps (true or false), std::piecewise_construct,
// std::forward_as_tuple(left key args), std::forward_as_tuple(right key args),
// std::forward_as_tuple(mapped val args)
// thanks to online resource for showing how to do this!
namespace temp {
template<std::size_t...> struct index_tuple{};
template<std::size_t I, typename IndexTuple, typename... Types>
struct make_indices_impl;
template<std::size_t I, std::size_t... Indices, typename T, typename... Types>
struct make_indices_impl<I, index_tuple<Indices...>, T, Types...>
{
typedef typename
make_indices_impl<I + 1,
index_tuple<Indices..., I>,
Types...>::type type;
};
template<std::size_t I, std::size_t... Indices>
struct make_indices_impl<I, index_tuple<Indices...> >
{
typedef index_tuple<Indices...> type;
};
template<typename... Types>
struct make_indices
: make_indices_impl<0, index_tuple<>, Types...>
{};
}
//indicate that left point and length rather than left and right points are
//passed to the constructor
struct length_construct_type {};
// range_map_item; basic range_type stored in range_map; here the left key and the
// right key delimiting the range [left, right) are stored, as well as the mapped
// value; the mapped value can be modified if the range_map_item is not const; this
// is contrary to the c++11 standards for the pair stored in map and multi-map
template<class kty, class ty>
class range_map_item {
typedef range_map_item<kty, ty> _myt;
public:
range_map_item(const kty& left, const kty& right)
: left(left), right(right), val() {}
range_map_item(const kty& left, const kty& right, const ty& val)
: left(left), right(right), val(val) {}
//length constructors
range_map_item(length_construct_type, const kty& left, const kty& length)
: left(left), right(left+length), val() {}
range_map_item(length_construct_type, const kty& left, const kty& length,
const ty& val) : left(left), right(left+length), val(val) {}
//c++11 constructors
range_map_item(kty&& left, kty&& right)
: left(std::forward<kty>(left)), right(std::forward<kty>(right)), val() {}
range_map_item(const kty& left, const kty& right, ty&& val)
: left(left), right(right), val(std::forward<ty>(val)) {}
range_map_item(kty&& left, kty&& right, const ty& val)
: left(std::forward<kty>(left)), right(std::forward<kty>(right)), val(val) {}
range_map_item(kty&& left, kty&& right, ty&& val)
: left(std::forward<kty>(left)), right(std::forward<kty>(right)), val(std::forward<ty>(val)) {}
//length constructors
range_map_item(length_construct_type, kty&& left, const kty& length)
: left(std::forward<kty>(left)), right(left+length), val() {}
range_map_item(length_construct_type, const kty& left, const kty& length,
ty&& val) : left(left), right(left+length), val(std::forward<ty>(val)) {}
range_map_item(length_construct_type, kty&& left, const kty& length,
const ty& val) : left(std::forward<kty>(left)), right(left+length), val(val) {}
range_map_item(length_construct_type, kty&& left, const kty& length,
ty&& val) : left(std::forward<kty>(left)), right(left+length),
val(std::forward<ty>(val)) {}
//piecewise constructor
template<class... left_args, class... right_args, class... mapped_args>
range_map_item(std::piecewise_construct_t pwc,
std::tuple<left_args...> left_tpl, std::tuple<right_args...> right_tpl,
std::tuple<mapped_args...> mapped_tpl)
: range_map_item(left_tpl, right_tpl, mapped_tpl,
typename temp::make_indices<left_args...>::type(),
typename temp::make_indices<right_args...>::type(),
typename temp::make_indices<mapped_args...>::type())
{}
const kty& get_left() const {
return left;
}
const kty& get_right() const {
return right;
}
kty width() const {
return right - left;
}
ty& mapped() {
return val;
}
const ty& mapped() const {
return val;
}
private:
range_map_item() {}
template<class... args1, class... args2, class... args3,
std::size_t... indices1, std::size_t... indices2, std::size_t... indices3>
range_map_item(std::tuple<args1...> tuple1, std::tuple<args2...> tuple2, std::tuple<args3...> tuple3,
temp::index_tuple<indices1...>, temp::index_tuple<indices2...>, temp::index_tuple<indices3...>)
: left(std::forward<args1>(std::get<indices1>(tuple1))...),
right(std::forward<args2>(std::get<indices2>(tuple2))...),
val(std::forward<args3>(std::get<indices3>(tuple3))...)
{}
kty left;
kty right;
ty val;
};
// constructs range_map_item to be forwarded
template<class kty, class ty>
range_map_item<kty, ty> make_range_map_item(kty&& left, kty&& right, ty&& val) {
return range_map_item<kty, ty>(std::forward<kty>(left), std::forward<kty>(right), std::forward<ty>(val));
}
}
#endif /* RM_BASE_HPP */

View file

@ -0,0 +1,208 @@
// (C) Beneficii. Released under Creative Commons license.
#ifndef BENEFICII_RANGE_MAP_RM_ITER_HPP
#define BENEFICII_RANGE_MAP_RM_ITER_HPP
#include "rm_node.h"
#include <iterator>
namespace beneficii {
// base class for iterator
template<class _range_map>
class _rm_iter_base {
typedef _rm_iter_base<_range_map> _myt;
protected:
typedef std::bidirectional_iterator_tag iterator_category;
typedef _range_node<typename _range_map::key_type,
typename _range_map::mapped_type> _node_type;
typedef typename _range_map::allocator_type _alloc_type;
typedef typename _alloc_type::template rebind<_node_type>::other _node_allocator;
typedef typename _node_allocator::pointer _nodeptr;
typedef typename _range_map::value_type value_type;
typedef typename _range_map::difference_type difference_type;
_rm_iter_base()
: _node(nullptr), _is_rgt_pt(false) {}
_rm_iter_base(_nodeptr _node, bool _is_rgt_pt)
: _node(_node), _is_rgt_pt(_is_rgt_pt) {}
_rm_iter_base(const _myt& _right)
: _node(_right._node), _is_rgt_pt(_right._is_rgt_pt) {}
void _do_assign(const _myt* _right) {
_node = _right->_node;
_is_rgt_pt = _right->_is_rgt_pt;
}
bool _do_equal(const _myt* _right) {
return _node == _right->_node && _is_rgt_pt == _right->_is_rgt_pt;
}
_nodeptr _node;
bool _is_rgt_pt;
};
template<class _range_map>
class _rm_const_iterator;
template<class _range_map>
class _rm_iterator : public _rm_iter_base<_range_map> {
typedef _rm_iter_base<_range_map> _base;
typedef _rm_iterator<_range_map> _myt;
typedef _rm_const_iterator<_range_map> _ott;
typedef typename _base::_node_type _node_type;
typedef typename _base::_nodeptr _nodeptr;
public:
typedef typename _base::iterator_category iterator_category;
typedef typename _base::value_type value_type;
typedef typename _base::difference_type difference_type;
typedef value_type* pointer;
typedef value_type& reference;
_rm_iterator() : _rm_iter_base<_range_map>() {}
_rm_iterator(_nodeptr _node, bool _is_rgt_pt)
: _rm_iter_base<_range_map>(_node, _is_rgt_pt) {}
_rm_iterator(const _myt& _right)
: _rm_iter_base<_range_map>(_right) {}
_myt operator=(const _myt& _right) {
if(this != &_right) {
this->_do_assign(&_right);
}
return *this;
}
bool operator==(const _myt& _right) {
return this->_do_equal(&_right);
}
bool operator!=(const _myt& _right) {
return !operator==(_right);
}
bool operator==(const _ott& _right) {
return this->_do_equal(&_right);
}
bool operator!=(const _ott& _right) {
return !operator==(_right);
}
reference operator*() {
return this->_is_rgt_pt ? this->_node->_end : this->_node->_start;
}
pointer operator->() {
return this->_is_rgt_pt ? &this->_node->_end : &this->_node->_start;
}
_myt operator++() {
this->_is_rgt_pt = _node_type::_next(&this->_node, this->_is_rgt_pt);
return *this;
}
_myt operator++(int) {
_myt _ret = *this;
operator++();
return _ret;
}
_myt operator--() {
this->_is_rgt_pt = _node_type::_prev(&this->_node, this->_is_rgt_pt);
return *this;
}
_myt operator--(int) {
_myt _ret = *this;
operator--();
return _ret;
}
};
template<class _range_map>
class _rm_const_iterator : public _rm_iter_base<_range_map> {
typedef _rm_iter_base<_range_map> _base;
typedef _rm_const_iterator<_range_map> _myt;
typedef _rm_iterator<_range_map> _ott;
typedef typename _base::_node_type _node_type;
typedef typename _base::_nodeptr _nodeptr;
public:
typedef typename _base::iterator_category iterator_category;
typedef typename _base::value_type value_type;
typedef typename _base::difference_type difference_type;
typedef const value_type* pointer;
typedef const value_type& reference;
_rm_const_iterator() : _rm_iter_base<_range_map>() {}
_rm_const_iterator(_nodeptr _node, bool _is_rgt_pt)
: _rm_iter_base<_range_map>(_node, _is_rgt_pt) {}
_rm_const_iterator(const _myt& _right)
: _rm_iter_base<_range_map>(_right) {}
_myt operator=(const _myt& _right) {
if(this != &_right) {
this->_do_assign(&_right);
}
return *this;
}
_rm_const_iterator(const _ott& _right)
: _rm_iter_base<_range_map>(_right) {}
_myt operator=(const _ott& _right) {
this->_do_assign(&_right);
return *this;
}
bool operator==(const _myt& _right) {
return this->_do_equal(&_right);
}
bool operator!=(const _myt& _right) {
return !operator==(_right);
}
bool operator==(const _ott& _right) {
return this->_do_equal(&_right);
}
bool operator!=(const _ott& _right) {
return !operator==(_right);
}
reference operator*() {
return this->_is_rgt_pt ? this->_node->_end : this->_node->_start;
}
pointer operator->() {
return this->_is_rgt_pt ? &this->_node->_end : &this->_node->_start;
}
_myt operator++() {
this->_is_rgt_pt = _node_type::_next(&this->_node, this->_is_rgt_pt);
return *this;
}
_myt operator++(int) {
_myt _ret = *this;
operator++();
return _ret;
}
_myt operator--() {
this->_is_rgt_pt = _node_type::_prev(&this->_node, this->_is_rgt_pt);
return *this;
}
_myt operator--(int) {
_myt _ret = *this;
operator--();
return _ret;
}
};
}
#endif /* RM_ITER_HPP */

View file

@ -0,0 +1,271 @@
// (C) Beneficii. Released under Creative Commons license.
#ifndef BENEFICII_RANGE_MAP_RM_NODE_HPP
#define BENEFICII_RANGE_MAP_RM_NODE_HPP
#include "rm_base.h"
namespace beneficii {
// the nodes the are allocated in memory by the range_map; the range_map_item used
// is constructed in this node; start and end points are kept track of here
// nothing outside the range_map library needs to call on _range_node, except on the
// individual points (which are of value_type) through the range_map iterators
// void* are used for the connecting nodes and templates for static functions,
// because the allocator may use a wrapper class for the node pointer.
template<class _key, class _mpd>
struct _range_node {
typedef _range_node<_key, _mpd> _myt;
struct _point {
_point(void* _node) : _node((_myt*) _node) {}
//returns whether current point is right end point
bool is_rgt_pt() const {
return this == &_node->_end;
}
//returns point pointed to
const _key& cur_pt() const {
return !is_rgt_pt() ? _node->_range.get_left() : _node->_range.get_right();
}
//returns point other than that pointed too
const _key& opp_pt() const {
return is_rgt_pt() ? _node->_range.get_left() : _node->_range.get_right();
}
//returns start point
const _key& start_pt() const {
return _node->_range.get_left();
}
//returns end point
const _key& end_pt() const {
return _node->_range.get_right();
}
_key width() const {
return _node->_range.width();
}
//returns reference to mapped value
_mpd& mapped() {
return _node->_range.mapped();
}
//returns const_reference to mapped value
const _mpd& mapped() const {
return _node->_range.mapped();
}
//returns const_reference to point on opposite end
const _point& opposite_pt() const {
return is_rgt_pt() ? _node->_start : _node->_end;
}
//returns const range_map_item
const range_map_item<_key, _mpd>& range() const {
return _node->_range;
}
private:
_myt* _node;
};
range_map_item<_key, _mpd> _range;
void* _parent;
void* _left;
void* _subtree;
void* _right;
int _color;
_point _start;
_point _end;
template<class _np>
static _np _get_parent(_np _n) {
return (_np) _n->_parent;
}
template<class _np>
static _np _grandparent(_np _n) {
_n = _get_parent(_n);
if(_n == nullptr) return nullptr;
if(_is_root(_n)) return nullptr;
return _get_parent(_n);
}
template<class _np>
static _np _sibling(_np _n) {
if(_is_root(_n)) return nullptr;
_np _m = _get_parent(_n);
if(_m == nullptr) return nullptr;
return _n == (_np) _m->_left ? (_np) _m->_right : (_np) _m->_left;
}
template<class _np>
static _np _aunt(_np _n) {
_n = _get_parent(_n);
if(_n == nullptr) return nullptr;
if(_is_root(_n)) return nullptr;
return _sibling(_n);
}
template<class _np>
static int _get_color(_np _n) {
return _n == nullptr ? _black : _n->_color;
}
template<class _np>
static bool _is_root(_np _n) {
return _n->_parent == nullptr || _n == (_np) ((_np) _n->_parent)->_subtree;
}
template<class _np>
static _np _min(_np _n) {
while(_n->_left != nullptr)
_n = (_np) _n->_left;
return _n;
}
template<class _np>
static _np _max(_np _n) {
while(_n->_right != nullptr)
_n = (_np) _n->_right;
return _n;
}
template<class _np>
static _np _next(_np _n) {
if(_n->_right == nullptr) {
while(_n->_parent != nullptr && _n == ((_np) _n->_parent)->_right)
_n = (_np) _n->_parent;
_n = (_np) _n->_parent;
} else {
_n = _min((_np) _n->_right);
}
return _n;
}
template<class _np>
static _np _prev(_np _n) {
if(_n->_left == nullptr) {
while(_n->_parent != nullptr && _n == (_np) ((_np) _n->_parent)->_left)
_n = _get_parent(_n);
_n = _get_parent(_n);
} else {
_n = _max((_np) _n->_left);
}
return _n;
}
template<class _np>
static _np _next_s(_np _n) {
if(_n->_right == nullptr) {
while(_n->_parent != nullptr && _n == (_np) ((_np) _n->_parent)->_right)
_n = (_np) _n->_parent;
if(_is_root(_n))
_n = nullptr;
else
_n = _get_parent(_n);
} else {
_n = _min((_np) _n->_right);
}
return _n;
}
template<class _np>
static _np _prev_s(_np _n) {
if(_n->_left == nullptr) {
while(_n->_parent != nullptr && _n == (_np) ((_np) _n->_parent)->_left)
_n = (_np) _n->_parent;
if(_is_root(_n))
_n = nullptr;
else
_n = _get_parent(_n);
} else {
_n = _max((_np) _n->_left);
}
return _n;
}
//moving functions for iterators
template<class _np>
static bool _next(_np* _n, bool _is_rgt_pt) {
bool _ret = _is_rgt_pt;
if(_is_rgt_pt) {
if((*_n)->_right == nullptr) {
while((*_n)->_parent != nullptr && *_n == (_np) ((_np) (*_n)->_parent)->_right)
*_n = _get_parent(*_n);
if((*_n)->_parent != nullptr) {
if(*_n == (_np) ((_np) (*_n)->_parent)->_subtree)
_ret = true;
else
_ret = false;
*_n = _get_parent(*_n);
} else {
*_n = nullptr;
_ret = false;
}
} else {
*_n = _min((_np) (*_n)->_right);
_ret = false;
}
} else {
if((*_n)->_subtree == nullptr) {
_ret = true;
} else {
*_n = _min((_np) (*_n)->_subtree);
_ret = false;
}
}
return _ret;
}
template<class _np>
static bool _prev(_np* _n, bool _is_rgt_pt) {
bool _ret = _is_rgt_pt;
if(_is_rgt_pt) {
if((*_n)->_subtree == nullptr) {
_ret = false;
} else {
*_n = _max((_np) (*_n)->_subtree);
_ret = true;
}
} else {
if((*_n)->_left == nullptr) {
while((*_n)->_parent != nullptr && *_n == (_np) ((_np) (*_n)->_parent)->_left)
*_n = _get_parent(*_n);
if((*_n)->_parent != nullptr) {
if(*_n == (_np) ((_np) (*_n)->_parent)->_subtree)
_ret = false;
else
_ret = true;
*_n = _get_parent(*_n);
} else {
*_n = nullptr;
_ret = false;
}
} else {
*_n = _max((_np) (*_n)->_left);
_ret = true;
}
}
return _ret;
}
static const int _black = 0;
static const int _red = 1;
};
/*#if __cplusplus >= 201103L
template<class _key, class _mpd>
using range_map_point = _range_node<_key, _mpd>::_point;
#endif*/
}
#endif /* RM_NODE_HPP */

File diff suppressed because it is too large Load diff

View file

@ -1334,6 +1334,7 @@ include_directories(
../libraries/ZVulkan/include
../libraries/ZWidget/include
../libraries/webp/include
../libraries/range_map/include
${SYSTEM_SOURCES_DIR}
)