ft_containers/containers/map.hpp
2022-11-24 18:14:52 +01:00

462 lines
8.8 KiB
C++

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* map.hpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/11/24 08:50:18 by apommier #+# #+# */
/* Updated: 2022/11/24 17:45:57 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
#pragma once
#include "./iterators/bidirectionnal_iterator.hpp"
#include "./iterators/pair.hpp"
#define RED 1
#define BLACK 0
//typedef typename Alloc::template rebind<s_node<T> >::other
namespace ft
{
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>>
class map
{
public :
//-----------------------------
//---------MEMBER TYPE---------
//-----------------------------
struct node;
typedef Key key_type;
typedef T mapped_type;
typedef std::pair<const Key, T> value_type;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef Compare key_compare;
typedef Allocator allocator_type;
typedef typename Allocator::template rebind<node>::other node_allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::const_pointer const_pointer;
typedef ft::bidirectionnal_iterator iterator;
typedef ft::bidirectionnal_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
struct node{
bool color;
node *parent;
node *right;
node *left;
value_type pair;
node(key_type &key, mapped_type &val)
: pair(make_pair(key, val)), parent(0), right(this->_end), left(this->_end), color(0) {}
};
//-----------------------------
//-----PRIVATE MEMBER TYPE-----
//-----------------------------
private :
key_compare _comp;
allocator_type _alloc;
node_allocator_type _node_alloc;
node *_root;
node *_end;
size_type _size;
public :
//---------------------------------------
//---------COPLIEN FORM FUNCTION---------
//---------------------------------------
explicit map( const Compare& comp = Compare(), const Allocator& alloc = Allocator() )
{
}
template< class InputIt >
map( InputIt first, InputIt last, const Compare& comp = Compare(), const Allocator& alloc = Allocator() )
{
}
map( const map& x)
{
}
~map()
{
}
map& operator=( const map& x )
{
}
//----------------------------------
//---------MEMBER FUNCTION----------
//----------------------------------
//-------------------------
//--------Iterators--------
//-------------------------
iterator begin()
{
}
const_iterator begin() const
{
}
iterator end()
{
}
const_iterator end() const
{
}
reverse_iterator rbegin()
{
}
const_reverse_iterator rbegin() const
{
}
reverse_iterator rend()
{
}
const_reverse_iterator rend() const
{
}
//------------------------
//--------Capacity--------
//------------------------
bool empty() const
{
if (!_size)
return (1);
return(0);
}
size_type size() const
{
return (_size);
}
size_type max_size() const
{
return (_alloc.max_size());
}
//------------------------------
//--------Element access--------
//------------------------------
mapped_type& operator[] (const key_type& k)
{
}
mapped_type& at (const key_type& k)
{
}
const mapped_type& at (const key_type& k) const
{
}
//-------------------------
//--------Modifiers--------
//-------------------------
ft::pair<iterator,bool> insert (const value_type& val)
{
}
iterator insert (iterator position, const value_type& val)
{
}
template <class InputIterator> void insert (InputIterator first, InputIterator last)
{
}
void erase (iterator position)
{
}
size_type erase (const key_type& k)
{
}
void erase (iterator first, iterator last)
{
}
void swap (map& x)
{
}
void clear()
{
}
//-------------------------
//--------Observers--------
//-------------------------
key_compare key_comp() const
{
}
value_compare value_comp() const
{
}
//-------------------------
//-------Operations--------
//-------------------------
iterator find (const key_type& k)
{
}
const_iterator find (const key_type& k) const
{
}
size_type count (const key_type& k) const
{
}
iterator lower_bound (const key_type& k)
{
}
const_iterator lower_bound (const key_type& k) const
{
}
iterator upper_bound (const key_type& k)
{
}
const_iterator upper_bound (const key_type& k) const
{
}
ft::pair<const_iterator,const_iterator> equal_range (const key_type& k) const
{
}
ft::pair<iterator,iterator> equal_range (const key_type& k)
{
}
/* ************************************************************************** */
/* ******************************TREE FUNCTIONS****************************** */
/* ************************************************************************** */
private :
template<typename T_node>
node *new_node(key_type key, mapped_type val)
{
node *ret;
ret = _node_alloc::allocate(1);
_node_alloc::construct(ret, node(key, val));
return (ret);
}
void left_rotate(node *elem) //x == elem
{
node *pt_right = elem->right;
elem->right = pt_right->left;
if (elem->right != NULL)
elem->right->parent = elem;
pt_right->parent = elem->parent;
if (elem->parent == NULL)
_root = pt_right;
else if (elem == elem->parent->left)
elem->parent->left = pt_right;
else
elem->parent->right = pt_right;
pt_right->left = elem;
elem->parent = pt_right;
}
void right_rotate(node *elem)
{
node *pt_left = elem->left;
elem->left = pt_left->right;
if (elem->left != NULL)
elem->left->parent = elem;
pt_left->parent = elem->parent;
if (elem->parent == NULL)
_root = pt_left;
else if (elem == elem->parent->left)
elem->parent->left = pt_left;
else
elem->parent->right = pt_left;
pt_left->right = elem;
elem->parent = pt_left;
}
void delete_fix()
{
}
void delete_node()
{
}
void insert_fix(node *new_elem, node *parent)
{
node *uncle = NULL;
while (new_elem->parent->color == RED)
{
if (new_elem->parent->parent && new_elem->parent == new_elem->parent->parent->left )
{
uncle = new_elem->parent->parent->right;
if (uncle != _end && uncle->color == RED) //uncle is red == only recoloring
{
new_elem->parent->color = BLACK; //parent
uncle->color = BLACK;
new_elem->parent->parent->color = RED; //grandparent
new_elem = new_elem->parent->parent;
}
else
{
if (new_elem == new_elem->parent->right) //if elem is right child
{
new_elem = new_elem->parent;
left_rotate(new_elem);
}
new_elem->parent->color = BLACK;
new_elem->parent->parent->color = RED;
right_rotate(new_elem->parent->parent);
}
}
else
{
uncle = new_elem->parent->parent->left;
if (uncle != _end && uncle->color == RED) //uncle is red == only recoloring
{
new_elem->parent->color = BLACK; //parent
uncle->color = BLACK;
new_elem->parent->parent->color = RED; //grandparent
new_elem = new_elem->parent->parent;
}
else
{
if (new_elem == new_elem->parent->left) //if elem is right child
{
new_elem = new_elem->parent;
right_rotate(new_elem);
}
new_elem->parent->color = BLACK;
new_elem->parent->parent->color = RED;
left_rotate(new_elem->parent->parent);
}
}
}
_root->color = BLACK;
}
node *insert(key_type key, mapped_type val)
{
node *x = _root;
node *new_parent;
if (this->empty())
{
_root = new_node(key, val);
_end = _root;
_size = 1;
return _root;
}
else
{
while (x != _end)
{
new_parent = x;
if (key < x->key)
x = x->right;
else if (key > x->key)
x = x->left;
else
return (x);
}
x = new_node(key, val);
x->parent = new_parent;
if (key < new_parent.key)
new_parent.left = x;
else
new_parent.right = x;
x->color = RED;
return (x);
}
this->insert_fix();
}
};
}