Compare commits

...

12 Commits

Author SHA1 Message Date
Andrey Semashev
75276a055d Disabled all but one OS X jobs because they are slow on Travis CI. 2019-10-22 15:11:41 +03:00
Andrey Semashev
309e6a1b31 Updated CI configs, added compilers. 2019-10-22 00:52:54 +03:00
Andrey Semashev
9eeb7f85c5 Replaced tabs with spaces. 2019-06-25 15:46:36 +03:00
Daniel Frey
62c34f51f6 Avoid confusion with the spaceship operator, fixes #59 2019-04-30 18:29:28 +02:00
Glen Fernandes
6a1917ceec Add Free Functions section heading 2019-04-29 20:12:30 -04:00
Glen Fernandes
47c9f69ffe Correct documentation URLs and update documentation 2019-04-29 18:48:51 -04:00
Glen Fernandes
7b74d2d494 Update libraries.json and documentation 2019-04-23 15:37:57 -04:00
Marshall Clow
57da5f0c18 Merge pull request #58 from boostorg/ostream_write
Refactor stream write functionality into a standalone utility
2019-04-23 03:56:04 -07:00
Glen Fernandes
dabf53a703 Refactor stream write functionality into a standalone utility 2019-04-19 09:53:29 -04:00
Marshall Clow
ff56b3649e Merge pull request #57 from glenfe/develop
Make string_view operator<< use rdbuf directly
2019-04-18 09:00:53 -07:00
Peter Dimov
31e0ae4c37 Switch Appveyor to 2015 image 2019-04-14 18:13:56 +03:00
Glen Fernandes
5fe9df91c0 Make string_view operator<< use rdbuf directly 2019-04-12 18:06:35 -04:00
13 changed files with 556 additions and 140 deletions

View File

@@ -1,4 +1,5 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2019 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
@@ -24,12 +25,32 @@ matrix:
- env: BOGUS_JOB=true
include:
# gcc, Linux
- os: linux
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
dist: trusty
compiler: gcc-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.7
dist: trusty
compiler: gcc-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: gcc-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
@@ -39,7 +60,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.8
dist: xenial
compiler: gcc-4.8
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
@@ -47,8 +69,10 @@ matrix:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.9
dist: xenial
compiler: gcc-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
@@ -58,7 +82,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-5
dist: xenial
compiler: gcc-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
@@ -68,7 +93,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-6
dist: xenial
compiler: gcc-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
@@ -78,8 +104,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
dist: xenial
compiler: gcc-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
@@ -89,9 +115,9 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
dist: xenial
compiler: gcc-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
@@ -100,22 +126,34 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
dist: bionic
compiler: gcc-9
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-9
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
# clang, Linux
- os: linux
compiler: clang++-3.5
dist: trusty
compiler: clang-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.5 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-3.6
dist: trusty
compiler: clang-3.6
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
addons:
apt:
@@ -124,10 +162,12 @@ matrix:
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.6 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-3.7
dist: trusty
compiler: clang-3.7
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
addons:
apt:
@@ -136,83 +176,149 @@ matrix:
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- sourceline: "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-3.8
dist: xenial
compiler: clang-3.8
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-5-dev
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-3.9
dist: xenial
compiler: clang-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-5-dev
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-3.9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-4.0
dist: xenial
compiler: clang-4
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-5-dev
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-4.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-5.0
dist: xenial
compiler: clang-5
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
- libstdc++-5-dev
- libstdc++-7-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-5.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17
dist: xenial
compiler: clang-6
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-6.0
- libstdc++-5-dev
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-6.0 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
compiler: clang++-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17
dist: xenial
compiler: clang-7
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-7
- libstdc++-5-dev
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-7 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-8
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-8
- libstdc++-8-dev
sources:
- ubuntu-toolchain-r-test
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-8 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-9
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-9
- libstdc++-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
- os: linux
dist: xenial
compiler: clang-libc++
env: TOOLSET=clang COMPILER=clang++-9 CXXSTD=03,11,14,17,2a CXXFLAGS="-stdlib=libc++" LINKFLAGS="-stdlib=libc++"
addons:
apt:
packages:
- clang-9
- libc++-9-dev
- libc++abi-9-dev
sources:
- sourceline: "ppa:ubuntu-toolchain-r/test"
- sourceline: "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main"
key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key"
# clang, OS X
# OS X builds are slow on Travis CI
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode9.4
#
# - os: osx
# env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
# osx_image: xcode10.3
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,17
osx_image: xcode11.2
install:
- GIT_FETCH_JOBS=8
@@ -243,7 +349,7 @@ script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null`
- ./b2 -j $BUILD_JOBS libs/utility/test toolset=$TOOLSET cxxstd=$CXXSTD
- ./b2 -j $BUILD_JOBS libs/utility/test toolset=$TOOLSET cxxstd=$CXXSTD ${CXXFLAGS:+cxxflags="$CXXFLAGS"} ${LINKFLAGS:+linkflags="$LINKFLAGS"}
notifications:
email:

View File

@@ -1,4 +1,5 @@
# Copyright 2016, 2017 Peter Dimov
# Copyright 2016-2019 Peter Dimov
# Copyright 2019 Andrey Semashev
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
@@ -14,13 +15,43 @@ branches:
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
TOOLSET: msvc-14.0
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
TOOLSET: msvc-14.1
- TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.0
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: msvc-14.1
CXXSTD: 14,17
ADDRMD: 32,64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: msvc-14.2
ADDRMD: 32,64
CXXSTD: 14,17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
- TOOLSET: clang-win
ADDRMD: 32,64
CXXSTD: 14,17
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\cygwin\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\cygwin64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
- TOOLSET: gcc
CXXSTD: 03,11,14,1z
ADDPATH: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin;
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
install:
- set GIT_FETCH_JOBS=8
@@ -43,7 +74,7 @@ install:
- git submodule init libs/integer
- git submodule init libs/detail
- git submodule update --jobs %GIT_FETCH_JOBS%
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility\
- cmd /c bootstrap
- b2 -d0 headers
@@ -52,4 +83,5 @@ build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/utility/test toolset=%TOOLSET% %CXXSTD%
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
- b2 -j %NUMBER_OF_PROCESSORS% libs/utility/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% variant=debug,release

View File

@@ -99,6 +99,19 @@ boostbook standalone_declval
<xsl:param>generate.section.toc.level=1
;
xml ostream_string : ostream_string.qbk ;
boostbook standalone_ostream_string
:
ostream_string
:
<xsl:param>root.filename=ostream_string
<xsl:param>chunk.section.depth=0
<xsl:param>chunk.first.sections=0
<xsl:param>toc.section.depth=1
<xsl:param>toc.max.depth=1
<xsl:param>generate.section.toc.level=1
;
xml string_ref : string_ref.qbk ;
boostbook standalone_string_ref
:
@@ -123,5 +136,5 @@ alias boostdoc ;
explicit boostdoc ;
alias boostrelease :
standalone_base_from_member standalone_compressed_pair
standalone_declval standalone_string_ref ;
standalone_declval standalone_ostream_string standalone_string_ref ;
explicit boostrelease ;

78
doc/ostream_string.qbk Normal file
View File

@@ -0,0 +1,78 @@
[/
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)
]
[article ostream_string
[quickbook 1.5]
[authors [Fernandes, Glen]]
[copyright 2019 Glen Joseph Fernandes]
[license Distributed under the Boost Software License, Version 1.0.]]
[section Overview]
The header <boost/utility/ostream_string.hpp> provides the function template
`boost::ostream_string` for formatted output that satisfies the requirements of
\[ostream.formatted.reqmts\].
[endsect]
[section Examples]
The inserter for class template `basic_string_view` could be implemented as
follows:
```
template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const basic_string_view<charT, traits>& str)
{
return boost::ostream_string(os, str.data(), str.size());
}
```
[endsect]
[section Reference]
```
namespace boost {
template<class charT, class traits>
std::basic_ostream<charT, traits>&
ostream_string(std::basic_ostream<charT, traits>& os,
const charT* data, std::size_t size);
} /* boost */
```
[heading Free functions]
[variablelist
[[`template<class charT, class traits> std::basic_ostream<charT, traits>&
ostream_string(std::basic_ostream<charT, traits>& os, const charT* data,
std::size_t size);`]
[[variablelist
[[Effects]
[Behaves like a formatted inserter (as described in
\[ostream.formatted.reqmts\]) of `os`. Creates a character sequence `seq` of
`size` characters starting at `data`, each widened using `os.widen()`
(\[basic.ios.members\]). Determines padding for `seq` as described in
\[ostream.formatted.reqmts\]. Inserts `seq` into `os`. Calls `width(0)`.]]
[[Returns][`os`.]]]]]]
[endsect]
[section History]
[heading boost 1.71]
* Glen Fernandes updated the implementation of the `basic_string_ref` and
`basic_string_view` stream insertion operators to write directly to the
`basic_streambuf` and refactored that functionality into this common utility.
[endsect]

View File

@@ -156,6 +156,11 @@ String-like operations:
[section History]
[/===============]
[heading boost 1.71]
* Glen Fernandes updated the implementation of the stream insertion operator to
write directly to the `basic_streambuf` and refactored that functionality into
a common utility.
[heading boost 1.53]
* Introduced

View File

@@ -0,0 +1,95 @@
/*
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 <boost/config.hpp>
#include <iosfwd>
#include <cstddef>
namespace boost {
namespace detail {
template<class charT, class traits>
inline std::size_t
oss_put(std::basic_ostream<charT, traits>& os, const charT* data,
std::size_t size)
{
return static_cast<std::size_t>(os.rdbuf()->sputn(data, size));
}
template<class charT, class traits>
inline bool
oss_fill(std::basic_ostream<charT, traits>& 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 charT, class traits>
class oss_guard {
public:
explicit oss_guard(std::basic_ostream<charT, traits>& os) BOOST_NOEXCEPT
: os_(&os) { }
~oss_guard() BOOST_NOEXCEPT_IF(false) {
if (os_) {
os_->setstate(std::basic_ostream<charT, traits>::badbit);
}
}
void release() BOOST_NOEXCEPT {
os_ = 0;
}
private:
oss_guard(const oss_guard&);
oss_guard& operator=(const oss_guard&);
std::basic_ostream<charT, traits>* os_;
};
} /* detail */
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
ostream_string(std::basic_ostream<charT, traits>& os, const charT* data,
std::size_t size)
{
typedef std::basic_ostream<charT, traits> stream;
detail::oss_guard<charT, traits> guard(os);
typename stream::sentry entry(os);
if (entry) {
std::size_t width = static_cast<std::size_t>(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

View File

@@ -1,5 +1,6 @@
/*
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
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,6 +18,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/ostream_string.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/throw_exception.hpp>
@@ -421,52 +423,11 @@ namespace boost {
return basic_string_ref<charT, traits>(x) >= y;
}
namespace detail {
template<class charT, class traits>
inline void sr_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
enum { chunk_size = 8 };
charT fill_chars[chunk_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>
void sr_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
const std::size_t size = str.size();
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
if (!align_left) {
detail::sr_insert_fill_chars(os, alignment_size);
if (os.good())
os.write(str.data(), size);
}
else {
os.write(str.data(), size);
if (os.good())
detail::sr_insert_fill_chars(os, alignment_size);
}
}
} // namespace detail
// Inserter
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
if (os.good()) {
const std::size_t size = str.size();
const std::size_t w = static_cast< std::size_t >(os.width());
if (w <= size)
os.write(str.data(), size);
else
detail::sr_insert_aligned(os, str);
os.width(0);
}
return os;
return boost::ostream_string(os, str.data(), str.size());
}
#if 0

View File

@@ -1,6 +1,7 @@
/*
Copyright (c) Marshall Clow 2012-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
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -19,6 +20,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/ostream_string.hpp>
#include <boost/utility/string_view_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <boost/container_hash/hash_fwd.hpp>
@@ -184,7 +186,7 @@ namespace boost {
if (pos > size())
BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
size_type rlen = (std::min)(n, len_ - pos);
traits_type::copy(s, data() + pos, rlen);
traits_type::copy(s, data() + pos, rlen);
return rlen;
}
@@ -571,53 +573,12 @@ namespace boost {
return basic_string_view<charT, traits>(x) >= y;
}
namespace detail {
template<class charT, class traits>
inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
enum { chunk_size = 8 };
charT fill_chars[chunk_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>
void sv_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
const std::size_t size = str.size();
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
if (!align_left) {
detail::sv_insert_fill_chars(os, alignment_size);
if (os.good())
os.write(str.data(), size);
}
else {
os.write(str.data(), size);
if (os.good())
detail::sv_insert_fill_chars(os, alignment_size);
}
}
} // namespace detail
// Inserter
template<class charT, class traits>
inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os,
const basic_string_view<charT,traits>& str) {
if (os.good()) {
const std::size_t size = str.size();
const std::size_t w = static_cast< std::size_t >(os.width());
if (w <= size)
os.write(str.data(), size);
else
detail::sv_insert_aligned(os, str);
os.width(0);
}
return os;
return boost::ostream_string(os, str.data(), str.size());
}
#if 0

View File

@@ -31,6 +31,7 @@
<a href="utility.htm#result_of">result_of</a><br>
<a href="throw_exception.html">throw_exception</a><br>
<a href="utility.htm">utility</a><br>
<a href="doc/html/ostream_string.html">ostream_string</a><br>
<a href="doc/html/string_ref.html">string_ref</a><br>
<a href="value_init.htm">value_init</a><br>
</p>

View File

@@ -85,6 +85,19 @@
"Daniel Frey <d.frey -at- gmx.de>"
]
},
{
"key": "utility/ostream_string",
"name": "ostream_string",
"description": "String formatted output function.",
"documentation": "doc/html/ostream_string.html",
"category": [
"IO"
],
"authors": "Glen Fernandes",
"maintainers": [
"Glen Fernandes <glenjofe -at- gmail.com>"
]
},
{
"key": "utility/result_of",
"name": "Result Of",
@@ -98,6 +111,19 @@
"Daniel Walker <daniel.j.walker -at- gmail.com>"
]
},
{
"key": "utility/string_ref",
"name": "string_ref",
"description": "String view templates.",
"documentation": "doc/html/string_ref.html",
"category": [
"Containers"
],
"authors": "Marshall Clow",
"maintainers": [
"Marshall Clow <marshall -at- idio.com>"
]
},
{
"key": "utility/value_initialized",
"name": "Value Initialized",

View File

@@ -119,8 +119,8 @@
also want <code>x &gt; y, x &gt;= y,</code> and <code>x &lt;= y</code>.
Moreover, unless your class has really surprising behavior, some of these
related operators can be defined in terms of others (e.g. <code>x &gt;= y
&lt;=&gt; !(x &lt; y)</code>). Replicating this boilerplate for multiple
classes is both tedious and error-prone. The <cite><a href=
is equivalent to !(x &lt; y)</code>). Replicating this boilerplate for
multiple classes is both tedious and error-prone. The <cite><a href=
"../../boost/operators.hpp">boost/operators.hpp</a></cite> templates help
by generating operators for you at namespace scope based on other
operators you've defined in your class.</p>

View File

@@ -42,3 +42,5 @@ compile-fail value_init_test_fail2.cpp ;
compile-fail value_init_test_fail3.cpp ;
compile-fail initialized_test_fail1.cpp ;
compile-fail initialized_test_fail2.cpp ;
run ostream_string_test.cpp ;

View File

@@ -0,0 +1,136 @@
/*
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)
*/
#include <boost/core/lightweight_test.hpp>
#include <boost/utility/ostream_string.hpp>
#include <sstream>
#include <string>
int main()
{
{
std::ostringstream os;
os.width(1);
os.fill('.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "xy");
}
{
std::wostringstream os;
os.width(1);
os.fill('.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"xy");
}
{
std::ostringstream os;
os.width(1);
os.fill('.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "xy");
}
{
std::wostringstream os;
os.width(1);
os.fill('.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"xy");
}
{
std::ostringstream os;
os.width(4);
os.fill('.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "xy..");
}
{
std::wostringstream os;
os.width(4);
os.fill(L'.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"xy..");
}
{
std::ostringstream os;
os.width(4);
os.fill('.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "..xy");
}
{
std::wostringstream os;
os.width(4);
os.fill(L'.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"..xy");
}
{
std::ostringstream os;
os.width(12);
os.fill('.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "xy..........");
}
{
std::wostringstream os;
os.width(12);
os.fill(L'.');
os.setf(std::ios_base::left, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"xy..........");
}
{
std::ostringstream os;
os.width(12);
os.fill('.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, "xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == "..........xy");
}
{
std::wostringstream os;
os.width(12);
os.fill(L'.');
os.setf(std::ios_base::right, std::ios_base::adjustfield);
boost::ostream_string(os, L"xy", 2);
BOOST_TEST(os.good());
BOOST_TEST(os.width() == 0);
BOOST_TEST(os.str() == L"..........xy");
}
return boost::report_errors();
}