码迷,mamicode.com
首页 > 其他好文 > 详细

(二)STL剖析——迭代器

时间:2016-08-12 06:47:55      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:stl剖析迭代器

TypeTraits.h

#pragma once

//双底线前缀的意思是SGI内部所用的东西,不在STL标准之内
//IteratorTraits负责萃取迭代器的特性
//__TypeTraits负责萃取型别的特性
struct __FalseType
{};

struct __TrueType
{};
//一个类究竟什么时候该有自己的平凡类型构造
template<class T>
struct __TypeTraits
{
	typedef __FalseType HasTrivialDefaultConstructor;
	typedef __FalseType HasTrivialCopyConstructor;
	typedef __FalseType HasTrivialAssignmentOperator;
	typedef __FalseType HasTrivialDestructor;//无平凡类型的析构
	typedef __FalseType IsPODType;
};
//针对原生指针设计的偏特化版本
template<class T>
struct __TypeTraits<T*>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;//有平凡类型的析构
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<char>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;//有平凡类型的析构
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<unsigned char>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<short>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<unsigned short>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<int>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
}; 

template<>
struct __TypeTraits<unsigned int>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<long>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<unsigned long>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<float>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<double>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};


template<>
struct __TypeTraits<long long>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

template<>
struct __TypeTraits<bool>
{
	typedef __TrueType HasTrivialDefaultConstructor;
	typedef __TrueType HasTrivialCopyConstructor;
	typedef __TrueType HasTrivialAssignmentOperator;
	typedef __TrueType HasTrivialDestructor;
	typedef __TrueType IsPODType;
};

//我们可以针对自定义类,自行设计一个特化版本,明确告诉编译器以下事例
//template<>
//struct __TypeTraits<Date>
//{
//	typedef __TrueType HasTrivialDefaultConstructor;
//	typedef __TrueType HasTrivialCopyConstructor;
//	typedef __TrueType HasTrivialAssignmentOperator;
//	typedef __TrueType HasTrivialDestructor;
//	typedef __TrueType IsPODType;
//};

Iterator.h

#pragma once

//具体使用哪种迭代器是容器自己所决定的,因为只有容器本身材知道自己应该要用哪种

// 用于标记迭代器类型 
struct InputIteratorTag{};
struct ForwardIteratorTag:public InputIteratorTag{};
struct BidirectionalIteratorTag:public ForwardIteratorTag{};
struct RandomAccessIteratorTag :public BidirectionalIteratorTag{};

//Iterator的保证
//任何迭代器都需要提供内嵌相应型别,方便迭代器萃取
//自行开发的迭代器最好继承下面这个迭代器,五种相应型别的继承
//新的迭代器只需按以下方式写(举例)
//template<class T>
//struct ListIter :public Iterator<BidirectionalIteratorTag,T>
//{};
template<class Category, class T, class Distance = ptrdiff_t,
		class Pointer = T*, class Reference = T&>
struct Iterator
{
	typedef Category IteratorCategory;
	typedef T ValueType;
	typedef Distance DifferenceType;//ptrdiff_t是C/C++标准库中定义的一个与机器相关的数据类型,通常用来保存两个指针减法操作的结果。
	typedef Pointer Pointer;
	typedef Reference Reference;
};

template<class Iterator>
struct IteratorTraits 
{
	typedef typename Iterator::IteratorCategory IteratorCategory;
	typedef typename Iterator::ValueType ValueType;
	typedef typename Iterator::DifferenceType DifferenceType;//用来表示两个迭代器之间的距离
	typedef typename Iterator::Pointer Pointer;
	typedef typename Iterator::Reference Reference;
};

//针对原生指针而设计的偏特化版本
template<class T>
struct IteratorTraits<T*>
{
	typedef RandomAccessIteratorTag IteratorCategory;
	typedef T ValueType;
	typedef ptrdiff_t DifferenceType;
	typedef T* PointerType;
	typedef T& ReferenceType;
};
//针对point-to-const而设计的偏特化版本
template<class T>
struct IteratorTraits<const T*>
{
	typedef const RandomAccessIteratorTag IteratorCategory;
	typedef T ValueType;
	typedef ptrdiff_t DifferenceType;
	typedef const T* PointerType;
	typedef const T& ReferenceType;
};

// 任何迭代器都应提供5种内嵌的相应型别
// 确保了能够更方便的跟STL融合。
// 且方便Iterator Traits的类型萃取
template <class T, class Distance>
struct InputIterator {//只读,迭代器所指对象不允许改变
	typedef InputIteratorTag   IteratorCategory;
	typedef T                  ValueType;
	typedef Distance           DifferenceType;
	typedef T*                 Pointer;
	typedef T&                 Reference;
};

template <class T, class Distance>
struct ForwardIterator {//读写
	typedef ForwardIteratorTag   IteratorCategory;
	typedef T                    ValueType;
	typedef Distance             DifferenceType;
	typedef T*                   Pointer;
	typedef T&                   Reference;
};

template <class T, class Distance>
struct BidirectionalIterator {//双向移动
	typedef BidirectionalIteratorTag   IteratorCategory;
	typedef T                          ValueType;
	typedef Distance                   DifferenceType;
	typedef T*                         Pointer;
	typedef T&                         Reference;
};

template <class T, class Distance>
struct RandomAccessIterator {//随机[]
	typedef RandomAccessIteratorTag    IteratorCategory;
	typedef T                          ValueType;
	typedef Distance                   DifferenceType;
	typedef T*                         Pointer;
	typedef T&                         Reference;
};

//决定迭代器的类型
template<class Iterator>
typename IteratorTraits<Iterator>::IteratorCategory IteratorCategory(const Iterator&)
{
	return IteratorTraits<Iterator>::IteratorCategory();//返回相应类型迭代器的对象
}
//决定迭代器的ValueType
template<class Iterator>
typename IteratorTraits<Iterator>::ValueType* ValueType(const Iterator&)
{
	return static_cast<typename IteratorTraits<Iterator>::ValueType*>(0);
}
template<class T, class Distance>
T* ValueType(const InputIterator<T, Distance>&)
{
	return (T*)(0);
}

template<class T, class Distance>
T* ValueType(const ForwardIterator<T, Distance>&)
{
	return (T*)(0);
}

template<class T, class Distance>
T* ValueType(const BidirectionalIterator<T, Distance>&)
{
	return (T*)(0);
}

template<class T, class Distance>
T* ValueType(const RandomAccessIterator<T, Distance>&)
{
	return (T*)(0);
}

template <class T>
T* ValueType(const T*) 
{ 
	return (T*)(0); 
}

//Advance函数////////////////////////////////////////////////////////////////
template<class InputIterator, class Distance>
void __Advance(InputIterator& it, Distance n, InputIteratorTag)
{
	while (n--)
		++it;
}

template<class BidirectionalIterator, class Distance>
void __Advance(BidirectionalIterator& it, Distance n, BidirectionalIteratorTag)
{
	//双向,逐一前进
	if (n >= 0){
		while (n-->0)
			++it;
	}
	else{
		while (n++ < 0)
			--it;
	}
}

template<class RandomAccessIterator, class Distance>
void __Advance(RandomAccessIterator& it, Distance n, RandomAccessIteratorTag)
{
	//双向,跳跃前进
	it += n;
}

//STL算法的命名规则:以算法所能接受之最低阶迭代器类型,来为其迭代器型别参数命名
template<class InputIterator, class Distance>
void Advance(InputIterator& it, Distance n)
{
	__Advance(it, n, IteratorTraits<InputIterator>::IteratorCategory());
}

//Distance函数////////////////////////////////////////////////////////////////
//__Distance()第三个参数为基类对象,可以接受派生类的对象
template<class InputIterator>
typename InputIterator::DifferenceType _Distance(InputIterator first, InputIterator last, InputIteratorTag)
{
	int len = 0;
	while (first != last){
		++len;
		++first;
	}
	return len;
}

template<class RandomAccessIterator>
typename RandomAccessIterator::DifferenceType _Distance(RandomAccessIterator first, RandomAccessIterator last, RandomAccessIteratorTag)
{
	return last - first;
}
template<class InputIterator>
typename InputIterator::DifferenceType Distance(InputIterator first, InputIterator last)
{
	return __Distance(first, last, IteratorTraits<InputIterator>::IteratorCategory());
}

Test.cpp

#include "Iterator.h"

void TestIterator()
{
	Vector<int> v;
	v.PushBack(1);
	v.PushBack(2);
	v.PushBack(3);
	v.PushBack(4);
	v.PushBack(5);

	Vector<int>::Iterator it1 = v.Begin();
	Advance(it1,10);

	List<int> l;
	l.PushBack(1);
	l.PushBack(2);
	l.PushBack(3);
	l.PushBack(4);
	l.PushBack(5);

	List<int>::Iterator it2 = l.Begin();
	Advance(it2, 4);
}


本文出自 “零蛋蛋” 博客,谢绝转载!

(二)STL剖析——迭代器

标签:stl剖析迭代器

原文地址:http://lingdandan.blog.51cto.com/10697032/1837110

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!