#ifndef _NTPM_AI_UNOP_H
#define _NTPM_AI_UNOP_H

#include <arithmetic_iterators/arithmetic_iterator.h>

namespace NTPMai {


template <class T_IT, class UNOP>
class unary_op_iterator : public arithmetic_iterator
{
public:
    typedef unary_op_iterator<T_IT,UNOP> Self;
    typedef typename UNOP::result_type value_type;
    typedef typename iterator_traits<T_IT>::difference_type difference_type;
    typedef value_type *pointer;
    typedef value_type &reference;
    typedef forward_iterator_tag iterator_category;

    unary_op_iterator() {}
    unary_op_iterator(T_IT _it) : it(_it) {}
    value_type operator*() {
	UNOP op;
	return op(static_cast<typename UNOP::argument_type>(*it));
    }
    Self &operator++() { ++it; return *this; }
    bool operator==(const Self &i) const {
	return it==i.it;
    }

private:
    T_IT it;
};

template <class T_P, class UNOP>
struct UNOP_Deffer{
    typedef Promise<unary_op_iterator<typename T_P::const_iterator,
				       UNOP> > V;
};


// handles binary operations on simple promises. returns a simple promise.
template <class T_IT, class UNOP>
inline typename UNOP_Deffer<Promise<T_IT>,UNOP>::V
make_unary_op_promise(Promise<T_IT> p, const UNOP &)
{
    typedef unary_op_iterator<Promise<T_IT>::const_iterator,UNOP> UNIT;
    UNIT begin(p.begin());
    UNIT end(p.end());
    return Promise<UNIT>(begin,end);
}


}

#endif // _NTPM_AI_UNOP_H
