mirror of
https://github.com/boostorg/io.git
synced 2025-07-29 11:57:14 +02:00
Compare commits
73 Commits
boost-1.64
...
master
Author | SHA1 | Date | |
---|---|---|---|
932dd48026 | |||
c68387509b | |||
065d371e17 | |||
0a0241dc9d | |||
7392d7274c | |||
10e478b071 | |||
0bd6c01164 | |||
3f8663f816 | |||
9ee00a8561 | |||
12ba3e8b46 | |||
8f9e13383d | |||
182290cf76 | |||
70945e76cd | |||
40b87939b2 | |||
cfe2e98267 | |||
60714a762d | |||
d2f4b71726 | |||
f62be9ea03 | |||
ab699e251f | |||
c8ce84089b | |||
9f8765e752 | |||
da05aefb48 | |||
c4a0fdd280 | |||
6bda141f23 | |||
5fd7b50697 | |||
8c95266ebc | |||
0b7828f310 | |||
7aa7d9a395 | |||
aa70414fde | |||
8f77d9cace | |||
37e03f2135 | |||
5d4c217fbe | |||
6dd527bf78 | |||
21b20f4a9e | |||
b1d5fbd27f | |||
afa8fbd744 | |||
cbe0f72c08 | |||
980cebe39e | |||
c761bbc285 | |||
c07058003c | |||
00b2270c66 | |||
daf69d8864 | |||
fc28ee1c44 | |||
661bb71ff3 | |||
7ac562b408 | |||
e276f63390 | |||
5c499073c1 | |||
f0b3cf1323 | |||
16913b5484 | |||
74db4d9a58 | |||
76ee346773 | |||
f47bf89c19 | |||
dd40a6cae4 | |||
4fa5ded263 | |||
2dc89e1eee | |||
41bafc2908 | |||
a6b31015c6 | |||
ec89e7ad9f | |||
ba7a6bef42 | |||
a66dac2ccc | |||
c0febbb420 | |||
69560d45d2 | |||
4255fe9abe | |||
3a643e558d | |||
cc27047270 | |||
fbceb17be3 | |||
20f343cc03 | |||
d206a7b5ed | |||
5fa66f1f76 | |||
560bbb84e3 | |||
8b6eca07ed | |||
c63b43c9d8 | |||
0c4a3d4ee9 |
61
.appveyor.yml
Normal file
61
.appveyor.yml
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright 2019 Glen Fernandes
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
version: 1.0.{build}-{branch}
|
||||
|
||||
shallow_clone: true
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-9.0
|
||||
ADDRMD: 32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-10.0
|
||||
ADDRMD: 32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-11.0
|
||||
ADDRMD: 32
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-12.0
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
TOOLSET: msvc-14.0
|
||||
ADDRMD: 32,64
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: msvc-14.1
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
TOOLSET: clang-win
|
||||
ADDRMD: 32,64
|
||||
CXXSTD: 14,17
|
||||
|
||||
install:
|
||||
- set BOOST_BRANCH=develop
|
||||
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||
- cd ..
|
||||
- git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost
|
||||
- cd boost
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/core
|
||||
- git submodule init libs/headers
|
||||
- git submodule init tools/build
|
||||
- git submodule init tools/boost_install
|
||||
- git submodule update
|
||||
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\io\
|
||||
- cmd /c bootstrap
|
||||
- b2 headers
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||
- if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD%
|
||||
- b2 libs/io/test toolset=%TOOLSET% %CXXSTD% %ADDRMD%
|
96
.gitattributes
vendored
96
.gitattributes
vendored
@ -1,96 +0,0 @@
|
||||
* text=auto !eol svneol=native#text/plain
|
||||
*.gitattributes text svneol=native#text/plain
|
||||
|
||||
# Scriptish formats
|
||||
*.bat text svneol=native#text/plain
|
||||
*.bsh text svneol=native#text/x-beanshell
|
||||
*.cgi text svneol=native#text/plain
|
||||
*.cmd text svneol=native#text/plain
|
||||
*.js text svneol=native#text/javascript
|
||||
*.php text svneol=native#text/x-php
|
||||
*.pl text svneol=native#text/x-perl
|
||||
*.pm text svneol=native#text/x-perl
|
||||
*.py text svneol=native#text/x-python
|
||||
*.sh eol=lf svneol=LF#text/x-sh
|
||||
configure eol=lf svneol=LF#text/x-sh
|
||||
|
||||
# Image formats
|
||||
*.bmp binary svneol=unset#image/bmp
|
||||
*.gif binary svneol=unset#image/gif
|
||||
*.ico binary svneol=unset#image/ico
|
||||
*.jpeg binary svneol=unset#image/jpeg
|
||||
*.jpg binary svneol=unset#image/jpeg
|
||||
*.png binary svneol=unset#image/png
|
||||
*.tif binary svneol=unset#image/tiff
|
||||
*.tiff binary svneol=unset#image/tiff
|
||||
*.svg text svneol=native#image/svg%2Bxml
|
||||
|
||||
# Data formats
|
||||
*.pdf binary svneol=unset#application/pdf
|
||||
*.avi binary svneol=unset#video/avi
|
||||
*.doc binary svneol=unset#application/msword
|
||||
*.dsp text svneol=crlf#text/plain
|
||||
*.dsw text svneol=crlf#text/plain
|
||||
*.eps binary svneol=unset#application/postscript
|
||||
*.gz binary svneol=unset#application/gzip
|
||||
*.mov binary svneol=unset#video/quicktime
|
||||
*.mp3 binary svneol=unset#audio/mpeg
|
||||
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
|
||||
*.ps binary svneol=unset#application/postscript
|
||||
*.psd binary svneol=unset#application/photoshop
|
||||
*.rdf binary svneol=unset#text/rdf
|
||||
*.rss text svneol=unset#text/xml
|
||||
*.rtf binary svneol=unset#text/rtf
|
||||
*.sln text svneol=native#text/plain
|
||||
*.swf binary svneol=unset#application/x-shockwave-flash
|
||||
*.tgz binary svneol=unset#application/gzip
|
||||
*.vcproj text svneol=native#text/xml
|
||||
*.vcxproj text svneol=native#text/xml
|
||||
*.vsprops text svneol=native#text/xml
|
||||
*.wav binary svneol=unset#audio/wav
|
||||
*.xls binary svneol=unset#application/vnd.ms-excel
|
||||
*.zip binary svneol=unset#application/zip
|
||||
|
||||
# Text formats
|
||||
.htaccess text svneol=native#text/plain
|
||||
*.bbk text svneol=native#text/xml
|
||||
*.cmake text svneol=native#text/plain
|
||||
*.css text svneol=native#text/css
|
||||
*.dtd text svneol=native#text/xml
|
||||
*.htm text svneol=native#text/html
|
||||
*.html text svneol=native#text/html
|
||||
*.ini text svneol=native#text/plain
|
||||
*.log text svneol=native#text/plain
|
||||
*.mak text svneol=native#text/plain
|
||||
*.qbk text svneol=native#text/plain
|
||||
*.rst text svneol=native#text/plain
|
||||
*.sql text svneol=native#text/x-sql
|
||||
*.txt text svneol=native#text/plain
|
||||
*.xhtml text svneol=native#text/xhtml%2Bxml
|
||||
*.xml text svneol=native#text/xml
|
||||
*.xsd text svneol=native#text/xml
|
||||
*.xsl text svneol=native#text/xml
|
||||
*.xslt text svneol=native#text/xml
|
||||
*.xul text svneol=native#text/xul
|
||||
*.yml text svneol=native#text/plain
|
||||
boost-no-inspect text svneol=native#text/plain
|
||||
CHANGES text svneol=native#text/plain
|
||||
COPYING text svneol=native#text/plain
|
||||
INSTALL text svneol=native#text/plain
|
||||
Jamfile text svneol=native#text/plain
|
||||
Jamroot text svneol=native#text/plain
|
||||
Jamfile.v2 text svneol=native#text/plain
|
||||
Jamrules text svneol=native#text/plain
|
||||
Makefile* text svneol=native#text/plain
|
||||
README text svneol=native#text/plain
|
||||
TODO text svneol=native#text/plain
|
||||
|
||||
# Code formats
|
||||
*.c text svneol=native#text/plain
|
||||
*.cpp text svneol=native#text/plain
|
||||
*.h text svneol=native#text/plain
|
||||
*.hpp text svneol=native#text/plain
|
||||
*.ipp text svneol=native#text/plain
|
||||
*.tpp text svneol=native#text/plain
|
||||
*.jam text svneol=native#text/plain
|
||||
*.java text svneol=native#text/plain
|
184
.github/workflows/ci.yml
vendored
Normal file
184
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
posix:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: gcc-4.8
|
||||
standard: "03,11"
|
||||
os: ubuntu-18.04
|
||||
install: g++-4.8
|
||||
- toolset: gcc-5
|
||||
standard: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-5
|
||||
- toolset: gcc-6
|
||||
standard: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: g++-6
|
||||
- toolset: gcc-7
|
||||
standard: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
- toolset: gcc-8
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
install: g++-8
|
||||
- toolset: gcc-9
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-18.04
|
||||
- toolset: gcc-10
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-10
|
||||
- toolset: gcc-11
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: g++-11
|
||||
- toolset: clang
|
||||
compiler: clang++-3.9
|
||||
standard: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-3.9
|
||||
- toolset: clang
|
||||
compiler: clang++-4.0
|
||||
standard: "03,11,14"
|
||||
os: ubuntu-18.04
|
||||
install: clang-4.0
|
||||
- toolset: clang
|
||||
compiler: clang++-5.0
|
||||
standard: "03,11,14,1z"
|
||||
os: ubuntu-18.04
|
||||
install: clang-5.0
|
||||
- toolset: clang
|
||||
compiler: clang++-6.0
|
||||
standard: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-6.0
|
||||
- toolset: clang
|
||||
compiler: clang++-7
|
||||
standard: "03,11,14,17"
|
||||
os: ubuntu-18.04
|
||||
install: clang-7
|
||||
- toolset: clang
|
||||
compiler: clang++-8
|
||||
standard: "03,11,14,17"
|
||||
os: ubuntu-20.04
|
||||
install: clang-8
|
||||
- toolset: clang
|
||||
compiler: clang++-9
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-9
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
standard: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-10
|
||||
- toolset: clang
|
||||
compiler: clang++-11
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-11
|
||||
- toolset: clang
|
||||
compiler: clang++-12
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.04
|
||||
install: clang-12
|
||||
- toolset: clang
|
||||
standard: "03,11,14,17,2a"
|
||||
os: macos-10.15
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install packages
|
||||
if: matrix.install
|
||||
run: sudo apt install ${{matrix.install}}
|
||||
|
||||
- name: Setup Boost
|
||||
run: |
|
||||
cd ..
|
||||
git clone --depth 1 https://github.com/boostorg/boost
|
||||
cd boost
|
||||
cp -r $GITHUB_WORKSPACE/* libs/io
|
||||
git submodule init libs/assert
|
||||
git submodule init libs/config
|
||||
git submodule init libs/core
|
||||
git submodule init libs/headers
|
||||
git submodule init tools/build
|
||||
git submodule init tools/boost_install
|
||||
git submodule update
|
||||
./bootstrap.sh
|
||||
./b2 -d0 headers
|
||||
|
||||
- name: Create user-config.jam
|
||||
if: matrix.compiler
|
||||
run: |
|
||||
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cd ../boost
|
||||
./b2 -j3 libs/io/test toolset=${{matrix.toolset}} cxxstd=${{matrix.standard}} variant=debug,release
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- toolset: msvc-14.1
|
||||
standard: "14,17,latest"
|
||||
target: 32,64
|
||||
os: windows-2016
|
||||
- toolset: msvc-14.2
|
||||
standard: "14,17,latest"
|
||||
target: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.3
|
||||
cxxstd: "14,17,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
standard: "03,11,14,17,2a"
|
||||
target: 64
|
||||
os: windows-2019
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Boost
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ..
|
||||
git clone --depth 1 https://github.com/boostorg/boost boost
|
||||
cd boost
|
||||
xcopy /s /e /q %GITHUB_WORKSPACE% libs\io\
|
||||
git submodule init libs/assert
|
||||
git submodule init libs/config
|
||||
git submodule init libs/core
|
||||
git submodule init libs/static_assert
|
||||
git submodule init libs/headers
|
||||
git submodule init tools/build
|
||||
git submodule init tools/boost_install
|
||||
git submodule update
|
||||
cmd /c bootstrap
|
||||
b2 -d0 headers
|
||||
|
||||
- name: Run tests
|
||||
shell: cmd
|
||||
run: |
|
||||
cd ../boost
|
||||
b2 -j3 libs/io/test toolset=${{matrix.toolset}} cxxstd=${{matrix.standard}} address-model=${{matrix.target}} variant=debug,release
|
301
.travis.yml
Normal file
301
.travis.yml
Normal file
@ -0,0 +1,301 @@
|
||||
# Copyright 2017 Edward Diener
|
||||
# Copyright 2019 Glen Fernandes
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
language: cpp
|
||||
|
||||
sudo: false
|
||||
|
||||
dist: trusty
|
||||
|
||||
python: "2.7"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- BOGUS_JOB=true
|
||||
|
||||
matrix:
|
||||
|
||||
exclude:
|
||||
- env: BOGUS_JOB=true
|
||||
|
||||
include:
|
||||
- os: linux
|
||||
compiler: g++
|
||||
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
|
||||
|
||||
- os: linux
|
||||
compiler: g++-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.6
|
||||
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.7
|
||||
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.8
|
||||
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-4.9
|
||||
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-4.9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-5
|
||||
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-5
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-6
|
||||
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-7
|
||||
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-8
|
||||
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: g++-9
|
||||
env: TOOLSET=gcc COMPILER=g++-9 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- g++-9
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
|
||||
- os: linux
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
|
||||
|
||||
- os: linux
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.3
|
||||
|
||||
- os: linux
|
||||
compiler: /usr/bin/clang++
|
||||
env: TOOLSET=clang COMPILER=/usr/bin/clang++ CXXSTD=03,11
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.4
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.5
|
||||
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.5
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.5
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.6
|
||||
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.6
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.6
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.7
|
||||
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.8
|
||||
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.8
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.8
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-3.9
|
||||
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-3.9
|
||||
- libstdc++-4.9-dev
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-precise-3.9
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-4.0
|
||||
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-4.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-4.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-5.0
|
||||
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-5.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-5.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-6.0
|
||||
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-6.0
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-6.0
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-7
|
||||
env: TOOLSET=clang COMPILER=clang++-7 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-7
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-7
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-8
|
||||
env: TOOLSET=clang COMPILER=clang++-8 CXXSTD=03,11,14,17,2a
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-8
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-8
|
||||
|
||||
- os: linux
|
||||
compiler: clang++-libc++
|
||||
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libc++-dev
|
||||
|
||||
- os: osx
|
||||
compiler: clang++
|
||||
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
|
||||
|
||||
install:
|
||||
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
|
||||
- cd ..
|
||||
- git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost
|
||||
- cd boost
|
||||
- git submodule init libs/assert
|
||||
- git submodule init libs/config
|
||||
- git submodule init libs/core
|
||||
- git submodule init libs/headers
|
||||
- git submodule init tools/build
|
||||
- git submodule init tools/boost_install
|
||||
- git submodule update
|
||||
- mkdir -p libs/io
|
||||
- cp -r $TRAVIS_BUILD_DIR/* libs/io
|
||||
- ./bootstrap.sh
|
||||
- ./b2 headers
|
||||
|
||||
script:
|
||||
- |-
|
||||
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||
- ./b2 libs/io/test toolset=$TOOLSET cxxstd=$CXXSTD
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_success: always
|
17
CMakeLists.txt
Normal file
17
CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright 2018 Mike Dev
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...3.20)
|
||||
|
||||
project(boost_io VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_io INTERFACE)
|
||||
add_library(Boost::io ALIAS boost_io)
|
||||
|
||||
target_include_directories(boost_io INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_io
|
||||
INTERFACE
|
||||
Boost::config
|
||||
)
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Boost.IO
|
||||
|
||||
The Boost IO C++ library provides utilities for dealing with the C++ standard
|
||||
library IO streams.
|
||||
|
||||
### License
|
||||
|
||||
Distributed under the
|
||||
[Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
|
23
doc/Jamfile
Normal file
23
doc/Jamfile
Normal file
@ -0,0 +1,23 @@
|
||||
# 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)
|
||||
|
||||
import asciidoctor ;
|
||||
|
||||
html io.html : io.adoc ;
|
||||
|
||||
install html_ : io.html : <location>html ;
|
||||
|
||||
pdf io.pdf : io.adoc ;
|
||||
explicit io.pdf ;
|
||||
|
||||
install pdf_ : io.pdf : <location>pdf ;
|
||||
explicit pdf_ ;
|
||||
|
||||
alias boostdoc ;
|
||||
explicit boostdoc ;
|
||||
|
||||
alias boostrelease : html_ ;
|
||||
explicit boostrelease ;
|
@ -1,67 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Boost I/O Library</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="white" text="black">
|
||||
<table border="1" bgcolor="teal" cellpadding="2">
|
||||
<tr>
|
||||
<td bgcolor="white"><img src="../../../boost.png"
|
||||
alt="boost.png (6897 bytes)" width="277"
|
||||
height="86"></td>
|
||||
<td><a href="../../../index.htm"><font face="Arial"
|
||||
color="white"><big>Home</big></font></a></td>
|
||||
<td><a href="../../libraries.htm"><font face="Arial"
|
||||
color="white"><big>Libraries</big></font></a></td>
|
||||
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial"
|
||||
color="white"><big>People</big></font></a></td>
|
||||
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial"
|
||||
color="white"><big>FAQ</big></font></a></td>
|
||||
<td><a href="../../../more/index.htm"><font face="Arial"
|
||||
color="white"><big>More</big></font></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h1>Boost Input/Output Library</h1>
|
||||
|
||||
<table border="1" cellpadding="5" align="center">
|
||||
<tr>
|
||||
<th>Header / Docs</th>
|
||||
<th>Contents</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<code><a href="../../../boost/io_fwd.hpp"><boost/io_fwd.hpp></a></code>
|
||||
</td>
|
||||
<td valign="top">
|
||||
Forward declaration header.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<code><a href="../../../boost/io/ios_state.hpp"><boost/io/ios_state.hpp></a></code><br>
|
||||
<br><a href="ios_state.html">documentation</a>
|
||||
</td>
|
||||
<td valign="top">
|
||||
State-saving classes for various IOStream attributes.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Rationale</h2>
|
||||
|
||||
<p>The I/O sub-library of Boost helps segregate the large number of
|
||||
Boost headers. This sub-library should contain various items to use
|
||||
with/for the standard I/O library.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised: 26 Feb 2002</p>
|
||||
|
||||
<p>Copyright 2002 Daryle Walker. Use, modification, and distribution are
|
||||
subject to the Boost Software License, Version 1.0. (See accompanying file <a
|
||||
href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a
|
||||
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||
</body>
|
||||
</html>
|
5
doc/io-docinfo-footer.html
Normal file
5
doc/io-docinfo-footer.html
Normal file
@ -0,0 +1,5 @@
|
||||
<style>
|
||||
.specification {
|
||||
margin-left: 2em;
|
||||
}
|
||||
</style>
|
39
doc/io.adoc
Normal file
39
doc/io.adoc
Normal file
@ -0,0 +1,39 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Boost.IO
|
||||
Daryle Walker, Beman Dawes, Glen Joseph Fernandes <glenjofe@gmail.com>
|
||||
:docinfo: private-footer
|
||||
:idprefix:
|
||||
:source-language: cpp
|
||||
:toc: left
|
||||
|
||||
This library contains various utilities for the standard I/O library.
|
||||
|
||||
:leveloffset: +1
|
||||
|
||||
include::ios_state.adoc[]
|
||||
|
||||
include::quoted.adoc[]
|
||||
|
||||
include::ostream_joiner.adoc[]
|
||||
|
||||
include::ostream_put.adoc[]
|
||||
|
||||
include::nullstream.adoc[]
|
||||
|
||||
:leveloffset: -1
|
||||
|
||||
## Copyright and License
|
||||
|
||||
* Copyright 2002 Daryle Walker
|
||||
* Copyright 2002, 2006, 2007, 2009, 2010 Beman Dawes
|
||||
* Copyright 2019 Glen Joseph Fernandes
|
||||
|
||||
Distributed under the
|
||||
http://www.boost.org/LICENSE_1_0.txt[Boost Software License, Version 1.0].
|
322
doc/ios_state.adoc
Normal file
322
doc/ios_state.adoc
Normal file
@ -0,0 +1,322 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# IO State Savers, <boost/io/ios_state.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/ios_state.hpp>` covers saving the stream state of objects
|
||||
in the {cpp} IOStreams system.
|
||||
|
||||
## Rationale
|
||||
|
||||
Sometimes a certain value has to change only for a limited scope. Saver classes
|
||||
save a copy of the current state of some object (or an aspect of an object),
|
||||
and reset the object's state at destruction time, undoing any change the object
|
||||
may have gone through.
|
||||
|
||||
The saver class strategy is helpful when using I/O stream objects. Manipulator
|
||||
objects can change some aspect of a stream during input or output. The state
|
||||
changed by the manipulator usually sticks to its new value after the I/O
|
||||
transaction. This can be a problem if manipulators are used in a function that
|
||||
is not supposed to externally change a stream's state.
|
||||
|
||||
```
|
||||
#include <ostream>
|
||||
#include <ios>
|
||||
|
||||
void hex_my_byte(std::ostream& os, char byte)
|
||||
{
|
||||
os << std::hex << static_cast<unsigned>(byte);
|
||||
}
|
||||
```
|
||||
|
||||
The `os` stream will retain its new hexadecimal printing mode after the call to
|
||||
`hex_my_byte`. The stream's printing mode can be saved and restored with manual
|
||||
calls to the stream's state inspecting and mutating member functions. The
|
||||
manual method becomes unwieldy if the main functionality is complex and/or
|
||||
needs to be exception safe. A saver class can implement the better
|
||||
"resource acquisition is initialization" strategy.
|
||||
|
||||
See the example below for better code, using saver classes.
|
||||
|
||||
## Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
class ios_flags_saver;
|
||||
class ios_precision_saver;
|
||||
class ios_width_saver;
|
||||
class ios_base_all_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_iostate_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_exception_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_tie_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_rdbuf_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_fill_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_locale_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_all_saver;
|
||||
|
||||
typedef basic_ios_iostate_saver<char> ios_iostate_saver;
|
||||
typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
|
||||
typedef basic_ios_exception_saver<char> ios_exception_saver;
|
||||
typedef basic_ios_exception_saver<wchar_t> wios_exception_saver;
|
||||
typedef basic_ios_tie_saver<char> ios_tie_saver;
|
||||
typedef basic_ios_tie_saver<wchar_t> wios_tie_saver;
|
||||
typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
|
||||
typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
|
||||
typedef basic_ios_fill_saver<char> ios_fill_saver;
|
||||
typedef basic_ios_fill_saver<wchar_t> wios_fill_saver;
|
||||
typedef basic_ios_locale_saver<char> ios_locale_saver;
|
||||
typedef basic_ios_locale_saver<wchar_t> wios_locale_saver;
|
||||
typedef basic_ios_all_saver<char> ios_all_saver;
|
||||
typedef basic_ios_all_saver<wchar_t> wios_all_saver;
|
||||
|
||||
class ios_iword_saver;
|
||||
class ios_pword_saver;
|
||||
class ios_all_word_saver;
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
## Savers for Basic Standard Attributes
|
||||
|
||||
The basic saver classes have this format:
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
class saver {
|
||||
public:
|
||||
typedef std::ios_base state_type;
|
||||
typedef `implementation_defined` aspect_type;
|
||||
|
||||
explicit saver(state_type& s);
|
||||
saver(state_type& s, const aspect_type& new_value);
|
||||
~saver();
|
||||
|
||||
void restore();
|
||||
};
|
||||
```
|
||||
|
||||
The `state_type` is the IOStreams base class `std::ios_base`. The user would
|
||||
usually place an actual input, output, or combined stream object for the
|
||||
state-type parameter, and not a base class object. The first constructor takes
|
||||
a stream object and saves a reference to the stream and the current value of a
|
||||
particular stream attribute. The second constructor works like the first, and
|
||||
uses its second argument to change the stream's attribute to the new
|
||||
`aspect_type` value given. The destructor restores the stream's attribute to
|
||||
the saved value. The restoration can be activated early (and often) with the
|
||||
`restore` member function.
|
||||
|
||||
.Basic IOStreams State Saver Classes
|
||||
[%header,cols=5*]
|
||||
|===
|
||||
|Class |Saved Attribute |Attribute Type |Reading Method |Writing Method
|
||||
|`ios_flags_saver`
|
||||
|Format control flags
|
||||
|`std::ios_base::fmtflags`
|
||||
|`flags`
|
||||
|`flags`
|
||||
|`ios_precision_saver`
|
||||
|Number of digits to print after decimal point
|
||||
|`std::streamsize`
|
||||
|`precision`
|
||||
|`precision`
|
||||
|`ios_width_saver`
|
||||
|Minimum field width for printing objects
|
||||
|`std::streamsize`
|
||||
|`width`
|
||||
|`width`
|
||||
|===
|
||||
|
||||
## Savers for Advanced Standard Attributes
|
||||
|
||||
The saver class templates have this format:
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
template<class Ch, class Tr>
|
||||
class saver {
|
||||
public:
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef `implementation-defined` aspect_type;
|
||||
|
||||
explicit saver(state_type& s);
|
||||
saver(state_type& s, const aspect_type& new_value);
|
||||
~saver();
|
||||
|
||||
void restore();
|
||||
};
|
||||
```
|
||||
|
||||
The `state_type` is a version of the IOStreams base class template
|
||||
`std::basic_ios<Ch, Tr>`, where `Ch` is a character type and `Tr` is a
|
||||
character traits class. The user would usually place an actual input,
|
||||
output, or combined stream object for the state-type parameter, and not a base
|
||||
class object. The first constructor takes a stream object and saves a reference
|
||||
to the stream and the current value of a particular stream attribute. The
|
||||
second constructor works like the first, and uses its second argument to change
|
||||
the stream's attribute to the new `aspect_type` value given. The destructor
|
||||
restores the stream's attribute to the saved value. The restoration can be
|
||||
activated early (and often) with the `restore` member function.
|
||||
|
||||
.Advanced IOStreams State Saver Class Templates
|
||||
[%header,cols=5*]
|
||||
|===
|
||||
|Class |Saved Attribute |Attribute Type |Reading Method |Writing Method
|
||||
|`basic_ios_iostate_saver<Ch, Tr>`
|
||||
|Failure state of the stream [1], [2]
|
||||
|`std::ios_base::iostate`
|
||||
|`rdstate`
|
||||
|`clear`
|
||||
|`basic_ios_exception_saver<Ch, Tr>`
|
||||
|Which failure states trigger an exception [1]
|
||||
|`std::ios_base::iostate`
|
||||
|`exceptions`
|
||||
|`exceptions`
|
||||
|`basic_ios_tie_saver<Ch, Tr>`
|
||||
|Output stream synchronized with the stream
|
||||
|`std::basic_ostream<Ch, Tr>*`
|
||||
|`tie`
|
||||
|`tie`
|
||||
|`basic_ios_rdbuf_saver<Ch, Tr>`
|
||||
|Stream buffer associated with the stream [2]
|
||||
|`std::basic_streambuf<Ch, Tr>*`
|
||||
|`rdbuf`
|
||||
|`rdbuf`
|
||||
|`basic_ios_fill_saver<Ch, Tr>`
|
||||
|Character used to pad oversized field widths
|
||||
|`Ch`
|
||||
|`fill`
|
||||
|`fill`
|
||||
|`basic_ios_locale_saver<Ch, Tr>`
|
||||
|Locale information associated with the stream [3]
|
||||
|`std::locale`
|
||||
|`getloc` (from `std::ios_base`)
|
||||
|`imbue` (from `std::basic_ios<Ch, Tr>`)
|
||||
|===
|
||||
|
||||
### Notes
|
||||
|
||||
1. When the failure state flags and/or the failure state exception watching
|
||||
flags are changed, an exception is thrown if a match occurs among the two sets
|
||||
of flags. This could mean that the constructor or destructor of these class
|
||||
templates may throw.
|
||||
2. When the associated stream buffer is changed, the stream's failure state set
|
||||
is reset to "good" if the given stream buffer's address is non-NULL, but the
|
||||
"bad" failure state is set if that address is NULL. This means that a saved
|
||||
failure state of "good" may be restored as "bad" if the stream is stripped of
|
||||
an associated stream buffer. Worse, given a NULL stream buffer address, an
|
||||
exception is thrown if the "bad" failure state is being watched. This could
|
||||
mean that the constructor or destructor of these class templates may throw.
|
||||
3. The saver for the locale uses the `std::basic_ios<Ch, Tr>` class to extract
|
||||
their information, although it could have used the functionality in
|
||||
`std::ios_base`. The problem is that the versions of the needed member
|
||||
functions in `ios_base` are not polymorphically related to the ones in
|
||||
`basic_ios`. The stream classes that will be used with the saver classes should
|
||||
use the versions of the member functions closest to them by inheritance, which
|
||||
means the ones in `basic_ios`.
|
||||
|
||||
## Savers for User-Defined Attributes
|
||||
|
||||
There are three class (templates) for combined attribute savers. The
|
||||
`ios_base_all_saver` saver class combines the functionality of all the basic
|
||||
attribute saver classes. It has a constructor that takes the stream to have its
|
||||
state preserved. The `basic_ios_all_saver` combines the functionality of all
|
||||
the advanced attribute saver class templates and the combined basic attribute
|
||||
saver class. It has a constructor that takes the stream to have its state
|
||||
preserved. The `ios_all_word_saver` saver class combines the saver classes that
|
||||
preserve user-defined formatting information. Its constructor takes the stream
|
||||
to have its attributes saved and the index of the user-defined attributes. The
|
||||
destructor for each class restores the saved state. Restoration can be
|
||||
activated early (and often) for a class with the restore member function.
|
||||
|
||||
## Example
|
||||
|
||||
The code used in the rationale can be improved at two places. The printing
|
||||
function could use a saver around the code that changes the formatting state.
|
||||
Or the calling function can surround the call with a saver. Or both can be
|
||||
done, especially if the user does not know if the printing function uses a
|
||||
state saver. If the user wants a series of changes back and forth, without
|
||||
surrounding each change within a separate block, the restore member function
|
||||
can be called between each trial.
|
||||
|
||||
```
|
||||
#include <boost/io/ios_state.hpp>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
void new_hex_my_byte(std::ostream& os, char byte)
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(os);
|
||||
os << std::hex << static_cast<unsigned>(byte);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// ...
|
||||
{
|
||||
boost::io::ios_all_saver ias(std::cout);
|
||||
new_hex_my_byte(std::cout, 'A');
|
||||
}
|
||||
// ...
|
||||
{
|
||||
boost::io::ios_all_saver ias(std::cerr);
|
||||
new_hex_my_byte(std::cerr, 'b');
|
||||
ias.restore();
|
||||
new_hex_my_byte(std::cerr, 'C');
|
||||
}
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
### Daryle Walker
|
||||
|
||||
Started the library. Contributed the initial versions of the format flags,
|
||||
precision, width, and user-defined format flags saver classes. Contributed the
|
||||
initial versions of the success state, success state exception flags, output
|
||||
stream tie, stream buffer, character fill, and locale saver class templates.
|
||||
Contributed the combined attribute classes and class template. Contributed the
|
||||
test file `ios_state_test.cpp`.
|
||||
|
||||
## History
|
||||
|
||||
### 20 Dec 2019
|
||||
|
||||
Glen Fernandes made all the saver classes non-copyable.
|
||||
|
||||
### 28 Feb 2005
|
||||
|
||||
Daryle Walker added the restore member functions, based on suggestions by
|
||||
Gennadiy Rozental and Rob Stewart.
|
||||
|
||||
### 13 Mar 2002
|
||||
|
||||
Daryle Walker implemented the initial version.
|
@ -1,468 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>I/O Stream-State Saver Library</title>
|
||||
</head>
|
||||
<body text="black" bgcolor="white" link="blue" vlink="purple" alink="red">
|
||||
<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)"
|
||||
align="middle" width="277" height="86">Header <<cite><a
|
||||
href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite>
|
||||
></h1>
|
||||
|
||||
<p>The header <cite><a
|
||||
href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite>
|
||||
covers saving the stream state of objects in the C++ IOStreams
|
||||
system.</p>
|
||||
|
||||
<h2><a name="contents">Contents</a></h2>
|
||||
|
||||
<ol>
|
||||
<li><a href="#contents">Contents</a></li>
|
||||
<li><a href="#rationale">Rationale</a></li>
|
||||
<li><a href="#header">Header Synopsis</a></li>
|
||||
<li><a href="#base_savers">Savers for Basic Standard Attributes</a></li>
|
||||
<li><a href="#adv_savers">Savers for Advanced Standard Attributes</a></li>
|
||||
<li><a href="#user_savers">Savers for User-Defined Attributes</a></li>
|
||||
<li><a href="#combo_savers">Savers for Combined Attributes</a></li>
|
||||
<li><a href="#example">Example</a></li>
|
||||
<li><a href="#refer">References</a></li>
|
||||
<li><a href="#credits">Credits</a>
|
||||
<ul>
|
||||
<li><a href="#contributors">Contributors</a></li>
|
||||
<li><a href="#history">History</a></li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
|
||||
<h2><a name="rationale">Rationale</a></h2>
|
||||
|
||||
<p>Sometimes a certain value has to change only for a limited scope.
|
||||
Saver classes save a copy of the current state of some object (or an
|
||||
aspect of an object), and reset the object's state at destruction time,
|
||||
undoing any change the object may have gone through.</p>
|
||||
|
||||
<p>The saver class strategy is helpful when using I/O stream objects.
|
||||
Manipulator objects can change some aspect of a stream during input or
|
||||
output. The state changed by the manipulator usually sticks to its new
|
||||
value after the I/O transaction. This can be a problem if manipulators
|
||||
are used in a function that is not supposed to externally change a
|
||||
stream's state.</p>
|
||||
|
||||
<blockquote><pre>#include <ostream>
|
||||
#include <ios>
|
||||
|
||||
void hex_my_byte( std::ostream &os, char byte )
|
||||
{
|
||||
os << std::hex << static_cast<unsigned>(byte);
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The <var>os</var> stream will retain its new hexadecimal printing
|
||||
mode after the call to <code>hex_my_byte</code>. The stream's printing
|
||||
mode can be saved and restored with manual calls to the stream's state
|
||||
inspecting and mutating member functions. The manual method becomes
|
||||
unwieldy if the main functionality is complex and/or needs to be
|
||||
exception safe. A saver class can implement the better "resource
|
||||
acquisition is initialization" strategy.</p>
|
||||
|
||||
<p>See the <a href="#example">example</a> below for better code, using
|
||||
saver classes.</p>
|
||||
|
||||
<h2><a name="header">Header Synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>#include <iosfwd> <i>// for std::char_traits (declaration)</i>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
|
||||
class ios_flags_saver;
|
||||
class ios_precision_saver;
|
||||
class ios_width_saver;
|
||||
class ios_base_all_saver;
|
||||
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_iostate_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_exception_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_tie_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_rdbuf_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_fill_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_locale_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_all_saver;
|
||||
|
||||
typedef basic_ios_iostate_saver<char> ios_iostate_saver;
|
||||
typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
|
||||
typedef basic_ios_exception_saver<char> ios_exception_saver;
|
||||
typedef basic_ios_exception_saver<wchar_t> wios_exception_saver;
|
||||
typedef basic_ios_tie_saver<char> ios_tie_saver;
|
||||
typedef basic_ios_tie_saver<wchar_t> wios_tie_saver;
|
||||
typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
|
||||
typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
|
||||
typedef basic_ios_fill_saver<char> ios_fill_saver;
|
||||
typedef basic_ios_fill_saver<wchar_t> wios_fill_saver;
|
||||
typedef basic_ios_locale_saver<char> ios_locale_saver;
|
||||
typedef basic_ios_locale_saver<wchar_t> wios_locale_saver;
|
||||
typedef basic_ios_all_saver<char> ios_all_saver;
|
||||
typedef basic_ios_all_saver<wchar_t> wios_all_saver;
|
||||
|
||||
class ios_iword_saver;
|
||||
class ios_pword_saver;
|
||||
class ios_all_word_saver;
|
||||
|
||||
}
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="base_savers">Savers for Basic Standard Attributes</a></h2>
|
||||
|
||||
<p>The basic saver classes have this format:</p>
|
||||
|
||||
<blockquote><pre>class <var>saver_class</var>
|
||||
{
|
||||
typedef std::ios_base state_type;
|
||||
typedef <i>implementation_defined</i> aspect_type;
|
||||
|
||||
explicit saver_class( state_type &s );
|
||||
saver_class( state_type &s, <var>aspect_type</var> const &new_value );
|
||||
~saver_class();
|
||||
|
||||
void restore();
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The <var>state_type</var> is the IOStreams base class
|
||||
<code>std::ios_base</code>. The user would usually place an actual
|
||||
input, output, or combined stream object for the state-type parameter,
|
||||
and not a base class object. The first constructor takes a stream
|
||||
object and saves a reference to the stream and the current value of a
|
||||
particular stream attribute. The second constructor works like the
|
||||
first, and uses its second argument to change the stream's attribute to
|
||||
the new <var>aspect_type</var> value given. The destructor restores the
|
||||
stream's attribute to the saved value. The restoration can be activated
|
||||
early (and often) with the <code>restore</code> member function.</p>
|
||||
|
||||
<table border="1" align="center">
|
||||
<caption>Basic IOStreams State Saver Classes</caption>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>Saved Attribute</th>
|
||||
<th>Attribute Type</th>
|
||||
<th>Reading Method</th>
|
||||
<th>Writing Method</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::ios_flags_saver</code></td>
|
||||
<td>Format control flags</td>
|
||||
<td><code>std::ios_base::fmtflags</code></td>
|
||||
<td><code>flags</code></td>
|
||||
<td><code>flags</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::ios_precision_saver</code></td>
|
||||
<td>Number of digits to print after decimal point</td>
|
||||
<td><code>std::streamsize</code></td>
|
||||
<td><code>precision</code></td>
|
||||
<td><code>precision</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::ios_width_saver</code></td>
|
||||
<td>Minimum field width for printing objects</td>
|
||||
<td><code>std::streamsize</code></td>
|
||||
<td><code>width</code></td>
|
||||
<td><code>width</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="adv_savers">Savers for Advanced Standard Attributes</a></h2>
|
||||
|
||||
<p>The saver class templates have this format:</p>
|
||||
|
||||
<blockquote><pre>template < typename Ch, class Tr >
|
||||
class <var>saver_class</var>
|
||||
{
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef <i>implementation_defined</i> aspect_type;
|
||||
|
||||
explicit saver_class( state_type &s );
|
||||
saver_class( state_type &s, <var>aspect_type</var> const &new_value );
|
||||
~saver_class();
|
||||
|
||||
void restore();
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The <var>state_type</var> is a version of the IOStreams base class
|
||||
template <code>std::basic_ios<Ch, Tr></code>, where
|
||||
<code>Ch</code> is a character type and <code>Tr</code> is a character
|
||||
traits class. The user would usually place an actual input, output, or
|
||||
combined stream object for the state-type parameter, and not a base
|
||||
class object. The first constructor takes a stream object and saves a
|
||||
reference to the stream and the current value of a particular stream
|
||||
attribute. The second constructor works like the first, and uses its
|
||||
second argument to change the stream's attribute to the new
|
||||
<var>aspect_type</var> value given. The destructor restores the stream's
|
||||
attribute to the saved value. The restoration can be activated
|
||||
early (and often) with the <code>restore</code> member function.</p>
|
||||
|
||||
<table border="1" align="center">
|
||||
<caption>Advanced IOStreams State Saver Class Templates</caption>
|
||||
<tr>
|
||||
<th>Class Template</th>
|
||||
<th>Saved Attribute</th>
|
||||
<th>Attribute Type</th>
|
||||
<th>Reading Method</th>
|
||||
<th>Writing Method</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_iostate_saver<Ch, Tr></code></td>
|
||||
<td>Failure state of the stream <a href="#Note1">[1]</a>, <a href="#Note2">[2]</a></td>
|
||||
<td><code>std::ios_base::iostate</code></td>
|
||||
<td><code>rdstate</code></td>
|
||||
<td><code>clear</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_exception_saver<Ch, Tr></code></td>
|
||||
<td>Which failure states trigger an exception <a href="#Note1">[1]</a></td>
|
||||
<td><code>std::ios_base::iostate</code></td>
|
||||
<td><code>exceptions</code></td>
|
||||
<td><code>exceptions</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_tie_saver<Ch, Tr></code></td>
|
||||
<td>Output stream synchronized with the stream</td>
|
||||
<td><code>std::basic_ostream<Ch, Tr> *</code></td>
|
||||
<td><code>tie</code></td>
|
||||
<td><code>tie</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_rdbuf_saver<Ch, Tr></code></td>
|
||||
<td>Stream buffer associated with the stream <a href="#Note2">[2]</a></td>
|
||||
<td><code>std::basic_streambuf<Ch, Tr> *</code></td>
|
||||
<td><code>rdbuf</code></td>
|
||||
<td><code>rdbuf</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_fill_saver<Ch, Tr></code></td>
|
||||
<td>Character used to pad oversized field widths</td>
|
||||
<td><code>Ch</code></td>
|
||||
<td><code>fill</code></td>
|
||||
<td><code>fill</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::basic_ios_locale_saver<Ch, Tr></code></td>
|
||||
<td>Locale information associated with the stream <a href="#Note3">[3]</a></td>
|
||||
<td><code>std::locale</code></td>
|
||||
<td><code>getloc</code> (from <code>std::ios_base</code>)</td>
|
||||
<td><code>imbue</code> (from <code>std::basic_ios<Ch, Tr></code>)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
<ol>
|
||||
<li>When the failure state flags and/or the failure state exception
|
||||
watching flags are changed, an exception is thrown if a match
|
||||
occurs among the two sets of flags. This could mean that
|
||||
the <a name="Note1">constructor or destructor of these class
|
||||
templates may throw</a>.</li>
|
||||
<li>When the associated stream buffer is changed, the stream's
|
||||
failure state set is reset to "good" if the given stream
|
||||
buffer's address is non-NULL, but the "bad" failure
|
||||
state is set if that address is NULL. This means that a saved
|
||||
failure state of "good" may be restored as "bad"
|
||||
if the stream is stripped of an associated stream buffer. Worse,
|
||||
given a NULL stream buffer address, an exception is thrown if the
|
||||
"bad" failure state is being watched. This could mean
|
||||
that the <a name="Note2">constructor or destructor of these class
|
||||
templates may throw</a>.</li>
|
||||
<li>The <a name="Note3">saver for the locale uses the
|
||||
<code>std::basic_ios<Ch, Tr></code> class to extract their
|
||||
information</a>, although it could have used the functionality
|
||||
in <code>std::ios_base</code>. The problem is that the versions
|
||||
of the needed member functions in <code>ios_base</code> are not
|
||||
polymorphically related to the ones in <code>basic_ios</code>.
|
||||
The stream classes that will be used with the saver classes
|
||||
should use the versions of the member functions closest to them
|
||||
by inheritance, which means the ones in
|
||||
<code>basic_ios</code>.</li>
|
||||
</ol>
|
||||
|
||||
<h2><a name="user_savers">Savers for User-Defined Attributes</a></h2>
|
||||
|
||||
<p>The saver classes for user-defined formatting information have this
|
||||
format:</p>
|
||||
|
||||
<blockquote><pre>#include <iosfwd> <i>// for std::ios_base (declaration)</i>
|
||||
|
||||
class <var>saver_class</var>
|
||||
{
|
||||
typedef std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef <i>implementation_defined</i> aspect_type;
|
||||
|
||||
explicit saver_class( state_type &s, index_type i );
|
||||
saver_class( state_type &s, index_type i, <var>aspect_type</var> const &new_value );
|
||||
~saver_class();
|
||||
|
||||
void restore();
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
<p>The index <var>i</var> differentiates between specific user-defined
|
||||
formatting attributes. The index can only be determined at run-time
|
||||
(most likely with the class-static <code>std::ios_base::xalloc</code>
|
||||
member function).</p>
|
||||
|
||||
<p>The <var>state_type</var> is the base class of the IOStreams system,
|
||||
<code>std::ios_base</code>. The user would usually place an actual
|
||||
input, output, or combined stream object for the state-type parameter,
|
||||
and not a base class object. The first constructor takes a stream
|
||||
object and index and saves a reference to the stream and the current
|
||||
value of a particular stream attribute. The second constructor works
|
||||
like the first, and uses its third argument to change the stream's
|
||||
attribute to the new <var>aspect_type</var> value given. The destructor
|
||||
restores the stream's attribute to the saved value. The restoration can
|
||||
be activated early (and often) with the <code>restore</code> member
|
||||
function.</p>
|
||||
|
||||
<table border="1" align="center">
|
||||
<caption>IOStream User-Defined State Saver Classes</caption>
|
||||
<tr>
|
||||
<th>Class</th>
|
||||
<th>Saved Attribute</th>
|
||||
<th>Attribute Type</th>
|
||||
<th>Reference Method</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::ios_iword_saver</code></td>
|
||||
<td>Numeric user-defined format flag</td>
|
||||
<td><code>long</code></td>
|
||||
<td><code>iword</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>boost::io::ios_pword_saver</code></td>
|
||||
<td>Pointer user-defined format flag</td>
|
||||
<td><code>void *</code></td>
|
||||
<td><code>pword</code></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a name="combo_savers">Savers for Combined Attributes</a></h2>
|
||||
|
||||
<p>There are three class (templates) for combined attribute savers. The
|
||||
<code>boost:io::ios_base_all_saver</code> saver class combines the
|
||||
functionality of all the basic attribute saver classes. It has a
|
||||
constructor that takes the stream to have its state preserved. The
|
||||
<code>boost::io::basic_ios_all_saver</code> combines the functionality
|
||||
of all the advanced attribute saver class templates and the combined
|
||||
basic attribute saver class. It has a constructor that takes the stream
|
||||
to have its state preserved. The
|
||||
<code>boost::io::ios_all_word_saver</code> saver class combines the
|
||||
saver classes that preserve user-defined formatting information. Its
|
||||
constructor takes the stream to have its attributes saved and the index
|
||||
of the user-defined attributes. The destructor for each class restores
|
||||
the saved state. Restoration can be activated early (and often) for a
|
||||
class with the <code>restore</code> member function.</p>
|
||||
|
||||
<h2><a name="example">Example</a></h2>
|
||||
|
||||
<p>The code used in the <a href="#rationale">rationale</a> can be
|
||||
improved at two places. The printing function could use a saver around
|
||||
the code that changes the formatting state. Or the calling function can
|
||||
surround the call with a saver. Or both can be done, especially if the
|
||||
user does not know if the printing function uses a state saver. If the
|
||||
user wants a series of changes back & forth, without surrounding each
|
||||
change within a separate block, the <code>restore</code> member function
|
||||
can be called between each trial.</p>
|
||||
|
||||
<blockquote><pre>#include <boost/io/ios_state.hpp>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
void new_hex_my_byte( std::ostream &os, char byte )
|
||||
{
|
||||
boost::io::ios_flags_saver ifs( os );
|
||||
|
||||
os << std::hex << static_cast<unsigned>(byte);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
|
||||
//...
|
||||
|
||||
{
|
||||
boost::io::ios_all_saver ias( cout );
|
||||
|
||||
new_hex_my_byte( cout, 'A' );
|
||||
}
|
||||
|
||||
//...
|
||||
|
||||
{
|
||||
boost::io::ios_all_saver ias( cerr );
|
||||
|
||||
new_hex_my_byte( cerr, 'b' );
|
||||
ias.restore();
|
||||
new_hex_my_byte( cerr, 'C' );
|
||||
}
|
||||
|
||||
//...
|
||||
}
|
||||
</pre></blockquote>
|
||||
|
||||
<h2><a name="refer">References</a></h2>
|
||||
|
||||
<ul>
|
||||
<li>The I/O state saver library header itself: <cite><a
|
||||
href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite></li>
|
||||
<li>Some test/example code: <cite><a
|
||||
href="../test/ios_state_test.cpp">ios_state_test.cpp</a></cite></li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="credits">Credits</a></h2>
|
||||
|
||||
<h3><a name="contributors">Contributors</a></h3>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a>
|
||||
<dd>Started the library. Contributed the initial versions of the
|
||||
format flags, precision, width, and user-defined format flags
|
||||
saver classes. Contributed the initial versions of the success
|
||||
state, success state exception flags, output stream tie, stream
|
||||
buffer, character fill, and locale saver class templates.
|
||||
Contributed the combined attribute classes and class template.
|
||||
Contributed the test file <cite><a
|
||||
href="../test/ios_state_test.cpp">ios_state_test.cpp</a></cite>.
|
||||
</dl>
|
||||
|
||||
<h3><a name="history">History</a></h3>
|
||||
|
||||
<dl>
|
||||
<dt>28 Feb 2005, Daryle Walker
|
||||
<dd>Added the <code>restore</code> member functions, based on suggestions
|
||||
by Gennadiy Rozental and Rob Stewart
|
||||
|
||||
<dt>13 Mar 2002, Daryle Walker
|
||||
<dd>Initial version
|
||||
</dl>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised: 28 February 2005</p>
|
||||
|
||||
<p>Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution
|
||||
are subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at
|
||||
<<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||
</body>
|
||||
</html>
|
75
doc/nullstream.adoc
Normal file
75
doc/nullstream.adoc
Normal file
@ -0,0 +1,75 @@
|
||||
////
|
||||
Copyright 2021 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
////
|
||||
|
||||
# Null Streams, <boost/io/nullstream.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/nullstream.hpp>` provides the class template
|
||||
`boost::io::basic_nullbuf` which is a null stream buffer and class template
|
||||
`boost::io::basic_onullstream` which is a null stream.
|
||||
|
||||
## Example
|
||||
|
||||
The following program passes a null stream to a function.
|
||||
|
||||
```
|
||||
#include <boost/io/ostream_joiner.hpp>
|
||||
#include <fstream>
|
||||
|
||||
void setup(std::ostream& log);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc == 2) {
|
||||
std::ofstream file(argv[1]);
|
||||
setup(file);
|
||||
} else {
|
||||
boost::io::onullstream none;
|
||||
setup(none);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<Char> >
|
||||
class basic_nullbuf
|
||||
: public std::basic_streambuf<CharT, Traits> {
|
||||
protected:
|
||||
typename Traits::int_type overflow(typename Traits::int_type c) override;
|
||||
|
||||
std::streamsize xsputn(const CharT*, std::streamsize n) override;
|
||||
};
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT> >
|
||||
class basic_onullstream
|
||||
: public std::basic_ostream<CharT, Traits> {
|
||||
public:
|
||||
basic_onullstream();
|
||||
};
|
||||
|
||||
typedef basic_onullstream<char> onullstream;
|
||||
typedef basic_onullstream<wchar_t> wonullstream;
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Glen Fernandes implemented `basic_nullbuf` and `basic_onullstream`.
|
142
doc/ostream_joiner.adoc
Normal file
142
doc/ostream_joiner.adoc
Normal file
@ -0,0 +1,142 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Delimited Iterators, <boost/io/ostream_joiner.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/ostream_joiner.hpp>` provides the class template
|
||||
`boost::io::ostream_joiner` which is an output iterator that writes objects to
|
||||
a `std::basic_ostream` separated by a delimiter. It is an implementation of
|
||||
the Library Fundamentals TS `std::ostream_joiner` which supports {cpp}03 and
|
||||
higher.
|
||||
|
||||
## Example
|
||||
|
||||
The following program writes the contents of a vector to standard output, with
|
||||
each element separated by a comma.
|
||||
|
||||
```
|
||||
#include <boost/io/ostream_joiner.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<int> v;
|
||||
v.push_back(2);
|
||||
v.push_back(4);
|
||||
v.push_back(6);
|
||||
v.push_back(8);
|
||||
std::copy(v.begin(), v.end(), boost::make_ostream_joiner(std::cout, ','));
|
||||
}
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class Delim, class Char = char,
|
||||
class Traits = std::char_traits<Char> >
|
||||
class ostream_joiner {
|
||||
public:
|
||||
typedef Char char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef std::basic_ostream<Char, Traits> ostream_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
ostream_joiner(ostream_type& output, const Delim& delim);
|
||||
ostream_joiner(ostream_type& output, Delim&& delim);
|
||||
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value);
|
||||
|
||||
ostream_joiner& operator*() noexcept;
|
||||
ostream_joiner& operator++() noexcept;
|
||||
ostream_joiner& operator++(int) noexcept;
|
||||
};
|
||||
|
||||
template<class Char, class Traits, class Delim>
|
||||
ostream_joiner<std::decay_t<Delim>, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim);
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
### Constructors
|
||||
|
||||
```
|
||||
ostream_joiner(ostream_type& output, const Delim& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
EFfects:: Initializes the stored reference to the stream with
|
||||
`std::addressof(output)` and the stored delimiter with `delim`.
|
||||
|
||||
```
|
||||
ostream_joiner(ostream_type& output, Delim&& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
EFfects:: Initializes the stored reference to the stream with
|
||||
`std::addressof(output)` and the stored delimiter with `std::move(delim)`.
|
||||
|
||||
### Member functions
|
||||
|
||||
```
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Effects:: If the is the first call to this member function, write the stored
|
||||
delimiter to the stored stream reference. Writes `value` to the stored stream
|
||||
reference.
|
||||
Returns:: `*this`.
|
||||
|
||||
```
|
||||
ostream_joiner& operator*() noexcept;
|
||||
```
|
||||
```
|
||||
ostream_joiner& operator++() noexcept;
|
||||
```
|
||||
```
|
||||
ostream_joiner& operator++(int) noexcept;
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Returns:: `*this`.
|
||||
|
||||
### Free functions
|
||||
|
||||
```
|
||||
template<class Char, class Traits, class Delim>
|
||||
ostream_joiner<decay_t<Delim>, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
Returns:: `ostream_joiner<std::decay_t<Delim>, Char, Traits>(output,
|
||||
std::forward<Delim>(delim))`.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Glen Fernandes implemented `ostream_joiner` and `make_ostream_joiner`.
|
73
doc/ostream_put.adoc
Normal file
73
doc/ostream_put.adoc
Normal file
@ -0,0 +1,73 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Insert Formatted Output, <boost/io/ostream_put.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Description
|
||||
|
||||
The header `<boost/io/ostream_put.hpp>` provides the function template
|
||||
`boost::io::ostream_put` for formatted output that satisfies the requirements
|
||||
of [ostream.formatted.reqmts].
|
||||
|
||||
## Example
|
||||
|
||||
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::io::ostream_put(os, str.data(), str.size());
|
||||
}
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
### Header Synopsis
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os,
|
||||
const charT* data, std::size_t size);
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
### Free functions
|
||||
|
||||
```
|
||||
template<class charT, class traits>
|
||||
std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os,
|
||||
const charT* data, std::size_t size);
|
||||
```
|
||||
|
||||
[.specification]
|
||||
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`.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
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.
|
145
doc/quoted.adoc
Normal file
145
doc/quoted.adoc
Normal file
@ -0,0 +1,145 @@
|
||||
////
|
||||
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)
|
||||
////
|
||||
|
||||
# Quoted Manipulators, <boost/io/quoted.hpp>
|
||||
:toc:
|
||||
:toc-title:
|
||||
:idprefix:
|
||||
|
||||
## Introduction
|
||||
|
||||
C++ Standard library stream I/O for strings that contain embedded spaces can
|
||||
produce unexpected results. For example,
|
||||
|
||||
```
|
||||
std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string roundtrip;
|
||||
|
||||
ss << original;
|
||||
ss >> roundtrip;
|
||||
|
||||
std::cout << original; // outputs: fooled you
|
||||
std::cout << roundtrip; // outputs: fooled
|
||||
|
||||
assert(original == roundtrip); // assert will fire
|
||||
```
|
||||
|
||||
The Boost quoted stream I/O manipulator places delimiters, defaulted to the
|
||||
double-quote ("), around strings on output, and strips off the delimiters on
|
||||
input. This ensures strings with embedded spaces round-trip as desired. For
|
||||
example,
|
||||
|
||||
```
|
||||
std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string roundtrip;
|
||||
|
||||
ss << quoted(original);
|
||||
ss >> quoted(roundtrip);
|
||||
|
||||
std::cout << quoted(original); // outputs: "fooled you"
|
||||
std::cout << roundtrip; // outputs: fooled you
|
||||
|
||||
assert(original == roundtrip); // assert will not fire
|
||||
```
|
||||
|
||||
If the string contains the delimiter character, on output that character will
|
||||
be preceded by an escape character, as will the escape character itself:
|
||||
|
||||
```
|
||||
std::cout << quoted("'Jack & Jill'", '&', '\''); // outputs: '&'Jack && Jill&''
|
||||
```
|
||||
|
||||
## Header synopsis
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
`unspecified-type1`
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& string,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
template<class Char>
|
||||
`unspecified-type2`
|
||||
quoted(const Char* string, Char escape='\\', Char delim='\"');
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
`unspecified-type3`
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& string,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
} // io
|
||||
} // boost
|
||||
```
|
||||
|
||||
*unspecified-type1*, *unspecified-type2*, and *unspecified-type3* are
|
||||
implementation supplied types with implementation supplied `operator<<`:
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
template<class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const `unspecified-typeN`& proxy);
|
||||
```
|
||||
|
||||
Effects:: Inserts characters into `os`:
|
||||
* `delim`
|
||||
* Each character in `string`. If the character to be output is equal to
|
||||
`escape` or `delim`, as determined by `operator==`, first output `escape`.
|
||||
* `delim`
|
||||
Remarks:: `string`, `escape`, and `delim` have the type and value of the
|
||||
corresponding arguments of the call to the `quoted` function that constructed
|
||||
`proxy`.
|
||||
Returns:: `os`.
|
||||
|
||||
*unspecified-type3* is an implementation supplied type with an implementation
|
||||
supplied `operator>>`:
|
||||
|
||||
[subs=+quotes]
|
||||
```
|
||||
template<class Char, class Traits>
|
||||
std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is,
|
||||
const `unspecified-type3`& proxy);
|
||||
```
|
||||
|
||||
Effects:: Extracts characters from `os`:
|
||||
* If the first character extracted is equal to `delim`, as determined by
|
||||
`operator==`, then:
|
||||
** Turn off the `skipws` flag.
|
||||
** `string.clear()`
|
||||
** Until an unescaped `delim` character is reached or `is.not_good()`, extract
|
||||
characters from `os` and append them to string, except that if an escape is
|
||||
reached, ignore it and append the next character to string.
|
||||
** Discard the final `delim` character.
|
||||
** Restore the `skipws` flag to its original value.
|
||||
* Otherwise, `os >> string`.
|
||||
|
||||
Remarks:: `string`, `escape`, and `delim` have the type and value of the
|
||||
corresponding arguments of the call to the `quoted` function that constructed
|
||||
`proxy`.
|
||||
Returns:: `is`.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
The `quoted()` stream manipulator emerged from discussions on the Boost
|
||||
developers mailing list. Participants included Beman Dawes, Rob Stewart,
|
||||
Alexander Lamaison, Eric Niebler, Vicente Botet, Andrey Semashev,
|
||||
Phil Richards, and Rob Murray. Eric Niebler's suggestions provided the basis
|
||||
for the name and form of the templates.
|
||||
|
||||
Beman Dawes started the implementation of `quoted()` as a private detail
|
||||
header. Glen Fernandes updated the implementation and also made it public.
|
||||
|
||||
Glen Fernandes corrected the implementation to properly account for stream
|
||||
width and fill, and optimized it to write directly to the stream buffer.
|
@ -1,164 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||||
<title>Boost "quoted" I/O manipulator</title>
|
||||
<meta name="generator" content="Microsoft FrontPage 5.0" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../doc/src/minimal.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<table border="0" cellpadding="5" cellspacing="0"
|
||||
style="border-collapse: collapse">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="277"><a href="../../../index.htm"><img
|
||||
src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle"
|
||||
width="300" height="86" border="0" /></a></td>
|
||||
<td>
|
||||
<h1 align="center">"Quoted"
|
||||
I/O Manipulators<br>
|
||||
for Strings</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table border="1" cellpadding="5" cellspacing="1" style="border-collapse: collapse" bordercolor="#111111">
|
||||
<tr>
|
||||
<td>
|
||||
<p align="center"><b>"Quoted"
|
||||
I/O Manipulators
|
||||
for Strings are not yet accepted into Boost as public components. Thus the
|
||||
header file is currently located in <boost/io/detail/quoted_manip.hpp></b></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>C++ Standard library stream I/O for strings that contain embedded spaces
|
||||
can produce unexpected results. For example,</p>
|
||||
<blockquote>
|
||||
<pre>std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string round_trip;
|
||||
|
||||
ss << original;
|
||||
ss >> round_trip;
|
||||
|
||||
std::cout << original; // outputs: fooled you
|
||||
std::cout << round_trip; // outputs: fooled
|
||||
|
||||
assert(original == round_trip); // assert will fire</pre>
|
||||
</blockquote>
|
||||
<p>The Boost <code>quoted</code> stream I/O manipulator places delimiters, defaulted
|
||||
to the double-quote (<code>"</code>), around strings on output, and strips off
|
||||
the delimiters on input. This ensures strings with embedded spaces round-trip as
|
||||
desired. For example,</p>
|
||||
<blockquote>
|
||||
<pre>std::stringstream ss;
|
||||
std::string original = "fooled you";
|
||||
std::string round_trip;
|
||||
|
||||
ss << quoted(original);
|
||||
ss >> quoted(round_trip);
|
||||
|
||||
std::cout << quoted(original); // outputs: "fooled you"
|
||||
std::cout << round_trip; // outputs: fooled you
|
||||
|
||||
assert(original == round_trip); // assert will not fire</pre>
|
||||
</blockquote>
|
||||
<p>If the string contains the delimiter character, on output that character will
|
||||
be preceded by an escape character, as will the escape character itself:</p>
|
||||
<blockquote>
|
||||
<pre>std::cout << quoted("'Jack & Jill'", '&', '\''); // outputs: '&'Jack && Jill&''</pre>
|
||||
</blockquote>
|
||||
<h2>Header <a href="../../../boost/io/detail/quoted_manip.hpp"><boost/io/quoted_manip.hpp></a> synopsis</h2>
|
||||
<pre>namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
// manipulator for const std::basic_string&
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
<b><i>unspecified-type1</i></b> quoted(const std::basic_string<Char, Traits, Alloc>& string,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for const C-string*
|
||||
|
||||
template <class Char>
|
||||
<b><i>unspecified-type2</i></b> quoted(const Char* string,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for non-const std::basic_string&
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
<b><i>unspecified-type3</i></b> quoted(std::basic_string<Char, Traits, Alloc>& string,
|
||||
Char escape='\\', Char delim='\"');
|
||||
}
|
||||
}</pre>
|
||||
<p><i><b><code>unspecified_type1</code></b></i>, <i><b><code>unspecified_type2</code></b></i>,
|
||||
and <i><b><code>unspecified_type3</code></b></i> are implementation supplied
|
||||
types with implementation supplied <code>operator<<</code>:</p>
|
||||
<blockquote>
|
||||
<pre>template <class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os, const <i><b><code>unspecified_typeN</code></b></i>& proxy);</pre>
|
||||
<p><i>Effects:</i> Inserts characters into <code>os</code>:</p>
|
||||
<ul>
|
||||
<li><code>delim</code>.</li>
|
||||
<li>Each character in <code>string</code>. If the character to be output is
|
||||
equal to <code>escape</code> or <code>delim</code>, as determined by <code>
|
||||
operator==</code>, first output <code>escape</code>. </li>
|
||||
<li><code>delim</code>.</li>
|
||||
</ul>
|
||||
<p><i>Remarks:</i> <code>string</code>, <code>escape</code>, and <code>delim</code>
|
||||
have the type and value of the corresponding arguments of the call to the <code>
|
||||
quoted</code> function that constructed <code>proxy</code>.</p>
|
||||
<p><i>Returns:</i> <code>os</code>. </p>
|
||||
</blockquote>
|
||||
<p><i><b><code>unspecified_type3</code></b></i> is an implementation supplied
|
||||
type with an implementation supplied <code>operator>></code>:</p>
|
||||
<blockquote>
|
||||
<pre>template <class Char, class Traits>
|
||||
std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is, const <i><b><code>unspecified_type3</code></b></i>& proxy);</pre>
|
||||
<p><i>Effects:</i> Extracts characters from <code>os</code>:</p>
|
||||
<ul>
|
||||
<li>If the first character extracted is equal to delim, as determined by
|
||||
<code>operator==</code>, then:<ul>
|
||||
<li>Turn off the <code>skipws</code> flag.</li>
|
||||
<li><code>string.clear()</code></li>
|
||||
<li>Until an unescaped <code>delim</code> character is reached or <code>
|
||||
is.not_good()</code>, extract
|
||||
characters from <code>os</code> and append them to <code>string</code>,
|
||||
except that if an <code>escape</code> is reached, ignore it and append the
|
||||
next character to <code>string</code>.</li>
|
||||
<li>Discard the final <code>delim</code> character.</li>
|
||||
<li>Restore the <code>skipws</code> flag to its original value.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Otherwise, <code>os >> string</code>.</li>
|
||||
</ul>
|
||||
<p><i>Remarks:</i> <code>string</code>, <code>escape</code>, and <code>delim</code>
|
||||
have the type and value of the corresponding arguments of the call to the <code>
|
||||
quoted</code> function that constructed <code>proxy</code>.</p>
|
||||
<p><i>Returns:</i> <code>is</code>. </p>
|
||||
</blockquote>
|
||||
<h2>Acknowledgements</h2>
|
||||
<p>The <code>quoted()</code> stream manipulator emerged from discussions on the
|
||||
Boost developers mailing list. Participants included Beman Dawes, Rob Stewart,
|
||||
Alexander Lamaison, Eric Niebler, Vicente Botet, Andrey Semashev, Phil Richards,
|
||||
and Rob Murray. Eric Niebler's suggestions provided the basis for the name and
|
||||
form of the templates. </p>
|
||||
<hr>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. See
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->08 March 2013<!--webbot bot="Timestamp" endspan i-checksum="27284" --></p>
|
||||
|
||||
</body>
|
||||
</html>
|
39
include/boost/io/detail/buffer_fill.hpp
Normal file
39
include/boost/io/detail/buffer_fill.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2019-2020 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_IO_DETAIL_BUFFER_FILL_HPP
|
||||
#define BOOST_IO_DETAIL_BUFFER_FILL_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline bool
|
||||
buffer_fill(std::basic_streambuf<charT, traits>& buf, charT ch,
|
||||
std::size_t size)
|
||||
{
|
||||
charT fill[] = { ch, ch, ch, ch, ch, ch, ch, ch };
|
||||
enum {
|
||||
chunk = sizeof fill / sizeof(charT)
|
||||
};
|
||||
for (; size > chunk; size -= chunk) {
|
||||
if (static_cast<std::size_t>(buf.sputn(fill, chunk)) != chunk) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return static_cast<std::size_t>(buf.sputn(fill, size)) == size;
|
||||
}
|
||||
|
||||
} /* detail */
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
45
include/boost/io/detail/ostream_guard.hpp
Normal file
45
include/boost/io/detail/ostream_guard.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2019-2020 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_IO_DETAIL_OSTREAM_GUARD_HPP
|
||||
#define BOOST_IO_DETAIL_OSTREAM_GUARD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class Char, class Traits>
|
||||
class ostream_guard {
|
||||
public:
|
||||
explicit ostream_guard(std::basic_ostream<Char, Traits>& os) BOOST_NOEXCEPT
|
||||
: os_(&os) { }
|
||||
|
||||
~ostream_guard() BOOST_NOEXCEPT_IF(false) {
|
||||
if (os_) {
|
||||
os_->setstate(std::basic_ostream<Char, Traits>::badbit);
|
||||
}
|
||||
}
|
||||
|
||||
void release() BOOST_NOEXCEPT {
|
||||
os_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_guard(const ostream_guard&);
|
||||
ostream_guard& operator=(const ostream_guard&);
|
||||
|
||||
std::basic_ostream<Char, Traits>* os_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -1,190 +0,0 @@
|
||||
// boost/io/quoted_manip.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Library home page http://www.boost.org/libs/io
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_IO_QUOTED_MANIP
|
||||
#define BOOST_IO_QUOTED_MANIP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
namespace detail { template <class String, class Char> struct quoted_proxy; }
|
||||
|
||||
// ------------ public interface ------------------------------------------------//
|
||||
|
||||
// manipulator for const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for non-const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& s,
|
||||
Char escape='\\', Char delim='\"');
|
||||
|
||||
// manipulator for const C-string*
|
||||
template <class Char>
|
||||
detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape='\\', Char delim='\"');
|
||||
|
||||
// ----------- implementation details -------------------------------------------//
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// proxy used as an argument pack
|
||||
template <class String, class Char>
|
||||
struct quoted_proxy
|
||||
{
|
||||
String string;
|
||||
Char escape;
|
||||
Char delim;
|
||||
|
||||
quoted_proxy(String s_, Char escape_, Char delim_)
|
||||
: string(s_), escape(escape_), delim(delim_) {}
|
||||
private:
|
||||
// String may be a const type, so disable the assignment operator
|
||||
quoted_proxy& operator=(const quoted_proxy&); // = deleted
|
||||
};
|
||||
|
||||
// abstract away difference between proxies with const or non-const basic_strings
|
||||
template <class Char, class Traits, class Alloc>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
basic_string_inserter_imp(std::basic_ostream<Char, Traits>& os,
|
||||
std::basic_string<Char, Traits, Alloc> const & string, Char escape, Char delim)
|
||||
{
|
||||
os << delim;
|
||||
typename std::basic_string<Char, Traits, Alloc>::const_iterator
|
||||
end_it = string.end();
|
||||
for (typename std::basic_string<Char, Traits, Alloc>::const_iterator
|
||||
it = string.begin();
|
||||
it != end_it;
|
||||
++it )
|
||||
{
|
||||
if (*it == delim || *it == escape)
|
||||
os << escape;
|
||||
os << *it;
|
||||
}
|
||||
os << delim;
|
||||
return os;
|
||||
}
|
||||
|
||||
// inserter for const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>& proxy)
|
||||
{
|
||||
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
|
||||
}
|
||||
|
||||
// inserter for non-const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||
{
|
||||
return basic_string_inserter_imp(os, proxy.string, proxy.escape, proxy.delim);
|
||||
}
|
||||
|
||||
// inserter for const C-string* proxies
|
||||
template <class Char, class Traits>
|
||||
std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const Char*, Char>& proxy)
|
||||
{
|
||||
os << proxy.delim;
|
||||
for (const Char* it = proxy.string;
|
||||
*it;
|
||||
++it )
|
||||
{
|
||||
if (*it == proxy.delim || *it == proxy.escape)
|
||||
os << proxy.escape;
|
||||
os << *it;
|
||||
}
|
||||
os << proxy.delim;
|
||||
return os;
|
||||
}
|
||||
|
||||
// extractor for non-const std::basic_string& proxies
|
||||
template <class Char, class Traits, class Alloc>
|
||||
std::basic_istream<Char, Traits>& operator>>(std::basic_istream<Char, Traits>& is,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>& proxy)
|
||||
{
|
||||
proxy.string.clear();
|
||||
Char c;
|
||||
is >> c;
|
||||
if (c != proxy.delim)
|
||||
{
|
||||
is.unget();
|
||||
is >> proxy.string;
|
||||
return is;
|
||||
}
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(is);
|
||||
is >> std::noskipws;
|
||||
for (;;)
|
||||
{
|
||||
is >> c;
|
||||
if (!is.good()) // cope with I/O errors or end-of-file
|
||||
break;
|
||||
if (c == proxy.escape)
|
||||
{
|
||||
is >> c;
|
||||
if (!is.good()) // cope with I/O errors or end-of-file
|
||||
break;
|
||||
}
|
||||
else if (c == proxy.delim)
|
||||
break;
|
||||
proxy.string += c;
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// manipulator implementation for const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||
{
|
||||
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> const &, Char>
|
||||
(s, escape, delim);
|
||||
}
|
||||
|
||||
// manipulator implementation for non-const std::basic_string&
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc> &, Char>
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape, Char delim)
|
||||
{
|
||||
return detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>&, Char>
|
||||
(s, escape, delim);
|
||||
}
|
||||
|
||||
// manipulator implementation for const C-string*
|
||||
template <class Char>
|
||||
inline detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape, Char delim)
|
||||
{
|
||||
return detail::quoted_proxy<const Char*, Char> (s, escape, delim);
|
||||
}
|
||||
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_IO_QUOTED_MANIP
|
@ -1,439 +1,485 @@
|
||||
// Boost io/ios_state.hpp header file --------------------------------------//
|
||||
|
||||
// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution
|
||||
// are subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
// See <http://www.boost.org/libs/io/> for the library's home page.
|
||||
/*
|
||||
Copyright 2002, 2005 Daryle Walker
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_IOS_STATE_HPP
|
||||
#define BOOST_IO_IOS_STATE_HPP
|
||||
|
||||
#include <boost/io_fwd.hpp> // self include
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <ios> // for std::ios_base, std::basic_ios, etc.
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/io_fwd.hpp>
|
||||
#include <ios>
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
#include <locale> // for std::locale
|
||||
#include <locale>
|
||||
#endif
|
||||
#include <ostream> // for std::basic_ostream
|
||||
#include <streambuf> // for std::basic_streambuf
|
||||
#include <string> // for std::char_traits
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
|
||||
|
||||
// Basic stream state saver class declarations -----------------------------//
|
||||
|
||||
class ios_flags_saver
|
||||
{
|
||||
class ios_flags_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef ::std::ios_base::fmtflags aspect_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef std::ios_base::fmtflags aspect_type;
|
||||
|
||||
explicit ios_flags_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.flags() )
|
||||
{}
|
||||
ios_flags_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.flags(a) )
|
||||
{}
|
||||
~ios_flags_saver()
|
||||
{ this->restore(); }
|
||||
explicit ios_flags_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.flags()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.flags( a_save_ ); }
|
||||
ios_flags_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.flags(a)) { }
|
||||
|
||||
~ios_flags_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.flags(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
|
||||
ios_flags_saver(const ios_flags_saver&);
|
||||
ios_flags_saver& operator=(const ios_flags_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
class ios_precision_saver
|
||||
{
|
||||
class ios_precision_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef ::std::streamsize aspect_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef std::streamsize aspect_type;
|
||||
|
||||
explicit ios_precision_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.precision() )
|
||||
{}
|
||||
ios_precision_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.precision(a) )
|
||||
{}
|
||||
~ios_precision_saver()
|
||||
{ this->restore(); }
|
||||
explicit ios_precision_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.precision()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.precision( a_save_ ); }
|
||||
ios_precision_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.precision(a)) { }
|
||||
|
||||
~ios_precision_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.precision(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
|
||||
ios_precision_saver(const ios_precision_saver&);
|
||||
ios_precision_saver& operator=(const ios_precision_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
class ios_width_saver
|
||||
{
|
||||
class ios_width_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef ::std::streamsize aspect_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef std::streamsize aspect_type;
|
||||
|
||||
explicit ios_width_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.width() )
|
||||
{}
|
||||
ios_width_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.width(a) )
|
||||
{}
|
||||
~ios_width_saver()
|
||||
{ this->restore(); }
|
||||
explicit ios_width_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.width()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.width( a_save_ ); }
|
||||
ios_width_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.width(a)) { }
|
||||
|
||||
~ios_width_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.width(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
ios_width_saver(const ios_width_saver&);
|
||||
ios_width_saver& operator=(const ios_width_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
|
||||
// Advanced stream state saver class template declarations -----------------//
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_iostate_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_iostate_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef ::std::ios_base::iostate aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::ios_base::iostate aspect_type;
|
||||
|
||||
explicit basic_ios_iostate_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.rdstate() )
|
||||
{}
|
||||
basic_ios_iostate_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.rdstate() )
|
||||
{ s.clear(a); }
|
||||
~basic_ios_iostate_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_iostate_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.rdstate()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.clear( a_save_ ); }
|
||||
basic_ios_iostate_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.rdstate()) {
|
||||
s.clear(a);
|
||||
}
|
||||
|
||||
~basic_ios_iostate_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.clear(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_iostate_saver(const basic_ios_iostate_saver&);
|
||||
basic_ios_iostate_saver& operator=(const basic_ios_iostate_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_exception_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_exception_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef ::std::ios_base::iostate aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::ios_base::iostate aspect_type;
|
||||
|
||||
explicit basic_ios_exception_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.exceptions() )
|
||||
{}
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
basic_ios_exception_saver( state_type &s, aspect_type a )
|
||||
#else
|
||||
basic_ios_exception_saver( state_type &s, aspect_type const &a )
|
||||
#endif
|
||||
: s_save_( s ), a_save_( s.exceptions() )
|
||||
{ s.exceptions(a); }
|
||||
~basic_ios_exception_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_exception_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.exceptions()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.exceptions( a_save_ ); }
|
||||
basic_ios_exception_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.exceptions()) {
|
||||
s.exceptions(a);
|
||||
}
|
||||
|
||||
~basic_ios_exception_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.exceptions(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_exception_saver(const basic_ios_exception_saver&);
|
||||
basic_ios_exception_saver& operator=(const basic_ios_exception_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_tie_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_tie_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef ::std::basic_ostream<Ch, Tr> * aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::basic_ostream<Ch, Tr>* aspect_type;
|
||||
|
||||
explicit basic_ios_tie_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.tie() )
|
||||
{}
|
||||
basic_ios_tie_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.tie(a) )
|
||||
{}
|
||||
~basic_ios_tie_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_tie_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.tie()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.tie( a_save_ ); }
|
||||
basic_ios_tie_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.tie(a)) { }
|
||||
|
||||
~basic_ios_tie_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.tie(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_tie_saver(const basic_ios_tie_saver&);
|
||||
basic_ios_tie_saver& operator=(const basic_ios_tie_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_rdbuf_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_rdbuf_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef ::std::basic_streambuf<Ch, Tr> * aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::basic_streambuf<Ch, Tr>* aspect_type;
|
||||
|
||||
explicit basic_ios_rdbuf_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.rdbuf() )
|
||||
{}
|
||||
basic_ios_rdbuf_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.rdbuf(a) )
|
||||
{}
|
||||
~basic_ios_rdbuf_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_rdbuf_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.rdbuf()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.rdbuf( a_save_ ); }
|
||||
basic_ios_rdbuf_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.rdbuf(a)) { }
|
||||
|
||||
~basic_ios_rdbuf_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.rdbuf(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_rdbuf_saver(const basic_ios_rdbuf_saver&);
|
||||
basic_ios_rdbuf_saver& operator=(const basic_ios_rdbuf_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_fill_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_fill_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef typename state_type::char_type aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef typename state_type::char_type aspect_type;
|
||||
|
||||
explicit basic_ios_fill_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.fill() )
|
||||
{}
|
||||
basic_ios_fill_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.fill(a) )
|
||||
{}
|
||||
~basic_ios_fill_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_fill_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.fill()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.fill( a_save_ ); }
|
||||
basic_ios_fill_saver(state_type& s, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.fill(a)) { }
|
||||
|
||||
~basic_ios_fill_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.fill(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_fill_saver(const basic_ios_fill_saver&);
|
||||
basic_ios_fill_saver& operator=(const basic_ios_fill_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_locale_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_locale_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef ::std::locale aspect_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::locale aspect_type;
|
||||
|
||||
explicit basic_ios_locale_saver( state_type &s )
|
||||
: s_save_( s ), a_save_( s.getloc() )
|
||||
{}
|
||||
basic_ios_locale_saver( state_type &s, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.imbue(a) )
|
||||
{}
|
||||
~basic_ios_locale_saver()
|
||||
{ this->restore(); }
|
||||
explicit basic_ios_locale_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a_save_(s.getloc()) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.imbue( a_save_ ); }
|
||||
basic_ios_locale_saver(state_type& s, const aspect_type& a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.imbue(a)) { }
|
||||
|
||||
~basic_ios_locale_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.imbue(a_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
basic_ios_locale_saver(const basic_ios_locale_saver&);
|
||||
basic_ios_locale_saver& operator=(const basic_ios_locale_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// User-defined stream state saver class declarations ----------------------//
|
||||
|
||||
class ios_iword_saver
|
||||
{
|
||||
class ios_iword_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef long aspect_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef long aspect_type;
|
||||
|
||||
explicit ios_iword_saver( state_type &s, index_type i )
|
||||
: s_save_( s ), a_save_( s.iword(i) ), i_save_( i )
|
||||
{}
|
||||
ios_iword_saver( state_type &s, index_type i, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.iword(i) ), i_save_( i )
|
||||
{ s.iword(i) = a; }
|
||||
~ios_iword_saver()
|
||||
{ this->restore(); }
|
||||
explicit ios_iword_saver(state_type& s, index_type i)
|
||||
: s_save_(s)
|
||||
, a_save_(s.iword(i))
|
||||
, i_save_(i) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.iword( i_save_ ) = a_save_; }
|
||||
ios_iword_saver(state_type& s, index_type i, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.iword(i))
|
||||
, i_save_(i) {
|
||||
s.iword(i) = a;
|
||||
}
|
||||
|
||||
~ios_iword_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.iword(i_save_) = a_save_;
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
index_type const i_save_;
|
||||
|
||||
ios_iword_saver(const ios_iword_saver&);
|
||||
ios_iword_saver& operator=(const ios_iword_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
index_type i_save_;
|
||||
};
|
||||
|
||||
class ios_pword_saver
|
||||
{
|
||||
class ios_pword_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef void * aspect_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef void* aspect_type;
|
||||
|
||||
explicit ios_pword_saver( state_type &s, index_type i )
|
||||
: s_save_( s ), a_save_( s.pword(i) ), i_save_( i )
|
||||
{}
|
||||
ios_pword_saver( state_type &s, index_type i, aspect_type const &a )
|
||||
: s_save_( s ), a_save_( s.pword(i) ), i_save_( i )
|
||||
{ s.pword(i) = a; }
|
||||
~ios_pword_saver()
|
||||
{ this->restore(); }
|
||||
explicit ios_pword_saver(state_type& s, index_type i)
|
||||
: s_save_(s)
|
||||
, a_save_(s.pword(i))
|
||||
, i_save_(i) { }
|
||||
|
||||
void restore()
|
||||
{ s_save_.pword( i_save_ ) = a_save_; }
|
||||
ios_pword_saver(state_type& s, index_type i, aspect_type a)
|
||||
: s_save_(s)
|
||||
, a_save_(s.pword(i))
|
||||
, i_save_(i) {
|
||||
s.pword(i) = a;
|
||||
}
|
||||
|
||||
~ios_pword_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore() {
|
||||
s_save_.pword(i_save_) = a_save_;
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
aspect_type const a_save_;
|
||||
index_type const i_save_;
|
||||
|
||||
ios_pword_saver(const ios_pword_saver&);
|
||||
ios_pword_saver operator=(const ios_pword_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
aspect_type a_save_;
|
||||
index_type i_save_;
|
||||
};
|
||||
|
||||
|
||||
// Combined stream state saver class (template) declarations ---------------//
|
||||
|
||||
class ios_base_all_saver
|
||||
{
|
||||
class ios_base_all_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef std::ios_base state_type;
|
||||
|
||||
explicit ios_base_all_saver( state_type &s )
|
||||
: s_save_( s ), a1_save_( s.flags() ), a2_save_( s.precision() )
|
||||
, a3_save_( s.width() )
|
||||
{}
|
||||
explicit ios_base_all_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a1_save_(s.flags())
|
||||
, a2_save_(s.precision())
|
||||
, a3_save_(s.width()) { }
|
||||
|
||||
~ios_base_all_saver()
|
||||
{ this->restore(); }
|
||||
~ios_base_all_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
s_save_.width( a3_save_ );
|
||||
s_save_.precision( a2_save_ );
|
||||
s_save_.flags( a1_save_ );
|
||||
void restore() {
|
||||
s_save_.width(a3_save_);
|
||||
s_save_.precision(a2_save_);
|
||||
s_save_.flags(a1_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
state_type::fmtflags const a1_save_;
|
||||
::std::streamsize const a2_save_;
|
||||
::std::streamsize const a3_save_;
|
||||
|
||||
ios_base_all_saver(const ios_base_all_saver&);
|
||||
ios_base_all_saver& operator=(const ios_base_all_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
state_type::fmtflags a1_save_;
|
||||
std::streamsize a2_save_;
|
||||
std::streamsize a3_save_;
|
||||
};
|
||||
|
||||
template < typename Ch, class Tr >
|
||||
class basic_ios_all_saver
|
||||
{
|
||||
template<class Ch, class Tr>
|
||||
class basic_ios_all_saver {
|
||||
public:
|
||||
typedef ::std::basic_ios<Ch, Tr> state_type;
|
||||
typedef std::basic_ios<Ch, Tr> state_type;
|
||||
|
||||
explicit basic_ios_all_saver( state_type &s )
|
||||
: s_save_( s ), a1_save_( s.flags() ), a2_save_( s.precision() )
|
||||
, a3_save_( s.width() ), a4_save_( s.rdstate() )
|
||||
, a5_save_( s.exceptions() ), a6_save_( s.tie() )
|
||||
, a7_save_( s.rdbuf() ), a8_save_( s.fill() )
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
, a9_save_( s.getloc() )
|
||||
#endif
|
||||
{}
|
||||
explicit basic_ios_all_saver(state_type& s)
|
||||
: s_save_(s)
|
||||
, a1_save_(s.flags())
|
||||
, a2_save_(s.precision())
|
||||
, a3_save_(s.width())
|
||||
, a4_save_(s.rdstate())
|
||||
, a5_save_(s.exceptions())
|
||||
, a6_save_(s.tie())
|
||||
, a7_save_(s.rdbuf())
|
||||
, a8_save_(s.fill())
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
, a9_save_(s.getloc())
|
||||
#endif
|
||||
{ }
|
||||
|
||||
~basic_ios_all_saver()
|
||||
{ this->restore(); }
|
||||
~basic_ios_all_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
s_save_.imbue( a9_save_ );
|
||||
#endif
|
||||
s_save_.fill( a8_save_ );
|
||||
s_save_.rdbuf( a7_save_ );
|
||||
s_save_.tie( a6_save_ );
|
||||
s_save_.exceptions( a5_save_ );
|
||||
s_save_.clear( a4_save_ );
|
||||
s_save_.width( a3_save_ );
|
||||
s_save_.precision( a2_save_ );
|
||||
s_save_.flags( a1_save_ );
|
||||
void restore() {
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
s_save_.imbue(a9_save_);
|
||||
#endif
|
||||
s_save_.fill(a8_save_);
|
||||
s_save_.rdbuf(a7_save_);
|
||||
s_save_.tie(a6_save_);
|
||||
s_save_.exceptions(a5_save_);
|
||||
s_save_.clear(a4_save_);
|
||||
s_save_.width(a3_save_);
|
||||
s_save_.precision(a2_save_);
|
||||
s_save_.flags(a1_save_);
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
typename state_type::fmtflags const a1_save_;
|
||||
::std::streamsize const a2_save_;
|
||||
::std::streamsize const a3_save_;
|
||||
typename state_type::iostate const a4_save_;
|
||||
typename state_type::iostate const a5_save_;
|
||||
::std::basic_ostream<Ch, Tr> * const a6_save_;
|
||||
::std::basic_streambuf<Ch, Tr> * const a7_save_;
|
||||
typename state_type::char_type const a8_save_;
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
::std::locale const a9_save_;
|
||||
#endif
|
||||
|
||||
basic_ios_all_saver(const basic_ios_all_saver&);
|
||||
basic_ios_all_saver& operator=(const basic_ios_all_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
typename state_type::fmtflags a1_save_;
|
||||
std::streamsize a2_save_;
|
||||
std::streamsize a3_save_;
|
||||
typename state_type::iostate a4_save_;
|
||||
typename state_type::iostate a5_save_;
|
||||
std::basic_ostream<Ch, Tr>* a6_save_;
|
||||
std::basic_streambuf<Ch, Tr>* a7_save_;
|
||||
typename state_type::char_type a8_save_;
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
std::locale a9_save_;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ios_all_word_saver
|
||||
{
|
||||
class ios_all_word_saver {
|
||||
public:
|
||||
typedef ::std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
typedef std::ios_base state_type;
|
||||
typedef int index_type;
|
||||
|
||||
ios_all_word_saver( state_type &s, index_type i )
|
||||
: s_save_( s ), i_save_( i ), a1_save_( s.iword(i) )
|
||||
, a2_save_( s.pword(i) )
|
||||
{}
|
||||
ios_all_word_saver(state_type& s, index_type i)
|
||||
: s_save_(s)
|
||||
, i_save_(i)
|
||||
, a1_save_(s.iword(i))
|
||||
, a2_save_(s.pword(i)) { }
|
||||
|
||||
~ios_all_word_saver()
|
||||
{ this->restore(); }
|
||||
~ios_all_word_saver() {
|
||||
this->restore();
|
||||
}
|
||||
|
||||
void restore()
|
||||
{
|
||||
s_save_.pword( i_save_ ) = a2_save_;
|
||||
s_save_.iword( i_save_ ) = a1_save_;
|
||||
void restore() {
|
||||
s_save_.pword(i_save_) = a2_save_;
|
||||
s_save_.iword(i_save_) = a1_save_;
|
||||
}
|
||||
|
||||
private:
|
||||
state_type & s_save_;
|
||||
index_type const i_save_;
|
||||
long const a1_save_;
|
||||
void * const a2_save_;
|
||||
|
||||
ios_all_word_saver(const ios_all_word_saver&);
|
||||
ios_all_word_saver& operator=(const ios_all_word_saver&);
|
||||
|
||||
state_type& s_save_;
|
||||
index_type i_save_;
|
||||
long a1_save_;
|
||||
void* a2_save_;
|
||||
};
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_IO_IOS_STATE_HPP
|
||||
#endif
|
||||
|
63
include/boost/io/nullstream.hpp
Normal file
63
include/boost/io/nullstream.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright 2021-2022 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_IO_NULLSTREAM_HPP
|
||||
#define BOOST_IO_NULLSTREAM_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT> >
|
||||
class basic_nullbuf
|
||||
: public std::basic_streambuf<CharT, Traits> {
|
||||
protected:
|
||||
typename Traits::int_type overflow(typename Traits::int_type c)
|
||||
BOOST_OVERRIDE {
|
||||
return Traits::not_eof(c);
|
||||
}
|
||||
|
||||
std::streamsize xsputn(const CharT*, std::streamsize n) BOOST_OVERRIDE {
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class CharT, class Traits>
|
||||
class nullbuf {
|
||||
public:
|
||||
boost::io::basic_nullbuf<CharT, Traits>* buf() {
|
||||
return &buf_;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::io::basic_nullbuf<CharT, Traits> buf_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class CharT, class Traits = std::char_traits<CharT> >
|
||||
class basic_onullstream
|
||||
: detail::nullbuf<CharT, Traits>
|
||||
, public std::basic_ostream<CharT, Traits> {
|
||||
public:
|
||||
basic_onullstream()
|
||||
: std::basic_ostream<CharT, Traits>(detail::nullbuf<CharT,
|
||||
Traits>::buf()) { }
|
||||
};
|
||||
|
||||
typedef basic_onullstream<char> onullstream;
|
||||
typedef basic_onullstream<wchar_t> wonullstream;
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
118
include/boost/io/ostream_joiner.hpp
Normal file
118
include/boost/io/ostream_joiner.hpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
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_IO_OSTREAM_JOINER_HPP
|
||||
#define BOOST_IO_OSTREAM_JOINER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_ADDRESSOF)
|
||||
template<class T>
|
||||
inline T*
|
||||
osj_address(T& o)
|
||||
{
|
||||
return std::addressof(o);
|
||||
}
|
||||
#else
|
||||
template<class T>
|
||||
inline T*
|
||||
osj_address(T& obj)
|
||||
{
|
||||
return &obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class Delim, class Char = char,
|
||||
class Traits = std::char_traits<Char> >
|
||||
class ostream_joiner {
|
||||
public:
|
||||
typedef Char char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef std::basic_ostream<Char, Traits> ostream_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
ostream_joiner(ostream_type& output, const Delim& delim)
|
||||
: output_(detail::osj_address(output))
|
||||
, delim_(delim)
|
||||
, first_(true) { }
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
ostream_joiner(ostream_type& output, Delim&& delim)
|
||||
: output_(detail::osj_address(output))
|
||||
, delim_(std::move(delim))
|
||||
, first_(true) { }
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
ostream_joiner& operator=(const T& value) {
|
||||
if (!first_) {
|
||||
*output_ << delim_;
|
||||
}
|
||||
first_ = false;
|
||||
*output_ << value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator*() BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator++() BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ostream_joiner& operator++(int) BOOST_NOEXCEPT {
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_type* output_;
|
||||
Delim delim_;
|
||||
bool first_;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
||||
template<class Char, class Traits, class Delim>
|
||||
inline ostream_joiner<typename std::decay<Delim>::type, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output, Delim&& delim)
|
||||
{
|
||||
return ostream_joiner<typename std::decay<Delim>::type, Char,
|
||||
Traits>(output, std::forward<Delim>(delim));
|
||||
}
|
||||
#else
|
||||
template<class Char, class Traits, class Delim>
|
||||
inline ostream_joiner<Delim, Char, Traits>
|
||||
make_ostream_joiner(std::basic_ostream<Char, Traits>& output,
|
||||
const Delim& delim)
|
||||
{
|
||||
return ostream_joiner<Delim, Char, Traits>(output, delim);
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
50
include/boost/io/ostream_put.hpp
Normal file
50
include/boost/io/ostream_put.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
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_IO_OSTREAM_PUT_HPP
|
||||
#define BOOST_IO_OSTREAM_PUT_HPP
|
||||
|
||||
#include <boost/io/detail/buffer_fill.hpp>
|
||||
#include <boost/io/detail/ostream_guard.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os, const charT* data,
|
||||
std::size_t size)
|
||||
{
|
||||
typedef std::basic_ostream<charT, traits> stream;
|
||||
detail::ostream_guard<charT, traits> guard(os);
|
||||
typename stream::sentry entry(os);
|
||||
if (entry) {
|
||||
std::basic_streambuf<charT, traits>& buf = *os.rdbuf();
|
||||
std::size_t width = static_cast<std::size_t>(os.width());
|
||||
if (width <= size) {
|
||||
if (static_cast<std::size_t>(buf.sputn(data, size)) != size) {
|
||||
return os;
|
||||
}
|
||||
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||
if (static_cast<std::size_t>(buf.sputn(data, size)) != size ||
|
||||
!detail::buffer_fill(buf, os.fill(), width - size)) {
|
||||
return os;
|
||||
}
|
||||
} else if (!detail::buffer_fill(buf, os.fill(), width - size) ||
|
||||
static_cast<std::size_t>(buf.sputn(data, size)) != size) {
|
||||
return os;
|
||||
}
|
||||
os.width(0);
|
||||
}
|
||||
guard.release();
|
||||
return os;
|
||||
}
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
217
include/boost/io/quoted.hpp
Normal file
217
include/boost/io/quoted.hpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright 2010 Beman Dawes
|
||||
|
||||
Copyright 2019-2020 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_IO_QUOTED_HPP
|
||||
#define BOOST_IO_QUOTED_HPP
|
||||
|
||||
#include <boost/io/detail/buffer_fill.hpp>
|
||||
#include <boost/io/detail/ostream_guard.hpp>
|
||||
#include <boost/io/ios_state.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class String, class Char>
|
||||
struct quoted_proxy {
|
||||
String string;
|
||||
Char escape;
|
||||
Char delim;
|
||||
};
|
||||
|
||||
template<class Char>
|
||||
struct quoted_state {
|
||||
const Char* string;
|
||||
std::size_t size;
|
||||
std::size_t count;
|
||||
};
|
||||
|
||||
template<class Char>
|
||||
inline quoted_state<Char>
|
||||
quoted_start(const Char* string, Char escape, Char delim)
|
||||
{
|
||||
const Char* end = string;
|
||||
std::size_t count = 2;
|
||||
for (Char ch; (ch = *end) != 0; ++end) {
|
||||
count += 1 + (ch == escape || ch == delim);
|
||||
}
|
||||
quoted_state<Char> state = { string,
|
||||
static_cast<std::size_t>(end - string), count };
|
||||
return state;
|
||||
}
|
||||
|
||||
template<class Char, class String>
|
||||
inline quoted_state<Char>
|
||||
quoted_start(const String* string, Char escape, Char delim)
|
||||
{
|
||||
const Char* begin = string->data();
|
||||
std::size_t size = string->size();
|
||||
std::size_t count = 2;
|
||||
for (const Char *it = begin, *end = begin + size; it != end; ++it) {
|
||||
Char ch = *it;
|
||||
count += 1 + (ch == escape || ch == delim);
|
||||
}
|
||||
quoted_state<Char> state = { begin, size, count };
|
||||
return state;
|
||||
}
|
||||
|
||||
template<class Char, class Traits>
|
||||
inline bool
|
||||
quoted_put(std::basic_streambuf<Char, Traits>& buf, const Char* string,
|
||||
std::size_t size, std::size_t count, Char escape, Char delim)
|
||||
{
|
||||
if (buf.sputc(delim) == Traits::eof()) {
|
||||
return false;
|
||||
}
|
||||
if (size == count) {
|
||||
if (static_cast<std::size_t>(buf.sputn(string, size)) != size) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
for (const Char* end = string + size; string != end; ++string) {
|
||||
Char ch = *string;
|
||||
if ((ch == escape || ch == delim) &&
|
||||
buf.sputc(escape) == Traits::eof()) {
|
||||
return false;
|
||||
}
|
||||
if (buf.sputc(ch) == Traits::eof()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.sputc(delim) != Traits::eof();
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class String>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
quoted_out(std::basic_ostream<Char, Traits>& os, String* string, Char escape,
|
||||
Char delim)
|
||||
{
|
||||
typedef std::basic_ostream<Char, Traits> stream;
|
||||
ostream_guard<Char, Traits> guard(os);
|
||||
typename stream::sentry entry(os);
|
||||
if (entry) {
|
||||
quoted_state<Char> state = boost::io::detail::quoted_start(string,
|
||||
escape, delim);
|
||||
std::basic_streambuf<Char, Traits>& buf = *os.rdbuf();
|
||||
std::size_t width = static_cast<std::size_t>(os.width());
|
||||
if (width <= state.count) {
|
||||
if (!boost::io::detail::quoted_put(buf, state.string, state.size,
|
||||
state.count, escape, delim)) {
|
||||
return os;
|
||||
}
|
||||
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||
if (!boost::io::detail::quoted_put(buf, state.string, state.size,
|
||||
state.count, escape, delim) ||
|
||||
!boost::io::detail::buffer_fill(buf, os.fill(),
|
||||
width - state.count)) {
|
||||
return os;
|
||||
}
|
||||
} else if (!boost::io::detail::buffer_fill(buf, os.fill(),
|
||||
width - state.count) ||
|
||||
!boost::io::detail::quoted_put(buf, state.string, state.size,
|
||||
state.count, escape, delim)) {
|
||||
return os;
|
||||
}
|
||||
os.width(0);
|
||||
}
|
||||
guard.release();
|
||||
return os;
|
||||
}
|
||||
|
||||
template<class Char, class Traits>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const Char*, Char>& proxy)
|
||||
{
|
||||
return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,
|
||||
proxy.delim);
|
||||
}
|
||||
|
||||
template <class Char, class Traits, class Alloc>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,
|
||||
Char>& proxy)
|
||||
{
|
||||
return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,
|
||||
proxy.delim);
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline std::basic_ostream<Char, Traits>&
|
||||
operator<<(std::basic_ostream<Char, Traits>& os,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy)
|
||||
{
|
||||
return boost::io::detail::quoted_out(os, proxy.string, proxy.escape,
|
||||
proxy.delim);
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline std::basic_istream<Char, Traits>&
|
||||
operator>>(std::basic_istream<Char, Traits>& is,
|
||||
const quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>& proxy)
|
||||
{
|
||||
Char ch;
|
||||
if (!(is >> ch)) {
|
||||
return is;
|
||||
}
|
||||
if (ch != proxy.delim) {
|
||||
is.unget();
|
||||
return is >> *proxy.string;
|
||||
}
|
||||
{
|
||||
boost::io::ios_flags_saver ifs(is);
|
||||
std::noskipws(is);
|
||||
proxy.string->clear();
|
||||
while ((is >> ch) && ch != proxy.delim) {
|
||||
if (ch == proxy.escape && !(is >> ch)) {
|
||||
break;
|
||||
}
|
||||
proxy.string->push_back(ch);
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
} /* detail */
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,
|
||||
Char>
|
||||
quoted(const std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',
|
||||
Char delim='\"')
|
||||
{
|
||||
detail::quoted_proxy<const std::basic_string<Char, Traits, Alloc>*,
|
||||
Char> proxy = { &s, escape, delim };
|
||||
return proxy;
|
||||
}
|
||||
|
||||
template<class Char, class Traits, class Alloc>
|
||||
inline detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*, Char>
|
||||
quoted(std::basic_string<Char, Traits, Alloc>& s, Char escape='\\',
|
||||
Char delim='\"')
|
||||
{
|
||||
detail::quoted_proxy<std::basic_string<Char, Traits, Alloc>*,
|
||||
Char> proxy = { &s, escape, delim };
|
||||
return proxy;
|
||||
}
|
||||
|
||||
template<class Char>
|
||||
inline detail::quoted_proxy<const Char*, Char>
|
||||
quoted(const Char* s, Char escape='\\', Char delim='\"')
|
||||
{
|
||||
detail::quoted_proxy<const Char*, Char> proxy = { s, escape, delim };
|
||||
return proxy;
|
||||
}
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
@ -1,67 +1,63 @@
|
||||
// Boost io_fwd.hpp header file --------------------------------------------//
|
||||
|
||||
// Copyright 2002 Daryle Walker. Use, modification, and distribution are subject
|
||||
// to the Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
// See <http://www.boost.org/libs/io/> for the library's home page.
|
||||
/*
|
||||
Copyright 2002 Daryle Walker
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_FWD_HPP
|
||||
#define BOOST_IO_FWD_HPP
|
||||
|
||||
#include <iosfwd> // for std::char_traits (declaration)
|
||||
#include <iosfwd>
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
|
||||
|
||||
// From <boost/io/ios_state.hpp> -------------------------------------------//
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
class ios_flags_saver;
|
||||
class ios_precision_saver;
|
||||
class ios_width_saver;
|
||||
class ios_base_all_saver;
|
||||
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_iostate_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_exception_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_tie_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_rdbuf_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_fill_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_locale_saver;
|
||||
template < typename Ch, class Tr = ::std::char_traits<Ch> >
|
||||
class basic_ios_all_saver;
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_iostate_saver;
|
||||
|
||||
typedef basic_ios_iostate_saver<char> ios_iostate_saver;
|
||||
typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
|
||||
typedef basic_ios_exception_saver<char> ios_exception_saver;
|
||||
typedef basic_ios_exception_saver<wchar_t> wios_exception_saver;
|
||||
typedef basic_ios_tie_saver<char> ios_tie_saver;
|
||||
typedef basic_ios_tie_saver<wchar_t> wios_tie_saver;
|
||||
typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
|
||||
typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
|
||||
typedef basic_ios_fill_saver<char> ios_fill_saver;
|
||||
typedef basic_ios_fill_saver<wchar_t> wios_fill_saver;
|
||||
typedef basic_ios_locale_saver<char> ios_locale_saver;
|
||||
typedef basic_ios_locale_saver<wchar_t> wios_locale_saver;
|
||||
typedef basic_ios_all_saver<char> ios_all_saver;
|
||||
typedef basic_ios_all_saver<wchar_t> wios_all_saver;
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_exception_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_tie_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_rdbuf_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_fill_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_locale_saver;
|
||||
|
||||
template<class Ch, class Tr = std::char_traits<Ch> >
|
||||
class basic_ios_all_saver;
|
||||
|
||||
typedef basic_ios_iostate_saver<char> ios_iostate_saver;
|
||||
typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver;
|
||||
typedef basic_ios_exception_saver<char> ios_exception_saver;
|
||||
typedef basic_ios_exception_saver<wchar_t> wios_exception_saver;
|
||||
typedef basic_ios_tie_saver<char> ios_tie_saver;
|
||||
typedef basic_ios_tie_saver<wchar_t> wios_tie_saver;
|
||||
typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver;
|
||||
typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver;
|
||||
typedef basic_ios_fill_saver<char> ios_fill_saver;
|
||||
typedef basic_ios_fill_saver<wchar_t> wios_fill_saver;
|
||||
typedef basic_ios_locale_saver<char> ios_locale_saver;
|
||||
typedef basic_ios_locale_saver<wchar_t> wios_locale_saver;
|
||||
typedef basic_ios_all_saver<char> ios_all_saver;
|
||||
typedef basic_ios_all_saver<wchar_t> wios_all_saver;
|
||||
|
||||
class ios_iword_saver;
|
||||
class ios_pword_saver;
|
||||
class ios_all_word_saver;
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
} // namespace io
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_IO_FWD_HPP
|
||||
#endif
|
||||
|
21
index.html
21
index.html
@ -1,14 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright Beman Dawes, 2001
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=doc/index.html">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=doc/html/io.html">
|
||||
<title>IO</title>
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="doc/index.html">doc/index.html</a>. <hr>
|
||||
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
|
||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
Redirecting you to <a href="doc/html/io.html">IO</a>.
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -1,15 +1,18 @@
|
||||
{
|
||||
"key": "io",
|
||||
"name": "IO State Savers",
|
||||
"name": "IO",
|
||||
"authors": [
|
||||
"Daryle Walker"
|
||||
"Daryle Walker",
|
||||
"Beman Dawes",
|
||||
"Glen Fernandes"
|
||||
],
|
||||
"description": "The I/O sub-library of Boost helps segregate the large number of Boost headers. This sub-library should contain various items to use with/for the standard I/O library.",
|
||||
"documentation": "doc/ios_state.html",
|
||||
"description": "Utilities for the standard I/O library.",
|
||||
"documentation": "doc/html/io.html",
|
||||
"category": [
|
||||
"IO"
|
||||
],
|
||||
"maintainers": [
|
||||
"Daryle Walker <darylew -at- hotmail.com>"
|
||||
]
|
||||
"Glen Fernandes <glenjofe -at- gmail.com>"
|
||||
],
|
||||
"cxxstd": "03"
|
||||
}
|
||||
|
20
test/Jamfile
Normal file
20
test/Jamfile
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright 2003 Daryle Walker
|
||||
#
|
||||
# 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)
|
||||
|
||||
import testing ;
|
||||
|
||||
project : requirements <warnings>pedantic <warnings-as-errors>on ;
|
||||
|
||||
run ios_state_unit_test.cpp ;
|
||||
run ios_state_test.cpp ;
|
||||
run quoted_test.cpp ;
|
||||
run quoted_fill_test.cpp ;
|
||||
run ostream_joiner_test.cpp ;
|
||||
run make_ostream_joiner_test.cpp ;
|
||||
run ostream_put_test.cpp ;
|
||||
run nullstream_test.cpp ;
|
@ -1,26 +0,0 @@
|
||||
# Boost.IO Library test Jamfile
|
||||
#
|
||||
# Copyright 2003 Daryle Walker. Use, modification, and distribution
|
||||
# are subject to the Boost Software License, Version 1.0. (See
|
||||
# accompanying file LICENSE_1_0.txt or a copy at
|
||||
# <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
#
|
||||
# See <http://www.boost.org/libs/io/> for the library's home page.
|
||||
|
||||
test-suite "io"
|
||||
: [ run ios_state_unit_test.cpp
|
||||
../../../libs/test/build//boost_unit_test_framework/<link>static
|
||||
: # args
|
||||
: # input files
|
||||
# : std::locale-support
|
||||
]
|
||||
|
||||
[ run ios_state_test.cpp
|
||||
../../../libs/test/build//boost_test_exec_monitor/<link>static
|
||||
: # args
|
||||
: # input files
|
||||
# : std::locale-support
|
||||
]
|
||||
|
||||
[ run quoted_manip_test.cpp ]
|
||||
;
|
@ -1,267 +1,171 @@
|
||||
// Boost ios_state_test.cpp test file --------------------------------------//
|
||||
/*
|
||||
Copyright 2002, 2003 Daryle Walker
|
||||
|
||||
// Copyright 2002, 2003 Daryle Walker. Use, modification, and distribution are
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
|
||||
// See <http://www.boost.org/libs/io/> for the library's home page.
|
||||
|
||||
// Revision History
|
||||
// 15 Jun 2003 Adjust to changes in Boost.Test (Daryle Walker)
|
||||
// 26 Feb 2002 Initial version (Daryle Walker)
|
||||
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/io/ios_state.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/test/minimal.hpp> // main, BOOST_CHECK, etc.
|
||||
|
||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
||||
#include <boost/io/ios_state.hpp> // for boost::io::ios_flags_saver, etc.
|
||||
|
||||
#include <cstddef> // for std::size_t
|
||||
#include <iomanip> // for std::setw
|
||||
#include <ios> // for std::ios_base, std::streamsize, etc.
|
||||
#include <iostream> // for std::cout, etc.
|
||||
#include <istream> // for std::istream
|
||||
#include <locale> // for std::numpunct, std::locale
|
||||
#include <ostream> // for std::endl, std::ostream
|
||||
#include <streambuf> // for std::streambuf
|
||||
#include <string> // for std::string
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <istream>
|
||||
#include <locale>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
|
||||
// Facet with the bool names spelled backwards
|
||||
class backward_bool_names
|
||||
: public std::numpunct<char>
|
||||
{
|
||||
typedef std::numpunct<char> base_type;
|
||||
: public std::numpunct<char> {
|
||||
typedef std::numpunct<char> base_type;
|
||||
|
||||
public:
|
||||
explicit backward_bool_names( std::size_t refs = 0 )
|
||||
: base_type( refs )
|
||||
{}
|
||||
explicit backward_bool_names(std::size_t refs = 0)
|
||||
: base_type( refs ) { }
|
||||
|
||||
protected:
|
||||
virtual ~backward_bool_names() {}
|
||||
~backward_bool_names() { }
|
||||
|
||||
virtual base_type::string_type do_truename() const
|
||||
{ return "eurt"; }
|
||||
virtual base_type::string_type do_falsename() const
|
||||
{ return "eslaf"; }
|
||||
base_type::string_type do_truename() const {
|
||||
return "eurt";
|
||||
}
|
||||
|
||||
base_type::string_type do_falsename() const {
|
||||
return "eslaf";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Index to test custom storage
|
||||
int const my_index = std::ios_base::xalloc();
|
||||
|
||||
// Test data
|
||||
char const test_string[] = "Hello world";
|
||||
int const test_num1 = -16;
|
||||
double const test_num2 = 34.5678901234;
|
||||
bool const test_bool = true;
|
||||
|
||||
|
||||
// Function prototypes
|
||||
void saver_tests_1( std::istream &input, std::ostream &output,
|
||||
std::ostream &err );
|
||||
void saver_tests_2( std::istream &input, std::ostream &output,
|
||||
std::ostream &err );
|
||||
|
||||
|
||||
// Test program
|
||||
int
|
||||
test_main
|
||||
(
|
||||
int , // "argc" is unused
|
||||
char * [] // "argv" is unused
|
||||
)
|
||||
void saver_tests_1(int index,
|
||||
std::istream& input,
|
||||
std::ostream& output,
|
||||
std::ostream& err)
|
||||
{
|
||||
using std::cout;
|
||||
using std::ios_base;
|
||||
using std::streamsize;
|
||||
using std::cin;
|
||||
|
||||
cout << "The original data is:\n";
|
||||
cout << '\t' << test_string << '\n';
|
||||
cout << '\t' << test_num1 << '\n';
|
||||
cout << '\t' << test_num2 << '\n';
|
||||
cout << '\t' << std::boolalpha << test_bool << std::endl;
|
||||
|
||||
// Save states for comparison later
|
||||
ios_base::fmtflags const cout_flags = cout.flags();
|
||||
streamsize const cout_precision = cout.precision();
|
||||
streamsize const cout_width = cout.width();
|
||||
ios_base::iostate const cout_iostate = cout.rdstate();
|
||||
ios_base::iostate const cout_exceptions = cout.exceptions();
|
||||
std::ostream * const cin_tie = cin.tie();
|
||||
std::streambuf * const cout_sb = cout.rdbuf();
|
||||
char const cout_fill = cout.fill();
|
||||
std::locale const cout_locale = cout.getloc();
|
||||
|
||||
cout.iword( my_index ) = 42L;
|
||||
cout.pword( my_index ) = &cin;
|
||||
|
||||
// Run saver tests with changing separate from saving
|
||||
saver_tests_1( cin, cout, std::cerr );
|
||||
|
||||
// Check if states are back to normal
|
||||
BOOST_CHECK( &cin == cout.pword(my_index) );
|
||||
BOOST_CHECK( 42L == cout.iword(my_index) );
|
||||
BOOST_CHECK( cout_locale == cout.getloc() );
|
||||
BOOST_CHECK( cout_fill == cout.fill() );
|
||||
BOOST_CHECK( cout_sb == cout.rdbuf() );
|
||||
BOOST_CHECK( cin_tie == cin.tie() );
|
||||
BOOST_CHECK( cout_exceptions == cout.exceptions() );
|
||||
BOOST_CHECK( cout_iostate == cout.rdstate() );
|
||||
BOOST_CHECK( cout_width == cout.width() );
|
||||
BOOST_CHECK( cout_precision == cout.precision() );
|
||||
BOOST_CHECK( cout_flags == cout.flags() );
|
||||
|
||||
// Run saver tests with combined saving and changing
|
||||
saver_tests_2( cin, cout, std::cerr );
|
||||
|
||||
// Check if states are back to normal
|
||||
BOOST_CHECK( &cin == cout.pword(my_index) );
|
||||
BOOST_CHECK( 42L == cout.iword(my_index) );
|
||||
BOOST_CHECK( cout_locale == cout.getloc() );
|
||||
BOOST_CHECK( cout_fill == cout.fill() );
|
||||
BOOST_CHECK( cout_sb == cout.rdbuf() );
|
||||
BOOST_CHECK( cin_tie == cin.tie() );
|
||||
BOOST_CHECK( cout_exceptions == cout.exceptions() );
|
||||
BOOST_CHECK( cout_iostate == cout.rdstate() );
|
||||
BOOST_CHECK( cout_width == cout.width() );
|
||||
BOOST_CHECK( cout_precision == cout.precision() );
|
||||
BOOST_CHECK( cout_flags == cout.flags() );
|
||||
|
||||
return boost::exit_success;
|
||||
}
|
||||
|
||||
// Save, change, and restore stream properties
|
||||
void
|
||||
saver_tests_1
|
||||
(
|
||||
std::istream & input,
|
||||
std::ostream & output,
|
||||
std::ostream & err
|
||||
)
|
||||
{
|
||||
using std::locale;
|
||||
using std::ios_base;
|
||||
using std::setw;
|
||||
|
||||
boost::io::ios_flags_saver const ifls( output );
|
||||
boost::io::ios_precision_saver const iprs( output );
|
||||
boost::io::ios_width_saver const iws( output );
|
||||
boost::io::ios_tie_saver const its( input );
|
||||
boost::io::ios_rdbuf_saver const irs( output );
|
||||
boost::io::ios_fill_saver const ifis( output );
|
||||
boost::io::ios_locale_saver const ils( output );
|
||||
boost::io::ios_iword_saver const iis( output, my_index );
|
||||
boost::io::ios_pword_saver const ipws( output, my_index );
|
||||
|
||||
locale loc( locale::classic(), new backward_bool_names );
|
||||
|
||||
input.tie( &err );
|
||||
output.rdbuf( err.rdbuf() );
|
||||
output.iword( my_index ) = 69L;
|
||||
output.pword( my_index ) = &err;
|
||||
|
||||
output << "The data is (again):\n";
|
||||
output.setf( ios_base::showpos | ios_base::boolalpha );
|
||||
output.setf( ios_base::internal, ios_base::adjustfield );
|
||||
output.fill( '@' );
|
||||
boost::io::ios_flags_saver ifls(output);
|
||||
boost::io::ios_precision_saver iprs(output);
|
||||
boost::io::ios_width_saver iws(output);
|
||||
boost::io::ios_tie_saver its(input);
|
||||
boost::io::ios_rdbuf_saver irs(output);
|
||||
boost::io::ios_fill_saver ifis(output);
|
||||
boost::io::ios_locale_saver ils(output);
|
||||
boost::io::ios_iword_saver iis(output, index);
|
||||
boost::io::ios_pword_saver ipws(output, index);
|
||||
std::locale loc(std::locale::classic(), new backward_bool_names);
|
||||
input.tie(&err);
|
||||
output.rdbuf(err.rdbuf());
|
||||
output.iword(index) = 69L;
|
||||
output.pword(index) = &err;
|
||||
output.setf(std::ios_base::showpos | std::ios_base::boolalpha);
|
||||
output.setf(std::ios_base::internal, std::ios_base::adjustfield);
|
||||
output.fill('@');
|
||||
output.precision( 9 );
|
||||
output << '\t' << test_string << '\n';
|
||||
output << '\t' << setw( 10 ) << test_num1 << '\n';
|
||||
output << '\t' << setw( 15 ) << test_num2 << '\n';
|
||||
output.imbue( loc );
|
||||
output << '\t' << test_bool << '\n';
|
||||
|
||||
BOOST_CHECK( &err == output.pword(my_index) );
|
||||
BOOST_CHECK( 69L == output.iword(my_index) );
|
||||
|
||||
try
|
||||
{
|
||||
boost::io::ios_exception_saver const ies( output );
|
||||
boost::io::ios_iostate_saver const iis( output );
|
||||
|
||||
output.exceptions( ios_base::eofbit | ios_base::badbit );
|
||||
output.setstate( ios_base::eofbit );
|
||||
BOOST_ERROR( "previous line should have thrown" );
|
||||
}
|
||||
output << "Hello world";
|
||||
output << std::setw(10) << -16;
|
||||
output << std::setw(15) << 34.5678901234;
|
||||
output.imbue(loc);
|
||||
output << true;
|
||||
BOOST_TEST(&err == output.pword(index));
|
||||
BOOST_TEST(69L == output.iword(index));
|
||||
try {
|
||||
boost::io::ios_exception_saver ies(output);
|
||||
boost::io::ios_iostate_saver ias(output);
|
||||
output.exceptions(std::ios_base::eofbit | std::ios_base::badbit);
|
||||
output.setstate(std::ios_base::eofbit);
|
||||
BOOST_ERROR("previous line should have thrown");
|
||||
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
|
||||
catch ( std::exception &f )
|
||||
} catch (std::exception&) {
|
||||
#else
|
||||
catch ( ios_base::failure &f )
|
||||
} catch (std::ios_base::failure&) {
|
||||
#endif
|
||||
{
|
||||
err << "Got the expected I/O failure: \"" << f.what() << "\".\n";
|
||||
BOOST_CHECK( output.exceptions() == ios_base::goodbit );
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
err << "Got an unknown error when doing exception test!\n";
|
||||
throw;
|
||||
BOOST_TEST(output.exceptions() == std::ios_base::goodbit );
|
||||
}
|
||||
}
|
||||
|
||||
// Save & change and restore stream properties
|
||||
void
|
||||
saver_tests_2
|
||||
(
|
||||
std::istream & input,
|
||||
std::ostream & output,
|
||||
std::ostream & err
|
||||
)
|
||||
void saver_tests_2(int index,
|
||||
std::istream& input,
|
||||
std::ostream& output,
|
||||
std::ostream& err)
|
||||
{
|
||||
using std::locale;
|
||||
using std::ios_base;
|
||||
|
||||
boost::io::ios_tie_saver const its( input, &err );
|
||||
boost::io::ios_rdbuf_saver const irs( output, err.rdbuf() );
|
||||
boost::io::ios_iword_saver const iis( output, my_index, 69L );
|
||||
boost::io::ios_pword_saver const ipws( output, my_index, &err );
|
||||
output << "The data is (a third time; adding the numbers):\n";
|
||||
|
||||
boost::io::ios_flags_saver const ifls( output, (output.flags()
|
||||
& ~ios_base::adjustfield) | ios_base::showpos | ios_base::boolalpha
|
||||
| (ios_base::internal & ios_base::adjustfield) );
|
||||
boost::io::ios_precision_saver const iprs( output, 9 );
|
||||
boost::io::ios_fill_saver const ifis( output, '@' );
|
||||
output << '\t' << test_string << '\n';
|
||||
|
||||
boost::io::ios_width_saver const iws( output, 12 );
|
||||
output.put( '\t' );
|
||||
output << test_num1 + test_num2;
|
||||
output.put( '\n' );
|
||||
|
||||
locale loc( locale::classic(),
|
||||
new backward_bool_names );
|
||||
boost::io::ios_locale_saver const ils( output, loc );
|
||||
output << '\t' << test_bool << '\n';
|
||||
|
||||
BOOST_CHECK( &err == output.pword(my_index) );
|
||||
BOOST_CHECK( 69L == output.iword(my_index) );
|
||||
|
||||
try
|
||||
{
|
||||
boost::io::ios_exception_saver const ies( output, ios_base::eofbit );
|
||||
boost::io::ios_iostate_saver const iis( output, output.rdstate()
|
||||
| ios_base::eofbit );
|
||||
|
||||
BOOST_ERROR( "previous line should have thrown" );
|
||||
}
|
||||
boost::io::ios_tie_saver its(input, &err);
|
||||
boost::io::ios_rdbuf_saver irs(output, err.rdbuf());
|
||||
boost::io::ios_iword_saver iis(output, index, 69L);
|
||||
boost::io::ios_pword_saver ipws(output, index, &err);
|
||||
boost::io::ios_flags_saver ifls(output,
|
||||
(output.flags() & ~std::ios_base::adjustfield) |
|
||||
std::ios_base::showpos |
|
||||
std::ios_base::boolalpha |
|
||||
(std::ios_base::internal & std::ios_base::adjustfield));
|
||||
boost::io::ios_precision_saver iprs(output, 9);
|
||||
boost::io::ios_fill_saver ifis(output, '@');
|
||||
output << "Hello world";
|
||||
boost::io::ios_width_saver iws(output, 12);
|
||||
output << -16 + 34.5678901234;
|
||||
std::locale loc(std::locale::classic(), new backward_bool_names);
|
||||
boost::io::ios_locale_saver ils(output, loc);
|
||||
output << true;
|
||||
BOOST_TEST(&err == output.pword(index));
|
||||
BOOST_TEST(69L == output.iword(index));
|
||||
try {
|
||||
boost::io::ios_exception_saver ies(output, std::ios_base::eofbit);
|
||||
boost::io::ios_iostate_saver ias(output,
|
||||
output.rdstate() | std::ios_base::eofbit );
|
||||
BOOST_ERROR("previous line should have thrown");
|
||||
#if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB))
|
||||
catch ( std::exception &f )
|
||||
} catch (std::exception&) {
|
||||
#else
|
||||
catch ( ios_base::failure &f )
|
||||
} catch (std::ios_base::failure&) {
|
||||
#endif
|
||||
{
|
||||
err << "Got the expected I/O failure: \"" << f.what() << "\".\n";
|
||||
BOOST_CHECK( output.exceptions() == ios_base::goodbit );
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
err << "Got an unknown error when doing exception test!\n";
|
||||
throw;
|
||||
BOOST_TEST(output.exceptions() == std::ios_base::goodbit);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int index = std::ios_base::xalloc();
|
||||
std::ostringstream out;
|
||||
std::ostringstream err;
|
||||
std::istringstream in;
|
||||
std::ios_base::fmtflags out_flags = out.flags();
|
||||
std::streamsize out_precision = out.precision();
|
||||
std::streamsize out_width = out.width();
|
||||
std::ios_base::iostate out_iostate = out.rdstate();
|
||||
std::ios_base::iostate out_exceptions = out.exceptions();
|
||||
std::ostream* in_tie = in.tie();
|
||||
std::streambuf* out_sb = out.rdbuf();
|
||||
char out_fill = out.fill();
|
||||
std::locale out_locale = out.getloc();
|
||||
out.iword(index) = 42L;
|
||||
out.pword(index) = ∈
|
||||
saver_tests_1(index, in, out, err);
|
||||
BOOST_TEST(&in == out.pword(index));
|
||||
BOOST_TEST(42L == out.iword(index));
|
||||
BOOST_TEST(out_locale == out.getloc());
|
||||
BOOST_TEST(out_fill == out.fill());
|
||||
BOOST_TEST(out_sb == out.rdbuf());
|
||||
BOOST_TEST(in_tie == in.tie());
|
||||
BOOST_TEST(out_exceptions == out.exceptions());
|
||||
BOOST_TEST(out_iostate == out.rdstate());
|
||||
BOOST_TEST(out_width == out.width());
|
||||
BOOST_TEST(out_precision == out.precision());
|
||||
BOOST_TEST(out_flags == out.flags());
|
||||
saver_tests_2(index, in, out, err);
|
||||
BOOST_TEST(&in == out.pword(index));
|
||||
BOOST_TEST(42L == out.iword(index));
|
||||
BOOST_TEST(out_locale == out.getloc());
|
||||
BOOST_TEST(out_fill == out.fill());
|
||||
BOOST_TEST(out_sb == out.rdbuf());
|
||||
BOOST_TEST(in_tie == in.tie());
|
||||
BOOST_TEST(out_exceptions == out.exceptions());
|
||||
BOOST_TEST(out_iostate == out.rdstate());
|
||||
BOOST_TEST(out_width == out.width());
|
||||
BOOST_TEST(out_precision == out.precision());
|
||||
BOOST_TEST(out_flags == out.flags());
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
21
test/make_ostream_joiner_test.cpp
Normal file
21
test/make_ostream_joiner_test.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
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/io/ostream_joiner.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <sstream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<char> j = boost::io::make_ostream_joiner(o, ',');
|
||||
*j++ = 1;
|
||||
*j++ = '2';
|
||||
*j++ = "3";
|
||||
BOOST_TEST_EQ(o.str(), "1,2,3");
|
||||
return boost::report_errors();
|
||||
}
|
28
test/nullstream_test.cpp
Normal file
28
test/nullstream_test.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright 2021 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/io/nullstream.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
boost::io::onullstream s;
|
||||
s << "abc";
|
||||
s << 100;
|
||||
s << std::endl;
|
||||
BOOST_TEST(s);
|
||||
}
|
||||
{
|
||||
boost::io::wonullstream s;
|
||||
s << L"abc";
|
||||
s << 100;
|
||||
s << std::endl;
|
||||
BOOST_TEST(s);
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
117
test/ostream_joiner_test.cpp
Normal file
117
test/ostream_joiner_test.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
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/io/ostream_joiner.hpp>
|
||||
#include <boost/core/is_same.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <sstream>
|
||||
|
||||
void test_char_type()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<char,
|
||||
boost::io::ostream_joiner<const char*>::char_type>::value));
|
||||
}
|
||||
|
||||
void test_traits_type()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<std::char_traits<char>,
|
||||
boost::io::ostream_joiner<const char*>::traits_type>::value));
|
||||
}
|
||||
|
||||
void test_ostream_type()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<std::ostream,
|
||||
boost::io::ostream_joiner<const char*>::ostream_type>::value));
|
||||
}
|
||||
|
||||
void test_iterator_category()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<std::output_iterator_tag,
|
||||
boost::io::ostream_joiner<const char*>::iterator_category>::value));
|
||||
}
|
||||
|
||||
void test_value_type()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<void,
|
||||
boost::io::ostream_joiner<const char*>::value_type>::value));
|
||||
}
|
||||
|
||||
void test_difference_type()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<void,
|
||||
boost::io::ostream_joiner<const char*>::difference_type>::value));
|
||||
}
|
||||
|
||||
void test_pointer()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<void,
|
||||
boost::io::ostream_joiner<const char*>::pointer>::value));
|
||||
}
|
||||
|
||||
void test_reference()
|
||||
{
|
||||
BOOST_TEST((boost::core::is_same<void,
|
||||
boost::io::ostream_joiner<const char*>::reference>::value));
|
||||
}
|
||||
|
||||
void test_construct()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST(o.str().empty());
|
||||
}
|
||||
|
||||
void test_assign()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
j = 1;
|
||||
BOOST_TEST_EQ(o.str(), "1");
|
||||
j = '2';
|
||||
BOOST_TEST_EQ(o.str(), "1,2");
|
||||
j = "3";
|
||||
BOOST_TEST_EQ(o.str(), "1,2,3");
|
||||
}
|
||||
|
||||
void test_increment()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&++j, &j);
|
||||
}
|
||||
|
||||
void test_post_increment()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&j++, &j);
|
||||
}
|
||||
|
||||
void test_value()
|
||||
{
|
||||
std::ostringstream o;
|
||||
boost::io::ostream_joiner<const char*> j(o, ",");
|
||||
BOOST_TEST_EQ(&*j, &j);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_char_type();
|
||||
test_traits_type();
|
||||
test_ostream_type();
|
||||
test_iterator_category();
|
||||
test_value_type();
|
||||
test_difference_type();
|
||||
test_pointer();
|
||||
test_reference();
|
||||
test_construct();
|
||||
test_assign();
|
||||
test_increment();
|
||||
test_post_increment();
|
||||
test_value();
|
||||
return boost::report_errors();
|
||||
}
|
136
test/ostream_put_test.cpp
Normal file
136
test/ostream_put_test.cpp
Normal 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/io/ostream_put.hpp>
|
||||
#include <boost/core/lightweight_test.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::io::ostream_put(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(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(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::io::ostream_put(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(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
boost::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(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::io::ostream_put(os, L"xy", 2);
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"..........xy");
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
136
test/quoted_fill_test.cpp
Normal file
136
test/quoted_fill_test.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright 2019-2020 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/io/quoted.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(2);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "\"xy\"");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(2);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"\"xy\"");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(2);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "\"xy\"");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(2);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"\"xy\"");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(6);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "\"xy\"..");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(6);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"\"xy\"..");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(6);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "..\"xy\"");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(6);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"..\"xy\"");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(14);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "\"xy\"..........");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(14);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"\"xy\"..........");
|
||||
}
|
||||
{
|
||||
std::ostringstream os;
|
||||
os.width(14);
|
||||
os.fill('.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted("xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == "..........\"xy\"");
|
||||
}
|
||||
{
|
||||
std::wostringstream os;
|
||||
os.width(14);
|
||||
os.fill(L'.');
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
os << boost::io::quoted(L"xy");
|
||||
BOOST_TEST(os.good());
|
||||
BOOST_TEST(os.width() == 0);
|
||||
BOOST_TEST(os.str() == L"..........\"xy\"");
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// libs/io/test/quote_manip_test.cpp ----------------------------------------------- //
|
||||
|
||||
// Copyright Beman Dawes 2010
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Library home page: http://www.boost.org/libs/io
|
||||
|
||||
// ---------------------------------------------------------------------------------- //
|
||||
|
||||
#include <boost/io/detail/quoted_manip.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
using boost::io::quoted;
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
std::wstringstream wss;
|
||||
|
||||
string r; // test results
|
||||
|
||||
const string s0("foo");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\"");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "foo");
|
||||
}
|
||||
|
||||
const string s0s("foo bar");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0s);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s0s);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "foo bar");
|
||||
}
|
||||
|
||||
const string s1("foo\\bar, \" *");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted("foo\\bar, \" *");
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s1.c_str());
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
|
||||
string s2("'Jack & Jill'");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s2, '&', '\'');
|
||||
ss >> quoted(r, '&', '\'');
|
||||
BOOST_TEST(r == s2);
|
||||
}
|
||||
|
||||
wstring ws1(L"foo$bar, \" *");
|
||||
wstring wr; // test results
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << quoted(ws1, L'$');
|
||||
wss >> quoted(wr, L'$');
|
||||
BOOST_TEST(wr == ws1);
|
||||
}
|
||||
|
||||
const string s3("const string");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << quoted(s3);
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == s3);
|
||||
}
|
||||
{
|
||||
// missing end delimiter test
|
||||
std::stringstream ss;
|
||||
ss << "\"abc"; // load ss with faulty quoting
|
||||
ss >> quoted(r); // this loops if istream error/eof not detected
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
// no initial delmiter test
|
||||
std::stringstream ss;
|
||||
ss << "abc";
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
// no initial delmiter, space in ss
|
||||
std::stringstream ss;
|
||||
ss << "abc def";
|
||||
ss >> quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
|
||||
// these should fail to compile because the arguments are const:
|
||||
// ss >> quoted(s1);
|
||||
// ss >> quoted("foo");
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
110
test/quoted_test.cpp
Normal file
110
test/quoted_test.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
Copyright 2010 Beman Dawes
|
||||
|
||||
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/io/quoted.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
int main()
|
||||
{
|
||||
const std::string s0("foo");
|
||||
std::string r;
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\"");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "foo");
|
||||
}
|
||||
const std::string s0s("foo bar");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0s);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s0s);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "foo bar");
|
||||
}
|
||||
const std::string s1("foo\\bar, \" *");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1);
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted("foo\\bar, \" *");
|
||||
ss >> r;
|
||||
BOOST_TEST(r == "\"foo\\\\bar,");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s1.c_str());
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s1);
|
||||
}
|
||||
std::string s2("'Jack & Jill'");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s2, '&', '\'');
|
||||
ss >> boost::io::quoted(r, '&', '\'');
|
||||
BOOST_TEST(r == s2);
|
||||
}
|
||||
const std::wstring ws1(L"foo$bar, \" *");
|
||||
std::wstring wr;
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << boost::io::quoted(ws1, L'$');
|
||||
wss >> boost::io::quoted(wr, L'$');
|
||||
BOOST_TEST(wr == ws1);
|
||||
}
|
||||
const std::string s3("const string");
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << boost::io::quoted(s3);
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == s3);
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "\"abc";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "abc";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "abc def";
|
||||
ss >> boost::io::quoted(r);
|
||||
BOOST_TEST(r == "abc");
|
||||
}
|
||||
return boost::report_errors();
|
||||
}
|
Reference in New Issue
Block a user