#ifndef VGS_PROCTOOLS_FORMATTER_H #define VGS_PROCTOOLS_FORMATTER_H #include #include #include #include namespace proctools { class format { friend const std::string& str( const format& value ); public: template struct prec_t { prec_t(const T& val, int width): m_val(val), m_width(width) {} const T& m_val; int m_width; }; template static prec_t prec(const T& val, int width); template struct width_t { width_t(const T& val, int width): m_val(val), m_width(width) {} const T& m_val; int m_width; }; template static width_t width(const T& val, int width); template struct fill_t { fill_t(const T& val, Elem ch): m_val(val), m_ch(ch) {} const T& m_val; Elem m_ch; }; template static fill_t fill(const T& val, Elem ch); template struct base_t { base_t(const T& val, int base): m_val(val), m_base(base) {} const T& m_val; int m_base; }; template static base_t base(const T& val, int base); format(const std::string& format): m_text(format), m_index(0) {} template format& operator%(const T& object); operator const std::string&() const { return m_text; } private: std::string m_text; int m_index; }; template std::ostream& operator<<(std::ostream& s, const format::prec_t& obj) { return s << std::setprecision(obj.m_width) << obj.m_val; } template format::prec_t format::prec(const T& val, int width) { return prec_t(val, width); } template std::ostream& operator<<(std::ostream& s, const format::width_t& obj) { return s << std::setw(obj.m_width) << obj.m_val; } template format::width_t format::width(const T& val, int width) { return width_t(val, width); } template std::ostream& operator<<(std::ostream& s, const format::fill_t& obj) { return s << std::setfill(obj.m_ch) << obj.m_val; } template format::fill_t format::fill(const T& val, Elem ch) { return fill_t(val, ch); } template std::ostream& operator<<(std::ostream& s, const format::base_t& obj) { return s << std::setbase(obj.m_base) << obj.m_val; } template format::base_t format::base(const T& val, int base) { return base_t(val, base); } template format& format::operator%(const T& object) { std::stringstream stream, item; stream << object; item << "{" << m_index << "}"; std::string::size_type pos; if ((pos = m_text.find(item.str())) != std::string::npos) m_text.replace(pos, item.str().length(), stream.str()); ++m_index; return *this; } inline const std::string& str( const format& value ) { return value.m_text; } }; #endif // VGS_PROCTOOLS_FORMATTER_H