(第十三步) STL: stl_map容器实现

map

特性:

  • 所有元素都会根据元素的键值自动被排序
  • map 的所有元素都是pair,同时拥有实值(value)和键值(key),pair的第一元素被视为键值,第二元素被视为实值。
  • map不允许两个元素拥有相同的键值。

总体性质和set区别不大,多了一个实值,KeyOfValue 要从证同identity变成选择select,所以对仿函数functional文件进行了一些功能添加

实现功能

  • begin()
  • end()
  • empty()
  • size()
  • clear()
  • find(val)
  • insert(val)
  • erase(val);

Functional

/*
* functional是非常简单的一个类,提供了小于和相等两个函数供调用
* 仿函数库
*
* 第六步
*/

#ifndef _FUNCTIONAL_H_
#define _FUNCTIONAL_H_

namespace mySTL{

	// STL规定,每一个Adaptable Unary Function都应该继承此类别
	template <class Arg, class Result>
	struct unary_function {
		typedef Arg		argument_type;
		typedef Result	result_type;
	};


	template<class Arg1, class Arg2, class Result>
	struct binary_function
	{
		typedef Arg1 first_argument_type;
		typedef Arg2 second_argument_type;
		typedef Result result_type;
	};

	//********** [less] ****************
	template<class T>
	struct less{
		typedef T first_argument_type;
		typedef T second_argument_type;
		typedef bool result_type;

		result_type operator()(const first_argument_type& x, const second_argument_type& y){
			return x < y;
		}
	};

	//********** [equal_to] ****************
	template<class T>
	struct equal_to{
		typedef T first_argument_type;
		typedef T second_argument_type;
		typedef bool result_type;

		result_type operator()(const first_argument_type& x, const second_argument_type& y){
			return x == y;
		}
	};



	//********** [identity] ****************
	template<class T>
	struct identity {
		const T& operator()(const T& x)const { return x; }
	};

	//********** [select] ****************
	// 选择函数(selection function) :接受一个pair,传回其第一元素
	// 此式运用于<stl_ map.h>, 用来指定RB - tree所需的KeyOfValue op
	// 由于map系以pair元素的第一元素为其键值,所以采用select1st
	template <class Pair>
	struct select1st : public unary_function<Pair, typename Pair::first_type>
	{
		const typename Pair::first_type& operator() (const Pair & x) const
		{
			return x.first;
		}
	};

}
#endif

stl_set.h

#pragma once

#include "stl_rb_tree.h"
#include "../Includes/Functional.h"
#include "../Includes/Allocator.h"
#include "../Includes/Utility.h"

namespace mySTL
{
	template<class Key, class T, class Compare = mySTL::less<Key>>
	class map
	{
		// typedefs :
		typedef Key								key_type;		// 键值型别
		typedef T								data_type;		// 数据(实值)型别
		typedef T								mapped_type;	//
		typedef pair<const Key, T>				value_type;		// 元素型别(键值 / 实值)
		typedef Compare							key_compare;	// 键值比较函数


		// 以下定义一个functor,其作用就是调用“元素比较函数”
		class value_compare
			: public binary_function<value_type, value_type, bool> {
			friend class map<Key, T, Compare>;
		protected:
			Compare comp;
			value_compare(Compare c) : comp(c) {}

		public:
			bool operator()(const value_type& x, const value_type& y) const {
				return comp(x.first, y.first);
			};
		};
	

	private:
		// 以下定义表述型别(representation type).以map元素型别(一个pair)
		// 的第一型别,作为RB-tree节点的键值型别
		typedef rb_tree<key_type, value_type, select1st<value_type>, key_compare> rep_type;

		rep_type t;			// 以红黑树( RB - tree)表现map
	public:
		typedef typename rep_type::pointer						pointer;
		typedef typename rep_type::const_pointer				const_pointer; 
		typedef typename rep_type::reference					reference;
		typedef typename rep_type::const_reference				const_reference; 
		typedef typename rep_type::iterator						iterator;
		// 注意上一行,map 并不像set 一样将iterator定义为RB - tree 的
		// const_iterator.因为它允许用户通过其迭代器修改元素的实值(value)
		typedef typename rep_type::const_iterator				const_iterator;
		typedef typename rep_type::size_type					size_type;

		// 注意, map一定使用底层 RB-tree 的insert_unique()而非insert_equal()
		// multimap 才使用insert_equal ()
		// 因为map不允许相同键值存在,multimap 才允许相同键值存在

		map() : t(Compare()) { }
		explicit map(const Compare& comp) : t(comp) { }

		template <class InputIterator>
		map(InputIterator first, InputIterator last)
			: t(Compare()) {
			t.insert_unique(first, last);
		}
		template <class InputIterator>
		map(InputIterator first, InputIterator last, const Compare& comp) : t(comp) 
		{ t.insert_unique(first, last); }

		map(const map<Key, T, Compare>& x) : t(x.t) {}
		map<Key, T, Compare>& operator=(const map<Key, T, Compare>& x) 
		{
			t = x.t;
			return *this;
		}


		iterator begin() { return t.begin(); }
		const_iterator begin() const { return t.begin(); }
		iterator end() { return t.end(); }
		const_iterator end() const { return t.end(); }
	
		bool empty() const {return t.empty();}
		size_type size() const { return t.size(); }
		size_type max_size() const { return t.max_size(); }

		// 注意以下下标( subscript)操作符
		T& operator [] (const Key& k)
		{
			return (*((insert(value_type(k, T()))).first)).second;
		}
	
		iterator find(const key_type& val) { return insert(value_type(val, T())).first; }

		//insert  erase
		//注意以下insert操作返回的型别
		pair<iterator, bool> insert(const value_type& x);
		void erase(iterator position);
		void erase(const value_type& val);

	};
}

#include "../Detail/stl_map.impl.h"

stl_set.impl.h

#pragma once
//#include "../p2_STL_Source/stl_map.h"

namespace mySTL
{


	template<class Key, class T, class Compare>
	inline pair<typename map<Key, T, Compare>::iterator, bool> 
		map<Key, T, Compare>::insert(const value_type& x)
	{
		return t.insert_unique(x);
	}

	template<class Key, class T, class Compare>
	inline void map<Key, T, Compare>::erase(iterator position)
	{
		typename rep_type::iterator tmp(position.ptr);
		t.erase(tmp);
	}

	template<class Key, class T, class Compare>
	inline void map<Key, T, Compare>::erase(const value_type& val)
	{
		t.erase(find(val));
	}
}

stl_set_test.h

#pragma once

#include "../p2_STL_Source/stl_map.h"
#include <string>

namespace mySTL
{
	namespace mapTest{

		template<class Key, class T, class Compare = mySTL::less<Key>>
		using myMap = mySTL::map<Key, T, Compare>;

		void test01();
	}
}

stl_set_test.cpp

#include "stl_map_test.h"

using namespace std;

namespace mySTL
{
	namespace mapTest {

		void test01()
		{
			map<int, string> ismap;
			cout << "size is: " << ismap.size() << endl;
			cout << "ismap is empty: " << boolalpha << ismap.empty() << endl;
			
			
			ismap[0] = "zhang";
			ismap[1] = "san";
			ismap[2] = "li";
			ismap[3] = "si";
			ismap[4] = "wangwu";
			cout << "size is: " << ismap.size() << endl;
			cout << ismap[1] << endl;
			
			for (int i = 0; i < ismap.size(); ++i)
			{
				cout << "第" << i << "个:" << ismap[i] << endl;
			}
										 
			cout << (*ismap.find(3)).second << endl;

		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值