#ifndef __PairUtils__
#define __PairUtils__
#include "Metaiterators.hpp"
namespace Lib {
template<typename P>
struct FirstOfPairFn
{
typename P::first_type operator()(P p) { return p.first; }
};
template<typename P>
struct SecondOfPairFn
{
typename P::second_type operator()(P p) { return p.second; }
};
template<typename C, typename D>
struct PairRightPushingFn
{
PairRightPushingFn(C c) : _c(c) {}
std::pair<C,D> operator()(D d) { return std::pair<C,D>(_c,d); }
private:
C _c;
};
template<typename C, class D>
struct PairLeftPushingFn
{
PairLeftPushingFn(D d): _d(d) {}
std::pair<C,D> operator()(C c) { return std::pair<C,D>(c,_d); }
private:
D _d;
};
template<typename C, typename DIt>
MappingIterator<DIt,PairRightPushingFn<C,ELEMENT_TYPE(DIt)> >
pushPairIntoRightIterator(std::pair<C, DIt > obj)
{
return getMappingIterator(obj.second, PairRightPushingFn<C,ELEMENT_TYPE(DIt)>(obj.first));
}
template<typename C, typename DIt>
MappingIterator<DIt,PairRightPushingFn<C,ELEMENT_TYPE(DIt)> >
pushPairIntoRightIterator(C c, DIt dit)
{
return getMappingIterator(std::move(dit), PairRightPushingFn<C,ELEMENT_TYPE(DIt)>(c));
}
template<typename C, typename D>
class RightPushedPair
{
public:
DECL_ELEMENT_TYPE(std::pair<C,ELEMENT_TYPE(D)>);
DECL_ITERATOR_TYPE(MappingIterator<ITERATOR_TYPE(D),PairRightPushingFn<C,ELEMENT_TYPE(D)> >);
RightPushedPair(std::pair<C,D> p) : _p(p) {}
std::pair<C,D> get() { return _p; }
private:
std::pair<C,D> _p;
};
template<typename C, typename DItb>
MappingIterator<ITERATOR_TYPE(DItb),PairRightPushingFn<C,ELEMENT_TYPE(DItb)> >
getContentIterator(RightPushedPair<C,DItb> obj)
{
return pushPairIntoRightIterator(obj.get().first,
getContentIterator(obj.get().second) );
}
};
#endif