#ifndef __JSELECTOR__ #define __JSELECTOR__ #include #include #include #include #include "JLang/JClonable.hh" #include "JLang/JAbstractIO.hh" #include "JLang/JConversion.hh" #include "JLang/JSharedPointer.hh" #include "JLang/JParameter.hh" #include "JLang/JClass.hh" namespace JTOOLS { namespace { using JLANG::JClonable; using JLANG::JStreamInput; using JLANG::JConversion; using JLANG::JSharedPointer; using JLANG::JParameter; using JLANG::JClass; } /** * Template definition of selector class. * This class can be used to set up a list of keys that are mapped to values which * are clonable and optionally readable. * A value can be cloned using method get(), provided a key has been selected * beforehand using the redirect operator (istream&)>> or the method set(..). * N.B: This class owns the objects pointed to using JSharedPointer<> * (with the default new/delete memory management policy). */ template >::is_derived, bool is_readible = JConversion::is_derived> class JSelector; /** * Template specialisation of JSelector class for clonable (but not readable) objects. */ template class JSelector : public std::map > { public: typedef std::map > map_type; typedef typename map_type::const_iterator const_iterator; typedef JClass_t* data_type; typedef typename JClass::argument_type argument_type; typedef typename map_type::value_type value_type; /** * Default constructor. */ JSelector() : std::map >() {} /** * Set key. * * \param key key */ void set(argument_type key) { this->key = key; } /** * Check validy of given key. * * \param key key * \return true if given key maps to a non-NULL value; else false */ bool is_valid(argument_type key) const { const_iterator i = this->find(key); return i != this->end() && i->second.is_valid(); } /** * Check validy of selected key. * * \return true if selected key maps to a non-NULL value; else false */ bool is_valid() const { return key.isDefined() && is_valid(key); } /** * Get clone of given key. * * \param key key * \return pointer to newly created object (or NULL) */ data_type get(argument_type key) const { const_iterator i = this->find(key); if (i != this->end()) return i->second->clone(); else return NULL; } /** * Get a clone of the value corresponding to the key selected by the last valid * input stream operation or call to method set(). * This method returns the optional default value if no key has been selected. * * \param value default value * \return pointer to newly created object (or NULL) */ data_type get(data_type value = NULL) const { if (key.isDefined()) return get(key); else return value; } /** * Read selector from input. * * \param in input stream * \param selector selector * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JSelector& selector) { in >> selector.key; return in; } /** * Write selector to output. * * \param out output stream * \param selector selector * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JSelector& selector) { out << selector.key; return out; } protected: JParameter key; }; /** * Template specialisation of JSelector class for clonable and readable objects. */ template class JSelector : public JSelector { public: typedef std::map > map_type; typedef typename map_type::const_iterator const_iterator; typedef JClass_t* data_type; typedef typename JClass::argument_type argument_type; typedef typename map_type::value_type value_type; /** * Default constructor. */ JSelector() : JSelector() {} /** * Constructor. * * \param value default value */ JSelector(data_type value) : JSelector(value) {} /** * Read selector and possibly object data from input. * * \param in input stream * \param selector selector * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JSelector& selector) { if (in >> selector.key) { const_iterator i = selector.find(selector.key); if (i != selector.end()) i->second->read(in); else in.setstate(std::ios_base::failbit); } return in; } }; } #endif