Untitled
unknown
plain_text
a year ago
4.6 kB
1
Indexable
Never
#include <iostream> #include <vector> class Number { public: typedef int Representation; class InvalidNumber { }; Number(); Number( const InvalidNumber& invalid ); explicit Number( const Representation& v ); friend Number operator + ( const Number& rop, const Number& lop ); bool operator == ( const Number& v ); bool operator != ( const Number& v ); bool operator == ( const Representation& v ); bool operator != ( const Representation& v ); bool IsValid() const; Representation GetRepresentation() const; private: Representation mValue; bool mValid; }; Number::Number() : mValue { 0 }, mValid { false } { } Number::Number( const Number::InvalidNumber& invalid ) : mValue { 0 }, mValid { false } { } Number::Number( const Representation& v ) : mValue { v }, mValid { true } { } bool Number::IsValid() const { return mValid; } Number::Representation Number::GetRepresentation() const { return mValue; } bool Number::operator == ( const Number& v ) { return ( v.mValid == mValid ) && ( v.mValue == mValue ); } bool Number::operator != ( const Number& v ) { return ( v.mValid != mValid ) || ( v.mValue != mValue ); } bool Number::operator == ( const Number::Representation& v ) { return ( mValid ) && ( v == mValue ); } bool Number::operator != ( const Number::Representation& v ) { return ( !mValid ) || ( v != mValue ); } Number operator + ( const Number& rop, const Number& lop ) { if( rop.mValid && lop.mValid ) { return Number { rop.mValue + lop.mValue }; } else { return Number { Number::InvalidNumber() }; } } Number NumberParser( const char* numberString ) { const char* p = numberString; while( *p != '\0' ) { if( !isdigit( *p ) ) { return Number { Number::InvalidNumber() }; } ++p; } Number::Representation value = atoi( numberString ); return Number { value }; } std::ostream& operator<< ( std::ostream& os, const Number& num ) { if( num.IsValid() ) { os << num.GetRepresentation(); } else { os << "Invalid number"; } return os; } class SimpleOperation { public: typedef Number Result_t; typedef Number Parameter_t; virtual ~SimpleOperation(); virtual Result_t operator()( const Parameter_t&, const Parameter_t& ) = 0; }; SimpleOperation::~SimpleOperation() { } class AssociativeOperation : public SimpleOperation { }; class SimpleSum : public AssociativeOperation { public: virtual Result_t operator()( const Parameter_t&, const Parameter_t& ); }; SimpleSum::Result_t SimpleSum::operator()( const Parameter_t& a, const Parameter_t& b ) { Result_t res = a + b; return res; } class PackOperation { public: AssociativeOperation::Result_t operator()( const std::vector<AssociativeOperation::Parameter_t>& ); virtual AssociativeOperation& getOperation() = 0; }; AssociativeOperation::Result_t PackOperation::operator()( const std::vector<AssociativeOperation::Parameter_t>& parameters ) { AssociativeOperation& operation = getOperation(); AssociativeOperation::Result_t tempResult = AssociativeOperation::Result_t { 0 }; for( auto param : parameters ) { tempResult = operation( tempResult, param ); } return tempResult; } class PackSum : public PackOperation { public: virtual AssociativeOperation& getOperation(); private: SimpleSum mSum; }; AssociativeOperation& PackSum::getOperation() { return mSum; } void print_usage() { std::cout << "Sum operator1 operator2\n"; std::cout << "print the sum of the operator \n"; } void print_parsingError( int argIndex ) { std::cout << "Error while parsing argument " << argIndex << "\n"; std::cout << "Aborting...\n"; } void print_result( Number res ) { std::cout << res << "\n"; } int main( int argc, char* argv[] ) { if( argc < 3 ) { print_usage(); return 1; } std::vector<Number> addends; int opIdx = 1; while( opIdx < argc ) { Number n = NumberParser( argv[opIdx] ); if( n == Number::InvalidNumber() ) { print_parsingError( opIdx ); return 1; } addends.push_back( n ); opIdx++; } PackOperation* op = new PackSum(); Number result = ( *op )( addends ); delete op; print_result( result ); return 0; }