【试着自己写一个STL 】Knife_STL —— algobase.h

#ifndef KNIFE_ALGOBASE_H
#define KNIFE_ALGOBASE_H

// 这个头文件看似是由一个个基础函数构成的算法库
// 但其实这些算法大部分都是基于iterator这个概念的,即
// 基于iterator的相关全局基础方法,使iterator在被使用
// 的时候更加得心应手;这些方法包括:
// iter_swap();
// distance(); advance();这几个在3.0版本后被改至iterator.h中了
// swap(), max(), min(); 这几个不是基于iterator的
// copy(); mismatch();

#include "config.h"
#include "iterator.h"
#include "knifeio.h"
#include "type_traits.h"
#include "pair.h"
#include <string.h> // use memmove() in it

_STL_NAMESPACE_BEGIN

// The name 1 2 implicit a kind of squence, so we use name a b
// And indeed we do need a T pointer to init type T implicitly
// Cause we can NOT use function or other expression in init type T explicit
template <typename InputIterator_a, typename InputIterator_b, typename T>
inline void _iter_swap(InputIterator_a a, InputIterator_b b, T*)
{
	T tmp = *a;
	*a = *b;
	*b = tmp;
}

// When we need the thing that iterator point to we should use *a
// and when we need the pointer point to the thing
// we should use &(*a);
template <typename InputIterator_a, typename InputIterator_b>
inline void iter_swap(InputIterator_a a, InputIterator_b b)
{
	_iter_swap(a, b, &(*a));
}

template <typename T>
inline void swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}

template <typename T>
inline const T& min(const T& a, const T& b)
{
	return (a < b) ? a : b;
}

template <typename T>
inline const T& max(const T& a, const T& b)
{
	return (b < a) ? a : b;
}

// SGI_STL_203的实现逻辑略微有点奇怪,他将comp(a, b)
// 与 a < b等同了,而且并没有使用这个函数的地方,所以
// 我在这里是做了修改的,comp(a, b)应该在a > b时返回true
// 在a < b时返回false
//
// 抱歉在这里犯下的巨大错误,在C++中,默认实现的是<操作符
// 所以comp应该是基于<操作符的,所以应该在a < b时返回true
// 已经改过了
template <typename T, typename Compare>
inline const T& min(const T& a, const T& b, Compare comp)
{
	return comp(a, b) ? a : b;
}

template <typename T, typename Compare>
inline const T& max(const T& a, const T& b, Compare comp)
{
	return comp(a, b) ? b : a;
}

// 这是描述两个iterator之间的距离的函数
template <typename RandomAccessIterator, typename Distance>
inline void _distance(RandomAccessIterator a, RandomAccessIterator b, Distance& dis, 
						random_access_iterator_tag)
{
	dis += b - a;
	// 注意,这里是在原值基础上加上距离,并不是赋值
}

template <typename InputIterator, typename Distance>
inline void _distance(InputIterator a, InputIterator b, Distance& dis, 
						input_iterator_tag)
{
	while (a != b) { ++a; ++dis; }
	// 在前++和后++中,前++是优先实现的,所以优先使用前++
}

template <typename InputIterator, typename Distance>
inline void distance(InputIterator a, InputIterator b, Distance& distance)
{
	_distance(a, b, distance, iterator_category(a));	
}

// 由于iterator_category()返回的是临时对象
// 所以不能使用诸如random_access_iterator_tag&
// 这样的参数来区分不同的iterator,必须使用random_access_iterator_tag
template <typename RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
_distance(RandomAccessIterator a, RandomAccessIterator b, random_access_iterator_tag)
{
	return b - a;
}

template <typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
_distance(InputIterator a, InputIterator b, input_iterator_tag)
{
	typename iterator_traits<InputIterator>::difference_type dis(0);
	while (b != a)
	{
		++a;
		++dis;
	}
	return dis;
}

template <typename InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator a, InputIterator b)
{
	return _distance(a, b, iterator_category(a));
}

// Distance类型被要求支持两个--操作,能转换为bool型
template <typename InputIterator, typename Distance>
inline void _advance(InputIterator& i, Distance n, input_iterator_tag)
{
	// 在SGI_STL 2.03是这样的:while (n--) ++i;
	// 那么当n为负的时候这里是处理不了的,但用户并没有被通知
	// 略有不恰当;而且不能要求一个distance一定可以转换为bool
	// 不过我找不到代替的方法。。。。。。。
	if (n) { while (n--) ++i; }
	else { printf("You can not make a iterator -- while this iterator only have ++ in advance()"); }
}

// Distance类型被要求支持两个--操作和两个++操作,能转换为bool型
template <typename BidirectionalIterator, typename Distance>
inline void _advance(BidirectionalIterator& i, Distance n, bidirectional_iterator_tag)
{
	if (n)
		while (n--) ++i;
	else
		while (n++) --i;
}

template <typename RandomAccessIterator, typename Distance>
inline void _advance(RandomAccessIterator& i, Distance n, random_access_iterator_tag)
{
	// 原文是 i+=n;在这里有暗含i要支持+=这样的操作,是不合理的
	i = i + n;
}

// 请记住使用&!!!!
template <typename InputIterator, typename Distance>
inline void advance(InputIterator& i, Distance n)
{
	_advance(i, n, iterator_category(i));
}

template <typename InputIterator, typename OutputIterator>
inline OutputIterator 
_copy(InputIterator first, InputIterator last, OutputIterator res, input_iterator_tag)
{
	// We'd better not use while (first != last) *res++ = *first++;
	// This method will be supposed to be written in the situation
	// we know what will the ++(int)operation do, and while it is much more
	// not effcient than ++() we should use ++() first;
	// so we use ++() here;
	for (; first != last; ++first, ++res)
		*res = *first;
	return res;
}

template <typename RandomAccessIterator, typename OutputIterator, typename Distance>
inline OutputIterator 
_copy_distance(RandomAccessIterator first, RandomAccessIterator last, OutputIterator res, Distance*)
{
 	for (Distance d = last - first; d != 0; --d, ++res, ++first)
		*res = *first;
	return res;
}

template <typename RandomAccessIterator, typename OutputIterator>
inline OutputIterator 
_copy(RandomAccessIterator first, RandomAccessIterator last, OutputIterator res, random_access_iterator_tag)
{
	// 在这里我们已经知道了iterator的类型,所以不必传递random_access_iterator_tag
	_copy_distance(first, last, res, distance_type(first));
}

template <typename InputIterator, typename OutputIterator>
struct copy_dispatcher {
	OutputIterator operator()(InputIterator first, InputIterator last, OutputIterator result)
	{
		return _copy(first, last, result, iterator_category(first));
	}
};

template <typename T>
inline T*
_copy_ptr(const T* first, const T* last, T* result, __true_type)
{
	const ptrdiff_t diff = last - first;
	memmove(result, first, sizeof(T) * diff);
	return result + diff;
}

template <typename T>
inline T*
_copy_ptr(const T* first, const T* last, T* result, __false_type)
{
	_copy_distance(first, last, result, (ptrdiff_t*) (0));
}

template <typename T>
struct copy_dispatcher<T*, T*> {
	T* operator()(T* first, T* last, T* res)
	{
		return _copy_ptr(first, last, res, 
				typename __type_traits<T>::has_trivial_assignment_operator());
	}
};

template <typename T>
struct copy_dispatcher<const T*, T*> {
	T* operator()(const T* first, const T* last, T* res)
	{
		return _copy_ptr(first, last, res, 
				typename __type_traits<T>::has_trivial_assignment_operator());
	}
};

template <typename InputIterator, typename OutputIterator>
inline OutputIterator
copy(InputIterator first, InputIterator last, OutputIterator res)
{
	return copy_dispatcher<InputIterator, OutputIterator>()(first, last, res);
}

inline char*
copy(const char* first, const char* last, char* result)
{
	const ptrdiff_t diff = last - first;
	memmove(result, first, diff);// Cause sizeof(char) is 1
	return result + diff;
}

inline wchar_t*
copy(const wchar_t* first, const wchar_t* last, wchar_t* result)
{
	const ptrdiff_t diff = last - first;
	memmove(result, first, sizeof(wchar_t) * diff);
	return result + diff;
}

// Easy , we copy the element to destination from the backward direction
template <typename BidirectionalIterator_a, typename BidirectionalIterator_b>
inline BidirectionalIterator_b
_copy_backward(BidirectionalIterator_a first, BidirectionalIterator_a last,
 				BidirectionalIterator_b res, input_iterator_tag)
{
	// we will copy the element from the form one 
	// of the res
	while (first != last) *--res = *--last; 
	return res;
}

template <typename BidirectionalIterator_a, typename BidirectionalIterator_b, typename Distance>
inline BidirectionalIterator_b
_copy_backward_distance(BidirectionalIterator_a first, BidirectionalIterator_a last,
							BidirectionalIterator_b res, Distance*)
{
	// Maybe !=() operation will come to much resources
	// so we'd better use a light type: distance
	Distance dis = last - first;
	while (dis != 0) { --dis; *--res = *--last; }
	return res;
}

template <typename BidirectionalIterator_a, typename BidirectionalIterator_b>
inline BidirectionalIterator_b
_copy_backward(BidirectionalIterator_a first, BidirectionalIterator_a last,
				BidirectionalIterator_b res, random_access_iterator_tag)
{
	_copy_backward_distance(first, last, res, distance_type(first));
}

template <typename BidirectionalIterator_a, typename BidirectionalIterator_b>
struct copy_backward_dispatcher {
	BidirectionalIterator_b operator()(BidirectionalIterator_a first, BidirectionalIterator_a last,
										BidirectionalIterator_b res)
	{
		return _copy_backward_backward(first, last, res, iterator_category(first));
	}
};

template <typename T>
inline T*
_copy_backward_ptr(const T* first, const T* last, T* res, __true_type)
{
	const ptrdiff_t diff = last - first;
	memmove(res - diff, first, sizeof(T) * diff);
	return res - diff;
}

template <typename T>
inline T*
_copy_backward_ptr(const T* first, const T* last, T* res, __false_type)
{
	return _copy_backward_distance(first, last, res, (ptrdiff_t*) (0));
}

template <typename T>
struct copy_backward_dispatcher<T*, T*> {
	T* operator()(T* first, T* last, T* res)
	{
		return _copy_backward_ptr(first, last, res, 
							typename __type_traits<T>::has_trivial_assignment_operator());
	}
};

template <typename T>
struct copy_backward_dispatcher<const T*, T*> {
	T* operator()(const T* first, const T* last, T* res)
	{
		return _copy_backward_ptr(first, last, res, 
							typename __type_traits<T>::has_trivial_assignment_operator());
	}
};

template <typename BidirectionalIterator_a, typename BidirectionalIterator_b>
inline BidirectionalIterator_b
copy_backward(BidirectionalIterator_a first, BidirectionalIterator_a last, BidirectionalIterator_b res)
{
	return copy_backward_dispatcher<BidirectionalIterator_a, BidirectionalIterator_b>()(first, last, res);
}


inline char*
copy_backward(const char* first, const char* last, char* result)
{
	const ptrdiff_t diff = last - first;
	memmove(result - diff, first, diff);// Cause sizeof(char) is 1
	return result - diff;
}

inline wchar_t*
copy_backward(const wchar_t* first, const wchar_t* last, wchar_t* result)
{
	const ptrdiff_t diff = last - first;
	memmove(result - diff, first, sizeof(wchar_t) * diff);
	return result - diff;
}

template <typename InputIterator, typename _Size, typename OutputIterator>
inline OutputIterator
_copy_n(InputIterator first, _Size size, OutputIterator res, 
		input_iterator_tag)
{
	// 原文是size != 0, 但在这里, 如果size是一个复杂类型
	// 那么他还必须重载和int值的比较操作符,或者满足从int到_Size的隐式转换
	// 当然,大部分时候,我们的constructor都是显示声明的,所以
	// 原文的实现是不合理的, 所以我将0改为了_Size(0),进行一个显示转型声明
	// 这或许不会增加太大的开销吧?
	while (size != _Size(0)) { --size; ++res; ++first; *res = *first;}
	return res;
}

template <typename RandomAccessIterator, typename _Size, typename OutputIterator>
inline OutputIterator
_copy_n(RandomAccessIterator first, _Size size, OutputIterator res, 
		random_access_iterator_tag)
{
	return copy(first, first + size, res);
}

// THis function is work for the situation that we 
// do not know last iterator, we just know the size
template <typename InputIterator, typename _Size, typename OutputIterator>
inline OutputIterator
copy_n(InputIterator first, _Size size, OutputIterator res)
{
	return _copy_n(first, size, res, iterator_category(first));
}

template <typename InputIterator, typename Value>
inline void 
fill(InputIterator first, InputIterator last, const Value& val)
{
	while (first != last) {  *first = val; ++first; }
}

template <typename InputIterator, typename _Size, typename Value>
inline void
fill_n(InputIterator first, _Size n, const Value& val)
{
	while (n != _Size(0)) {  *first = val; --n; ++first; }
}

// We get the last iterator pair if these two is soooo match
template <typename InputIterator_a, typename InputIterator_b>
inline pair<InputIterator_a, InputIterator_b>
mismatch(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b)
{
	while (first_a != last_a && *first_a == *first_b)
	{
		++first_a;
		++first_b;
	}

	return pair<InputIterator_a, InputIterator_b>(first_a, first_b);
}

template <typename InputIterator_a, typename InputIterator_b,
			 typename BinaryPredicate> // BinaryPredicate could be a functor
inline pair<InputIterator_a, InputIterator_b>
mismatch(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	// The binary predicate should handle the content the iterator point to
	// so we should pass content the iterator point to rather than the iterator
	// to the binary predicate to handle
	while (first_a != last_a && binary_predicate(*first_a, *first_b))
	{
		++first_a;
		++first_b;
	}

	return pair<InputIterator_a, InputIterator_b>(first_a, first_b);
}

// 有时候我们并不需要得到mismatch的iterator组成的pair
// 这给我们一种两层封装的感觉,我们可能只要mismatch的value组成的pair
// 所以我直接封装了这样一个函数,满足需求
// 这个函数也有他的BinaryPredicate版本
template <typename InputIterator_a, typename InputIterator_b>
inline pair<typename iterator_traits<InputIterator_a>::value_type,
			typename iterator_traits<InputIterator_b>::value_type>
mismatch_content(InputIterator_a first_a, InputIterator_a last_a, 
					InputIterator_b first_b)
{
	while (first_a != last_a && *first_a == *first_b)
	{
		++first_a;
		++first_b;
	}

	return pair<typename iterator_traits<InputIterator_a>::value_type,
				typename iterator_traits<InputIterator_b>::value_type>
		   (*first_a, *first_b);
}

template <typename InputIterator_a, typename InputIterator_b, 
			typename BinaryPredicate>
inline pair<typename iterator_traits<InputIterator_a>::value_type,
			typename iterator_traits<InputIterator_b>::value_type>
mismatch_content(InputIterator_a first_a, InputIterator_a last_a, 
					InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (first_a != last_a && binary_predicate(*first_a, *first_b))
	{
		++first_a;
		++first_b;
	}

	return pair<typename iterator_traits<InputIterator_a>::value_type,
				typename iterator_traits<InputIterator_b>::value_type>
		   (*first_a, *first_b);
}

// 遍历式的实现,当我们找到不符合的部分时,就直接退出,减少CPU占用
template <typename InputIterator_a, typename InputIterator_b>
inline bool
equal(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b)
{
	while (first_a != last_a)
	{
		if (*first_a == *first_b)
		{
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}

	return true;
}

template <typename InputIterator_a, typename InputIterator_b, 
			typename BinaryPredicate>
inline bool
equal(InputIterator_a first_a, InputIterator_a last_a, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (first_a != last_a)
	{
		if (binary_predicate(*first_a, *first_b))
		{
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

// I added this function for the reason the same as we added the function fill_n
template <typename InputIterator_a, typename _Size, typename InputIterator_b>
inline bool
equal_n(InputIterator_a first_a, _Size size, InputIterator_b first_b)
{
	while (size != _Size(0))
	{
		if (*first_a == *first_b)
		{
			--size;
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

template <typename InputIterator_a, typename _Size, 
			typename InputIterator_b, typename BinaryPredicate>
inline bool
equal(InputIterator_a first_a, _Size size, 
			InputIterator_b first_b, BinaryPredicate binary_predicate)
{
	while (size != _Size(0))
	{
		if (binary_predicate(*first_a, *first_b))
		{
			--size;
			++first_a;
			++first_b;
		}
		else
		{
			return false;
		}
	}
	
	return true;
}

// 来自有道字典:lexicographic -- 字典式的, 以字典序比较两个list
// 多用于比较两个字符串,所以有专门对于字符串的优化
// 在a < b时返回true
template <typename InputIterator_a, typename InputIterator_b>
inline bool
lexicographical_compare(InputIterator_a first_a, InputIterator_a last_a, 
						InputIterator_b first_b, InputIterator_b last_b)
{
	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (*first_b < *first_a) return true;
		if (*first_a < *first_b) return false;
	}

	// Note:: must be && here!!
	return first_a == last_a && first_b != last_b;
}

// STL有一个对于字符串的优化版本,这个版本借用C的函数实现
// 看来C的函数确实在char*处理方面效率很高,多多学习,以后可以用上
// 但是这里CHAR_MAX == SCHAR_MAX的部分实在不懂,为何要这样?
// 所以我这里只使用了unsigned char*的实现代替了char*的实现
// 好像还挺好用
inline bool
lexicographical_compare(const char* first_a, 
						const char* last_a, 
						const char* first_b, 
						const char* last_b)
{
	const size_t len_a = last_a - first_a;
	const size_t len_b = last_b - first_b;
	const int result = memcmp(first_a, first_b, min(len_a, len_b));
	return result != 0 ? result < 0 : len_a < len_b;
}

// inline bool
// lexicographical_compare(const char* first_a, 
// 						const char* last_a, 
// 						const char* first_b, 
// 						const char* last_b)
// {
// 	const size_t len_a = last_a - first_a;
// 	const size_t len_b = last_b - first_b;
// 	const int result = memcmp(first_a, first_b, min(len_a, len_b));
// 	knife::printf("Result: ", result);
// 	return result != 0 ? result < 0 : len_a < len_b;
// }

// inline bool 
// lexicographical_compare(const char* first1,
// 						const char* last1,
//                         const char* first2, 
//                         const char* last2)
// {
// #if CHAR_MAX == SCHAR_MAX
//   	return lexicographical_compare(	(const signed char*) first1,
//                                  	(const signed char*) last1,
//                                  	(const signed char*) first2,
//                                  	(const signed char*) last2);
// #else
//   	return lexicographical_compare(	(const unsigned char*) first1,
//                                  	(const unsigned char*) last1,
//                                  	(const unsigned char*) first2,
//                                  	(const unsigned char*) last2);
// #endif
// }

template <typename InputIterator_a, typename InputIterator_b, typename Compare>
inline bool
lexicographical_compare(InputIterator_a first_a, InputIterator_a last_a, 
						InputIterator_b first_b, InputIterator_b last_b, 
						Compare comp)
{
	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (comp(*first_a, *first_b)) return true;
		if (comp(*first_a, *first_b)) return false;
	}

	// Note:: must be && here!!
	return first_a == last_a && first_b != last_b;
}

// 我更改了一下实现的方法,个人认为比原版的好,这里贴出原版的
// 各位可以比较一下
template <typename InputIterator_a, typename InputIterator_b>
inline int
lexicographical_compare_3way(InputIterator_a first_a, InputIterator_a last_a, 
							 InputIterator_b first_b, InputIterator_b last_b)
{
	static int more = 1;
	static int less = -1;
	static int equal = 0;

	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (*first_a < *first_b) return less;
		if (*first_b < *first_a) return more;
	}

	return (first_a == last_a) ? ((first_b == last_b) ? equal : less) : more;
}

// 以下都属于原版
// template <class InputIterator1, class InputIterator2>
// int lexicographical_compare_3way(InputIterator1 first1, InputIterator1 last1,
//                                  InputIterator2 first2, InputIterator2 last2)
// {
//     while (first1 != last1 && first2 != last2) {
//         	if (*first1 < *first2) return -1;
//         	if (*first2 < *first1) return 1;
// 			++first1; ++first2;
//     }
//
//     if (first2 == last2) {
// 			return !(first1 == last1);
//     } else {
//         	return -1;
//     }
// }

template <typename InputIterator_a, typename InputIterator_b, typename Compare>
inline int
lexicographical_compare_3way(InputIterator_a first_a, InputIterator_a last_a, 
							 InputIterator_b first_b, InputIterator_b last_b, 
							 Compare comp)
{
	static int more = 1;
	static int less = -1;
	static int equal = 0;

	for (; first_a != last_a || first_b != last_b; ++first_a, ++first_b)
	{
		if (comp(*first_a, *first_b)) return less;
		if (comp(*first_b, *first_a)) return more;
	}

	return (first_a == last_a) ? ((first_b == last_b) ? equal : less) : more;
}

// 这里有一个例外:如"apple"和"appleapple"比较返回的就是-5
// 这里有点没搞懂他设计的想法,难道不是a比b小的时候返回-1吗?
// 他的想法貌似是对两个字符串比较时,我们还需要得出一些额外的值
// 用以告诉user更多信息,但为什么不在template的部分也这么做呢?
// 偏偏要在特化部分这么做
inline int 
lexicographical_compare_3way(const char* first_a, const char* last_a,
							 const char* first_b, const char* last_b)
{
	const size_t len_a = last_a - first_a;
	const size_t len_b = last_b - first_b;
	const int result = memcmp(first_a, first_b, min(len_a, len_b));
	knife::printf(len_a, len_b);
	return result == 0 ? len_a - len_b : result;
}
// 后面的问题很lexicographical_compare一样,就不举例了

// SGI的作者真是直接额,不知道的就直接叫pointer
// 对于我这种命名强迫症患者真是解脱
template <typename T>
inline void destroy(T* pointer)
{
	pointer->~T();
}

// placement new for initialize A_Type in 
// the place where the A_Type* pointer point
// 这个placement new 非常的暴力,如果你传个临时变量
// 的地址过来,他也会执行的,这个函数会在你只重载了
// void* operator new(size_t)的时候报错,因为没有
// void* operator new(size_t, B_Type*)的版本
// 看来世上的事不能总是保证正确,虽然我们已经尽力了
template <typename A_Type, typename B_Type>
inline void construct(A_Type* buffer, const B_Type& value)
{
	new (buffer) A_Type(value);
}

template <typename ForwardIterator>
inline void __destroy_aux_aux(ForwardIterator first, ForwardIterator last, forward_iterator_tag)
{
	for (; first != last; ++first) destroy(&*first);
}

template <typename RandomAccessIterator, typename Distance>
inline void __destroy_aux_aux_d(RandomAccessIterator first, RandomAccessIterator last, Distance*)
{
	for (Distance d = last - first; d != Distance(0); --d, ++first) destroy(&*first);
}

// 相对于原文我又做了一次封装,相信大家不介意的吧
template <typename RandomAccessIterator>
inline void __destroy_aux_aux(RandomAccessIterator first, RandomAccessIterator last, random_access_iterator_tag)
{
	__destroy_aux_aux_d(first, last, distance_type(first));
}

template <typename ForwardIterator>
inline void _destroy_aux(ForwardIterator first, ForwardIterator last, __false_type)
{
	__destroy_aux_aux(first, last, iterator_category(first));
}

// trivial destructor即无用的destructor,所以可以不调用
template <typename ForwardIterator>
inline void _destroy_aux(ForwardIterator first, ForwardIterator last, __true_type) {}

// 为啥要叫_destroy_aux?!!!!,aux是辅助的意思
// 为了得到iterator所指的类型,我们不得不做一次这样的包装
template <typename ForwardIterator, typename Content>
inline void _destroy(ForwardIterator first, ForwardIterator last, const Content&)
{
	_destroy_aux(first, last, __type_traits<Content>::has_trivial_destructor());
}

template <typename ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
	_destroy(first, last, value_type(first));
}

// char类型当然有trivial_destructor,但大家貌似经常对char*做这样的操作
// 为了优化,就直接写了这样一个特化版本,这是C++ GP里面非常重要常用的方法
// 学习了!
inline void destroy(char*, char*) {}
inline void destroy(wchar_t*, wchar_t*) {}

_STL_NAMESPACE_END

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值