diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..eee4d10 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,56 @@ +# 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 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + TOOLSET: msvc-10.0 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + TOOLSET: msvc-11.0 + - 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 update --init tools/build + - git submodule update --init libs/config + - git submodule update --init tools/boostdep + - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\io\ + - python tools/boostdep/depinst/depinst.py io + - cmd /c bootstrap + - b2 headers + +build: off + +test_script: + - PATH=%ADDPATH%%PATH% + - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% + - if not "%ADDRMD%" == "" set ADDRMD=address-model=%ADDRMD% + - b2 libs/io/test toolset=%TOOLSET% %CXXSTD% %ADDRMD% diff --git a/.travis.yml b/.travis.yml index 1c23ece..82da550 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,39 +1,297 @@ # Copyright 2017 Edward Diener +# Copyright 2019 Glen Fernandes # Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) language: cpp sudo: false -python: "2.7" +dist: trusty -os: - - linux - - osx +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 $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root - - cd boost-root + - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost + - cd boost - git submodule update --init tools/build - git submodule update --init libs/config - git submodule update --init tools/boostdep + - mkdir -p libs/io - cp -r $TRAVIS_BUILD_DIR/* libs/io - python tools/boostdep/depinst/depinst.py io - ./bootstrap.sh - ./b2 headers script: - - TOOLSET=gcc,clang - - if [ $TRAVIS_OS_NAME == osx ]; then TOOLSET=clang; fi - - ./b2 --verbose-test libs/config/test//config_info toolset=$TOOLSET || true - - ./b2 libs/io/test toolset=$TOOLSET + - |- + echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam + - ./b2 libs/io/test toolset=$TOOLSET cxxstd=$CXXSTD notifications: email: diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1078f1b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +# Copyright 2018 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required( VERSION 3.5 ) +project( BoostIO 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 +) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b1857e3..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2017 Edward Diener -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) - -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,msvc-10.0,msvc-11.0,msvc-12.0,msvc-14.0 - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - TOOLSET: msvc-14.1 - -install: - - cd .. - - git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root - - cd boost-root - - git submodule update --init tools/build - - git submodule update --init libs/config - - git submodule update --init tools/boostdep - - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\io - - python tools/boostdep/depinst/depinst.py io - - bootstrap - - b2 headers - -build: off - -test_script: - - b2 libs/io/test toolset=%TOOLSET% diff --git a/doc/Jamfile b/doc/Jamfile new file mode 100644 index 0000000..2756ce8 --- /dev/null +++ b/doc/Jamfile @@ -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 : html ; + +pdf io.pdf : io.adoc ; +explicit io.pdf ; + +install pdf_ : io.pdf : pdf ; +explicit pdf_ ; + +alias boostdoc ; +explicit boostdoc ; + +alias boostrelease : html_ ; +explicit boostrelease ; diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 4885739..0000000 --- a/doc/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - -Boost I/O Library - - - - - - - - - - - - -
boost.png (6897 bytes)HomeLibrariesPeopleFAQMore
- -

Boost Input/Output Library

- - - - - - - - - - - - - - -
Header / DocsContents
- <boost/io_fwd.hpp> - - Forward declaration header. -
- <boost/io/ios_state.hpp>
-
documentation -
- State-saving classes for various IOStream attributes. -
- -

Rationale

- -

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.

- -
- -

Revised: 26 Feb 2002

- -

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>.)

- - diff --git a/doc/io.adoc b/doc/io.adoc new file mode 100644 index 0000000..6685efe --- /dev/null +++ b/doc/io.adoc @@ -0,0 +1,32 @@ +//// +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 +:idprefix: +:source-language: cpp +:toc: left + +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. + +:leveloffset: +1 + +include::ios_state.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]. diff --git a/doc/ios_state.adoc b/doc/ios_state.adoc new file mode 100644 index 0000000..dec2d41 --- /dev/null +++ b/doc/ios_state.adoc @@ -0,0 +1,316 @@ +//// +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) +//// + +# ios_state, +:toc: +:toc-title: +:idprefix: + +## Description + +The header `` 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 +#include + +void hex_my_byte(std::ostream& os, char byte) +{ + os << std::hex << static_cast(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 basic_ios_iostate_saver; + +template > +class basic_ios_exception_saver; + +template > +class basic_ios_tie_saver; + +template > +class basic_ios_rdbuf_saver; + +template > +class basic_ios_fill_saver; + +template > +class basic_ios_locale_saver; + +template > +class basic_ios_all_saver; + +typedef basic_ios_iostate_saver ios_iostate_saver; +typedef basic_ios_iostate_saver wios_iostate_saver; +typedef basic_ios_exception_saver ios_exception_saver; +typedef basic_ios_exception_saver wios_exception_saver; +typedef basic_ios_tie_saver ios_tie_saver; +typedef basic_ios_tie_saver wios_tie_saver; +typedef basic_ios_rdbuf_saver ios_rdbuf_saver; +typedef basic_ios_rdbuf_saver wios_rdbuf_saver; +typedef basic_ios_fill_saver ios_fill_saver; +typedef basic_ios_fill_saver wios_fill_saver; +typedef basic_ios_locale_saver ios_locale_saver; +typedef basic_ios_locale_saver wios_locale_saver; +typedef basic_ios_all_saver ios_all_saver; +typedef basic_ios_all_saver 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_class { + typedef std::ios_base state_type; + typedef `implementation_defined` aspect_type; + + explicit saver_class(state_type& s); + saver_class(state_type& s, const aspect_type& new_value); + ~saver_class(); + + 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 saver_class { + typedef std::basic_ios state_type; + typedef `implementation-defined` aspect_type; + + explicit saver_class(state_type& s); + saver_class(state_type& s, const aspect_type& new_value); + ~saver_class(); + + void restore(); +}; +``` + +The `state_type` is a version of the IOStreams base class template +`std::basic_ios`, 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` +|Failure state of the stream [1], [2] +|`std::ios_base::iostate` +|`rdstate` +|`clear` +|`basic_ios_exception_saver` +|Which failure states trigger an exception [1] +|`std::ios_base::iostate` +|`exceptions` +|`exceptions` +|`basic_ios_tie_saver` +|Output stream synchronized with the stream +|`std::basic_ostream*` +|`tie` +|`tie` +|`basic_ios_rdbuf_saver` +|Stream buffer associated with the stream [2] +|`std::basic_streambuf*` +|`rdbuf` +|`rdbuf` +|`basic_ios_fill_saver` +|Character used to pad oversized field widths +|`Ch` +|`fill` +|`fill` +|`basic_ios_locale_saver` +|Locale information associated with the stream [3] +|`std::locale` +|`getloc` (from `std::ios_base`) +|`imbue` (from `std::basic_ios`) +|=== + +### 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` 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 & forth, without +surrounding each change within a separate block, the restore member function +can be called between each trial. + +``` +#include +#include +#include +#include + +void new_hex_my_byte(std::ostream& os, char byte) +{ + boost::io::ios_flags_saver ifs(os); + os << std::hex << static_cast(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 + +### 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. diff --git a/doc/ios_state.html b/doc/ios_state.html deleted file mode 100644 index 9be4fa2..0000000 --- a/doc/ios_state.html +++ /dev/null @@ -1,468 +0,0 @@ - - - -I/O Stream-State Saver Library - - -

boost.png (6897 bytes)Header <boost/io/ios_state.hpp ->

- -

The header boost/io/ios_state.hpp -covers saving the stream state of objects in the C++ IOStreams -system.

- -

Contents

- -
    -
  1. Contents
  2. -
  3. Rationale
  4. -
  5. Header Synopsis
  6. -
  7. Savers for Basic Standard Attributes
  8. -
  9. Savers for Advanced Standard Attributes
  10. -
  11. Savers for User-Defined Attributes
  12. -
  13. Savers for Combined Attributes
  14. -
  15. Example
  16. -
  17. References
  18. -
  19. Credits -
  20. -
- -

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

- -
#include <iosfwd>  // for std::char_traits (declaration)
-
-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;
-
-}
-}
-
- -

Savers for Basic Standard Attributes

- -

The basic saver classes have this format:

- -
class saver_class
-{
-    typedef std::ios_base           state_type;
-    typedef implementation_defined  aspect_type;
-
-    explicit  saver_class( state_type &s );
-              saver_class( state_type &s, aspect_type const &new_value );
-             ~saver_class();
-
-    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
ClassSaved AttributeAttribute TypeReading MethodWriting Method
boost::io::ios_flags_saverFormat control flagsstd::ios_base::fmtflagsflagsflags
boost::io::ios_precision_saverNumber of digits to print after decimal pointstd::streamsizeprecisionprecision
boost::io::ios_width_saverMinimum field width for printing objectsstd::streamsizewidthwidth
- -

Savers for Advanced Standard Attributes

- -

The saver class templates have this format:

- -
template < typename Ch, class Tr >
-class saver_class
-{
-    typedef std::basic_ios<Ch, Tr>  state_type;
-    typedef implementation_defined  aspect_type;
-
-    explicit  saver_class( state_type &s );
-              saver_class( state_type &s, aspect_type const &new_value );
-             ~saver_class();
-
-    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
Class TemplateSaved AttributeAttribute TypeReading MethodWriting Method
boost::io::basic_ios_iostate_saver<Ch, Tr>Failure state of the stream [1], [2]std::ios_base::iostaterdstateclear
boost::io::basic_ios_exception_saver<Ch, Tr>Which failure states trigger an exception [1]std::ios_base::iostateexceptionsexceptions
boost::io::basic_ios_tie_saver<Ch, Tr>Output stream synchronized with the streamstd::basic_ostream<Ch, Tr> *tietie
boost::io::basic_ios_rdbuf_saver<Ch, Tr>Stream buffer associated with the stream [2]std::basic_streambuf<Ch, Tr> *rdbufrdbuf
boost::io::basic_ios_fill_saver<Ch, Tr>Character used to pad oversized field widthsChfillfill
boost::io::basic_ios_locale_saver<Ch, Tr>Locale information associated with the stream [3]std::localegetloc (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. -
  3. 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.
  4. -
  5. 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.
  6. -
- -

Savers for User-Defined Attributes

- -

The saver classes for user-defined formatting information have this -format:

- -
#include <iosfwd>  // for std::ios_base (declaration)
-
-class saver_class
-{
-    typedef std::ios_base           state_type;
-    typedef int                     index_type;
-    typedef implementation_defined  aspect_type;
-
-    explicit  saver_class( state_type &s, index_type i );
-              saver_class( state_type &s, index_type i, aspect_type const &new_value );
-             ~saver_class();
-
-    void  restore();
-};
-
- -

The index i differentiates between specific user-defined -formatting attributes. The index can only be determined at run-time -(most likely with the class-static std::ios_base::xalloc -member function).

- -

The state_type is the base class of the IOStreams system, -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 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 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.

- - - - - - - - - - - - - - - - - - - - - -
IOStream User-Defined State Saver Classes
ClassSaved AttributeAttribute TypeReference Method
boost::io::ios_iword_saverNumeric user-defined format flaglongiword
boost::io::ios_pword_saverPointer user-defined format flagvoid *pword
- -

Savers for Combined Attributes

- -

There are three class (templates) for combined attribute savers. The -boost:io::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 -boost::io::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 -boost::io::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 & 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()
-{
-    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' );
-    }
-
-    //...
-}
-
- -

References

- - - -

Credits

- -

Contributors

- -
-
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

- -
-
28 Feb 2005, Daryle Walker -
Added the restore member functions, based on suggestions - by Gennadiy Rozental and Rob Stewart - -
13 Mar 2002, Daryle Walker -
Initial version -
- -
- -

Revised: 28 February 2005

- -

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>.)

- - diff --git a/doc/quoted.adoc b/doc/quoted.adoc new file mode 100644 index 0000000..d82120c --- /dev/null +++ b/doc/quoted.adoc @@ -0,0 +1,139 @@ +//// +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, +: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 +`unspecified-type1` +quoted(const std::basic_string& string, + Char escape='\\', Char delim='\"'); + +template +`unspecified-type2` +quoted(const Char* string, Char escape='\\', Char delim='\"'); + +template +`unspecified-type3` +quoted(std::basic_string& 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 +std::basic_ostream& +operator<<(std::basic_ostream& 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 +std::basic_istream& +operator>>(std::basic_istream& 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. diff --git a/doc/quoted_manip.html b/doc/quoted_manip.html deleted file mode 100644 index 14a3380..0000000 --- a/doc/quoted_manip.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - Boost "quoted" I/O manipulator - - - - - - - - - - - - - -
boost.png (6897 bytes) -

"Quoted" - I/O Manipulators
- for Strings

-
- - - - - -
-

"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>

- -

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 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
-
-

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 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
-
-

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 <boost/io/quoted_manip.hpp> synopsis

-
namespace boost
-{
-  namespace io
-  {
-    // manipulator for const std::basic_string&
-
-    template <class Char, class Traits, class Alloc>
-    unspecified-type1 quoted(const std::basic_string<Char, Traits, Alloc>& string,
-                             Char escape='\\', Char delim='\"');
-
-    // manipulator for const C-string*
-
-    template <class Char>
-    unspecified-type2 quoted(const Char* string,
-                             Char escape='\\', Char delim='\"');
-
-    // manipulator for non-const std::basic_string&
-
-    template <class Char, class Traits, class Alloc>
-    unspecified-type3 quoted(std::basic_string<Char, Traits, Alloc>& string,
-                             Char escape='\\', Char delim='\"');
-  }
-}
-

unspecified_type1, unspecified_type2, -and unspecified_type3 are implementation supplied -types with implementation supplied operator<<:

-
-
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>>:

-
-
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.

-
-

© Copyright Beman Dawes, 2002, 2006, 2007, 2009, 2010

-

Distributed under the Boost Software License, Version 1.0. See -www.boost.org/LICENSE_1_0.txt

-

Revised -08 March 2013

- - - \ No newline at end of file diff --git a/index.html b/index.html index debe825..caa266d 100644 --- a/index.html +++ b/index.html @@ -1,14 +1,17 @@ + + - + + +Span -Automatic redirection failed, please go to -doc/index.html
-

© Copyright Beman Dawes, 2001

-

Distributed under the Boost Software License, Version 1.0. (See accompanying -file LICENSE_1_0.txt or copy -at www.boost.org/LICENSE_1_0.txt) -

+Redirecting you to IO. - \ No newline at end of file + diff --git a/meta/libraries.json b/meta/libraries.json index 1e2b3e9..3259e18 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -2,10 +2,10 @@ "key": "io", "name": "IO State Savers", "authors": [ - "Daryle Walker" + "Daryle Walker", + "Beman Dawes" ], - "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 using the standard I/O library.", "category": [ "IO" ], diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 4b48bce..8d12343 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,26 +1,13 @@ -# Boost.IO Library test Jamfile +# Copyright 2003 Daryle Walker # -# 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 -# .) +# Copyright 2019 Glen Joseph Fernandes +# (glenjofe@gmail.com) # -# See for the library's home page. +# Distributed under the Boost Software License, Version 1.0. +# (http://www.boost.org/LICENSE_1_0.txt) -test-suite "io" - : [ run ios_state_unit_test.cpp - ../../../libs/test/build//boost_unit_test_framework/static - : # args - : # input files - # : std::locale-support - ] +import testing ; - [ run ios_state_test.cpp - ../../../libs/test/build//boost_test_exec_monitor/static - : # args - : # input files - # : std::locale-support - ] - - [ run quoted_manip_test.cpp ] - ; +run ios_state_unit_test.cpp ; +run ios_state_test.cpp ; +run quoted_manip_test.cpp ; diff --git a/test/ios_state_test.cpp b/test/ios_state_test.cpp index 79975f0..4e35c51 100644 --- a/test/ios_state_test.cpp +++ b/test/ios_state_test.cpp @@ -4,6 +4,9 @@ // subject to the Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or a copy at .) +// Copyright 2019 Glen Joseph Fernandes +// (glenjofe@gmail.com) + // See for the library's home page. // Revision History @@ -11,9 +14,8 @@ // 26 Feb 2002 Initial version (Daryle Walker) #include -#include // main, BOOST_CHECK, etc. +#include -#include // for boost::exit_success #include // for boost::io::ios_flags_saver, etc. #include // for std::size_t @@ -68,12 +70,7 @@ void saver_tests_2( std::istream &input, std::ostream &output, // Test program -int -test_main -( - int , // "argc" is unused - char * [] // "argv" is unused -) +int main() { using std::cout; using std::ios_base; @@ -104,35 +101,35 @@ test_main 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() ); + BOOST_TEST( &cin == cout.pword(my_index) ); + BOOST_TEST( 42L == cout.iword(my_index) ); + BOOST_TEST( cout_locale == cout.getloc() ); + BOOST_TEST( cout_fill == cout.fill() ); + BOOST_TEST( cout_sb == cout.rdbuf() ); + BOOST_TEST( cin_tie == cin.tie() ); + BOOST_TEST( cout_exceptions == cout.exceptions() ); + BOOST_TEST( cout_iostate == cout.rdstate() ); + BOOST_TEST( cout_width == cout.width() ); + BOOST_TEST( cout_precision == cout.precision() ); + BOOST_TEST( 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() ); + BOOST_TEST( &cin == cout.pword(my_index) ); + BOOST_TEST( 42L == cout.iword(my_index) ); + BOOST_TEST( cout_locale == cout.getloc() ); + BOOST_TEST( cout_fill == cout.fill() ); + BOOST_TEST( cout_sb == cout.rdbuf() ); + BOOST_TEST( cin_tie == cin.tie() ); + BOOST_TEST( cout_exceptions == cout.exceptions() ); + BOOST_TEST( cout_iostate == cout.rdstate() ); + BOOST_TEST( cout_width == cout.width() ); + BOOST_TEST( cout_precision == cout.precision() ); + BOOST_TEST( cout_flags == cout.flags() ); - return boost::exit_success; + return boost::report_errors(); } // Save, change, and restore stream properties @@ -176,8 +173,8 @@ saver_tests_1 output.imbue( loc ); output << '\t' << test_bool << '\n'; - BOOST_CHECK( &err == output.pword(my_index) ); - BOOST_CHECK( 69L == output.iword(my_index) ); + BOOST_TEST( &err == output.pword(my_index) ); + BOOST_TEST( 69L == output.iword(my_index) ); try { @@ -195,7 +192,7 @@ saver_tests_1 #endif { err << "Got the expected I/O failure: \"" << f.what() << "\".\n"; - BOOST_CHECK( output.exceptions() == ios_base::goodbit ); + BOOST_TEST( output.exceptions() == ios_base::goodbit ); } catch ( ... ) { @@ -239,8 +236,8 @@ saver_tests_2 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) ); + BOOST_TEST( &err == output.pword(my_index) ); + BOOST_TEST( 69L == output.iword(my_index) ); try { @@ -257,7 +254,7 @@ saver_tests_2 #endif { err << "Got the expected I/O failure: \"" << f.what() << "\".\n"; - BOOST_CHECK( output.exceptions() == ios_base::goodbit ); + BOOST_TEST( output.exceptions() == ios_base::goodbit ); } catch ( ... ) { diff --git a/test/ios_state_unit_test.cpp b/test/ios_state_unit_test.cpp index 6aa2011..7dee6c7 100644 --- a/test/ios_state_unit_test.cpp +++ b/test/ios_state_unit_test.cpp @@ -4,6 +4,9 @@ // subject to the Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or a copy at .) +// Copyright 2019 Glen Joseph Fernandes +// (glenjofe@gmail.com) + // See for the library's home page. // Revision History @@ -11,7 +14,7 @@ #include #include // for boost::io::ios_flags_saver, etc. -#include // for main, BOOST_CHECK, etc. +#include #include // for NULL #include // for std::setiosflags, etc. @@ -60,33 +63,33 @@ ios_flags_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); { boost::io::ios_flags_saver ifs( ss ); - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); ss << noskipws << fixed << boolalpha; - BOOST_CHECK_EQUAL( (ios_base::boolalpha | ios_base::dec + BOOST_TEST_EQ( (ios_base::boolalpha | ios_base::dec | ios_base::fixed), ss.flags() ); } - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); { boost::io::ios_flags_saver ifs( ss, (ios_base::showbase | ios_base::internal) ); - BOOST_CHECK_EQUAL( (ios_base::showbase | ios_base::internal), + BOOST_TEST_EQ( (ios_base::showbase | ios_base::internal), ss.flags() ); ss << setiosflags( ios_base::unitbuf ); - BOOST_CHECK_EQUAL( (ios_base::showbase | ios_base::internal + BOOST_TEST_EQ( (ios_base::showbase | ios_base::internal | ios_base::unitbuf), ss.flags() ); } - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); } // Unit test for precision saving @@ -99,29 +102,29 @@ ios_precision_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( 6, ss.precision() ); + BOOST_TEST_EQ( 6, ss.precision() ); { boost::io::ios_precision_saver ips( ss ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); + BOOST_TEST_EQ( 6, ss.precision() ); ss << setprecision( 4 ); - BOOST_CHECK_EQUAL( 4, ss.precision() ); + BOOST_TEST_EQ( 4, ss.precision() ); } - BOOST_CHECK_EQUAL( 6, ss.precision() ); + BOOST_TEST_EQ( 6, ss.precision() ); { boost::io::ios_precision_saver ips( ss, 8 ); - BOOST_CHECK_EQUAL( 8, ss.precision() ); + BOOST_TEST_EQ( 8, ss.precision() ); ss << setprecision( 10 ); - BOOST_CHECK_EQUAL( 10, ss.precision() ); + BOOST_TEST_EQ( 10, ss.precision() ); } - BOOST_CHECK_EQUAL( 6, ss.precision() ); + BOOST_TEST_EQ( 6, ss.precision() ); } // Unit test for width saving @@ -134,29 +137,29 @@ ios_width_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_width_saver iws( ss ); - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( 0, ss.width() ); ss << setw( 4 ); - BOOST_CHECK_EQUAL( 4, ss.width() ); + BOOST_TEST_EQ( 4, ss.width() ); } - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_width_saver iws( ss, 8 ); - BOOST_CHECK_EQUAL( 8, ss.width() ); + BOOST_TEST_EQ( 8, ss.width() ); ss << setw( 10 ); - BOOST_CHECK_EQUAL( 10, ss.width() ); + BOOST_TEST_EQ( 10, ss.width() ); } - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( 0, ss.width() ); } // Unit test for I/O-state saving @@ -169,43 +172,43 @@ ios_iostate_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); { boost::io::ios_iostate_saver iis( ss ); char c; - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); ss >> c; - BOOST_CHECK_EQUAL( (ios_base::eofbit | ios_base::failbit), + BOOST_TEST_EQ( (ios_base::eofbit | ios_base::failbit), ss.rdstate() ); - BOOST_CHECK( ss.eof() ); - BOOST_CHECK( ss.fail() ); - BOOST_CHECK( !ss.bad() ); + BOOST_TEST( ss.eof() ); + BOOST_TEST( ss.fail() ); + BOOST_TEST( !ss.bad() ); } - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); { boost::io::ios_iostate_saver iis( ss, ios_base::eofbit ); - BOOST_CHECK_EQUAL( ios_base::eofbit, ss.rdstate() ); - BOOST_CHECK( ss.eof() ); + BOOST_TEST_EQ( ios_base::eofbit, ss.rdstate() ); + BOOST_TEST( ss.eof() ); ss.setstate( ios_base::badbit ); - BOOST_CHECK_EQUAL( (ios_base::eofbit | ios_base::badbit), + BOOST_TEST_EQ( (ios_base::eofbit | ios_base::badbit), ss.rdstate() ); - BOOST_CHECK( ss.eof() ); - BOOST_CHECK( ss.fail() ); - BOOST_CHECK( ss.bad() ); + BOOST_TEST( ss.eof() ); + BOOST_TEST( ss.fail() ); + BOOST_TEST( ss.bad() ); } - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); } // Unit test for exception-flag saving @@ -218,15 +221,15 @@ ios_exception_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); { boost::io::ios_exception_saver ies( ss ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); ss.exceptions( ios_base::failbit ); - BOOST_CHECK_EQUAL( ios_base::failbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::failbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); @@ -234,32 +237,32 @@ ios_exception_saver_unit_test char c; #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB)) - BOOST_CHECK_THROW( ss >> c, std::exception ); + BOOST_TEST_THROWS( ss >> c, std::exception ); #else - BOOST_CHECK_THROW( ss >> c, std::ios_base::failure ); + BOOST_TEST_THROWS( ss >> c, std::ios_base::failure ); #endif } } - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); { boost::io::ios_exception_saver ies( ss, ios_base::eofbit ); - BOOST_CHECK_EQUAL( ios_base::eofbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::eofbit, ss.exceptions() ); ss.exceptions( ios_base::badbit ); - BOOST_CHECK_EQUAL( ios_base::badbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::badbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); char c; - BOOST_CHECK_NO_THROW( ss >> c ); + BOOST_TEST_NOT( ss >> c ); } } - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); } // Unit test for tied-stream saving @@ -270,29 +273,29 @@ ios_tie_saver_unit_test { using namespace std; - BOOST_CHECK( NULL == cout.tie() ); + BOOST_TEST( NULL == cout.tie() ); { boost::io::ios_tie_saver its( cout ); - BOOST_CHECK( NULL == cout.tie() ); + BOOST_TEST( NULL == cout.tie() ); cout.tie( &clog ); - BOOST_CHECK_EQUAL( &clog, cout.tie() ); + BOOST_TEST_EQ( &clog, cout.tie() ); } - BOOST_CHECK( NULL == cout.tie() ); + BOOST_TEST( NULL == cout.tie() ); { boost::io::ios_tie_saver its( cout, &clog ); - BOOST_CHECK_EQUAL( &clog, cout.tie() ); + BOOST_TEST_EQ( &clog, cout.tie() ); cout.tie( &cerr ); - BOOST_CHECK_EQUAL( &cerr, cout.tie() ); + BOOST_TEST_EQ( &cerr, cout.tie() ); } - BOOST_CHECK( NULL == cout.tie() ); + BOOST_TEST( NULL == cout.tie() ); } // Unit test for connected-streambuf saving @@ -305,31 +308,31 @@ ios_rdbuf_saver_unit_test iostream s( NULL ); - BOOST_CHECK( NULL == s.rdbuf() ); + BOOST_TEST( NULL == s.rdbuf() ); { stringbuf sb; boost::io::ios_rdbuf_saver irs( s ); - BOOST_CHECK( NULL == s.rdbuf() ); + BOOST_TEST( NULL == s.rdbuf() ); s.rdbuf( &sb ); - BOOST_CHECK_EQUAL( &sb, s.rdbuf() ); + BOOST_TEST_EQ( &sb, s.rdbuf() ); } - BOOST_CHECK( NULL == s.rdbuf() ); + BOOST_TEST( NULL == s.rdbuf() ); { stringbuf sb1, sb2( "Hi there" ); boost::io::ios_rdbuf_saver irs( s, &sb1 ); - BOOST_CHECK_EQUAL( &sb1, s.rdbuf() ); + BOOST_TEST_EQ( &sb1, s.rdbuf() ); s.rdbuf( &sb2 ); - BOOST_CHECK_EQUAL( &sb2, s.rdbuf() ); + BOOST_TEST_EQ( &sb2, s.rdbuf() ); } - BOOST_CHECK( NULL == s.rdbuf() ); + BOOST_TEST( NULL == s.rdbuf() ); } // Unit test for fill-character saving @@ -342,29 +345,29 @@ ios_fill_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( ' ', ss.fill() ); + BOOST_TEST_EQ( ' ', ss.fill() ); { boost::io::ios_fill_saver ifs( ss ); - BOOST_CHECK_EQUAL( ' ', ss.fill() ); + BOOST_TEST_EQ( ' ', ss.fill() ); ss.fill( 'x' ); - BOOST_CHECK_EQUAL( 'x', ss.fill() ); + BOOST_TEST_EQ( 'x', ss.fill() ); } - BOOST_CHECK_EQUAL( ' ', ss.fill() ); + BOOST_TEST_EQ( ' ', ss.fill() ); { boost::io::ios_fill_saver ifs( ss, '3' ); - BOOST_CHECK_EQUAL( '3', ss.fill() ); + BOOST_TEST_EQ( '3', ss.fill() ); ss.fill( '+' ); - BOOST_CHECK_EQUAL( '+', ss.fill() ); + BOOST_TEST_EQ( '+', ss.fill() ); } - BOOST_CHECK_EQUAL( ' ', ss.fill() ); + BOOST_TEST_EQ( ' ', ss.fill() ); } // Unit test for locale saving @@ -379,48 +382,48 @@ ios_locale_saver_unit_test stringstream ss; - BOOST_CHECK( locale() == ss.getloc() ); - // locales are unprintable, so no BOOST_CHECK_EQUAL - BOOST_CHECK( !has_facet(ss.getloc()) || (NULL + BOOST_TEST( locale() == ss.getloc() ); + // locales are unprintable, so no BOOST_TEST_EQ + BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); // my implementation of has_facet just checks IDs, but doesn't do dynamic // cast (therefore if a specifc facet type is missing, but its base class // is available, has_facet will mistakenly[?] match), so I have to do it - // here. I wanted: "BOOST_CHECK( ! has_facet< backward_bool_names >( + // here. I wanted: "BOOST_TEST( ! has_facet< backward_bool_names >( // ss.getloc() ) )" { boost::io::ios_locale_saver ils( ss ); - BOOST_CHECK( locale() == ss.getloc() ); + BOOST_TEST( locale() == ss.getloc() ); ss.imbue( locale::classic() ); - BOOST_CHECK( locale::classic() == ss.getloc() ); + BOOST_TEST( locale::classic() == ss.getloc() ); } - BOOST_CHECK( locale() == ss.getloc() ); - BOOST_CHECK( !has_facet(ss.getloc()) || (NULL + BOOST_TEST( locale() == ss.getloc() ); + BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); { boost::io::ios_locale_saver ils( ss, locale::classic() ); - BOOST_CHECK( locale::classic() == ss.getloc() ); - BOOST_CHECK( !has_facet(ss.getloc()) || (NULL + BOOST_TEST( locale::classic() == ss.getloc() ); + BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); ss.imbue( locale(locale::classic(), new backward_bool_names) ); - BOOST_CHECK( locale::classic() != ss.getloc() ); - BOOST_CHECK( has_facet(ss.getloc()) && (NULL + BOOST_TEST( locale::classic() != ss.getloc() ); + BOOST_TEST( has_facet(ss.getloc()) && (NULL != dynamic_cast( &use_facet(ss.getloc()) )) ); - //BOOST_CHECK( has_facet(ss.getloc()) ); + //BOOST_TEST( has_facet(ss.getloc()) ); } - BOOST_CHECK( locale() == ss.getloc() ); - BOOST_CHECK( !has_facet(ss.getloc()) || (NULL + BOOST_TEST( locale() == ss.getloc() ); + BOOST_TEST( !has_facet(ss.getloc()) || (NULL == dynamic_cast( &use_facet(ss.getloc()) )) ); } @@ -435,29 +438,29 @@ ios_iword_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); { boost::io::ios_iword_saver iis( ss, word_index ); - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); ss.iword( word_index ) = 6; - BOOST_CHECK_EQUAL( 6, ss.iword(word_index) ); + BOOST_TEST_EQ( 6, ss.iword(word_index) ); } - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); { boost::io::ios_iword_saver iis( ss, word_index, 100 ); - BOOST_CHECK_EQUAL( 100, ss.iword(word_index) ); + BOOST_TEST_EQ( 100, ss.iword(word_index) ); ss.iword( word_index ) = -2000; - BOOST_CHECK_EQUAL( -2000, ss.iword(word_index) ); + BOOST_TEST_EQ( -2000, ss.iword(word_index) ); } - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); } // Unit test for user-defined pointer data saving @@ -470,29 +473,29 @@ ios_pword_saver_unit_test stringstream ss; - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_pword_saver ips( ss, word_index ); - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); ss.pword( word_index ) = &ss; - BOOST_CHECK_EQUAL( &ss, ss.pword(word_index) ); + BOOST_TEST_EQ( &ss, ss.pword(word_index) ); } - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_pword_saver ips( ss, word_index, ss.rdbuf() ); - BOOST_CHECK_EQUAL( ss.rdbuf(), ss.pword(word_index) ); + BOOST_TEST_EQ( ss.rdbuf(), ss.pword(word_index) ); ss.pword( word_index ) = &ss; - BOOST_CHECK_EQUAL( &ss, ss.pword(word_index) ); + BOOST_TEST_EQ( &ss, ss.pword(word_index) ); } - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); } // Unit test for all ios_base data saving @@ -505,27 +508,27 @@ ios_base_all_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); { boost::io::ios_base_all_saver ibas( ss ); - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); ss << hex << unitbuf << setprecision( 5 ) << setw( 7 ); - BOOST_CHECK_EQUAL( (ios_base::unitbuf | ios_base::hex + BOOST_TEST_EQ( (ios_base::unitbuf | ios_base::hex | ios_base::skipws), ss.flags() ); - BOOST_CHECK_EQUAL( 5, ss.precision() ); - BOOST_CHECK_EQUAL( 7, ss.width() ); + BOOST_TEST_EQ( 5, ss.precision() ); + BOOST_TEST_EQ( 7, ss.width() ); } - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); } // Unit test for all basic_ios data saving @@ -541,46 +544,46 @@ ios_all_saver_unit_test stringbuf sb; iostream ss( &sb ); - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); - BOOST_CHECK( NULL == ss.tie() ); - BOOST_CHECK( &sb == ss.rdbuf() ); - BOOST_CHECK_EQUAL( ' ', ss.fill() ); - BOOST_CHECK( locale() == ss.getloc() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST( NULL == ss.tie() ); + BOOST_TEST( &sb == ss.rdbuf() ); + BOOST_TEST_EQ( ' ', ss.fill() ); + BOOST_TEST( locale() == ss.getloc() ); { boost::io::ios_all_saver ias( ss ); - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); - BOOST_CHECK( NULL == ss.tie() ); - BOOST_CHECK( &sb == ss.rdbuf() ); - BOOST_CHECK_EQUAL( ' ', ss.fill() ); - BOOST_CHECK( locale() == ss.getloc() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST( NULL == ss.tie() ); + BOOST_TEST( &sb == ss.rdbuf() ); + BOOST_TEST_EQ( ' ', ss.fill() ); + BOOST_TEST( locale() == ss.getloc() ); ss << oct << showpos << noskipws; - BOOST_CHECK_EQUAL( (ios_base::showpos | ios_base::oct), ss.flags() ); + BOOST_TEST_EQ( (ios_base::showpos | ios_base::oct), ss.flags() ); ss << setprecision( 3 ); - BOOST_CHECK_EQUAL( 3, ss.precision() ); + BOOST_TEST_EQ( 3, ss.precision() ); ss << setw( 9 ); - BOOST_CHECK_EQUAL( 9, ss.width() ); + BOOST_TEST_EQ( 9, ss.width() ); ss.setstate( ios_base::eofbit ); - BOOST_CHECK_EQUAL( ios_base::eofbit, ss.rdstate() ); - BOOST_CHECK( ss.eof() ); + BOOST_TEST_EQ( ios_base::eofbit, ss.rdstate() ); + BOOST_TEST( ss.eof() ); ss.exceptions( ios_base::failbit ); - BOOST_CHECK_EQUAL( ios_base::failbit, ss.exceptions() ); + BOOST_TEST_EQ( ios_base::failbit, ss.exceptions() ); { boost::io::ios_iostate_saver iis( ss ); @@ -588,38 +591,38 @@ ios_all_saver_unit_test char c; #if defined(BOOST_GCC) || (defined(BOOST_CLANG) && defined(BOOST_GNU_STDLIB)) - BOOST_CHECK_THROW( ss >> c, std::exception ); + BOOST_TEST_THROWS( ss >> c, std::exception ); #else - BOOST_CHECK_THROW( ss >> c, std::ios_base::failure ); + BOOST_TEST_THROWS( ss >> c, std::ios_base::failure ); #endif } ss.tie( &clog ); - BOOST_CHECK_EQUAL( &clog, ss.tie() ); + BOOST_TEST_EQ( &clog, ss.tie() ); ss.rdbuf( cerr.rdbuf() ); - BOOST_CHECK_EQUAL( cerr.rdbuf(), ss.rdbuf() ); + BOOST_TEST_EQ( cerr.rdbuf(), ss.rdbuf() ); ss << setfill( 'x' ); - BOOST_CHECK_EQUAL( 'x', ss.fill() ); + BOOST_TEST_EQ( 'x', ss.fill() ); ss.imbue( locale(locale::classic(), new backward_bool_names) ); - BOOST_CHECK( locale() != ss.getloc() ); - BOOST_CHECK( has_facet(ss.getloc()) && (NULL + BOOST_TEST( locale() != ss.getloc() ); + BOOST_TEST( has_facet(ss.getloc()) && (NULL != dynamic_cast( &use_facet(ss.getloc()) )) ); } - BOOST_CHECK_EQUAL( (ios_base::skipws | ios_base::dec), ss.flags() ); - BOOST_CHECK_EQUAL( 6, ss.precision() ); - BOOST_CHECK_EQUAL( 0, ss.width() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.rdstate() ); - BOOST_CHECK( ss.good() ); - BOOST_CHECK_EQUAL( ios_base::goodbit, ss.exceptions() ); - BOOST_CHECK( NULL == ss.tie() ); - BOOST_CHECK( &sb == ss.rdbuf() ); - BOOST_CHECK_EQUAL( ' ', ss.fill() ); - BOOST_CHECK( locale() == ss.getloc() ); + BOOST_TEST_EQ( (ios_base::skipws | ios_base::dec), ss.flags() ); + BOOST_TEST_EQ( 6, ss.precision() ); + BOOST_TEST_EQ( 0, ss.width() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.rdstate() ); + BOOST_TEST( ss.good() ); + BOOST_TEST_EQ( ios_base::goodbit, ss.exceptions() ); + BOOST_TEST( NULL == ss.tie() ); + BOOST_TEST( &sb == ss.rdbuf() ); + BOOST_TEST_EQ( ' ', ss.fill() ); + BOOST_TEST( locale() == ss.getloc() ); } // Unit test for user-defined data saving @@ -632,54 +635,46 @@ ios_word_saver_unit_test stringstream ss; - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); { boost::io::ios_all_word_saver iaws( ss, word_index ); - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); ss.iword( word_index ) = -11; ss.pword( word_index ) = ss.rdbuf(); - BOOST_CHECK_EQUAL( -11, ss.iword(word_index) ); - BOOST_CHECK_EQUAL( ss.rdbuf(), ss.pword(word_index) ); + BOOST_TEST_EQ( -11, ss.iword(word_index) ); + BOOST_TEST_EQ( ss.rdbuf(), ss.pword(word_index) ); } - BOOST_CHECK_EQUAL( 0, ss.iword(word_index) ); - BOOST_CHECK( NULL == ss.pword(word_index) ); + BOOST_TEST_EQ( 0, ss.iword(word_index) ); + BOOST_TEST( NULL == ss.pword(word_index) ); } // Unit test program -boost::unit_test::test_suite * -init_unit_test_suite -( - int , // "argc" is unused - char * [] // "argv" is unused -) +int main() { - boost::unit_test::test_suite * test - = BOOST_TEST_SUITE( "I/O state saver test" ); + ios_flags_saver_unit_test(); + ios_precision_saver_unit_test(); + ios_width_saver_unit_test(); - test->add( BOOST_TEST_CASE(ios_flags_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_precision_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_width_saver_unit_test) ); + ios_iostate_saver_unit_test(); + ios_exception_saver_unit_test(); + ios_tie_saver_unit_test(); + ios_rdbuf_saver_unit_test(); + ios_fill_saver_unit_test(); + ios_locale_saver_unit_test(); - test->add( BOOST_TEST_CASE(ios_iostate_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_exception_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_tie_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_rdbuf_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_fill_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_locale_saver_unit_test) ); + ios_iword_saver_unit_test(); + ios_pword_saver_unit_test(); - test->add( BOOST_TEST_CASE(ios_iword_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_pword_saver_unit_test) ); + ios_base_all_saver_unit_test(); + ios_all_saver_unit_test(); + ios_word_saver_unit_test(); - test->add( BOOST_TEST_CASE(ios_base_all_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_all_saver_unit_test) ); - test->add( BOOST_TEST_CASE(ios_word_saver_unit_test) ); - - return test; + return boost::report_errors(); } diff --git a/test/quoted_manip_test.cpp b/test/quoted_manip_test.cpp index 31c6f05..80e6f78 100644 --- a/test/quoted_manip_test.cpp +++ b/test/quoted_manip_test.cpp @@ -10,7 +10,7 @@ // ---------------------------------------------------------------------------------- // #include -#include +#include #include #include diff --git a/test/test_cmake/CMakeLists.txt b/test/test_cmake/CMakeLists.txt new file mode 100644 index 0000000..46bfcf4 --- /dev/null +++ b/test/test_cmake/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright 2018 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt +# +# NOTE: This does NOT run the unit tests for Boost.IO. +# It only tests, if the CMakeLists.txt file in the +# Boost.IO root directory works as expected. + +cmake_minimum_required( VERSION 3.5 ) + +project( BoostIoCMakeSelfTest ) + +add_subdirectory( ../../../config ${CMAKE_CURRENT_BINARY_DIR}/libs/config ) +add_subdirectory( ../.. ${CMAKE_CURRENT_BINARY_DIR}/libs/io ) + +add_executable( boost_io_cmake_self_test main.cpp ) +target_link_libraries( boost_io_cmake_self_test Boost::io ) diff --git a/test/test_cmake/main.cpp b/test/test_cmake/main.cpp new file mode 100644 index 0000000..e5c3372 --- /dev/null +++ b/test/test_cmake/main.cpp @@ -0,0 +1,5 @@ +#include +#include + +int main() { +}