#ifndef _either_hxx_ #define _either_hxx_ #include #include #include using std::ostream; using std::function; template class either { public: static either left (L l) { return either(&l,NULL); } static either right(R r) { return either(NULL,&r); } bool isLeft () const { return (_l != NULL); } bool isRight() const { return (_r != NULL); } L fromLeft () const { assert(isLeft ()); return L(*_l); } R fromRight () const { assert(isRight()); return R(*_r); } ~either() { if (_l != NULL) delete _l; if (_r != NULL) delete _r; } private: L* _l; R* _r; either(const L* l,const R* r) : _l(l != NULL ? new L(*l) : NULL) , _r(r != NULL ? new R(*r) : NULL) {} }; template ostream& operator<<(ostream& out,const either &e) { if (e.isLeft()) out << ""; if (e.isRight()) out << ""; return out; } template either Bind(either e,function(R1)>& f) { if (e.isLeft()) return either::left(e.fromLeft()); return f(e.fromRight()); } template either Return(R r) { return either::right(r); } template either operator>>=(eithere,function(R1)>&f) { if (e.isLeft()) return either::left(e.fromLeft()); return f(e.fromRight()); } #endif