Compare commits

...

22 Commits

Author SHA1 Message Date
Peter Dimov
9d46de1578 Replace use of mpl/has_xxx.hpp with handwritten traits 2017-12-21 06:30:03 +02:00
Peter Dimov
976a4d2fc1 Merge branch 'develop' into feature/result_of-no-mpl 2017-12-20 23:16:08 +02:00
Peter Dimov
ea81279b35 Add appveyor.yml 2017-12-20 23:14:36 +02:00
Peter Dimov
7d101d420c Replace mpl primitives with type_traits 2017-12-20 21:55:07 +02:00
Peter Dimov
d8acfef27b Update includes in utility.hpp; add deprecation comment 2017-12-02 04:35:22 +02:00
Peter Dimov
d7ae336915 Merge branch 'master' into develop 2017-12-02 03:47:03 +02:00
Peter Dimov
b74f49f1e5 Remove dependency on iterator in <boost/utility.hpp> 2017-12-02 03:38:29 +02:00
Daniel Frey
5977f11be8 Merge pull request #36 from boostorg/develop
Protect dereferenceable<> against overloaded operator&, fixes #35
2017-12-01 20:59:24 +01:00
Daniel Frey
ad0fc7c9d3 Protect dereferenceable<> against overloaded operator&, fixes #35 2017-11-23 21:14:07 +01:00
Peter Dimov
a6c175e2c3 clang 3.5 can't handle libstdc++-5 2017-10-28 14:11:41 +03:00
Peter Dimov
874ca2307b Update clangs to libstdc++-5-dev for constexpr std::min 2017-10-28 04:49:50 +03:00
Peter Dimov
5220260145 Update .travis.yml 2017-10-27 15:31:19 +03:00
Daniel Frey
2f5a6fbcf1 Adapt to C++17, fixes #34 2017-10-15 10:34:04 +02:00
Peter Dimov
51ba9f1b45 Add one more case to value_init_workaround_test 2017-09-24 12:47:05 +03:00
Andrey Semashev
5cef1403b0 Merge pull request #33 from morinmorin/fix_no_expr_sfinae
result_of<F&(…)> fails on MSVC-12 if F is a function pointer
2017-09-23 21:59:06 +03:00
morinmorin
81ce4693f6 Add tests for result_of<F&(...)> in C++11. 2017-09-20 23:44:35 +09:00
morinmorin
fb2f110eb4 Fix result_of_is_callable to support references to function pointers.
On compilers without the support of expression SFINAE, decltype-based
result_of<FP&(...)> failed to compile (FP is a function pointer type).
2017-09-20 23:40:56 +09:00
Andrey Semashev
2ed5ee9588 Moved numeric_traits_test.cpp to Boost.Detail. 2017-09-20 01:42:15 +03:00
Andrey Semashev
88c36c1941 Remove generator iterator test and docs as these were moved to Boost.Iterator. 2017-08-28 20:41:11 +03:00
Andrey Semashev
0b2409a942 Updated links to next/prior docs. 2017-08-26 20:07:12 +03:00
Andrey Semashev
62b39548be Moved next/prior to Boost.Iterator. 2017-08-26 17:25:14 +03:00
Andrey Semashev
2722fdcda3 Use std::iterator_traits to detect iterators, when possible.
This allows next/prior to detect user's iterators that do not
define iterator_category nested type but specialize
std::iterator_traits instead.
2017-07-23 20:29:25 +03:00
17 changed files with 205 additions and 1257 deletions

View File

@@ -8,14 +8,11 @@ sudo: false
python: "2.7"
os:
- linux
- osx
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
@@ -28,10 +25,12 @@ matrix:
include:
- os: linux
env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03
compiler: g++
env: TOOLSET=gcc COMPILER=g++ CXXSTD=03,11
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++03
compiler: g++-4.7
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
@@ -40,34 +39,17 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++03
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
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++03
compiler: g++-4.9
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
@@ -76,16 +58,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++03
compiler: g++-5
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14,1z
addons:
apt:
packages:
@@ -94,61 +68,8 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++1z
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z
compiler: g++-6
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
@@ -158,7 +79,8 @@ matrix:
- os: linux
dist: trusty
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++03
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
@@ -167,43 +89,12 @@ matrix:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++11
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
- os: linux
dist: trusty
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++14
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++1z
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
- os: linux
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++03
compiler: clang++-3.5
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
@@ -213,97 +104,44 @@ matrix:
- llvm-toolchain-precise-3.5
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++03
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
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++03
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
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++03
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
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11
addons:
apt:
packages:
- clang-3.8
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++03
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11
addons:
apt:
packages:
- clang-3.9
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14
compiler: clang++-3.9
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
@@ -314,73 +152,37 @@ matrix:
- llvm-toolchain-precise-3.9
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- clang-4.0
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++03
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++11
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
- clang-5.0
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++14
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++1z
addons:
apt:
packages:
- clang-4.0
- libstdc++-6-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- llvm-toolchain-trusty-5.0
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- 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/config
@@ -392,8 +194,8 @@ install:
script:
- |-
echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam
- ./b2 libs/utility/test toolset=$TOOLSET
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 libs/utility/test toolset=$TOOLSET cxxstd=$CXXSTD
notifications:
email:

44
appveyor.yml Normal file
View File

@@ -0,0 +1,44 @@
# 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/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\utility
- python tools/boostdep/depinst/depinst.py utility
- cmd /c bootstrap
- b2 headers
build: off
test_script:
- PATH=%ADDPATH%%PATH%
- if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD%
- b2 -j3 libs/utility/test toolset=%TOOLSET% %CXXSTD%

View File

@@ -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 &lt;class Generator&gt;
class generator_iterator_policies;
template &lt;class Generator&gt;
class generator_iterator_generator;
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; 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 &lt;class Generator&gt;
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 &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; 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 &lt;iostream&gt;
#include &lt;boost/generator_iterator.hpp&gt;
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&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; 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 &copy; 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>

View File

@@ -1,180 +0,0 @@
// Boost next_prior.hpp header file ---------------------------------------//
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003.
// Copyright (c) Andrey Semashev 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)
// 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>
#include <boost/config.hpp>
#include <boost/core/enable_if.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>
#include <boost/iterator/advance.hpp>
#include <boost/iterator/reverse_iterator.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 {
// The trait attempts to detect if the T type is an iterator. Class-type iterators are assumed
// to have the nested type iterator_category. Strictly speaking, this is not required to be the
// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
// Still, this is a good heuristic in practice, and we can't do anything better anyway.
// Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
// required to be only present for iterators.
template< typename T, typename Void = void >
struct is_iterator
{
static BOOST_CONSTEXPR_OR_CONST bool value = false;
};
template< typename T >
struct is_iterator< T, typename enable_if_has_type< typename T::iterator_category >::type >
{
static BOOST_CONSTEXPR_OR_CONST bool value = true;
};
template< typename T >
struct is_iterator< T*, void >
{
static BOOST_CONSTEXPR_OR_CONST bool value = true;
};
template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
struct next_plus_impl;
template< typename T, typename Distance >
struct next_plus_impl< 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_plus_assign_impl :
public next_plus_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct next_plus_assign_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
x += n;
return x;
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
struct next_advance_impl :
public next_plus_assign_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct next_advance_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
boost::iterators::advance(x, n);
return x;
}
};
template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
struct prior_minus_impl;
template< typename T, typename Distance >
struct prior_minus_impl< 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_minus_assign_impl :
public prior_minus_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_minus_assign_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
x -= n;
return x;
}
};
template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value >
struct prior_advance_impl :
public prior_minus_assign_impl< T, Distance >
{
};
template< typename T, typename Distance >
struct prior_advance_impl< T, Distance, true >
{
static T call(T x, Distance n)
{
// Avoid negating n to sidestep possible integer overflow
boost::iterators::reverse_iterator< T > rx(x);
boost::iterators::advance(rx, n);
return rx.base();
}
};
} // 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_advance_impl< 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_advance_impl< T, Distance >::call(x, n);
}
} // namespace boost
#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED

View File

@@ -1,7 +1,7 @@
// Boost operators.hpp header file ----------------------------------------//
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
// (C) Copyright Daniel Frey 2002-2016.
// (C) Copyright Daniel Frey 2002-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)
@@ -9,6 +9,9 @@
// See http://www.boost.org/libs/utility/operators.htm for documentation.
// 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++
@@ -96,6 +99,7 @@
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/core/addressof.hpp>
#if defined(__sgi) && !defined(__GNUC__)
# pragma set woff 1234
@@ -300,7 +304,7 @@ struct dereferenceable : B
{
P operator->() const
{
return &*static_cast<const T&>(*this);
return ::boost::addressof(*static_cast<const T&>(*this));
}
};
@@ -824,6 +828,21 @@ template <class T> struct operators<T, 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) ------------//
// (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,
class V,
class D = std::ptrdiff_t,
@@ -831,13 +850,13 @@ template <class T,
class R = V const &>
struct input_iterator_helper
: input_iteratable<T, P
, std::iterator<std::input_iterator_tag, V, D, P, R
, iterator_helper<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
, iterator_helper<std::output_iterator_tag, void, void, void, void
> >
{
T& operator*() { return static_cast<T&>(*this); }
@@ -851,7 +870,7 @@ template <class T,
class R = V&>
struct forward_iterator_helper
: forward_iteratable<T, P
, std::iterator<std::forward_iterator_tag, V, D, P, R
, iterator_helper<std::forward_iterator_tag, V, D, P, R
> > {};
template <class T,
@@ -861,7 +880,7 @@ template <class T,
class R = V&>
struct bidirectional_iterator_helper
: bidirectional_iteratable<T, P
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
, iterator_helper<std::bidirectional_iterator_tag, V, D, P, R
> > {};
template <class T,
@@ -871,7 +890,7 @@ template <class T,
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
, iterator_helper<std::random_access_iterator_tag, V, D, P, R
> >
{
friend D requires_difference_operator(const T& x, const T& y) {

View File

@@ -9,13 +9,16 @@
#ifndef 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/binary.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/identity_type.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/core/checked_delete.hpp>
#include <boost/core/noncopyable.hpp>
#include <boost/next_prior.hpp>
#endif // BOOST_UTILITY_HPP

View File

@@ -25,16 +25,16 @@
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)>
: mpl::if_<
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
: conditional<
is_pointer<F>::value || is_member_function_pointer<F>::value
, boost::detail::tr1_result_of_impl<
typename remove_cv<F>::type,
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<
F,
F(BOOST_RESULT_OF_ARGS),
(boost::detail::has_result_type<F>::value)> >::type { };
(boost::detail::result_of_has_result_type<F>::value)> >::type { };
#endif
#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
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
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)>,
detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> >::type { };
#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)>
struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
: mpl::if_<
is_member_function_pointer<F>
: conditional<
is_member_function_pointer<F>::value
, detail::tr1_result_of_impl<
typename remove_cv<F>::type,
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>
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>
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>
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>
struct BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())
: mpl::eval_if<
is_class<typename remove_reference<F>::type>,
: conditional<
is_class<typename remove_reference<F>::type>::value,
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)>
@@ -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())
))
);
typedef mpl::bool_<value> type;
typedef integral_constant<bool, value> type;
};
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>

View File

@@ -18,19 +18,16 @@
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/facilities/intercept.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_pointer.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/declval.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/declval.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
# 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.
#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_DECLTYPE
# 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)
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.
#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
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);
};
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>
result_of_no_type result_of_is_private_type(T const &);
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>
struct is_function_with_no_args : mpl::false_ {};
struct is_function_with_no_args : false_type {};
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>
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>
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_nested_result<F, FArgs> >::type
{};

View File

@@ -24,8 +24,8 @@
<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="iterator_adaptors.htm">iterator_adaptors</a><br>
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
<a href="utility.htm#functions_next_prior">next/prior</a><br>
<a href="../iterator/doc/generator_iterator.htm">generator iterator adaptors</a> (moved to the Boost.Iterator library)<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="operators.htm">operators</a><br>
<a href="utility.htm#result_of">result_of</a><br>

View File

@@ -1667,8 +1667,8 @@ T operator+( T lhs, const T&amp; rhs )
<td><code>P operator-&gt;() const</code></td>
<td><code>(&amp;*i)</code>. Return convertible to
<code>P</code>.</td>
<td><code>*i</code>. Address of the returned value convertible
to <code>P</code>.</td>
</tr>
<tr>

View File

@@ -24,10 +24,6 @@ run compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>sta
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 ;
@@ -52,5 +48,3 @@ 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 ;

View File

@@ -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();
}

View File

@@ -1,104 +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()));
BOOST_REQUIRE(plus_one_test(x.rbegin(), x.rend(), y.begin()));
BOOST_REQUIRE(plus_n_test(x.rbegin(), x.rend(), y.begin()));
BOOST_REQUIRE(minus_one_test(x.rbegin(), x.rend(), y.end()));
BOOST_REQUIRE(minus_n_test(x.rbegin(), x.rend(), y.end()));
BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), x.size()));
BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), 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;
}

View File

@@ -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;
}

View File

@@ -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<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<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)
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));

View File

@@ -75,6 +75,24 @@ namespace
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>
bool is_value_initialized(const T(& arg)[2])
{
@@ -132,7 +150,8 @@ int main()
const unsigned num_failures =
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<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
// One or more failures are expected.

View File

@@ -17,7 +17,7 @@
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>
<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>
Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
<li>
@@ -28,45 +28,6 @@
<li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
</ul>
<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-().&nbsp; This means that non-modifying computation of the next or
prior value requires a temporary, even though operator++() or operator--() is
provided.&nbsp; 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 &lt;class T&gt;
T next(T x) { return ++x; }
template &lt;class T, class Distance&gt;
T next(T x, Distance n)
{
std::advance(x, n);
return x;
}
template &lt;class T&gt;
T prior(T x) { return --x; }
template &lt;class T, class Distance&gt;
T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
}</pre>
</blockquote>
<p>Usage is simple:</p>
<blockquote>
<pre>const std::list&lt;T&gt;::iterator p = get_some_iterator();
const std::list&lt;T&gt;::iterator prev = boost::prior(p);
const std::list&lt;T&gt;::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
result_of</a></h2> <p>The class template