#ifndef __JTOOLS__JSELECTOR__ #define __JTOOLS__JSELECTOR__ #include #include #include #include "JLang/JSharedPointer.hh" #include "JLang/JAbstractIO.hh" #include "JLang/JParameter.hh" #include "JLang/JClass.hh" #include "JLang/JType.hh" #include "JLang/JException.hh" #include "JTools/JDriver.hh" /** * \author mdejong */ namespace JTOOLS {} namespace JPP { using namespace JTOOLS; } namespace JTOOLS { using JLANG::JSharedPointer; using JLANG::JStreamInput; using JLANG::JStreamOutput; using JLANG::JType; using JLANG::JNullPointerException; /** * Abstract class of an automatic pointer. * This abstract class can be used for loading and storing of objects. */ template class JAbstractAutoPointer : public JSharedPointer, public JStreamInput, public JStreamOutput { public: /** * Default constructor. */ JAbstractAutoPointer() : JSharedPointer(), JStreamInput(), JStreamOutput() {} }; /** * Template class for loading and storing of objects. * This class implements the JAbstractAutoPointer interface. */ template class JAutoPointer : public JAbstractAutoPointer, private JDriver { public: /** * Default constructor. */ JAutoPointer() : JAbstractAutoPointer() {} /** * Constructor. * This class owns the pointer. * * \param p pointer to object */ JAutoPointer(JDerived_t* p) : JAbstractAutoPointer() { this->reset(p); } /** * Stream input. * This method creates a new object and read the corresponding input data * if the redirect operator >>(isteam&) is defined for this data type. * * \param in input stream * \return input stream */ virtual std::istream& read(std::istream& in) override { JDerived_t* p = this->load(in); if (p != NULL) { this->reset(p); } return in; } /** * Stream output. * This method writes the corresponding data * if the redirect operator <<(osteam&) is defined for this data type. * * \param out output stream * \return output stream */ virtual std::ostream& write(std::ostream& out) const override { this->store(out, this->get()); return out; } }; /** * Handler class for automatic pointer. */ template class JAutoElement : public JSharedPointer< JAbstractAutoPointer > { typedef JAbstractAutoPointer JAbstractAutoPointer_t; typedef JSharedPointer JSharedPointer_t; typedef JAutoElement JAutoElement_t; public: /** * Default constructor. */ JAutoElement() : JSharedPointer_t() {} /** * Constructor. * * \param type data type */ template JAutoElement(JType type) : JSharedPointer_t() { this->set(type); } /** * Constructor. * This class owns the pointer. * * \param p pointer to object */ template JAutoElement(JDerived_t* p) : JSharedPointer_t() { this->set(p); } /** * Set the automatic pointer to the given data type. */ template void set() { this->set(JType()); } /** * Set the automatic pointer to the given data type. * * \param type data type */ template void set(JType type) { this->reset(new JAutoPointer()); } /** * Set the automatic pointer to the given data type. * * \param p pointer to object */ template void set(JDerived_t* p) { this->reset(new JAutoPointer(p)); } /** * Assign given data type to the automatic pointer. * * \param type data type * \return this JAutoElement */ template JAutoElement& operator=(JType type) { set(type); return *this; } /** * Assign given data type to the automatic pointer. * * \param p pointer to object * \return this JAutoElement */ template JAutoElement& operator=(JDerived_t* p) { set(p); return *this; } /** * Stream input. * * \param in input stream * \param element element * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JAutoElement_t& element) { if (element.is_valid()) return element.get()->read(in); else return in; } /** * Stream output. * * \param out output stream * \param element element * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JAutoElement_t& element) { if (element.is_valid()) return element.get()->write(out); else return out; } }; /** * Template selector class. * This class can be used to set up a list of keys that are mapped to handlers * which create new objects by stream input operations. */ template class JSelector : public std::map > { public: typedef std::map > map_type; typedef typename map_type::const_iterator const_iterator; typedef typename map_type::iterator iterator; typedef typename JLANG::JClass::argument_type argument_type; typedef typename map_type::value_type value_type; /** * Default constructor. */ JSelector() : map_type() {} /** * Insert data type at given key. * * \param key key * \param type data type */ template void insert(argument_type key, JType type) { map_type::insert(value_type(key, JAutoElement(type))); } /** * Insert data type at given key. * * \param key key */ template void insert(argument_type key) { insert(key, JType()); } /** * Insert data type at given key. * This object pointed to will become the default value. * * \param key key * \param p pointer to object */ template void insert(argument_type key, JDerived_t* p) { this->key = key; map_type::insert(value_type(key, JAutoElement(p))); } /** * Get key. * * \return key */ JKey_t getKey() const { return this->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() && i->second.get()->is_valid(); } /** * Check validy of selected key. * * \return true if selected key maps to a valid object; else false */ bool is_valid() const { return key.isDefined() && is_valid(key); } /** * Get the object corresponding to the given key. * * \param key key * \return object */ JBase_t& get(argument_type key) const { const_iterator i = this->find(key); if (i != this->end() && i->second.is_valid() && i->second.get()->is_valid()) return *(i->second.get()->get()); else throw JNullPointerException("JSelecor<>: no object."); } /** * Get the object corresponding to the selected key. * * \return selected object */ JBase_t& get() const { if (key.isDefined()) return this->get(key); else throw JNullPointerException("JSelecor<>: no selection."); } /** * Read selector from input stream. * * \param in input stream * \param selector selector * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JSelector& selector) { if (in >> selector.key) { typename JSelector::iterator i = selector.find(selector.key); if (i != selector.end() && i->second.is_valid()) in >> i->second; else in.setstate(std::ios_base::failbit); } return in; } /** * Write selector to output stream. * * \param out output stream * \param selector selector * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JSelector& selector) { if (selector.key.isDefined()) { typename JSelector::const_iterator i = selector.find(selector.key); if (i != selector.end() && i->second.is_valid()) { return out << selector.key << ' ' << *(i->second); } } return out; } protected: JLANG::JParameter key; }; } #endif