Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MichaelBurge/237217e3151f2788f3c04c1c5ded4f4c to your computer and use it in GitHub Desktop.
Save MichaelBurge/237217e3151f2788f3c04c1c5ded4f4c to your computer and use it in GitHub Desktop.
Old "enterprise" integer operations in C++
#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