#pragma once
#include<iostream>template<typenameT>structunbounded{private:enumclasstag_t{POSITIVE_INFINITY,NEGATIVE_INFINITY,FINITE}tag_;Tvalue_;unbounded(tag_ttag_):tag_(tag_){}public:usingvalue_type=T;unbounded():tag_(tag_t::FINITE),value_(T()){}unbounded(Tvalue_):tag_(tag_t::FINITE),value_(value_){}unbounded(constunbounded<T>&that):tag_(that.tag_),value_(that.value_){}boolis_positive_inf()const{returntag_==tag_t::POSITIVE_INFINITY;}boolis_negative_inf()const{returntag_==tag_t::NEGATIVE_INFINITY;}boolis_finite()const{returntag_==tag_t::FINITE;}Tvalue()const{returnvalue_;}T&value(){returnvalue_;}staticautopositive_inf(){returnunbounded(tag_t::POSITIVE_INFINITY);}staticautonegative_inf(){returnunbounded(tag_t::NEGATIVE_INFINITY);}friendstd::ostream&operator<<(std::ostream&s,constunbounded&a){switch(a.tag_){casetag_t::POSITIVE_INFINITY:s<<"∞";break;casetag_t::NEGATIVE_INFINITY:s<<"-∞";break;casetag_t::FINITE:s<<a.value_;}returns;}unboundedoperator-()const{if(is_finite())return-value_;elseif(is_positive_inf())returnunbounded::negative_inf();returnunbounded::positive_inf();}auto&operator+=(unboundedthat){if(is_finite()){if(that.is_finite())value_+=that.value_;elsetag_=that.tag_;}return*this;}autooperator+(unboundedthat)const{returnunbounded(*this)+=that;}auto&operator-=(unboundedthat){return(*this)+=(-that);}autooperator-(unboundedthat)const{returnunbounded(*this)-=that;}intcompare(unboundedthat)const{if(is_positive_inf()){if(that.is_positive_inf())return0;elsereturn1;}elseif(is_negative_inf()){if(that.is_negative_inf())return0;elsereturn-1;}else{if(that.is_positive_inf())return-1;elseif(that.is_negative_inf())return1;elsereturn(value_>that.value_)-(value_<that.value_);}}booloperator==(unboundedthat)const{returncompare(that)==0;}booloperator!=(unboundedthat)const{returncompare(that)!=0;}booloperator<(unboundedthat)const{returncompare(that)<0;}booloperator<=(unboundedthat)const{returncompare(that)<=0;}booloperator>(unboundedthat)const{returncompare(that)>0;}booloperator>=(unboundedthat)const{returncompare(that)>=0;}};