/* Copyright 2019 Glen Joseph Fernandes (glenjofe@gmail.com) Distributed under the Boost Software License, Version 1.0. (http://www.boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_UTILITY_OSTREAM_STRING_HPP #define BOOST_UTILITY_OSTREAM_STRING_HPP #include #include #include namespace boost { namespace detail { template inline std::size_t oss_put(std::basic_ostream& os, const charT* data, std::size_t size) { return static_cast(os.rdbuf()->sputn(data, size)); } template inline bool oss_fill(std::basic_ostream& os, std::size_t size) { charT c = os.fill(); charT fill[] = { c, c, c, c, c, c, c, c }; enum { chunk = sizeof fill / sizeof(charT) }; for (; size > chunk; size -= chunk) { if (boost::detail::oss_put(os, fill, chunk) != chunk) { return false; } } return boost::detail::oss_put(os, fill, size) == size; } template class oss_guard { public: explicit oss_guard(std::basic_ostream& os) BOOST_NOEXCEPT : os_(&os) { } ~oss_guard() BOOST_NOEXCEPT_IF(false) { if (os_) { os_->setstate(std::basic_ostream::badbit); } } void release() BOOST_NOEXCEPT { os_ = 0; } private: oss_guard(const oss_guard&); oss_guard& operator=(const oss_guard&); std::basic_ostream* os_; }; } /* detail */ template inline std::basic_ostream& ostream_string(std::basic_ostream& os, const charT* data, std::size_t size) { typedef std::basic_ostream stream; detail::oss_guard guard(os); typename stream::sentry entry(os); if (entry) { std::size_t width = static_cast(os.width()); if (width <= size) { if (detail::oss_put(os, data, size) != size) { return os; } } else if ((os.flags() & stream::adjustfield) == stream::left) { if (detail::oss_put(os, data, size) != size || !detail::oss_fill(os, width - size)) { return os; } } else if (!detail::oss_fill(os, width - size) || detail::oss_put(os, data, size) != size) { return os; } os.width(0); } guard.release(); return os; } } /* boost */ #endif