Created
March 21, 2018 04:04
-
-
Save MichaelBurge/237217e3151f2788f3c04c1c5ded4f4c to your computer and use it in GitHub Desktop.
Old "enterprise" integer operations in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <deque> | |
#include <functional> | |
#include <string> | |
#include <list> | |
#include <algorithm> | |
using namespace std; | |
union Integer; | |
union Integer | |
{ | |
public: | |
const Integer& fred; | |
// recurse on everything below fred | |
const Integer& recurse(const function<const Integer&(const Integer&,const Integer&)> 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<Integer*> 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) << " - <Set representation too large>" << endl; | |
system("pause"); | |
const Integer& threeFactorial = fred.fact(factory.CreateSucc(three)); | |
cout << "3!: " << IntegerToInt(threeFactorial) << " - " << endl; | |
system("pause"); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment