
#define MP_TPL	template < typename Key, typename T, typename Compare, typename Alloc >
#define MP		map<Key, T, Compare, Alloc>

namespace ft {


	/************
	 * copliens :
	 ************/
// constructors ------------------------------
MP_TPL MP::
	map (const key_compare & comp, const allocator_type & alloc)
	: _bst()
	, _allocator(alloc)
	, _comp(comp) {

	return;
}
MP_TPL template <class InputIt> MP::
	map (InputIt first, InputIt last, const key_compare& comp, const allocator_type& alloc)
	: _bst(first, last)
	, _allocator(alloc)
	, _comp(comp) {
}
MP_TPL MP::
	map (const map& x)
	: _bst()
	, _allocator(x._allocator)
	, _comp(x._comp) {

	*this = x;
}
// destructor --------------------------------
MP_TPL MP::
	~map() { clear(); }
// operator= ---------------------------------
MP_TPL MP& MP::
	operator= (const map& x) {

	if (this == &x)
		return (*this);

	map	new_map(x.begin(), x.end());
	swap(new_map);
	return (*this);
}


	/*************
	 * iterators :
	 *************/
// begin -------------------------------------
MP_TPL typename MP::iterator MP::
	begin() { return (_bst.begin()); }
MP_TPL typename MP::const_iterator MP::
	begin() const { return (_bst.begin()); }
// end ---------------------------------------
MP_TPL typename MP::iterator MP::
	end() { return (_bst.end()); }
MP_TPL typename MP::const_iterator MP::
	end() const { return (_bst.end()); }
// rbegin ------------------------------------
MP_TPL typename MP::reverse_iterator MP::
	rbegin() { return (_bst.rbegin()); }
MP_TPL typename MP::const_reverse_iterator MP::
	rbegin() const { return (_bst.rbegin()); }
// rend --------------------------------------
MP_TPL typename MP::reverse_iterator MP::
	rend() { return (_bst.rend()); }
MP_TPL typename MP::const_reverse_iterator MP::
	rend() const { return (_bst.rend()); }


	/************
	 * capacity :
	 ************/
// empty -------------------------------------
MP_TPL bool MP::
	empty() const { return (_bst.empty()); }
// size --------------------------------------
MP_TPL typename MP::size_type MP::
	size() const { return (_bst.size()); }
// max_size ----------------------------------
MP_TPL typename MP::size_type MP::
	max_size() const { return (_bst.max_size()); }


	/******************
	 * element access :
	 ******************/
// operator[] --------------------------------
MP_TPL typename MP::mapped_type& MP::
	operator[] (const key_type& k) { return _bst[k]; }


	/*************
	 * modifiers :
	 *************/
// insert ------------------------------------
MP_TPL pair<typename MP::iterator, bool> MP::
	insert (const value_type& val) { return (_bst.insert(val)); }
MP_TPL typename MP::iterator MP::
	insert (iterator pos, const value_type& val) { return (_bst.insert(pos, val)); }
MP_TPL template <class InputIt> void MP::
		insert (InputIt first, InputIt last) { return (_bst.insert(first, last)); }
// erase -------------------------------------
MP_TPL void MP::
	erase (iterator pos) { return (_bst.erase(pos)); }
MP_TPL typename MP::size_type MP::
	erase (const key_type& k) { return (_bst.erase(k)); }
MP_TPL void MP::
	erase (iterator first, iterator last) { return (_bst.erase(first, last)); }
// swap --------------------------------------
MP_TPL void MP::
	swap (map& x) {

	bst_map      tmp;

	tmp.swap(_bst);
	_bst.swap(x._bst);
	x._bst.swap(tmp);
}
// clear -------------------------------------
MP_TPL void MP::
	clear() {

	_bst.clear();
}


	/*************
	 * observers :
	 *************/
// key_comp ----------------------------------
MP_TPL typename MP::key_compare MP::
	key_comp() const { return (value_compare(_comp).comp); }
// value_comp --------------------------------
MP_TPL typename MP::value_compare MP::
	value_comp() const { return (value_compare(_comp)); }


	/**************
	 * operations :
	 **************/
// find --------------------------------------
MP_TPL typename MP::iterator MP::
	find (const key_type& k) { return (_bst.find(k)); }
MP_TPL typename MP::const_iterator MP::
	find (const key_type& k) const { return (_bst.find(k)); }
// count -------------------------------------
MP_TPL typename MP::size_type MP::
	count (const key_type& k) const { return (_bst.count(k)); }
// lower_bound -------------------------------
MP_TPL typename MP::iterator MP::
	lower_bound (const key_type& k) {

	iterator	it = begin();
	iterator	it_end = end();

	while (it != it_end)
	{
		if (_comp(it->first, k) == false)
			return (it);
		++it;
	}
	return (it_end);
}
MP_TPL typename MP::const_iterator MP::
	lower_bound (const key_type& k) const {

	const_iterator	it = begin();
	const_iterator	it_end = end();

	while (it != it_end)
	{
		if (_comp(it->first, k) == false)
			return (it);
		++it;
	}
	return (it_end);
}
// upper_bound -------------------------------
MP_TPL typename MP::iterator MP::
	upper_bound (const key_type& k) {

	iterator	it = begin();
	iterator	it_end = end();

	while (it != it_end)
	{
		if (_comp(k, it->first))
			return (it);
		++it;
	}
	return (it_end);
}
MP_TPL typename MP::const_iterator MP::
	upper_bound (const key_type& k) const {

	const_iterator	it = begin();
	const_iterator	it_end = end();

	while (it != it_end)
	{
		if (_comp(k, it->first))
			return (it);
		++it;
	}
	return (it_end);
}
// equal_range -------------------------------
MP_TPL pair<typename MP::const_iterator, typename MP::const_iterator> MP::
	equal_range (const key_type& k) const {

	return ft::make_pair( lower_bound(k), upper_bound(k) );
}
MP_TPL pair<typename MP::iterator, typename MP::iterator> MP::
	equal_range (const key_type& k) {

	return ft::make_pair( lower_bound(k), upper_bound(k) );
}


	/*************
	 * allocator :
	 *************/
// get_allocator -----------------------------
MP_TPL typename MP::allocator_type MP::
	get_allocator() const { return (_allocator); }


	/************************
	 * non-member functions :
	 ************************/
// operator == -------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator==
	( const MP& lhs, const MP& rhs ) {
	
	return (lhs._bst == rhs._bst);
}
// operator < --------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator<
	( const MP& lhs, const MP& rhs ) {
	
	return (lhs._bst < rhs._bst);
}
// operator != -------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator!=
	( const MP& lhs, const MP& rhs ) { return !(lhs == rhs); }
// operator <= -------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator<=
	( const MP& lhs, const MP& rhs ) { return !(lhs > rhs); }
// operator > --------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator>
	( const MP& lhs, const MP& rhs ) { return (rhs < lhs); }
// operator >= -------------------------------
template< class Key, class T, class Compare, class Alloc > bool operator>=
	( const MP& lhs, const MP& rhs ) { return !(lhs < rhs); }
// swap (map) -----------------------------
template< class Key, class T, class Compare, class Alloc > void swap
	( const MP& lhs, const MP& rhs ) { lhs.swap(rhs); }

} // namespace ft

#undef VT
#undef VT_TPL

