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;
}
}
}