Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Source/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ check:
@bin/deque_demo
@bin/list_demo
@bin/Rb_tree_test
@bin/set_test
clean:
@rm -r bin
distclean: clean
162 changes: 162 additions & 0 deletions Source/header/set.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/**
* file: set.h
* date: 2018/05/16
* author: F_TD5X(jhx)
**/

#ifndef _CUSTL_SET_H
#define _CUSTL_SET_H

#include "tree.h"

namespace custl {

template <typename _Key, typename _Compare = std::less<_Key>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std是什么鬼

typename _Alloc = _Key>
class set;

template <typename _Key, typename _Compare, class _Alloc>
class set {
public:
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;

private:
typedef _Rb_tree<key_type, value_type, std::_Identity<value_type>, key_compare,
_Alloc>
_Rep_type;
_Rep_type _M_t;

public:
typedef typename _Rep_type::const_pointer pointer;
typedef typename _Rep_type::const_pointer const_pointer;
typedef typename _Rep_type::const_reference reference;
typedef typename _Rep_type::const_reference const_reference;
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
typedef typename _Rep_type::allocator_type allocator_type;
set() : _M_t(_Compare(), allocator_type()) {}
explicit set(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) {}

set(const set<_Key, _Compare, _Alloc>& __x) : _M_t(__x._M_t) {}
set<_Key, _Compare, _Alloc>& operator=(
const set<_Key, _Compare, _Alloc>& __x) {
_M_t = __x._M_t;
return *this;
}
template <typename _InputIterator>
set(_InputIterator __first, _InputIterator __last)
: _M_t(_Compare(), allocator_type()) {
_M_t.insert_unique(__first, __last);
}

template <typename _InputIterator>
set(_InputIterator __first, _InputIterator __last, const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) {
_M_t.insert_unique(__first, __last);
}

key_compare key_comp() const { return _M_t.key_comp(); }
value_compare value_comp() const { return _M_t.key_comp(); }
allocator_type get_allocator() const { return _M_t.get_allocator(); }

iterator begin() const { return _M_t.begin(); }
iterator end() const { return _M_t.end(); }
//reverse_iterator rbegin() const { return _M_t.rbegin(); }
//reverse_iterator rend() const { return _M_t.rend(); }
bool empty() const { return _M_t.empty(); }
size_type size() const { return _M_t.size(); }
size_type max_size() const { return _M_t.max_size(); }
void swap(set<_Key, _Compare, _Alloc>& __x) { _M_t.swap(__x._M_t); }

std::pair<iterator, bool> insert(const value_type& __x) {
std::pair<typename _Rep_type::iterator, bool> __p =
_M_t.insert_unique(__x);
return std::pair<iterator, bool>(__p.first, __p.second);
}
iterator insert(iterator __position, const value_type& __x) {
typedef typename _Rep_type::iterator _Rep_iterator;
return _M_t.insert_unique((_Rep_iterator&)__position, __x);
}
template <class _InputIterator>
void insert(_InputIterator __first, _InputIterator __last) {
_M_t.insert_unique(__first, __last);
}
void erase(iterator __position) {
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__position);
}
size_type erase(const key_type& __x) { return _M_t.erase(__x); }
void erase(iterator __first, iterator __last) {
typedef typename _Rep_type::iterator _Rep_iterator;
_M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last);
}
void clear() { _M_t.clear(); }

iterator find(const key_type& __x) const { return _M_t.find(__x); }
size_type count(const key_type& __x) const {
return _M_t.find(__x) == _M_t.end() ? 0 : 1;
}
iterator lower_bound(const key_type& __x) const {
return _M_t.lower_bound(__x);
}
iterator upper_bound(const key_type& __x) const {
return _M_t.upper_bound(__x);
}
std::pair<iterator, iterator> equal_range(const key_type& __x) const {
return _M_t.equal_range(__x);
}
};

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator==(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return __x._M_t == __y._M_t;
}

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator<(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return __x._M_t < __y._M_t;
}

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator!=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return !(__x == __y);
}

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator>(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return __y < __x;
}

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator<=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return !(__y < __x);
}

template <typename _Key, typename _Compare, typename _Alloc>
inline bool operator>=(const set<_Key, _Compare, _Alloc>& __x,
const set<_Key, _Compare, _Alloc>& __y) {
return !(__x < __y);
}

template <typename _Key, typename _Compare, typename _Alloc>
inline void swap(set<_Key, _Compare, _Alloc>& __x,
set<_Key, _Compare, _Alloc>& __y) {
__x.swap(__y);
}

} // namespace custl

#endif
90 changes: 58 additions & 32 deletions Source/header/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,26 +427,26 @@ inline _Rb_tree_node_base* _Rb_tree_rebalance_for_erase(
template <typename _Key, typename _Val, typename _KeyOfValue, typename _Compare,
typename _Alloc = allocator<_Val>>
class _Rb_tree {
protected:
typedef _Rb_tree_node_base* _Base_ptr;
typedef _Rb_tree_color _Color_type;
protected:
typedef _Rb_tree_node_base* _Base_ptr;
typedef _Rb_tree_color _Color_type;
typedef _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> _Self;

public:
typedef _Key key_type;
typedef _Val value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* const_pointer;
typedef const value_type& const_reference;
typedef _Rb_tree_node<_Val>* _Link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
public:
typedef _Key key_type;
typedef _Val value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef const value_type* const_pointer;
typedef const value_type& const_reference;
typedef _Rb_tree_node<_Val>* _Link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;

allocator_type get_allocator() const { return allocator_type(); }

protected:
protected:
_Link_type _M_header;
_Link_type _M_get_node() {
return allocator<_Rb_tree_node<_Val>>::allocate(1);
Expand Down Expand Up @@ -475,7 +475,7 @@ class _Rb_tree {
_M_put_node(__p);
}

protected:
protected:
size_type _M_node_count;
_Compare _M_key_compare;

Expand Down Expand Up @@ -529,16 +529,16 @@ class _Rb_tree {
return (_Link_type)_Rb_tree_node_base::_S_maximum(__x);
}

public:
public:
typedef _Rb_tree_iterator<_Val> iterator;
typedef _Rb_tree_const_iterator<_Val> const_iterator;

private:
private:
iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v);
_Link_type _M_copy(_Link_type __x, _Link_type __p);
void _M_erase(_Link_type __x);

public:
public:
_Rb_tree() : _M_node_count(0), _M_key_compare() {
_M_header = _M_get_node();
_M_empty_initialize();
Expand Down Expand Up @@ -570,31 +570,31 @@ class _Rb_tree {
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& operator=(
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x);

private:
private:
void _M_empty_initialize() {
_S_color(_M_header) = red;
_M_root() = nullptr;
_M_rightmost() = _M_leftmost() = _M_header;
}

public:
public:
_Compare key_comp() const { return _M_key_compare; }
iterator begin() { return _M_leftmost(); }
iterator end() { return _M_header; }
const_iterator begin() const { return _M_leftmost(); }
const_iterator end() const { return _M_header; }

bool empty() { return _M_node_count == 0; }
bool empty() const { return _M_node_count == 0; }
size_type size() const { return _M_node_count; }
size_type max_size() const { return size_type(-1); }

void swap(_Self& __t) {
swap(_M_header, __t._M_header);
swap(_M_node_count, __t._M_node_count);
swap(_M_key_compare, __t._M_key_compare);
std::swap(_M_header, __t._M_header);
std::swap(_M_node_count, __t._M_node_count);
std::swap(_M_key_compare, __t._M_key_compare);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std废话啊。。。又没人写 stl_utility 。

}

public:
public:
std::pair<iterator, bool> insert_unique(const value_type& __x);
iterator insert_equal(const value_type& __x);
iterator insert_unique(iterator __pos, const value_type& __x);
Expand All @@ -603,6 +603,10 @@ class _Rb_tree {
void insert_unique(const value_type* __first, const value_type* __last);
void insert_equal(const_iterator __first, const_iterator __last);
void insert_equal(const value_type* __first, const value_type* __last);
template <typename _InsertIterator>
void insert_unique(_InsertIterator __first, _InsertIterator __last);
template <typename _InsertIterator>
void insert_equal(_InsertIterator __first, _InsertIterator __last);

void erase(iterator __pos);
size_type erase(const key_type& __x);
Expand Down Expand Up @@ -845,25 +849,29 @@ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_equal(
}
}

template <typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Cmp,
typename _Alloc>
void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::insert_equal(
const _Val* __first, const _Val* __last) {
for (; __first != __last; ++__first) insert_equal(*__first);
}

template <typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Cmp,
typename _Alloc>
void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::insert_equal(
const_iterator __first, const_iterator __last) {
for (; __first != __last; ++__first) insert_equal(*__first);
}

template <typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Cmp,
typename _Alloc>
void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::insert_unique(
const _Val* __first, const _Val* __last) {
for (; __first != __last; ++__first) insert_unique(*__first);
}

template <typename _Key, typename _Val, typename _KoV, typename _Cmp, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Cmp,
typename _Alloc>
void _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::insert_unique(
const_iterator __first, const_iterator __last) {
for (; __first != __last; ++__first) insert_unique(*__first);
Expand Down Expand Up @@ -891,7 +899,8 @@ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::erase(const _Key& __x) {
return __n;
}

template <typename _Key, typename _Val, typename _KoV, typename _Compare, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Compare,
typename _Alloc>
typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
_Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_M_copy(_Link_type __x,
_Link_type __p) {
Expand Down Expand Up @@ -1073,7 +1082,8 @@ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::equal_range(
return std::pair<iterator, iterator>(lower_bound(__k), upper_bound(__k));
}

template <typename _Key, typename _Val, typename _KoV, typename _Compare, typename _Alloc>
template <typename _Key, typename _Val, typename _KoV, typename _Compare,
typename _Alloc>
inline std::pair<
typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator,
typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator>
Expand Down Expand Up @@ -1129,6 +1139,22 @@ bool _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::__verify() const {
return true;
}

template <typename _Key, typename _Val, typename _KeyOfValue, typename _Compare,
typename _Alloc>
template <typename _II>
void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(
_II __first, _II __last) {
for (; __first != __last; ++__first) insert_unique(*__first);
}

template <typename _Key, typename _Val, typename _KeyOfValue, typename _Compare,
typename _Alloc>
template <typename _II>
void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_equal(
_II __first, _II __last) {
for (; __first != __last; ++__first) insert_equal(*__first);
}

template <typename _Key, typename _Val, typename _KeyOfValue, typename _Compare,
typename _Alloc = allocator<_Val>>
struct rb_tree : public _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc> {
Expand Down
6 changes: 6 additions & 0 deletions Source/test/Rb_tree_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ int main() {
custl::_Rb_tree<int, int, std::_Identity<int>, std::less<int>>::iterator
it = tree.begin();
for (int i = 1; it != tree.end(); ++it, ++i) assert(*it == i);
assert(*(++tree.lower_bound(2)) == 3);
assert(*tree.upper_bound(2) == 3);

// Cleaer test
tree.clear();
Expand Down Expand Up @@ -74,6 +76,7 @@ int main() {

// Structure verify
assert(tree.__verify());
tree.clear();

// copy test
custl::_Rb_tree<int, int, std::_Identity<int>, std::less<int>> t1;
Expand All @@ -96,5 +99,8 @@ int main() {
t4.insert_unique(Node(i));
assert((*(++t4.begin())).a == 2);

//swap test
t1.swap(tree);

std::cout << "Rb tree Unit test passed" << std::endl;
}
Loading