Skip to content

Commit

Permalink
feat(ordered container): ordered container & fix __bitree__::_S_check
Browse files Browse the repository at this point in the history
  • Loading branch information
1nchy committed Jan 13, 2023
1 parent b41aeeb commit c3dc71d
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 10 deletions.
72 changes: 72 additions & 0 deletions ordered_map.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef _ASP_ORDERED_MAP_HPP_
#define _ASP_ORDERED_MAP_HPP_

#include <functional>

#include "basic_param.hpp"
#include "rb_tree.hpp"

namespace asp {

template <typename _Key, typename _Tp,
typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp>>
> class ordered_map;

template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
class ordered_map {
typedef ordered_map<_Key, _Tp, _Compare, _Alloc> self;
typedef rb_tree<_Key, std::pair<const _Key, _Tp>, _select_0x, true, _Compare, _Alloc> map_rbt;
map_rbt _r;
public:
typedef typename map_rbt::key_type key_type;
typedef typename map_rbt::value_type value_type;
typedef typename map_rbt::mapped_type mapped_type;
typedef typename map_rbt::key_compare key_compare;
typedef typename map_rbt::iterator iterator;
typedef typename map_rbt::const_iterator const_iterator;
typedef typename map_rbt::ireturn_type ireturn_type;
typedef typename map_rbt::insert_status insert_status;
typedef typename map_rbt::ext_iterator ext_iterator;
typedef typename map_rbt::ext_key ext_key;
typedef typename map_rbt::ext_value ext_value;

/// (de)constructor
ordered_map() = default;
ordered_map(const self& _x) : _r(_x._r) {}
virtual ~ordered_map() = default;

/// implement
size_type size() const { return _r.size(); }
bool empty() const { return _r.empty(); }
iterator begin() { return _r.begin(); }
iterator end() { return _r.end(); }
const_iterator cbegin() const { return _r.cbegin(); }
const_iterator cend() const { return _r.cend(); }
ireturn_type insert(const value_type& _v) { return _r.insert(_v); }
ireturn_type set(const key_type& _k, const mapped_type& _m) { return _r.insert(value_type(_k, _m)); }
size_type erase(const key_type& _k) { return _r.erase(_k); }
size_type count(const key_type& _k) const { return _r.count(_k); }
void clear() { _r.clear(); }
iterator find(const key_type& _k) { return _r.find(_k); }
const_iterator find(const key_type& _k) const { return _r.find(_k); }
#ifdef _CONTAINER_CHECK_
int check() const { return _r.check(); }
#endif // _CONTAINER_CHECK_

/// output
template <typename _K, typename _T, typename _C, typename _A>
friend std::ostream& operator<<(std::ostream& os, const ordered_map<_K, _T, _C, _A>& _um);
// friend std::ostream& operator<<(std::ostream& os, const const_iterator& _i);
};

template <typename _Key, typename _Tp, typename _Comp, typename _Alloc> auto
operator<<(std::ostream& os, const ordered_map<_Key, _Tp, _Comp, _Alloc>& _um)
-> std::ostream& {
os << _um._r;
return os;
};

};

#endif // _ASP_ORDERED_MAP_HPP_
72 changes: 72 additions & 0 deletions ordered_multimap.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef _ASP_ORDERED_MULTI_MAP_HPP_
#define _ASP_ORDERED_MULTI_MAP_HPP_

#include <functional>

#include "basic_param.hpp"
#include "rb_tree.hpp"

namespace asp {

template <typename _Key, typename _Tp,
typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp>>
> class ordered_multimap;

template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
class ordered_multimap {
typedef ordered_multimap<_Key, _Tp, _Compare, _Alloc> self;
typedef rb_tree<_Key, std::pair<const _Key, _Tp>, _select_0x, false, _Compare, _Alloc> mmap_rbt;
mmap_rbt _r;
public:
typedef typename mmap_rbt::key_type key_type;
typedef typename mmap_rbt::value_type value_type;
typedef typename mmap_rbt::mapped_type mapped_type;
typedef typename mmap_rbt::key_compare key_compare;
typedef typename mmap_rbt::iterator iterator;
typedef typename mmap_rbt::const_iterator const_iterator;
typedef typename mmap_rbt::ireturn_type ireturn_type;
typedef typename mmap_rbt::insert_status insert_status;
typedef typename mmap_rbt::ext_iterator ext_iterator;
typedef typename mmap_rbt::ext_key ext_key;
typedef typename mmap_rbt::ext_value ext_value;

/// (de)constructor
ordered_multimap() = default;
ordered_multimap(const self& _x) : _r(_x._r) {}
virtual ~ordered_multimap() = default;

/// implement
size_type size() const { return _r.size(); }
bool empty() const { return _r.empty(); }
iterator begin() { return _r.begin(); }
iterator end() { return _r.end(); }
const_iterator cbegin() const { return _r.cbegin(); }
const_iterator cend() const { return _r.cend(); }
ireturn_type insert(const value_type& _v) { return _r.insert(_v); }
ireturn_type set(const key_type& _k, const mapped_type& _m) { return _r.insert(value_type(_k, _m)); }
size_type erase(const key_type& _k) { return _r.erase(_k); }
size_type count(const key_type& _k) const { return _r.count(_k); }
void clear() { _r.clear(); }
iterator find(const key_type& _k) { return _r.find(_k); }
const_iterator find(const key_type& _k) const { return _r.find(_k); }
#ifdef _CONTAINER_CHECK_
int check() const { return _r.check(); }
#endif // _CONTAINER_CHECK_

/// output
template <typename _K, typename _T, typename _C, typename _A>
friend std::ostream& operator<<(std::ostream& os, const ordered_multimap<_K, _T, _C, _A>& _um);
// friend std::ostream& operator<<(std::ostream& os, const const_iterator& _i);
};

template <typename _Key, typename _Tp, typename _Comp, typename _Alloc> auto
operator<<(std::ostream& os, const ordered_multimap<_Key, _Tp, _Comp, _Alloc>& _um)
-> std::ostream& {
os << _um._r;
return os;
};

};

#endif // _ASP_ORDERED_MULTI_MAP_HPP_
72 changes: 72 additions & 0 deletions ordered_multiset.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef _ASP_ORDERED_MULTI_SET_HPP_
#define _ASP_ORDERED_MULTI_SET_HPP_

#include <functional>

#include "basic_param.hpp"
#include "rb_tree.hpp"

namespace asp {

template <typename _Tp,
typename _Compare = std::less<_Tp>,
typename _Alloc = std::allocator<_Tp>
> class ordered_multiset;

template <typename _Tp, typename _Compare, typename _Alloc>
class ordered_multiset {
typedef ordered_multiset<_Tp, _Compare, _Alloc> self;
typedef rb_tree<_Tp, _Tp, _select_self, false, _Compare, _Alloc> mset_rbt;
mset_rbt _r;
public:
typedef typename mset_rbt::key_type key_type;
typedef typename mset_rbt::value_type value_type;
typedef typename mset_rbt::mapped_type mapped_type;
typedef typename mset_rbt::key_compare key_compare;
typedef typename mset_rbt::iterator iterator;
typedef typename mset_rbt::const_iterator const_iterator;
typedef typename mset_rbt::ireturn_type ireturn_type;
typedef typename mset_rbt::insert_status insert_status;
typedef typename mset_rbt::ext_iterator ext_iterator;
typedef typename mset_rbt::ext_key ext_key;
typedef typename mset_rbt::ext_value ext_value;

/// (de)constructor
ordered_multiset() = default;
ordered_multiset(const self& _x) : _r(_x._r) {}
virtual ~ordered_multiset() = default;

/// implement
size_type size() const { return _r.size(); }
bool empty() const { return _r.empty(); }
iterator begin() { return _r.begin(); }
iterator end() { return _r.end(); }
const_iterator cbegin() const { return _r.cbegin(); }
const_iterator cend() const { return _r.cend(); }
ireturn_type insert(const value_type& _v) { return _r.insert(_v); }
ireturn_type set(const key_type& _k, const mapped_type& _m) { return _r.insert(value_type(_k, _m)); }
size_type erase(const key_type& _k) { return _r.erase(_k); }
size_type count(const key_type& _k) const { return _r.count(_k); }
void clear() { _r.clear(); }
iterator find(const key_type& _k) { return _r.find(_k); }
const_iterator find(const key_type& _k) const { return _r.find(_k); }
#ifdef _CONTAINER_CHECK_
int check() const { return _r.check(); }
#endif // _CONTAINER_CHECK_

/// output
template <typename _T, typename _C, typename _A>
friend std::ostream& operator<<(std::ostream& os, const ordered_multiset<_T, _C, _A>& _um);
// friend std::ostream& operator<<(std::ostream& os, const const_iterator& _i);
};

template <typename _Tp, typename _Comp, typename _Alloc> auto
operator<<(std::ostream& os, const ordered_multiset<_Tp, _Comp, _Alloc>& _um)
-> std::ostream& {
os << _um._r;
return os;
};

};

#endif // _ASP_ORDERED_MULTI_SET_HPP_
72 changes: 72 additions & 0 deletions ordered_set.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef _ASP_ORDERED_SET_HPP_
#define _ASP_ORDERED_SET_HPP_

#include <functional>

#include "basic_param.hpp"
#include "rb_tree.hpp"

namespace asp {

template <typename _Tp,
typename _Compare = std::less<_Tp>,
typename _Alloc = std::allocator<_Tp>
> class ordered_set;

template <typename _Tp, typename _Compare, typename _Alloc>
class ordered_set {
typedef ordered_set<_Tp, _Compare, _Alloc> self;
typedef rb_tree<_Tp, _Tp, _select_self, true, _Compare, _Alloc> set_rbt;
set_rbt _r;
public:
typedef typename set_rbt::key_type key_type;
typedef typename set_rbt::value_type value_type;
typedef typename set_rbt::mapped_type mapped_type;
typedef typename set_rbt::key_compare key_compare;
typedef typename set_rbt::iterator iterator;
typedef typename set_rbt::const_iterator const_iterator;
typedef typename set_rbt::ireturn_type ireturn_type;
typedef typename set_rbt::insert_status insert_status;
typedef typename set_rbt::ext_iterator ext_iterator;
typedef typename set_rbt::ext_key ext_key;
typedef typename set_rbt::ext_value ext_value;

/// (de)constructor
ordered_set() = default;
ordered_set(const self& _x) : _r(_x._r) {}
virtual ~ordered_set() = default;

/// implement
size_type size() const { return _r.size(); }
bool empty() const { return _r.empty(); }
iterator begin() { return _r.begin(); }
iterator end() { return _r.end(); }
const_iterator cbegin() const { return _r.cbegin(); }
const_iterator cend() const { return _r.cend(); }
ireturn_type insert(const value_type& _v) { return _r.insert(_v); }
ireturn_type set(const key_type& _k, const mapped_type& _m) { return _r.insert(value_type(_k, _m)); }
size_type erase(const key_type& _k) { return _r.erase(_k); }
size_type count(const key_type& _k) const { return _r.count(_k); }
void clear() { _r.clear(); }
iterator find(const key_type& _k) { return _r.find(_k); }
const_iterator find(const key_type& _k) const { return _r.find(_k); }
#ifdef _CONTAINER_CHECK_
int check() const { return _r.check(); }
#endif // _CONTAINER_CHECK_

/// output
template <typename _T, typename _C, typename _A>
friend std::ostream& operator<<(std::ostream& os, const ordered_set<_T, _C, _A>& _um);
// friend std::ostream& operator<<(std::ostream& os, const const_iterator& _i);
};

template <typename _Tp, typename _Comp, typename _Alloc> auto
operator<<(std::ostream& os, const ordered_set<_Tp, _Comp, _Alloc>& _um)
-> std::ostream& {
os << _um._r;
return os;
};

};

#endif // _ASP_ORDERED_SET_HPP_
5 changes: 4 additions & 1 deletion rb_tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ class rb_tree : public rb_tree_alloc<_Value, _Alloc> {
typedef typename rbt_alloc::node_alloc_traits node_alloc_traits;

typedef _Key key_type;
typedef _Comp key_compare;
typedef typename base::node_type node_type;
typedef const node_type const_node_type;
typedef typename base::node_type_base node_type_base;
Expand All @@ -264,6 +265,7 @@ class rb_tree : public rb_tree_alloc<_Value, _Alloc> {
typedef typename _ContainerTypeTraits::ext_iterator ext_iterator;
typedef typename _ContainerTypeTraits::ext_value ext_value;
typedef typename _ContainerTypeTraits::mapped_type mapped_type;
typedef _ExtKey ext_key;

rb_tree_header<_Value> _m_impl;
_ExtKey _m_extract_key;
Expand Down Expand Up @@ -922,7 +924,8 @@ rb_tree<_Key, _Value, _ExtKey, _UniqueKey, _Comp, _Alloc>::equal_range(const key

template <typename _Key, typename _Value, typename _ExtKey, bool _UniqueKey, typename _Comp, typename _Alloc> auto
rb_tree<_Key, _Value, _ExtKey, _UniqueKey, _Comp, _Alloc>::check() const -> int {
auto _bt_check = __bitree__::_S_check(&_m_impl._header, _m_impl._node_count);
typedef rb_tree<_Key, _Value, _ExtKey, _UniqueKey, _Comp, _Alloc> rb_tree_t;
auto _bt_check = __bitree__::_S_check<_Comp, typename rb_tree_t::ext_key>(&_m_impl._header, _m_impl._node_count);
auto _rb_check = __rb_tree__::_S_check(&_m_impl._header);
return _bt_check + (_rb_check>0 ? 100 : 0) + _rb_check;
};
Expand Down
6 changes: 0 additions & 6 deletions set.hpp

This file was deleted.

8 changes: 5 additions & 3 deletions tree_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "node.hpp"

#include "associative_container_aux.hpp"

namespace asp {

template <typename _Tp> struct bitree_node;
Expand Down Expand Up @@ -54,7 +56,7 @@ template <typename _Node> _Node* _S_bitree_node_decrease(_Node* _x);
/**
* @brief check the order of binary tree.
*/
template <typename _Node> int _S_check(const _Node* _header, size_type _n);
template <typename _Comp, typename _ExtKey, typename _Node> int _S_check(const _Node* _header, size_type _n);
};

template <typename _Tp> struct bitree_node : node<_Tp> {
Expand Down Expand Up @@ -303,7 +305,7 @@ template <typename _Node> _Node* _S_bitree_node_decrease(_Node* _x) {
* 2 : error in order ;
* 3 : error in %_node_count .
*/
template <typename _Node> int _S_check(const _Node* _header, size_type _n) {
template <typename _Comp, typename _ExtKey, typename _Node> int _S_check(const _Node* _header, size_type _n) {
const _Node* _root = _header->_parent;
if (_root == nullptr) { return 0; }
const _Node* _leftmost = _S_minimum(_root);
Expand All @@ -328,7 +330,7 @@ template <typename _Node> int _S_check(const _Node* _header, size_type _n) {
}
if (_traverse_node.size() != _n) { return 3; }
for (int _i = 0; _i < _traverse_node.size() - 1; ++_i) {
if (_traverse_node[_i]->val() > _traverse_node[_i+1]->val()) {
if (_Comp()(_ExtKey()(_traverse_node[_i+1]->val()), _ExtKey()(_traverse_node[_i]->val()))) {
return 2;
}
}
Expand Down

0 comments on commit c3dc71d

Please sign in to comment.