# C++ 泛型算法学习笔记（equal, accumulate, back_iterator, pair）

## equal

equal是区间比较算法

template <class _InputIterator1, class _InputIterator2>
inline _LIBCPP_INLINE_VISIBILITY
bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2)
{
typedef typename iterator_traits<_InputIterator1>::value_type __v1;
typedef typename iterator_traits<_InputIterator2>::value_type __v2;
return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
}

template <class _InputIterator1, class _InputIterator2, class _BinaryPredicate>
inline _LIBCPP_INLINE_VISIBILITY
bool
equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _BinaryPredicate __pred)
{
for (; __first1 != __last1; ++__first1, (void) ++__first2)
if (!__pred(*__first1, *__first2))
return false;
return true;
}

struct _point{
int x;
int y;
_point():x(0), y(0) {  }
_point(int x_,int y_):x(x_), y(y_) {  }
friend _point operator + (const _point p1, const _point p2){
_point p(p1);
p.x = p.x + p2.x;
p.y = p.y + p2.y;
return p;
}
friend ostream& operator << (ostream &out,const _point p){
out<<"("<<p.x<<" , "<<p.y<<")";
return out;
}
friend bool operator == (const _point &p1, const _point &p2){
return p1.x == p2.x && p1.y == p2.y;
}
};

int main()
{
_point p[] = {{0,0},{1,1},{2,2}};
cout<<equal(p,p+2,p)<<endl;
return 0;
}

    cout<<equal(p+1,p+2,p+2,[](const _point p1,const _point p2){
return p1.y && p2.y && p1.x/p1.y == p2.x/p2.y;
})<<endl;

bool isPalindrome(const string str){
return equal(str.begin(),str.begin()+str.size()/2,str.rbegin());
}

int main()
{
cout<<isPalindrome("abcba")<<endl;
cout<<isPalindrome("jordan")<<endl;
return 0;
}

## accumulate

accumulate函数定义在numeric头文件中，用于计算一段范围内的元素之和。

template <class _InputIterator, class _Tp, class _BinaryOperation>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
{
for (; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}

struct _point{
int x;
int y;
_point():x(0), y(0) {  }
_point(int x_,int y_):x(x_), y(y_) {  }
friend _point operator + (const _point p1, const _point p2){
_point p(p1);
p.x = p.x + p2.x;
p.y = p.y + p2.y;
return p;
}
friend ostream& operator << (ostream &out,const _point p){
out<<"("<<p.x<<" , "<<p.y<<")";
return out;
}
};

int main()
{
vector<_point> vp;
vp.push_back(_point(1,1));
vp.push_back(_point(2,2));
vp.push_back(_point(3,3));
cout<<accumulate(vp.begin(),vp.end(),_point(0,0))<<endl;

cout<<accumulate(vp.begin(),vp.end(),_point(0,0),[](const _point p1, const _point p2){
_point p(p1);
p.x = p.x - p2.x;
p.y = p.y - p2.y;
return p;
})<<endl;
return 0;
}

## back_iterator

back_iterator返回对象的地址。

template <class _Container>
inline _LIBCPP_INLINE_VISIBILITY
back_insert_iterator<_Container>
back_inserter(_Container& __x)
{
return back_insert_iterator<_Container>(__x);
}

// ==>

_LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}

// ==>

template <class _Tp>
inline _LIBCPP_NO_CFI _LIBCPP_INLINE_VISIBILITY
_Tp*
{
return reinterpret_cast<_Tp *>(
const_cast<char *>(&reinterpret_cast<const volatile char &>(__x)));
}

// operator = 调用了容器的push_back函数。

_LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
{container->push_back(__value_); return *this;}

    string str;
str.push_back('1');
auto it = back_inserter(str);
*it = '2';
cout<<str<<endl;  //12

    string str;
str.push_back('1');
fill_n(back_inserter(str),10,'0');
cout<<str<<endl;  //10000000000

## pair

template<typename T1, typename T2, typename T3>
struct treble {
T1 first;
T2 second;
T3 third;
treble(): first(),second(),third() {}
treble(const T1 &__first, const T2 &__second, const T3 &__third){
first = __first; second = __second; third = __third;
}
treble& operator = (const treble &another){
this->first = another.first;
this->second = another.second;
this->third = another.third;
return *this;
}
template <typename T>
void basic_swap(T &t1, T &t2){
T t = t1;
t1 = t2;
t2 = t;
}
void swap(treble &another){
basic_swap(first,another.first);
basic_swap(second,another.second);
basic_swap(third,another.third);
}
friend ostream & operator <<(ostream &out, const treble &ins){
out<<"("<<ins.first<<", "<<ins.second<<", "<<ins.third<<")";
return out;
}
};

template<typename T1, typename T2, typename T3>
inline _LIBCPP_INLINE_VISIBILITY
treble<T1,T2,T3>
make_treble(const T1 &__first, const T2 &__second, const T3 &__third)
{
return treble<T1, T2, T3>(__first, __second, __third);
}

int main()
{
treble<int,string,double> ins = make_treble(1,string("one"),1.00);
cout<<ins<<endl;

treble<int,string,double> ano;
ano.swap(ins);
cout<<"after swap:\n";
cout<<ano<<endl;
cout<<ins<<endl;
return 0;
}