forked from boostorg/utility
Compare commits
91 Commits
svn-branch
...
boost-1.51
Author | SHA1 | Date | |
---|---|---|---|
|
d1f35eb7d5 | ||
|
fb2d391928 | ||
|
ad5cf8cf08 | ||
|
2fc827ad23 | ||
|
88e7d86270 | ||
|
6b9f0103d5 | ||
|
7aa68731b4 | ||
|
87b3643647 | ||
|
c9d56eed6e | ||
|
e36315c151 | ||
|
1aa48ea698 | ||
|
d01eb82fb7 | ||
|
86791caf0e | ||
|
8176af84e1 | ||
|
b7d4b6edae | ||
|
d7cf3628f7 | ||
|
b273cd3914 | ||
|
ca7db1f361 | ||
|
2a7e81e07f | ||
|
13da21e7b1 | ||
|
b3ffef536d | ||
|
e2c98762db | ||
|
8af4250c3c | ||
|
e30889304c | ||
|
b4dee80e61 | ||
|
a47dce770c | ||
|
dab1e8e522 | ||
|
583422cda2 | ||
|
ee146a02a1 | ||
|
c131cbd0b2 | ||
|
f8bef7ba95 | ||
|
e54cbf3053 | ||
|
d5291d08b8 | ||
|
61755605af | ||
|
cd12e322bd | ||
|
8cb975feb7 | ||
|
ffe151458e | ||
|
4003a9f74a | ||
|
211eb04f33 | ||
|
e57213b298 | ||
|
51f9adbfa1 | ||
|
eaaf17a88f | ||
|
48cfd42123 | ||
|
76aa5d2f27 | ||
|
ce67dde4f0 | ||
|
a69e872a91 | ||
|
e3640e45c2 | ||
|
b7cd171b2b | ||
|
b2e6a82adb | ||
|
390372294a | ||
|
ffbbf38e12 | ||
|
9e73b2c6ae | ||
|
633832e872 | ||
|
862cb2a4e0 | ||
|
b012f16ee5 | ||
|
3d96ab26d4 | ||
|
8652bf51ec | ||
|
9168cb9c61 | ||
|
e1991374ae | ||
|
d0ee9a7c28 | ||
|
10e83b490b | ||
|
4b24dba257 | ||
|
7a036f6f3a | ||
|
e632b0fb1f | ||
|
17bee9d43f | ||
|
492a8ad213 | ||
|
8827b8ed8b | ||
|
8849fbc52d | ||
|
50bc75a802 | ||
|
9b52e49fda | ||
|
ab479794f3 | ||
|
97b8966337 | ||
|
88099a882f | ||
|
d5554eb6d7 | ||
|
13bdfb8bbd | ||
|
74462349c2 | ||
|
6aa648d315 | ||
|
9ff18c2c96 | ||
|
d5ea07c737 | ||
|
aa0096bf42 | ||
|
005c2f3cc8 | ||
|
09f7aab52d | ||
|
30a40f9f76 | ||
|
d9f8bae673 | ||
|
3c7b409460 | ||
|
ee3551e8dc | ||
|
95da2e90de | ||
|
6dd93ab916 | ||
|
505d419a1b | ||
|
d968b5f5b9 | ||
|
d809d4e832 |
@@ -129,8 +129,6 @@ particular member type does not need to concern itself with the integer.</p>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
#include <type_traits> <i>// exposition only</i>
|
||||
|
||||
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
||||
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
||||
#endif
|
||||
@@ -141,11 +139,6 @@ class boost::base_from_member
|
||||
protected:
|
||||
MemberType member;
|
||||
|
||||
#if <i>C++2011 is in use</i>
|
||||
template< typename ...T >
|
||||
explicit constexpr base_from_member( T&& ...x )
|
||||
noexcept( std::is_nothrow_constructible<MemberType, T...>::value );
|
||||
#else
|
||||
base_from_member();
|
||||
|
||||
template< typename T1 >
|
||||
@@ -161,7 +154,6 @@ protected:
|
||||
typename T10 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
|
||||
T8 x8, T9 x9, T10 x10 );
|
||||
#endif
|
||||
};
|
||||
</pre></blockquote>
|
||||
|
||||
@@ -174,29 +166,13 @@ value of zero if it is omitted. The class template has a protected
|
||||
data member called <var>member</var> that the derived class can use
|
||||
for later base classes (or itself).</p>
|
||||
|
||||
<p>If the appropriate features of C++2011 are present, there will be a single
|
||||
constructor template. It implements "perfect forwarding" to the best
|
||||
constructor call of <code>member</code> (if any). The constructor template is
|
||||
marked both <code>constexpr</code> and <code>explicit</code>. The former will
|
||||
be ignored if the corresponding inner constructor call (of <code>member</code>)
|
||||
does not have the marker. The latter binds the other way; always taking
|
||||
effect, even when the inner constructor call does not have the marker. The
|
||||
constructor template propagates the <code>noexcept</code> status of the inner
|
||||
constructor call. (The constructor template has a trailing parameter with a
|
||||
default value that disables the template when its signature is too close to the
|
||||
signatures of the automatically-defined non-template copy- and/or
|
||||
move-constructors of <code>base_from_member</code>.)</p>
|
||||
|
||||
<p>On earlier-standard compilers, there is a default constructor and several
|
||||
constructor member templates. These constructor templates can take as many
|
||||
arguments (currently up to ten) as possible and pass them to a constructor of
|
||||
the data member.</p>
|
||||
|
||||
<p>Since C++ does not allow any way to explicitly state
|
||||
<p>There is a default constructor and several constructor member
|
||||
templates. These constructor templates can take as many arguments
|
||||
(currently up to ten) as possible and pass them to a constructor of
|
||||
the data member. Since C++ does not allow any way to explicitly state
|
||||
the template parameters of a templated constructor, make sure that
|
||||
the arguments are already close as possible to the actual type used in
|
||||
the data member's desired constructor. Explicit conversions may be
|
||||
necessary.</p>
|
||||
the data member's desired constructor.</p>
|
||||
|
||||
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies
|
||||
the maximum argument length for the constructor templates. The constant
|
||||
@@ -204,7 +180,7 @@ may be overridden if more (or less) argument configurations are needed. The
|
||||
constant may be read for code that is expandable like the class template and
|
||||
needs to maintain the same maximum size. (Example code would be a class that
|
||||
uses this class template as a base class for a member with a flexible set of
|
||||
constructors.) This constant is ignored when C++2011 features are present.</p>
|
||||
constructors.)</p>
|
||||
|
||||
<h2><a name="usage">Usage</a></h2>
|
||||
|
||||
@@ -347,14 +323,11 @@ constructor argument for <code>pbase0_type</code> is converted from
|
||||
argument for <code>pbase2_type</code> is converted from <code>int</code>
|
||||
to <code>double</code>. The second constructor argument for
|
||||
<code>pbase3_type</code> is a special case of necessary conversion; all
|
||||
forms of the null-pointer literal in C++ (except <code>nullptr</code> from
|
||||
C++2011) also look like compile-time integral expressions, so C++ always
|
||||
interprets such code as an integer when it has overloads that can take either
|
||||
an integer or a pointer. The last conversion is necessary for the compiler to
|
||||
call a constructor form with the exact pointer type used in
|
||||
<code>switcher</code>'s constructor. (If C++2011's <code>nullptr</code> is
|
||||
used, it still needs a conversion if multiple pointer types can be accepted in
|
||||
a constructor call but <code>std::nullptr_t</code> cannot.)</p>
|
||||
forms of the null-pointer literal in C++ also look like compile-time
|
||||
integral expressions, so C++ always interprets such code as an integer
|
||||
when it has overloads that can take either an integer or a pointer. The
|
||||
last conversion is necessary for the compiler to call a constructor form
|
||||
with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||
|
||||
<h2><a name="credits">Credits</a></h2>
|
||||
|
||||
@@ -387,9 +360,9 @@ a constructor call but <code>std::nullptr_t</code> cannot.)</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised: 16 February 2012</p>
|
||||
<p>Revised: 28 August 2004</p>
|
||||
|
||||
<p>Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and distribution
|
||||
<p>Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and distribution
|
||||
are subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a
|
||||
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||
|
@@ -210,10 +210,8 @@ int main()
|
||||
comparible_UDT u;
|
||||
c1(u);
|
||||
call_traits_checker<int> c2;
|
||||
call_traits_checker<enum_UDT> c2b;
|
||||
int i = 2;
|
||||
c2(i);
|
||||
c2b(one);
|
||||
int* pi = &i;
|
||||
int a[2] = {1,2};
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
|
||||
@@ -294,11 +292,7 @@ int main()
|
||||
BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
|
||||
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
|
||||
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
|
||||
// test enum:
|
||||
BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
|
||||
BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
|
||||
BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
|
||||
BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
project : requirements
|
||||
# Path for links to Boost:
|
||||
<xsl:param>boost.root=../../../..
|
||||
|
||||
|
||||
# Some general style settings:
|
||||
<xsl:param>table.footnote.number.format=1
|
||||
<xsl:param>footnote.number.format=1
|
||||
@@ -43,7 +43,7 @@ using quickbook ;
|
||||
path-constant boost-images : ../../../doc/src/images ;
|
||||
|
||||
xml declval : declval.qbk ;
|
||||
boostbook standalone_declval
|
||||
boostbook standalone
|
||||
:
|
||||
declval
|
||||
:
|
||||
@@ -59,42 +59,10 @@ boostbook standalone_declval
|
||||
<xsl:param>toc.max.depth=1
|
||||
# How far down we go with TOC's
|
||||
<xsl:param>generate.section.toc.level=1
|
||||
|
||||
;
|
||||
|
||||
xml string_ref : string_ref.qbk ;
|
||||
boostbook standalone_string_ref
|
||||
:
|
||||
string_ref
|
||||
:
|
||||
# File name of HTML output:
|
||||
<xsl:param>root.filename=string_ref
|
||||
# How far down we chunk nested sections, basically all of them:
|
||||
<xsl:param>chunk.section.depth=0
|
||||
# Don't put the first section on the same page as the TOC:
|
||||
<xsl:param>chunk.first.sections=0
|
||||
# How far down sections get TOC's
|
||||
<xsl:param>toc.section.depth=1
|
||||
# Max depth in each TOC:
|
||||
<xsl:param>toc.max.depth=1
|
||||
# How far down we go with TOC's
|
||||
<xsl:param>generate.section.toc.level=1
|
||||
;
|
||||
|
||||
xml explicit_operator_bool : explicit_operator_bool.qbk ;
|
||||
boostbook standalone_explicit_operator_bool
|
||||
:
|
||||
explicit_operator_bool
|
||||
:
|
||||
# File name of HTML output:
|
||||
<xsl:param>root.filename=explicit_operator_bool
|
||||
# How far down we chunk nested sections, basically all of them:
|
||||
<xsl:param>chunk.section.depth=0
|
||||
# Don't put the first section on the same page as the TOC:
|
||||
<xsl:param>chunk.first.sections=0
|
||||
# How far down sections get TOC's
|
||||
<xsl:param>toc.section.depth=1
|
||||
# Max depth in each TOC:
|
||||
<xsl:param>toc.max.depth=1
|
||||
# How far down we go with TOC's
|
||||
<xsl:param>generate.section.toc.level=1
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
@@ -1,68 +0,0 @@
|
||||
[/
|
||||
/ Copyright (c) 2013 Andrey Semashev
|
||||
/
|
||||
/ 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)
|
||||
/]
|
||||
|
||||
[article BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL
|
||||
[quickbook 1.5]
|
||||
[authors [Semashev, Andrey]]
|
||||
[copyright 2013 Andrey Semashev]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
]
|
||||
|
||||
[/===============]
|
||||
[section Overview]
|
||||
[/===============]
|
||||
|
||||
`BOOST_EXPLICIT_OPERATOR_BOOL()` and `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` are compatibility helper macros that expand to an explicit conversion operator to `bool`. For compilers not supporting explicit conversion operators introduced in C++11 the macros expand to a conversion operator that implements the [@http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool safe bool idiom]. In case if the compiler is not able to handle safe bool idiom well the macros expand to a regular conversion operator to `bool`.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[/===============]
|
||||
[section Examples]
|
||||
[/===============]
|
||||
|
||||
Both macros are intended to be placed within a user's class definition. The generated conversion operators will be implemented in terms of `operator!()` that should be defined by user in this class. In case of `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` the generated conversion operator will be declared `constexpr` which requires the corresponding `operator!()` to also be `constexpr`.
|
||||
|
||||
template< typename T >
|
||||
class my_ptr
|
||||
{
|
||||
T* m_p;
|
||||
|
||||
public:
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !m_p;
|
||||
}
|
||||
};
|
||||
|
||||
Now `my_ptr` can be used in conditional expressions, similarly to a regular pointer:
|
||||
|
||||
my_ptr< int > p;
|
||||
if (p)
|
||||
std::cout << "true" << std::endl;
|
||||
|
||||
[endsect]
|
||||
|
||||
[/===============]
|
||||
[section History]
|
||||
[/===============]
|
||||
|
||||
[heading boost 1.55]
|
||||
|
||||
* The macro was extracted from Boost.Log.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
<div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div>
|
||||
<div><p class="copyright">Copyright © 2009 -2012 Vicente J. Botet Escriba</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="idp13456288"></a><p>
|
||||
<a name="idp13449552"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
@@ -49,7 +49,7 @@
|
||||
<dt><span class="section"><a href="declval.html#declval.history">History</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section declval_overview">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.overview"></a><a class="link" href="declval.html#declval.overview" title="Overview">Overview</a>
|
||||
</h2></div></div></div>
|
||||
@@ -109,7 +109,7 @@
|
||||
is expected to be part of the daily tool-box of the C++0x programmer.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section declval_reference">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.reference"></a><a class="link" href="declval.html#declval.reference" title="Reference">Reference </a>
|
||||
</h2></div></div></div>
|
||||
@@ -149,16 +149,16 @@
|
||||
if the type From can be explicitly converted to type To.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section declval_history">
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="declval.history"></a><a class="link" href="declval.html#declval.history" title="History">History</a>
|
||||
</h2></div></div></div>
|
||||
<a name="declval.history.boost_1_50"></a><h4>
|
||||
<a name="idp13559952"></a>
|
||||
<a name="idp13553216"></a>
|
||||
<a class="link" href="declval.html#declval.history.boost_1_50">boost 1.50</a>
|
||||
</h4>
|
||||
<p>
|
||||
New Features:
|
||||
Fixes:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
||||
<a href="http://svn.boost.org/trac/boost/ticket/6570" target="_top">#6570</a>
|
||||
@@ -167,7 +167,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: March 25, 2012 at 18:26:23 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: May 28, 2012 at 18:59:06 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
|
@@ -1,280 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>String_Ref</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
|
||||
<link rel="home" href="string_ref.html" title="String_Ref">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"></div>
|
||||
<div class="article">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<div><h2 class="title">
|
||||
<a name="string_ref"></a>String_Ref</h2></div>
|
||||
<div><div class="authorgroup"><div class="author"><h3 class="author">
|
||||
<span class="firstname">Marshall</span> <span class="surname">Clow</span>
|
||||
</h3></div></div></div>
|
||||
<div><p class="copyright">Copyright © 2012 Marshall Clow</p></div>
|
||||
<div><div class="legalnotice">
|
||||
<a name="string_ref.legal"></a><p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="toc">
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl>
|
||||
<dt><span class="section"><a href="string_ref.html#string_ref.overview">Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="string_ref.html#string_ref.examples">Examples</a></span></dt>
|
||||
<dt><span class="section"><a href="string_ref.html#string_ref.reference">Reference </a></span></dt>
|
||||
<dt><span class="section"><a href="string_ref.html#string_ref.history">History</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section string_ref_overview">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="string_ref.overview"></a><a class="link" href="string_ref.html#string_ref.overview" title="Overview">Overview</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
Boost.StringRef is an implementation of Jeffrey Yaskin's <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html" target="_top">N3442:
|
||||
string_ref: a non-owning reference to a string</a>.
|
||||
</p>
|
||||
<p>
|
||||
When you are parsing/processing strings from some external source, frequently
|
||||
you want to pass a piece of text to a procedure for specialized processing.
|
||||
The canonical way to do this is as a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
|
||||
but that has certain drawbacks:
|
||||
</p>
|
||||
<p>
|
||||
1) If you are processing a buffer of text (say a HTTP response or the contents
|
||||
of a file), then you have to create the string from the text you want to pass,
|
||||
which involves memory allocation and copying of data.
|
||||
</p>
|
||||
<p>
|
||||
2) if a routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
|
||||
and wants to pass a portion of that string to another routine, then it must
|
||||
create a new string of that substring.
|
||||
</p>
|
||||
<p>
|
||||
3) A routine receives a constant <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
|
||||
and wants to return a portion of the string, then it must create a new string
|
||||
to return.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">string_ref</span></code> is designed to solve
|
||||
these efficiency problems. A <code class="computeroutput"><span class="identifier">string_ref</span></code>
|
||||
is a read-only reference to a contiguous sequence of characters, and provides
|
||||
much of the functionality of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
|
||||
A <code class="computeroutput"><span class="identifier">string_ref</span></code> is cheap to create,
|
||||
copy and pass by value, because it does not actually own the storage that it
|
||||
points to.
|
||||
</p>
|
||||
<p>
|
||||
A <code class="computeroutput"><span class="identifier">string_ref</span></code> is implemented
|
||||
as a small struct that contains a pointer to the start of the character data
|
||||
and a count. A <code class="computeroutput"><span class="identifier">string_ref</span></code> is
|
||||
cheap to create and cheap to copy.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">string_ref</span></code> acts as a container;
|
||||
it includes all the methods that you would expect in a container, including
|
||||
iteration support, <code class="computeroutput"><span class="keyword">operator</span> <span class="special">[]</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">at</span></code> and <code class="computeroutput"><span class="identifier">size</span></code>.
|
||||
It can be used with any of the iterator-based algorithms in the STL - as long
|
||||
as you don't need to change the underlying data (<code class="computeroutput"><span class="identifier">sort</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">remove</span></code>, for example, will
|
||||
not work)
|
||||
</p>
|
||||
<p>
|
||||
Besides generic container functionality, <code class="computeroutput"><span class="identifier">string_ref</span></code>
|
||||
provides a subset of the interface of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
|
||||
This makes it easy to replace parameters of type <code class="computeroutput"><span class="keyword">const</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span></code>
|
||||
with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>. Like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">string_ref</span></code> has a static member
|
||||
variable named <code class="computeroutput"><span class="identifier">npos</span></code> to denote
|
||||
the result of failed searches, and to mean "the end".
|
||||
</p>
|
||||
<p>
|
||||
Because a <code class="computeroutput"><span class="identifier">string_ref</span></code> does not
|
||||
own the data that it "points to", it introduces lifetime issues into
|
||||
code that uses it. The programmer must ensure that the data that a <code class="computeroutput"><span class="identifier">string_ref</span></code> refers to exists as long as the
|
||||
<code class="computeroutput"><span class="identifier">string_ref</span></code> does.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section string_ref_examples">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="string_ref.examples"></a><a class="link" href="string_ref.html#string_ref.examples" title="Examples">Examples</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
Integrating <code class="computeroutput"><span class="identifier">string_ref</span></code> into
|
||||
your code is fairly simple. Wherever you pass a <code class="computeroutput"><span class="keyword">const</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> as a parameter, that's a candidate
|
||||
for passing a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span></code>.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&</span><span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Let's figure out what happens in this (contrived) example.
|
||||
</p>
|
||||
<p>
|
||||
First, a temporary string is created from the string literal <code class="computeroutput"><span class="string">"ABCDEFG"</span></code>, and it is passed (by reference)
|
||||
to the routine <code class="computeroutput"><span class="identifier">extract_part</span></code>.
|
||||
Then a second string is created in the call <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">::</span><span class="identifier">substr</span></code>
|
||||
and returned to <code class="computeroutput"><span class="identifier">extract_part</span></code>
|
||||
(this copy may be elided by RVO). Then <code class="computeroutput"><span class="identifier">extract_part</span></code>
|
||||
returns that string back to the caller (again this copy may be elided). The
|
||||
first temporary string is deallocated, and <code class="computeroutput"><span class="identifier">front</span></code>
|
||||
is called on the second string, and then it is deallocated as well.
|
||||
</p>
|
||||
<p>
|
||||
Two <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>s are created, and two copy operations.
|
||||
That's (potentially) four memory allocations and deallocations, and the associated
|
||||
copying of data.
|
||||
</p>
|
||||
<p>
|
||||
Now let's look at the same code with <code class="computeroutput"><span class="identifier">string_ref</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_ref</span> <span class="identifier">bar</span> <span class="special">)</span> <span class="special">{</span>
|
||||
<span class="keyword">return</span> <span class="identifier">bar</span><span class="special">.</span><span class="identifier">substr</span> <span class="special">(</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="string">"ABCDEFG"</span> <span class="special">).</span><span class="identifier">front</span><span class="special">()</span> <span class="special">==</span> <span class="string">"C"</span> <span class="special">)</span> <span class="special">{</span> <span class="comment">/* do something */</span> <span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
No memory allocations. No copying of character data. No changes to the code
|
||||
other than the types. There are two <code class="computeroutput"><span class="identifier">string_ref</span></code>s
|
||||
created, and two <code class="computeroutput"><span class="identifier">string_ref</span></code>s
|
||||
copied, but those are cheap operations.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section string_ref_reference">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="string_ref.reference"></a><a class="link" href="string_ref.html#string_ref.reference" title="Reference">Reference </a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
The header file "string_ref.hpp" defines a template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">basic_string_ref</span></code>,
|
||||
and four specializations - for <code class="computeroutput"><span class="keyword">char</span></code>
|
||||
/ <code class="computeroutput"><span class="keyword">wchar_t</span></code> / <code class="computeroutput"><span class="identifier">char16_t</span></code>
|
||||
/ <code class="computeroutput"><span class="identifier">char32_t</span></code> .
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">string_ref</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>
|
||||
</p>
|
||||
<p>
|
||||
Construction and copying:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="special">();</span> <span class="comment">// Constructs an empty string_ref</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a NULL-terminated string</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">str</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">len</span><span class="special">);</span> <span class="comment">// Constructs from a pointer, length pair</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Allocator</span><span class="special">></span>
|
||||
<span class="identifier">basic_string_ref</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_string</span><span class="special"><</span><span class="identifier">charT</span><span class="special">,</span> <span class="identifier">traits</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">>&</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// Constructs from a std::string</span>
|
||||
<span class="identifier">basic_string_ref</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">);</span>
|
||||
<span class="identifier">basic_string_ref</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">basic_string_ref</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">string_ref</span></code> does not define
|
||||
a move constructor nor a move-assignment operator because copying a <code class="computeroutput"><span class="identifier">string_ref</span></code> is just a cheap as moving one.
|
||||
</p>
|
||||
<p>
|
||||
Basic container-like functions:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">length</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">max_size</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">bool</span> <span class="identifier">empty</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
|
||||
<span class="comment">// All iterators are const_iterators</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">cbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">const_iterator</span> <span class="identifier">cend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">const_reverse_iterator</span> <span class="identifier">rbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">const_reverse_iterator</span> <span class="identifier">crbegin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">const_reverse_iterator</span> <span class="identifier">rend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">const_reverse_iterator</span> <span class="identifier">crend</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Access to the individual elements (all of which are const):
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">at</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">pos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">front</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">back</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">data</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
Modifying the <code class="computeroutput"><span class="identifier">string_ref</span></code> (but
|
||||
not the underlying data):
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">clear</span><span class="special">();</span>
|
||||
<span class="keyword">void</span> <span class="identifier">remove_prefix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span>
|
||||
<span class="keyword">void</span> <span class="identifier">remove_suffix</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
Searching:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_last_of</span> <span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
String-like operations:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_ref</span> <span class="identifier">substr</span><span class="special">(</span><span class="identifier">size_type</span> <span class="identifier">pos</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">=</span><span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <span class="comment">// Creates a new string_ref</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">charT</span> <span class="identifier">c</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">basic_string_ref</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span>
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section string_ref_history">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="string_ref.history"></a><a class="link" href="string_ref.html#string_ref.history" title="History">History</a>
|
||||
</h2></div></div></div>
|
||||
<h4>
|
||||
<a name="string_ref.history.h0"></a>
|
||||
<span><a name="string_ref.history.boost_1_53"></a></span><a class="link" href="string_ref.html#string_ref.history.boost_1_53">boost
|
||||
1.53</a>
|
||||
</h4>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
|
||||
Introduced
|
||||
</li></ul></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: January 14, 2013 at 16:24:14 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"></div>
|
||||
</body>
|
||||
</html>
|
@@ -1,167 +0,0 @@
|
||||
[/
|
||||
/ Copyright (c) 2012 Marshall Clow
|
||||
/
|
||||
/ 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)
|
||||
/]
|
||||
|
||||
[article String_Ref
|
||||
[quickbook 1.5]
|
||||
[authors [Clow, Marshall]]
|
||||
[copyright 2012 Marshall Clow]
|
||||
[license
|
||||
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])
|
||||
]
|
||||
]
|
||||
|
||||
[/===============]
|
||||
[section Overview]
|
||||
[/===============]
|
||||
|
||||
Boost.StringRef is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442:
|
||||
string_ref: a non-owning reference to a string].
|
||||
|
||||
When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. The canonical way to do this is as a `std::string`, but that has certain drawbacks:
|
||||
|
||||
1) If you are processing a buffer of text (say a HTTP response or the contents of a file), then you have to create the string from the text you want to pass, which involves memory allocation and copying of data.
|
||||
|
||||
2) if a routine receives a constant `std::string` and wants to pass a portion of that string to another routine, then it must create a new string of that substring.
|
||||
|
||||
3) A routine receives a constant `std::string` and wants to return a portion of the string, then it must create a new string to return.
|
||||
|
||||
`string_ref` is designed to solve these efficiency problems. A `string_ref` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_ref` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to.
|
||||
|
||||
A `string_ref` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_ref` is cheap to create and cheap to copy.
|
||||
|
||||
`string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work)
|
||||
|
||||
Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. Like `std::string`, `string_ref` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end".
|
||||
|
||||
Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[/===============]
|
||||
[section Examples]
|
||||
[/===============]
|
||||
|
||||
Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`.
|
||||
|
||||
std::string extract_part ( const std::string &bar ) {
|
||||
return bar.substr ( 2, 3 );
|
||||
}
|
||||
|
||||
if ( extract_part ( "ABCDEFG" ).front() == 'C' ) { /* do something */ }
|
||||
|
||||
Let's figure out what happens in this (contrived) example.
|
||||
|
||||
First, a temporary string is created from the string literal `"ABCDEFG"`, and it is passed (by reference) to the routine `extract_part`. Then a second string is created in the call `std::string::substr` and returned to `extract_part` (this copy may be elided by RVO). Then `extract_part` returns that string back to the caller (again this copy may be elided). The first temporary string is deallocated, and `front` is called on the second string, and then it is deallocated as well.
|
||||
|
||||
Two `std::string`s are created, and two copy operations. That's (potentially) four memory allocations and deallocations, and the associated copying of data.
|
||||
|
||||
Now let's look at the same code with `string_ref`:
|
||||
|
||||
boost::string_ref extract_part ( boost::string_ref bar ) {
|
||||
return bar.substr ( 2, 3 );
|
||||
}
|
||||
|
||||
if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ }
|
||||
|
||||
No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[/=================]
|
||||
[section:reference Reference ]
|
||||
[/=================]
|
||||
|
||||
The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` .
|
||||
|
||||
`#include <boost/utility/string_ref.hpp>`
|
||||
|
||||
Construction and copying:
|
||||
|
||||
BOOST_CONSTEXPR basic_string_ref (); // Constructs an empty string_ref
|
||||
BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string
|
||||
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair
|
||||
template<typename Allocator>
|
||||
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str); // Constructs from a std::string
|
||||
basic_string_ref (const basic_string_ref &rhs);
|
||||
basic_string_ref& operator=(const basic_string_ref &rhs);
|
||||
|
||||
`string_ref` does not define a move constructor nor a move-assignment operator because copying a `string_ref` is just a cheap as moving one.
|
||||
|
||||
Basic container-like functions:
|
||||
|
||||
BOOST_CONSTEXPR size_type size() const ;
|
||||
BOOST_CONSTEXPR size_type length() const ;
|
||||
BOOST_CONSTEXPR size_type max_size() const ;
|
||||
BOOST_CONSTEXPR bool empty() const ;
|
||||
|
||||
// All iterators are const_iterators
|
||||
BOOST_CONSTEXPR const_iterator begin() const ;
|
||||
BOOST_CONSTEXPR const_iterator cbegin() const ;
|
||||
BOOST_CONSTEXPR const_iterator end() const ;
|
||||
BOOST_CONSTEXPR const_iterator cend() const ;
|
||||
const_reverse_iterator rbegin() const ;
|
||||
const_reverse_iterator crbegin() const ;
|
||||
const_reverse_iterator rend() const ;
|
||||
const_reverse_iterator crend() const ;
|
||||
|
||||
Access to the individual elements (all of which are const):
|
||||
|
||||
BOOST_CONSTEXPR const charT& operator[](size_type pos) const ;
|
||||
const charT& at(size_t pos) const ;
|
||||
BOOST_CONSTEXPR const charT& front() const ;
|
||||
BOOST_CONSTEXPR const charT& back() const ;
|
||||
BOOST_CONSTEXPR const charT* data() const ;
|
||||
|
||||
Modifying the `string_ref` (but not the underlying data):
|
||||
|
||||
void clear();
|
||||
void remove_prefix(size_type n);
|
||||
void remove_suffix(size_type n);
|
||||
|
||||
Searching:
|
||||
|
||||
size_type find(basic_string_ref s) const ;
|
||||
size_type find(charT c) const ;
|
||||
size_type rfind(basic_string_ref s) const ;
|
||||
size_type rfind(charT c) const ;
|
||||
size_type find_first_of(charT c) const ;
|
||||
size_type find_last_of (charT c) const ;
|
||||
|
||||
size_type find_first_of(basic_string_ref s) const ;
|
||||
size_type find_last_of(basic_string_ref s) const ;
|
||||
size_type find_first_not_of(basic_string_ref s) const ;
|
||||
size_type find_first_not_of(charT c) const ;
|
||||
size_type find_last_not_of(basic_string_ref s) const ;
|
||||
size_type find_last_not_of(charT c) const ;
|
||||
|
||||
String-like operations:
|
||||
|
||||
BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref
|
||||
bool starts_with(charT c) const ;
|
||||
bool starts_with(basic_string_ref x) const ;
|
||||
bool ends_with(charT c) const ;
|
||||
bool ends_with(basic_string_ref x) const ;
|
||||
|
||||
[endsect]
|
||||
|
||||
[/===============]
|
||||
[section History]
|
||||
[/===============]
|
||||
|
||||
[heading boost 1.53]
|
||||
* Introduced
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
|
||||
|
@@ -46,7 +46,7 @@ HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_pla
|
||||
<p>Suppose we have a class</p>
|
||||
<pre>struct X
|
||||
{
|
||||
X ( int, std::string ) ;
|
||||
X ( int, std:::string ) ;
|
||||
} ;</pre>
|
||||
<p>And a container for it which supports an empty state (that is, which can contain zero objects):</p>
|
||||
<pre>struct C
|
||||
|
@@ -34,7 +34,6 @@
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
namespace boost
|
||||
@@ -43,7 +42,7 @@ namespace boost
|
||||
char const * function, char const * file, long line); // user defined
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \
|
||||
#define BOOST_ASSERT(expr) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
@@ -64,7 +63,6 @@ namespace boost
|
||||
|
||||
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
namespace boost
|
||||
@@ -73,7 +71,7 @@ namespace boost
|
||||
char const * function, char const * file, long line); // user defined
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
@@ -82,7 +80,6 @@ namespace boost
|
||||
#define BOOST_ASSERT_HPP
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
// IDE's like Visual Studio perform better if output goes to std::cout or
|
||||
@@ -92,33 +89,26 @@ namespace boost
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace assertion
|
||||
{
|
||||
{
|
||||
namespace assertion
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
// Note: The template is needed to make the function non-inline and avoid linking errors
|
||||
template< typename CharT >
|
||||
BOOST_NOINLINE void assertion_failed_msg(CharT const * expr, char const * msg, char const * function,
|
||||
inline void assertion_failed_msg(char const * expr, char const * msg, char const * function,
|
||||
char const * file, long line)
|
||||
{
|
||||
BOOST_ASSERT_MSG_OSTREAM
|
||||
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
|
||||
<< function << ":\n"
|
||||
<< file << '(' << line << "): " << msg << std::endl;
|
||||
#ifdef UNDER_CE
|
||||
// The Windows CE CRT library does not have abort() so use exit(-1) instead.
|
||||
std::exit(-1);
|
||||
#else
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
} // detail
|
||||
} // assertion
|
||||
} // detail
|
||||
#endif
|
||||
|
||||
#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
|
||||
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
|
||||
? ((void)0) \
|
||||
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
|
||||
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_enum.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
@@ -44,26 +43,20 @@ struct ct_imp2<T, true>
|
||||
typedef const T param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b1, bool b2>
|
||||
template <typename T, bool isp, bool b1>
|
||||
struct ct_imp
|
||||
{
|
||||
typedef const T& param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b2>
|
||||
struct ct_imp<T, isp, true, b2>
|
||||
template <typename T, bool isp>
|
||||
struct ct_imp<T, isp, true>
|
||||
{
|
||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool isp, bool b1>
|
||||
struct ct_imp<T, isp, b1, true>
|
||||
{
|
||||
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b1, bool b2>
|
||||
struct ct_imp<T, true, b1, b2>
|
||||
template <typename T, bool b1>
|
||||
struct ct_imp<T, true, b1>
|
||||
{
|
||||
typedef const T param_type;
|
||||
};
|
||||
@@ -86,8 +79,7 @@ public:
|
||||
typedef typename boost::detail::ct_imp<
|
||||
T,
|
||||
::boost::is_pointer<T>::value,
|
||||
::boost::is_arithmetic<T>::value,
|
||||
::boost::is_enum<T>::value
|
||||
::boost::is_arithmetic<T>::value
|
||||
>::param_type param_type;
|
||||
};
|
||||
|
||||
|
11
include/boost/exception.hpp
Normal file
11
include/boost/exception.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
//Copyright (c) 2006-2008 Emil Dotchevski and Reverge Studios, Inc.
|
||||
|
||||
//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)
|
||||
|
||||
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||
|
||||
#error The header <boost/exception.hpp> has been deprecated. Please #include <boost/exception/all.hpp> instead.
|
||||
|
||||
#endif
|
@@ -9,8 +9,6 @@
|
||||
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||
#define BOOST_NONCOPYABLE_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// Private copy constructor and copy assignment ensure classes derived from
|
||||
@@ -23,21 +21,11 @@ namespace noncopyable_ // protection from unintended ADL
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
#ifndef BOOST_NO_DEFAULTED_FUNCTIONS
|
||||
BOOST_CONSTEXPR noncopyable() = default;
|
||||
~noncopyable() = default;
|
||||
#else
|
||||
noncopyable() {}
|
||||
noncopyable() {}
|
||||
~noncopyable() {}
|
||||
#endif
|
||||
#ifndef BOOST_NO_DELETED_FUNCTIONS
|
||||
noncopyable( const noncopyable& ) = delete;
|
||||
noncopyable& operator=( const noncopyable& ) = delete;
|
||||
#else
|
||||
private: // emphasize the following members are private
|
||||
private: // emphasize the following members are private
|
||||
noncopyable( const noncopyable& );
|
||||
noncopyable& operator=( const noncopyable& );
|
||||
#endif
|
||||
const noncopyable& operator=( const noncopyable& );
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||
// Douglas Gregor (gregod@cs.rpi.edu)
|
||||
//
|
||||
// Copyright (C) 2002, 2008 Peter Dimov
|
||||
@@ -50,7 +50,7 @@ template<class T> struct addressof_impl
|
||||
|
||||
template<class T> T * addressof( T & v )
|
||||
{
|
||||
#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || defined( __SUNPRO_CC )
|
||||
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) )
|
||||
|
||||
return boost::detail::addressof_impl<T>::f( v, 0 );
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// boost utility/base_from_member.hpp header file --------------------------//
|
||||
|
||||
// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and
|
||||
// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
|
||||
// distribution are subject to the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or a copy at
|
||||
// <http://www.boost.org/LICENSE_1_0.txt>.)
|
||||
@@ -10,15 +10,10 @@
|
||||
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
|
||||
// Base-from-member arity configuration macro ------------------------------//
|
||||
@@ -58,59 +53,6 @@
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Type-unmarking class template -------------------------------------------//
|
||||
|
||||
// Type-trait to get the raw type, i.e. the type without top-level reference nor
|
||||
// cv-qualification, from a type expression. Mainly for function arguments, any
|
||||
// reference part is stripped first.
|
||||
|
||||
// Contributed by Daryle Walker
|
||||
|
||||
template < typename T >
|
||||
struct remove_cv_ref
|
||||
{
|
||||
typedef typename ::boost::remove_cv<typename
|
||||
::boost::remove_reference<T>::type>::type type;
|
||||
|
||||
}; // boost::detail::remove_cv_ref
|
||||
|
||||
// Unmarked-type comparison class template ---------------------------------//
|
||||
|
||||
// Type-trait to check if two type expressions have the same raw type.
|
||||
|
||||
// Contributed by Daryle Walker, based on a work-around by Luc Danton
|
||||
|
||||
template < typename T, typename U >
|
||||
struct is_related
|
||||
: public ::boost::is_same<
|
||||
typename ::boost::detail::remove_cv_ref<T>::type,
|
||||
typename ::boost::detail::remove_cv_ref<U>::type >
|
||||
{};
|
||||
|
||||
// Enable-if-on-unidentical-unmarked-type class template -------------------//
|
||||
|
||||
// Enable-if on the first two type expressions NOT having the same raw type.
|
||||
|
||||
// Contributed by Daryle Walker, based on a work-around by Luc Danton
|
||||
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
||||
template<typename ...T>
|
||||
struct enable_if_unrelated
|
||||
: public ::boost::enable_if_c<true>
|
||||
{};
|
||||
|
||||
template<typename T, typename U, typename ...U2>
|
||||
struct enable_if_unrelated<T, U, U2...>
|
||||
: public ::boost::disable_if< ::boost::detail::is_related<T, U> >
|
||||
{};
|
||||
#endif
|
||||
|
||||
} // namespace boost::detail
|
||||
|
||||
|
||||
// Base-from-member class template -----------------------------------------//
|
||||
|
||||
// Helper to initialize a base object so a derived class can use this
|
||||
@@ -126,25 +68,12 @@ class base_from_member
|
||||
protected:
|
||||
MemberType member;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
|
||||
!(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4))
|
||||
template <typename ...T, typename EnableIf = typename
|
||||
::boost::detail::enable_if_unrelated<base_from_member, T...>::type>
|
||||
explicit BOOST_CONSTEXPR base_from_member( T&& ...x )
|
||||
BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType(
|
||||
static_cast<T&&>(x)... )) ) // no std::is_nothrow_constructible...
|
||||
: member( static_cast<T&&>(x)... ) // ...nor std::forward needed
|
||||
{}
|
||||
#else
|
||||
base_from_member()
|
||||
: member()
|
||||
{}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||
BOOST_PRIVATE_CTR_DEF, _ )
|
||||
#endif
|
||||
|
||||
}; // boost::base_from_member
|
||||
|
||||
|
@@ -1,44 +1,49 @@
|
||||
// declval.hpp -------------------------------------------------------------//
|
||||
// common_type.hpp ---------------------------------------------------------//
|
||||
|
||||
// Copyright 2010 Vicente J. Botet Escriba
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_UTILITY_DECLVAL_HPP
|
||||
#define BOOST_UTILITY_DECLVAL_HPP
|
||||
#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include <boost/type_traits/add_rvalue_reference.hpp>
|
||||
//#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// //
|
||||
// C++03 implementation of //
|
||||
// 20.2.4 Function template declval [declval] //
|
||||
// Written by Vicente J. Botet Escriba //
|
||||
//~ 20.3.4 Function template declval [declval]
|
||||
//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as
|
||||
//~ unevaluated operands.
|
||||
//~ 2 Remarks: If this function is used, the program is ill-formed.
|
||||
//~ 3 Remarks: The template parameter T of declval may be an incomplete type.
|
||||
//~ [ Example:
|
||||
|
||||
//~ template <class To, class From>
|
||||
//~ decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
|
||||
//~ declares a function template convert which only participats in overloading if the type From can be
|
||||
//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). <20>end
|
||||
//~ example ]
|
||||
// //
|
||||
// 1 The library provides the function template declval to simplify the
|
||||
// definition of expressions which occur as unevaluated operands.
|
||||
// 2 Remarks: If this function is used, the program is ill-formed.
|
||||
// 3 Remarks: The template parameter T of declval may be an incomplete type.
|
||||
// [ Example:
|
||||
//
|
||||
// template <class To, class From>
|
||||
// decltype(static_cast<To>(declval<From>())) convert(From&&);
|
||||
//
|
||||
// declares a function template convert which only participates in overloading
|
||||
// if the type From can be explicitly converted to type To. For another example
|
||||
// see class template common_type (20.9.7.6). -end example ]
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace boost {
|
||||
|
||||
//#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
template <typename T>
|
||||
typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
|
||||
//#else
|
||||
// template <typename T>
|
||||
// typename add_lvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
|
||||
//#endif
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UTILITY_DECLVAL_HPP
|
||||
#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
|
||||
|
@@ -5,11 +5,6 @@
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Copyright Daniel Walker, Eric Niebler, Michel Morin 2008-2012.
|
||||
// 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)
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
# error Boost result_of - do not include this file!
|
||||
@@ -23,44 +18,31 @@
|
||||
#endif
|
||||
|
||||
#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_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_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> >
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
||||
typename remove_cv<F>::type,
|
||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)>
|
||||
, boost::detail::tr1_result_of_impl<
|
||||
F,
|
||||
F(BOOST_RESULT_OF_ARGS),
|
||||
F(BOOST_RESULT_OF_ARGS),
|
||||
(boost::detail::has_result_type<F>::value)> >::type { };
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: detail::cpp0x_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||
#endif // BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
|
||||
#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> >,
|
||||
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
|
||||
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
|
||||
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))>
|
||||
// Uses declval following N3225 20.7.7.6 when F is not a pointer.
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
: mpl::if_<
|
||||
is_member_function_pointer<F>
|
||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||
, 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
|
||||
>
|
||||
, detail::cpp0x_result_of_impl<
|
||||
@@ -69,119 +51,55 @@ struct cpp0x_result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
>::type
|
||||
{};
|
||||
|
||||
#ifdef BOOST_NO_SFINAE_EXPR
|
||||
namespace detail {
|
||||
|
||||
template<typename F>
|
||||
struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION());
|
||||
|
||||
template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
|
||||
struct BOOST_PP_CAT(result_of_callable_fun_2_, BOOST_PP_ITERATION())<R(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T))> {
|
||||
R operator()(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), T)) const;
|
||||
typedef result_of_private_type const &(*pfn_t)(...);
|
||||
operator pfn_t() const volatile;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION());
|
||||
|
||||
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>,
|
||||
result_of_wrap_callable_class<F>,
|
||||
mpl::identity<BOOST_PP_CAT(result_of_callable_fun_, BOOST_PP_ITERATION())<typename remove_cv<F>::type> >
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename T)>
|
||||
struct BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION()) {
|
||||
typedef typename BOOST_PP_CAT(result_of_select_call_wrapper_type_, BOOST_PP_ITERATION())<F>::type wrapper_t;
|
||||
static const bool value = (
|
||||
sizeof(result_of_no_type) == sizeof(detail::result_of_is_private_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;
|
||||
};
|
||||
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), true>
|
||||
: lazy_enable_if<
|
||||
BOOST_PP_CAT(result_of_is_callable_, BOOST_PP_ITERATION())<F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), T)>
|
||||
, cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
|
||||
>
|
||||
{};
|
||||
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false>
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||
{
|
||||
typedef decltype(
|
||||
boost::declval<F>()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), declval<T, >() BOOST_PP_INTERCEPT)
|
||||
)
|
||||
) type;
|
||||
};
|
||||
|
||||
#else // BOOST_NO_SFINAE_EXPR
|
||||
} // namespace detail
|
||||
|
||||
template<typename F BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
typename result_of_always_void<decltype(
|
||||
boost::declval<F>()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
|
||||
)
|
||||
)>::type> {
|
||||
typedef decltype(
|
||||
boost::declval<F>()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), boost::declval<T, >() BOOST_PP_INTERCEPT)
|
||||
)
|
||||
) type;
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_SFINAE_EXPR
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
#else // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#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_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||
#endif
|
||||
|
||||
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
#endif // defined(BOOST_NO_DECLTYPE)
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
|
||||
#if BOOST_PP_ITERATION() >= 1
|
||||
#if BOOST_PP_ITERATION() >= 1
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
FArgs, false>
|
||||
@@ -189,7 +107,8 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const,
|
||||
@@ -198,7 +117,8 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
volatile,
|
||||
@@ -207,7 +127,8 @@ struct tr1_result_of_impl<R (T0::*)
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct tr1_result_of_impl<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const volatile,
|
||||
|
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 empty_deleter.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 22.04.2007
|
||||
*
|
||||
* This header contains an \c empty_deleter implementation. This is an empty
|
||||
* function object that receives a pointer and does nothing with it.
|
||||
* Such empty deletion strategy may be convenient, for example, when
|
||||
* constructing <tt>shared_ptr</tt>s that point to some object that should not be
|
||||
* deleted (i.e. a variable on the stack or some global singleton, like <tt>std::cout</tt>).
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
|
||||
#define BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
//! A function object that does nothing and can be used as an empty deleter for \c shared_ptr
|
||||
struct empty_deleter
|
||||
{
|
||||
//! Function object result type
|
||||
typedef void result_type;
|
||||
/*!
|
||||
* Does nothing
|
||||
*/
|
||||
void operator() (const volatile void*) const BOOST_NOEXCEPT {}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
|
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2009
|
||||
*
|
||||
* This header defines a compatibility macro that implements an unspecified
|
||||
* \c bool operator idiom, which is superseded with explicit conversion operators in
|
||||
* C++11.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
|
||||
#define BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
/*!
|
||||
* \brief The macro defines an explicit operator of conversion to \c bool
|
||||
*
|
||||
* The macro should be used inside the definition of a class that has to
|
||||
* support the conversion. The class should also implement <tt>operator!</tt>,
|
||||
* in terms of which the conversion operator will be implemented.
|
||||
*/
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE explicit operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The macro defines a constexpr explicit operator of conversion to \c bool
|
||||
*
|
||||
* The macro should be used inside the definition of a class that has to
|
||||
* support the conversion. The class should also implement <tt>operator!</tt>,
|
||||
* in terms of which the conversion operator will be implemented.
|
||||
*/
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
|
||||
// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
|
||||
#define BOOST_NO_UNSPECIFIED_BOOL
|
||||
#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
|
||||
|
||||
#if !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(__IBMCPP__)
|
||||
|
||||
struct unspecified_bool
|
||||
{
|
||||
// NOTE TO THE USER: If you see this in error messages then you tried
|
||||
// to apply an unsupported operator on the object that supports
|
||||
// explicit conversion to bool.
|
||||
struct OPERATORS_NOT_ALLOWED;
|
||||
static void true_value(OPERATORS_NOT_ALLOWED*) {}
|
||||
};
|
||||
typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
|
||||
|
||||
#else
|
||||
|
||||
// MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't
|
||||
struct unspecified_bool
|
||||
{
|
||||
// NOTE TO THE USER: If you see this in error messages then you tried
|
||||
// to apply an unsupported operator on the object that supports
|
||||
// explicit conversion to bool.
|
||||
struct OPERATORS_NOT_ALLOWED;
|
||||
void true_value(OPERATORS_NOT_ALLOWED*) {}
|
||||
};
|
||||
typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\
|
||||
{\
|
||||
return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
|
||||
}
|
||||
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const\
|
||||
{\
|
||||
return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
#endif // BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
|
@@ -10,57 +10,24 @@
|
||||
#define BOOST_RESULT_OF_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#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>
|
||||
|
||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 16
|
||||
#endif
|
||||
|
||||
// Use the decltype-based version of result_of by default if the compiler
|
||||
// supports N3276 <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011/n3276.pdf>.
|
||||
// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
|
||||
// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
|
||||
#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
|
||||
(defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
|
||||
(defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
|
||||
# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
|
||||
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
|
||||
# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
# define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
# else
|
||||
# define BOOST_RESULT_OF_USE_TR1
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
@@ -73,79 +40,8 @@ namespace detail {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
|
||||
|
||||
template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl;
|
||||
|
||||
template<typename F> struct cpp0x_result_of;
|
||||
|
||||
#ifdef BOOST_NO_SFINAE_EXPR
|
||||
|
||||
// There doesn't seem to be any other way to turn this off such that the presence of
|
||||
// the user-defined operator,() below doesn't cause spurious warning all over the place,
|
||||
// so unconditionally turn it off.
|
||||
#if BOOST_MSVC
|
||||
# pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used
|
||||
#endif
|
||||
|
||||
struct result_of_private_type {};
|
||||
|
||||
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);
|
||||
|
||||
template<typename C>
|
||||
struct result_of_callable_class : C {
|
||||
result_of_callable_class();
|
||||
typedef result_of_private_type const &(*pfn_t)(...);
|
||||
operator pfn_t() const volatile;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct result_of_wrap_callable_class {
|
||||
typedef result_of_callable_class<C> type;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct result_of_wrap_callable_class<C const> {
|
||||
typedef result_of_callable_class<C> const type;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct result_of_wrap_callable_class<C volatile> {
|
||||
typedef result_of_callable_class<C> volatile type;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct result_of_wrap_callable_class<C const volatile> {
|
||||
typedef result_of_callable_class<C> const volatile type;
|
||||
};
|
||||
|
||||
template<typename C>
|
||||
struct result_of_wrap_callable_class<C &> {
|
||||
typedef typename result_of_wrap_callable_class<C>::type &type;
|
||||
};
|
||||
|
||||
template<typename F, bool TestCallability = true> struct cpp0x_result_of_impl;
|
||||
|
||||
#else // BOOST_NO_SFINAE_EXPR
|
||||
|
||||
template<typename T>
|
||||
struct result_of_always_void
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename F, typename Enable = void> struct cpp0x_result_of_impl {};
|
||||
|
||||
#endif // BOOST_NO_SFINAE_EXPR
|
||||
template<typename F> struct cpp0x_result_of_impl;
|
||||
|
||||
template<typename F>
|
||||
struct result_of_void_impl
|
||||
|
@@ -1,536 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BOOST_STRING_REF_HPP
|
||||
#define BOOST_STRING_REF_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
// A helper functor because sometimes we don't have lambdas
|
||||
template <typename charT, typename traits>
|
||||
class string_ref_traits_eq {
|
||||
public:
|
||||
string_ref_traits_eq ( charT ch ) : ch_(ch) {}
|
||||
bool operator () ( charT val ) const { return traits::eq ( ch_, val ); }
|
||||
charT ch_;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
class basic_string_ref {
|
||||
public:
|
||||
// types
|
||||
typedef charT value_type;
|
||||
typedef const charT* pointer;
|
||||
typedef const charT& reference;
|
||||
typedef const charT& const_reference;
|
||||
typedef 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_ref ()
|
||||
: ptr_(NULL), len_(0) {}
|
||||
|
||||
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs)
|
||||
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
||||
|
||||
basic_string_ref& operator=(const basic_string_ref &rhs) {
|
||||
ptr_ = rhs.ptr_;
|
||||
len_ = rhs.len_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
basic_string_ref(const charT* str)
|
||||
: ptr_(str), len_(traits::length(str)) {}
|
||||
|
||||
template<typename Allocator>
|
||||
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
|
||||
: ptr_(str.data()), len_(str.length()) {}
|
||||
|
||||
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len)
|
||||
: ptr_(str), len_(len) {}
|
||||
|
||||
#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> ( ptr_, len_ );
|
||||
}
|
||||
#endif
|
||||
|
||||
std::basic_string<charT, traits> to_string () const {
|
||||
return std::basic_string<charT, traits> ( ptr_, len_ );
|
||||
}
|
||||
|
||||
// iterators
|
||||
BOOST_CONSTEXPR const_iterator begin() const { return ptr_; }
|
||||
BOOST_CONSTEXPR const_iterator cbegin() const { return ptr_; }
|
||||
BOOST_CONSTEXPR const_iterator end() const { return ptr_ + len_; }
|
||||
BOOST_CONSTEXPR const_iterator cend() const { return ptr_ + len_; }
|
||||
const_reverse_iterator rbegin() const { return const_reverse_iterator (end()); }
|
||||
const_reverse_iterator crbegin() const { return const_reverse_iterator (end()); }
|
||||
const_reverse_iterator rend() const { return const_reverse_iterator (begin()); }
|
||||
const_reverse_iterator crend() const { return const_reverse_iterator (begin()); }
|
||||
|
||||
// capacity
|
||||
BOOST_CONSTEXPR size_type size() const { return len_; }
|
||||
BOOST_CONSTEXPR size_type length() const { return len_; }
|
||||
BOOST_CONSTEXPR size_type max_size() const { return len_; }
|
||||
BOOST_CONSTEXPR bool empty() const { return len_ == 0; }
|
||||
|
||||
// element access
|
||||
BOOST_CONSTEXPR const charT& operator[](size_type pos) const { return ptr_[pos]; }
|
||||
|
||||
const charT& at(size_t pos) const {
|
||||
if ( pos >= len_ )
|
||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) );
|
||||
return ptr_[pos];
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR const charT& front() const { return ptr_[0]; }
|
||||
BOOST_CONSTEXPR const charT& back() const { return ptr_[len_-1]; }
|
||||
BOOST_CONSTEXPR const charT* data() const { return ptr_; }
|
||||
|
||||
// modifiers
|
||||
void clear() { len_ = 0; }
|
||||
void remove_prefix(size_type n) {
|
||||
if ( n > len_ )
|
||||
n = len_;
|
||||
ptr_ += n;
|
||||
len_ -= n;
|
||||
}
|
||||
|
||||
void remove_suffix(size_type n) {
|
||||
if ( n > len_ )
|
||||
n = len_;
|
||||
len_ -= n;
|
||||
}
|
||||
|
||||
|
||||
// basic_string_ref string operations
|
||||
basic_string_ref substr(size_type pos, size_type n=npos) const {
|
||||
if ( pos > size())
|
||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
|
||||
if ( n == npos || pos + n > size())
|
||||
n = size () - pos;
|
||||
return basic_string_ref ( data() + pos, n );
|
||||
}
|
||||
|
||||
int compare(basic_string_ref x) const {
|
||||
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 );
|
||||
}
|
||||
|
||||
bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); }
|
||||
bool starts_with(basic_string_ref x) const {
|
||||
return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
|
||||
}
|
||||
|
||||
bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); }
|
||||
bool ends_with(basic_string_ref x) const {
|
||||
return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0;
|
||||
}
|
||||
|
||||
size_type find(basic_string_ref s) const {
|
||||
const_iterator iter = std::search ( this->cbegin (), this->cend (),
|
||||
s.cbegin (), s.cend (), traits::eq );
|
||||
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||
}
|
||||
|
||||
size_type find(charT c) const {
|
||||
const_iterator iter = std::find_if ( this->cbegin (), this->cend (),
|
||||
detail::string_ref_traits_eq<charT, traits> ( c ));
|
||||
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||
}
|
||||
|
||||
size_type rfind(basic_string_ref s) const {
|
||||
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
|
||||
s.crbegin (), s.crend (), traits::eq );
|
||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
||||
}
|
||||
|
||||
size_type rfind(charT c) const {
|
||||
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
|
||||
detail::string_ref_traits_eq<charT, traits> ( c ));
|
||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
||||
}
|
||||
|
||||
size_type find_first_of(charT c) const { return find (c); }
|
||||
size_type find_last_of (charT c) const { return rfind (c); }
|
||||
|
||||
size_type find_first_of(basic_string_ref s) const {
|
||||
const_iterator iter = std::find_first_of
|
||||
( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq );
|
||||
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||
}
|
||||
|
||||
size_type find_last_of(basic_string_ref s) const {
|
||||
const_reverse_iterator iter = std::find_first_of
|
||||
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
|
||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
|
||||
}
|
||||
|
||||
size_type find_first_not_of(basic_string_ref s) const {
|
||||
const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s );
|
||||
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
||||
}
|
||||
|
||||
size_type find_first_not_of(charT c) const {
|
||||
for ( const_iterator iter = this->cbegin (); iter != this->cend (); ++iter )
|
||||
if ( !traits::eq ( c, *iter ))
|
||||
return std::distance ( this->cbegin (), iter );
|
||||
return npos;
|
||||
}
|
||||
|
||||
size_type find_last_not_of(basic_string_ref s) const {
|
||||
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
|
||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
||||
}
|
||||
|
||||
size_type find_last_not_of(charT c) const {
|
||||
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
|
||||
if ( !traits::eq ( c, *iter ))
|
||||
return reverse_distance ( this->crbegin (), iter );
|
||||
return npos;
|
||||
}
|
||||
|
||||
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>
|
||||
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
|
||||
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 bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
if ( x.size () != y.size ()) return false;
|
||||
return x.compare(y) == 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x == basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) == y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator==(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x == basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator==(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) == y;
|
||||
}
|
||||
|
||||
// Inequality
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
if ( x.size () != y.size ()) return true;
|
||||
return x.compare(y) != 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x != basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) != y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator!=(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x != basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator!=(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) != y;
|
||||
}
|
||||
|
||||
// Less than
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
return x.compare(y) < 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x < basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) < y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x < basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) < y;
|
||||
}
|
||||
|
||||
// Greater than
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
return x.compare(y) > 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x > basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) > y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x > basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) > y;
|
||||
}
|
||||
|
||||
// Less than or equal to
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
return x.compare(y) <= 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x <= basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) <= y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<=(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x <= basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator<=(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) <= y;
|
||||
}
|
||||
|
||||
// Greater than or equal to
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
|
||||
return x.compare(y) >= 0;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
|
||||
return x >= basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits, typename Allocator>
|
||||
inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) >= y;
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>=(basic_string_ref<charT, traits> x, const charT * y) {
|
||||
return x >= basic_string_ref<charT, traits>(y);
|
||||
}
|
||||
|
||||
template<typename charT, typename traits>
|
||||
inline bool operator>=(const charT * x, basic_string_ref<charT, traits> y) {
|
||||
return basic_string_ref<charT, traits>(x) >= y;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline void 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 insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
||||
const std::size_t size = str.size();
|
||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
||||
if (!align_left) {
|
||||
detail::insert_fill_chars(os, alignment_size);
|
||||
if (os.good())
|
||||
os.write(str.data(), size);
|
||||
}
|
||||
else {
|
||||
os.write(str.data(), size);
|
||||
if (os.good())
|
||||
detail::insert_fill_chars(os, alignment_size);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Inserter
|
||||
template<class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>&
|
||||
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
||||
if (os.good()) {
|
||||
const std::size_t size = str.size();
|
||||
const std::size_t w = static_cast< std::size_t >(os.width());
|
||||
if (w <= size)
|
||||
os.write(str.data(), size);
|
||||
else
|
||||
detail::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_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoi ( std::string(str), idx, base );
|
||||
}
|
||||
|
||||
inline long stol (string_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stol ( std::string(str), idx, base );
|
||||
}
|
||||
|
||||
inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoul ( std::string(str), idx, base );
|
||||
}
|
||||
|
||||
inline long long stoll (string_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoll ( std::string(str), idx, base );
|
||||
}
|
||||
|
||||
inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoull ( std::string(str), idx, base );
|
||||
}
|
||||
|
||||
inline float stof (string_ref str, size_t* idx=0) {
|
||||
return std::stof ( std::string(str), idx );
|
||||
}
|
||||
|
||||
inline double stod (string_ref str, size_t* idx=0) {
|
||||
return std::stod ( std::string(str), idx );
|
||||
}
|
||||
|
||||
inline long double stold (string_ref str, size_t* idx=0) {
|
||||
return std::stold ( std::string(str), idx );
|
||||
}
|
||||
|
||||
inline int stoi (wstring_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoi ( std::wstring(str), idx, base );
|
||||
}
|
||||
|
||||
inline long stol (wstring_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stol ( std::wstring(str), idx, base );
|
||||
}
|
||||
|
||||
inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoul ( std::wstring(str), idx, base );
|
||||
}
|
||||
|
||||
inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoll ( std::wstring(str), idx, base );
|
||||
}
|
||||
|
||||
inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
|
||||
return std::stoull ( std::wstring(str), idx, base );
|
||||
}
|
||||
|
||||
inline float stof (wstring_ref str, size_t* idx=0) {
|
||||
return std::stof ( std::wstring(str), idx );
|
||||
}
|
||||
|
||||
inline double stod (wstring_ref str, size_t* idx=0) {
|
||||
return std::stod ( std::wstring(str), idx );
|
||||
}
|
||||
|
||||
inline long double stold (wstring_ref str, size_t* idx=0) {
|
||||
return std::stold ( std::wstring(str), idx );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
namespace std {
|
||||
// Hashing
|
||||
template<> struct hash<boost::string_ref>;
|
||||
template<> struct hash<boost::u16string_ref>;
|
||||
template<> struct hash<boost::u32string_ref>;
|
||||
template<> struct hash<boost::wstring_ref>;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BOOST_STRING_REF_FWD_HPP
|
||||
#define BOOST_STRING_REF_FWD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename charT, typename traits = std::char_traits<charT> > class basic_string_ref;
|
||||
typedef basic_string_ref<char, std::char_traits<char> > string_ref;
|
||||
typedef basic_string_ref<wchar_t, std::char_traits<wchar_t> > wstring_ref;
|
||||
|
||||
#ifndef BOOST_NO_CXX11_CHAR16_T
|
||||
typedef basic_string_ref<char16_t, std::char_traits<char16_t> > u16string_ref;
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_CHAR32_T
|
||||
typedef basic_string_ref<char32_t, std::char_traits<char32_t> > u32string_ref;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
16
index.html
16
index.html
@@ -14,30 +14,21 @@
|
||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||
<blockquote>
|
||||
<p>
|
||||
<a href="utility.htm#addressof">addressof</a><br>
|
||||
<a href="assert.html">assert</a><br>
|
||||
<a href="base_from_member.html">base_from_member</a><br>
|
||||
<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br>
|
||||
<a href="call_traits.htm">call_traits</a><br>
|
||||
<a href="checked_delete.html">checked_delete</a><br>
|
||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||
<a href="current_function.html">current_function</a><br>
|
||||
<a href="doc/html/declval.html">declval</a><br>
|
||||
<a href="enable_if.html">enable_if</a><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="utility.htm#Class_noncopyable">noncopyable</a><br>
|
||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||
<a href="operators.htm">operators</a><br>
|
||||
<a href="utility.htm#result_of">result_of</a><br>
|
||||
<a href="swap.html">swap</a><br>
|
||||
<a href="throw_exception.html">throw_exception</a><br>
|
||||
<a href="utility.htm">utility</a><br>
|
||||
<a href="doc/html/string_ref.html">string_ref</a><br>
|
||||
<a href="value_init.htm">value_init</a>
|
||||
<a href="doc/html/explicit_operator_bool.html">BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL</a><br>
|
||||
</p>
|
||||
<a href="value_init.htm">value_init</a></p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>© Copyright Beman Dawes, 2001</p>
|
||||
@@ -50,3 +41,4 @@
|
||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
@@ -8,11 +8,6 @@
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
alias unit_test_framework
|
||||
: # sources
|
||||
/boost//unit_test_framework
|
||||
;
|
||||
|
||||
# Please keep the tests ordered by filename
|
||||
test-suite utility
|
||||
:
|
||||
@@ -36,9 +31,6 @@ test-suite utility
|
||||
[ run ../ref_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 ]
|
||||
@@ -48,10 +40,5 @@ test-suite utility
|
||||
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||
[ run ../verify_test.cpp ]
|
||||
[ run explicit_operator_bool.cpp ]
|
||||
[ compile-fail explicit_operator_bool_compile_fail_conv_int.cpp ]
|
||||
[ compile-fail explicit_operator_bool_compile_fail_conv_pvoid.cpp ]
|
||||
[ compile-fail explicit_operator_bool_compile_fail_delete.cpp ]
|
||||
[ compile-fail explicit_operator_bool_compile_fail_shift.cpp ]
|
||||
;
|
||||
|
||||
|
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2010
|
||||
*
|
||||
* \brief This test checks that explicit operator bool can be used in
|
||||
* the valid contexts.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE explicit_operator_bool_compile
|
||||
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// A test object that has the operator of explicit conversion to bool
|
||||
struct checkable1
|
||||
{
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct checkable2
|
||||
{
|
||||
BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()
|
||||
BOOST_CONSTEXPR bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
checkable1 val1;
|
||||
if (val1)
|
||||
{
|
||||
checkable2 val2;
|
||||
if (val2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_conv_int.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2010
|
||||
*
|
||||
* \brief This test checks that explicit operator bool cannot be used in
|
||||
* an unintended context.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_int
|
||||
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// A test object that has the operator of explicit conversion to bool
|
||||
struct checkable
|
||||
{
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
checkable val;
|
||||
int n = val;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_conv_pvoid.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2010
|
||||
*
|
||||
* \brief This test checks that explicit operator bool cannot be used in
|
||||
* an unintended context.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_conv_pvoid
|
||||
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// A test object that has the operator of explicit conversion to bool
|
||||
struct checkable
|
||||
{
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
checkable val;
|
||||
void* p = val;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_delete.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2010
|
||||
*
|
||||
* \brief This test checks that explicit operator bool cannot be used in
|
||||
* an unintended context.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE util_explicit_operator_bool_delete
|
||||
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// A test object that has the operator of explicit conversion to bool
|
||||
struct checkable
|
||||
{
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
checkable val;
|
||||
delete val;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 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 explicit_operator_bool_compile_fail_shift.cpp
|
||||
* \author Andrey Semashev
|
||||
* \date 17.07.2010
|
||||
*
|
||||
* \brief This test checks that explicit operator bool cannot be used in
|
||||
* an unintended context.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE explicit_operator_bool_compile_fail_shift
|
||||
|
||||
#include <boost/utility/explicit_operator_bool.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
// A test object that has the operator of explicit conversion to bool
|
||||
struct checkable
|
||||
{
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
bool operator! () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
checkable val;
|
||||
val << 2;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -5,13 +5,7 @@
|
||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Examples:
|
||||
// To run the default test:
|
||||
// $ cd libs/utility/test && bjam
|
||||
// To test decltype on g++ 2.7:
|
||||
// $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE"
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#include <boost/utility/result_of.hpp>
|
||||
@@ -68,9 +62,6 @@ struct int_result_type_and_float_result_of_and_char_return_template
|
||||
char operator()(char);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct cv_overload_check {};
|
||||
|
||||
struct result_of_member_function_template
|
||||
{
|
||||
template<typename F> struct result;
|
||||
@@ -78,13 +69,13 @@ struct result_of_member_function_template
|
||||
template<typename This, typename That> struct result<This(That)> { typedef That type; };
|
||||
template<class T> typename result<result_of_member_function_template(T)>::type operator()(T);
|
||||
|
||||
template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; };
|
||||
template<typename This, typename That> struct result<const This(That)> { typedef const That type; };
|
||||
template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const;
|
||||
|
||||
template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; };
|
||||
template<typename This, typename That> struct result<volatile This(That)> { typedef volatile That type; };
|
||||
template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile;
|
||||
|
||||
template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; };
|
||||
template<typename This, typename That> struct result<const volatile This(That)> { typedef const volatile That type; };
|
||||
template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile;
|
||||
|
||||
template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; };
|
||||
@@ -100,17 +91,14 @@ struct result_of_member_function_template
|
||||
template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T);
|
||||
};
|
||||
|
||||
struct no_result_type_or_result
|
||||
struct no_result_type_or_result_of
|
||||
{
|
||||
short operator()(double);
|
||||
cv_overload_check<const short> operator()(double) const;
|
||||
cv_overload_check<volatile short> operator()(double) volatile;
|
||||
cv_overload_check<const volatile short> operator()(double) const volatile;
|
||||
int operator()();
|
||||
cv_overload_check<const int> operator()() const;
|
||||
cv_overload_check<volatile int> operator()() volatile;
|
||||
cv_overload_check<const volatile int> operator()() const volatile;
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
int operator()(double);
|
||||
short operator()(double) const;
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
@@ -118,44 +106,20 @@ struct no_result_type_or_result
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct no_result_type_or_result_template
|
||||
struct no_result_type_or_result_of_template
|
||||
{
|
||||
short operator()(double);
|
||||
cv_overload_check<const short> operator()(double) const;
|
||||
cv_overload_check<volatile short> operator()(double) volatile;
|
||||
cv_overload_check<const volatile short> operator()(double) const volatile;
|
||||
int operator()();
|
||||
cv_overload_check<const int> operator()() const;
|
||||
cv_overload_check<volatile int> operator()() volatile;
|
||||
cv_overload_check<const volatile int> operator()() const volatile;
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
int operator()(double);
|
||||
short operator()(double) const;
|
||||
unsigned int operator()();
|
||||
unsigned short operator()() volatile;
|
||||
const unsigned short operator()() const volatile;
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
short operator()(int&&);
|
||||
int operator()(int&);
|
||||
long operator()(int const&);
|
||||
#endif
|
||||
};
|
||||
|
||||
// sfinae_tests are derived from example code from Joel de Guzman,
|
||||
// which demonstrated the interaction between result_of and SFINAE.
|
||||
template <typename F, typename Arg>
|
||||
typename boost::result_of<F(Arg const&)>::type
|
||||
sfinae_test(F f, Arg const& arg)
|
||||
{
|
||||
return f(arg);
|
||||
}
|
||||
|
||||
template <typename F, typename Arg>
|
||||
typename boost::result_of<F(Arg&)>::type
|
||||
sfinae_test(F f, Arg& arg)
|
||||
{
|
||||
return f(arg);
|
||||
}
|
||||
|
||||
int sfinae_test_f(int& i)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
@@ -166,10 +130,6 @@ int main()
|
||||
typedef int (&func_ref)(float, double);
|
||||
typedef int (*func_ptr_0)();
|
||||
typedef int (&func_ref_0)();
|
||||
typedef void (*func_ptr_void)(float, double);
|
||||
typedef void (&func_ref_void)(float, double);
|
||||
typedef void (*func_ptr_void_0)();
|
||||
typedef void (&func_ref_void_0)();
|
||||
typedef int (X::*mem_func_ptr)(float);
|
||||
typedef int (X::*mem_func_ptr_c)(float) const;
|
||||
typedef int (X::*mem_func_ptr_v)(float) volatile;
|
||||
@@ -196,8 +156,8 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
|
||||
// Prior to decltype, result_of could not deduce the return type
|
||||
// of nullary function objects unless they exposed a result_type.
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
// nullary function objects unless they exposed a result_type.
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
|
||||
@@ -209,11 +169,14 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
|
||||
|
||||
// Prior to decltype, result_of ignored a nested result<> if
|
||||
// result_type was defined. After decltype, result_of deduces the
|
||||
// actual return type of the function object, ignoring both
|
||||
// result<> and result_type.
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
|
||||
#else
|
||||
@@ -221,52 +184,41 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
|
||||
#endif
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(void)>::type, int>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
|
||||
@@ -279,38 +231,26 @@ int main()
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
|
||||
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value));
|
||||
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, 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<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile 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));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value));
|
||||
#if !defined(BOOST_NO_DECLTYPE)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(void)>::type, unsigned int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of(double)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of(void)>::type, unsigned short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of(void)>::type, const unsigned short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(double)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(void)>::type, unsigned int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value));
|
||||
#if !defined(BOOST_NO_RVALUE_REFERENCES)
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(int const&)>::type, long>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&&)>::type, short>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int&)>::type, int>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(int const&)>::type, long>::value));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
int i = 123;
|
||||
sfinae_test(sfinae_test_f, i);
|
||||
#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
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_ref.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
typedef boost::string_ref string_ref;
|
||||
|
||||
// Should be equal
|
||||
void interop ( const std::string &str, string_ref ref ) {
|
||||
// BOOST_CHECK ( str == ref );
|
||||
BOOST_CHECK ( str.size () == ref.size ());
|
||||
BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ()));
|
||||
BOOST_CHECK ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
|
||||
}
|
||||
|
||||
void null_tests ( const char *p ) {
|
||||
// All zero-length string-refs should be equal
|
||||
string_ref sr1; // NULL, 0
|
||||
string_ref sr2 ( NULL, 0 );
|
||||
string_ref sr3 ( p, 0 );
|
||||
string_ref sr4 ( p );
|
||||
sr4.clear ();
|
||||
|
||||
BOOST_CHECK ( sr1 == sr2 );
|
||||
BOOST_CHECK ( sr1 == sr3 );
|
||||
BOOST_CHECK ( sr2 == sr3 );
|
||||
BOOST_CHECK ( sr1 == sr4 );
|
||||
}
|
||||
|
||||
// make sure that substrings work just like strings
|
||||
void test_substr ( const std::string &str ) {
|
||||
const size_t sz = str.size ();
|
||||
string_ref 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_ref 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
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_main )
|
||||
{
|
||||
const char **p = &test_strings[0];
|
||||
|
||||
while ( *p != NULL ) {
|
||||
interop ( *p, *p );
|
||||
test_substr ( *p );
|
||||
test_remove ( *p );
|
||||
null_tests ( *p );
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
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 <cstring> // for std::strchr
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
typedef boost::string_ref string_ref;
|
||||
|
||||
void ends_with ( const char *arg ) {
|
||||
const size_t sz = strlen ( arg );
|
||||
string_ref sr ( arg );
|
||||
string_ref sr2 ( arg );
|
||||
const char *p = arg;
|
||||
|
||||
while ( *p ) {
|
||||
BOOST_CHECK ( sr.ends_with ( p ));
|
||||
++p;
|
||||
}
|
||||
|
||||
while ( !sr2.empty ()) {
|
||||
BOOST_CHECK ( sr.ends_with ( sr2 ));
|
||||
sr2.remove_prefix (1);
|
||||
}
|
||||
|
||||
sr2 = arg;
|
||||
while ( !sr2.empty ()) {
|
||||
BOOST_CHECK ( sr.ends_with ( sr2 ));
|
||||
sr2.remove_prefix (1);
|
||||
}
|
||||
|
||||
char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
|
||||
sr2 = arg;
|
||||
if ( sz > 0 )
|
||||
BOOST_CHECK ( sr2.ends_with ( ch ));
|
||||
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
|
||||
BOOST_CHECK ( sr2.ends_with ( string_ref ()));
|
||||
}
|
||||
|
||||
void starts_with ( const char *arg ) {
|
||||
const size_t sz = strlen ( arg );
|
||||
string_ref sr ( arg );
|
||||
string_ref sr2 ( arg );
|
||||
const char *p = arg + std::strlen ( arg ) - 1;
|
||||
while ( p >= arg ) {
|
||||
std::string foo ( arg, p + 1 );
|
||||
BOOST_CHECK ( sr.starts_with ( foo ));
|
||||
--p;
|
||||
}
|
||||
|
||||
while ( !sr2.empty ()) {
|
||||
BOOST_CHECK ( sr.starts_with ( sr2 ));
|
||||
sr2.remove_suffix (1);
|
||||
}
|
||||
|
||||
char ch = *arg;
|
||||
sr2 = arg;
|
||||
if ( sz > 0 )
|
||||
BOOST_CHECK ( sr2.starts_with ( ch ));
|
||||
BOOST_CHECK ( !sr2.starts_with ( ++ch ));
|
||||
BOOST_CHECK ( sr2.starts_with ( string_ref ()));
|
||||
}
|
||||
|
||||
void reverse ( const char *arg ) {
|
||||
// Round trip
|
||||
string_ref sr1 ( arg );
|
||||
std::string string1 ( sr1.rbegin (), sr1.rend ());
|
||||
string_ref sr2 ( string1 );
|
||||
std::string string2 ( sr2.rbegin (), sr2.rend ());
|
||||
|
||||
BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
|
||||
BOOST_CHECK ( string2 == arg );
|
||||
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
||||
}
|
||||
|
||||
// This helper function eliminates signed vs. unsigned warnings
|
||||
string_ref::size_type ptr_diff ( const char *res, const char *base ) {
|
||||
BOOST_CHECK ( res >= base );
|
||||
return static_cast<string_ref::size_type> ( res - base );
|
||||
}
|
||||
|
||||
void find ( const char *arg ) {
|
||||
string_ref sr1;
|
||||
string_ref sr2;
|
||||
const char *p;
|
||||
|
||||
// Look for each character in the string(searching from the start)
|
||||
p = arg;
|
||||
sr1 = arg;
|
||||
while ( *p ) {
|
||||
string_ref::size_type pos = sr1.find(*p);
|
||||
BOOST_CHECK ( pos != string_ref::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_ref::size_type pos = sr1.rfind(*p);
|
||||
BOOST_CHECK ( pos != string_ref::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_ref sr3 ( p, 2 );
|
||||
string_ref::size_type pos = sr1.find ( sr3 );
|
||||
BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast<string_ref::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_ref::size_type pos = sr1.find(ch);
|
||||
const char *strp = std::strchr ( arg, ch );
|
||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
|
||||
if ( strp != NULL )
|
||||
BOOST_CHECK ( 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_ref::size_type pos = sr1.rfind(ch);
|
||||
const char *strp = std::strrchr ( arg, ch );
|
||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos ));
|
||||
if ( strp != NULL )
|
||||
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
||||
}
|
||||
|
||||
|
||||
// Find everything at the start
|
||||
p = arg;
|
||||
sr1 = arg;
|
||||
while ( !sr1.empty ()) {
|
||||
string_ref::size_type pos = sr1.find(*p);
|
||||
BOOST_CHECK ( pos == 0 );
|
||||
sr1.remove_prefix (1);
|
||||
++p;
|
||||
}
|
||||
|
||||
// Find everything at the end
|
||||
sr1 = arg;
|
||||
p = arg + strlen ( arg ) - 1;
|
||||
while ( !sr1.empty ()) {
|
||||
string_ref::size_type pos = sr1.rfind(*p);
|
||||
BOOST_CHECK ( pos == sr1.size () - 1 );
|
||||
sr1.remove_suffix (1);
|
||||
--p;
|
||||
}
|
||||
|
||||
// Find everything at the start
|
||||
sr1 = arg;
|
||||
p = arg;
|
||||
while ( !sr1.empty ()) {
|
||||
string_ref::size_type pos = sr1.find_first_of(*p);
|
||||
BOOST_CHECK ( pos == 0 );
|
||||
sr1.remove_prefix (1);
|
||||
++p;
|
||||
}
|
||||
|
||||
|
||||
// Find everything at the end
|
||||
sr1 = arg;
|
||||
p = arg + strlen ( arg ) - 1;
|
||||
while ( !sr1.empty ()) {
|
||||
string_ref::size_type pos = sr1.find_last_of(*p);
|
||||
BOOST_CHECK ( 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_CHECK ( sr1.find_first_of ( sr2 ) == 0 );
|
||||
BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
|
||||
sr1.remove_prefix ( 1 );
|
||||
}
|
||||
|
||||
p = arg;
|
||||
sr1 = arg;
|
||||
while ( *p ) {
|
||||
string_ref::size_type pos1 = sr1.find_first_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 ));
|
||||
if ( pos2 != string_ref::npos ) {
|
||||
for ( size_t i = 0 ; i < pos2; ++i )
|
||||
BOOST_CHECK ( sr1[i] == *p );
|
||||
BOOST_CHECK ( sr1 [ pos2 ] != *p );
|
||||
}
|
||||
|
||||
BOOST_CHECK ( pos2 != pos1 );
|
||||
++p;
|
||||
}
|
||||
|
||||
// Basic sanity checking for "find_last_of / find_last_not_of"
|
||||
sr1 = arg;
|
||||
sr2 = arg;
|
||||
while ( !sr1.empty() ) {
|
||||
BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
|
||||
BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
|
||||
sr1.remove_suffix ( 1 );
|
||||
}
|
||||
|
||||
p = arg;
|
||||
sr1 = arg;
|
||||
while ( *p ) {
|
||||
string_ref::size_type pos1 = sr1.find_last_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_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ());
|
||||
if ( pos2 != string_ref::npos ) {
|
||||
for ( size_t i = sr1.size () -1 ; i > pos2; --i )
|
||||
BOOST_CHECK ( sr1[i] == *p );
|
||||
BOOST_CHECK ( sr1 [ pos2 ] != *p );
|
||||
}
|
||||
|
||||
BOOST_CHECK ( pos2 != pos1 );
|
||||
++p;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void to_string ( const char *arg ) {
|
||||
string_ref sr1;
|
||||
std::string str1;
|
||||
std::string str2;
|
||||
|
||||
str1.assign ( arg );
|
||||
sr1 = arg;
|
||||
// str2 = sr1.to_string<std::allocator<char> > ();
|
||||
str2 = sr1.to_string ();
|
||||
BOOST_CHECK ( str1 == str2 );
|
||||
|
||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||
std::string str3 = static_cast<std::string> ( sr1 );
|
||||
BOOST_CHECK ( str1 == str3 );
|
||||
#endif
|
||||
}
|
||||
|
||||
void compare ( const char *arg ) {
|
||||
string_ref sr1;
|
||||
std::string str1;
|
||||
std::string str2 = str1;
|
||||
|
||||
str1.assign ( arg );
|
||||
sr1 = arg;
|
||||
BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref
|
||||
BOOST_CHECK ( sr1 == str1); // compare string and string_ref
|
||||
BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string
|
||||
BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer
|
||||
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref
|
||||
|
||||
if ( sr1.size () > 0 ) {
|
||||
(*str1.rbegin())++;
|
||||
BOOST_CHECK ( sr1 != str1 );
|
||||
BOOST_CHECK ( str1 != sr1 );
|
||||
BOOST_CHECK ( sr1 < str1 );
|
||||
BOOST_CHECK ( sr1 <= str1 );
|
||||
BOOST_CHECK ( str1 > sr1 );
|
||||
BOOST_CHECK ( str1 >= sr1 );
|
||||
|
||||
(*str1.rbegin()) -= 2;
|
||||
BOOST_CHECK ( sr1 != str1 );
|
||||
BOOST_CHECK ( str1 != sr1 );
|
||||
BOOST_CHECK ( sr1 > str1 );
|
||||
BOOST_CHECK ( sr1 >= str1 );
|
||||
BOOST_CHECK ( str1 < sr1 );
|
||||
BOOST_CHECK ( 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
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_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++;
|
||||
}
|
||||
}
|
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE string_ref_test_io
|
||||
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/mpl/vector.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.
|
||||
#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[] =
|
||||
{
|
||||
"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_ref 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
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||
|
||||
context< char_type > ctx;
|
||||
|
||||
ostream_type strm;
|
||||
strm << string_ref_type(ctx.abcd);
|
||||
BOOST_CHECK(strm.str() == ctx.abcd);
|
||||
}
|
||||
|
||||
// Test support for padding
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||
|
||||
context< char_type > ctx;
|
||||
|
||||
// Test for padding
|
||||
{
|
||||
ostream_type strm_ref;
|
||||
strm_ref << ctx.begin << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
|
||||
|
||||
ostream_type strm_correct;
|
||||
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
||||
|
||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||
}
|
||||
|
||||
// Test for long padding
|
||||
{
|
||||
ostream_type strm_ref;
|
||||
strm_ref << ctx.begin << std::setw(100) << string_ref_type(ctx.abcd) << ctx.end;
|
||||
|
||||
ostream_type strm_correct;
|
||||
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
||||
|
||||
BOOST_CHECK(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_ref_type(ctx.abcd) << ctx.end;
|
||||
|
||||
ostream_type strm_correct;
|
||||
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
||||
|
||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||
}
|
||||
}
|
||||
|
||||
// Test support for padding fill
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||
|
||||
context< char_type > ctx;
|
||||
|
||||
ostream_type strm_ref;
|
||||
strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_ref_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_CHECK(strm_ref.str() == strm_correct.str());
|
||||
}
|
||||
|
||||
// Test support for alignment
|
||||
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
||||
{
|
||||
typedef CharT char_type;
|
||||
typedef std::basic_string< char_type > string_type;
|
||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||
|
||||
context< char_type > ctx;
|
||||
|
||||
// Left alignment
|
||||
{
|
||||
ostream_type strm_ref;
|
||||
strm_ref << ctx.begin << std::left << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
|
||||
|
||||
ostream_type strm_correct;
|
||||
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
||||
|
||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||
}
|
||||
|
||||
// Right alignment
|
||||
{
|
||||
ostream_type strm_ref;
|
||||
strm_ref << ctx.begin << std::right << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
|
||||
|
||||
ostream_type strm_correct;
|
||||
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
||||
|
||||
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||
}
|
||||
}
|
438
utility.htm
438
utility.htm
@@ -84,10 +84,8 @@ const std::list<T>::iterator next = boost::next(prev, 2);</pre>
|
||||
will prevent the otherwise implicitly-generated functions (which don't have the
|
||||
proper semantics) from becoming a trap for other programmers.</p>
|
||||
<p>The traditional way to deal with these is to declare a private copy constructor
|
||||
and copy assignment, and then document why this is done. A new alternative
|
||||
was introduced in C++2011, declaring a copy constructor and a copy assignment
|
||||
operator, but marking both as <code>delete</code>d. Deriving
|
||||
from <b>noncopyable</b> is simpler and clearer, and doesn't require additional
|
||||
and copy assignment, and then document why this is done. But deriving
|
||||
from <b>noncopyable</b> is simpler and clearer, and doesn't require additional
|
||||
documentation.</p>
|
||||
<p>The program <a href="noncopyable_test.cpp">noncopyable_test.cpp</a> can be used
|
||||
to verify class <b>noncopyable</b> works as expected. It has have been run
|
||||
@@ -108,9 +106,7 @@ class ResourceLadenFileSystem : boost::noncopyable {
|
||||
about the effect on compiler optimization of adding (even trivial inline)
|
||||
destructor declarations. He says "Probably this concern is misplaced,
|
||||
because noncopyable will be used mostly for classes which own resources and
|
||||
thus have non-trivial destruction semantics." With C++2011, using an
|
||||
optimized and trivial constructor and similar destructor can be enforced by
|
||||
declaring both and marking them <code>default</code>.</p>
|
||||
thus have non-trivial destruction semantics."</p>
|
||||
<h2><a name="addressof">Function template addressof()</a></h2>
|
||||
<p>Function <strong>addressof()</strong> returns the address of an object.</p>
|
||||
<blockquote>
|
||||
@@ -147,7 +143,7 @@ void f() {
|
||||
<h2><a name="result_of">Class template
|
||||
result_of</a></h2> <p>The class template
|
||||
<code>result_of</code> helps determine the type of a
|
||||
call expression. For example, given an lvalue <code>f</code> of
|
||||
call expression. Given an lvalue <code>f</code> of
|
||||
type <code>F</code> and lvalues <code>t1</code>,
|
||||
<code>t2</code>, ..., <code>t<em>N</em></code> of
|
||||
types <code>T1</code>, <code>T2</code>, ...,
|
||||
@@ -159,24 +155,22 @@ void f() {
|
||||
the type <code>F</code> to be a function pointer,
|
||||
function reference, member function pointer, or class
|
||||
type. By default, <em>N</em> may be any value between 0 and
|
||||
16. To change the upper limit, define the macro
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>. Class template <code>result_of</code>
|
||||
resides in the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
|
||||
<p>If your compiler's support for <code>decltype</code> is
|
||||
adequate, <code>result_of</code> automatically uses it to
|
||||
deduce the type of the call expression, in which case
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> names the type
|
||||
<code>decltype(boost::declval<F>()(boost::declval<T1>(),
|
||||
boost::declval<T2>(), ...,
|
||||
boost::declval<T<em>N</em>>()))</code>, as in the
|
||||
following example.</p>
|
||||
<p>If your compiler supports <code>decltype</code>,
|
||||
then you can enable automatic result type deduction by
|
||||
defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>,
|
||||
as in the following example.</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
<pre>#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
struct functor {
|
||||
template<class T>
|
||||
T operator()(T x)
|
||||
{
|
||||
@@ -186,29 +180,21 @@ void f() {
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type; // type is int</pre>
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>You can test whether <code>result_of</code> is using
|
||||
<code>decltype</code> by checking if the macro
|
||||
<code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
|
||||
including <code>result_of.hpp</code>. You can also force
|
||||
<code>result_of</code> to use <code>decltype</code> by
|
||||
defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
|
||||
to including <code>result_of.hpp</code>.</p>
|
||||
|
||||
<p>If <code>decltype</code> is not used,
|
||||
<p>If <code>decltype</code> is not enabled,
|
||||
then automatic result type deduction of function
|
||||
objects is not possible. Instead, <code>result_of</code>
|
||||
uses the following protocol to allow the programmer to
|
||||
specify a type. When <code>F</code> is a class type with a
|
||||
member type <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> is
|
||||
T<em>N</em>)></code> is
|
||||
<code>F::result_type</code>. When <code>F</code> does
|
||||
not contain <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> is <code>F::result<F(T1,
|
||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||
T2, ..., T<em>N</em>)>::type</code> when
|
||||
<code><em>N</em> > 0</code> or <code>void</code>
|
||||
when <code><em>N</em> = 0</code>. Note that it is the
|
||||
@@ -235,69 +221,22 @@ typedef boost::result_of<
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type; // type is int</pre>
|
||||
>::type type;</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Since <code>decltype</code> is a new language
|
||||
feature recently standardized in C++11,
|
||||
if you are writing a function object
|
||||
to be used with <code>result_of</code>, for
|
||||
maximum portability, you might consider following
|
||||
the above protocol even if your compiler has
|
||||
proper <code>decltype</code> support. If you wish to continue to
|
||||
<p>In a future
|
||||
release, <code>BOOST_RESULT_OF_USE_DECLTYPE</code>
|
||||
may be enabled by default on compilers that
|
||||
support <code>decltype</code>, so if you use the above
|
||||
protocol please take care to ensure that
|
||||
the <code>result_type</code>
|
||||
and <code>result<></code> members accurately
|
||||
represent the result type. If you wish to continue to
|
||||
use the protocol on compilers that
|
||||
support <code>decltype</code>, there are two options:
|
||||
You can use <code>boost::tr1_result_of</code>, which is also
|
||||
defined in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.
|
||||
Alternatively, you can define the macro
|
||||
<code>BOOST_RESULT_OF_USE_TR1</code>, which causes
|
||||
<code>result_of</code> to use the protocol described
|
||||
above instead of <code>decltype</code>. If you choose to
|
||||
follow the protocol, take care to ensure that the
|
||||
<code>result_type</code> and
|
||||
<code>result<></code> members accurately
|
||||
represent the return type of
|
||||
<code>operator()</code> given a call expression.</p>
|
||||
|
||||
<p>Additionally, <code>boost::result_of</code>
|
||||
provides a third mode of operation, which some users
|
||||
may find convenient. When
|
||||
<code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
|
||||
is defined, <code>boost::result_of</code> behaves as
|
||||
follows. If the function object has a member
|
||||
type <code>result_type</code> or member
|
||||
template <code>result<></code>, then
|
||||
<code>boost::result_of</code> will use the TR1
|
||||
protocol. Otherwise,
|
||||
<code>boost::result_of</code> will
|
||||
use <code>decltype</code>. Using TR1 with
|
||||
a <code>declytpe</code> fallback may workaround
|
||||
certain problems at the cost of portability. For
|
||||
example:
|
||||
<ul>
|
||||
<li>Deficient compiler: If your code
|
||||
requires <code>boost::result_of</code> to work
|
||||
with incomplete return types but your
|
||||
compiler's <code>decltype</code> implementation
|
||||
does not support incomplete return types, then you
|
||||
can use the TR1 protocol as a workaround. Support
|
||||
for incomplete return types was added late in the
|
||||
C++11 standardization process
|
||||
(see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">N3276</a>)
|
||||
and is not implemented by some compilers.</li>
|
||||
|
||||
<li>Deficient legacy code: If your existing TR1
|
||||
function object advertises a different type than
|
||||
the actual result type deduced
|
||||
by <code>decltype</code>, then using TR1 with a
|
||||
<code>decltype</code> fallback will allow you to
|
||||
work with both your existing TR1 function objects
|
||||
and new C++11 function object. This situation
|
||||
could occur if your legacy function objects
|
||||
misused the TR1 protocol. See the documentation on
|
||||
known <a href="#result_of_tr1_diff">differences</a>
|
||||
between <code>boost::result_of</code> and TR1.</li>
|
||||
</ul>
|
||||
support <code>decltype</code>,
|
||||
use <code>boost::tr1_result_of</code>, which is also
|
||||
defined
|
||||
in <code><<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p>
|
||||
|
||||
<a name="BOOST_NO_RESULT_OF"></a>
|
||||
<p>This implementation of <code>result_of</code>
|
||||
@@ -314,322 +253,7 @@ typedef boost::result_of<
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
||||
or, for motivation and design rationale,
|
||||
the <code>result_of</code> <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
||||
|
||||
<a name="result_of_guidelines">
|
||||
<h3>Usage guidelines for boost::result_of</h3>
|
||||
</a>
|
||||
|
||||
<p>The following are general suggestions about when
|
||||
and how to use <code>boost::result_of</code>.</p>
|
||||
|
||||
<ol>
|
||||
<li> If you are targeting C++11 and are not concerned
|
||||
about portability to non-compliant compilers or
|
||||
previous versions of the standard, then use
|
||||
<code>std::result_of</code>. If <code>std::result_of</code>
|
||||
meets your needs, then there's no reason to stop using
|
||||
it.</li>
|
||||
|
||||
<li> If you are targeting C++11 but may port your code
|
||||
to legacy compilers at some time in the future, then
|
||||
use <code>boost::result_of</code> with
|
||||
<code>decltype</code>. When <code>decltype</code> is
|
||||
used <code>boost::result_of</code>
|
||||
and <code>std::result_of</code> are usually
|
||||
interchangeable. See the documentation on
|
||||
known <a href="#result_of_cxx11_diff">differences</a>
|
||||
between boost::result_of and C++11 result_of.</li>
|
||||
|
||||
<li> If compiler portability is required,
|
||||
use <code>boost::result_of</code> with the TR1 protocol.</li>
|
||||
</ol>
|
||||
|
||||
<p>Regardless of how you
|
||||
configure <code>boost::result_of</code>, it is
|
||||
important to bear in mind that the return type of a
|
||||
function may change depending on its arguments, and
|
||||
additionally, the return type of a member function may
|
||||
change depending on the cv-qualification of the
|
||||
object. <code>boost::result_of</code> must be passed
|
||||
the appropriately cv-qualified types in order to
|
||||
deduce the corresponding return type. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
int& operator()(int);
|
||||
int const& operator()(int) const;
|
||||
|
||||
float& operator()(float&);
|
||||
float const& operator()(float const&);
|
||||
};
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(int)
|
||||
>::type type1; // type1 is int &
|
||||
|
||||
typedef boost::result_of<
|
||||
const functor(int)
|
||||
>::type type2; // type2 is int const &
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(float&)
|
||||
>::type type3; // type3 is float &
|
||||
|
||||
typedef boost::result_of<
|
||||
functor(float const&)
|
||||
>::type type4; // type4 is float const &</pre>
|
||||
</blockquote>
|
||||
|
||||
<a name="result_of_tr1_protocol_guidelines">
|
||||
<h3>Usage guidelines for the TR1 result_of protocol</h3>
|
||||
</a>
|
||||
|
||||
<p>On compliant C++11
|
||||
compilers, <code>boost::result_of</code> can
|
||||
use <code>decltype</code> to deduce the type of any
|
||||
call expression, including calls to function
|
||||
objects. However, on pre-C++11 compilers or on
|
||||
compilers without adequate decltype support,
|
||||
additional scaffolding is needed from function
|
||||
objects as described above. The following are
|
||||
suggestions about how to use the TR1 protocol.</p>
|
||||
|
||||
<ul>
|
||||
<li>When the return type does not depend on the
|
||||
argument types or the cv-qualification of the
|
||||
function object, simply
|
||||
define <code>result_type</code>. There is no need
|
||||
to use the <code>result</code> template unless the
|
||||
return type varies.</li>
|
||||
|
||||
<li>Use the protocol specified type when defining
|
||||
function prototypes. This can help ensure the
|
||||
actual return type does not get out of sync with
|
||||
the protocol specification. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
typedef int result_type;
|
||||
result_type operator()(int);
|
||||
};</pre>
|
||||
</blockquote> </li>
|
||||
|
||||
<li>Always specify the <code>result</code>
|
||||
specialization near the corresponding
|
||||
<code>operator()</code> overload. This can make it
|
||||
easier to keep the specializations in sync with the
|
||||
overloads. For example:
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result;
|
||||
|
||||
template<class F>
|
||||
struct result<F(int)> {
|
||||
typedef int& type;
|
||||
};
|
||||
result<functor(int)>::type operator()(int);
|
||||
|
||||
template<class F>
|
||||
struct result<const F(int)> {
|
||||
typedef int const& type;
|
||||
};
|
||||
result<const functor(int)>::type operator()(int) const;
|
||||
};</pre>
|
||||
</blockquote> </li>
|
||||
|
||||
<li>Use type transformations to simplify
|
||||
the <code>result</code> template specialization. For
|
||||
example, the following uses
|
||||
<a href="../type_traits/doc/html/index.html">Boost.TypeTraits</a>
|
||||
to specialize the <code>result</code> template for
|
||||
a single <code>operator()</code> that can be called on
|
||||
both a const and non-const function object with
|
||||
either an lvalue or rvalue argument.
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result;
|
||||
|
||||
template<class F, class T>
|
||||
struct result<F(T)>
|
||||
: boost::remove_cv<
|
||||
typename boost::remove_reference<T>::type
|
||||
>
|
||||
{};
|
||||
|
||||
template<class T>
|
||||
T operator()(T const& x) const;
|
||||
};</pre>
|
||||
</blockquote></li>
|
||||
</ul>
|
||||
|
||||
<a name="result_of_tr1_diff">
|
||||
<h3>Known differences between boost::result_of and TR1 result_of</h3>
|
||||
</a>
|
||||
|
||||
When using <code>decltype</code>, <code>boost::result_of</code>
|
||||
ignores the TR1 protocol and instead deduces the
|
||||
return type of function objects directly
|
||||
via <code>decltype</code>. In most situations, users
|
||||
will not notice a difference, so long as they use the
|
||||
protocol correctly. The following are situations in
|
||||
which the type deduced
|
||||
by <code>boost::result_of</code> is known to differ depending on
|
||||
whether <code>decltype</code> or the TR1 protocol is
|
||||
used.
|
||||
|
||||
<ul>
|
||||
<li> TR1 protocol misusage
|
||||
|
||||
<p>When using the TR1
|
||||
protocol, <code>boost::result_of</code> cannot
|
||||
detect whether the actual type of a call to a
|
||||
function object is the same as the type specified
|
||||
by the protocol, which allows for the possibility
|
||||
of inadvertent mismatches between the specified
|
||||
type and the actual type. When
|
||||
using <code>decltype</code>, these subtle bugs
|
||||
may result in compilation errors. For example:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
typedef short result_type;
|
||||
int operator()(short);
|
||||
};
|
||||
|
||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<boost::result_of<functor(short)>::type, int>::value
|
||||
));
|
||||
|
||||
#else
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<boost::result_of<functor(short)>::type, short>::value
|
||||
));
|
||||
|
||||
#endif</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Note that the user can
|
||||
force <code>boost::result_of</code> to use the TR1
|
||||
protocol even on platforms that
|
||||
support <code>decltype</code> by
|
||||
defining <code>BOOST_RESULT_OF_USE_TR1</code>.</p></li>
|
||||
|
||||
<li> Nullary function objects
|
||||
|
||||
<p>When using the TR1 protocol, <code>boost::result_of</code>
|
||||
cannot always deduce the type of calls to
|
||||
nullary function objects, in which case the
|
||||
type defaults to void. When using <code>decltype</code>,
|
||||
<code>boost::result_of</code> always gives the actual type of the
|
||||
call expression. For example:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result {
|
||||
typedef int type;
|
||||
};
|
||||
int operator()();
|
||||
};
|
||||
|
||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<boost::result_of<functor()>::type, int>::value
|
||||
));
|
||||
|
||||
#else
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<boost::result_of<functor()>::type, void>::value
|
||||
));
|
||||
|
||||
#endif</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>Note that there are some workarounds for the
|
||||
nullary function problem. So long as the return
|
||||
type does not vary,
|
||||
<code>result_type</code> can always be used to
|
||||
specify the return type regardless of arity. If the
|
||||
return type does vary, then the user can
|
||||
specialize <code>boost::result_of</code> itself for
|
||||
nullary calls.</p></li>
|
||||
|
||||
<li> Non-class prvalues and cv-qualification
|
||||
|
||||
<p>When using the TR1
|
||||
protocol, <code>boost::result_of</code> will
|
||||
report the cv-qualified type specified
|
||||
by <code>result_type</code> or
|
||||
the <code>result</code> template regardless of
|
||||
the actual cv-qualification of the call
|
||||
expression. When using
|
||||
<code>decltype</code>, <code>boost::result_of</code>
|
||||
will report the actual type of the call expression,
|
||||
which is not cv-qualified when the expression is a
|
||||
non-class prvalue. For example:</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>struct functor {
|
||||
template<class> struct result;
|
||||
template<class F, class T> struct result<F(const T)> {
|
||||
typedef const T type;
|
||||
};
|
||||
|
||||
const short operator()(const short);
|
||||
int const & operator()(int const &);
|
||||
};
|
||||
|
||||
// Non-prvalue call expressions work the same with or without decltype.
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::result_of<functor(int const &)>::type,
|
||||
int const &
|
||||
::value
|
||||
));
|
||||
|
||||
// Non-class prvalue call expressions are not actually cv-qualified,
|
||||
// but only the decltype-based result_of reports this accurately.
|
||||
|
||||
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::result_of<functor(const short)>::type,
|
||||
short
|
||||
::value
|
||||
));
|
||||
|
||||
#else
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<
|
||||
boost::result_of<functor(const short)>::type,
|
||||
const short
|
||||
::value
|
||||
));
|
||||
|
||||
#endif</pre>
|
||||
</blockquote></li>
|
||||
</ul>
|
||||
|
||||
<a name="result_of_cxx11_diff">
|
||||
<h3>Known differences between boost::result_of and C++11 result_of</h3>
|
||||
</a>
|
||||
|
||||
<p>When using <code>decltype</code>, <code>boost::result_of</code>
|
||||
implements most of the C++11 result_of
|
||||
specification. One known exception is that
|
||||
<code>boost::result_of</code> does not implement the
|
||||
requirements regarding pointers to member data.</p>
|
||||
|
||||
<p>Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others</p>
|
||||
Contributed by Doug Gregor.</p>
|
||||
|
||||
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||
|
@@ -295,7 +295,7 @@ so for those compilers that need to have such a workaround, based on the
|
||||
<br> operator T&() { return x ; }
|
||||
<br> T const &data() const { return x ; }
|
||||
<br> T& data() { return x ; }
|
||||
<br> void swap( value_initialized& );
|
||||
<br> void swap( value_initialized<T>& );
|
||||
<br>
|
||||
<br> private :
|
||||
<br> <i>unspecified</i> x ;
|
||||
@@ -313,12 +313,6 @@ so for those compilers that need to have such a workaround, based on the
|
||||
<br> return x.data() ;
|
||||
<br>}
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>void swap ( value_initialized<T>& lhs, value_initialized<T>& rhs )
|
||||
<br>{
|
||||
<br> lhs.swap(rhs) ;
|
||||
<br>}
|
||||
<br>
|
||||
<br>} // namespace boost
|
||||
<br></pre>
|
||||
|
||||
@@ -391,7 +385,7 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
||||
<br> operator T&();
|
||||
<br> T const &data() const;
|
||||
<br> T& data();
|
||||
<br> void swap( initialized& );
|
||||
<br> void swap( value_initialized<T>& );
|
||||
<br>
|
||||
<br> private :
|
||||
<br> <i>unspecified</i> x ;
|
||||
@@ -403,9 +397,6 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p>
|
||||
<br>template<class T>
|
||||
<br>T& get ( initialized<T>& x );
|
||||
<br>
|
||||
<br>template<class T>
|
||||
<br>void swap ( initialized<T>& lhs, initialized<T>& rhs );
|
||||
<br>
|
||||
<br>} // namespace boost
|
||||
<br></pre>
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
//
|
||||
// Sample POD type
|
||||
@@ -215,7 +215,7 @@ template<class T>
|
||||
void check_initialized_value ( T const& y )
|
||||
{
|
||||
T initializedValue = boost::initialized_value ;
|
||||
BOOST_TEST ( y == initializedValue ) ;
|
||||
BOOST_CHECK ( y == initializedValue ) ;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
@@ -245,125 +245,128 @@ void check_initialized_value( NonPOD const& )
|
||||
template<class T>
|
||||
bool test ( T const& y, T const& z )
|
||||
{
|
||||
const int errors_before_test = boost::detail::test_errors();
|
||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||
|
||||
check_initialized_value(y);
|
||||
|
||||
boost::value_initialized<T> x ;
|
||||
BOOST_TEST ( y == x ) ;
|
||||
BOOST_TEST ( y == boost::get(x) ) ;
|
||||
BOOST_CHECK ( y == x ) ;
|
||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||
|
||||
static_cast<T&>(x) = z ;
|
||||
boost::get(x) = z ;
|
||||
BOOST_TEST ( x == z ) ;
|
||||
BOOST_CHECK ( x == z ) ;
|
||||
|
||||
boost::value_initialized<T> const x_c ;
|
||||
BOOST_TEST ( y == x_c ) ;
|
||||
BOOST_TEST ( y == boost::get(x_c) ) ;
|
||||
BOOST_CHECK ( y == x_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||
x_c_ref = z ;
|
||||
BOOST_TEST ( x_c == z ) ;
|
||||
BOOST_CHECK ( x_c == z ) ;
|
||||
|
||||
boost::value_initialized<T> const copy1 = x;
|
||||
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
||||
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
||||
|
||||
boost::value_initialized<T> copy2;
|
||||
copy2 = x;
|
||||
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
||||
|
||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||
BOOST_TEST ( y == *ptr ) ;
|
||||
BOOST_CHECK ( y == *ptr ) ;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
boost::value_initialized<T const> cx ;
|
||||
BOOST_TEST ( y == cx ) ;
|
||||
BOOST_TEST ( y == boost::get(cx) ) ;
|
||||
BOOST_CHECK ( y == cx ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
||||
|
||||
boost::value_initialized<T const> const cx_c ;
|
||||
BOOST_TEST ( y == cx_c ) ;
|
||||
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
||||
BOOST_CHECK ( y == cx_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
||||
#endif
|
||||
|
||||
return boost::detail::test_errors() == errors_before_test ;
|
||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||
}
|
||||
|
||||
int main(int, char **)
|
||||
int test_main(int, char **)
|
||||
{
|
||||
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||
|
||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||
|
||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||
|
||||
StringAndInt stringAndInt0;
|
||||
StringAndInt stringAndInt1;
|
||||
stringAndInt0.i = 0;
|
||||
stringAndInt1.i = 1;
|
||||
stringAndInt1.s = std::string("1");
|
||||
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
||||
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
||||
|
||||
StructWithDestructor structWithDestructor0;
|
||||
StructWithDestructor structWithDestructor1;
|
||||
structWithDestructor0.i = 0;
|
||||
structWithDestructor1.i = 1;
|
||||
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
||||
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
||||
|
||||
StructWithVirtualFunction structWithVirtualFunction0;
|
||||
StructWithVirtualFunction structWithVirtualFunction1;
|
||||
structWithVirtualFunction0.i = 0;
|
||||
structWithVirtualFunction1.i = 1;
|
||||
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||
|
||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||
|
||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
||||
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||
get(swapFunctionCallTester1).data = 1;
|
||||
get(swapFunctionCallTester2).data = 2;
|
||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
||||
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||
|
||||
return boost::report_errors();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user