//built with mimggw g++ (gcc version 4.5.0 (GCC))
#include <iostream>
#include <map>
#include <string>
#include <ostream>
//ploy dimensional iterators
// what we are dealing with here is a N dimensional deep map
template <int n, typename Key, typename Value >
class MultiDimMap
{
public:
//problem here for types u cant reach inside of the yet to be defined struct and get its type. You need to have it pre-definable.
typedef MultiDimMap<n-1, Key, Value> InnerMapClass;
typedef std::map<Key, InnerMapClass> MapClass;
//instance depend types.
//"typename" is need here so the compiler knows we are pointing
//to a type that is not yet a solid implementation.
typedef typename InnerMapClass::iterator InnerMapClassItr;
typedef typename MapClass::iterator MapClassItr;
class iterator
{
public:
Value& operator*() { return *inner; }
iterator& operator++()
{
++inner;
valid_or_next();
return *this;
}
bool operator!=(const iterator& oit) const
{
return (oit.outer != outer &&
(map->end() == outer ||
oit.map->end() == oit.outer ||
oit.inner != inner));
}
bool operator==(const iterator& oit) const { return !(oit != *this); }
std::ostream& print(std::ostream& out) { out << outer->first << ":"; inner.print(out); return out; }
iterator() :
map(NULL),
outer(),
inner()
{}
iterator(MapClass& map_, const MapClassItr& outer_) :
map(&map_),
outer(outer_),
inner()
{
inner = outer->second.begin();
valid_or_next();
}
private:
void valid_or_next()
{
while(
(map->end() != outer) &&
(outer->second.end() == inner)
)
{
++outer;
inner = outer->second.begin();
}
}
MapClass* map;
MapClassItr outer;
InnerMapClassItr inner;
};
iterator begin() { return iterator(map, map.begin()); }
iterator end() { return iterator(map, map.end() ); }
InnerMapClass& operator[](Key key) { return map[key]; }
private:
MapClass map;
};
//The recursive termination..
template <typename Key, typename Value >
class MultiDimMap<1, Key, Value >
{
public:
typedef std::map<Key, Value> MapClass;
//instance depend types.
//"typename" is need here so the compiler knows we are pointing
//to a type that is not yet a solid implementation.
typedef typename MapClass::iterator MapClassItr;
class iterator
{
public:
Value& operator*() { return it->second; }
iterator& operator++() { it++; return *this; }
bool operator!=(const iterator& oit) const { return oit.it != it; }
bool operator==(const iterator& oit) const { return !(oit != *this); }
std::ostream& print(std::ostream& out) const { out << it->first << ":" << it->second; return out; }
iterator() : it() {}
iterator(const MapClassItr& it_) : it(it_) {}
private:
MapClassItr it;
};
iterator begin() { return iterator(map.begin()); }
iterator end() { return iterator(map.end() ); }
Value& operator[](Key key) { return map[key]; }
private:
MapClass map;
};
//this hates me fix it later
//template <int n, typename Key, typename Value >
//std::ostream& operator<<( std::ostream& out, const typename MultiDimMap<n, Key, Value>::iterator& it )
//{
// return it.print(out);
//}
int main()
{
MultiDimMap<1, std::string, int> stringInt1DMap;
stringInt1DMap["a"] = 2;
stringInt1DMap["b"] = 5;
MultiDimMap<2, std::string, int> stringInt2DMap;
stringInt2DMap["d"]["b"] = 5;
stringInt2DMap["a"]["c"] = 2;
stringInt2DMap["d"]["c"] = 3;
MultiDimMap<3, int, std::string> intString3DMap;
intString3DMap[2][1][1] = "first";
intString3DMap[1][1][2] = "second";
intString3DMap[2][2][1] = "third";
std::cout << "1d Iteration:" << std::endl;
MultiDimMap<1, std::string, int>::iterator it1d;
for(it1d = stringInt1DMap.begin();
it1d != stringInt1DMap.end();
++it1d)
{
std::cout << " ";
it1d.print(std::cout);
std::cout << " Value:" << *it1d << std::endl;
}
std::cout << "2d Iteration:" << std::endl;
MultiDimMap<2, std::string, int>::iterator it2d;
for(it2d = stringInt2DMap.begin();
it2d != stringInt2DMap.end();
++it2d)
{
std::cout << " ";
it2d.print(std::cout);
std::cout << " Value:" << *it2d << std::endl;
}
std::cout << "3d Iteration:" << std::endl;
MultiDimMap<3, int, std::string>::iterator it3d;
for(it3d = intString3DMap.begin();
it3d != intString3DMap.end();
++it3d)
{
std::cout << " ";
it3d.print(std::cout);
std::cout << " Value:" << *it3d << std::endl;
}
}
Friday, November 4, 2011
Recursive Templates -- Iterable poly dimensional associative arrays
And here is the template based array with a iterator added to it that is capable of iterating all the final cells in the array. Its not the most efficient but it works.
Also note the operator<< is a bit busted at the moment.. Will fix it when im not about to fall asleep.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment