mirror of
https://github.com/boostorg/utility.git
synced 2025-05-09 15:04:00 +00:00
Make string_view operator<< use rdbuf directly
This commit is contained in:
parent
f03b681d01
commit
5fe9df91c0
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) Marshall Clow 2012-2015.
|
Copyright (c) Marshall Clow 2012-2015.
|
||||||
|
Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -424,32 +425,43 @@ namespace boost {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline void sr_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
inline std::size_t sr_os_put(std::basic_ostream<charT, traits>& os,
|
||||||
enum { chunk_size = 8 };
|
const charT* data, std::size_t size) {
|
||||||
charT fill_chars[chunk_size];
|
return static_cast<std::size_t>(os.rdbuf()->sputn(data, size));
|
||||||
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
}
|
||||||
for (; n >= chunk_size && os.good(); n -= chunk_size)
|
|
||||||
os.write(fill_chars, static_cast< std::size_t >(chunk_size));
|
|
||||||
if (n > 0 && os.good())
|
|
||||||
os.write(fill_chars, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
void sr_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
inline bool sr_os_fill(std::basic_ostream<charT, traits>& os,
|
||||||
const std::size_t size = str.size();
|
std::size_t size) {
|
||||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
enum { chunk = 8 };
|
||||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
charT fill[chunk];
|
||||||
if (!align_left) {
|
std::fill_n(fill, static_cast<std::size_t>(chunk), os.fill());
|
||||||
detail::sr_insert_fill_chars(os, alignment_size);
|
for (; size > chunk; size -= chunk) {
|
||||||
if (os.good())
|
if (detail::sr_os_put(os, fill, chunk) != chunk) {
|
||||||
os.write(str.data(), size);
|
return false;
|
||||||
}
|
|
||||||
else {
|
|
||||||
os.write(str.data(), size);
|
|
||||||
if (os.good())
|
|
||||||
detail::sr_insert_fill_chars(os, alignment_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return detail::sr_os_put(os, fill, size) == size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class charT, class traits>
|
||||||
|
class sr_os_holder {
|
||||||
|
public:
|
||||||
|
explicit sr_os_holder(std::basic_ostream<charT, traits>& os)
|
||||||
|
: os_(&os) { }
|
||||||
|
~sr_os_holder() BOOST_NOEXCEPT_IF(false) {
|
||||||
|
if (os_) {
|
||||||
|
os_->setstate(std::basic_ostream<charT, traits>::badbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void release() {
|
||||||
|
os_ = 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
sr_os_holder(const sr_os_holder&);
|
||||||
|
sr_os_holder& operator=(const sr_os_holder&);
|
||||||
|
std::basic_ostream<charT, traits>* os_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@ -457,15 +469,28 @@ namespace boost {
|
|||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline std::basic_ostream<charT, traits>&
|
inline std::basic_ostream<charT, traits>&
|
||||||
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
||||||
if (os.good()) {
|
typedef std::basic_ostream<charT, traits> stream;
|
||||||
const std::size_t size = str.size();
|
detail::sr_os_holder<charT, traits> hold(os);
|
||||||
const std::size_t w = static_cast< std::size_t >(os.width());
|
typename stream::sentry entry(os);
|
||||||
if (w <= size)
|
if (entry) {
|
||||||
os.write(str.data(), size);
|
std::size_t width = static_cast<std::size_t>(os.width());
|
||||||
else
|
std::size_t size = str.size();
|
||||||
detail::sr_insert_aligned(os, str);
|
if (width <= size) {
|
||||||
os.width(0);
|
if (detail::sr_os_put(os, str.data(), size) != size) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||||
|
if (detail::sr_os_put(os, str.data(), size) != size ||
|
||||||
|
!detail::sr_os_fill(os, width - size)) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} else if (!detail::sr_os_fill(os, width - size) ||
|
||||||
|
detail::sr_os_put(os, str.data(), size) != size) {
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
os.width(0);
|
||||||
|
}
|
||||||
|
hold.release();
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) Marshall Clow 2012-2015.
|
Copyright (c) Marshall Clow 2012-2015.
|
||||||
Copyright (c) Beman Dawes 2015
|
Copyright (c) Beman Dawes 2015
|
||||||
|
Copyright (c) Glen Joseph Fernandes 2019 (glenjofe@gmail.com)
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@ -574,32 +575,43 @@ namespace boost {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
inline std::size_t sv_os_put(std::basic_ostream<charT, traits>& os,
|
||||||
enum { chunk_size = 8 };
|
const charT* data, std::size_t size) {
|
||||||
charT fill_chars[chunk_size];
|
return static_cast<std::size_t>(os.rdbuf()->sputn(data, size));
|
||||||
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
}
|
||||||
for (; n >= chunk_size && os.good(); n -= chunk_size)
|
|
||||||
os.write(fill_chars, static_cast< std::size_t >(chunk_size));
|
|
||||||
if (n > 0 && os.good())
|
|
||||||
os.write(fill_chars, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
void sv_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
|
inline bool sv_os_fill(std::basic_ostream<charT, traits>& os,
|
||||||
const std::size_t size = str.size();
|
std::size_t size) {
|
||||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
enum { chunk = 8 };
|
||||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
charT fill[chunk];
|
||||||
if (!align_left) {
|
std::fill_n(fill, static_cast<std::size_t>(chunk), os.fill());
|
||||||
detail::sv_insert_fill_chars(os, alignment_size);
|
for (; size > chunk; size -= chunk) {
|
||||||
if (os.good())
|
if (detail::sv_os_put(os, fill, chunk) != chunk) {
|
||||||
os.write(str.data(), size);
|
return false;
|
||||||
}
|
|
||||||
else {
|
|
||||||
os.write(str.data(), size);
|
|
||||||
if (os.good())
|
|
||||||
detail::sv_insert_fill_chars(os, alignment_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return detail::sv_os_put(os, fill, size) == size;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class charT, class traits>
|
||||||
|
class sv_os_holder {
|
||||||
|
public:
|
||||||
|
explicit sv_os_holder(std::basic_ostream<charT, traits>& os)
|
||||||
|
: os_(&os) { }
|
||||||
|
~sv_os_holder() BOOST_NOEXCEPT_IF(false) {
|
||||||
|
if (os_) {
|
||||||
|
os_->setstate(std::basic_ostream<charT, traits>::badbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void release() {
|
||||||
|
os_ = 0;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
sv_os_holder(const sv_os_holder&);
|
||||||
|
sv_os_holder& operator=(const sv_os_holder&);
|
||||||
|
std::basic_ostream<charT, traits>* os_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
@ -608,15 +620,28 @@ namespace boost {
|
|||||||
inline std::basic_ostream<charT, traits>&
|
inline std::basic_ostream<charT, traits>&
|
||||||
operator<<(std::basic_ostream<charT, traits>& os,
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
const basic_string_view<charT,traits>& str) {
|
const basic_string_view<charT,traits>& str) {
|
||||||
if (os.good()) {
|
typedef std::basic_ostream<charT, traits> stream;
|
||||||
const std::size_t size = str.size();
|
detail::sv_os_holder<charT, traits> hold(os);
|
||||||
const std::size_t w = static_cast< std::size_t >(os.width());
|
typename stream::sentry entry(os);
|
||||||
if (w <= size)
|
if (entry) {
|
||||||
os.write(str.data(), size);
|
std::size_t width = static_cast<std::size_t>(os.width());
|
||||||
else
|
std::size_t size = str.size();
|
||||||
detail::sv_insert_aligned(os, str);
|
if (width <= size) {
|
||||||
os.width(0);
|
if (detail::sv_os_put(os, str.data(), size) != size) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||||
|
if (detail::sv_os_put(os, str.data(), size) != size ||
|
||||||
|
!detail::sv_os_fill(os, width - size)) {
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} else if (!detail::sv_os_fill(os, width - size) ||
|
||||||
|
detail::sv_os_put(os, str.data(), size) != size) {
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
os.width(0);
|
||||||
|
}
|
||||||
|
hold.release();
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user