#ifndef __JROUTER__ #define __JROUTER__ #include #include "JLang/JComparisonAvailable.hh" namespace JTOOLS { namespace { using JLANG::JComparisonAvailable; } /** * Direct addressing of elements with unique identifiers. */ template::has_eq> class JRouter; /** * Template specialisation of JRouter without default address comparison. */ template class JRouter : protected std::deque { public: /** * Default constructor. */ JRouter() : std::deque() {} /** * Virtual destructor. */ virtual ~JRouter() {} /** * Get default address. * * \return default address */ virtual const JAddress_t& getDefaultAddress() const { static JAddress_t address; return address; } /** * Put entry. * * \param id identifier * \param address address */ void put(const int id, const JAddress_t& address) { if (this->empty()) { this->push_back(address); first = id; } else { for ( ; id < first; --first) this->push_front(getDefaultAddress()); const unsigned int index = (unsigned int) (id - first); while (index >= this->size()) this->push_back(getDefaultAddress()); this->at(index) = address; } } /** * Check whether given id is in range. * * \param id identifier * \return true if in range; else false */ bool in_range(const int id) const { return (id >= this->first && id < this->first + (int) this->size()); } /** * Get entry. * * \param id identifier * \return address */ const JAddress_t& get(const int id) const { return this->at(id - first); } protected: int first; }; /** * Template specialisation of JRouter wit default address comparison. */ template class JRouter : public JRouter { protected: /** * Simple data structure for validation of address. */ class JAddress { public: friend class JRouter; /** * Default constructor. */ JAddress() : __is_valid(false), __address () {} /** * Constructor. * * \param address default address */ JAddress(const JAddress_t& address) : __is_valid(true), __address (address) {} /** * Compare to given address. * * \param address address * \return true if valid and equal; else false */ bool equals(const JAddress_t& address) const { return __is_valid && address == __address; } private: bool __is_valid; JAddress_t __address; }; public: /** * Default constructor. */ JRouter() : JRouter(), defaultAddress() {} /** * Constructor. * * \param address default address */ JRouter(const JAddress_t& address) : JRouter(), defaultAddress(address) {} /** * Check availability of default address. * * \return true if available; else false */ bool hasDefaultAddress() const { return defaultAddress.isValid(); } /** * Get default address. * * \return default address */ virtual const JAddress_t& getDefaultAddress() const { return defaultAddress.__address; } /** * Set default address. * * \param address default address */ void setDefaultAddress(const JAddress_t& address) { defaultAddress = JAddress(address); } /** * Has valid entry (i.e in range and not equal to default address). * * \param id identifier * \return true if present and not equal to default; else false */ bool has(const int id) const { return (this->in_range(id) && !this->defaultAddress.equals(this->get(id))); } private: JAddress defaultAddress; }; } #endif