#ifndef __JMULTIKEY__ #define __JMULTIKEY__ #include #include "JLang/JClass.hh" namespace JTOOLS { namespace { using JLANG::JClass; } /** * Forward declaration of template JMultiKey<> class. */ template class JMultiKey; namespace { /** * Auxiliary class for copying between const and non-const key types. */ template struct JArgument { typedef const JMultiKey& argument_type; }; template struct JArgument { typedef const JMultiKey& argument_type; }; } /** * Multi-dimensional key. * * This class reproduces the key of a multi-dimensional map. * The individual data members can be accessed as: * * JMultiKey<3, key_type> key; * * key[[.second].second].first; */ template class JMultiKey : public std::pair > { public: typedef JKey_t key_type; typedef JMultiKey mapped_type; typedef std::pair pair; /** * Default constructor. */ JMultiKey() : pair() {} /** * Constructor. * The secondary key is appended to the end of the primary keys. * * \param __first primary keys * \param __second secondary key */ JMultiKey(typename JClass::argument_type __first, typename JClass ::argument_type __second) : pair(__first.first, mapped_type(__first.second, __second)) {} /** * Constructor. * The primary key is inserted at the start of the secondary keys. * * \param __first primary key * \param __second secondary keys */ JMultiKey(typename JClass ::argument_type __first, typename JClass::argument_type __second) : pair(__first, __second) {} /** * Copy constructor. * * \param key key */ JMultiKey(typename JArgument::argument_type key) : pair(key.first, key.second) {} }; /** * Two-dimensional key. */ template class JMultiKey<2, JKey_t> : public std::pair > { public: typedef JKey_t key_type; typedef JMultiKey<1, JKey_t> mapped_type; typedef std::pair pair; /** * Default constructor. */ JMultiKey() : pair() {} /** * Constructor. * The secondary key is appended to the end of the primary key. * * \param __first primary key * \param __second secondary key */ JMultiKey(typename JClass::argument_type __first, typename JClass ::argument_type __second) : pair(__first.first, __second) {} /** * Constructor. * The primary key is inserted at the start of the secondary key. * * \param __first primary key * \param __second secondary key */ JMultiKey(typename JClass ::argument_type __first, typename JClass::argument_type __second) : pair(__first, __second) {} /** * Copy constructor. * * \param key key */ JMultiKey(typename JArgument<2, JKey_t>::argument_type key) : pair(key.first, key.second) {} }; /** * One-dimensional key. */ template class JMultiKey<1, JKey_t> { public: typedef JKey_t key_type; /** * Default constructor. */ JMultiKey() : first() {} /** * Constructor. * * \param __first key */ JMultiKey(typename JClass::argument_type __first) : first(__first) {} /** * Copy constructor. * * \param key key */ JMultiKey(typename JArgument<1, JKey_t>::argument_type key) : first(key.first) {} key_type first; }; /** * Empty key. */ template class JMultiKey<0, JKey_t> {}; /** * Less than operator. * * \param x first multi-key * \param y second multi-key * \return true if x < y; else false */ template inline bool operator<(const JMultiKey& x, const JMultiKey& y) { if (x.first == y.first) return x.second < y.second; else return x.first < y.first; } /** * Less than operator. * * \param x first multi-key * \param y second multi-key * \return true if x < y; else false */ template inline bool operator<(const JMultiKey<1, JKey_t>& x, const JMultiKey<1, JKey_t>& y) { return x.first < y.first; } /** * Equal operator. * * \param x first multi-key * \param y second multi-key * \return true if x equals y; else false */ template inline bool operator==(const JMultiKey& x, const JMultiKey& y) { return (x.first == y.first && x.second == y.second); } /** * Equal operator. * * \param x first multi-key * \param y second multi-key * \return true if x equals y; else false */ template inline bool operator==(const JMultiKey<1, JKey_t>& x, const JMultiKey<1, JKey_t>& y) { return (x.first == y.first); } } #endif