#ifndef __JLANG__JSTREAMAVAILABLE__ #define __JLANG__JSTREAMAVAILABLE__ #include #include #include #include "JLang/JBool.hh" /** * \author mdejong */ /** * Test availability of stream operators. */ template class JStreamAvailable { template static auto is(U*) -> decltype(std::declval() >> std::declval()); template static auto os(U*) -> decltype(std::declval() << std::declval()); template static auto is(...) -> std::false_type; template static auto os(...) -> std::false_type; public: static const bool has_istream = std::is_same(0))>::value; //!< true if std::istream& operator>>(std::istream&, T&) is defined; else false static const bool has_ostream = std::is_same(0))>::value; //!< true if std::ostream& operator<<(std::ostream&, const T&) is defined; else false }; /** * Auxiliary data structure for handling std::ostream. */ struct STREAM { protected: /** * Auxiliary class for format stream. */ struct JStream { /** * Constructor. * * \param out output stream * \param message message printed in case operator std::ostream<< is unavailable */ JStream(std::ostream& out, const std::string& message) : out (out), message(message) {} /** * Write value to output stream. * * \param value value * \return this JStream */ template std::ostream& operator<<(const T& value) { using namespace JPP; return print(out, value, JBool::has_ostream>()); } private: /** * Print value if given option is true. * * \param out output stream * \param value value * \param option true * \return output stream */ template std::ostream& print(std::ostream& out, const T& value, const JLANG::JBool& option) { return out << value; } /** * Print value if given option is true. * * \param out output stream * \param value value * \param option false * \return output stream */ template std::ostream& print(std::ostream& out, const T& value, const JLANG::JBool& option) { return out << message; } std::ostream& out; std::string message; }; std::string message; public: /** * Constructor. * * \param message message printed in case operator std::ostream<< is unavailable */ STREAM(const std::string& message = "") : message(message) {} /** * Format specifier. * * \param out output stream * \param format format * \return output stream */ friend inline JStream operator<<(std::ostream& out, const STREAM& format) { return JStream(out, format.message); } }; #endif