#include <iostream>
#include <map>
#include <string>
class ValueNotFoundException {};
template<typename T> class Memory
{
typedef std::map<std::string, T> MemoryMap;
Memory<T> *outerMemory;
MemoryMap mmap;
std::string memname; // tylko dla wydruku :D
Memory(Memory *outer, std::string name) // tylko dla wydruku :D (memname = name)
: outerMemory(outer), memname(name)
{
}
public:
std::string getName(void) const { return memname; } // tylko dla wydruku :D
static Memory getGlobal(void)
{
static Memory global(0, "(global)");
return global;
}
Memory createInnerMemory(std::string name)
{
return Memory(this, name);
}
Memory<T>& setValue(std::string name, T value)
{
mmap[name] = value;
return *this;
}
T getValue(std::string name)
{
if(mmap.find(name) != mmap.end()) return mmap[name]; // gdy znaleziono...
if(!outerMemory) throw ValueNotFoundException(); // gdy nie znaleziono i jesteśmy w "globalu", to nie ma i na razie :D
return outerMemory->getValue(name); // gdy nie znzaleziono, ale to na szczescie jakas inna pamiec :P
}
unsigned printMemTree() // tylko dla wydruku
{
using std::cout;
using std::endl;
class Helper
{
public:
static void addTabs(unsigned u)
{
for(unsigned i = 0; i < u; i++)
cout << " ";
}
};
unsigned tabs = outerMemory ? outerMemory->printMemTree() : 0; // dobijamy sie aż do globala
Helper::addTabs(tabs);
cout << "ZAKRES \"" << memname << "\" : " << endl;
typedef typename MemoryMap::iterator Iter;
for(Iter it = mmap.begin(); it != mmap.end(); it++) // ALE SIĘ WKURWIŁEM TU KOMPILATORZE JEBANY
{
Helper::addTabs(tabs + 1);
cout << '\"' << it->first << "\" : " << it->second << endl;
}
return tabs + 1; // jedziem wyżej :D
}
};
template<typename T> void print(std::string name, Memory<T>& mem)
{
try
{
T value = mem.getValue(name);
std::cout << '`' << name << '`' << " (z perspektywy \"" << mem.getName() <<"\") = " << value << std::endl;
}
catch(ValueNotFoundException&)
{
std::cout << "Nie znaleziono zmiennej `" << name << "` z zakresu \"" << mem.getName() << '\"' << std::endl;
}
}
int main(void)
{
typedef Memory<int> MemI;
MemI global = MemI::getGlobal();
MemI inner1 = global.createInnerMemory("inner1");
MemI inner2 = inner1.createInnerMemory("inner2");
global.setValue("o", 123);
inner1.setValue("x", 666).setValue("r", 30);
inner2.setValue("x", 82);
inner2.printMemTree(); // rysujemy drzewko :P
// TESTUJEMY
print("o", global);
print("r", inner2);
print("o", inner2);
print("dupadupadupa", inner1);
print("x", inner2);
print("o", inner1);
return 0;
}