Reduce calls to rdbuf() in ostream_put

This commit is contained in:
Glen Fernandes
2020-04-05 13:30:33 -04:00
parent 5fd7b50697
commit c4a0fdd280
2 changed files with 12 additions and 12 deletions

View File

@ -8,7 +8,7 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_IO_IOS_STATE_HPP
#include <boost/io_fwd.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <ios>
#ifndef BOOST_NO_STD_LOCALE
#include <locale>

View File

@ -18,27 +18,26 @@ namespace detail {
template<class charT, class traits>
inline std::size_t
osp_put(std::basic_ostream<charT, traits>& os, const charT* data,
osp_put(std::basic_streambuf<charT, traits>& out, const charT* data,
std::size_t size)
{
return static_cast<std::size_t>(os.rdbuf()->sputn(data, size));
return static_cast<std::size_t>(out.sputn(data, size));
}
template<class charT, class traits>
inline bool
osp_fill(std::basic_ostream<charT, traits>& os, std::size_t size)
osp_fill(std::basic_streambuf<charT, traits>& out, charT c, 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::io::detail::osp_put(os, fill, chunk) != chunk) {
if (boost::io::detail::osp_put(out, fill, chunk) != chunk) {
return false;
}
}
return boost::io::detail::osp_put(os, fill, size) == size;
return boost::io::detail::osp_put(out, fill, size) == size;
}
template<class charT, class traits>
@ -75,18 +74,19 @@ ostream_put(std::basic_ostream<charT, traits>& os, const charT* data,
detail::osp_guard<charT, traits> guard(os);
typename stream::sentry entry(os);
if (entry) {
std::basic_streambuf<charT, traits>& out = *os.rdbuf();
std::size_t width = static_cast<std::size_t>(os.width());
if (width <= size) {
if (detail::osp_put(os, data, size) != size) {
if (detail::osp_put(out, data, size) != size) {
return os;
}
} else if ((os.flags() & stream::adjustfield) == stream::left) {
if (detail::osp_put(os, data, size) != size ||
!detail::osp_fill(os, width - size)) {
if (detail::osp_put(out, data, size) != size ||
!detail::osp_fill(out, os.fill(), width - size)) {
return os;
}
} else if (!detail::osp_fill(os, width - size) ||
detail::osp_put(os, data, size) != size) {
} else if (!detail::osp_fill(out, os.fill(), width - size) ||
detail::osp_put(out, data, size) != size) {
return os;
}
os.width(0);