#ifndef __JMIXEDMULTIMAP__ #define __JMIXEDMULTIMAP__ #include "JLang/JClass.hh" #include "JLang/JMapList.hh" #include "JLang/JEquals.hh" #include "JLang/JIncrement.hh" #include "JTools/JPair.hh" #include "JTools/JMultiPair.hh" namespace JTOOLS { namespace { using JLANG::JNullType; using JLANG::JMapList; using JLANG::JMapLength; using JLANG::JMultipleMap; using JLANG::JEquals; using JLANG::JIncrement; } /** * Mixed multi-dimensional map. * * The first template parameter refers to the data type of the (multi-dimensional) key, * the second to the data type of the overall mapped value and * the third to the list of maps used. * * The first_type and second_type refer to the pair-wise element of this map, respectively. * The key_type and mapped_type refer to the data type of the (multi-dimensional) key and * the data type of overall mapped value, respectively. */ template class JMixedMultiMap; template class JMap_t, class JTail_t> class JMixedMultiMap > : public JMap_t > { public: enum { NUMBER_OF_DIMENSIONS = JMapLength< JMapList >::value }; typedef JMap_t > JMultiMap_t; typedef JKey_t key_type; typedef JValue_t mapped_type; typedef typename JMultiMap_t::key_type first_type; typedef typename JMultiMap_t::mapped_type second_type; typedef typename JMultiMap_t::value_type value_type; typedef typename JMultiMap_t::iterator iterator; typedef typename JMultiMap_t::reverse_iterator reverse_iterator; typedef typename JMultiMap_t::const_iterator const_iterator; typedef typename JMultiMap_t::const_reverse_iterator const_reverse_iterator; using JMultiMap_t::insert; /** * Default constructor. */ JMixedMultiMap() : JMultiMap_t() {} /** * Insert element. * * \param key multi-dimensional key * \param value value */ void insert(const JMultiKey& key, const JValue_t& value) { (*this)[key.first].insert(key.second, value); } /** * Insert element. * * \param value multi-dimensional pair */ void insert(const JMultiPair& value) { (*this)[value.first].insert(value.second); } class super_const_iterator; // forward declaration /** * Multi-dimensional iterator. */ class super_iterator : public JEquals , public JIncrement { public: typedef JPair element_type; typedef std::auto_ptr pointer; typedef JMultiPair reference; friend class JMixedMultiMap >; friend class super_const_iterator; /** * Default constructor. */ super_iterator() {} pointer operator->() { return pointer(new element_type(i->first, second)); } reference operator*() { return reference(i->first, *second); } /** * Equality of super_iterator. * * \param that super_iterator * \return true if equal; else false */ bool equals(const super_iterator& that) const { return i == that.i && (i == end || second.equals(that.second)); } /** * Increment super_iterator. * * \return true if valid; else false */ bool increment() { if (!second.increment()) { while (++i != end) { second = i->second.super_begin(); if (second != i->second.super_end()) break; } } return i != end; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_iterator(iterator __begin, iterator __end) { begin = __begin; end = __end; for (i = begin; i != end; ++i) { second = i->second.super_begin(); if (second != i->second.super_end()) break; } } iterator begin; iterator end; iterator i; typename second_type::super_iterator second; }; /** * Multi-dimensional const_iterator. */ class super_const_iterator : public JEquals , public JIncrement { public: typedef JPair element_type; typedef std::auto_ptr pointer; typedef JMultiPair reference; friend class JMixedMultiMap >; /** * Default constructor. */ super_const_iterator() {} /** * Copy constructor. * * \param that super_iterator */ super_const_iterator(super_iterator that) : begin(that.begin), end (that.end), i (that.i), second(that.second) {} pointer operator->() { return pointer(new element_type(i->first, second)); } reference operator*() { return reference(i->first, *second); } /** * Equality of super_iterator. * * \param that super_iterator * \return true if equal; else false */ bool equals(const super_const_iterator& that) const { return i == that.i && (i == end || second.equals(that.second)); } /** * Increment super_iterator. * * \return true if valid; else false */ bool increment() { if (!second.increment()) { while (++i != end) { second = i->second.super_begin(); if (second != i->second.super_end()) break; } } return i != end; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_const_iterator(const_iterator __begin, const_iterator __end) { begin = __begin; end = __end; for (i = begin; i != end; ++i) { second = i->second.super_begin(); if (second != i->second.super_end()) break; } } const_iterator begin; const_iterator end; const_iterator i; typename second_type::super_const_iterator second; }; /** * 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 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()); } }; /** * Terminator class of recursive JMixedMultiMap<..., JMapList<> > class. */ template class JMap_t> class JMixedMultiMap > : public JMap_t { public: enum { NUMBER_OF_DIMENSIONS = 1 }; typedef JMap_t JMultiMap_t; typedef JKey_t key_type; typedef JValue_t mapped_type; typedef typename JMultiMap_t::key_type first_type; typedef typename JMultiMap_t::mapped_type second_type; typedef typename JMultiMap_t::value_type value_type; typedef typename JMultiMap_t::iterator iterator; typedef typename JMultiMap_t::reverse_iterator reverse_iterator; typedef typename JMultiMap_t::const_iterator const_iterator; typedef typename JMultiMap_t::const_reverse_iterator const_reverse_iterator; using JMultiMap_t::insert; /** * Default constructor. */ JMixedMultiMap() : JMultiMap_t() {} /** * Insert element. * * \param key multi-dimensional key * \param value value */ void insert(const JMultiKey<1, JKey_t>& key, const JValue_t& value) { insert(value_type(key.first, value)); } /** * Insert element. * * \param value multi-dimensional pair */ void insert(const JMultiPair<1, JKey_t, JValue_t>& value) { insert(value_type(value.first, value.second)); } class super_const_iterator; // forward declaration /** * Terminator class of multi-dimensional iterator. */ class super_iterator : public JEquals , public JIncrement { public: typedef JPair element_type; typedef std::auto_ptr pointer; typedef JMultiPair<1, const JKey_t, JValue_t&> reference; friend class JMixedMultiMap >; friend class super_const_iterator; /** * Default constructor. */ super_iterator() {} pointer operator->() { return pointer(new element_type(i->first, i->second)); } reference operator*() { return reference(i->first, i->second); } /** * Equality of super_iterator. * * \param that super_iterator * \return true if equal; else false */ bool equals(const super_iterator& that) const { return i == that.i; } /** * Increment super_iterator. * * \return true if valid; else false */ bool increment() { return ++i != end; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_iterator(iterator __begin, iterator __end) { begin = __begin; end = __end; i = __begin; } iterator begin; iterator end; iterator i; }; /** * Terminator class of multi-dimensional const_iterator. */ class super_const_iterator : public JEquals , public JIncrement { public: typedef JPair element_type; typedef std::auto_ptr pointer; typedef JMultiPair<1, const JKey_t, const JValue_t&> reference; friend class JMixedMultiMap >; /** * Default constructor. */ super_const_iterator() {} /** * Copy constructor. * * \param that super_iterator */ super_const_iterator(super_iterator that) : begin(that.begin), end (that.end), i (that.i) {} pointer operator->() { return pointer(new element_type(i->first, i->second)); } reference operator*() { return reference(i->first, i->second); } /** * Equality of super_iterator. * * \param that super_iterator * \return true if equal; else false */ bool equals(const super_const_iterator& that) const { return i == that.i; } /** * Increment super_iterator. * * \return true if valid; else false */ bool increment() { return ++i != end; } private: /** * Constructor. * * \param __begin begin of data * \param __end end of data */ super_const_iterator(const_iterator __begin, const_iterator __end) { begin = __begin; end = __end; i = __begin; } const_iterator begin; const_iterator end; const_iterator i; }; /** * 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 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()); } }; /** * Copy multi-dimensional map. * * \param input multi-dimensional map * \param output multi-dimensional map */ template void copy(const JMixedMultiMap& input, JMappableCollection& output) { output.clear(); for (typename JMixedMultiMap::const_iterator i = input.begin(); i != input.end(); ++i) copy(i->second, output[i->first]); } } #endif