mirror of
https://github.com/boostorg/utility.git
synced 2025-10-06 14:00:55 +02:00
Compare commits
94 Commits
string_vie
...
boost-1.68
Author | SHA1 | Date | |
---|---|---|---|
|
ebe44296ca | ||
|
7709f0e430 | ||
|
eacea4664d | ||
|
1fe5af5264 | ||
|
56f13625b1 | ||
|
ac4e8da91d | ||
|
426836d860 | ||
|
82df2b82fc | ||
|
f8a243bcff | ||
|
51f7f7f53e | ||
|
5f535a151c | ||
|
c88936800d | ||
|
96fbce5759 | ||
|
9d46de1578 | ||
|
976a4d2fc1 | ||
|
ea81279b35 | ||
|
7d101d420c | ||
|
d8acfef27b | ||
|
d7ae336915 | ||
|
b74f49f1e5 | ||
|
5977f11be8 | ||
|
ad0fc7c9d3 | ||
|
a6c175e2c3 | ||
|
874ca2307b | ||
|
5220260145 | ||
|
2f5a6fbcf1 | ||
|
51ba9f1b45 | ||
|
5cef1403b0 | ||
|
81ce4693f6 | ||
|
fb2f110eb4 | ||
|
2ed5ee9588 | ||
|
88c36c1941 | ||
|
0b2409a942 | ||
|
62b39548be | ||
|
2722fdcda3 | ||
|
792d0538d2 | ||
|
06ae661775 | ||
|
d9d076874e | ||
|
e25d85446e | ||
|
5bc9e47688 | ||
|
ec50f22b8b | ||
|
592382dc61 | ||
|
6cf9c22cf1 | ||
|
33475f87e4 | ||
|
21261a8630 | ||
|
7d60e8e378 | ||
|
10ff4d4fcd | ||
|
89bf74beee | ||
|
bfdcce0f97 | ||
|
330b49d602 | ||
|
68b26cddbe | ||
|
6c4ab93573 | ||
|
0876da45db | ||
|
00f02167e3 | ||
|
9960d9f395 | ||
|
ccfd741c0a | ||
|
c5c479d49c | ||
|
3e8f73c6ac | ||
|
38121f2af3 | ||
|
38b536ff05 | ||
|
9ae6492af9 | ||
|
816607e212 | ||
|
a3ab942bc2 | ||
|
0f1f793caf | ||
|
ff445c0ece | ||
|
9fae8be166 | ||
|
b90a28f0e1 | ||
|
febca584d9 | ||
|
21dc552cf9 | ||
|
fda210f597 | ||
|
3d853b0e83 | ||
|
4814d1ebfe | ||
|
e5932ebb08 | ||
|
93a2e25092 | ||
|
39577f86d1 | ||
|
8392991c46 | ||
|
c5b1256650 | ||
|
c56dd13592 | ||
|
181f302ee4 | ||
|
287844fe76 | ||
|
3982b6d633 | ||
|
0b492bee9c | ||
|
a9236d00a9 | ||
|
4313bfc323 | ||
|
f61c94e812 | ||
|
1dfacff7ec | ||
|
a25ac4550b | ||
|
d767054a79 | ||
|
08a1b7da61 | ||
|
8ab8e36dcf | ||
|
1caa745dd7 | ||
|
cf5ad341ed | ||
|
1f6de83fe2 | ||
|
cb6500161b |
206
.travis.yml
Normal file
206
.travis.yml
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# Copyright 2016, 2017 Peter Dimov
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
- /feature\/.*/
|
||||||
|
|
||||||
|
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.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
|
||||||
|
dist: trusty
|
||||||
|
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: clang++
|
||||||
|
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: clang++-3.5
|
||||||
|
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- clang-3.5
|
||||||
|
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
|
||||||
|
- libstdc++-5-dev
|
||||||
|
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
|
||||||
|
- libstdc++-5-dev
|
||||||
|
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++-5-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++-5-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
|
||||||
|
- libstdc++-5-dev
|
||||||
|
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
|
||||||
|
- libstdc++-5-dev
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-5.0
|
||||||
|
|
||||||
|
- 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 --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||||
|
- cd boost-root
|
||||||
|
- git submodule update --init tools/build
|
||||||
|
- git submodule update --init libs/assert
|
||||||
|
- git submodule update --init libs/config
|
||||||
|
- git submodule update --init libs/core
|
||||||
|
- git submodule update --init libs/preprocessor
|
||||||
|
- git submodule update --init libs/static_assert
|
||||||
|
- git submodule update --init libs/throw_exception
|
||||||
|
- git submodule update --init libs/type_traits
|
||||||
|
- cp -r $TRAVIS_BUILD_DIR/* libs/utility
|
||||||
|
- ./bootstrap.sh
|
||||||
|
- ./b2 headers
|
||||||
|
|
||||||
|
script:
|
||||||
|
- |-
|
||||||
|
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
|
||||||
|
- ./b2 -j3 libs/utility/test toolset=$TOOLSET cxxstd=$CXXSTD
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
on_success: always
|
48
appveyor.yml
Normal file
48
appveyor.yml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Copyright 2016, 2017 Peter Dimov
|
||||||
|
# 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
|
||||||
|
- /feature\/.*/
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
|
||||||
|
TOOLSET: msvc-9.0,msvc-10.0,msvc-11.0,msvc-12.0
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
TOOLSET: msvc-14.0
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
|
TOOLSET: msvc-14.1
|
||||||
|
CXXSTD: 14,17
|
||||||
|
|
||||||
|
install:
|
||||||
|
- set BOOST_BRANCH=develop
|
||||||
|
- if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master
|
||||||
|
- cd ..
|
||||||
|
- git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
|
||||||
|
- cd boost-root
|
||||||
|
- git submodule update --init tools/build
|
||||||
|
- git submodule update --init libs/assert
|
||||||
|
- git submodule update --init libs/config
|
||||||
|
- git submodule update --init libs/core
|
||||||
|
- git submodule update --init libs/preprocessor
|
||||||
|
- git submodule update --init libs/static_assert
|
||||||
|
- git submodule update --init libs/throw_exception
|
||||||
|
- git submodule update --init libs/type_traits
|
||||||
|
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility
|
||||||
|
- cmd /c bootstrap
|
||||||
|
- b2 -d0 headers
|
||||||
|
|
||||||
|
build: off
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- PATH=%ADDPATH%%PATH%
|
||||||
|
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
|
||||||
|
- b2 -j3 libs/utility/test toolset=%TOOLSET% %CXXSTD%
|
@@ -117,3 +117,11 @@ boostbook standalone_string_ref
|
|||||||
# How far down we go with TOC's
|
# How far down we go with TOC's
|
||||||
<xsl:param>generate.section.toc.level=1
|
<xsl:param>generate.section.toc.level=1
|
||||||
;
|
;
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
alias boostdoc ;
|
||||||
|
explicit boostdoc ;
|
||||||
|
alias boostrelease :
|
||||||
|
standalone_base_from_member standalone_compressed_pair
|
||||||
|
standalone_declval standalone_string_ref ;
|
||||||
|
explicit boostrelease ;
|
||||||
|
@@ -1,163 +0,0 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Language" content="en-us">
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
|
|
||||||
|
|
||||||
<title>Generator Iterator Adaptor Documentation</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
|
||||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="middle"
|
|
||||||
width="277" height="86">
|
|
||||||
|
|
||||||
<h1>Generator Iterator Adaptor</h1>
|
|
||||||
|
|
||||||
<p>Defined in header <a href=
|
|
||||||
"../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></p>
|
|
||||||
|
|
||||||
<p>The generator iterator adaptor makes it easier to create custom input
|
|
||||||
iterators from 0-ary functions and function objects. The adaptor takes a
|
|
||||||
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a> and
|
|
||||||
creates a model of <a href=
|
|
||||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>. Each
|
|
||||||
increment retrieves an item from the generator and makes it available to be
|
|
||||||
retrieved by dereferencing. The motivation for this iterator is that some
|
|
||||||
concepts can be more naturally expressed as a generator, while most STL
|
|
||||||
algorithms expect an iterator. An example is the <a href=
|
|
||||||
"../random/index.html">Random Number</a> library.</p>
|
|
||||||
|
|
||||||
<h2>Synopsis</h2>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
namespace boost {
|
|
||||||
template <class Generator>
|
|
||||||
class generator_iterator_policies;
|
|
||||||
|
|
||||||
template <class Generator>
|
|
||||||
class generator_iterator_generator;
|
|
||||||
|
|
||||||
template <class Generator>
|
|
||||||
typename generator_iterator_generator<Generator>::type
|
|
||||||
make_generator_iterator(Generator & gen);
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2>The Generator Iterator Generator Class</h2>
|
|
||||||
|
|
||||||
<p>The class generator_iterator_generator is a helper class whose purpose
|
|
||||||
is to construct a generator iterator type. The template parameter for this
|
|
||||||
class is the Generator function object type that is being wrapped. The
|
|
||||||
generator iterator adaptor only holds a reference (or pointer) to the
|
|
||||||
function object, therefore the function object must outlive the generator
|
|
||||||
iterator adaptor constructed from it.</p>
|
|
||||||
<pre>
|
|
||||||
template <class Generator>
|
|
||||||
class generator_iterator_generator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef <i>unspecified</i> type; // the resulting generator iterator type
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h3>Template Parameters</h3>
|
|
||||||
|
|
||||||
<table border summary="">
|
|
||||||
<tr>
|
|
||||||
<th>Parameter</th>
|
|
||||||
|
|
||||||
<th>Description</th>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td><tt><a href=
|
|
||||||
"http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt></td>
|
|
||||||
|
|
||||||
<td>The generator (0-ary function object) type being wrapped. The
|
|
||||||
return type of the function must be defined as
|
|
||||||
<tt>Generator::result_type</tt>. The function object must be a model of
|
|
||||||
<a href=
|
|
||||||
"http://www.sgi.com/tech/stl/Generator.html">Generator</a>.</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>Concept Model</h3>
|
|
||||||
|
|
||||||
<p>The generator iterator class is a model of <a href=
|
|
||||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.</p>
|
|
||||||
|
|
||||||
<h3>Members</h3>
|
|
||||||
|
|
||||||
<p>The generator iterator implements the member functions and operators
|
|
||||||
required of the <a href=
|
|
||||||
"http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
|
|
||||||
concept.<br></p>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2><a name="make_generator_iterator" id="make_generator_iterator">The
|
|
||||||
Generator Iterator Object Generator</a></h2>
|
|
||||||
|
|
||||||
<p>The <tt>make_generator_iterator()</tt> function provides a convenient
|
|
||||||
way to create generator iterator objects. The function saves the user the
|
|
||||||
trouble of explicitly writing out the iterator types.</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
template <class Generator>
|
|
||||||
typename generator_iterator_generator<Generator>::type
|
|
||||||
make_generator_iterator(Generator & gen);
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h3>Example</h3>
|
|
||||||
|
|
||||||
<p>The following program shows how <code>generator_iterator</code>
|
|
||||||
transforms a generator into an input iterator.</p>
|
|
||||||
|
|
||||||
<blockquote>
|
|
||||||
<pre>
|
|
||||||
#include <iostream>
|
|
||||||
#include <boost/generator_iterator.hpp>
|
|
||||||
|
|
||||||
class my_generator
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef int result_type;
|
|
||||||
my_generator() : state(0) { }
|
|
||||||
int operator()() { return ++state; }
|
|
||||||
private:
|
|
||||||
int state;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
my_generator gen;
|
|
||||||
boost::generator_iterator_generator<my_generator>::type it = boost::make_generator_iterator(gen);
|
|
||||||
for(int i = 0; i < 10; ++i, ++it)
|
|
||||||
std::cout << *it << std::endl;
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
</blockquote>
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
|
|
||||||
"../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
|
|
||||||
height="31" width="88"></a></p>
|
|
||||||
|
|
||||||
<p>Revised
|
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
|
|
||||||
|
|
||||||
<p><i>Copyright © 2001 <a href=
|
|
||||||
"http://www.boost.org/people/jens_maurer.htm">Jens Maurer</a></i></p>
|
|
||||||
|
|
||||||
<p><i>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">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,63 +0,0 @@
|
|||||||
//
|
|
||||||
// Copyright 2014 Peter Dimov
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <boost/generator_iterator.hpp>
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
class X
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
int v;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef int result_type;
|
|
||||||
|
|
||||||
X(): v( 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int operator()()
|
|
||||||
{
|
|
||||||
return ++v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n( InputIterator first, Size n, OutputIterator result )
|
|
||||||
{
|
|
||||||
while( n-- > 0 )
|
|
||||||
{
|
|
||||||
*result++ = *first++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_test()
|
|
||||||
{
|
|
||||||
X x;
|
|
||||||
boost::generator_iterator<X> in( &x );
|
|
||||||
|
|
||||||
int const N = 4;
|
|
||||||
int v[ N ] = { 0 };
|
|
||||||
|
|
||||||
::copy_n( in, 4, v );
|
|
||||||
|
|
||||||
BOOST_TEST_EQ( v[0], 1 );
|
|
||||||
BOOST_TEST_EQ( v[1], 2 );
|
|
||||||
BOOST_TEST_EQ( v[2], 3 );
|
|
||||||
BOOST_TEST_EQ( v[3], 4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
copy_test();
|
|
||||||
return boost::report_errors();
|
|
||||||
}
|
|
@@ -1,165 +0,0 @@
|
|||||||
// Boost next_prior.hpp header file ---------------------------------------//
|
|
||||||
|
|
||||||
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. 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)
|
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
|
||||||
|
|
||||||
// Revision History
|
|
||||||
// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker)
|
|
||||||
|
|
||||||
#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
||||||
#define BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1310
|
|
||||||
#include <boost/mpl/and.hpp>
|
|
||||||
#include <boost/type_traits/is_integral.hpp>
|
|
||||||
#endif
|
|
||||||
#include <boost/type_traits/is_unsigned.hpp>
|
|
||||||
#include <boost/type_traits/integral_promotion.hpp>
|
|
||||||
#include <boost/type_traits/make_signed.hpp>
|
|
||||||
#include <boost/type_traits/has_plus.hpp>
|
|
||||||
#include <boost/type_traits/has_plus_assign.hpp>
|
|
||||||
#include <boost/type_traits/has_minus.hpp>
|
|
||||||
#include <boost/type_traits/has_minus_assign.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Helper functions for classes like bidirectional iterators not supporting
|
|
||||||
// operator+ and operator-
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
// const std::list<T>::iterator p = get_some_iterator();
|
|
||||||
// const std::list<T>::iterator prev = boost::prior(p);
|
|
||||||
// const std::list<T>::iterator next = boost::next(prev, 2);
|
|
||||||
|
|
||||||
// Contributed by Dave Abrahams
|
|
||||||
|
|
||||||
namespace next_prior_detail {
|
|
||||||
|
|
||||||
template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
|
|
||||||
struct next_impl2
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
std::advance(x, n);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Distance >
|
|
||||||
struct next_impl2< T, Distance, true >
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
return x + n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value >
|
|
||||||
struct next_impl1 :
|
|
||||||
public next_impl2< T, Distance >
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Distance >
|
|
||||||
struct next_impl1< T, Distance, true >
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
x += n;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<
|
|
||||||
typename T,
|
|
||||||
typename Distance,
|
|
||||||
typename PromotedDistance = typename integral_promotion< Distance >::type,
|
|
||||||
#if !defined(_MSC_VER) || _MSC_VER > 1310
|
|
||||||
bool IsUInt = is_unsigned< PromotedDistance >::value
|
|
||||||
#else
|
|
||||||
// MSVC 7.1 has problems with applying is_unsigned to non-integral types
|
|
||||||
bool IsUInt = mpl::and_< is_integral< PromotedDistance >, is_unsigned< PromotedDistance > >::value
|
|
||||||
#endif
|
|
||||||
>
|
|
||||||
struct prior_impl3
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
std::advance(x, -n);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Distance, typename PromotedDistance >
|
|
||||||
struct prior_impl3< T, Distance, PromotedDistance, true >
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
typedef typename make_signed< PromotedDistance >::type signed_distance;
|
|
||||||
std::advance(x, -static_cast< signed_distance >(static_cast< PromotedDistance >(n)));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
|
|
||||||
struct prior_impl2 :
|
|
||||||
public prior_impl3< T, Distance >
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Distance >
|
|
||||||
struct prior_impl2< T, Distance, true >
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
return x - n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value >
|
|
||||||
struct prior_impl1 :
|
|
||||||
public prior_impl2< T, Distance >
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template< typename T, typename Distance >
|
|
||||||
struct prior_impl1< T, Distance, true >
|
|
||||||
{
|
|
||||||
static T call(T x, Distance n)
|
|
||||||
{
|
|
||||||
x -= n;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace next_prior_detail
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T next(T x) { return ++x; }
|
|
||||||
|
|
||||||
template <class T, class Distance>
|
|
||||||
inline T next(T x, Distance n)
|
|
||||||
{
|
|
||||||
return next_prior_detail::next_impl1< T, Distance >::call(x, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline T prior(T x) { return --x; }
|
|
||||||
|
|
||||||
template <class T, class Distance>
|
|
||||||
inline T prior(T x, Distance n)
|
|
||||||
{
|
|
||||||
return next_prior_detail::prior_impl1< T, Distance >::call(x, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED
|
|
@@ -1,6 +1,7 @@
|
|||||||
// Boost operators.hpp header file ----------------------------------------//
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||||
|
// (C) Copyright Daniel Frey 2002-2017.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -8,6 +9,11 @@
|
|||||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
|
// 23 Nov 17 Protect dereferenceable<> from overloaded operator&.
|
||||||
|
// 15 Oct 17 Adapted to C++17, replace std::iterator<> with manual
|
||||||
|
// implementation.
|
||||||
|
// 22 Feb 16 Added ADL protection, preserve old work-arounds in
|
||||||
|
// operators_v1.hpp and clean up this file. (Daniel Frey)
|
||||||
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||||
// (Matthew Bradbury, fixes #4432)
|
// (Matthew Bradbury, fixes #4432)
|
||||||
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||||
@@ -70,7 +76,7 @@
|
|||||||
// issue at the cost of some simplicity.
|
// issue at the cost of some simplicity.
|
||||||
//
|
//
|
||||||
// One of the complications is an existence of special auxiliary class template
|
// One of the complications is an existence of special auxiliary class template
|
||||||
// 'is_chained_base<>' (see 'detail' namespace below), which is used
|
// 'is_chained_base<>' (see 'operators_detail' namespace below), which is used
|
||||||
// to determine whether its template parameter is a library's operator template
|
// to determine whether its template parameter is a library's operator template
|
||||||
// or not. You have to specialize 'is_chained_base<>' for each new
|
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||||
// operator template you add to the library.
|
// operator template you add to the library.
|
||||||
@@ -82,9 +88,18 @@
|
|||||||
#ifndef BOOST_OPERATORS_HPP
|
#ifndef BOOST_OPERATORS_HPP
|
||||||
#define BOOST_OPERATORS_HPP
|
#define BOOST_OPERATORS_HPP
|
||||||
|
|
||||||
|
// If old work-arounds are needed, refer to the preserved version without
|
||||||
|
// ADL protection.
|
||||||
|
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_USE_OPERATORS_V1)
|
||||||
|
#include "operators_v1.hpp"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/iterator.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/core/addressof.hpp>
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
# pragma set woff 1234
|
# pragma set woff 1234
|
||||||
@@ -94,32 +109,27 @@
|
|||||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||||
#endif // operator-> not begin a UDT
|
#endif // operator-> not begin a UDT
|
||||||
|
|
||||||
namespace boost {
|
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||||
namespace detail {
|
// templates, which are explicitly targeted at the 1-type-argument and
|
||||||
|
// 2-type-argument operator forms, respectively.
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace operators_impl
|
||||||
|
{
|
||||||
|
namespace operators_detail
|
||||||
|
{
|
||||||
|
|
||||||
template <typename T> class empty_base {};
|
template <typename T> class empty_base {};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace operators_detail
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
|
||||||
// templates, which are explicitly targeted at the 1-type-argument and
|
|
||||||
// 2-type-argument operator forms, respectively. Some compilers get confused
|
|
||||||
// when inline friend functions are overloaded in namespaces other than the
|
|
||||||
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
|
|
||||||
// these templates must go in the global namespace.
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||||
|
|
||||||
// Note that friend functions defined in a class are implicitly inline.
|
// Note that friend functions defined in a class are implicitly inline.
|
||||||
// See the C++ std, 11.4 [class.friend] paragraph 5
|
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct less_than_comparable2 : B
|
struct less_than_comparable2 : B
|
||||||
{
|
{
|
||||||
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||||
@@ -130,7 +140,7 @@ struct less_than_comparable2 : B
|
|||||||
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct less_than_comparable1 : B
|
struct less_than_comparable1 : B
|
||||||
{
|
{
|
||||||
friend bool operator>(const T& x, const T& y) { return y < x; }
|
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||||
@@ -138,7 +148,7 @@ struct less_than_comparable1 : B
|
|||||||
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct equality_comparable2 : B
|
struct equality_comparable2 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
@@ -146,7 +156,7 @@ struct equality_comparable2 : B
|
|||||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct equality_comparable1 : B
|
struct equality_comparable1 : B
|
||||||
{
|
{
|
||||||
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||||
@@ -165,7 +175,7 @@ struct equality_comparable1 : B
|
|||||||
// implementation available.
|
// implementation available.
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
@@ -174,7 +184,7 @@ struct NAME##2 : B \
|
|||||||
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
@@ -182,21 +192,21 @@ struct NAME##1 : B \
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
@@ -211,34 +221,34 @@ struct NAME##1 : B \
|
|||||||
// optimization opportunities to the compiler :)
|
// optimization opportunities to the compiler :)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
{ return T( lhs ) OP##= rhs; } \
|
{ return T( lhs ) OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
@@ -261,7 +271,7 @@ BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
|||||||
|
|
||||||
// incrementable and decrementable contributed by Jeremy Siek
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct incrementable : B
|
struct incrementable : B
|
||||||
{
|
{
|
||||||
friend T operator++(T& x, int)
|
friend T operator++(T& x, int)
|
||||||
@@ -274,7 +284,7 @@ private: // The use of this typedef works around a Borland bug
|
|||||||
typedef T incrementable_type;
|
typedef T incrementable_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct decrementable : B
|
struct decrementable : B
|
||||||
{
|
{
|
||||||
friend T operator--(T& x, int)
|
friend T operator--(T& x, int)
|
||||||
@@ -289,16 +299,16 @@ private: // The use of this typedef works around a Borland bug
|
|||||||
|
|
||||||
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct dereferenceable : B
|
struct dereferenceable : B
|
||||||
{
|
{
|
||||||
P operator->() const
|
P operator->() const
|
||||||
{
|
{
|
||||||
return &*static_cast<const T&>(*this);
|
return ::boost::addressof(*static_cast<const T&>(*this));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
|
template <class T, class I, class R, class B = operators_detail::empty_base<T> >
|
||||||
struct indexable : B
|
struct indexable : B
|
||||||
{
|
{
|
||||||
R operator[](I n) const
|
R operator[](I n) const
|
||||||
@@ -313,14 +323,14 @@ struct indexable : B
|
|||||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
@@ -330,13 +340,13 @@ struct NAME##1 : B \
|
|||||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
@@ -349,7 +359,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
|||||||
|
|
||||||
#undef BOOST_BINARY_OPERATOR
|
#undef BOOST_BINARY_OPERATOR
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct equivalent2 : B
|
struct equivalent2 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const T& x, const U& y)
|
friend bool operator==(const T& x, const U& y)
|
||||||
@@ -358,7 +368,7 @@ struct equivalent2 : B
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct equivalent1 : B
|
struct equivalent1 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const T&x, const T&y)
|
friend bool operator==(const T&x, const T&y)
|
||||||
@@ -367,7 +377,7 @@ struct equivalent1 : B
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct partially_ordered2 : B
|
struct partially_ordered2 : B
|
||||||
{
|
{
|
||||||
friend bool operator<=(const T& x, const U& y)
|
friend bool operator<=(const T& x, const U& y)
|
||||||
@@ -384,7 +394,7 @@ struct partially_ordered2 : B
|
|||||||
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct partially_ordered1 : B
|
struct partially_ordered1 : B
|
||||||
{
|
{
|
||||||
friend bool operator>(const T& x, const T& y)
|
friend bool operator>(const T& x, const T& y)
|
||||||
@@ -397,161 +407,161 @@ struct partially_ordered1 : B
|
|||||||
|
|
||||||
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct totally_ordered2
|
struct totally_ordered2
|
||||||
: less_than_comparable2<T, U
|
: less_than_comparable2<T, U
|
||||||
, equality_comparable2<T, U, B
|
, equality_comparable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct totally_ordered1
|
struct totally_ordered1
|
||||||
: less_than_comparable1<T
|
: less_than_comparable1<T
|
||||||
, equality_comparable1<T, B
|
, equality_comparable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct additive2
|
struct additive2
|
||||||
: addable2<T, U
|
: addable2<T, U
|
||||||
, subtractable2<T, U, B
|
, subtractable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct additive1
|
struct additive1
|
||||||
: addable1<T
|
: addable1<T
|
||||||
, subtractable1<T, B
|
, subtractable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct multiplicative2
|
struct multiplicative2
|
||||||
: multipliable2<T, U
|
: multipliable2<T, U
|
||||||
, dividable2<T, U, B
|
, dividable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct multiplicative1
|
struct multiplicative1
|
||||||
: multipliable1<T
|
: multipliable1<T
|
||||||
, dividable1<T, B
|
, dividable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_multiplicative2
|
struct integer_multiplicative2
|
||||||
: multiplicative2<T, U
|
: multiplicative2<T, U
|
||||||
, modable2<T, U, B
|
, modable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_multiplicative1
|
struct integer_multiplicative1
|
||||||
: multiplicative1<T
|
: multiplicative1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct arithmetic2
|
struct arithmetic2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, multiplicative2<T, U, B
|
, multiplicative2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct arithmetic1
|
struct arithmetic1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, multiplicative1<T, B
|
, multiplicative1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_arithmetic2
|
struct integer_arithmetic2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, integer_multiplicative2<T, U, B
|
, integer_multiplicative2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_arithmetic1
|
struct integer_arithmetic1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, integer_multiplicative1<T, B
|
, integer_multiplicative1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct bitwise2
|
struct bitwise2
|
||||||
: xorable2<T, U
|
: xorable2<T, U
|
||||||
, andable2<T, U
|
, andable2<T, U
|
||||||
, orable2<T, U, B
|
, orable2<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct bitwise1
|
struct bitwise1
|
||||||
: xorable1<T
|
: xorable1<T
|
||||||
, andable1<T
|
, andable1<T
|
||||||
, orable1<T, B
|
, orable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct unit_steppable
|
struct unit_steppable
|
||||||
: incrementable<T
|
: incrementable<T
|
||||||
, decrementable<T, B
|
, decrementable<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct shiftable2
|
struct shiftable2
|
||||||
: left_shiftable2<T, U
|
: left_shiftable2<T, U
|
||||||
, right_shiftable2<T, U, B
|
, right_shiftable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct shiftable1
|
struct shiftable1
|
||||||
: left_shiftable1<T
|
: left_shiftable1<T
|
||||||
, right_shiftable1<T, B
|
, right_shiftable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ring_operators2
|
struct ring_operators2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, subtractable2_left<T, U
|
, subtractable2_left<T, U
|
||||||
, multipliable2<T, U, B
|
, multipliable2<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ring_operators1
|
struct ring_operators1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, multipliable1<T, B
|
, multipliable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_ring_operators2
|
struct ordered_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, totally_ordered2<T, U, B
|
, totally_ordered2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_ring_operators1
|
struct ordered_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, totally_ordered1<T, B
|
, totally_ordered1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct field_operators2
|
struct field_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
, dividable2_left<T, U, B
|
, dividable2_left<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct field_operators1
|
struct field_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T, B
|
, dividable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_field_operators2
|
struct ordered_field_operators2
|
||||||
: field_operators2<T, U
|
: field_operators2<T, U
|
||||||
, totally_ordered2<T, U, B
|
, totally_ordered2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_field_operators1
|
struct ordered_field_operators1
|
||||||
: field_operators1<T
|
: field_operators1<T
|
||||||
, totally_ordered1<T, B
|
, totally_ordered1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidian_ring_operators2
|
struct euclidian_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
@@ -560,26 +570,26 @@ struct euclidian_ring_operators2
|
|||||||
, modable2_left<T, U, B
|
, modable2_left<T, U, B
|
||||||
> > > > > {};
|
> > > > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidian_ring_operators1
|
struct euclidian_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T
|
, dividable1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidian_ring_operators2
|
struct ordered_euclidian_ring_operators2
|
||||||
: totally_ordered2<T, U
|
: totally_ordered2<T, U
|
||||||
, euclidian_ring_operators2<T, U, B
|
, euclidian_ring_operators2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidian_ring_operators1
|
struct ordered_euclidian_ring_operators1
|
||||||
: totally_ordered1<T
|
: totally_ordered1<T
|
||||||
, euclidian_ring_operators1<T, B
|
, euclidian_ring_operators1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidean_ring_operators2
|
struct euclidean_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
@@ -588,43 +598,43 @@ struct euclidean_ring_operators2
|
|||||||
, modable2_left<T, U, B
|
, modable2_left<T, U, B
|
||||||
> > > > > {};
|
> > > > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidean_ring_operators1
|
struct euclidean_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T
|
, dividable1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidean_ring_operators2
|
struct ordered_euclidean_ring_operators2
|
||||||
: totally_ordered2<T, U
|
: totally_ordered2<T, U
|
||||||
, euclidean_ring_operators2<T, U, B
|
, euclidean_ring_operators2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidean_ring_operators1
|
struct ordered_euclidean_ring_operators1
|
||||||
: totally_ordered1<T
|
: totally_ordered1<T
|
||||||
, euclidean_ring_operators1<T, B
|
, euclidean_ring_operators1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct input_iteratable
|
struct input_iteratable
|
||||||
: equality_comparable1<T
|
: equality_comparable1<T
|
||||||
, incrementable<T
|
, incrementable<T
|
||||||
, dereferenceable<T, P, B
|
, dereferenceable<T, P, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct output_iteratable
|
struct output_iteratable
|
||||||
: incrementable<T, B
|
: incrementable<T, B
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct forward_iteratable
|
struct forward_iteratable
|
||||||
: input_iteratable<T, P, B
|
: input_iteratable<T, P, B
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct bidirectional_iteratable
|
struct bidirectional_iteratable
|
||||||
: forward_iteratable<T, P
|
: forward_iteratable<T, P
|
||||||
, decrementable<T, B
|
, decrementable<T, B
|
||||||
@@ -634,7 +644,7 @@ struct bidirectional_iteratable
|
|||||||
// which is an indirect base class of bidirectional_iterable,
|
// which is an indirect base class of bidirectional_iterable,
|
||||||
// random_access_iteratable must not be derived from totally_ordered1
|
// random_access_iteratable must not be derived from totally_ordered1
|
||||||
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||||
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> >
|
||||||
struct random_access_iteratable
|
struct random_access_iteratable
|
||||||
: bidirectional_iteratable<T, P
|
: bidirectional_iteratable<T, P
|
||||||
, less_than_comparable1<T
|
, less_than_comparable1<T
|
||||||
@@ -642,124 +652,64 @@ struct random_access_iteratable
|
|||||||
, indexable<T, D, R, B
|
, indexable<T, D, R, B
|
||||||
> > > > {};
|
> > > > {};
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
} // namespace boost
|
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
|
|
||||||
//
|
|
||||||
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
|
||||||
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
|
||||||
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
|
|
||||||
// two-argument forms. Note that these macros expect to be invoked from within
|
|
||||||
// boost.
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
// The template is already in boost so we have nothing to do.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
|
||||||
|
|
||||||
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
# ifndef BOOST_NO_USING_TEMPLATE
|
|
||||||
|
|
||||||
// Bring the names in with a using-declaration
|
|
||||||
// to avoid stressing the compiler.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
|
|
||||||
// from working, we are forced to use inheritance for that compiler.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name) \
|
|
||||||
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, V, W, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name) \
|
|
||||||
template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, V, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name) \
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, B> {};
|
|
||||||
|
|
||||||
# endif // BOOST_NO_USING_TEMPLATE
|
|
||||||
|
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Here's where we put it all together, defining the xxxx forms of the templates
|
// Here's where we put it all together, defining the xxxx forms of the templates.
|
||||||
// in namespace boost. We also define specializations of is_chained_base<> for
|
// We also define specializations of is_chained_base<> for
|
||||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
// the xxxx, xxxx1, and xxxx2 templates.
|
||||||
// necessary.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
namespace operators_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||||
|
// didn't cope well with the more obvious non-type template parameter.
|
||||||
|
struct true_t {};
|
||||||
|
struct false_t {};
|
||||||
|
|
||||||
|
} // namespace operators_detail
|
||||||
|
|
||||||
// is_chained_base<> - a traits class used to distinguish whether an operator
|
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||||
// template argument is being used for base class chaining, or is specifying a
|
// template argument is being used for base class chaining, or is specifying a
|
||||||
// 2nd argument type.
|
// 2nd argument type.
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
// A type parameter is used instead of a plain bool because Borland's compiler
|
|
||||||
// didn't cope well with the more obvious non-type template parameter.
|
|
||||||
namespace detail {
|
|
||||||
struct true_t {};
|
|
||||||
struct false_t {};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
// Unspecialized version assumes that most types are not being used for base
|
// Unspecialized version assumes that most types are not being used for base
|
||||||
// class chaining. We specialize for the operator templates defined in this
|
// class chaining. We specialize for the operator templates defined in this
|
||||||
// library.
|
// library.
|
||||||
template<class T> struct is_chained_base {
|
template<class T> struct is_chained_base {
|
||||||
typedef ::boost::detail::false_t value;
|
typedef operators_detail::false_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boost
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
|
// for a 4-type-argument operator template.
|
||||||
// Import a 4-type-argument operator template into boost (if necessary) and
|
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
|
||||||
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
|
||||||
template<class T, class U, class V, class W, class B> \
|
template<class T, class U, class V, class W, class B> \
|
||||||
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
|
struct is_chained_base< template_name4<T, U, V, W, B> > { \
|
||||||
typedef ::boost::detail::true_t value; \
|
typedef operators_detail::true_t value; \
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 3-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 3-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
|
||||||
template<class T, class U, class V, class B> \
|
template<class T, class U, class V, class B> \
|
||||||
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
|
struct is_chained_base< template_name3<T, U, V, B> > { \
|
||||||
typedef ::boost::detail::true_t value; \
|
typedef operators_detail::true_t value; \
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 2-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 2-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
|
||||||
template<class T, class U, class B> \
|
template<class T, class U, class B> \
|
||||||
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
|
struct is_chained_base< template_name2<T, U, B> > { \
|
||||||
typedef ::boost::detail::true_t value; \
|
typedef operators_detail::true_t value; \
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 1-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 1-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
|
||||||
template<class T, class B> \
|
template<class T, class B> \
|
||||||
struct is_chained_base< ::boost::template_name1<T, B> > { \
|
struct is_chained_base< template_name1<T, B> > { \
|
||||||
typedef ::boost::detail::true_t value; \
|
typedef operators_detail::true_t value; \
|
||||||
};
|
};
|
||||||
|
|
||||||
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||||
@@ -779,31 +729,31 @@ template<class T> struct is_chained_base {
|
|||||||
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||||
template <class T \
|
template <class T \
|
||||||
,class U = T \
|
,class U = T \
|
||||||
,class B = ::boost::detail::empty_base<T> \
|
,class B = operators_detail::empty_base<T> \
|
||||||
,class O = typename is_chained_base<U>::value \
|
,class O = typename is_chained_base<U>::value \
|
||||||
> \
|
> \
|
||||||
struct template_name : template_name##2<T, U, B> {}; \
|
struct template_name; \
|
||||||
\
|
\
|
||||||
template<class T, class U, class B> \
|
template<class T, class U, class B> \
|
||||||
struct template_name<T, U, B, ::boost::detail::true_t> \
|
struct template_name<T, U, B, operators_detail::false_t> \
|
||||||
|
: template_name##2<T, U, B> {}; \
|
||||||
|
\
|
||||||
|
template<class T, class U> \
|
||||||
|
struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \
|
||||||
: template_name##1<T, U> {}; \
|
: template_name##1<T, U> {}; \
|
||||||
\
|
\
|
||||||
template <class T, class B> \
|
template <class T, class B> \
|
||||||
struct template_name<T, T, B, ::boost::detail::false_t> \
|
struct template_name<T, T, B, operators_detail::false_t> \
|
||||||
: template_name##1<T, B> {}; \
|
: template_name##1<T, B> {}; \
|
||||||
\
|
\
|
||||||
template<class T, class U, class B, class O> \
|
template<class T, class U, class B, class O> \
|
||||||
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
|
struct is_chained_base< template_name<T, U, B, O> > { \
|
||||||
typedef ::boost::detail::true_t value; \
|
typedef operators_detail::true_t value; \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||||
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||||
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||||
BOOST_OPERATOR_TEMPLATE(multipliable)
|
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||||
@@ -857,13 +807,7 @@ BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
|||||||
#undef BOOST_OPERATOR_TEMPLATE3
|
#undef BOOST_OPERATOR_TEMPLATE3
|
||||||
#undef BOOST_OPERATOR_TEMPLATE2
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
#undef BOOST_OPERATOR_TEMPLATE1
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE1
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE2
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE3
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE4
|
|
||||||
|
|
||||||
// The following 'operators' classes can only be used portably if the derived class
|
|
||||||
// declares ALL of the required member operators.
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
struct operators2
|
struct operators2
|
||||||
: totally_ordered2<T,U
|
: totally_ordered2<T,U
|
||||||
@@ -884,6 +828,21 @@ template <class T> struct operators<T, T>
|
|||||||
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||||
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
||||||
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
||||||
|
// (Adapted to C++17 by Daniel Frey) --------------------------------------//
|
||||||
|
template <class Category,
|
||||||
|
class T,
|
||||||
|
class Distance = std::ptrdiff_t,
|
||||||
|
class Pointer = T*,
|
||||||
|
class Reference = T&>
|
||||||
|
struct iterator_helper
|
||||||
|
{
|
||||||
|
typedef Category iterator_category;
|
||||||
|
typedef T value_type;
|
||||||
|
typedef Distance difference_type;
|
||||||
|
typedef Pointer pointer;
|
||||||
|
typedef Reference reference;
|
||||||
|
};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
class D = std::ptrdiff_t,
|
class D = std::ptrdiff_t,
|
||||||
@@ -891,13 +850,13 @@ template <class T,
|
|||||||
class R = V const &>
|
class R = V const &>
|
||||||
struct input_iterator_helper
|
struct input_iterator_helper
|
||||||
: input_iteratable<T, P
|
: input_iteratable<T, P
|
||||||
, boost::iterator<std::input_iterator_tag, V, D, P, R
|
, iterator_helper<std::input_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct output_iterator_helper
|
struct output_iterator_helper
|
||||||
: output_iteratable<T
|
: output_iteratable<T
|
||||||
, boost::iterator<std::output_iterator_tag, void, void, void, void
|
, iterator_helper<std::output_iterator_tag, void, void, void, void
|
||||||
> >
|
> >
|
||||||
{
|
{
|
||||||
T& operator*() { return static_cast<T&>(*this); }
|
T& operator*() { return static_cast<T&>(*this); }
|
||||||
@@ -911,7 +870,7 @@ template <class T,
|
|||||||
class R = V&>
|
class R = V&>
|
||||||
struct forward_iterator_helper
|
struct forward_iterator_helper
|
||||||
: forward_iteratable<T, P
|
: forward_iteratable<T, P
|
||||||
, boost::iterator<std::forward_iterator_tag, V, D, P, R
|
, iterator_helper<std::forward_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
@@ -921,7 +880,7 @@ template <class T,
|
|||||||
class R = V&>
|
class R = V&>
|
||||||
struct bidirectional_iterator_helper
|
struct bidirectional_iterator_helper
|
||||||
: bidirectional_iteratable<T, P
|
: bidirectional_iteratable<T, P
|
||||||
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
, iterator_helper<std::bidirectional_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
@@ -931,7 +890,7 @@ template <class T,
|
|||||||
class R = V&>
|
class R = V&>
|
||||||
struct random_access_iterator_helper
|
struct random_access_iterator_helper
|
||||||
: random_access_iteratable<T, P, D, R
|
: random_access_iteratable<T, P, D, R
|
||||||
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
|
, iterator_helper<std::random_access_iterator_tag, V, D, P, R
|
||||||
> >
|
> >
|
||||||
{
|
{
|
||||||
friend D requires_difference_operator(const T& x, const T& y) {
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
@@ -939,10 +898,14 @@ struct random_access_iterator_helper
|
|||||||
}
|
}
|
||||||
}; // random_access_iterator_helper
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
|
} // namespace operators_impl
|
||||||
|
using namespace operators_impl;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
#pragma reset woff 1234
|
#pragma reset woff 1234
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
#endif // BOOST_OPERATORS_HPP
|
#endif // BOOST_OPERATORS_HPP
|
||||||
|
951
include/boost/operators_v1.hpp
Normal file
951
include/boost/operators_v1.hpp
Normal file
@@ -0,0 +1,951 @@
|
|||||||
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
|
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 22 Feb 16 Preserve old work-arounds. (Daniel Frey)
|
||||||
|
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||||
|
// (Matthew Bradbury, fixes #4432)
|
||||||
|
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||||
|
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||||
|
// for T::operator<, etc. (Daniel Frey)
|
||||||
|
// 24 May 07 Changed empty_base to depend on T, see
|
||||||
|
// http://svn.boost.org/trac/boost/ticket/979
|
||||||
|
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
||||||
|
// correct named return value optimization (NRVO) to produce optimal
|
||||||
|
// code. (Daniel Frey)
|
||||||
|
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
||||||
|
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
||||||
|
// 27 Aug 01 'left' form for non commutative operators added;
|
||||||
|
// additional classes for groups of related operators added;
|
||||||
|
// workaround for empty base class optimization
|
||||||
|
// bug of GCC 3.0 (Helmut Zeisel)
|
||||||
|
// 25 Jun 01 output_iterator_helper changes: removed default template
|
||||||
|
// parameters, added support for self-proxying, additional
|
||||||
|
// documentation and tests (Aleksey Gurtovoy)
|
||||||
|
// 29 May 01 Added operator classes for << and >>. Added input and output
|
||||||
|
// iterator helper classes. Added classes to connect equality and
|
||||||
|
// relational operators. Added classes for groups of related
|
||||||
|
// operators. Reimplemented example operator and iterator helper
|
||||||
|
// classes in terms of the new groups. (Daryle Walker, with help
|
||||||
|
// from Alexy Gurtovoy)
|
||||||
|
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
||||||
|
// supplied arguments from actually being used (Dave Abrahams)
|
||||||
|
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||||
|
// refactoring of compiler workarounds, additional documentation
|
||||||
|
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
||||||
|
// Dave Abrahams)
|
||||||
|
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
||||||
|
// Jeremy Siek (Dave Abrahams)
|
||||||
|
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
||||||
|
// (Mark Rodgers)
|
||||||
|
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
||||||
|
// 10 Jun 00 Support for the base class chaining technique was added
|
||||||
|
// (Aleksey Gurtovoy). See documentation and the comments below
|
||||||
|
// for the details.
|
||||||
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
|
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
||||||
|
// specializations of dividable, subtractable, modable (Ed Brey)
|
||||||
|
// 17 Nov 99 Add comments (Beman Dawes)
|
||||||
|
// Remove unnecessary specialization of operators<> (Ed Brey)
|
||||||
|
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
||||||
|
// operators.(Beman Dawes)
|
||||||
|
// 12 Nov 99 Add operators templates (Ed Brey)
|
||||||
|
// 11 Nov 99 Add single template parameter version for compilers without
|
||||||
|
// partial specialization (Beman Dawes)
|
||||||
|
// 10 Nov 99 Initial version
|
||||||
|
|
||||||
|
// 10 Jun 00:
|
||||||
|
// An additional optional template parameter was added to most of
|
||||||
|
// operator templates to support the base class chaining technique (see
|
||||||
|
// documentation for the details). Unfortunately, a straightforward
|
||||||
|
// implementation of this change would have broken compatibility with the
|
||||||
|
// previous version of the library by making it impossible to use the same
|
||||||
|
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
|
||||||
|
// an operator template. This implementation solves the backward-compatibility
|
||||||
|
// issue at the cost of some simplicity.
|
||||||
|
//
|
||||||
|
// One of the complications is an existence of special auxiliary class template
|
||||||
|
// 'is_chained_base<>' (see 'detail' namespace below), which is used
|
||||||
|
// to determine whether its template parameter is a library's operator template
|
||||||
|
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||||
|
// operator template you add to the library.
|
||||||
|
//
|
||||||
|
// However, most of the non-trivial implementation details are hidden behind
|
||||||
|
// several local macros defined below, and as soon as you understand them,
|
||||||
|
// you understand the whole library implementation.
|
||||||
|
|
||||||
|
#ifndef BOOST_OPERATORS_V1_HPP
|
||||||
|
#define BOOST_OPERATORS_V1_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
|
# pragma set woff 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||||
|
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||||
|
#endif // operator-> not begin a UDT
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T> class empty_base {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||||
|
// templates, which are explicitly targeted at the 1-type-argument and
|
||||||
|
// 2-type-argument operator forms, respectively. Some compilers get confused
|
||||||
|
// when inline friend functions are overloaded in namespaces other than the
|
||||||
|
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
|
||||||
|
// these templates must go in the global namespace.
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||||
|
|
||||||
|
// Note that friend functions defined in a class are implicitly inline.
|
||||||
|
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct less_than_comparable2 : B
|
||||||
|
{
|
||||||
|
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||||
|
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
|
||||||
|
friend bool operator>(const U& x, const T& y) { return y < x; }
|
||||||
|
friend bool operator<(const U& x, const T& y) { return y > x; }
|
||||||
|
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||||
|
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct less_than_comparable1 : B
|
||||||
|
{
|
||||||
|
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||||
|
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||||
|
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equality_comparable2 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
|
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||||
|
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equality_comparable1 : B
|
||||||
|
{
|
||||||
|
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A macro which produces "name_2left" from "name".
|
||||||
|
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
|
||||||
|
|
||||||
|
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
// This is the optimal implementation for ISO/ANSI C++,
|
||||||
|
// but it requires the compiler to implement the NRVO.
|
||||||
|
// If the compiler has no NRVO, this is the best symmetric
|
||||||
|
// implementation available.
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
// For compilers without NRVO the following code is optimal, but not
|
||||||
|
// symmetric! Note that the implementation of
|
||||||
|
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
|
||||||
|
// optimization opportunities to the compiler :)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ return T( lhs ) OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
||||||
|
|
||||||
|
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
|
||||||
|
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
|
||||||
|
#undef BOOST_OPERATOR2_LEFT
|
||||||
|
|
||||||
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct incrementable : B
|
||||||
|
{
|
||||||
|
friend T operator++(T& x, int)
|
||||||
|
{
|
||||||
|
incrementable_type nrv(x);
|
||||||
|
++x;
|
||||||
|
return nrv;
|
||||||
|
}
|
||||||
|
private: // The use of this typedef works around a Borland bug
|
||||||
|
typedef T incrementable_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct decrementable : B
|
||||||
|
{
|
||||||
|
friend T operator--(T& x, int)
|
||||||
|
{
|
||||||
|
decrementable_type nrv(x);
|
||||||
|
--x;
|
||||||
|
return nrv;
|
||||||
|
}
|
||||||
|
private: // The use of this typedef works around a Borland bug
|
||||||
|
typedef T decrementable_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct dereferenceable : B
|
||||||
|
{
|
||||||
|
P operator->() const
|
||||||
|
{
|
||||||
|
return &*static_cast<const T&>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct indexable : B
|
||||||
|
{
|
||||||
|
R operator[](I n) const
|
||||||
|
{
|
||||||
|
return *(static_cast<const T&>(*this) + n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||||
|
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
BOOST_BINARY_OPERATOR( left_shiftable, << )
|
||||||
|
BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
||||||
|
|
||||||
|
#undef BOOST_BINARY_OPERATOR
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equivalent2 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T& x, const U& y)
|
||||||
|
{
|
||||||
|
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equivalent1 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T&x, const T&y)
|
||||||
|
{
|
||||||
|
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct partially_ordered2 : B
|
||||||
|
{
|
||||||
|
friend bool operator<=(const T& x, const U& y)
|
||||||
|
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>=(const T& x, const U& y)
|
||||||
|
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>(const U& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<(const U& x, const T& y)
|
||||||
|
{ return y > x; }
|
||||||
|
friend bool operator<=(const U& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
|
||||||
|
friend bool operator>=(const U& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct partially_ordered1 : B
|
||||||
|
{
|
||||||
|
friend bool operator>(const T& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<=(const T& x, const T& y)
|
||||||
|
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>=(const T& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct totally_ordered2
|
||||||
|
: less_than_comparable2<T, U
|
||||||
|
, equality_comparable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct totally_ordered1
|
||||||
|
: less_than_comparable1<T
|
||||||
|
, equality_comparable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct additive2
|
||||||
|
: addable2<T, U
|
||||||
|
, subtractable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct additive1
|
||||||
|
: addable1<T
|
||||||
|
, subtractable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct multiplicative2
|
||||||
|
: multipliable2<T, U
|
||||||
|
, dividable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct multiplicative1
|
||||||
|
: multipliable1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_multiplicative2
|
||||||
|
: multiplicative2<T, U
|
||||||
|
, modable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_multiplicative1
|
||||||
|
: multiplicative1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, integer_multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, integer_multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bitwise2
|
||||||
|
: xorable2<T, U
|
||||||
|
, andable2<T, U
|
||||||
|
, orable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bitwise1
|
||||||
|
: xorable1<T
|
||||||
|
, andable1<T
|
||||||
|
, orable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct unit_steppable
|
||||||
|
: incrementable<T
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct shiftable2
|
||||||
|
: left_shiftable2<T, U
|
||||||
|
, right_shiftable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct shiftable1
|
||||||
|
: left_shiftable1<T
|
||||||
|
, right_shiftable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ring_operators2
|
||||||
|
: additive2<T, U
|
||||||
|
, subtractable2_left<T, U
|
||||||
|
, multipliable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ring_operators1
|
||||||
|
: additive1<T
|
||||||
|
, multipliable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct field_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct field_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_field_operators2
|
||||||
|
: field_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_field_operators1
|
||||||
|
: field_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidian_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U
|
||||||
|
, modable2<T, U
|
||||||
|
, modable2_left<T, U, B
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidian_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidian_ring_operators2
|
||||||
|
: totally_ordered2<T, U
|
||||||
|
, euclidian_ring_operators2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidian_ring_operators1
|
||||||
|
: totally_ordered1<T
|
||||||
|
, euclidian_ring_operators1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidean_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U
|
||||||
|
, modable2<T, U
|
||||||
|
, modable2_left<T, U, B
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidean_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidean_ring_operators2
|
||||||
|
: totally_ordered2<T, U
|
||||||
|
, euclidean_ring_operators2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidean_ring_operators1
|
||||||
|
: totally_ordered1<T
|
||||||
|
, euclidean_ring_operators1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct input_iteratable
|
||||||
|
: equality_comparable1<T
|
||||||
|
, incrementable<T
|
||||||
|
, dereferenceable<T, P, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct output_iteratable
|
||||||
|
: incrementable<T, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct forward_iteratable
|
||||||
|
: input_iteratable<T, P, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bidirectional_iteratable
|
||||||
|
: forward_iteratable<T, P
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
// To avoid repeated derivation from equality_comparable,
|
||||||
|
// which is an indirect base class of bidirectional_iterable,
|
||||||
|
// random_access_iteratable must not be derived from totally_ordered1
|
||||||
|
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||||
|
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct random_access_iteratable
|
||||||
|
: bidirectional_iteratable<T, P
|
||||||
|
, less_than_comparable1<T
|
||||||
|
, additive2<T, D
|
||||||
|
, indexable<T, D, R, B
|
||||||
|
> > > > {};
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
} // namespace boost
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
|
||||||
|
//
|
||||||
|
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
||||||
|
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
||||||
|
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
|
||||||
|
// two-argument forms. Note that these macros expect to be invoked from within
|
||||||
|
// boost.
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
// The template is already in boost so we have nothing to do.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
||||||
|
|
||||||
|
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
# ifndef BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
|
// Bring the names in with a using-declaration
|
||||||
|
// to avoid stressing the compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
|
||||||
|
// from working, we are forced to use inheritance for that compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) \
|
||||||
|
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, V, W, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) \
|
||||||
|
template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, V, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name) \
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, B> {};
|
||||||
|
|
||||||
|
# endif // BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Here's where we put it all together, defining the xxxx forms of the templates
|
||||||
|
// in namespace boost. We also define specializations of is_chained_base<> for
|
||||||
|
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||||
|
// necessary.
|
||||||
|
//
|
||||||
|
|
||||||
|
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||||
|
// template argument is being used for base class chaining, or is specifying a
|
||||||
|
// 2nd argument type.
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||||
|
// didn't cope well with the more obvious non-type template parameter.
|
||||||
|
namespace detail {
|
||||||
|
struct true_t {};
|
||||||
|
struct false_t {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Unspecialized version assumes that most types are not being used for base
|
||||||
|
// class chaining. We specialize for the operator templates defined in this
|
||||||
|
// library.
|
||||||
|
template<class T> struct is_chained_base {
|
||||||
|
typedef ::boost::detail::false_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
// Import a 4-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
|
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
||||||
|
template<class T, class U, class V, class W, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 3-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
|
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
||||||
|
template<class T, class U, class V, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 2-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
|
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
||||||
|
template<class T, class U, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 1-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
|
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
||||||
|
template<class T, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name1<T, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||||
|
// can be used for specifying both 1-argument and 2-argument forms. Requires the
|
||||||
|
// existence of two previously defined class templates named '<template_name>1'
|
||||||
|
// and '<template_name>2' which must implement the corresponding 1- and 2-
|
||||||
|
// argument forms.
|
||||||
|
//
|
||||||
|
// The template type parameter O == is_chained_base<U>::value is used to
|
||||||
|
// distinguish whether the 2nd argument to <template_name> is being used for
|
||||||
|
// base class chaining from another boost operator template or is describing a
|
||||||
|
// 2nd operand type. O == true_t only when U is actually an another operator
|
||||||
|
// template from the library. Partial specialization is used to select an
|
||||||
|
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
||||||
|
//
|
||||||
|
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||||
|
template <class T \
|
||||||
|
,class U = T \
|
||||||
|
,class B = ::boost::detail::empty_base<T> \
|
||||||
|
,class O = typename is_chained_base<U>::value \
|
||||||
|
> \
|
||||||
|
struct template_name : template_name##2<T, U, B> {}; \
|
||||||
|
\
|
||||||
|
template<class T, class U, class B> \
|
||||||
|
struct template_name<T, U, B, ::boost::detail::true_t> \
|
||||||
|
: template_name##1<T, U> {}; \
|
||||||
|
\
|
||||||
|
template <class T, class B> \
|
||||||
|
struct template_name<T, T, B, ::boost::detail::false_t> \
|
||||||
|
: template_name##1<T, B> {}; \
|
||||||
|
\
|
||||||
|
template<class T, class U, class B, class O> \
|
||||||
|
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(addable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(subtractable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(dividable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(modable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(modable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(xorable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(andable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(orable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE3(indexable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(equivalent)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(partially_ordered)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(totally_ordered)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(additive)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(multiplicative)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(arithmetic)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(bitwise)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
||||||
|
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE4
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE3
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE1
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE2
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE3
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE4
|
||||||
|
|
||||||
|
// The following 'operators' classes can only be used portably if the derived class
|
||||||
|
// declares ALL of the required member operators.
|
||||||
|
template <class T, class U>
|
||||||
|
struct operators2
|
||||||
|
: totally_ordered2<T,U
|
||||||
|
, integer_arithmetic2<T,U
|
||||||
|
, bitwise2<T,U
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U = T>
|
||||||
|
struct operators : operators2<T, U> {};
|
||||||
|
|
||||||
|
template <class T> struct operators<T, T>
|
||||||
|
: totally_ordered<T
|
||||||
|
, integer_arithmetic<T
|
||||||
|
, bitwise<T
|
||||||
|
, unit_steppable<T
|
||||||
|
> > > > {};
|
||||||
|
|
||||||
|
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||||
|
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
||||||
|
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V const *,
|
||||||
|
class R = V const &>
|
||||||
|
struct input_iterator_helper
|
||||||
|
: input_iteratable<T, P
|
||||||
|
, std::iterator<std::input_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct output_iterator_helper
|
||||||
|
: output_iteratable<T
|
||||||
|
, std::iterator<std::output_iterator_tag, void, void, void, void
|
||||||
|
> >
|
||||||
|
{
|
||||||
|
T& operator*() { return static_cast<T&>(*this); }
|
||||||
|
T& operator++() { return static_cast<T&>(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct forward_iterator_helper
|
||||||
|
: forward_iteratable<T, P
|
||||||
|
, std::iterator<std::forward_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct bidirectional_iterator_helper
|
||||||
|
: bidirectional_iteratable<T, P
|
||||||
|
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct random_access_iterator_helper
|
||||||
|
: random_access_iteratable<T, P, D, R
|
||||||
|
, std::iterator<std::random_access_iterator_tag, V, D, P, R
|
||||||
|
> >
|
||||||
|
{
|
||||||
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
|
return x - y;
|
||||||
|
}
|
||||||
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
|
#pragma reset woff 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_OPERATORS_V1_HPP
|
@@ -9,13 +9,16 @@
|
|||||||
#ifndef BOOST_UTILITY_HPP
|
#ifndef BOOST_UTILITY_HPP
|
||||||
#define BOOST_UTILITY_HPP
|
#define BOOST_UTILITY_HPP
|
||||||
|
|
||||||
#include <boost/utility/addressof.hpp>
|
// Use of this header is discouraged and it will be deprecated.
|
||||||
|
// Please include one or more of the headers below instead.
|
||||||
|
|
||||||
#include <boost/utility/base_from_member.hpp>
|
#include <boost/utility/base_from_member.hpp>
|
||||||
#include <boost/utility/binary.hpp>
|
#include <boost/utility/binary.hpp>
|
||||||
#include <boost/utility/enable_if.hpp>
|
|
||||||
#include <boost/utility/identity_type.hpp>
|
#include <boost/utility/identity_type.hpp>
|
||||||
#include <boost/checked_delete.hpp>
|
|
||||||
#include <boost/next_prior.hpp>
|
#include <boost/core/addressof.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/core/enable_if.hpp>
|
||||||
|
#include <boost/core/checked_delete.hpp>
|
||||||
|
#include <boost/core/noncopyable.hpp>
|
||||||
|
|
||||||
#endif // BOOST_UTILITY_HPP
|
#endif // BOOST_UTILITY_HPP
|
||||||
|
@@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
|
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||||
explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
||||||
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
|
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
|
||||||
{} \
|
{} \
|
||||||
/**/
|
/**/
|
||||||
@@ -142,7 +142,8 @@ protected:
|
|||||||
: member()
|
: member()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
template < typename T0 > explicit base_from_member( T0 x0 ) : member( x0 ) {}
|
||||||
|
BOOST_PP_REPEAT_FROM_TO( 2, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||||
BOOST_PRIVATE_CTR_DEF, _ )
|
BOOST_PRIVATE_CTR_DEF, _ )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -33,8 +33,12 @@ bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class OptionalPointee>
|
template<class OptionalPointee>
|
||||||
struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
|
struct equal_pointees_t
|
||||||
{
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
typedef OptionalPointee first_argument_type;
|
||||||
|
typedef OptionalPointee second_argument_type;
|
||||||
|
|
||||||
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
||||||
{ return equal_pointees(x,y) ; }
|
{ return equal_pointees(x,y) ; }
|
||||||
} ;
|
} ;
|
||||||
@@ -56,8 +60,12 @@ bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y )
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class OptionalPointee>
|
template<class OptionalPointee>
|
||||||
struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
|
struct less_pointees_t
|
||||||
{
|
{
|
||||||
|
typedef bool result_type;
|
||||||
|
typedef OptionalPointee first_argument_type;
|
||||||
|
typedef OptionalPointee second_argument_type;
|
||||||
|
|
||||||
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
|
||||||
{ return less_pointees(x,y) ; }
|
{ return less_pointees(x,y) ; }
|
||||||
} ;
|
} ;
|
||||||
|
58
include/boost/utility/detail/minstd_rand.hpp
Normal file
58
include/boost/utility/detail/minstd_rand.hpp
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
||||||
|
#define BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
||||||
|
|
||||||
|
// Copyright 2017 Peter Dimov
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// An implementation of minstd_rand that does not require
|
||||||
|
// the Random library
|
||||||
|
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class minstd_rand
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
boost::uint_least32_t x_;
|
||||||
|
|
||||||
|
enum { a = 48271, m = 2147483647 };
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
minstd_rand(): x_( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit minstd_rand( boost::uint_least32_t x ): x_( x % m )
|
||||||
|
{
|
||||||
|
if( x_ == 0 )
|
||||||
|
{
|
||||||
|
x_ = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::uint_least32_t operator()()
|
||||||
|
{
|
||||||
|
boost::uint_least64_t y = x_;
|
||||||
|
|
||||||
|
y = ( a * y ) % m;
|
||||||
|
|
||||||
|
x_ = static_cast<boost::uint_least32_t>( y );
|
||||||
|
|
||||||
|
return x_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // #ifndef BOOST_UTILITY_DETAIL_MINSTD_RAND_HPP_INCLUDED
|
@@ -25,16 +25,16 @@
|
|||||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
: mpl::if_<
|
: conditional<
|
||||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
is_pointer<F>::value || is_member_function_pointer<F>::value
|
||||||
, boost::detail::tr1_result_of_impl<
|
, boost::detail::tr1_result_of_impl<
|
||||||
typename remove_cv<F>::type,
|
typename remove_cv<F>::type,
|
||||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
||||||
(boost::detail::has_result_type<F>::value)>
|
(boost::detail::result_of_has_result_type<F>::value)>
|
||||||
, boost::detail::tr1_result_of_impl<
|
, boost::detail::tr1_result_of_impl<
|
||||||
F,
|
F,
|
||||||
F(BOOST_RESULT_OF_ARGS),
|
F(BOOST_RESULT_OF_ARGS),
|
||||||
(boost::detail::has_result_type<F>::value)> >::type { };
|
(boost::detail::result_of_has_result_type<F>::value)> >::type { };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
@@ -46,7 +46,7 @@ struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
|||||||
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
: mpl::if_<mpl::or_<detail::has_result_type<F>, detail::has_result<F> >,
|
: conditional<detail::result_of_has_result_type<F>::value || detail::result_of_has_result<F>::value,
|
||||||
tr1_result_of<F(BOOST_RESULT_OF_ARGS)>,
|
tr1_result_of<F(BOOST_RESULT_OF_ARGS)>,
|
||||||
detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
|
detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
|
||||||
#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
@@ -57,8 +57,8 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
: mpl::if_<
|
: conditional<
|
||||||
is_member_function_pointer<F>
|
is_member_function_pointer<F>::value
|
||||||
, detail::tr1_result_of_impl<
|
, detail::tr1_result_of_impl<
|
||||||
typename remove_cv<F>::type,
|
typename remove_cv<F>::type,
|
||||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||||
@@ -82,25 +82,22 @@ struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION());
|
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())
|
||||||
|
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
|
||||||
|
{};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *>
|
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F *>
|
||||||
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
|
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename F>
|
|
||||||
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<F &>
|
|
||||||
: BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<F>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
|
struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
|
||||||
: mpl::eval_if<
|
: conditional<
|
||||||
is_class<typename remove_reference<F>::type>,
|
is_class<typename remove_reference<F>::type>::value,
|
||||||
result_of_wrap_callable_class<F>,
|
result_of_wrap_callable_class<F>,
|
||||||
mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> >
|
type_identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<typename remove_reference<F>::type>::type> >
|
||||||
>
|
>::type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
|
||||||
@@ -111,7 +108,7 @@ struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) {
|
|||||||
(boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type())
|
(boost::declval<wrapper_t>()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)), result_of_weird_type())
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
typedef mpl::bool_<value> type;
|
typedef integral_constant<bool, value> type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
|
@@ -18,19 +18,16 @@
|
|||||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/mpl/has_xxx.hpp>
|
|
||||||
#include <boost/mpl/if.hpp>
|
|
||||||
#include <boost/mpl/eval_if.hpp>
|
|
||||||
#include <boost/mpl/bool.hpp>
|
|
||||||
#include <boost/mpl/identity.hpp>
|
|
||||||
#include <boost/mpl/or.hpp>
|
|
||||||
#include <boost/type_traits/is_class.hpp>
|
#include <boost/type_traits/is_class.hpp>
|
||||||
#include <boost/type_traits/is_pointer.hpp>
|
#include <boost/type_traits/is_pointer.hpp>
|
||||||
#include <boost/type_traits/is_member_function_pointer.hpp>
|
#include <boost/type_traits/is_member_function_pointer.hpp>
|
||||||
#include <boost/type_traits/remove_cv.hpp>
|
#include <boost/type_traits/remove_cv.hpp>
|
||||||
#include <boost/type_traits/remove_reference.hpp>
|
#include <boost/type_traits/remove_reference.hpp>
|
||||||
#include <boost/utility/declval.hpp>
|
#include <boost/type_traits/declval.hpp>
|
||||||
#include <boost/utility/enable_if.hpp>
|
#include <boost/type_traits/conditional.hpp>
|
||||||
|
#include <boost/type_traits/type_identity.hpp>
|
||||||
|
#include <boost/type_traits/integral_constant.hpp>
|
||||||
|
#include <boost/core/enable_if.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||||
# define BOOST_RESULT_OF_NUM_ARGS 16
|
# define BOOST_RESULT_OF_NUM_ARGS 16
|
||||||
@@ -47,10 +44,6 @@
|
|||||||
BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
|
BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
|
|
||||||
# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef BOOST_RESULT_OF_USE_TR1
|
#ifndef BOOST_RESULT_OF_USE_TR1
|
||||||
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
|
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
@@ -71,11 +64,40 @@ template<typename F> struct tr1_result_of; // a TR1-style implementation of resu
|
|||||||
#if !defined(BOOST_NO_SFINAE)
|
#if !defined(BOOST_NO_SFINAE)
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
|
||||||
|
typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
|
||||||
|
|
||||||
|
template<class T> struct result_of_has_type {};
|
||||||
|
|
||||||
|
template<class T> struct result_of_has_result_type_impl
|
||||||
|
{
|
||||||
|
template<class U> static result_of_yes_type f( result_of_has_type<typename U::result_type>* );
|
||||||
|
template<class U> static result_of_no_type f( ... );
|
||||||
|
|
||||||
|
typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct result_of_has_result_type: result_of_has_result_type_impl<T>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
// Work around a nvcc bug by only defining has_result when it's needed.
|
// Work around a nvcc bug by only defining has_result when it's needed.
|
||||||
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
|
||||||
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
|
|
||||||
|
template<template<class> class C> struct result_of_has_template {};
|
||||||
|
|
||||||
|
template<class T> struct result_of_has_result_impl
|
||||||
|
{
|
||||||
|
template<class U> static result_of_yes_type f( result_of_has_template<U::template result>* );
|
||||||
|
template<class U> static result_of_no_type f( ... );
|
||||||
|
|
||||||
|
typedef boost::integral_constant<bool, sizeof(f<T>(0)) == sizeof(result_of_yes_type)> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct result_of_has_result: result_of_has_result_impl<T>::type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
||||||
@@ -97,9 +119,6 @@ struct result_of_weird_type {
|
|||||||
friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
|
friend result_of_private_type operator,(result_of_private_type, result_of_weird_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef char result_of_yes_type; // sizeof(result_of_yes_type) == 1
|
|
||||||
typedef char (&result_of_no_type)[2]; // sizeof(result_of_no_type) == 2
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
result_of_no_type result_of_is_private_type(T const &);
|
result_of_no_type result_of_is_private_type(T const &);
|
||||||
result_of_yes_type result_of_is_private_type(result_of_private_type);
|
result_of_yes_type result_of_is_private_type(result_of_private_type);
|
||||||
@@ -180,10 +199,10 @@ struct tr1_result_of_impl<F, FArgs, true>
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename FArgs>
|
template<typename FArgs>
|
||||||
struct is_function_with_no_args : mpl::false_ {};
|
struct is_function_with_no_args : false_type {};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
struct is_function_with_no_args<F(void)> : mpl::true_ {};
|
struct is_function_with_no_args<F(void)> : true_type {};
|
||||||
|
|
||||||
template<typename F, typename FArgs>
|
template<typename F, typename FArgs>
|
||||||
struct result_of_nested_result : F::template result<FArgs>
|
struct result_of_nested_result : F::template result<FArgs>
|
||||||
@@ -191,7 +210,7 @@ struct result_of_nested_result : F::template result<FArgs>
|
|||||||
|
|
||||||
template<typename F, typename FArgs>
|
template<typename F, typename FArgs>
|
||||||
struct tr1_result_of_impl<F, FArgs, false>
|
struct tr1_result_of_impl<F, FArgs, false>
|
||||||
: mpl::if_<is_function_with_no_args<FArgs>,
|
: conditional<is_function_with_no_args<FArgs>::value,
|
||||||
result_of_void_impl<F>,
|
result_of_void_impl<F>,
|
||||||
result_of_nested_result<F, FArgs> >::type
|
result_of_nested_result<F, FArgs> >::type
|
||||||
{};
|
{};
|
||||||
@@ -201,6 +220,11 @@ struct tr1_result_of_impl<F, FArgs, false>
|
|||||||
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
|
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
|
||||||
#include BOOST_PP_ITERATE()
|
#include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// inform dependency trackers, as they can't see through macro includes
|
||||||
|
#include <boost/utility/detail/result_of_iterate.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# define BOOST_NO_RESULT_OF 1
|
# define BOOST_NO_RESULT_OF 1
|
||||||
#endif
|
#endif
|
||||||
|
@@ -27,6 +27,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||||
|
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
|
||||||
|
#define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -57,26 +62,44 @@ namespace boost {
|
|||||||
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
||||||
|
|
||||||
// construct/copy
|
// construct/copy
|
||||||
BOOST_CONSTEXPR basic_string_ref ()
|
BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT
|
||||||
: ptr_(NULL), len_(0) {}
|
: ptr_(NULL), len_(0) {}
|
||||||
|
|
||||||
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs)
|
// by defaulting these functions, basic_string_ref becomes
|
||||||
|
// trivially copy/move constructible.
|
||||||
|
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_string_ref& operator=(const basic_string_ref &rhs) {
|
basic_string_ref& operator=(const basic_string_ref &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
|
{
|
||||||
ptr_ = rhs.ptr_;
|
ptr_ = rhs.ptr_;
|
||||||
len_ = rhs.len_;
|
len_ = rhs.len_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_string_ref(const charT* str)
|
basic_string_ref(const charT* str) BOOST_NOEXCEPT
|
||||||
: ptr_(str), len_(traits::length(str)) {}
|
: ptr_(str), len_(traits::length(str)) {}
|
||||||
|
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
|
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
|
||||||
: ptr_(str.data()), len_(str.length()) {}
|
: ptr_(str.data()), len_(str.length()) {}
|
||||||
|
|
||||||
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len)
|
// #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||||
|
// // Constructing a string_ref from a temporary string is a bad idea
|
||||||
|
// template<typename Allocator>
|
||||||
|
// basic_string_ref( std::basic_string<charT, traits, Allocator>&&)
|
||||||
|
// = delete;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT
|
||||||
: ptr_(str), len_(len) {}
|
: ptr_(str), len_(len) {}
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
@@ -139,9 +162,7 @@ namespace boost {
|
|||||||
basic_string_ref substr(size_type pos, size_type n=npos) const {
|
basic_string_ref substr(size_type pos, size_type n=npos) const {
|
||||||
if ( pos > size())
|
if ( pos > size())
|
||||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
|
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
|
||||||
if ( n == npos || pos + n > size())
|
return basic_string_ref(data() + pos, (std::min)(size() - pos, n));
|
||||||
n = size () - pos;
|
|
||||||
return basic_string_ref ( data() + pos, n );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare(basic_string_ref x) const {
|
int compare(basic_string_ref x) const {
|
||||||
@@ -174,13 +195,13 @@ namespace boost {
|
|||||||
size_type rfind(basic_string_ref s) const {
|
size_type rfind(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
|
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
|
||||||
s.crbegin (), s.crend (), traits::eq );
|
s.crbegin (), s.crend (), traits::eq );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type rfind(charT c) const {
|
size_type rfind(charT c) const {
|
||||||
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
|
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
|
||||||
detail::string_ref_traits_eq<charT, traits> ( c ));
|
detail::string_ref_traits_eq<charT, traits> ( c ));
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_first_of(charT c) const { return find (c); }
|
size_type find_first_of(charT c) const { return find (c); }
|
||||||
@@ -195,7 +216,7 @@ namespace boost {
|
|||||||
size_type find_last_of(basic_string_ref s) const {
|
size_type find_last_of(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = std::find_first_of
|
const_reverse_iterator iter = std::find_first_of
|
||||||
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
|
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_first_not_of(basic_string_ref s) const {
|
size_type find_first_not_of(basic_string_ref s) const {
|
||||||
@@ -212,21 +233,17 @@ namespace boost {
|
|||||||
|
|
||||||
size_type find_last_not_of(basic_string_ref s) const {
|
size_type find_last_not_of(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
|
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_last_not_of(charT c) const {
|
size_type find_last_not_of(charT c) const {
|
||||||
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
|
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
|
||||||
if ( !traits::eq ( c, *iter ))
|
if ( !traits::eq ( c, *iter ))
|
||||||
return reverse_distance ( this->crbegin (), iter );
|
return this->size() - 1 - std::distance(this->crbegin(), iter);
|
||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename r_iter>
|
|
||||||
size_type reverse_distance ( r_iter first, r_iter last ) const {
|
|
||||||
return len_ - 1 - std::distance ( first, last );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
|
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
|
||||||
@@ -405,7 +422,7 @@ namespace boost {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline void insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
inline void sr_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
||||||
enum { chunk_size = 8 };
|
enum { chunk_size = 8 };
|
||||||
charT fill_chars[chunk_size];
|
charT fill_chars[chunk_size];
|
||||||
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
||||||
@@ -416,19 +433,19 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
void insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
void sr_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
||||||
const std::size_t size = str.size();
|
const std::size_t size = str.size();
|
||||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
||||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
||||||
if (!align_left) {
|
if (!align_left) {
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sr_insert_fill_chars(os, alignment_size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sr_insert_fill_chars(os, alignment_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +461,7 @@ namespace boost {
|
|||||||
if (w <= size)
|
if (w <= size)
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
else
|
else
|
||||||
detail::insert_aligned(os, str);
|
detail::sr_insert_aligned(os, str);
|
||||||
os.width(0);
|
os.width(0);
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
|
705
include/boost/utility/string_view.hpp
Normal file
705
include/boost/utility/string_view.hpp
Normal file
@@ -0,0 +1,705 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2012-2015.
|
||||||
|
Copyright (c) Beman Dawes 2015
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
|
||||||
|
Based on the StringRef implementation in LLVM (http://llvm.org) and
|
||||||
|
N3422 by Jeffrey Yasskin
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
|
||||||
|
Updated July 2015 to reflect the Library Fundamentals TS
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_STRING_VIEW_HPP
|
||||||
|
#define BOOST_STRING_VIEW_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
#include <boost/utility/string_view_fwd.hpp>
|
||||||
|
#include <boost/throw_exception.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||||
|
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
|
||||||
|
#define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
// A helper functor because sometimes we don't have lambdas
|
||||||
|
template <typename charT, typename traits>
|
||||||
|
class string_view_traits_eq {
|
||||||
|
public:
|
||||||
|
string_view_traits_eq ( charT ch ) : ch_(ch) {}
|
||||||
|
bool operator()( charT val ) const { return traits::eq (ch_, val); }
|
||||||
|
charT ch_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits> // traits defaulted in string_view_fwd.hpp
|
||||||
|
class basic_string_view {
|
||||||
|
public:
|
||||||
|
// types
|
||||||
|
typedef traits traits_type;
|
||||||
|
typedef charT value_type;
|
||||||
|
typedef charT* pointer;
|
||||||
|
typedef const charT* const_pointer;
|
||||||
|
typedef charT& reference;
|
||||||
|
typedef const charT& const_reference;
|
||||||
|
typedef const_pointer const_iterator; // impl-defined
|
||||||
|
typedef const_iterator iterator;
|
||||||
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
|
typedef const_reverse_iterator reverse_iterator;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
||||||
|
|
||||||
|
// construct/copy
|
||||||
|
BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
|
||||||
|
: ptr_(NULL), len_(0) {}
|
||||||
|
|
||||||
|
// by defaulting these functions, basic_string_ref becomes
|
||||||
|
// trivially copy/move constructible.
|
||||||
|
BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
|
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
ptr_ = rhs.ptr_;
|
||||||
|
len_ = rhs.len_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename Allocator>
|
||||||
|
basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT
|
||||||
|
: ptr_(str.data()), len_(str.length()) {}
|
||||||
|
|
||||||
|
// #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||||
|
// // Constructing a string_view from a temporary string is a bad idea
|
||||||
|
// template<typename Allocator>
|
||||||
|
// basic_string_view( std::basic_string<charT, traits, Allocator>&&)
|
||||||
|
// = delete;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR basic_string_view(const charT* str)
|
||||||
|
: ptr_(str), len_(traits::length(str)) {}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len)
|
||||||
|
: ptr_(str), len_(len) {}
|
||||||
|
|
||||||
|
// iterators
|
||||||
|
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
|
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
|
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
||||||
|
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
||||||
|
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
|
||||||
|
const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
|
||||||
|
const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
|
||||||
|
const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
|
||||||
|
|
||||||
|
// capacity
|
||||||
|
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
|
||||||
|
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
|
||||||
|
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; }
|
||||||
|
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
|
||||||
|
|
||||||
|
// element access
|
||||||
|
BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR const_reference at(size_t pos) const {
|
||||||
|
return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
|
||||||
|
BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
|
||||||
|
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
|
|
||||||
|
// modifiers
|
||||||
|
void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n) {
|
||||||
|
if ( n > len_ )
|
||||||
|
n = len_;
|
||||||
|
ptr_ += n;
|
||||||
|
len_ -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n) {
|
||||||
|
if ( n > len_ )
|
||||||
|
n = len_;
|
||||||
|
len_ -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT {
|
||||||
|
std::swap(ptr_, s.ptr_);
|
||||||
|
std::swap(len_, s.len_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// basic_string_view string operations
|
||||||
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
|
template<typename Allocator>
|
||||||
|
explicit operator std::basic_string<charT, traits, Allocator>() const {
|
||||||
|
return std::basic_string<charT, traits, Allocator>(begin(), end());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
|
||||||
|
template<typename Allocator = std::allocator<charT> >
|
||||||
|
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
|
||||||
|
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
std::basic_string<charT, traits> to_string() const {
|
||||||
|
return std::basic_string<charT, traits>(begin(), end());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Allocator>
|
||||||
|
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
|
||||||
|
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_type copy(charT* s, size_type n, size_type pos=0) const {
|
||||||
|
if (pos > size())
|
||||||
|
BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
|
||||||
|
size_type rlen = (std::min)(n, len_ - pos);
|
||||||
|
traits_type::copy(s, data() + pos, rlen);
|
||||||
|
return rlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
|
||||||
|
if ( pos > size())
|
||||||
|
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
|
||||||
|
return basic_string_view(data() + pos, (std::min)(size() - pos, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
|
||||||
|
const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_));
|
||||||
|
return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
|
||||||
|
const BOOST_NOEXCEPT {
|
||||||
|
return substr(pos1, n1).compare(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
||||||
|
basic_string_view x, size_type pos2, size_type n2) const {
|
||||||
|
return substr(pos1, n1).compare(x.substr(pos2, n2));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
|
||||||
|
return compare(basic_string_view(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
|
||||||
|
return substr(pos1, n1).compare(basic_string_view(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
||||||
|
const charT* x, size_type n2) const {
|
||||||
|
return substr(pos1, n1).compare(basic_string_view(x, n2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches
|
||||||
|
BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension
|
||||||
|
return !empty() && traits::eq(c, front());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
|
||||||
|
return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT { // Boost extension
|
||||||
|
return !empty() && traits::eq(c, back());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
|
||||||
|
return len_ >= x.len_ &&
|
||||||
|
traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
|
||||||
|
if (pos > size())
|
||||||
|
return npos;
|
||||||
|
if (s.empty())
|
||||||
|
return pos;
|
||||||
|
if (s.size() > size() - pos)
|
||||||
|
return npos;
|
||||||
|
const charT* cur = ptr_ + pos;
|
||||||
|
const charT* last = cend() - s.size() + 1;
|
||||||
|
for (; cur != last ; ++cur) {
|
||||||
|
cur = traits::find(cur, last - cur, s[0]);
|
||||||
|
if (!cur)
|
||||||
|
return npos;
|
||||||
|
if (traits::compare(cur, s.cbegin(), s.size()) == 0)
|
||||||
|
return cur - ptr_;
|
||||||
|
}
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT {
|
||||||
|
if (pos > size())
|
||||||
|
return npos;
|
||||||
|
const charT* ret_ptr = traits::find(ptr_ + pos, len_ - pos, c);
|
||||||
|
if (ret_ptr)
|
||||||
|
return ret_ptr - ptr_;
|
||||||
|
return npos;
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return find(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
|
{ return find(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
// rfind
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
||||||
|
if (len_ < s.len_)
|
||||||
|
return npos;
|
||||||
|
if (pos > len_ - s.len_)
|
||||||
|
pos = len_ - s.len_;
|
||||||
|
if (s.len_ == 0u) // an empty string is always found
|
||||||
|
return pos;
|
||||||
|
for (const charT* cur = ptr_ + pos; ; --cur) {
|
||||||
|
if (traits::compare(cur, s.ptr_, s.len_) == 0)
|
||||||
|
return cur - ptr_;
|
||||||
|
if (cur == ptr_)
|
||||||
|
return npos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return rfind(basic_string_view(&c, 1), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return rfind(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return rfind(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
// find_first_of
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
|
||||||
|
if (pos >= len_ || s.len_ == 0)
|
||||||
|
return npos;
|
||||||
|
const_iterator iter = std::find_first_of
|
||||||
|
(this->cbegin () + pos, this->cend (), s.cbegin (), s.cend (), traits::eq);
|
||||||
|
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
|
{ return find(c, pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return find_first_of(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
|
{ return find_first_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
// find_last_of
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
||||||
|
if (s.len_ == 0u)
|
||||||
|
return npos;
|
||||||
|
if (pos >= len_)
|
||||||
|
pos = 0;
|
||||||
|
else
|
||||||
|
pos = len_ - (pos+1);
|
||||||
|
const_reverse_iterator iter = std::find_first_of
|
||||||
|
( this->crbegin () + pos, this->crend (), s.cbegin (), s.cend (), traits::eq );
|
||||||
|
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_of(basic_string_view(&c, 1), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_of(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
// find_first_not_of
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT {
|
||||||
|
if (pos >= len_)
|
||||||
|
return npos;
|
||||||
|
if (s.len_ == 0)
|
||||||
|
return pos;
|
||||||
|
const_iterator iter = find_not_of ( this->cbegin () + pos, this->cend (), s );
|
||||||
|
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
|
{ return find_first_not_of(basic_string_view(&c, 1), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return find_first_not_of(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
|
{ return find_first_not_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
// find_last_not_of
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
||||||
|
if (pos >= len_)
|
||||||
|
pos = len_ - 1;
|
||||||
|
if (s.len_ == 0u)
|
||||||
|
return pos;
|
||||||
|
pos = len_ - (pos+1);
|
||||||
|
const_reverse_iterator iter = find_not_of ( this->crbegin () + pos, this->crend (), s );
|
||||||
|
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
||||||
|
}
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_not_of(basic_string_view(&c, 1), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_not_of(basic_string_view(s, n), pos); }
|
||||||
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
|
{ return find_last_not_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename r_iter>
|
||||||
|
size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
|
||||||
|
// Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
|
||||||
|
return len_ - 1 - std::distance ( first, last );
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
|
||||||
|
for (; first != last ; ++first)
|
||||||
|
if ( 0 == traits::find(s.ptr_, s.len_, *first))
|
||||||
|
return first;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
const charT *ptr_;
|
||||||
|
std::size_t len_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Comparison operators
|
||||||
|
// Equality
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
if (x.size () != y.size ()) return false;
|
||||||
|
return x.compare(y) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inequality
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
if ( x.size () != y.size ()) return true;
|
||||||
|
return x.compare(y) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less than
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return x.compare(y) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Greater than
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return x.compare(y) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Less than or equal to
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return x.compare(y) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Greater than or equal to
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return x.compare(y) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "sufficient additional overloads of comparison functions"
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x == basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x == basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x != basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) != y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x != basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) != y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x < basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) < y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x < basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) < y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x > basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) > y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x > basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) > y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x <= basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) <= y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x <= basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) <= y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
|
||||||
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
|
return x >= basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename Allocator>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) >= y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x,
|
||||||
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
|
return x >= basic_string_view<charT, traits>(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits>
|
||||||
|
inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x,
|
||||||
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
|
return basic_string_view<charT, traits>(x) >= y;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class charT, class traits>
|
||||||
|
inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
||||||
|
enum { chunk_size = 8 };
|
||||||
|
charT fill_chars[chunk_size];
|
||||||
|
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
||||||
|
for (; n >= chunk_size && os.good(); n -= chunk_size)
|
||||||
|
os.write(fill_chars, static_cast< std::size_t >(chunk_size));
|
||||||
|
if (n > 0 && os.good())
|
||||||
|
os.write(fill_chars, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class charT, class traits>
|
||||||
|
void sv_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
|
||||||
|
const std::size_t size = str.size();
|
||||||
|
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
||||||
|
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
||||||
|
if (!align_left) {
|
||||||
|
detail::sv_insert_fill_chars(os, alignment_size);
|
||||||
|
if (os.good())
|
||||||
|
os.write(str.data(), size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
os.write(str.data(), size);
|
||||||
|
if (os.good())
|
||||||
|
detail::sv_insert_fill_chars(os, alignment_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Inserter
|
||||||
|
template<class charT, class traits>
|
||||||
|
inline std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
|
const basic_string_view<charT,traits>& str) {
|
||||||
|
if (os.good()) {
|
||||||
|
const std::size_t size = str.size();
|
||||||
|
const std::size_t w = static_cast< std::size_t >(os.width());
|
||||||
|
if (w <= size)
|
||||||
|
os.write(str.data(), size);
|
||||||
|
else
|
||||||
|
detail::sv_insert_aligned(os, str);
|
||||||
|
os.width(0);
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// numeric conversions
|
||||||
|
//
|
||||||
|
// These are short-term implementations.
|
||||||
|
// In a production environment, I would rather avoid the copying.
|
||||||
|
//
|
||||||
|
inline int stoi (string_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoi ( std::string(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long stol (string_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stol ( std::string(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoul ( std::string(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long long stoll (string_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoll ( std::string(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoull ( std::string(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float stof (string_view str, size_t* idx=0) {
|
||||||
|
return std::stof ( std::string(str), idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double stod (string_view str, size_t* idx=0) {
|
||||||
|
return std::stod ( std::string(str), idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long double stold (string_view str, size_t* idx=0) {
|
||||||
|
return std::stold ( std::string(str), idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int stoi (wstring_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoi ( std::wstring(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long stol (wstring_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stol ( std::wstring(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoul ( std::wstring(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long long stoll (wstring_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoll ( std::wstring(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) {
|
||||||
|
return std::stoull ( std::wstring(str), idx, base );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float stof (wstring_view str, size_t* idx=0) {
|
||||||
|
return std::stof ( std::wstring(str), idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double stod (wstring_view str, size_t* idx=0) {
|
||||||
|
return std::stod ( std::wstring(str), idx );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline long double stold (wstring_view str, size_t* idx=0) {
|
||||||
|
return std::stold ( std::wstring(str), idx );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
namespace std {
|
||||||
|
// Hashing
|
||||||
|
template<> struct hash<boost::string_view>;
|
||||||
|
template<> struct hash<boost::u16string_view>;
|
||||||
|
template<> struct hash<boost::u32string_view>;
|
||||||
|
template<> struct hash<boost::wstring_view>;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
39
include/boost/utility/string_view_fwd.hpp
Normal file
39
include/boost/utility/string_view_fwd.hpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2012-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
|
||||||
|
Based on the StringRef implementation in LLVM (http://llvm.org) and
|
||||||
|
N3422 by Jeffrey Yasskin
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
|
||||||
|
Updated July 2015 to reflect the Library Fundamentals TS
|
||||||
|
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BOOST_STRING_VIEW_FWD_HPP
|
||||||
|
#define BOOST_STRING_VIEW_FWD_HPP
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<typename charT, typename traits = std::char_traits<charT> > class basic_string_view;
|
||||||
|
typedef basic_string_view<char, std::char_traits<char> > string_view;
|
||||||
|
typedef basic_string_view<wchar_t, std::char_traits<wchar_t> > wstring_view;
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_CHAR16_T
|
||||||
|
typedef basic_string_view<char16_t, std::char_traits<char16_t> > u16string_view;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_CHAR32_T
|
||||||
|
typedef basic_string_view<char32_t, std::char_traits<char32_t> > u32string_view;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -20,12 +20,12 @@
|
|||||||
<a href="call_traits.htm">call_traits</a><br>
|
<a href="call_traits.htm">call_traits</a><br>
|
||||||
<a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to the Boost.Core library)<br>
|
<a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to the Boost.Core library)<br>
|
||||||
<a href="doc/html/compressed_pair.html">compressed_pair</a><br>
|
<a href="doc/html/compressed_pair.html">compressed_pair</a><br>
|
||||||
<a href="doc/html/declval.html">declval</a><br>
|
<a href="../type_traits/doc/html/boost_typetraits/reference/declval.html">declval</a> (moved to the Boost.TypeTraits library)<br>
|
||||||
<a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to the Boost.Core library)<br>
|
<a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to the Boost.Core library)<br>
|
||||||
<a href="in_place_factories.html">in_place_factory</a><br>
|
<a href="in_place_factories.html">in_place_factory</a><br>
|
||||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
<a href="../iterator/doc/generator_iterator.htm">generator iterator adaptors</a> (moved to the Boost.Iterator library)<br>
|
||||||
<a href="utility.htm#functions_next_prior">next/prior</a><br>
|
<a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next/prior</a> (moved to the Boost.Iterator library)<br>
|
||||||
<a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)<br>
|
<a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)<br>
|
||||||
<a href="operators.htm">operators</a><br>
|
<a href="operators.htm">operators</a><br>
|
||||||
<a href="utility.htm#result_of">result_of</a><br>
|
<a href="utility.htm#result_of">result_of</a><br>
|
||||||
|
@@ -1,406 +0,0 @@
|
|||||||
// (C) Copyright David Abrahams 2001.
|
|
||||||
// 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)
|
|
||||||
|
|
||||||
// See http://www.boost.org for most recent version including documentation.
|
|
||||||
|
|
||||||
// Revision History
|
|
||||||
// 1 Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
|
|
||||||
// 11 Feb 2001 Fixes for Borland (David Abrahams)
|
|
||||||
// 23 Jan 2001 Added test for wchar_t (David Abrahams)
|
|
||||||
// 23 Jan 2001 Now statically selecting a test for signed numbers to avoid
|
|
||||||
// warnings with fancy compilers. Added commentary and
|
|
||||||
// additional dumping of traits data for tested types (David
|
|
||||||
// Abrahams).
|
|
||||||
// 21 Jan 2001 Initial version (David Abrahams)
|
|
||||||
|
|
||||||
#include <boost/detail/numeric_traits.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
#include <boost/type_traits.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
#include <boost/utility.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
#include <climits>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#ifndef BOOST_NO_LIMITS
|
|
||||||
# include <limits>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// =================================================================================
|
|
||||||
// template class complement_traits<Number> --
|
|
||||||
//
|
|
||||||
// statically computes the max and min for 1s and 2s-complement binary
|
|
||||||
// numbers. This helps on platforms without <limits> support. It also shows
|
|
||||||
// an example of a recursive template that works with MSVC!
|
|
||||||
//
|
|
||||||
|
|
||||||
template <unsigned size> struct complement; // forward
|
|
||||||
|
|
||||||
// The template complement, below, does all the real work, using "poor man's
|
|
||||||
// partial specialization". We need complement_traits_aux<> so that MSVC doesn't
|
|
||||||
// complain about undefined min/max as we're trying to recursively define them.
|
|
||||||
template <class Number, unsigned size>
|
|
||||||
struct complement_traits_aux
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <unsigned size>
|
|
||||||
struct complement
|
|
||||||
{
|
|
||||||
template <class Number>
|
|
||||||
struct traits
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
// indirection through complement_traits_aux necessary to keep MSVC happy
|
|
||||||
typedef complement_traits_aux<Number, size - 1> prev;
|
|
||||||
public:
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
|
||||||
// GCC 4.0.2 ICEs on these C-style casts
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max =
|
|
||||||
Number((prev::max) << CHAR_BIT)
|
|
||||||
+ Number(UCHAR_MAX));
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = Number((prev::min) << CHAR_BIT));
|
|
||||||
#else
|
|
||||||
// Avoid left shifting negative integers, use multiplication instead
|
|
||||||
BOOST_STATIC_CONSTANT(Number, shift = 1u << CHAR_BIT);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max =
|
|
||||||
Number(Number(prev::max) * shift)
|
|
||||||
+ Number(UCHAR_MAX));
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) * shift));
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Template class complement_base<> -- defines values for min and max for
|
|
||||||
// complement<1>, at the deepest level of recursion. Uses "poor man's partial
|
|
||||||
// specialization" again.
|
|
||||||
template <bool is_signed> struct complement_base;
|
|
||||||
|
|
||||||
template <> struct complement_base<false>
|
|
||||||
{
|
|
||||||
template <class Number>
|
|
||||||
struct values
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = 0);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct complement_base<true>
|
|
||||||
{
|
|
||||||
template <class Number>
|
|
||||||
struct values
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Base specialization of complement, puts an end to the recursion.
|
|
||||||
template <>
|
|
||||||
struct complement<1>
|
|
||||||
{
|
|
||||||
template <class Number>
|
|
||||||
struct traits
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min =
|
|
||||||
complement_base<is_signed>::template values<Number>::min);
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max =
|
|
||||||
complement_base<is_signed>::template values<Number>::max);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now here's the "pretty" template you're intended to actually use.
|
|
||||||
// complement_traits<Number>::min, complement_traits<Number>::max are the
|
|
||||||
// minimum and maximum values of Number if Number is a built-in integer type.
|
|
||||||
template <class Number>
|
|
||||||
struct complement_traits
|
|
||||||
{
|
|
||||||
BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
|
|
||||||
BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
|
|
||||||
};
|
|
||||||
|
|
||||||
// =================================================================================
|
|
||||||
|
|
||||||
// Support for streaming various numeric types in exactly the format I want. I
|
|
||||||
// needed this in addition to all the assertions so that I could see exactly
|
|
||||||
// what was going on.
|
|
||||||
//
|
|
||||||
// Numbers go through a 2-stage conversion process (by default, though, no real
|
|
||||||
// conversion).
|
|
||||||
//
|
|
||||||
template <class T> struct stream_as {
|
|
||||||
typedef T t1;
|
|
||||||
typedef T t2;
|
|
||||||
};
|
|
||||||
|
|
||||||
// char types first get converted to unsigned char, then to unsigned.
|
|
||||||
template <> struct stream_as<char> {
|
|
||||||
typedef unsigned char t1;
|
|
||||||
typedef unsigned t2;
|
|
||||||
};
|
|
||||||
template <> struct stream_as<unsigned char> {
|
|
||||||
typedef unsigned char t1; typedef unsigned t2;
|
|
||||||
};
|
|
||||||
template <> struct stream_as<signed char> {
|
|
||||||
typedef unsigned char t1; typedef unsigned t2;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
|
|
||||||
|
|
||||||
// With this library implementation, __int64 and __uint64 get streamed as strings
|
|
||||||
template <> struct stream_as<boost::uintmax_t> {
|
|
||||||
typedef std::string t1;
|
|
||||||
typedef std::string t2;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct stream_as<boost::intmax_t> {
|
|
||||||
typedef std::string t1;
|
|
||||||
typedef std::string t2;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Standard promotion process for streaming
|
|
||||||
template <class T> struct promote
|
|
||||||
{
|
|
||||||
static typename stream_as<T>::t1 from(T x) {
|
|
||||||
typedef typename stream_as<T>::t1 t1;
|
|
||||||
return t1(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
|
|
||||||
|
|
||||||
// On this platform, stream them as long/unsigned long if they fit.
|
|
||||||
// Otherwise, write a string.
|
|
||||||
template <> struct promote<boost::uintmax_t> {
|
|
||||||
std::string static from(const boost::uintmax_t x) {
|
|
||||||
if (x > ULONG_MAX)
|
|
||||||
return std::string("large unsigned value");
|
|
||||||
else
|
|
||||||
return boost::lexical_cast<std::string>((unsigned long)x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <> struct promote<boost::intmax_t> {
|
|
||||||
std::string static from(const boost::intmax_t x) {
|
|
||||||
if (x > boost::intmax_t(ULONG_MAX))
|
|
||||||
return std::string("large positive signed value");
|
|
||||||
else if (x >= 0)
|
|
||||||
return boost::lexical_cast<std::string>((unsigned long)x);
|
|
||||||
|
|
||||||
if (x < boost::intmax_t(LONG_MIN))
|
|
||||||
return std::string("large negative signed value");
|
|
||||||
else
|
|
||||||
return boost::lexical_cast<std::string>((long)x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is the function which converts types to the form I want to stream them in.
|
|
||||||
template <class T>
|
|
||||||
typename stream_as<T>::t2 stream_number(T x)
|
|
||||||
{
|
|
||||||
return promote<T>::from(x);
|
|
||||||
}
|
|
||||||
// =================================================================================
|
|
||||||
|
|
||||||
//
|
|
||||||
// Tests for built-in signed and unsigned types
|
|
||||||
//
|
|
||||||
|
|
||||||
// Tag types for selecting tests
|
|
||||||
struct unsigned_tag {};
|
|
||||||
struct signed_tag {};
|
|
||||||
|
|
||||||
// Tests for unsigned numbers. The extra default Number parameter works around
|
|
||||||
// an MSVC bug.
|
|
||||||
template <class Number>
|
|
||||||
void test_aux(unsigned_tag, Number*)
|
|
||||||
{
|
|
||||||
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
|
|
||||||
BOOST_STATIC_ASSERT(!boost::detail::is_signed<Number>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
(sizeof(Number) < sizeof(boost::intmax_t))
|
|
||||||
| (boost::is_same<difference_type, boost::intmax_t>::value));
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
|
||||||
// GCC 4.0.2 ICEs on this C-style cases
|
|
||||||
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
|
|
||||||
BOOST_STATIC_ASSERT((complement_traits<Number>::min) == Number(0));
|
|
||||||
#else
|
|
||||||
// Force casting to Number here to work around the fact that it's an enum on MSVC
|
|
||||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
|
|
||||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) == Number(0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const Number max = complement_traits<Number>::max;
|
|
||||||
const Number min = complement_traits<Number>::min;
|
|
||||||
|
|
||||||
const Number test_max = (sizeof(Number) < sizeof(boost::intmax_t))
|
|
||||||
? max
|
|
||||||
: max / 2 - 1;
|
|
||||||
|
|
||||||
std::cout << std::hex << "(unsigned) min = " << stream_number(min) << ", max = "
|
|
||||||
<< stream_number(max) << "..." << std::flush;
|
|
||||||
std::cout << "difference_type = " << typeid(difference_type).name() << "..."
|
|
||||||
<< std::flush;
|
|
||||||
|
|
||||||
difference_type d1 = boost::detail::numeric_distance(Number(0), test_max);
|
|
||||||
difference_type d2 = boost::detail::numeric_distance(test_max, Number(0));
|
|
||||||
|
|
||||||
std::cout << "0->" << stream_number(test_max) << "==" << std::dec << stream_number(d1) << "; "
|
|
||||||
<< std::hex << stream_number(test_max) << "->0==" << std::dec << stream_number(d2) << "..." << std::flush;
|
|
||||||
|
|
||||||
assert(d1 == difference_type(test_max));
|
|
||||||
assert(d2 == -difference_type(test_max));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests for signed numbers. The extra default Number parameter works around an
|
|
||||||
// MSVC bug.
|
|
||||||
struct out_of_range_tag {};
|
|
||||||
struct in_range_tag {};
|
|
||||||
|
|
||||||
// This test morsel gets executed for numbers whose difference will always be
|
|
||||||
// representable in intmax_t
|
|
||||||
template <class Number>
|
|
||||||
void signed_test(in_range_tag, Number*)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
|
|
||||||
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
|
|
||||||
const Number max = complement_traits<Number>::max;
|
|
||||||
const Number min = complement_traits<Number>::min;
|
|
||||||
|
|
||||||
difference_type d1 = boost::detail::numeric_distance(min, max);
|
|
||||||
difference_type d2 = boost::detail::numeric_distance(max, min);
|
|
||||||
|
|
||||||
std::cout << stream_number(min) << "->" << stream_number(max) << "==";
|
|
||||||
std::cout << std::dec << stream_number(d1) << "; ";
|
|
||||||
std::cout << std::hex << stream_number(max) << "->" << stream_number(min)
|
|
||||||
<< "==" << std::dec << stream_number(d2) << "..." << std::flush;
|
|
||||||
assert(d1 == difference_type(max) - difference_type(min));
|
|
||||||
assert(d2 == difference_type(min) - difference_type(max));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This test morsel gets executed for numbers whose difference may exceed the
|
|
||||||
// capacity of intmax_t.
|
|
||||||
template <class Number>
|
|
||||||
void signed_test(out_of_range_tag, Number*)
|
|
||||||
{
|
|
||||||
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
|
|
||||||
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
|
|
||||||
const Number max = complement_traits<Number>::max;
|
|
||||||
const Number min = complement_traits<Number>::min;
|
|
||||||
|
|
||||||
difference_type min_distance = complement_traits<difference_type>::min;
|
|
||||||
difference_type max_distance = complement_traits<difference_type>::max;
|
|
||||||
|
|
||||||
const Number n1 = Number(min + max_distance);
|
|
||||||
const Number n2 = Number(max + min_distance);
|
|
||||||
difference_type d1 = boost::detail::numeric_distance(min, n1);
|
|
||||||
difference_type d2 = boost::detail::numeric_distance(max, n2);
|
|
||||||
|
|
||||||
std::cout << stream_number(min) << "->" << stream_number(n1) << "==";
|
|
||||||
std::cout << std::dec << stream_number(d1) << "; ";
|
|
||||||
std::cout << std::hex << stream_number(max) << "->" << stream_number(n2)
|
|
||||||
<< "==" << std::dec << stream_number(d2) << "..." << std::flush;
|
|
||||||
assert(d1 == max_distance);
|
|
||||||
assert(d2 == min_distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Number>
|
|
||||||
void test_aux(signed_tag, Number*)
|
|
||||||
{
|
|
||||||
typedef typename boost::detail::numeric_traits<Number>::difference_type difference_type;
|
|
||||||
BOOST_STATIC_ASSERT(boost::detail::is_signed<Number>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
(sizeof(Number) < sizeof(boost::intmax_t))
|
|
||||||
| (boost::is_same<difference_type, Number>::value));
|
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
|
||||||
// GCC 4.0.2 ICEs on this cast
|
|
||||||
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
|
|
||||||
BOOST_STATIC_ASSERT((complement_traits<Number>::min) < Number(0));
|
|
||||||
#else
|
|
||||||
// Force casting to Number here to work around the fact that it's an enum on MSVC
|
|
||||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
|
|
||||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) < Number(0));
|
|
||||||
#endif
|
|
||||||
const Number max = complement_traits<Number>::max;
|
|
||||||
const Number min = complement_traits<Number>::min;
|
|
||||||
|
|
||||||
std::cout << std::hex << "min = " << stream_number(min) << ", max = "
|
|
||||||
<< stream_number(max) << "..." << std::flush;
|
|
||||||
std::cout << "difference_type = " << typeid(difference_type).name() << "..."
|
|
||||||
<< std::flush;
|
|
||||||
|
|
||||||
typedef typename boost::detail::if_true<
|
|
||||||
(sizeof(Number) < sizeof(boost::intmax_t))>
|
|
||||||
::template then<
|
|
||||||
in_range_tag,
|
|
||||||
out_of_range_tag
|
|
||||||
>::type
|
|
||||||
range_tag;
|
|
||||||
signed_test<Number>(range_tag(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Test for all numbers. The extra default Number parameter works around an MSVC
|
|
||||||
// bug.
|
|
||||||
template <class Number>
|
|
||||||
void test(Number* = 0)
|
|
||||||
{
|
|
||||||
std::cout << "testing " << typeid(Number).name() << ":\n"
|
|
||||||
#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
|
||||||
<< "is_signed: " << (std::numeric_limits<Number>::is_signed ? "true\n" : "false\n")
|
|
||||||
<< "is_bounded: " << (std::numeric_limits<Number>::is_bounded ? "true\n" : "false\n")
|
|
||||||
<< "digits: " << std::numeric_limits<Number>::digits << "\n"
|
|
||||||
#endif
|
|
||||||
<< "..." << std::flush;
|
|
||||||
|
|
||||||
// factoring out difference_type for the assert below confused Borland :(
|
|
||||||
typedef boost::detail::is_signed<
|
|
||||||
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
|
|
||||||
typename
|
|
||||||
#endif
|
|
||||||
boost::detail::numeric_traits<Number>::difference_type
|
|
||||||
> is_signed;
|
|
||||||
BOOST_STATIC_ASSERT(is_signed::value);
|
|
||||||
|
|
||||||
typedef typename boost::detail::if_true<
|
|
||||||
boost::detail::is_signed<Number>::value
|
|
||||||
>::template then<signed_tag, unsigned_tag>::type signedness;
|
|
||||||
|
|
||||||
test_aux<Number>(signedness(), 0);
|
|
||||||
std::cout << "passed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
test<char>();
|
|
||||||
test<unsigned char>();
|
|
||||||
test<signed char>();
|
|
||||||
test<wchar_t>();
|
|
||||||
test<short>();
|
|
||||||
test<unsigned short>();
|
|
||||||
test<int>();
|
|
||||||
test<unsigned int>();
|
|
||||||
test<long>();
|
|
||||||
test<unsigned long>();
|
|
||||||
#if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
|
|
||||||
test< ::boost::long_long_type>();
|
|
||||||
test< ::boost::ulong_long_type>();
|
|
||||||
#elif defined(BOOST_MSVC)
|
|
||||||
// The problem of not having compile-time static class constants other than
|
|
||||||
// enums prevents this from working, since values get truncated.
|
|
||||||
// test<boost::uintmax_t>();
|
|
||||||
// test<boost::intmax_t>();
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1667,8 +1667,8 @@ T operator+( T lhs, const T& rhs )
|
|||||||
|
|
||||||
<td><code>P operator->() const</code></td>
|
<td><code>P operator->() const</code></td>
|
||||||
|
|
||||||
<td><code>(&*i)</code>. Return convertible to
|
<td><code>*i</code>. Address of the returned value convertible
|
||||||
<code>P</code>.</td>
|
to <code>P</code>.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
@@ -1,322 +0,0 @@
|
|||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
|
||||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
|
||||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
|
||||||
<title>Shared Container Iterator Documentation</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body bgcolor="#FFFFFF" text="#000000">
|
|
||||||
|
|
||||||
<img src="../../boost.png" alt="boost.png (6897 bytes)"
|
|
||||||
align="center" width="277" height="86">
|
|
||||||
|
|
||||||
<h1>Shared Container Iterator</h1>
|
|
||||||
|
|
||||||
Defined in header
|
|
||||||
<a href="../../boost/shared_container_iterator.hpp">boost/shared_container_iterator.hpp</a>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The purpose of the shared container iterator is to attach the lifetime
|
|
||||||
of a container to the lifetime of its iterators. In other words, the
|
|
||||||
container will not be deleted until after all its iterators are
|
|
||||||
destroyed. The shared container iterator is typically used to
|
|
||||||
implement functions that return iterators over a range of objects that
|
|
||||||
only need to exist for the lifetime of the iterators. By returning a
|
|
||||||
pair of shared iterators from a function, the callee can return a
|
|
||||||
heap-allocated range of objects whose lifetime is automatically managed.
|
|
||||||
<p>
|
|
||||||
The shared container iterator augments an iterator over a shared
|
|
||||||
container. It maintains a reference count on the shared
|
|
||||||
container. If only shared container iterators hold references to
|
|
||||||
the container, the container's lifetime will end when the last shared
|
|
||||||
container iterator over it is destroyed. In any case, the shared
|
|
||||||
container is guaranteed to persist beyond the lifetime of all
|
|
||||||
the iterators. In all other ways, the
|
|
||||||
shared container iterator behaves the same as its base iterator.
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Synopsis</h2>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
namespace boost {
|
|
||||||
template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
|
|
||||||
class shared_container_iterator;
|
|
||||||
|
|
||||||
template <typename <a href="http://www.sgi.com/tech/stl/Container.html">Container</a>>
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
make_shared_container_iterator(typename Container::iterator base,
|
|
||||||
boost::shared_ptr<Container> const& container);
|
|
||||||
|
|
||||||
std::pair<
|
|
||||||
typename shared_container_iterator<Container>,
|
|
||||||
typename shared_container_iterator<Container>
|
|
||||||
>
|
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<h2><a name="generator">The Shared Container Iterator Type</a></h2>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
template <typename Container> class shared_container_iterator;
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
The class template <tt>shared_container_iterator</tt>
|
|
||||||
is the shared container iterator type. The <tt>Container</tt> template
|
|
||||||
type argument must model the
|
|
||||||
<a href="http://www.sgi.com/tech/stl/Container.html">Container</a>
|
|
||||||
concept.
|
|
||||||
|
|
||||||
<h3>Example</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The following example illustrates how to create an iterator that
|
|
||||||
regulates the lifetime of a reference counted <tt>std::vector</tt>.
|
|
||||||
Though the original shared pointer <tt>ints</tt> ceases to exist
|
|
||||||
after <tt>set_range()</tt> returns, the
|
|
||||||
<tt>shared_counter_iterator</tt> objects maintain references to the
|
|
||||||
underlying vector and thereby extend the container's lifetime.
|
|
||||||
<p>
|
|
||||||
<a href="./shared_iterator_example1.cpp">shared_iterator_example1.cpp</a>:
|
|
||||||
<PRE>
|
|
||||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
|
|
||||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
|
|
||||||
<font color="#008040">#include <algorithm></font>
|
|
||||||
<font color="#008040">#include <iostream></font>
|
|
||||||
<font color="#008040">#include <vector></font>
|
|
||||||
|
|
||||||
<B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator;
|
|
||||||
|
|
||||||
|
|
||||||
<B>void</B> set_range(iterator& i, iterator& end) {
|
|
||||||
|
|
||||||
boost::shared_ptr< std::vector<<B>int</B>> > ints(<B>new</B> std::vector<<B>int</B>>());
|
|
||||||
|
|
||||||
ints->push_back(<font color="#0000A0">0</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">1</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">2</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">3</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">4</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">5</font>);
|
|
||||||
|
|
||||||
i = iterator(ints->begin(),ints);
|
|
||||||
end = iterator(ints->end(),ints);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<B>int</B> main() {
|
|
||||||
|
|
||||||
iterator i,end;
|
|
||||||
|
|
||||||
set_range(i,end);
|
|
||||||
|
|
||||||
std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>));
|
|
||||||
std::cout.put(<font color="#0000FF">'\n'</font>);
|
|
||||||
|
|
||||||
<B>return</B> <font color="#0000A0">0</font>;
|
|
||||||
}
|
|
||||||
</PRE>
|
|
||||||
|
|
||||||
The output from this part is:
|
|
||||||
<pre>
|
|
||||||
0,1,2,3,4,5,
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h3>Template Parameters</h3>
|
|
||||||
|
|
||||||
<Table border>
|
|
||||||
<TR>
|
|
||||||
<TH>Parameter</TH><TH>Description</TH>
|
|
||||||
</TR>
|
|
||||||
|
|
||||||
<TR>
|
|
||||||
<TD><a
|
|
||||||
href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a></TD>
|
|
||||||
<TD>The type of the container that we wish to iterate over. It must be
|
|
||||||
a model of the
|
|
||||||
<a href="http://www.sgi.com/tech/stl/Container.html"><tt>Container</tt></a>
|
|
||||||
concept.
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
</Table>
|
|
||||||
|
|
||||||
<h3>Model of</h3>
|
|
||||||
|
|
||||||
The <tt>shared_container_iterator<Container></tt> type models the
|
|
||||||
same iterator concept as the base iterator
|
|
||||||
(<tt>Container::iterator</tt>).
|
|
||||||
|
|
||||||
<h3>Members</h3>
|
|
||||||
|
|
||||||
The shared container iterator type implements the member functions and
|
|
||||||
operators required of the <a
|
|
||||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
|
||||||
concept, though only operations defined for the base iterator will be valid.
|
|
||||||
In addition it has the following constructor:
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
shared_container_iterator(Container::iterator const& it,
|
|
||||||
boost::shared_ptr<Container> const& container)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<hr>
|
|
||||||
<p>
|
|
||||||
|
|
||||||
|
|
||||||
<h2><a name="make_iterator">The Shared Container Iterator Object Generator</a></h2>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
template <typename Container>
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
make_shared_container_iterator(Container::iterator base,
|
|
||||||
boost::shared_ptr<Container> const& container)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
This function provides an alternative to directly constructing a
|
|
||||||
shared container iterator. Using the object generator, a shared
|
|
||||||
container iterator can be created and passed to a function without
|
|
||||||
explicitly specifying its type.
|
|
||||||
|
|
||||||
<h3>Example</h3>
|
|
||||||
|
|
||||||
This example, similar to the previous, uses
|
|
||||||
<tt>make_shared_container_iterator()</tt> to create the iterators.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="./shared_iterator_example2.cpp">shared_iterator_example2.cpp</a>:
|
|
||||||
|
|
||||||
<PRE>
|
|
||||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
|
|
||||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
|
|
||||||
<font color="#008040">#include <algorithm></font>
|
|
||||||
<font color="#008040">#include <iterator></font>
|
|
||||||
<font color="#008040">#include <iostream></font>
|
|
||||||
<font color="#008040">#include <vector></font>
|
|
||||||
|
|
||||||
|
|
||||||
<B>template</B> <<B>typename</B> Iterator>
|
|
||||||
<B>void</B> print_range_nl (Iterator begin, Iterator end) {
|
|
||||||
<B>typedef</B> <B>typename</B> std::iterator_traits<Iterator>::value_type val;
|
|
||||||
std::copy(begin,end,std::ostream_iterator<val>(std::cout,<font color="#0000FF">","</font>));
|
|
||||||
std::cout.put(<font color="#0000FF">'\n'</font>);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<B>int</B> main() {
|
|
||||||
|
|
||||||
<B>typedef</B> boost::shared_ptr< std::vector<<B>int</B>> > ints_t;
|
|
||||||
{
|
|
||||||
ints_t ints(<B>new</B> std::vector<<B>int</B>>());
|
|
||||||
|
|
||||||
ints->push_back(<font color="#0000A0">0</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">1</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">2</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">3</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">4</font>);
|
|
||||||
ints->push_back(<font color="#0000A0">5</font>);
|
|
||||||
|
|
||||||
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
|
|
||||||
boost::make_shared_container_iterator(ints->end(),ints));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<B>return</B> <font color="#0000A0">0</font>;
|
|
||||||
}
|
|
||||||
</PRE>
|
|
||||||
|
|
||||||
Observe that the <tt>shared_container_iterator</tt> type is never
|
|
||||||
explicitly named. The output from this example is the same as the previous.
|
|
||||||
|
|
||||||
<h2><a name="make_range">The Shared Container Iterator Range Generator</a></h2>
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
template <typename Container>
|
|
||||||
std::pair<
|
|
||||||
shared_container_iterator<Container>,
|
|
||||||
shared_container_iterator<Container>
|
|
||||||
>
|
|
||||||
make_shared_container_range(boost::shared_ptr<Container> const& container);
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
Class <tt>shared_container_iterator</tt> is meant primarily to return,
|
|
||||||
using iterators, a range of values that we can guarantee will be alive as
|
|
||||||
long as the iterators are. This is a convenience
|
|
||||||
function to do just that. It is equivalent to
|
|
||||||
|
|
||||||
<pre>
|
|
||||||
std::make_pair(make_shared_container_iterator(container->begin(),container),
|
|
||||||
make_shared_container_iterator(container->end(),container));
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h3>Example</h3>
|
|
||||||
|
|
||||||
In the following example, a range of values is returned as a pair of
|
|
||||||
<tt>shared_container_iterator</tt> objects.
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="./shared_iterator_example3.cpp">shared_iterator_example3.cpp</a>:
|
|
||||||
|
|
||||||
<PRE>
|
|
||||||
<font color="#008040">#include "shared_container_iterator.hpp"</font>
|
|
||||||
<font color="#008040">#include "boost/shared_ptr.hpp"</font>
|
|
||||||
<font color="#008040">#include "boost/tuple/tuple.hpp" // for boost::tie</font>
|
|
||||||
<font color="#008040">#include <algorithm> // for std::copy</font>
|
|
||||||
<font color="#008040">#include <iostream> </font>
|
|
||||||
<font color="#008040">#include <vector></font>
|
|
||||||
|
|
||||||
|
|
||||||
<B>typedef</B> boost::shared_container_iterator< std::vector<<B>int</B>> > iterator;
|
|
||||||
|
|
||||||
std::pair<iterator,iterator>
|
|
||||||
return_range() {
|
|
||||||
boost::shared_ptr< std::vector<<B>int</B>> > range(<B>new</B> std::vector<<B>int</B>>());
|
|
||||||
range->push_back(<font color="#0000A0">0</font>);
|
|
||||||
range->push_back(<font color="#0000A0">1</font>);
|
|
||||||
range->push_back(<font color="#0000A0">2</font>);
|
|
||||||
range->push_back(<font color="#0000A0">3</font>);
|
|
||||||
range->push_back(<font color="#0000A0">4</font>);
|
|
||||||
range->push_back(<font color="#0000A0">5</font>);
|
|
||||||
<B>return</B> boost::make_shared_container_range(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
<B>int</B> main() {
|
|
||||||
|
|
||||||
|
|
||||||
iterator i,end;
|
|
||||||
|
|
||||||
boost::tie(i,end) = return_range();
|
|
||||||
|
|
||||||
std::copy(i,end,std::ostream_iterator<<B>int</B>>(std::cout,<font color="#0000FF">","</font>));
|
|
||||||
std::cout.put(<font color="#0000FF">'\n'</font>);
|
|
||||||
|
|
||||||
<B>return</B> <font color="#0000A0">0</font>;
|
|
||||||
}
|
|
||||||
</PRE>
|
|
||||||
|
|
||||||
Though the <tt>range</tt> object only lives for the duration of the
|
|
||||||
<tt>return_range</tt> call, the reference counted
|
|
||||||
<tt>std::vector</tt> will live until <tt>i</tt> and <tt>end</tt>
|
|
||||||
are both destroyed. The output from this example is the same as
|
|
||||||
the previous two.
|
|
||||||
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
<!-- hhmts start -->
|
|
||||||
Last modified: Mon Aug 11 11:27:03 EST 2003
|
|
||||||
<!-- hhmts end -->
|
|
||||||
<p><EFBFBD> Copyright 2003 The Trustees of Indiana University.
|
|
||||||
Use, modification and distribution is subject to 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)</p>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@@ -1,42 +0,0 @@
|
|||||||
// Copyright 2003 The Trustees of Indiana University.
|
|
||||||
|
|
||||||
// Use, modification and distribution is subject to 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)
|
|
||||||
|
|
||||||
#include "boost/shared_container_iterator.hpp"
|
|
||||||
#include "boost/shared_ptr.hpp"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
typedef boost::shared_container_iterator< std::vector<int> > iterator;
|
|
||||||
|
|
||||||
|
|
||||||
void set_range(iterator& i, iterator& end) {
|
|
||||||
|
|
||||||
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
|
|
||||||
|
|
||||||
ints->push_back(0);
|
|
||||||
ints->push_back(1);
|
|
||||||
ints->push_back(2);
|
|
||||||
ints->push_back(3);
|
|
||||||
ints->push_back(4);
|
|
||||||
ints->push_back(5);
|
|
||||||
|
|
||||||
i = iterator(ints->begin(),ints);
|
|
||||||
end = iterator(ints->end(),ints);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
iterator i,end;
|
|
||||||
|
|
||||||
set_range(i,end);
|
|
||||||
|
|
||||||
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
|
|
||||||
std::cout.put('\n');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1,43 +0,0 @@
|
|||||||
// Copyright 2003 The Trustees of Indiana University.
|
|
||||||
|
|
||||||
// Use, modification and distribution is subject to 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)
|
|
||||||
|
|
||||||
#include "boost/shared_container_iterator.hpp"
|
|
||||||
#include "boost/shared_ptr.hpp"
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iterator>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
void print_range_nl (Iterator begin, Iterator end) {
|
|
||||||
typedef typename std::iterator_traits<Iterator>::value_type val;
|
|
||||||
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
|
|
||||||
std::cout.put('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
typedef boost::shared_ptr< std::vector<int> > ints_t;
|
|
||||||
{
|
|
||||||
ints_t ints(new std::vector<int>());
|
|
||||||
|
|
||||||
ints->push_back(0);
|
|
||||||
ints->push_back(1);
|
|
||||||
ints->push_back(2);
|
|
||||||
ints->push_back(3);
|
|
||||||
ints->push_back(4);
|
|
||||||
ints->push_back(5);
|
|
||||||
|
|
||||||
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
|
|
||||||
boost::make_shared_container_iterator(ints->end(),ints));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
// Copyright 2003 The Trustees of Indiana University.
|
|
||||||
|
|
||||||
// Use, modification and distribution is subject to 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)
|
|
||||||
|
|
||||||
#include "boost/shared_container_iterator.hpp"
|
|
||||||
#include "boost/shared_ptr.hpp"
|
|
||||||
#include "boost/tuple/tuple.hpp" // for boost::tie
|
|
||||||
#include <algorithm> // for std::copy
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
typedef boost::shared_container_iterator< std::vector<int> > iterator;
|
|
||||||
|
|
||||||
std::pair<iterator,iterator>
|
|
||||||
return_range() {
|
|
||||||
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
|
|
||||||
range->push_back(0);
|
|
||||||
range->push_back(1);
|
|
||||||
range->push_back(2);
|
|
||||||
range->push_back(3);
|
|
||||||
range->push_back(4);
|
|
||||||
range->push_back(5);
|
|
||||||
return boost::make_shared_container_range(range);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
|
|
||||||
iterator i,end;
|
|
||||||
|
|
||||||
boost::tie(i,end) = return_range();
|
|
||||||
|
|
||||||
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
|
|
||||||
std::cout.put('\n');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -1,64 +0,0 @@
|
|||||||
// Copyright 2003 The Trustees of Indiana University.
|
|
||||||
|
|
||||||
// Use, modification and distribution is subject to 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)
|
|
||||||
|
|
||||||
// Shared container iterator adaptor
|
|
||||||
// Author: Ronald Garcia
|
|
||||||
// See http://boost.org/libs/utility/shared_container_iterator.html
|
|
||||||
// for documentation.
|
|
||||||
|
|
||||||
//
|
|
||||||
// shared_iterator_test.cpp - Regression tests for shared_container_iterator.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
#include "boost/shared_container_iterator.hpp"
|
|
||||||
#include "boost/shared_ptr.hpp"
|
|
||||||
#include <vector>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
struct resource {
|
|
||||||
static int count;
|
|
||||||
resource() { ++count; }
|
|
||||||
resource(resource const&) { ++count; }
|
|
||||||
~resource() { --count; }
|
|
||||||
};
|
|
||||||
int resource::count = 0;
|
|
||||||
|
|
||||||
typedef std::vector<resource> resources_t;
|
|
||||||
|
|
||||||
typedef boost::shared_container_iterator< resources_t > iterator;
|
|
||||||
|
|
||||||
|
|
||||||
void set_range(iterator& i, iterator& end) {
|
|
||||||
|
|
||||||
boost::shared_ptr< resources_t > objs(new resources_t());
|
|
||||||
|
|
||||||
for (int j = 0; j != 6; ++j)
|
|
||||||
objs->push_back(resource());
|
|
||||||
|
|
||||||
i = iterator(objs->begin(),objs);
|
|
||||||
end = iterator(objs->end(),objs);
|
|
||||||
assert(resource::count == 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
assert(resource::count == 0);
|
|
||||||
|
|
||||||
{
|
|
||||||
iterator i;
|
|
||||||
{
|
|
||||||
iterator end;
|
|
||||||
set_range(i,end);
|
|
||||||
assert(resource::count == 6);
|
|
||||||
}
|
|
||||||
assert(resource::count == 6);
|
|
||||||
}
|
|
||||||
assert(resource::count == 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -8,37 +8,36 @@
|
|||||||
# bring in rules for testing
|
# bring in rules for testing
|
||||||
import testing ;
|
import testing ;
|
||||||
|
|
||||||
alias unit_test_framework
|
run base_from_member_test.cpp ;
|
||||||
: # sources
|
run base_from_member_ref_test.cpp ;
|
||||||
/boost//unit_test_framework
|
|
||||||
;
|
|
||||||
|
|
||||||
# Please keep the tests ordered by filename
|
run binary_test.cpp ;
|
||||||
test-suite utility
|
|
||||||
:
|
|
||||||
[ run ../base_from_member_test.cpp ]
|
|
||||||
[ run ../base_from_member_ref_test.cpp ]
|
|
||||||
[ run ../binary_test.cpp ]
|
|
||||||
[ run ../call_traits_test.cpp : -u ]
|
|
||||||
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ]
|
|
||||||
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
|
||||||
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
|
||||||
[ run ../numeric_traits_test.cpp ]
|
|
||||||
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
|
||||||
[ compile result_of_test.cpp ]
|
|
||||||
[ run ../shared_iterator_test.cpp ]
|
|
||||||
[ run string_ref_test1.cpp unit_test_framework ]
|
|
||||||
[ run string_ref_test2.cpp unit_test_framework ]
|
|
||||||
[ run string_ref_test_io.cpp unit_test_framework ]
|
|
||||||
[ run ../value_init_test.cpp ]
|
|
||||||
[ run ../value_init_workaround_test.cpp ]
|
|
||||||
[ run ../initialized_test.cpp ]
|
|
||||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
|
||||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
|
||||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
|
||||||
[ compile-fail ../initialized_test_fail1.cpp ]
|
|
||||||
[ compile-fail ../initialized_test_fail2.cpp ]
|
|
||||||
|
|
||||||
[ run ../generator_iterator_test.cpp ]
|
run call_traits_test.cpp : -u ;
|
||||||
;
|
|
||||||
|
|
||||||
|
run compressed_pair_test.cpp ;
|
||||||
|
|
||||||
|
run iterators_test.cpp ;
|
||||||
|
|
||||||
|
run operators_test.cpp ;
|
||||||
|
|
||||||
|
compile result_of_test.cpp ;
|
||||||
|
|
||||||
|
# compile-fail string_ref_from_rvalue.cpp ;
|
||||||
|
run string_ref_test1.cpp ;
|
||||||
|
run string_ref_test2.cpp ;
|
||||||
|
run string_ref_test_io.cpp ;
|
||||||
|
# compile-fail string_view_from_rvalue.cpp ;
|
||||||
|
compile string_view_constexpr_test1.cpp ;
|
||||||
|
run string_view_test1.cpp ;
|
||||||
|
run string_view_test2.cpp ;
|
||||||
|
run string_view_test_io.cpp ;
|
||||||
|
|
||||||
|
run value_init_test.cpp ;
|
||||||
|
run value_init_workaround_test.cpp ;
|
||||||
|
run initialized_test.cpp ;
|
||||||
|
compile-fail value_init_test_fail1.cpp ;
|
||||||
|
compile-fail value_init_test_fail2.cpp ;
|
||||||
|
compile-fail value_init_test_fail3.cpp ;
|
||||||
|
compile-fail initialized_test_fail1.cpp ;
|
||||||
|
compile-fail initialized_test_fail2.cpp ;
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <boost/utility/base_from_member.hpp>
|
#include <boost/utility/base_from_member.hpp>
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
struct foo : boost::base_from_member<int&>
|
struct foo : boost::base_from_member<int&>
|
||||||
{
|
{
|
@@ -10,15 +10,14 @@
|
|||||||
// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker)
|
// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker)
|
||||||
// 29 Aug 2001 Initial Version (Daryle Walker)
|
// 29 Aug 2001 Initial Version (Daryle Walker)
|
||||||
|
|
||||||
#include <boost/test/minimal.hpp> // for BOOST_CHECK, main
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
|
#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
|
||||||
#include <boost/noncopyable.hpp> // for boost::noncopyable
|
#include <boost/noncopyable.hpp> // for boost::noncopyable
|
||||||
|
|
||||||
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
|
#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
|
||||||
|
|
||||||
#include <functional> // for std::binary_function, std::less
|
#include <functional> // for std::less
|
||||||
#include <iostream> // for std::cout (std::ostream, std::endl indirectly)
|
#include <iostream> // for std::cout (std::ostream, std::endl indirectly)
|
||||||
#include <set> // for std::set
|
#include <set> // for std::set
|
||||||
#include <typeinfo> // for std::type_info
|
#include <typeinfo> // for std::type_info
|
||||||
@@ -46,7 +45,6 @@ template < typename T >
|
|||||||
|
|
||||||
// A custom comparison type is needed
|
// A custom comparison type is needed
|
||||||
struct object_id_compare
|
struct object_id_compare
|
||||||
: std::binary_function<object_id, object_id, bool>
|
|
||||||
{
|
{
|
||||||
bool operator ()( object_id const &a, object_id const &b ) const;
|
bool operator ()( object_id const &a, object_id const &b ) const;
|
||||||
|
|
||||||
@@ -173,13 +171,13 @@ object_registrar obj_reg;
|
|||||||
|
|
||||||
// Main functionality
|
// Main functionality
|
||||||
int
|
int
|
||||||
test_main( int , char * [] )
|
main()
|
||||||
{
|
{
|
||||||
BOOST_CHECK( obj_reg.db_.empty() );
|
BOOST_TEST( obj_reg.db_.empty() );
|
||||||
BOOST_CHECK( obj_reg.defrauders_in_.empty() );
|
BOOST_TEST( obj_reg.defrauders_in_.empty() );
|
||||||
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
|
BOOST_TEST( obj_reg.defrauders_out_.empty() );
|
||||||
BOOST_CHECK( obj_reg.overeager_.empty() );
|
BOOST_TEST( obj_reg.overeager_.empty() );
|
||||||
BOOST_CHECK( obj_reg.overkilled_.empty() );
|
BOOST_TEST( obj_reg.overkilled_.empty() );
|
||||||
|
|
||||||
// Make a separate block to examine pre- and post-effects
|
// Make a separate block to examine pre- and post-effects
|
||||||
{
|
{
|
||||||
@@ -187,20 +185,20 @@ test_main( int , char * [] )
|
|||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
||||||
bad_class bc;
|
bad_class bc;
|
||||||
BOOST_CHECK( obj_reg.db_.size() == 3 );
|
BOOST_TEST( obj_reg.db_.size() == 3 );
|
||||||
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
|
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
|
||||||
|
|
||||||
good_class_1 gc1;
|
good_class_1 gc1;
|
||||||
BOOST_CHECK( obj_reg.db_.size() == 6 );
|
BOOST_TEST( obj_reg.db_.size() == 6 );
|
||||||
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
|
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
|
||||||
|
|
||||||
good_class_2 gc2;
|
good_class_2 gc2;
|
||||||
BOOST_CHECK( obj_reg.db_.size() == 11 );
|
BOOST_TEST( obj_reg.db_.size() == 11 );
|
||||||
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
|
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
|
||||||
|
|
||||||
BOOST_CHECK( obj_reg.defrauders_out_.empty() );
|
BOOST_TEST( obj_reg.defrauders_out_.empty() );
|
||||||
BOOST_CHECK( obj_reg.overeager_.empty() );
|
BOOST_TEST( obj_reg.overeager_.empty() );
|
||||||
BOOST_CHECK( obj_reg.overkilled_.empty() );
|
BOOST_TEST( obj_reg.overkilled_.empty() );
|
||||||
|
|
||||||
// Getting the addresses of the objects ensure
|
// Getting the addresses of the objects ensure
|
||||||
// that they're used, and not optimized away.
|
// that they're used, and not optimized away.
|
||||||
@@ -209,13 +207,13 @@ test_main( int , char * [] )
|
|||||||
cout << "Object 'gc2' is at " << &gc2 << '.' << endl;
|
cout << "Object 'gc2' is at " << &gc2 << '.' << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( obj_reg.db_.empty() );
|
BOOST_TEST( obj_reg.db_.empty() );
|
||||||
BOOST_CHECK( obj_reg.defrauders_in_.size() == 1 );
|
BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
|
||||||
BOOST_CHECK( obj_reg.defrauders_out_.size() == 1 );
|
BOOST_TEST( obj_reg.defrauders_out_.size() == 1 );
|
||||||
BOOST_CHECK( obj_reg.overeager_.empty() );
|
BOOST_TEST( obj_reg.overeager_.empty() );
|
||||||
BOOST_CHECK( obj_reg.overkilled_.empty() );
|
BOOST_TEST( obj_reg.overkilled_.empty() );
|
||||||
|
|
||||||
return boost::exit_success;
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@@ -6,7 +6,7 @@
|
|||||||
http://www.boost.org/LICENSE_1_0.txt)
|
http://www.boost.org/LICENSE_1_0.txt)
|
||||||
==============================================================================*/
|
==============================================================================*/
|
||||||
|
|
||||||
#include <boost/test/minimal.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/utility/binary.hpp>
|
#include <boost/utility/binary.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -614,34 +614,34 @@ typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id];
|
|||||||
unsigned_int_id_type binary_type_checker( unsigned int );
|
unsigned_int_id_type binary_type_checker( unsigned int );
|
||||||
unsigned_long_int_id_type binary_type_checker( unsigned long int );
|
unsigned_long_int_id_type binary_type_checker( unsigned long int );
|
||||||
|
|
||||||
int test_main( int, char *[] )
|
int main()
|
||||||
{
|
{
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_1_bit ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_2_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_3_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_4_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_5_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_6_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_7_bits ) );
|
||||||
BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) );
|
BOOST_TEST( is_ascending_from_0_array( unsigned_ints_8_bits ) );
|
||||||
|
|
||||||
BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0]
|
BOOST_TEST( std::equal( &random_unsigned_ints_hex[0]
|
||||||
, random_unsigned_ints_hex + num_random_test_values
|
, random_unsigned_ints_hex + num_random_test_values
|
||||||
, &random_unsigned_ints_binary[0]
|
, &random_unsigned_ints_binary[0]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
|
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
|
||||||
== unsigned_int_id
|
== unsigned_int_id
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
|
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
|
||||||
== unsigned_long_int_id
|
== unsigned_long_int_id
|
||||||
);
|
);
|
||||||
|
|
||||||
BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
|
BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
|
||||||
== unsigned_long_int_id
|
== unsigned_long_int_id
|
||||||
);
|
);
|
||||||
|
|
||||||
return 0;
|
return boost::report_errors();
|
||||||
}
|
}
|
@@ -14,7 +14,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <boost/compressed_pair.hpp>
|
#include <boost/compressed_pair.hpp>
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
@@ -79,47 +79,47 @@ void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type
|
|||||||
// first param construct:
|
// first param construct:
|
||||||
boost::compressed_pair<T1,T2> cp2(p1);
|
boost::compressed_pair<T1,T2> cp2(p1);
|
||||||
cp2.second() = p2;
|
cp2.second() = p2;
|
||||||
BOOST_CHECK(cp2.first() == p1);
|
BOOST_TEST(cp2.first() == p1);
|
||||||
BOOST_CHECK(cp2.second() == p2);
|
BOOST_TEST(cp2.second() == p2);
|
||||||
// second param construct:
|
// second param construct:
|
||||||
boost::compressed_pair<T1,T2> cp3(p2);
|
boost::compressed_pair<T1,T2> cp3(p2);
|
||||||
cp3.first() = p1;
|
cp3.first() = p1;
|
||||||
BOOST_CHECK(cp3.second() == p2);
|
BOOST_TEST(cp3.second() == p2);
|
||||||
BOOST_CHECK(cp3.first() == p1);
|
BOOST_TEST(cp3.first() == p1);
|
||||||
// both param construct:
|
// both param construct:
|
||||||
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
||||||
BOOST_CHECK(cp4.first() == p1);
|
BOOST_TEST(cp4.first() == p1);
|
||||||
BOOST_CHECK(cp4.second() == p2);
|
BOOST_TEST(cp4.second() == p2);
|
||||||
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
||||||
BOOST_CHECK(cp5.first() == p3);
|
BOOST_TEST(cp5.first() == p3);
|
||||||
BOOST_CHECK(cp5.second() == p4);
|
BOOST_TEST(cp5.second() == p4);
|
||||||
// check const members:
|
// check const members:
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
||||||
BOOST_CHECK(cpr1.first() == p1);
|
BOOST_TEST(cpr1.first() == p1);
|
||||||
BOOST_CHECK(cpr1.second() == p2);
|
BOOST_TEST(cpr1.second() == p2);
|
||||||
|
|
||||||
// copy construct:
|
// copy construct:
|
||||||
boost::compressed_pair<T1,T2> cp6(cp4);
|
boost::compressed_pair<T1,T2> cp6(cp4);
|
||||||
BOOST_CHECK(cp6.first() == p1);
|
BOOST_TEST(cp6.first() == p1);
|
||||||
BOOST_CHECK(cp6.second() == p2);
|
BOOST_TEST(cp6.second() == p2);
|
||||||
// assignment:
|
// assignment:
|
||||||
cp1 = cp4;
|
cp1 = cp4;
|
||||||
BOOST_CHECK(cp1.first() == p1);
|
BOOST_TEST(cp1.first() == p1);
|
||||||
BOOST_CHECK(cp1.second() == p2);
|
BOOST_TEST(cp1.second() == p2);
|
||||||
cp1 = cp5;
|
cp1 = cp5;
|
||||||
BOOST_CHECK(cp1.first() == p3);
|
BOOST_TEST(cp1.first() == p3);
|
||||||
BOOST_CHECK(cp1.second() == p4);
|
BOOST_TEST(cp1.second() == p4);
|
||||||
// swap:
|
// swap:
|
||||||
cp4.swap(cp5);
|
cp4.swap(cp5);
|
||||||
BOOST_CHECK(cp4.first() == p3);
|
BOOST_TEST(cp4.first() == p3);
|
||||||
BOOST_CHECK(cp4.second() == p4);
|
BOOST_TEST(cp4.second() == p4);
|
||||||
BOOST_CHECK(cp5.first() == p1);
|
BOOST_TEST(cp5.first() == p1);
|
||||||
BOOST_CHECK(cp5.second() == p2);
|
BOOST_TEST(cp5.second() == p2);
|
||||||
swap(cp4,cp5);
|
swap(cp4,cp5);
|
||||||
BOOST_CHECK(cp4.first() == p1);
|
BOOST_TEST(cp4.first() == p1);
|
||||||
BOOST_CHECK(cp4.second() == p2);
|
BOOST_TEST(cp4.second() == p2);
|
||||||
BOOST_CHECK(cp5.first() == p3);
|
BOOST_TEST(cp5.first() == p3);
|
||||||
BOOST_CHECK(cp5.second() == p4);
|
BOOST_TEST(cp5.second() == p4);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -148,20 +148,20 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
|
|||||||
#endif
|
#endif
|
||||||
// both param construct:
|
// both param construct:
|
||||||
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
||||||
BOOST_CHECK(cp4.first() == p1);
|
BOOST_TEST(cp4.first() == p1);
|
||||||
BOOST_CHECK(cp4.second() == p2);
|
BOOST_TEST(cp4.second() == p2);
|
||||||
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
||||||
BOOST_CHECK(cp5.first() == p3);
|
BOOST_TEST(cp5.first() == p3);
|
||||||
BOOST_CHECK(cp5.second() == p4);
|
BOOST_TEST(cp5.second() == p4);
|
||||||
// check const members:
|
// check const members:
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
||||||
BOOST_CHECK(cpr1.first() == p1);
|
BOOST_TEST(cpr1.first() == p1);
|
||||||
BOOST_CHECK(cpr1.second() == p2);
|
BOOST_TEST(cpr1.second() == p2);
|
||||||
|
|
||||||
// copy construct:
|
// copy construct:
|
||||||
boost::compressed_pair<T1,T2> cp6(cp4);
|
boost::compressed_pair<T1,T2> cp6(cp4);
|
||||||
BOOST_CHECK(cp6.first() == p1);
|
BOOST_TEST(cp6.first() == p1);
|
||||||
BOOST_CHECK(cp6.second() == p2);
|
BOOST_TEST(cp6.second() == p2);
|
||||||
// assignment:
|
// assignment:
|
||||||
// VC6 bug:
|
// VC6 bug:
|
||||||
// When second() is an empty class, VC6 performs the
|
// When second() is an empty class, VC6 performs the
|
||||||
@@ -174,8 +174,8 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
|
|||||||
// settings - some generate the problem others do not.
|
// settings - some generate the problem others do not.
|
||||||
cp4.first() = p3;
|
cp4.first() = p3;
|
||||||
cp4.second() = p4;
|
cp4.second() = p4;
|
||||||
BOOST_CHECK(cp4.first() == p3);
|
BOOST_TEST(cp4.first() == p3);
|
||||||
BOOST_CHECK(cp4.second() == p4);
|
BOOST_TEST(cp4.second() == p4);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// supplimentary tests for case where first arg only is a reference type:
|
// supplimentary tests for case where first arg only is a reference type:
|
||||||
@@ -199,8 +199,8 @@ void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second
|
|||||||
// first param construct:
|
// first param construct:
|
||||||
boost::compressed_pair<T1,T2> cp2(p1);
|
boost::compressed_pair<T1,T2> cp2(p1);
|
||||||
cp2.second() = p2;
|
cp2.second() = p2;
|
||||||
BOOST_CHECK(cp2.first() == p1);
|
BOOST_TEST(cp2.first() == p1);
|
||||||
BOOST_CHECK(cp2.second() == p2);
|
BOOST_TEST(cp2.second() == p2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -225,8 +225,8 @@ void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second
|
|||||||
// second param construct:
|
// second param construct:
|
||||||
boost::compressed_pair<T1,T2> cp3(p2);
|
boost::compressed_pair<T1,T2> cp3(p2);
|
||||||
cp3.first() = p1;
|
cp3.first() = p1;
|
||||||
BOOST_CHECK(cp3.second() == p2);
|
BOOST_TEST(cp3.second() == p2);
|
||||||
BOOST_CHECK(cp3.first() == p1);
|
BOOST_TEST(cp3.first() == p1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,14 +253,14 @@ void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_par
|
|||||||
// second param construct:
|
// second param construct:
|
||||||
boost::compressed_pair<T1,T2> cp3(p2);
|
boost::compressed_pair<T1,T2> cp3(p2);
|
||||||
cp3.first()[0] = p1[0];
|
cp3.first()[0] = p1[0];
|
||||||
BOOST_CHECK(cp3.second() == p2);
|
BOOST_TEST(cp3.second() == p2);
|
||||||
BOOST_CHECK(cp3.first()[0] == p1[0]);
|
BOOST_TEST(cp3.first()[0] == p1[0]);
|
||||||
// check const members:
|
// check const members:
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp3;
|
const boost::compressed_pair<T1,T2>& cpr1 = cp3;
|
||||||
BOOST_CHECK(cpr1.first()[0] == p1[0]);
|
BOOST_TEST(cpr1.first()[0] == p1[0]);
|
||||||
BOOST_CHECK(cpr1.second() == p2);
|
BOOST_TEST(cpr1.second() == p2);
|
||||||
|
|
||||||
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
|
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
@@ -283,14 +283,14 @@ void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_par
|
|||||||
// first param construct:
|
// first param construct:
|
||||||
boost::compressed_pair<T1,T2> cp2(p1);
|
boost::compressed_pair<T1,T2> cp2(p1);
|
||||||
cp2.second()[0] = p2[0];
|
cp2.second()[0] = p2[0];
|
||||||
BOOST_CHECK(cp2.first() == p1);
|
BOOST_TEST(cp2.first() == p1);
|
||||||
BOOST_CHECK(cp2.second()[0] == p2[0]);
|
BOOST_TEST(cp2.second()[0] == p2[0]);
|
||||||
// check const members:
|
// check const members:
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp2;
|
const boost::compressed_pair<T1,T2>& cpr1 = cp2;
|
||||||
BOOST_CHECK(cpr1.first() == p1);
|
BOOST_TEST(cpr1.first() == p1);
|
||||||
BOOST_CHECK(cpr1.second()[0] == p2[0]);
|
BOOST_TEST(cpr1.second()[0] == p2[0]);
|
||||||
|
|
||||||
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
|
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
@@ -312,18 +312,18 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para
|
|||||||
boost::compressed_pair<T1,T2> cp1;
|
boost::compressed_pair<T1,T2> cp1;
|
||||||
cp1.first()[0] = p1[0];
|
cp1.first()[0] = p1[0];
|
||||||
cp1.second()[0] = p2[0];
|
cp1.second()[0] = p2[0];
|
||||||
BOOST_CHECK(cp1.first()[0] == p1[0]);
|
BOOST_TEST(cp1.first()[0] == p1[0]);
|
||||||
BOOST_CHECK(cp1.second()[0] == p2[0]);
|
BOOST_TEST(cp1.second()[0] == p2[0]);
|
||||||
// check const members:
|
// check const members:
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp1;
|
const boost::compressed_pair<T1,T2>& cpr1 = cp1;
|
||||||
BOOST_CHECK(cpr1.first()[0] == p1[0]);
|
BOOST_TEST(cpr1.first()[0] == p1[0]);
|
||||||
BOOST_CHECK(cpr1.second()[0] == p2[0]);
|
BOOST_TEST(cpr1.second()[0] == p2[0]);
|
||||||
|
|
||||||
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
|
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
|
||||||
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
|
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_main(int, char *[])
|
int main()
|
||||||
{
|
{
|
||||||
// declare some variables to pass to the tester:
|
// declare some variables to pass to the tester:
|
||||||
non_empty1 ne1(2);
|
non_empty1 ne1(2);
|
||||||
@@ -383,13 +383,5 @@ int test_main(int, char *[])
|
|||||||
compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
|
compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
|
||||||
// T1 == T2, both non-empty
|
// T1 == T2, both non-empty
|
||||||
compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
|
compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
|
||||||
return 0;
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -9,7 +9,7 @@
|
|||||||
// 2 May 2010 (Created) Niels Dekker
|
// 2 May 2010 (Created) Niels Dekker
|
||||||
|
|
||||||
#include <boost/utility/value_init.hpp>
|
#include <boost/utility/value_init.hpp>
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@@ -12,11 +12,9 @@
|
|||||||
// library (Daryle Walker)
|
// library (Daryle Walker)
|
||||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/test/test_tools.hpp> // for main
|
|
||||||
|
|
||||||
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
|
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
|
||||||
#include <boost/operators.hpp> // for boost::random_access_iterator_helper
|
#include <boost/operators.hpp> // for boost::random_access_iterator_helper
|
||||||
|
|
||||||
#include <cstddef> // for std::ptrdiff_t, std::size_t
|
#include <cstddef> // for std::ptrdiff_t, std::size_t
|
||||||
@@ -126,7 +124,7 @@ typename test_opr<T, R, P>::iter_type const
|
|||||||
|
|
||||||
// Main testing function
|
// Main testing function
|
||||||
int
|
int
|
||||||
test_main( int , char * [] )
|
main()
|
||||||
{
|
{
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
@@ -136,7 +134,7 @@ test_main( int , char * [] )
|
|||||||
test1_type::master_test( "non-const string" );
|
test1_type::master_test( "non-const string" );
|
||||||
test2_type::master_test( "const string" );
|
test2_type::master_test( "const string" );
|
||||||
|
|
||||||
return boost::exit_success;
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests for all of the operators added by random_access_iterator_helper
|
// Tests for all of the operators added by random_access_iterator_helper
|
||||||
@@ -174,7 +172,7 @@ test_opr<T, R, P>::post_increment_test
|
|||||||
oss << *i++ << ' ';
|
oss << *i++ << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
|
BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test post-decrement
|
// Test post-decrement
|
||||||
@@ -193,7 +191,7 @@ test_opr<T, R, P>::post_decrement_test
|
|||||||
oss << *i << ' ';
|
oss << *i << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "plum grape peach pear orange apple ");
|
BOOST_TEST( oss.str() == "plum grape peach pear orange apple ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test indirect structure referral
|
// Test indirect structure referral
|
||||||
@@ -211,7 +209,7 @@ test_opr<T, R, P>::indirect_referral_test
|
|||||||
oss << i->size() << ' ';
|
oss << i->size() << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "5 6 4 5 5 4 ");
|
BOOST_TEST( oss.str() == "5 6 4 5 5 4 ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test offset addition
|
// Test offset addition
|
||||||
@@ -230,7 +228,7 @@ test_opr<T, R, P>::offset_addition_test
|
|||||||
oss << *i << ' ';
|
oss << *i << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "apple pear grape ");
|
BOOST_TEST( oss.str() == "apple pear grape ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test offset addition, in reverse order
|
// Test offset addition, in reverse order
|
||||||
@@ -249,7 +247,7 @@ test_opr<T, R, P>::reverse_offset_addition_test
|
|||||||
oss << *i << ' ';
|
oss << *i << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "apple pear grape ");
|
BOOST_TEST( oss.str() == "apple pear grape ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test offset subtraction
|
// Test offset subtraction
|
||||||
@@ -272,7 +270,7 @@ test_opr<T, R, P>::offset_subtraction_test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "grape pear apple ");
|
BOOST_TEST( oss.str() == "grape pear apple ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test comparisons
|
// Test comparisons
|
||||||
@@ -296,10 +294,10 @@ test_opr<T, R, P>::comparison_test
|
|||||||
{
|
{
|
||||||
ptrdiff_t const j_offset = j - fruit_begin;
|
ptrdiff_t const j_offset = j - fruit_begin;
|
||||||
|
|
||||||
BOOST_CHECK( (i != j) == (i_offset != j_offset) );
|
BOOST_TEST( (i != j) == (i_offset != j_offset) );
|
||||||
BOOST_CHECK( (i > j) == (i_offset > j_offset) );
|
BOOST_TEST( (i > j) == (i_offset > j_offset) );
|
||||||
BOOST_CHECK( (i <= j) == (i_offset <= j_offset) );
|
BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
|
||||||
BOOST_CHECK( (i >= j) == (i_offset >= j_offset) );
|
BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout << std::endl;
|
cout << std::endl;
|
||||||
@@ -320,5 +318,5 @@ test_opr<T, R, P>::indexing_test
|
|||||||
oss << fruit_begin[ k ] << ' ';
|
oss << fruit_begin[ k ] << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
|
BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
|
||||||
}
|
}
|
@@ -1,97 +0,0 @@
|
|||||||
// Boost test program for next() and prior() utilities.
|
|
||||||
|
|
||||||
// Copyright 2003 Daniel 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/utility for documentation.
|
|
||||||
|
|
||||||
// Revision History 13 Dec 2003 Initial Version (Daniel Walker)
|
|
||||||
|
|
||||||
// next() and prior() are replacements for operator+ and operator- for
|
|
||||||
// non-random-access iterators. The semantics of these operators are
|
|
||||||
// such that after executing j = i + n, std::distance(i, j) equals
|
|
||||||
// n. Tests are provided to ensure next() has the same
|
|
||||||
// result. Parallel tests are provided for prior(). The tests call
|
|
||||||
// next() and prior() several times. next() and prior() are very
|
|
||||||
// simple functions, though, and it would be very strange if these
|
|
||||||
// tests were to fail.
|
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
|
||||||
#include <boost/test/test_tools.hpp>
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <boost/next_prior.hpp>
|
|
||||||
|
|
||||||
template<class RandomAccessIterator, class ForwardIterator>
|
|
||||||
bool plus_one_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2)
|
|
||||||
{
|
|
||||||
RandomAccessIterator i = first;
|
|
||||||
ForwardIterator j = first2;
|
|
||||||
while(i != last)
|
|
||||||
i = i + 1, j = boost::next(j);
|
|
||||||
return std::distance(first, i) == std::distance(first2, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class RandomAccessIterator, class ForwardIterator>
|
|
||||||
bool plus_n_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2)
|
|
||||||
{
|
|
||||||
RandomAccessIterator i = first;
|
|
||||||
ForwardIterator j = first2;
|
|
||||||
for(int n = 0; i != last; ++n)
|
|
||||||
i = first + n, j = boost::next(first2, n);
|
|
||||||
return std::distance(first, i) == std::distance(first2, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class RandomAccessIterator, class BidirectionalIterator>
|
|
||||||
bool minus_one_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2)
|
|
||||||
{
|
|
||||||
RandomAccessIterator i = last;
|
|
||||||
BidirectionalIterator j = last2;
|
|
||||||
while(i != first)
|
|
||||||
i = i - 1, j = boost::prior(j);
|
|
||||||
return std::distance(i, last) == std::distance(j, last2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class RandomAccessIterator, class BidirectionalIterator>
|
|
||||||
bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2)
|
|
||||||
{
|
|
||||||
RandomAccessIterator i = last;
|
|
||||||
BidirectionalIterator j = last2;
|
|
||||||
for(int n = 0; i != first; ++n)
|
|
||||||
i = last - n, j = boost::prior(last2, n);
|
|
||||||
return std::distance(i, last) == std::distance(j, last2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Iterator, class Distance>
|
|
||||||
bool minus_n_unsigned_test(Iterator first, Iterator last, Distance size)
|
|
||||||
{
|
|
||||||
Iterator i = boost::prior(last, size);
|
|
||||||
return i == first;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_main(int, char*[])
|
|
||||||
{
|
|
||||||
std::vector<int> x(8);
|
|
||||||
std::list<int> y(x.begin(), x.end());
|
|
||||||
|
|
||||||
// Tests with iterators
|
|
||||||
BOOST_REQUIRE(plus_one_test(x.begin(), x.end(), y.begin()));
|
|
||||||
BOOST_REQUIRE(plus_n_test(x.begin(), x.end(), y.begin()));
|
|
||||||
BOOST_REQUIRE(minus_one_test(x.begin(), x.end(), y.end()));
|
|
||||||
BOOST_REQUIRE(minus_n_test(x.begin(), x.end(), y.end()));
|
|
||||||
BOOST_REQUIRE(minus_n_unsigned_test(x.begin(), x.end(), x.size()));
|
|
||||||
BOOST_REQUIRE(minus_n_unsigned_test(y.begin(), y.end(), y.size()));
|
|
||||||
|
|
||||||
// Tests with integers
|
|
||||||
BOOST_REQUIRE(boost::next(5) == 6);
|
|
||||||
BOOST_REQUIRE(boost::next(5, 7) == 12);
|
|
||||||
BOOST_REQUIRE(boost::prior(5) == 4);
|
|
||||||
BOOST_REQUIRE(boost::prior(5, 7) == -2);
|
|
||||||
BOOST_REQUIRE(boost::prior(5, 7u) == -2);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@@ -21,13 +21,10 @@
|
|||||||
// 12 Dec 99 Minor update, output confirmation message.
|
// 12 Dec 99 Minor update, output confirmation message.
|
||||||
// 15 Nov 99 Initial version
|
// 15 Nov 99 Initial version
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
|
||||||
|
|
||||||
#include <boost/config.hpp> // for BOOST_MSVC
|
#include <boost/config.hpp> // for BOOST_MSVC
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
|
||||||
#include <boost/operators.hpp> // for the tested items
|
#include <boost/operators.hpp> // for the tested items
|
||||||
#include <boost/random/linear_congruential.hpp> // for boost::minstd_rand
|
#include <boost/utility/detail/minstd_rand.hpp> // for boost::detail::minstd_rand
|
||||||
#include <boost/test/test_tools.hpp> // for main
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
#include <iostream> // for std::cout (std::endl indirectly)
|
#include <iostream> // for std::cout (std::endl indirectly)
|
||||||
|
|
||||||
@@ -38,11 +35,9 @@ namespace
|
|||||||
int true_value(int x) { return x; }
|
int true_value(int x) { return x; }
|
||||||
long true_value(long x) { return x; }
|
long true_value(long x) { return x; }
|
||||||
signed char true_value(signed char x) { return x; }
|
signed char true_value(signed char x) { return x; }
|
||||||
short true_value(short x) { return x; }
|
|
||||||
unsigned int true_value(unsigned int x) { return x; }
|
unsigned int true_value(unsigned int x) { return x; }
|
||||||
unsigned long true_value(unsigned long x) { return x; }
|
unsigned long true_value(unsigned long x) { return x; }
|
||||||
unsigned char true_value(unsigned char x) { return x; }
|
unsigned char true_value(unsigned char x) { return x; }
|
||||||
unsigned short true_value(unsigned short x) { return x; }
|
|
||||||
|
|
||||||
// verify the minimum requirements for some operators
|
// verify the minimum requirements for some operators
|
||||||
class convertible_to_bool
|
class convertible_to_bool
|
||||||
@@ -313,17 +308,17 @@ namespace
|
|||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_CHECK( true_value(y1) == true_value(y2) );
|
BOOST_TEST( true_value(y1) == true_value(y2) );
|
||||||
BOOST_CHECK( true_value(x1) == true_value(x2) );
|
BOOST_TEST( true_value(x1) == true_value(x2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_CHECK( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
|
BOOST_TEST( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
|
||||||
BOOST_CHECK( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
|
BOOST_TEST( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
|
||||||
BOOST_CHECK( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
|
BOOST_TEST( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
|
||||||
BOOST_CHECK( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
|
BOOST_TEST( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
@@ -337,8 +332,8 @@ namespace
|
|||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_CHECK( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
|
BOOST_TEST( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
|
||||||
BOOST_CHECK( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
|
BOOST_TEST( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
@@ -352,7 +347,7 @@ namespace
|
|||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
|
BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
@@ -366,7 +361,7 @@ namespace
|
|||||||
template <class A, class B>
|
template <class A, class B>
|
||||||
void test_value_equality(A a, B b)
|
void test_value_equality(A a, B b)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(a.value() == b);
|
BOOST_TEST(a.value() == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
|
#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
|
||||||
@@ -492,16 +487,16 @@ namespace
|
|||||||
void test_incrementable(X1 x1, X2 x2)
|
void test_incrementable(X1 x1, X2 x2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, x1, x2, x2 );
|
sanity_check( x1, x1, x2, x2 );
|
||||||
BOOST_CHECK( (x1++).value() == x2++ );
|
BOOST_TEST( (x1++).value() == x2++ );
|
||||||
BOOST_CHECK( x1.value() == x2 );
|
BOOST_TEST( x1.value() == x2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class X2>
|
template <class X1, class X2>
|
||||||
void test_decrementable(X1 x1, X2 x2)
|
void test_decrementable(X1 x1, X2 x2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, x1, x2, x2 );
|
sanity_check( x1, x1, x2, x2 );
|
||||||
BOOST_CHECK( (x1--).value() == x2-- );
|
BOOST_TEST( (x1--).value() == x2-- );
|
||||||
BOOST_CHECK( x1.value() == x2 );
|
BOOST_TEST( x1.value() == x2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
@@ -534,7 +529,7 @@ namespace
|
|||||||
template <class Big, class Small>
|
template <class Big, class Small>
|
||||||
struct tester
|
struct tester
|
||||||
{
|
{
|
||||||
void operator()(boost::minstd_rand& randomizer) const
|
void operator()(boost::detail::minstd_rand& randomizer) const
|
||||||
{
|
{
|
||||||
Big b1 = Big( randomizer() );
|
Big b1 = Big( randomizer() );
|
||||||
Big b2 = Big( randomizer() );
|
Big b2 = Big( randomizer() );
|
||||||
@@ -548,7 +543,7 @@ namespace
|
|||||||
template <class Big, class Small>
|
template <class Big, class Small>
|
||||||
struct tester_left
|
struct tester_left
|
||||||
{
|
{
|
||||||
void operator()(boost::minstd_rand& randomizer) const
|
void operator()(boost::detail::minstd_rand& randomizer) const
|
||||||
{
|
{
|
||||||
Big b1 = Big( randomizer() );
|
Big b1 = Big( randomizer() );
|
||||||
Small s = Small( randomizer() );
|
Small s = Small( randomizer() );
|
||||||
@@ -605,10 +600,10 @@ template Wrapped6<unsigned long, unsigned char>;
|
|||||||
template Wrapped6<unsigned int, unsigned char>;
|
template Wrapped6<unsigned int, unsigned char>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PRIVATE_EXPR_TEST(e, t) BOOST_CHECK( ((e), (t)) )
|
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
|
||||||
|
|
||||||
int
|
int
|
||||||
test_main( int , char * [] )
|
main()
|
||||||
{
|
{
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
@@ -622,7 +617,7 @@ test_main( int , char * [] )
|
|||||||
|
|
||||||
for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
|
for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
|
||||||
{
|
{
|
||||||
boost::minstd_rand r;
|
boost::detail::minstd_rand r;
|
||||||
tester<long, int>()(r);
|
tester<long, int>()(r);
|
||||||
tester<long, signed char>()(r);
|
tester<long, signed char>()(r);
|
||||||
tester<long, long>()(r);
|
tester<long, long>()(r);
|
||||||
@@ -650,22 +645,22 @@ test_main( int , char * [] )
|
|||||||
MyInt i2(2);
|
MyInt i2(2);
|
||||||
MyInt i;
|
MyInt i;
|
||||||
|
|
||||||
BOOST_CHECK( i1.value() == 1 );
|
BOOST_TEST( i1.value() == 1 );
|
||||||
BOOST_CHECK( i2.value() == 2 );
|
BOOST_TEST( i2.value() == 2 );
|
||||||
BOOST_CHECK( i.value() == 0 );
|
BOOST_TEST( i.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyInt objects.\n";
|
cout << "Created MyInt objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
|
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(i2 == i) );
|
BOOST_TEST( static_cast<bool>(i2 == i) );
|
||||||
BOOST_CHECK( static_cast<bool>(i1 != i2) );
|
BOOST_TEST( static_cast<bool>(i1 != i2) );
|
||||||
BOOST_CHECK( static_cast<bool>(i1 < i2) );
|
BOOST_TEST( static_cast<bool>(i1 < i2) );
|
||||||
BOOST_CHECK( static_cast<bool>(i1 <= i2) );
|
BOOST_TEST( static_cast<bool>(i1 <= i2) );
|
||||||
BOOST_CHECK( static_cast<bool>(i <= i2) );
|
BOOST_TEST( static_cast<bool>(i <= i2) );
|
||||||
BOOST_CHECK( static_cast<bool>(i2 > i1) );
|
BOOST_TEST( static_cast<bool>(i2 > i1) );
|
||||||
BOOST_CHECK( static_cast<bool>(i2 >= i1) );
|
BOOST_TEST( static_cast<bool>(i2 >= i1) );
|
||||||
BOOST_CHECK( static_cast<bool>(i2 >= i) );
|
BOOST_TEST( static_cast<bool>(i2 >= i) );
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
|
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
|
||||||
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
|
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
|
||||||
@@ -689,86 +684,86 @@ test_main( int , char * [] )
|
|||||||
MyLong j2(2);
|
MyLong j2(2);
|
||||||
MyLong j;
|
MyLong j;
|
||||||
|
|
||||||
BOOST_CHECK( j1.value() == 1 );
|
BOOST_TEST( j1.value() == 1 );
|
||||||
BOOST_CHECK( j2.value() == 2 );
|
BOOST_TEST( j2.value() == 2 );
|
||||||
BOOST_CHECK( j.value() == 0 );
|
BOOST_TEST( j.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyLong objects.\n";
|
cout << "Created MyLong objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
|
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(j2 == j) );
|
BOOST_TEST( static_cast<bool>(j2 == j) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 == j) );
|
BOOST_TEST( static_cast<bool>(2 == j) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 == 2) );
|
BOOST_TEST( static_cast<bool>(j2 == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j == j2) );
|
BOOST_TEST( static_cast<bool>(j == j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 != j2) );
|
BOOST_TEST( static_cast<bool>(j1 != j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 != 2) );
|
BOOST_TEST( static_cast<bool>(j1 != 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 != j2) );
|
BOOST_TEST( static_cast<bool>(1 != j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 < j2) );
|
BOOST_TEST( static_cast<bool>(j1 < j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 < j2) );
|
BOOST_TEST( static_cast<bool>(1 < j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 < 2) );
|
BOOST_TEST( static_cast<bool>(j1 < 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 <= j2) );
|
BOOST_TEST( static_cast<bool>(j1 <= j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 <= j2) );
|
BOOST_TEST( static_cast<bool>(1 <= j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j1 <= j) );
|
BOOST_TEST( static_cast<bool>(j1 <= j) );
|
||||||
BOOST_CHECK( static_cast<bool>(j <= j2) );
|
BOOST_TEST( static_cast<bool>(j <= j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 <= j2) );
|
BOOST_TEST( static_cast<bool>(2 <= j2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j <= 2) );
|
BOOST_TEST( static_cast<bool>(j <= 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 > j1) );
|
BOOST_TEST( static_cast<bool>(j2 > j1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 > j1) );
|
BOOST_TEST( static_cast<bool>(2 > j1) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 > 1) );
|
BOOST_TEST( static_cast<bool>(j2 > 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 >= j1) );
|
BOOST_TEST( static_cast<bool>(j2 >= j1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 >= j1) );
|
BOOST_TEST( static_cast<bool>(2 >= j1) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 >= 1) );
|
BOOST_TEST( static_cast<bool>(j2 >= 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 >= j) );
|
BOOST_TEST( static_cast<bool>(j2 >= j) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 >= j) );
|
BOOST_TEST( static_cast<bool>(2 >= j) );
|
||||||
BOOST_CHECK( static_cast<bool>(j2 >= 2) );
|
BOOST_TEST( static_cast<bool>(j2 >= 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j1 + 2) == 3) );
|
BOOST_TEST( static_cast<bool>((j1 + 2) == 3) );
|
||||||
BOOST_CHECK( static_cast<bool>((1 + j2) == 3) );
|
BOOST_TEST( static_cast<bool>((1 + j2) == 3) );
|
||||||
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
|
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j + 2) == 5) );
|
BOOST_TEST( static_cast<bool>((j + 2) == 5) );
|
||||||
BOOST_CHECK( static_cast<bool>((3 + j2) == 5) );
|
BOOST_TEST( static_cast<bool>((3 + j2) == 5) );
|
||||||
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
|
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j - 1) == 4) );
|
BOOST_TEST( static_cast<bool>((j - 1) == 4) );
|
||||||
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
|
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j * 2) == 8) );
|
BOOST_TEST( static_cast<bool>((j * 2) == 8) );
|
||||||
BOOST_CHECK( static_cast<bool>((4 * j2) == 8) );
|
BOOST_TEST( static_cast<bool>((4 * j2) == 8) );
|
||||||
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
|
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j / 2) == 4) );
|
BOOST_TEST( static_cast<bool>((j / 2) == 4) );
|
||||||
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
|
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j % 3) == 1) );
|
BOOST_TEST( static_cast<bool>((j % 3) == 1) );
|
||||||
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
|
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
|
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((1 | j2 | j) == 7) );
|
BOOST_TEST( static_cast<bool>((1 | j2 | j) == 7) );
|
||||||
BOOST_CHECK( static_cast<bool>((j1 | 2 | j) == 7) );
|
BOOST_TEST( static_cast<bool>((j1 | 2 | j) == 7) );
|
||||||
BOOST_CHECK( static_cast<bool>((j1 | j2 | 4) == 7) );
|
BOOST_TEST( static_cast<bool>((j1 | j2 | 4) == 7) );
|
||||||
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
|
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((7 & j2) == 2) );
|
BOOST_TEST( static_cast<bool>((7 & j2) == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>((j & 2) == 2) );
|
BOOST_TEST( static_cast<bool>((j & 2) == 2) );
|
||||||
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
|
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
|
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((3 ^ j1) == 2) );
|
BOOST_TEST( static_cast<bool>((3 ^ j1) == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>((j ^ 1) == 2) );
|
BOOST_TEST( static_cast<bool>((j ^ 1) == 2) );
|
||||||
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
|
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
|
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j1 << 2) == 4) );
|
BOOST_TEST( static_cast<bool>((j1 << 2) == 4) );
|
||||||
BOOST_CHECK( static_cast<bool>((j2 << 1) == 4) );
|
BOOST_TEST( static_cast<bool>((j2 << 1) == 4) );
|
||||||
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
|
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>((j >> 2) == 1) );
|
BOOST_TEST( static_cast<bool>((j >> 2) == 1) );
|
||||||
BOOST_CHECK( static_cast<bool>((j2 >> 1) == 1) );
|
BOOST_TEST( static_cast<bool>((j2 >> 1) == 1) );
|
||||||
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
|
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
|
||||||
|
|
||||||
cout << "Performed tests on MyLong objects.\n";
|
cout << "Performed tests on MyLong objects.\n";
|
||||||
@@ -777,22 +772,22 @@ test_main( int , char * [] )
|
|||||||
MyChar k2(2);
|
MyChar k2(2);
|
||||||
MyChar k;
|
MyChar k;
|
||||||
|
|
||||||
BOOST_CHECK( k1.value() == 1 );
|
BOOST_TEST( k1.value() == 1 );
|
||||||
BOOST_CHECK( k2.value() == 2 );
|
BOOST_TEST( k2.value() == 2 );
|
||||||
BOOST_CHECK( k.value() == 0 );
|
BOOST_TEST( k.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyChar objects.\n";
|
cout << "Created MyChar objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
|
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(k2 == k) );
|
BOOST_TEST( static_cast<bool>(k2 == k) );
|
||||||
BOOST_CHECK( static_cast<bool>(k1 != k2) );
|
BOOST_TEST( static_cast<bool>(k1 != k2) );
|
||||||
BOOST_CHECK( static_cast<bool>(k1 < k2) );
|
BOOST_TEST( static_cast<bool>(k1 < k2) );
|
||||||
BOOST_CHECK( static_cast<bool>(k1 <= k2) );
|
BOOST_TEST( static_cast<bool>(k1 <= k2) );
|
||||||
BOOST_CHECK( static_cast<bool>(k <= k2) );
|
BOOST_TEST( static_cast<bool>(k <= k2) );
|
||||||
BOOST_CHECK( static_cast<bool>(k2 > k1) );
|
BOOST_TEST( static_cast<bool>(k2 > k1) );
|
||||||
BOOST_CHECK( static_cast<bool>(k2 >= k1) );
|
BOOST_TEST( static_cast<bool>(k2 >= k1) );
|
||||||
BOOST_CHECK( static_cast<bool>(k2 >= k) );
|
BOOST_TEST( static_cast<bool>(k2 >= k) );
|
||||||
|
|
||||||
cout << "Performed tests on MyChar objects.\n";
|
cout << "Performed tests on MyChar objects.\n";
|
||||||
|
|
||||||
@@ -800,39 +795,39 @@ test_main( int , char * [] )
|
|||||||
MyShort l2(2);
|
MyShort l2(2);
|
||||||
MyShort l;
|
MyShort l;
|
||||||
|
|
||||||
BOOST_CHECK( l1.value() == 1 );
|
BOOST_TEST( l1.value() == 1 );
|
||||||
BOOST_CHECK( l2.value() == 2 );
|
BOOST_TEST( l2.value() == 2 );
|
||||||
BOOST_CHECK( l.value() == 0 );
|
BOOST_TEST( l.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyShort objects.\n";
|
cout << "Created MyShort objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
|
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(l2 == l) );
|
BOOST_TEST( static_cast<bool>(l2 == l) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 == l) );
|
BOOST_TEST( static_cast<bool>(2 == l) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 == 2) );
|
BOOST_TEST( static_cast<bool>(l2 == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l == l2) );
|
BOOST_TEST( static_cast<bool>(l == l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 != l2) );
|
BOOST_TEST( static_cast<bool>(l1 != l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 != 2) );
|
BOOST_TEST( static_cast<bool>(l1 != 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 != l2) );
|
BOOST_TEST( static_cast<bool>(1 != l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 < l2) );
|
BOOST_TEST( static_cast<bool>(l1 < l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 < l2) );
|
BOOST_TEST( static_cast<bool>(1 < l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 < 2) );
|
BOOST_TEST( static_cast<bool>(l1 < 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 <= l2) );
|
BOOST_TEST( static_cast<bool>(l1 <= l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 <= l2) );
|
BOOST_TEST( static_cast<bool>(1 <= l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l1 <= l) );
|
BOOST_TEST( static_cast<bool>(l1 <= l) );
|
||||||
BOOST_CHECK( static_cast<bool>(l <= l2) );
|
BOOST_TEST( static_cast<bool>(l <= l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 <= l2) );
|
BOOST_TEST( static_cast<bool>(2 <= l2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l <= 2) );
|
BOOST_TEST( static_cast<bool>(l <= 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 > l1) );
|
BOOST_TEST( static_cast<bool>(l2 > l1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 > l1) );
|
BOOST_TEST( static_cast<bool>(2 > l1) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 > 1) );
|
BOOST_TEST( static_cast<bool>(l2 > 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 >= l1) );
|
BOOST_TEST( static_cast<bool>(l2 >= l1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 >= l1) );
|
BOOST_TEST( static_cast<bool>(2 >= l1) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 >= 1) );
|
BOOST_TEST( static_cast<bool>(l2 >= 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 >= l) );
|
BOOST_TEST( static_cast<bool>(l2 >= l) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 >= l) );
|
BOOST_TEST( static_cast<bool>(2 >= l) );
|
||||||
BOOST_CHECK( static_cast<bool>(l2 >= 2) );
|
BOOST_TEST( static_cast<bool>(l2 >= 2) );
|
||||||
|
|
||||||
cout << "Performed tests on MyShort objects.\n";
|
cout << "Performed tests on MyShort objects.\n";
|
||||||
|
|
||||||
@@ -842,44 +837,44 @@ test_main( int , char * [] )
|
|||||||
MyDoubleInt di;
|
MyDoubleInt di;
|
||||||
MyDoubleInt tmp;
|
MyDoubleInt tmp;
|
||||||
|
|
||||||
BOOST_CHECK( di1.value() == 1 );
|
BOOST_TEST( di1.value() == 1 );
|
||||||
BOOST_CHECK( di2.value() == 2 );
|
BOOST_TEST( di2.value() == 2 );
|
||||||
BOOST_CHECK( di2.value() == 2 );
|
BOOST_TEST( di2.value() == 2 );
|
||||||
BOOST_CHECK( di.value() == 0 );
|
BOOST_TEST( di.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyDoubleInt objects.\n";
|
cout << "Created MyDoubleInt objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
|
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(di2 == di) );
|
BOOST_TEST( static_cast<bool>(di2 == di) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 == di) );
|
BOOST_TEST( static_cast<bool>(2 == di) );
|
||||||
BOOST_CHECK( static_cast<bool>(di == 2) );
|
BOOST_TEST( static_cast<bool>(di == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 < di2) );
|
BOOST_TEST( static_cast<bool>(di1 < di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 < di2) );
|
BOOST_TEST( static_cast<bool>(1 < di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 <= di2) );
|
BOOST_TEST( static_cast<bool>(di1 <= di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 <= di2) );
|
BOOST_TEST( static_cast<bool>(1 <= di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 > di1) );
|
BOOST_TEST( static_cast<bool>(di2 > di1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 > 1) );
|
BOOST_TEST( static_cast<bool>(di2 > 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 >= di1) );
|
BOOST_TEST( static_cast<bool>(di2 >= di1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 >= 1) );
|
BOOST_TEST( static_cast<bool>(di2 >= 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 / di2 == half) );
|
BOOST_TEST( static_cast<bool>(di1 / di2 == half) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 / 2 == half) );
|
BOOST_TEST( static_cast<bool>(di1 / 2 == half) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 / di2 == half) );
|
BOOST_TEST( static_cast<bool>(1 / di2 == half) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 * di2 == di2) );
|
BOOST_TEST( static_cast<bool>(di1 * di2 == di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 * 2 == di2) );
|
BOOST_TEST( static_cast<bool>(di1 * 2 == di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 * di2 == di2) );
|
BOOST_TEST( static_cast<bool>(1 * di2 == di2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 - di1 == di1) );
|
BOOST_TEST( static_cast<bool>(di2 - di1 == di1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di2 - 1 == di1) );
|
BOOST_TEST( static_cast<bool>(di2 - 1 == di1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 - di1 == di1) );
|
BOOST_TEST( static_cast<bool>(2 - di1 == di1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
|
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
|
PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 + di1 == di2) );
|
BOOST_TEST( static_cast<bool>(di1 + di1 == di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(di1 + 1 == di2) );
|
BOOST_TEST( static_cast<bool>(di1 + 1 == di2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 + di1 == di2) );
|
BOOST_TEST( static_cast<bool>(1 + di1 == di2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
|
PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
|
||||||
|
|
||||||
@@ -890,52 +885,52 @@ test_main( int , char * [] )
|
|||||||
MyLongInt li;
|
MyLongInt li;
|
||||||
MyLongInt tmp2;
|
MyLongInt tmp2;
|
||||||
|
|
||||||
BOOST_CHECK( li1.value() == 1 );
|
BOOST_TEST( li1.value() == 1 );
|
||||||
BOOST_CHECK( li2.value() == 2 );
|
BOOST_TEST( li2.value() == 2 );
|
||||||
BOOST_CHECK( li.value() == 0 );
|
BOOST_TEST( li.value() == 0 );
|
||||||
|
|
||||||
cout << "Created MyLongInt objects.\n";
|
cout << "Created MyLongInt objects.\n";
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
|
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
|
||||||
|
|
||||||
BOOST_CHECK( static_cast<bool>(li2 == li) );
|
BOOST_TEST( static_cast<bool>(li2 == li) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 == li) );
|
BOOST_TEST( static_cast<bool>(2 == li) );
|
||||||
BOOST_CHECK( static_cast<bool>(li == 2) );
|
BOOST_TEST( static_cast<bool>(li == 2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 < li2) );
|
BOOST_TEST( static_cast<bool>(li1 < li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 < li2) );
|
BOOST_TEST( static_cast<bool>(1 < li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 <= li2) );
|
BOOST_TEST( static_cast<bool>(li1 <= li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 <= li2) );
|
BOOST_TEST( static_cast<bool>(1 <= li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 > li1) );
|
BOOST_TEST( static_cast<bool>(li2 > li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 > 1) );
|
BOOST_TEST( static_cast<bool>(li2 > 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 >= li1) );
|
BOOST_TEST( static_cast<bool>(li2 >= li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 >= 1) );
|
BOOST_TEST( static_cast<bool>(li2 >= 1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 % li2 == li1) );
|
BOOST_TEST( static_cast<bool>(li1 % li2 == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 % 2 == li1) );
|
BOOST_TEST( static_cast<bool>(li1 % 2 == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 % li2 == li1) );
|
BOOST_TEST( static_cast<bool>(1 % li2 == li1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 / li2 == 0) );
|
BOOST_TEST( static_cast<bool>(li1 / li2 == 0) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 / 2 == 0) );
|
BOOST_TEST( static_cast<bool>(li1 / 2 == 0) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 / li2 == 0) );
|
BOOST_TEST( static_cast<bool>(1 / li2 == 0) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 * li2 == li2) );
|
BOOST_TEST( static_cast<bool>(li1 * li2 == li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 * 2 == li2) );
|
BOOST_TEST( static_cast<bool>(li1 * 2 == li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 * li2 == li2) );
|
BOOST_TEST( static_cast<bool>(1 * li2 == li2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 - li1 == li1) );
|
BOOST_TEST( static_cast<bool>(li2 - li1 == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li2 - 1 == li1) );
|
BOOST_TEST( static_cast<bool>(li2 - 1 == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(2 - li1 == li1) );
|
BOOST_TEST( static_cast<bool>(2 - li1 == li1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
|
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
|
PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 + li1 == li2) );
|
BOOST_TEST( static_cast<bool>(li1 + li1 == li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(li1 + 1 == li2) );
|
BOOST_TEST( static_cast<bool>(li1 + 1 == li2) );
|
||||||
BOOST_CHECK( static_cast<bool>(1 + li1 == li2) );
|
BOOST_TEST( static_cast<bool>(1 + li1 == li2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
|
||||||
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
|
PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
|
||||||
|
|
||||||
cout << "Performed tests on MyLongInt objects.\n";
|
cout << "Performed tests on MyLongInt objects.\n";
|
||||||
|
|
||||||
return boost::exit_success;
|
return boost::report_errors();
|
||||||
}
|
}
|
@@ -297,6 +297,12 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr&(char, float)>::type, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr const&(char, float)>::type, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of&(double)>::type, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of const&(double)>::type, int>::value));
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));
|
||||||
|
26
test/string_ref_from_rvalue.cpp
Normal file
26
test/string_ref_from_rvalue.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2017.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||||
|
#error "Unsupported test"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string makeatemp() { return "abc"; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::basic_string_ref<char> sv(makeatemp());
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -13,17 +13,16 @@
|
|||||||
|
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
|
||||||
#define BOOST_TEST_MAIN
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
typedef boost::string_ref string_ref;
|
typedef boost::string_ref string_ref;
|
||||||
|
|
||||||
// Should be equal
|
// Should be equal
|
||||||
void interop ( const std::string &str, string_ref ref ) {
|
void interop ( const std::string &str, string_ref ref ) {
|
||||||
// BOOST_CHECK ( str == ref );
|
// BOOST_TEST ( str == ref );
|
||||||
BOOST_CHECK ( str.size () == ref.size ());
|
BOOST_TEST ( str.size () == ref.size ());
|
||||||
BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
|
BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ()));
|
||||||
BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
|
BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void null_tests ( const char *p ) {
|
void null_tests ( const char *p ) {
|
||||||
@@ -34,10 +33,10 @@ void null_tests ( const char *p ) {
|
|||||||
string_ref sr4 ( p );
|
string_ref sr4 ( p );
|
||||||
sr4.clear ();
|
sr4.clear ();
|
||||||
|
|
||||||
BOOST_CHECK ( sr1 == sr2 );
|
BOOST_TEST ( sr1 == sr2 );
|
||||||
BOOST_CHECK ( sr1 == sr3 );
|
BOOST_TEST ( sr1 == sr3 );
|
||||||
BOOST_CHECK ( sr2 == sr3 );
|
BOOST_TEST ( sr2 == sr3 );
|
||||||
BOOST_CHECK ( sr1 == sr4 );
|
BOOST_TEST ( sr1 == sr4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure that substrings work just like strings
|
// make sure that substrings work just like strings
|
||||||
@@ -94,7 +93,7 @@ const char *test_strings [] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( test_main )
|
int main()
|
||||||
{
|
{
|
||||||
const char **p = &test_strings[0];
|
const char **p = &test_strings[0];
|
||||||
|
|
||||||
@@ -106,4 +105,6 @@ BOOST_AUTO_TEST_CASE( test_main )
|
|||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
|
||||||
#define BOOST_TEST_MAIN
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
typedef boost::string_ref string_ref;
|
typedef boost::string_ref string_ref;
|
||||||
|
|
||||||
@@ -24,27 +23,27 @@ void ends_with ( const char *arg ) {
|
|||||||
const char *p = arg;
|
const char *p = arg;
|
||||||
|
|
||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
BOOST_CHECK ( sr.ends_with ( p ));
|
BOOST_TEST ( sr.ends_with ( p ));
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( !sr2.empty ()) {
|
while ( !sr2.empty ()) {
|
||||||
BOOST_CHECK ( sr.ends_with ( sr2 ));
|
BOOST_TEST ( sr.ends_with ( sr2 ));
|
||||||
sr2.remove_prefix (1);
|
sr2.remove_prefix (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sr2 = arg;
|
sr2 = arg;
|
||||||
while ( !sr2.empty ()) {
|
while ( !sr2.empty ()) {
|
||||||
BOOST_CHECK ( sr.ends_with ( sr2 ));
|
BOOST_TEST ( sr.ends_with ( sr2 ));
|
||||||
sr2.remove_prefix (1);
|
sr2.remove_prefix (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
|
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
|
||||||
sr2 = arg;
|
sr2 = arg;
|
||||||
if ( sz > 0 )
|
if ( sz > 0 )
|
||||||
BOOST_CHECK ( sr2.ends_with ( ch ));
|
BOOST_TEST ( sr2.ends_with ( ch ));
|
||||||
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
|
BOOST_TEST ( !sr2.ends_with ( ++ch ));
|
||||||
BOOST_CHECK ( sr2.ends_with ( string_ref ()));
|
BOOST_TEST ( sr2.ends_with ( string_ref ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void starts_with ( const char *arg ) {
|
void starts_with ( const char *arg ) {
|
||||||
@@ -54,21 +53,21 @@ void starts_with ( const char *arg ) {
|
|||||||
const char *p = arg + std::strlen ( arg ) - 1;
|
const char *p = arg + std::strlen ( arg ) - 1;
|
||||||
while ( p >= arg ) {
|
while ( p >= arg ) {
|
||||||
std::string foo ( arg, p + 1 );
|
std::string foo ( arg, p + 1 );
|
||||||
BOOST_CHECK ( sr.starts_with ( foo ));
|
BOOST_TEST ( sr.starts_with ( foo ));
|
||||||
--p;
|
--p;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( !sr2.empty ()) {
|
while ( !sr2.empty ()) {
|
||||||
BOOST_CHECK ( sr.starts_with ( sr2 ));
|
BOOST_TEST ( sr.starts_with ( sr2 ));
|
||||||
sr2.remove_suffix (1);
|
sr2.remove_suffix (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char ch = *arg;
|
char ch = *arg;
|
||||||
sr2 = arg;
|
sr2 = arg;
|
||||||
if ( sz > 0 )
|
if ( sz > 0 )
|
||||||
BOOST_CHECK ( sr2.starts_with ( ch ));
|
BOOST_TEST ( sr2.starts_with ( ch ));
|
||||||
BOOST_CHECK ( !sr2.starts_with ( ++ch ));
|
BOOST_TEST ( !sr2.starts_with ( ++ch ));
|
||||||
BOOST_CHECK ( sr2.starts_with ( string_ref ()));
|
BOOST_TEST ( sr2.starts_with ( string_ref ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reverse ( const char *arg ) {
|
void reverse ( const char *arg ) {
|
||||||
@@ -78,14 +77,14 @@ void reverse ( const char *arg ) {
|
|||||||
string_ref sr2 ( string1 );
|
string_ref sr2 ( string1 );
|
||||||
std::string string2 ( sr2.rbegin (), sr2.rend ());
|
std::string string2 ( sr2.rbegin (), sr2.rend ());
|
||||||
|
|
||||||
BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
|
BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
|
||||||
BOOST_CHECK ( string2 == arg );
|
BOOST_TEST ( string2 == arg );
|
||||||
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This helper function eliminates signed vs. unsigned warnings
|
// This helper function eliminates signed vs. unsigned warnings
|
||||||
string_ref::size_type ptr_diff ( const char *res, const char *base ) {
|
string_ref::size_type ptr_diff ( const char *res, const char *base ) {
|
||||||
BOOST_CHECK ( res >= base );
|
BOOST_TEST ( res >= base );
|
||||||
return static_cast<string_ref::size_type> ( res - base );
|
return static_cast<string_ref::size_type> ( res - base );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ void find ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
string_ref::size_type pos = sr1.find(*p);
|
string_ref::size_type pos = sr1.find(*p);
|
||||||
BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
|
BOOST_TEST ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +107,7 @@ void find ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
string_ref::size_type pos = sr1.rfind(*p);
|
string_ref::size_type pos = sr1.rfind(*p);
|
||||||
BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
|
BOOST_TEST ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +117,7 @@ void find ( const char *arg ) {
|
|||||||
while ( *p && *(p+1)) {
|
while ( *p && *(p+1)) {
|
||||||
string_ref sr3 ( p, 2 );
|
string_ref sr3 ( p, 2 );
|
||||||
string_ref::size_type pos = sr1.find ( sr3 );
|
string_ref::size_type pos = sr1.find ( sr3 );
|
||||||
BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
|
BOOST_TEST ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +128,9 @@ void find ( const char *arg ) {
|
|||||||
for ( int ch = 1; ch < 256; ++ch ) {
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
string_ref::size_type pos = sr1.find(ch);
|
string_ref::size_type pos = sr1.find(ch);
|
||||||
const char *strp = std::strchr ( arg, ch );
|
const char *strp = std::strchr ( arg, ch );
|
||||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
|
BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
|
||||||
if ( strp != NULL )
|
if ( strp != NULL )
|
||||||
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
@@ -141,9 +140,9 @@ void find ( const char *arg ) {
|
|||||||
for ( int ch = 1; ch < 256; ++ch ) {
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
string_ref::size_type pos = sr1.rfind(ch);
|
string_ref::size_type pos = sr1.rfind(ch);
|
||||||
const char *strp = std::strrchr ( arg, ch );
|
const char *strp = std::strrchr ( arg, ch );
|
||||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
|
BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
|
||||||
if ( strp != NULL )
|
if ( strp != NULL )
|
||||||
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -152,7 +151,7 @@ void find ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
while ( !sr1.empty ()) {
|
while ( !sr1.empty ()) {
|
||||||
string_ref::size_type pos = sr1.find(*p);
|
string_ref::size_type pos = sr1.find(*p);
|
||||||
BOOST_CHECK ( pos == 0 );
|
BOOST_TEST ( pos == 0 );
|
||||||
sr1.remove_prefix (1);
|
sr1.remove_prefix (1);
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@@ -162,7 +161,7 @@ void find ( const char *arg ) {
|
|||||||
p = arg + std::strlen ( arg ) - 1;
|
p = arg + std::strlen ( arg ) - 1;
|
||||||
while ( !sr1.empty ()) {
|
while ( !sr1.empty ()) {
|
||||||
string_ref::size_type pos = sr1.rfind(*p);
|
string_ref::size_type pos = sr1.rfind(*p);
|
||||||
BOOST_CHECK ( pos == sr1.size () - 1 );
|
BOOST_TEST ( pos == sr1.size () - 1 );
|
||||||
sr1.remove_suffix (1);
|
sr1.remove_suffix (1);
|
||||||
--p;
|
--p;
|
||||||
}
|
}
|
||||||
@@ -172,7 +171,7 @@ void find ( const char *arg ) {
|
|||||||
p = arg;
|
p = arg;
|
||||||
while ( !sr1.empty ()) {
|
while ( !sr1.empty ()) {
|
||||||
string_ref::size_type pos = sr1.find_first_of(*p);
|
string_ref::size_type pos = sr1.find_first_of(*p);
|
||||||
BOOST_CHECK ( pos == 0 );
|
BOOST_TEST ( pos == 0 );
|
||||||
sr1.remove_prefix (1);
|
sr1.remove_prefix (1);
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@@ -183,7 +182,7 @@ void find ( const char *arg ) {
|
|||||||
p = arg + std::strlen ( arg ) - 1;
|
p = arg + std::strlen ( arg ) - 1;
|
||||||
while ( !sr1.empty ()) {
|
while ( !sr1.empty ()) {
|
||||||
string_ref::size_type pos = sr1.find_last_of(*p);
|
string_ref::size_type pos = sr1.find_last_of(*p);
|
||||||
BOOST_CHECK ( pos == sr1.size () - 1 );
|
BOOST_TEST ( pos == sr1.size () - 1 );
|
||||||
sr1.remove_suffix (1);
|
sr1.remove_suffix (1);
|
||||||
--p;
|
--p;
|
||||||
}
|
}
|
||||||
@@ -192,8 +191,8 @@ void find ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
sr2 = arg;
|
sr2 = arg;
|
||||||
while ( !sr1.empty() ) {
|
while ( !sr1.empty() ) {
|
||||||
BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
|
BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
|
||||||
BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
|
BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
|
||||||
sr1.remove_prefix ( 1 );
|
sr1.remove_prefix ( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,14 +201,14 @@ void find ( const char *arg ) {
|
|||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
string_ref::size_type pos1 = sr1.find_first_of(*p);
|
string_ref::size_type pos1 = sr1.find_first_of(*p);
|
||||||
string_ref::size_type pos2 = sr1.find_first_not_of(*p);
|
string_ref::size_type pos2 = sr1.find_first_not_of(*p);
|
||||||
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
|
BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
|
||||||
if ( pos2 != string_ref::npos ) {
|
if ( pos2 != string_ref::npos ) {
|
||||||
for ( size_t i = 0 ; i < pos2; ++i )
|
for ( size_t i = 0 ; i < pos2; ++i )
|
||||||
BOOST_CHECK ( sr1[i] == *p );
|
BOOST_TEST ( sr1[i] == *p );
|
||||||
BOOST_CHECK ( sr1 [ pos2 ] != *p );
|
BOOST_TEST ( sr1 [ pos2 ] != *p );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK ( pos2 != pos1 );
|
BOOST_TEST ( pos2 != pos1 );
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,8 +216,8 @@ void find ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
sr2 = arg;
|
sr2 = arg;
|
||||||
while ( !sr1.empty() ) {
|
while ( !sr1.empty() ) {
|
||||||
BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
|
BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
|
||||||
BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
|
BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
|
||||||
sr1.remove_suffix ( 1 );
|
sr1.remove_suffix ( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,15 +226,15 @@ void find ( const char *arg ) {
|
|||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
string_ref::size_type pos1 = sr1.find_last_of(*p);
|
string_ref::size_type pos1 = sr1.find_last_of(*p);
|
||||||
string_ref::size_type pos2 = sr1.find_last_not_of(*p);
|
string_ref::size_type pos2 = sr1.find_last_not_of(*p);
|
||||||
BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
|
BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
|
||||||
BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ());
|
BOOST_TEST ( pos2 == string_ref::npos || pos1 < sr1.size ());
|
||||||
if ( pos2 != string_ref::npos ) {
|
if ( pos2 != string_ref::npos ) {
|
||||||
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
|
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
|
||||||
BOOST_CHECK ( sr1[i] == *p );
|
BOOST_TEST ( sr1[i] == *p );
|
||||||
BOOST_CHECK ( sr1 [ pos2 ] != *p );
|
BOOST_TEST ( sr1 [ pos2 ] != *p );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CHECK ( pos2 != pos1 );
|
BOOST_TEST ( pos2 != pos1 );
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,11 +250,11 @@ void to_string ( const char *arg ) {
|
|||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
// str2 = sr1.to_string<std::allocator<char> > ();
|
// str2 = sr1.to_string<std::allocator<char> > ();
|
||||||
str2 = sr1.to_string ();
|
str2 = sr1.to_string ();
|
||||||
BOOST_CHECK ( str1 == str2 );
|
BOOST_TEST ( str1 == str2 );
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
std::string str3 = static_cast<std::string> ( sr1 );
|
std::string str3 = static_cast<std::string> ( sr1 );
|
||||||
BOOST_CHECK ( str1 == str3 );
|
BOOST_TEST ( str1 == str3 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,28 +265,28 @@ void compare ( const char *arg ) {
|
|||||||
|
|
||||||
str1.assign ( arg );
|
str1.assign ( arg );
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref
|
BOOST_TEST ( sr1 == sr1); // compare string_ref and string_ref
|
||||||
BOOST_CHECK ( sr1 == str1); // compare string and string_ref
|
BOOST_TEST ( sr1 == str1); // compare string and string_ref
|
||||||
BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string
|
BOOST_TEST ( str1 == sr1 ); // compare string_ref and string
|
||||||
BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer
|
BOOST_TEST ( sr1 == arg ); // compare string_ref and pointer
|
||||||
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref
|
BOOST_TEST ( arg == sr1 ); // compare pointer and string_ref
|
||||||
|
|
||||||
if ( sr1.size () > 0 ) {
|
if ( sr1.size () > 0 ) {
|
||||||
(*str1.rbegin())++;
|
(*str1.rbegin())++;
|
||||||
BOOST_CHECK ( sr1 != str1 );
|
BOOST_TEST ( sr1 != str1 );
|
||||||
BOOST_CHECK ( str1 != sr1 );
|
BOOST_TEST ( str1 != sr1 );
|
||||||
BOOST_CHECK ( sr1 < str1 );
|
BOOST_TEST ( sr1 < str1 );
|
||||||
BOOST_CHECK ( sr1 <= str1 );
|
BOOST_TEST ( sr1 <= str1 );
|
||||||
BOOST_CHECK ( str1 > sr1 );
|
BOOST_TEST ( str1 > sr1 );
|
||||||
BOOST_CHECK ( str1 >= sr1 );
|
BOOST_TEST ( str1 >= sr1 );
|
||||||
|
|
||||||
(*str1.rbegin()) -= 2;
|
(*str1.rbegin()) -= 2;
|
||||||
BOOST_CHECK ( sr1 != str1 );
|
BOOST_TEST ( sr1 != str1 );
|
||||||
BOOST_CHECK ( str1 != sr1 );
|
BOOST_TEST ( str1 != sr1 );
|
||||||
BOOST_CHECK ( sr1 > str1 );
|
BOOST_TEST ( sr1 > str1 );
|
||||||
BOOST_CHECK ( sr1 >= str1 );
|
BOOST_TEST ( sr1 >= str1 );
|
||||||
BOOST_CHECK ( str1 < sr1 );
|
BOOST_TEST ( str1 < sr1 );
|
||||||
BOOST_CHECK ( str1 <= sr1 );
|
BOOST_TEST ( str1 <= sr1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +300,7 @@ const char *test_strings [] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( test_main )
|
int main()
|
||||||
{
|
{
|
||||||
const char **p = &test_strings[0];
|
const char **p = &test_strings[0];
|
||||||
|
|
||||||
@@ -315,4 +314,6 @@ BOOST_AUTO_TEST_CASE( test_main )
|
|||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@@ -12,8 +12,6 @@
|
|||||||
* \brief This header contains tests for stream operations of \c basic_string_ref.
|
* \brief This header contains tests for stream operations of \c basic_string_ref.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE string_ref_test_io
|
|
||||||
|
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@@ -23,23 +21,10 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/mpl/vector.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
typedef boost::mpl::vector<
|
|
||||||
char
|
|
||||||
#if !defined(BOOST_NO_STD_WSTRING) && !defined(BOOST_NO_STD_WSTREAMBUF) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
|
|
||||||
, wchar_t
|
|
||||||
#endif
|
|
||||||
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
|
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
|
||||||
, char16_t
|
|
||||||
#endif
|
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
|
||||||
, char32_t
|
|
||||||
#endif
|
|
||||||
*/
|
*/
|
||||||
>::type char_types;
|
|
||||||
|
|
||||||
static const char* test_strings[] =
|
static const char* test_strings[] =
|
||||||
{
|
{
|
||||||
@@ -72,10 +57,10 @@ struct context
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Test regular output
|
// Test regular output
|
||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
template<class CharT>
|
||||||
|
void test_string_ref_output()
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -83,14 +68,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
|||||||
|
|
||||||
ostream_type strm;
|
ostream_type strm;
|
||||||
strm << string_ref_type(ctx.abcd);
|
strm << string_ref_type(ctx.abcd);
|
||||||
BOOST_CHECK(strm.str() == ctx.abcd);
|
BOOST_TEST(strm.str() == ctx.abcd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test support for padding
|
// Test support for padding
|
||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
template<class CharT>
|
||||||
|
void test_padding()
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -104,7 +89,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for long padding
|
// Test for long padding
|
||||||
@@ -115,7 +100,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that short width does not truncate the string
|
// Test that short width does not truncate the string
|
||||||
@@ -126,15 +111,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test support for padding fill
|
// Test support for padding fill
|
||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
template<class CharT>
|
||||||
|
void test_padding_fill()
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -146,14 +131,14 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test support for alignment
|
// Test support for alignment
|
||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
template<class CharT>
|
||||||
|
void test_alignment()
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -167,7 +152,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right alignment
|
// Right alignment
|
||||||
@@ -178,6 +163,22 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
|||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class CharT>
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
test_string_ref_output<CharT>();
|
||||||
|
test_padding<CharT>();
|
||||||
|
test_padding_fill<CharT>();
|
||||||
|
test_alignment<CharT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test<char>();
|
||||||
|
test<wchar_t>();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
114
test/string_view_constexpr_test1.cpp
Normal file
114
test/string_view_constexpr_test1.cpp
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2017-2017.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <new> // for placement new
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
|
||||||
|
#include <cstring> // for std::strchr and std::strcmp
|
||||||
|
#include <cstdlib> // for std::malloc and std::free
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
|
|
||||||
|
#if __cplusplus >= 201402L
|
||||||
|
struct constexpr_char_traits
|
||||||
|
{
|
||||||
|
typedef char char_type;
|
||||||
|
typedef int int_type;
|
||||||
|
typedef std::streamoff off_type;
|
||||||
|
typedef std::streampos pos_type;
|
||||||
|
typedef std::mbstate_t state_type;
|
||||||
|
|
||||||
|
static void assign(char_type& c1, const char_type& c2) noexcept { c1 = c2; }
|
||||||
|
static constexpr bool eq(char_type c1, char_type c2) noexcept { return c1 == c2; }
|
||||||
|
static constexpr bool lt(char_type c1, char_type c2) noexcept { return c1 < c2; }
|
||||||
|
|
||||||
|
static constexpr int compare(const char_type* s1, const char_type* s2, size_t n) noexcept;
|
||||||
|
static constexpr size_t length(const char_type* s) noexcept;
|
||||||
|
static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept;
|
||||||
|
static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n) noexcept;
|
||||||
|
static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n) noexcept;
|
||||||
|
static constexpr char_type* assign(char_type* s, size_t n, char_type a) noexcept;
|
||||||
|
|
||||||
|
static constexpr int_type not_eof(int_type c) noexcept { return eq_int_type(c, eof()) ? ~eof() : c; }
|
||||||
|
static constexpr char_type to_char_type(int_type c) noexcept { return char_type(c); }
|
||||||
|
static constexpr int_type to_int_type(char_type c) noexcept { return int_type(c); }
|
||||||
|
static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept { return c1 == c2; }
|
||||||
|
static constexpr int_type eof() noexcept { return EOF; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// yields:
|
||||||
|
// 0 if for each i in [0,n), X::eq(s1[i],s2[i]) is true;
|
||||||
|
// else, a negative value if, for some j in [0,n), X::lt(s1[j],s2[j]) is true and
|
||||||
|
// for each i in [0,j) X::eq(s2[i],s2[i]) is true;
|
||||||
|
// else a positive value.
|
||||||
|
constexpr int constexpr_char_traits::compare(const char_type* s1, const char_type* s2, size_t n) noexcept
|
||||||
|
{
|
||||||
|
for (; n != 0; --n, ++s1, ++s2)
|
||||||
|
{
|
||||||
|
if (lt(*s1, *s2))
|
||||||
|
return -1;
|
||||||
|
if (lt(*s2, *s1))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// yields: the smallest i such that X::eq(s[i],charT()) is true.
|
||||||
|
constexpr size_t constexpr_char_traits::length(const char_type* s) noexcept
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
for (; !eq(*s, char_type(0)); ++s)
|
||||||
|
++len;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef boost::basic_string_view<char, constexpr_char_traits> string_view;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
constexpr string_view sv1;
|
||||||
|
constexpr string_view sv2{"abc", 3}; // ptr, len
|
||||||
|
constexpr string_view sv3{"def"}; // ptr
|
||||||
|
|
||||||
|
constexpr const char *s1 = "";
|
||||||
|
constexpr const char *s2 = "abc";
|
||||||
|
|
||||||
|
static_assert( (sv1 == sv1), "" );
|
||||||
|
|
||||||
|
static_assert(!(sv1 == sv2), "" );
|
||||||
|
static_assert( (sv1 != sv2), "" );
|
||||||
|
static_assert( (sv1 < sv2), "" );
|
||||||
|
static_assert( (sv1 <= sv2), "" );
|
||||||
|
static_assert(!(sv1 > sv2), "" );
|
||||||
|
static_assert(!(sv1 >= sv2), "" );
|
||||||
|
|
||||||
|
static_assert(!(s1 == sv2), "" );
|
||||||
|
static_assert( (s1 != sv2), "" );
|
||||||
|
static_assert( (s1 < sv2), "" );
|
||||||
|
static_assert( (s1 <= sv2), "" );
|
||||||
|
static_assert(!(s1 > sv2), "" );
|
||||||
|
static_assert(!(s1 >= sv2), "" );
|
||||||
|
|
||||||
|
static_assert(!(sv1 == s2), "" );
|
||||||
|
static_assert( (sv1 != s2), "" );
|
||||||
|
static_assert( (sv1 < s2), "" );
|
||||||
|
static_assert( (sv1 <= s2), "" );
|
||||||
|
static_assert(!(sv1 > s2), "" );
|
||||||
|
static_assert(!(sv1 >= s2), "" );
|
||||||
|
|
||||||
|
static_assert( sv1.compare(sv2) < 0, "" );
|
||||||
|
static_assert( sv1.compare(sv1) == 0, "" );
|
||||||
|
static_assert( sv3.compare(sv1) > 0, "" );
|
||||||
|
|
||||||
|
static_assert( sv1.compare(s2) < 0, "" );
|
||||||
|
static_assert( sv1.compare(s1) == 0, "" );
|
||||||
|
static_assert( sv3.compare(s1) > 0, "" );
|
||||||
|
}
|
||||||
|
#endif
|
26
test/string_view_from_rvalue.cpp
Normal file
26
test/string_view_from_rvalue.cpp
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2017.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||||
|
#error "Unsupported test"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string makeatemp() { return "abc"; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
boost::basic_string_view<char> sv(makeatemp());
|
||||||
|
return 0;
|
||||||
|
}
|
110
test/string_view_test1.cpp
Normal file
110
test/string_view_test1.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2012-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
|
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
typedef boost::string_view string_view;
|
||||||
|
|
||||||
|
// Should be equal
|
||||||
|
void interop ( const std::string &str, string_view ref ) {
|
||||||
|
// BOOST_TEST ( str == ref );
|
||||||
|
BOOST_TEST ( str.size () == ref.size ());
|
||||||
|
BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ()));
|
||||||
|
BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void null_tests ( const char *p ) {
|
||||||
|
// All zero-length string-refs should be equal
|
||||||
|
string_view sr1; // NULL, 0
|
||||||
|
string_view sr2 ( NULL, 0 );
|
||||||
|
string_view sr3 ( p, 0 );
|
||||||
|
string_view sr4 ( p );
|
||||||
|
sr4.clear ();
|
||||||
|
|
||||||
|
BOOST_TEST ( sr1 == sr2 );
|
||||||
|
BOOST_TEST ( sr1 == sr3 );
|
||||||
|
BOOST_TEST ( sr2 == sr3 );
|
||||||
|
BOOST_TEST ( sr1 == sr4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that substrings work just like strings
|
||||||
|
void test_substr ( const std::string &str ) {
|
||||||
|
const size_t sz = str.size ();
|
||||||
|
string_view ref ( str );
|
||||||
|
|
||||||
|
// Substrings at the end
|
||||||
|
for ( size_t i = 0; i <= sz; ++ i )
|
||||||
|
interop ( str.substr ( i ), ref.substr ( i ));
|
||||||
|
|
||||||
|
// Substrings at the beginning
|
||||||
|
for ( size_t i = 0; i <= sz; ++ i )
|
||||||
|
interop ( str.substr ( 0, i ), ref.substr ( 0, i ));
|
||||||
|
|
||||||
|
// All possible substrings
|
||||||
|
for ( size_t i = 0; i < sz; ++i )
|
||||||
|
for ( size_t j = i; j < sz; ++j )
|
||||||
|
interop ( str.substr ( i, j ), ref.substr ( i, j ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that removing prefixes and suffixes work just like strings
|
||||||
|
void test_remove ( const std::string &str ) {
|
||||||
|
const size_t sz = str.size ();
|
||||||
|
std::string work;
|
||||||
|
string_view ref;
|
||||||
|
|
||||||
|
for ( size_t i = 1; i <= sz; ++i ) {
|
||||||
|
work = str;
|
||||||
|
ref = str;
|
||||||
|
while ( ref.size () >= i ) {
|
||||||
|
interop ( work, ref );
|
||||||
|
work.erase ( 0, i );
|
||||||
|
ref.remove_prefix (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( size_t i = 1; i < sz; ++ i ) {
|
||||||
|
work = str;
|
||||||
|
ref = str;
|
||||||
|
while ( ref.size () >= i ) {
|
||||||
|
interop ( work, ref );
|
||||||
|
work.erase ( work.size () - i, i );
|
||||||
|
ref.remove_suffix (i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *test_strings [] = {
|
||||||
|
"",
|
||||||
|
"1",
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||||
|
"0123456789",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const char **p = &test_strings[0];
|
||||||
|
|
||||||
|
while ( *p != NULL ) {
|
||||||
|
interop ( *p, *p );
|
||||||
|
test_substr ( *p );
|
||||||
|
test_remove ( *p );
|
||||||
|
null_tests ( *p );
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
406
test/string_view_test2.cpp
Normal file
406
test/string_view_test2.cpp
Normal file
@@ -0,0 +1,406 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) Marshall Clow 2012-2012.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
For more information, see http://www.boost.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <new> // for placement new
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
|
||||||
|
#include <cstring> // for std::strchr and std::strcmp
|
||||||
|
#include <cstdlib> // for std::malloc and std::free
|
||||||
|
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
typedef boost::string_view string_view;
|
||||||
|
|
||||||
|
void ends_with ( const char *arg ) {
|
||||||
|
const size_t sz = std::strlen ( arg );
|
||||||
|
string_view sr ( arg );
|
||||||
|
string_view sr2 ( arg );
|
||||||
|
const char *p = arg;
|
||||||
|
|
||||||
|
while ( *p ) {
|
||||||
|
BOOST_TEST ( sr.ends_with ( p ));
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( !sr2.empty ()) {
|
||||||
|
BOOST_TEST ( sr.ends_with ( sr2 ));
|
||||||
|
sr2.remove_prefix (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sr2 = arg;
|
||||||
|
while ( !sr2.empty ()) {
|
||||||
|
BOOST_TEST ( sr.ends_with ( sr2 ));
|
||||||
|
sr2.remove_prefix (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
|
||||||
|
sr2 = arg;
|
||||||
|
if ( sz > 0 )
|
||||||
|
BOOST_TEST ( sr2.ends_with ( ch ));
|
||||||
|
BOOST_TEST ( !sr2.ends_with ( ++ch ));
|
||||||
|
BOOST_TEST ( sr2.ends_with ( string_view()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void starts_with ( const char *arg ) {
|
||||||
|
const size_t sz = std::strlen ( arg );
|
||||||
|
string_view sr ( arg );
|
||||||
|
string_view sr2 ( arg );
|
||||||
|
const char *p = arg + std::strlen ( arg ) - 1;
|
||||||
|
while ( p >= arg ) {
|
||||||
|
std::string foo ( arg, p + 1 );
|
||||||
|
BOOST_TEST ( sr.starts_with ( foo ));
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( !sr2.empty ()) {
|
||||||
|
BOOST_TEST ( sr.starts_with ( sr2 ));
|
||||||
|
sr2.remove_suffix (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char ch = *arg;
|
||||||
|
sr2 = arg;
|
||||||
|
if ( sz > 0 )
|
||||||
|
BOOST_TEST ( sr2.starts_with ( ch ));
|
||||||
|
BOOST_TEST ( !sr2.starts_with ( ++ch ));
|
||||||
|
BOOST_TEST ( sr2.starts_with ( string_view ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void reverse ( const char *arg ) {
|
||||||
|
// Round trip
|
||||||
|
string_view sr1 ( arg );
|
||||||
|
std::string string1 ( sr1.rbegin (), sr1.rend ());
|
||||||
|
string_view sr2 ( string1 );
|
||||||
|
std::string string2 ( sr2.rbegin (), sr2.rend ());
|
||||||
|
|
||||||
|
BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
|
||||||
|
BOOST_TEST ( string2 == arg );
|
||||||
|
BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This helper function eliminates signed vs. unsigned warnings
|
||||||
|
string_view::size_type ptr_diff ( const char *res, const char *base ) {
|
||||||
|
BOOST_TEST ( res >= base );
|
||||||
|
return static_cast<string_view::size_type> ( res - base );
|
||||||
|
}
|
||||||
|
|
||||||
|
void find ( const char *arg ) {
|
||||||
|
string_view sr1;
|
||||||
|
string_view sr2;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
// Look for each character in the string(searching from the start)
|
||||||
|
p = arg;
|
||||||
|
sr1 = arg;
|
||||||
|
while ( *p ) {
|
||||||
|
string_view::size_type pos = sr1.find(*p);
|
||||||
|
BOOST_TEST ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg )));
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for each character in the string (searching from the end)
|
||||||
|
p = arg;
|
||||||
|
sr1 = arg;
|
||||||
|
while ( *p ) {
|
||||||
|
string_view::size_type pos = sr1.rfind(*p);
|
||||||
|
BOOST_TEST ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for pairs on characters (searching from the start)
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg;
|
||||||
|
while ( *p && *(p+1)) {
|
||||||
|
string_view sr3 ( p, 2 );
|
||||||
|
string_view::size_type pos = sr1.find ( sr3 );
|
||||||
|
BOOST_TEST ( pos != string_view::npos && pos <= static_cast<string_view::size_type>( p - arg ));
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg;
|
||||||
|
// for all possible chars, see if we find them in the right place.
|
||||||
|
// Note that strchr will/might do the _wrong_ thing if we search for NULL
|
||||||
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
|
string_view::size_type pos = sr1.find(ch);
|
||||||
|
const char *strp = std::strchr ( arg, ch );
|
||||||
|
BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
|
||||||
|
if ( strp != NULL )
|
||||||
|
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg;
|
||||||
|
// for all possible chars, see if we find them in the right place.
|
||||||
|
// Note that strchr will/might do the _wrong_ thing if we search for NULL
|
||||||
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
|
string_view::size_type pos = sr1.rfind(ch);
|
||||||
|
const char *strp = std::strrchr ( arg, ch );
|
||||||
|
BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
|
||||||
|
if ( strp != NULL )
|
||||||
|
BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find everything at the start
|
||||||
|
p = arg;
|
||||||
|
sr1 = arg;
|
||||||
|
while ( !sr1.empty ()) {
|
||||||
|
string_view::size_type pos = sr1.find(*p);
|
||||||
|
BOOST_TEST ( pos == 0 );
|
||||||
|
sr1.remove_prefix (1);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find everything at the end
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg + std::strlen ( arg ) - 1;
|
||||||
|
while ( !sr1.empty ()) {
|
||||||
|
string_view::size_type pos = sr1.rfind(*p);
|
||||||
|
BOOST_TEST ( pos == sr1.size () - 1 );
|
||||||
|
sr1.remove_suffix (1);
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find everything at the start
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg;
|
||||||
|
while ( !sr1.empty ()) {
|
||||||
|
string_view::size_type pos = sr1.find_first_of(*p);
|
||||||
|
BOOST_TEST ( pos == 0 );
|
||||||
|
sr1.remove_prefix (1);
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find everything at the end
|
||||||
|
sr1 = arg;
|
||||||
|
p = arg + std::strlen ( arg ) - 1;
|
||||||
|
while ( !sr1.empty ()) {
|
||||||
|
string_view::size_type pos = sr1.find_last_of(*p);
|
||||||
|
BOOST_TEST ( pos == sr1.size () - 1 );
|
||||||
|
sr1.remove_suffix (1);
|
||||||
|
--p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic sanity checking for "find_first_of / find_first_not_of"
|
||||||
|
sr1 = arg;
|
||||||
|
sr2 = arg;
|
||||||
|
while ( !sr1.empty() ) {
|
||||||
|
BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
|
||||||
|
BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_view::npos );
|
||||||
|
sr1.remove_prefix ( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
p = arg;
|
||||||
|
sr1 = arg;
|
||||||
|
while ( *p ) {
|
||||||
|
string_view::size_type pos1 = sr1.find_first_of(*p);
|
||||||
|
string_view::size_type pos2 = sr1.find_first_not_of(*p);
|
||||||
|
BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
|
||||||
|
if ( pos2 != string_view::npos ) {
|
||||||
|
for ( size_t i = 0 ; i < pos2; ++i )
|
||||||
|
BOOST_TEST ( sr1[i] == *p );
|
||||||
|
BOOST_TEST ( sr1 [ pos2 ] != *p );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST ( pos2 != pos1 );
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic sanity checking for "find_last_of / find_last_not_of"
|
||||||
|
sr1 = arg;
|
||||||
|
sr2 = arg;
|
||||||
|
while ( !sr1.empty() ) {
|
||||||
|
BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
|
||||||
|
BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_view::npos );
|
||||||
|
sr1.remove_suffix ( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
p = arg;
|
||||||
|
sr1 = arg;
|
||||||
|
while ( *p ) {
|
||||||
|
string_view::size_type pos1 = sr1.find_last_of(*p);
|
||||||
|
string_view::size_type pos2 = sr1.find_last_not_of(*p);
|
||||||
|
BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
|
||||||
|
BOOST_TEST ( pos2 == string_view::npos || pos1 < sr1.size ());
|
||||||
|
if ( pos2 != string_view::npos ) {
|
||||||
|
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
|
||||||
|
BOOST_TEST ( sr1[i] == *p );
|
||||||
|
BOOST_TEST ( sr1 [ pos2 ] != *p );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_TEST ( pos2 != pos1 );
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class custom_allocator {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef void* void_pointer;
|
||||||
|
typedef const void* const_void_pointer;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef custom_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
custom_allocator() BOOST_NOEXCEPT {}
|
||||||
|
template <typename U>
|
||||||
|
custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
|
||||||
|
|
||||||
|
pointer allocate(size_type n) const {
|
||||||
|
return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
|
||||||
|
}
|
||||||
|
void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
|
||||||
|
std::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer address(reference value) const BOOST_NOEXCEPT {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer address(const_reference value) const BOOST_NOEXCEPT {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
|
||||||
|
return (~(size_type)0u) / sizeof(value_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template <class U, class... Args>
|
||||||
|
void construct(U* ptr, Args&&... args) const {
|
||||||
|
::new((void*)ptr) U(static_cast<Args&&>(args)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class U, class V>
|
||||||
|
void construct(U* ptr, V&& value) const {
|
||||||
|
::new((void*)ptr) U(static_cast<V&&>(value));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template <class U, class V>
|
||||||
|
void construct(U* ptr, const V& value) const {
|
||||||
|
::new((void*)ptr) U(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
void construct(U* ptr) const {
|
||||||
|
::new((void*)ptr) U();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
void destroy(U* ptr) const {
|
||||||
|
(void)ptr;
|
||||||
|
ptr->~U();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template <typename T, typename U>
|
||||||
|
BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void to_string ( const char *arg ) {
|
||||||
|
string_view sr1;
|
||||||
|
std::string str1;
|
||||||
|
std::string str2;
|
||||||
|
|
||||||
|
str1.assign ( arg );
|
||||||
|
sr1 = arg;
|
||||||
|
// str2 = sr1.to_string<std::allocator<char> > ();
|
||||||
|
str2 = sr1.to_string ();
|
||||||
|
BOOST_TEST ( str1 == str2 );
|
||||||
|
|
||||||
|
std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
|
||||||
|
BOOST_TEST ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
|
std::string str4 = static_cast<std::string> ( sr1 );
|
||||||
|
BOOST_TEST ( str1 == str4 );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void compare ( const char *arg ) {
|
||||||
|
string_view sr1;
|
||||||
|
std::string str1;
|
||||||
|
std::string str2 = str1;
|
||||||
|
|
||||||
|
str1.assign ( arg );
|
||||||
|
sr1 = arg;
|
||||||
|
BOOST_TEST ( sr1 == sr1); // compare string_view and string_view
|
||||||
|
BOOST_TEST ( sr1 == str1); // compare string and string_view
|
||||||
|
BOOST_TEST ( str1 == sr1 ); // compare string_view and string
|
||||||
|
BOOST_TEST ( sr1 == arg ); // compare string_view and pointer
|
||||||
|
BOOST_TEST ( arg == sr1 ); // compare pointer and string_view
|
||||||
|
|
||||||
|
if ( sr1.size () > 0 ) {
|
||||||
|
(*str1.rbegin())++;
|
||||||
|
BOOST_TEST ( sr1 != str1 );
|
||||||
|
BOOST_TEST ( str1 != sr1 );
|
||||||
|
BOOST_TEST ( sr1 < str1 );
|
||||||
|
BOOST_TEST ( sr1 <= str1 );
|
||||||
|
BOOST_TEST ( str1 > sr1 );
|
||||||
|
BOOST_TEST ( str1 >= sr1 );
|
||||||
|
|
||||||
|
(*str1.rbegin()) -= 2;
|
||||||
|
BOOST_TEST ( sr1 != str1 );
|
||||||
|
BOOST_TEST ( str1 != sr1 );
|
||||||
|
BOOST_TEST ( sr1 > str1 );
|
||||||
|
BOOST_TEST ( sr1 >= str1 );
|
||||||
|
BOOST_TEST ( str1 < sr1 );
|
||||||
|
BOOST_TEST ( str1 <= sr1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *test_strings [] = {
|
||||||
|
"",
|
||||||
|
"0",
|
||||||
|
"abc",
|
||||||
|
"AAA", // all the same
|
||||||
|
"adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
|
||||||
|
"abc\0asdfadsfasf",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const char **p = &test_strings[0];
|
||||||
|
|
||||||
|
while ( *p != NULL ) {
|
||||||
|
starts_with ( *p );
|
||||||
|
ends_with ( *p );
|
||||||
|
reverse ( *p );
|
||||||
|
find ( *p );
|
||||||
|
to_string ( *p );
|
||||||
|
compare ( *p );
|
||||||
|
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
184
test/string_view_test_io.cpp
Normal file
184
test/string_view_test_io.cpp
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Andrey Semashev 2013.
|
||||||
|
* Distributed under the Boost Software License, Version 1.0.
|
||||||
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* \file string_ref_test_io.cpp
|
||||||
|
* \author Andrey Semashev
|
||||||
|
* \date 26.05.2013
|
||||||
|
*
|
||||||
|
* \brief This header contains tests for stream operations of \c basic_string_ref.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/utility/string_view.hpp>
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
|
/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char* test_strings[] =
|
||||||
|
{
|
||||||
|
"begin",
|
||||||
|
"abcd",
|
||||||
|
"end"
|
||||||
|
};
|
||||||
|
|
||||||
|
//! The context with test data for particular character type
|
||||||
|
template< typename CharT >
|
||||||
|
struct context
|
||||||
|
{
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_string< char_type > string_type;
|
||||||
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
|
|
||||||
|
string_type begin, abcd, end;
|
||||||
|
|
||||||
|
context()
|
||||||
|
{
|
||||||
|
boost::string_view str = test_strings[0];
|
||||||
|
std::copy(str.begin(), str.end(), std::back_inserter(begin));
|
||||||
|
|
||||||
|
str = test_strings[1];
|
||||||
|
std::copy(str.begin(), str.end(), std::back_inserter(abcd));
|
||||||
|
|
||||||
|
str = test_strings[2];
|
||||||
|
std::copy(str.begin(), str.end(), std::back_inserter(end));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test regular output
|
||||||
|
template<class CharT>
|
||||||
|
void test_string_view_output()
|
||||||
|
{
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
|
context< char_type > ctx;
|
||||||
|
|
||||||
|
ostream_type strm;
|
||||||
|
strm << string_view_type(ctx.abcd);
|
||||||
|
BOOST_TEST(strm.str() == ctx.abcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test support for padding
|
||||||
|
template<class CharT>
|
||||||
|
void test_padding()
|
||||||
|
{
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
|
context< char_type > ctx;
|
||||||
|
|
||||||
|
// Test for padding
|
||||||
|
{
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for long padding
|
||||||
|
{
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that short width does not truncate the string
|
||||||
|
{
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test support for padding fill
|
||||||
|
template<class CharT>
|
||||||
|
void test_padding_fill()
|
||||||
|
{
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
|
context< char_type > ctx;
|
||||||
|
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test support for alignment
|
||||||
|
template<class CharT>
|
||||||
|
void test_alignment()
|
||||||
|
{
|
||||||
|
typedef CharT char_type;
|
||||||
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
|
context< char_type > ctx;
|
||||||
|
|
||||||
|
// Left alignment
|
||||||
|
{
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right alignment
|
||||||
|
{
|
||||||
|
ostream_type strm_ref;
|
||||||
|
strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
|
ostream_type strm_correct;
|
||||||
|
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
|
BOOST_TEST(strm_ref.str() == strm_correct.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class CharT>
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
test_string_view_output<CharT>();
|
||||||
|
test_padding<CharT>();
|
||||||
|
test_padding_fill<CharT>();
|
||||||
|
test_alignment<CharT>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test<char>();
|
||||||
|
test<wchar_t>();
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
@@ -16,13 +16,12 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "boost/utility/value_init.hpp"
|
#include "boost/utility/value_init.hpp"
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/detail/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sample POD type
|
// Sample POD type
|
||||||
@@ -271,8 +270,11 @@ bool test ( T const& y, T const& z )
|
|||||||
copy2 = x;
|
copy2 = x;
|
||||||
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
{
|
||||||
|
boost::value_initialized<T> * ptr = new boost::value_initialized<T>;
|
||||||
BOOST_TEST ( y == *ptr ) ;
|
BOOST_TEST ( y == *ptr ) ;
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
boost::value_initialized<T const> cx ;
|
boost::value_initialized<T const> cx ;
|
||||||
@@ -287,7 +289,7 @@ bool test ( T const& y, T const& z )
|
|||||||
return boost::detail::test_errors() == errors_before_test ;
|
return boost::detail::test_errors() == errors_before_test ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int, char **)
|
int main()
|
||||||
{
|
{
|
||||||
BOOST_TEST ( test( 0,1234 ) ) ;
|
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||||
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
@@ -17,9 +17,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boost/test/minimal.hpp"
|
int main()
|
||||||
|
|
||||||
int test_main(int, char **)
|
|
||||||
{
|
{
|
||||||
boost::value_initialized<int> const x_c ;
|
boost::value_initialized<int> const x_c ;
|
||||||
|
|
||||||
@@ -27,11 +25,3 @@ int test_main(int, char **)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -17,9 +17,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boost/test/minimal.hpp"
|
int main()
|
||||||
|
|
||||||
int test_main(int, char **)
|
|
||||||
{
|
{
|
||||||
boost::value_initialized<int const> cx ;
|
boost::value_initialized<int const> cx ;
|
||||||
|
|
||||||
@@ -27,10 +25,3 @@ int test_main(int, char **)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -17,9 +17,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boost/test/minimal.hpp"
|
int main()
|
||||||
|
|
||||||
int test_main(int, char **)
|
|
||||||
{
|
{
|
||||||
boost::value_initialized<int const> const cx_c ;
|
boost::value_initialized<int const> const cx_c ;
|
||||||
|
|
||||||
@@ -27,11 +25,3 @@ int test_main(int, char **)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -75,6 +75,24 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct int_pair_struct
|
||||||
|
{
|
||||||
|
int first;
|
||||||
|
int second;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int int_pair_struct::*ptr_to_member_type;
|
||||||
|
|
||||||
|
struct ptr_to_member_struct
|
||||||
|
{
|
||||||
|
ptr_to_member_type data;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool is_value_initialized(const ptr_to_member_struct& arg)
|
||||||
|
{
|
||||||
|
return arg.data == 0;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool is_value_initialized(const T(& arg)[2])
|
bool is_value_initialized(const T(& arg)[2])
|
||||||
{
|
{
|
||||||
@@ -132,7 +150,8 @@ int main()
|
|||||||
const unsigned num_failures =
|
const unsigned num_failures =
|
||||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
|
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
|
||||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
|
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
|
||||||
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>());
|
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) +
|
||||||
|
FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>());
|
||||||
|
|
||||||
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
|
||||||
// One or more failures are expected.
|
// One or more failures are expected.
|
41
utility.htm
41
utility.htm
@@ -17,7 +17,7 @@
|
|||||||
Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
|
Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
|
||||||
checked_array_delete()</a> (moved to the Boost.Core library)</li>
|
checked_array_delete()</a> (moved to the Boost.Core library)</li>
|
||||||
<li>
|
<li>
|
||||||
Function templates <a href="#functions_next_prior">next() and prior()</a></li>
|
Function templates <a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next() and prior()</a> (moved to the Boost.Iterator library)</li>
|
||||||
<li>
|
<li>
|
||||||
Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
|
Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -28,45 +28,6 @@
|
|||||||
<li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
|
<li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>
|
<h2>
|
||||||
<a name="functions_next_prior">Function</a> templates next() and prior()</h2>
|
|
||||||
<p>Certain data types, such as the C++ Standard Library's forward and bidirectional
|
|
||||||
iterators, do not provide addition and subtraction via operator+() or
|
|
||||||
operator-(). This means that non-modifying computation of the next or
|
|
||||||
prior value requires a temporary, even though operator++() or operator--() is
|
|
||||||
provided. It also means that writing code like <code>itr+1</code> inside
|
|
||||||
a template restricts the iterator category to random access iterators.</p>
|
|
||||||
<p>The next() and prior() functions provide a simple way around these problems:</p>
|
|
||||||
<blockquote>
|
|
||||||
<pre>template <class T>
|
|
||||||
T next(T x) { return ++x; }
|
|
||||||
|
|
||||||
template <class T, class Distance>
|
|
||||||
T next(T x, Distance n)
|
|
||||||
{
|
|
||||||
std::advance(x, n);
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T prior(T x) { return --x; }
|
|
||||||
|
|
||||||
template <class T, class Distance>
|
|
||||||
T prior(T x, Distance n)
|
|
||||||
{
|
|
||||||
std::advance(x, -n);
|
|
||||||
return x;
|
|
||||||
}</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>Usage is simple:</p>
|
|
||||||
<blockquote>
|
|
||||||
<pre>const std::list<T>::iterator p = get_some_iterator();
|
|
||||||
const std::list<T>::iterator prev = boost::prior(p);
|
|
||||||
const std::list<T>::iterator next = boost::next(prev, 2);</pre>
|
|
||||||
</blockquote>
|
|
||||||
<p>The distance from the given iterator should be supplied as an absolute value. For
|
|
||||||
example, the iterator four iterators prior to the given iterator <code>p</code>
|
|
||||||
may be obtained by <code>prior(p, 4)</code>.</p>
|
|
||||||
<p>Contributed by <a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>. Two-argument versions by Daniel Walker.</p>
|
|
||||||
|
|
||||||
<h2><a name="result_of">Class template
|
<h2><a name="result_of">Class template
|
||||||
result_of</a></h2> <p>The class template
|
result_of</a></h2> <p>The class template
|
||||||
|
Reference in New Issue
Block a user