#ifndef __JTOOLS__JMULTIHASHMAP__ #define __JTOOLS__JMULTIHASHMAP__ #include "JLang/JNullType.hh" #include "JLang/JTypeList.hh" #include "JLang/JSinglePointer.hh" #include "JLang/JEquals.hh" #include "JLang/JForwardIterator.hh" #include "JLang/JException.hh" #include "JTools/JHashMap.hh" #include "JTools/JHashEvaluator.hh" #include "JTools/JTuple.hh" #include "JTools/JPair.hh" /** * \file * * General purpose class for multidimensional hash maps. * \author mdejong */ namespace JTOOLS {} namespace JPP { using namespace JTOOLS; } namespace JTOOLS { using JLANG::JEquals; using JLANG::JForwardIterator; using JLANG::JNullType; using JLANG::JTypeList; using JLANG::JTYPELIST; using JLANG::JClass; using JLANG::JIndexOutOfRange; using JIO::JReader; using JIO::JWriter; /** * Multi-dimensional hash map. */ template struct JHashMap, JValue_t, JEvaluator_t> : public JHashMap, JEvaluator_t> { typedef JHead_t key_type; typedef JHashMap mapped_type; typedef std::pair value_type; typedef JEvaluator_t evaluator_type; typedef JTuple< JTypeList > multikey_type; typedef JHashMap map_type; typedef typename map_type::const_iterator const_iterator; typedef typename map_type::const_reverse_iterator const_reverse_iterator; typedef typename map_type::iterator iterator; typedef typename map_type::reverse_iterator reverse_iterator; using map_type::get; using map_type::put; using map_type::has; using map_type::erase; /** * Constructor. * * \param evaluator evaluator */ JHashMap(const JEvaluator_t& evaluator = JEvaluator_t()) : JHashMap, JEvaluator_t>(evaluator) {} class super_const_iterator; // forward declaration /** * Multidimensional iterator. */ class super_iterator : public JEquals , public JForwardIterator { typedef JPair value_type; typedef JLANG::JSinglePointer pointer_type; typedef JTuple< JTypeList > reference_type; friend class JHashMap; public: /** * Default constructor. */ super_iterator() {} /** * Smart pointer operator. * * \return pointer to pair of iterators */ pointer_type operator->() { return pointer_type(new value_type(i->first, second)); } /** * Dereference operator. * * \return multidimensional pair */ reference_type operator*() { return reference_type(i->first, *second); } /** * Equality of super iterator. * * \param cursor super iterator * \return true if equal; else false */ virtual bool equals(const super_iterator& cursor) const { return i == cursor.i && (i == range.second || second.equals(cursor.second)); } /** * Increment super_iterator. * * \return true if valid; else false */ virtual bool increment() override { if (!second.increment()) { while (++i != range.second) { second = i->second.super_begin(); if (second != i->second.super_end()) { break; } } } return i != range.second; } /** * Get multi-dimensional key. * * \return key */ multikey_type getKey() const { return multikey_type(i->first, second.getKey()); } /** * Get value. * * \return value */ JValue_t& getValue() { return second.getValue(); } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_iterator(iterator __begin, iterator __end) : range(__begin, __end) { for (i = range.first; i != range.second; ++i) { second = i->second.super_begin(); if (second != i->second.super_end()) { break; } } } std::pair range; iterator i; typename mapped_type::super_iterator second; }; /** * Multidimensional const_iterator. */ class super_const_iterator : public JEquals , public JForwardIterator { typedef JPair value_type; typedef JLANG::JSinglePointer pointer_type; typedef JTuple< JTypeList > reference_type; friend class JHashMap; public: /** * Default constructor. */ super_const_iterator() {} /** * Copy constructor. * * \param cursor super_iterator */ super_const_iterator(super_iterator cursor) : range (cursor.range), i (cursor.i), second(cursor.second) {} /** * Smart pointer operator. * * \return pointer to pair of iterators */ pointer_type operator->() { return pointer_type(new value_type(i->first, second)); } /** * Dereference operator. * * \return multidimensional pair */ reference_type operator*() { return reference_type(i->first, *second); } /** * Equality of super iterator. * * \param cursor super iterator * \return true if equal; else false */ virtual bool equals(const super_const_iterator& cursor) const { return i == cursor.i && (i == range.second || second.equals(cursor.second)); } /** * Increment super_iterator. * * \return true if valid; else false */ virtual bool increment() override { if (!second.increment()) { while (++i != range.second) { second = i->second.super_begin(); if (second != i->second.super_end()) { break; } } } return i != range.second; } /** * Get multi-dimensional key. * * \return key */ multikey_type getKey() const { return multikey_type(i->first, second.getKey()); } /** * Get value. * * \return value */ const JValue_t& getValue() { return second.getValue(); } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_const_iterator(const_iterator __begin, const_iterator __end) : range(__begin, __end) { for (i = range.first; i != range.second; ++i) { second = i->second.super_begin(); if (second != i->second.super_end()) { break; } } } std::pair range; const_iterator i; typename mapped_type::super_const_iterator second; }; /** * Get super_iterator to begin of data. * * \return super iterator */ super_const_iterator super_begin() const { return super_const_iterator(this->begin(), this->end()); } /** * Get super_iterator to end of data. * * \return super iterator */ super_const_iterator super_end() const { return super_const_iterator(this->end(), this->end()); } /** * Get super_iterator to begin of data. * * \return super iterator */ super_iterator super_begin() { return super_iterator(this->begin(), this->end()); } /** * Get super_iterator to end of data. * * \return super iterator */ super_iterator super_end() { return super_iterator(this->end(), this->end()); } /** * Get mapped value. * * \param key key * \return value */ JValue_t& get(const multikey_type& key) { this->get(key.first).get(key.second); } /** * Get mapped value. * * This method will throw an exception if given key is not present following the prerequisite of constness. * * \param key key * \return value */ const JValue_t& get(const multikey_type& key) const { this->get(key.first).get(key.second); } /** * Put tuple-wise element (key,value) into collection. * * \param key key * \param value value */ void put(const multikey_type& key, const JValue_t& value) { this->get(key.first).put(key.second, value); } /** * Erase element. * * \param key key * \return true if element with given key has been erased; else false */ bool erase(const multikey_type& key) { if (this->has(key.first)) return this->get(key.first).erase(key.second); else return false; } /** * Test whether key is present. * * \param key key * \return true if present; else false */ bool has(const multikey_type& key) const { return map_type::has(key.first) && this->get(key.first).has(key.second); } }; /** * Terminator class of recursive class JHashMap. */ template struct JHashMap, JValue_t, JEvaluator_t> : public JHashMap { typedef JHead_t key_type; typedef JValue_t mapped_type; typedef std::pair value_type; typedef JEvaluator_t evaluator_type; typedef JHead_t multikey_type; typedef JHashMap map_type; typedef typename map_type::const_iterator const_iterator; typedef typename map_type::const_reverse_iterator const_reverse_iterator; typedef typename map_type::iterator iterator; typedef typename map_type::reverse_iterator reverse_iterator; /** * Constructor. * * \param evaluator evaluator */ JHashMap(const JEvaluator_t& evaluator = JEvaluator_t()) : JHashMap(evaluator) {} class super_const_iterator; // forward declaration /** * Terminator class of multidimensional iterator. */ class super_iterator : public JEquals , public JForwardIterator { typedef JPair value_type; typedef JLANG::JSinglePointer pointer_type; typedef JTuple< JTypeList > reference_type; friend class JHashMap; public: /** * Default constructor. */ super_iterator() {} /** * Smart pointer operator. * * \return pointer to pair of iterators */ pointer_type operator->() { return pointer_type(new value_type(i->first, i->second)); } /** * Dereference operator. * * \return multidimensional pair */ reference_type operator*() { return reference_type(i->first, i->second); } /** * Equality of super iterator. * * \param cursor super iterator * \return true if equal; else false */ virtual bool equals(const super_iterator& cursor) const { return i == cursor.i; } /** * Increment super_iterator. * * \return true if valid; else false */ virtual bool increment() override { return ++i != range.second; } /** * Get multi-dimensional key. * * \return key */ multikey_type getKey() const { return multikey_type(i->first); } /** * Get value. * * \return value */ JValue_t& getValue() { return i->second; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_iterator(iterator __begin, iterator __end) : range(__begin, __end), i (__begin) {} std::pair range; iterator i; }; /** * Terminator class of multidimensional const_iterator. */ class super_const_iterator : public JEquals , public JForwardIterator { typedef JPair value_type; typedef JLANG::JSinglePointer pointer_type; typedef JTuple< JTypeList > reference_type; friend class JHashMap; public: /** * Default constructor. */ super_const_iterator() {} /** * Copy constructor. * * \param cursor super_iterator */ super_const_iterator(super_iterator cursor) : range(cursor.range), i (cursor.i) {} /** * Smart pointer operator. * * \return pointer to pair of iterators */ pointer_type operator->() { return pointer_type(new value_type(i->first, i->second)); } /** * Dereference operator. * * \return multidimensional pair */ reference_type operator*() { return reference_type(i->first, i->second); } /** * Equality of super iterator. * * \param cursor super iterator * \return true if equal; else false */ virtual bool equals(const super_const_iterator& cursor) const { return i == cursor.i; } /** * Increment super_iterator. * * \return true if valid; else false */ virtual bool increment() override { return ++i != range.second; } /** * Get multi-dimensional key. * * \return key */ multikey_type getKey() const { return multikey_type(i->first); } /** * Get value. * * \return value */ const JValue_t& getValue() { return i->second; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_const_iterator(const_iterator __begin, const_iterator __end) : range(__begin, __end), i (__begin) {} std::pair range; const_iterator i; }; /** * Get super_iterator to begin of data. * * \return super_iterator */ super_const_iterator super_begin() const { return super_const_iterator(this->begin(), this->end()); } /** * Get super_iterator to end of data. * * \return super_iterator */ super_const_iterator super_end() const { return super_const_iterator(this->end(), this->end()); } /** * Get super_iterator to begin of data. * * \return super_iterator */ super_iterator super_begin() { return super_iterator(this->begin(), this->end()); } /** * Get super_iterator to end of data. * * \return super_iterator */ super_iterator super_end() { return super_iterator(this->end(), this->end()); } }; } #endif