#ifndef __JLANG__JPRINTHELPER__ #define __JLANG__JPRINTHELPER__ #include #include "JLang/JType.hh" #include "JLang/JBool.hh" #include "JLang/JTest.hh" #include "JLang/JClass.hh" /** * \author mdejong */ namespace JLANG {} namespace JPP { using namespace JLANG; } namespace JLANG { /** * Auxiliary class to print via member method const char* __str__() const;. */ class JPrintHelper { /** * Print interface. */ struct JTypeout { /** * Virtual destructor. */ virtual ~JTypeout() {} /** * Print object. * * \param out output stream * \param p pointer to object * \return output stream */ virtual std::ostream& print(std::ostream& out, const void* p) const = 0; }; /** * Type writer implementation of interface JTypeout based on member method const char* __str__() const; */ template struct JTypewriter : public JTypeout { /** * Print object. * * \param out output stream * \param p pointer to object * \return output stream */ virtual std::ostream& print(std::ostream& out, const void* p) const override { return out << ((const T*) p)->__str__();; } }; /** * Get type writer. * * \param type type * \param option true */ template static JTypeout* get(JType type, JBool option) { return new JTypewriter(); } const void* p; //!< pointer to object JTypeout* typeout; //!< pointer to printer interface public: /** * Test for availability of member method const char* __str__() const;. */ template::is_primitive> class JMemberMethod : public JTest { using JTest::test; template static JTrue test(JTypecheck*); public: static const bool __str__ = JTEST(test(0)); }; /** * Specialisation of JMemberMethod for primitive data types. */ template struct JMemberMethod { static const bool __str__ = false; }; /** * Constructor * * \param object object */ template JPrintHelper(const T& object) : p(&object), typeout(get(JType(), JBool::__str__>())) {} /** * Destructor. */ ~JPrintHelper() { delete typeout; } /** * Print object. * * \param out output stream * \return output stream */ inline std::ostream& print(std::ostream& out) const { return typeout->print(out, p); } private: JPrintHelper(const JPrintHelper&); JPrintHelper(JPrintHelper&&); JPrintHelper& operator=(const JPrintHelper&); JPrintHelper& operator=(JPrintHelper&&); }; /** * Auxiliary class to temporarily replace std::ostream. */ struct JPrinter { /** * Constructor. * * \param out output stream */ JPrinter(std::ostream& out) : __out(out) {} /** * Type definition of I/O operator. */ typedef std::ostream& (*io_manip) (std::ostream&); /** * Parse I/O manipulator. * * \param manip I/O manipulator * \return output stream */ inline std::ostream& operator<<(io_manip manip) { return __out << manip; } /** * Parse object. * * \param object object * \return output stream */ template inline std::ostream& operator<<(const T& object) { return __out << object; } private: std::ostream& __out; }; } /** * Print object via helper. * * \param out output stream * \param object object * \return output stream */ inline JLANG::JPrinter operator<<(std::ostream& out, const JLANG::JPrintHelper& object) { return object.print(out); } #endif