#include #include #include #include #include #include using namespace std; union Integer; union Integer { public: const Integer& fred; // recurse on everything below fred const Integer& recurse(const function fred2,const Integer& fred3) const { if (data) { return [&](const Integer& fred) mutable throw() -> const Integer& { return fred.recurse(fred2,fred2(fred3,fred));} (fred); } else return fred3; } bool isZero() const { return data == 0; } private: Integer() : fred(*this){}; Integer(const Integer& fred2) : fred(fred2){}; int *data; friend class EnterpriseIntegerFactory; friend ostream& operator<<(ostream&,const Integer&); }; ostream& operator<<(ostream& fred2,const Integer& fred3) { fred2 << "{"; fred3.recurse([&](const Integer& fred,const Integer& fred4) mutable throw() -> const Integer& { fred2 << fred4 << ","; return fred;},fred3); return fred2 << "}"; } class EnterpriseIntegerFactory { list m_allocPool; public: Integer Zero; EnterpriseIntegerFactory() { memset(&Zero.data,0,sizeof(int*)); } Integer& CreateSucc(const Integer& fred) { Integer* ret = new Integer(fred); m_allocPool.push_back(ret); return *ret; } ~EnterpriseIntegerFactory() { for_each(m_allocPool.begin(),m_allocPool.end(),[](Integer* val) -> void { delete val;}); } }; class EnterpriseOperationFactory; class CurriedOperation { public: CurriedOperation(EnterpriseOperationFactory *p_Factory,const Integer& a) : fred(a) { m_Factory = p_Factory; } protected: const Integer& fred; EnterpriseOperationFactory *m_Factory; virtual const Integer& doOp(const Integer& b)=0; friend class EnterpriseOperationFactory; }; class EnterpriseOperationFactory { EnterpriseIntegerFactory* m_Factory; public: EnterpriseOperationFactory(EnterpriseIntegerFactory *p_Factory) : m_Factory(p_Factory) {} class Adder : public CurriedOperation { public: Adder(EnterpriseOperationFactory *p_Factory, const Integer& a) : CurriedOperation(p_Factory,a) {}; const Integer& doOp(const Integer& num) { return fred.recurse([&](const Integer& fred3,const Integer& fred2) -> const Integer& { return m_Factory->m_Factory->CreateSucc(fred3);}, num); } }; class Multiplier : public CurriedOperation { public: Multiplier(EnterpriseOperationFactory *p_Factory, const Integer& a) : CurriedOperation(p_Factory,a) {}; const Integer& doOp(const Integer& num) { return fred.recurse([&](const Integer& fred,const Integer& fred2) -> const Integer& { return m_Factory->add(num,fred);}, m_Factory->m_Factory->Zero); } }; class Factorial : public CurriedOperation { public: Factorial(EnterpriseOperationFactory *p_Factory, const Integer& a) : CurriedOperation(p_Factory,a) {}; const Integer& doOp(const Integer& dummy) { return fred.recurse([&](const Integer& fred,const Integer& fred2) -> const Integer& { return fred.isZero() ? m_Factory->m_Factory->CreateSucc(m_Factory->m_Factory->Zero) : // Return 1 instead of 0. m_Factory->mult(fred,m_Factory->m_Factory->CreateSucc(fred2)); // Otherwise multiply by iterator. },m_Factory->m_Factory->CreateSucc(m_Factory->m_Factory->Zero)); } }; const Integer& add(const Integer& a,const Integer& b) { Adder adder(this,a); return adder.doOp(b); } const Integer& mult(const Integer& a,const Integer& b) { Multiplier mult(this,a); return mult.doOp(b); } const Integer& fact(const Integer& a) { Factorial fact(this,a); return fact.doOp(fact.m_Factory->m_Factory->Zero); } }; int IntegerToInt(const Integer& fred) { int i = 0; fred.recurse([&](const Integer& a,const Integer& b)-> const Integer& {i++; return a;},fred); return i; } int _tmain(int argc, _TCHAR* argv[]) { EnterpriseIntegerFactory factory; EnterpriseOperationFactory fred(&factory); Integer& one = factory.CreateSucc(factory.Zero); const Integer& onePlusOne = fred.add(one,one); cout << "1+1: " << IntegerToInt(onePlusOne) << " - " << onePlusOne << endl; system("pause"); Integer& five = factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.Zero))))); Integer& three = factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.Zero))); cout << "5: " << IntegerToInt(five) << " - "<< five << endl; cout << "3: " << IntegerToInt(three) << " - " << three << endl; const Integer& fivePlusThree = fred.add(five,three); cout << "5+3: " << IntegerToInt(fivePlusThree) << " - " << fivePlusThree << endl; Integer& num = factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.CreateSucc(factory.Zero)))); cout << IntegerToInt(num) << " - " << num << endl; system("pause"); const Integer& fiveTimesThree = fred.mult(five,three); cout << "5*3: " << IntegerToInt(fiveTimesThree) << " - " << endl; system("pause"); const Integer& threeFactorial = fred.fact(factory.CreateSucc(three)); cout << "3!: " << IntegerToInt(threeFactorial) << " - " << endl; system("pause"); return 0; }