shared_ptr | weak_ptr | allocator | Compare | type_traits...
插入和析构测试
#include "redBlackTreeMap.hpp"
void test(void){
{
map<int, int> m;
m.insert({1,1});
m.insert({5,3});
m.insert({3,2});
m.insert({7,9});
m.iterate();
}
}
int main( void ){
test();
std::atexit([]{ std::cout.flush(); });
return 0;
}
很完美 下面是实现
#include <iostream>
#include <functional>
#include <memory>
#include <utility>
#include <type_traits>
#include <optional>
#include <initializer_list>
#include <cassert>
template <class Key,
class T,
class Compare
= std::less<Key>,
class Allocator
= std::allocator<std::pair<const Key, T>>>
class map{
public:
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<const Key, T> value_type;
private:
typedef std::pair<Key, T> non_const_value_type;
public:
typedef std::size_t size_type;
typedef std::ptrdiff_t diference_type;
typedef Compare key_compare;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef Allocator allocator_type;
typedef typename std::allocator_traits<Allocator>::pointer
pointer;
typedef typename std::allocator_traits<Allocator>::const_pointer
const_pointer;
public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
{
friend class map<Key, T, Compare, Allocator>;
protected:
Compare comp;
value_compare(Compare __comp) : comp(__comp) {}
private:
[[nodiscard]] inline bool
operator()(const non_const_value_type& x, const value_type& y)
{ return comp(x.first,y.first); }
[[nodiscard]] inline bool
operator()(const non_const_value_type& x, const non_const_value_type& y)
{ return comp(x.first,y.first); }
public:
[[nodiscard]] inline bool
operator()(const value_type& x, const value_type& y)
{ return comp(x.first,y.first); }
};
private:
enum Colors
: unsigned char{
RED,
BLACK,
};
enum Orientions
: unsigned char{
LEFT,
RIGHT,
ROOT
};
private:
struct Node{
std::shared_ptr<Node> children[2];
std::weak_ptr<Node> parent;
Colors color;
non_const_value_type value;
~Node(void){ std::puts("~Node()..."); }
Node(void) noexcept = default;
Node(Node&&) noexcept = default;
explicit Node(const Node& ) = delete;
Node(const value_type& __value) noexcept : value(__value) {}
Node(Colors __color) noexcept : color(__color) {}
Node(Colors __color, const value_type& __value)
noexcept(noexcept(Node(__value)))
: Node(__value){ color = __color; }
};
private:
typedef std::shared_ptr<Node> SharedPtr;
typedef std::weak_ptr<Node> WeakPtr;
typedef Node * RawPtr;
typedef typename std::allocator_traits<Allocator>
::template rebind_traits<Node>::allocator_type
allocator;
private:
allocator Alloc;
private:
SharedPtr NIL;
SharedPtr root;
private:
constexpr void Sentinel( void ){
auto p { std::allocator_traits<allocator>::allocate(Alloc, 1U) };
std::allocator_traits<allocator>::construct(Alloc, p, Colors::BLACK, value_type{} );
NIL = SharedPtr{p, [this]<typename Pointer>(Pointer p){
p->children[Orientions::LEFT].reset();
p->children[Orientions::RIGHT].reset();
p->parent.reset();
std::allocator_traits<allocator>::destroy(Alloc, p);
std::allocator_traits<allocator>::deallocate(Alloc, p, 1U);
puts("[report]:SharedPtr(SENTINEL) destroy and deallocate...");
}};
NIL->children[Orientions::LEFT] = NIL;
NIL->children[Orientions::RIGHT] = NIL;
NIL->parent = NIL;
}
template <class... Args>
constexpr [[nodiscard]] SharedPtr Construct(Args&&...args){
auto p { std::allocator_traits<allocator>::allocate(Alloc, 1U) };
std::allocator_traits<allocator>::construct(Alloc, p, std::forward<Args>(args)...);
SharedPtr R{p, [this]<typename Pointer>(Pointer p){
std::allocator_traits<allocator>::destroy(Alloc, p);
std::allocator_traits<allocator>::deallocate(Alloc, p, 1U);
puts("[report]:SharedPtr(NODE) destroy and deallocate...");
}};
R->children[Orientions::LEFT] = NIL;
R->children[Orientions::RIGHT] = NIL;
R->parent = NIL;
return R;
}
private:
size_type count { 0U };
public:
map(void) { Sentinel(); root = NIL; }
map(map&&) noexcept = default;
map(const map& other) {}
~map(void) = default;
public:
key_compare key_comp(void)const
{ return key_compare(); }
value_compare value_comp(void)const
{ return value_compare(key_comp()); }
void insert(const value_type& x){
insert(root, x);
}
void iterate(void){ iterate(root); }
private:
void insert(SharedPtr& o, const value_type& x){
void* current = reinterpret_cast<void*>(&o);
void* parent = reinterpret_cast<void*>(&o->parent);
while(!(*(SharedPtr*)current == NIL)){
parent = current;
current = reinterpret_cast<void*>
(&(*(SharedPtr*)current)->children
[static_cast<unsigned>(value_comp()
((*(SharedPtr*)current)->value, x))]);
}
*(SharedPtr*)current = Construct(Colors::RED, x);
(*(SharedPtr*)current)->parent = *(WeakPtr*)parent;
}
void insertMaintainer(SharedPtr& o){
assert((o == NIL)
&& "insertMaintainer called while NIL given");
if(rootChecker(o)) return;
if(SharedPtr(o->parent)->color == Colors::BLACK) return;
if(rootChecker(SharedPtr(o->parent)))
return (void)(SharedPtr(o->parent)->color = Colors::BLACK);
if(uncleChecker(o) && uncleGetter(o)->color == Colors::RED){
SharedPtr(o->parent)->color = Colors::BLACK;
uncleGetter(o)->color = Colors::BLACK;
grandParentGetter(o)->color = Colors::RED;
return (void)(insertMaintainer(grandParentGetter(o)));
}
if( !uncleChecker(o) || uncleGetter(o)->color == Colors::BLACK){
if(!(orient(o) == orient(SharedPtr(o->parent))))
rotate(SharedPtr(o->parent), orient(o) ^ 1 );
}
}
void parentMaintainer(const SharedPtr& o) {
for( auto i {0U}; i < 2; ++i)
if(!(o->children[i] == NIL))
o->childrent[i]->parent = WeakPtr(o);
}
void rotate(SharedPtr& o, Orientions dir) {
auto oriention { orient(o) };
auto& parent = SharedPtr(o->parent);
auto& successor = o->children[dir ^ 1];
o->children[dir ^ 1] = successor->children[dir];
successor->chidren[dir] = o;
parentMaintainer(o);
parentMaintainer(successor);
if(oriention == Orientions::ROOT)
return (void)(root = successor);
parent->children[oriention] = successor;
}
void iterate(SharedPtr& o){
if(o == NIL)return;
iterate(o->children[Orientions::LEFT]);
std::cout << o->value.first << '\n';
iterate(o->children[Orientions::RIGHT]);
}
[[nodiscard]] inline bool
leafChecker(const SharedPtr& o) const noexcept{
return (!(o == NIL)
&& o->children[Orientions::LEFT] == NIL
&& o->children[Orientions::RIGHT] == NIL);
}
[[nodiscard]] inline bool
rootChecker(const SharedPtr& o) const noexcept{
return (!(o == NIL) && SharedPtr(o->parent) == NIL);
}
[[nodiscard]] Orientions
orient(const SharedPtr& o) const noexcept{
assert((o == NIL)
&& "orient function called while NIL was given");
if(rootChecker(o)) return Orientions::ROOT;
if(SharedPtr(o->parent)->children[Orientions::LEFT] == o)
return Orientions::LEFT;
return Orientions::RIGHT;
}
[[nodiscard]] inline SharedPtr&
siblingGetter(const SharedPtr& o) const noexcept{
assert((rootChecker(o))
&& "siblingGetter called while root was given...");
return SharedPtr(o->parent)->children[orient(o)];
}
[[nodiscard]] inline bool
siblingChecker(const SharedPtr& o) const noexcept{
return !rootChecker(o) && !(siblingGetter(o) == NIL);
}
[[nodiscard]] inline SharedPtr&
uncleGetter(const SharedPtr& o) const noexcept{
assert(rootChecker(o)
&& "uncleGetter called while root was given...");
return SharedPtr(o->parent)->siblingGetter();
}
[[nodiscard]] inline bool
uncleChecker(const SharedPtr& o) const noexcept{
return !rootChecker(o) && !(uncleGetter(o) == NIL);
}
[[nodiscard]] inline SharedPtr&
grandParentGetter(const SharedPtr& o) const noexcept{
assert(rootChecker(o)
&& "grandParentGetter called while root was given...");
return SharedPtr(SharedPtr(o->parent)->parent);
}
[[nodiscard]] inline bool
grandParentChecker(const SharedPtr& o) const noexcept{
return !rootChecker(o) && !(grandParentGetter(o) == NIL);
}
};