//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