forked from boostorg/utility
Compare commits
27 Commits
string_vie
...
boost-1.62
Author | SHA1 | Date | |
---|---|---|---|
|
febca584d9 | ||
|
21dc552cf9 | ||
|
fda210f597 | ||
|
3d853b0e83 | ||
|
4814d1ebfe | ||
|
e5932ebb08 | ||
|
93a2e25092 | ||
|
39577f86d1 | ||
|
8392991c46 | ||
|
c5b1256650 | ||
|
c56dd13592 | ||
|
181f302ee4 | ||
|
287844fe76 | ||
|
3982b6d633 | ||
|
0b492bee9c | ||
|
a9236d00a9 | ||
|
4313bfc323 | ||
|
f61c94e812 | ||
|
1dfacff7ec | ||
|
a25ac4550b | ||
|
d767054a79 | ||
|
08a1b7da61 | ||
|
8ab8e36dcf | ||
|
1caa745dd7 | ||
|
cf5ad341ed | ||
|
1f6de83fe2 | ||
|
cb6500161b |
@@ -117,22 +117,3 @@ boostbook standalone_string_ref
|
|||||||
# How far down we go with TOC's
|
# How far down we go with TOC's
|
||||||
<xsl:param>generate.section.toc.level=1
|
<xsl:param>generate.section.toc.level=1
|
||||||
;
|
;
|
||||||
|
|
||||||
xml string_view : string_view.qbk ;
|
|
||||||
boostbook standalone_string_view
|
|
||||||
:
|
|
||||||
string_view
|
|
||||||
:
|
|
||||||
# File name of HTML output:
|
|
||||||
<xsl:param>root.filename=string_view
|
|
||||||
# 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,381 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
||||||
<title>String_View</title>
|
|
||||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
|
||||||
<meta name="generator" content="DocBook XSL Stylesheets V1.77.1">
|
|
||||||
<link rel="home" href="string_view.html" title="String_View">
|
|
||||||
</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_view"></a>String_View</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 class="author"><h3 class="author">
|
|
||||||
<span class="firstname">Beman</span> <span class="surname">Dawes</span>
|
|
||||||
</h3></div>
|
|
||||||
</div></div>
|
|
||||||
<div><p class="copyright">Copyright © 2012 Marshall Clow</p></div>
|
|
||||||
<div><p class="copyright">Copyright © 2015 Beman Dawes</p></div>
|
|
||||||
<div><div class="legalnotice">
|
|
||||||
<a name="string_view.legal"></a><p>
|
|
||||||
Distributed under the Boost Software License, Version 1.0. <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_view.html#string_view.overview">Overview</a></span></dt>
|
|
||||||
<dt><span class="section"><a href="string_view.html#string_view.examples">Examples</a></span></dt>
|
|
||||||
<dt><span class="section"><a href="string_view.html#string_view.reference">Reference </a></span></dt>
|
|
||||||
<dt><span class="section"><a href="string_view.html#string_view.compiler_support">Compiler Support</a></span></dt>
|
|
||||||
<dt><span class="section"><a href="string_view.html#string_view.history">History</a></span></dt>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
||||||
<a name="string_view.overview"></a><a class="link" href="string_view.html#string_view.overview" title="Overview">Overview</a>
|
|
||||||
</h2></div></div></div>
|
|
||||||
<p>
|
|
||||||
Boost.StringView is an implementation of <code class="computeroutput"><span class="identifier">string_view</span></code>
|
|
||||||
as specified in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#string.view" target="_top">N4480:
|
|
||||||
ISO/IEC DTS 19568, Technical Specification - C++ Extensions for Library Fundamentals</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_view</span></code> is designed to
|
|
||||||
solve these efficiency problems. A <code class="computeroutput"><span class="identifier">string_view</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_view</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_view</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_view</span></code>
|
|
||||||
is cheap to create and cheap to copy.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code class="computeroutput"><span class="identifier">string_view</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_view</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_view</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_view</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_view</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_view</span></code> refers to exists as long as the
|
|
||||||
<code class="computeroutput"><span class="identifier">string_view</span></code> does.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Note: The header actually contains a class template, <code class="computeroutput"><span class="identifier">basic_string_view</span></code>
|
|
||||||
and four typedefs:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">charT</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">traits</span> <span class="special">=</span> <span class="identifier">char_traits</span><span class="special"><</span><span class="identifier">charT</span><span class="special">>></span>
|
|
||||||
<span class="keyword">class</span> <span class="identifier">basic_string_view</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">basic_string_view</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="identifier">string_view</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">basic_string_view</span><span class="special"><</span><span class="keyword">char16_t</span><span class="special">></span> <span class="identifier">u16string_view</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">basic_string_view</span><span class="special"><</span><span class="keyword">char32_t</span><span class="special">></span> <span class="identifier">u32string_view</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">basic_string_view</span><span class="special"><</span><span class="keyword">wchar_t</span><span class="special">></span> <span class="identifier">wstring_view</span><span class="special">;</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
So you can have views of strings of any of the four built-in character types
|
|
||||||
as well as strings of user-defined character-like type strings. For the sake
|
|
||||||
of simple exposition, we concentrate on <code class="computeroutput"><span class="identifier">string_view</span></code>
|
|
||||||
(i.e. <code class="computeroutput"><span class="keyword">char</span></code> strings) in this documentation.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
||||||
<a name="string_view.examples"></a><a class="link" href="string_view.html#string_view.examples" title="Examples">Examples</a>
|
|
||||||
</h2></div></div></div>
|
|
||||||
<p>
|
|
||||||
Integrating <code class="computeroutput"><span class="identifier">string_view</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_view</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="char">'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_view</span></code>:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_view</span> <span class="identifier">extract_part</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">string_view</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_view</span></code>s
|
|
||||||
created, and two <code class="computeroutput"><span class="identifier">string_view</span></code>s
|
|
||||||
copied, but those are cheap operations.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
||||||
<a name="string_view.reference"></a><a class="link" href="string_view.html#string_view.reference" title="Reference">Reference </a>
|
|
||||||
</h2></div></div></div>
|
|
||||||
<p>
|
|
||||||
The header file "string_view.hpp" defines a class template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">basic_string_view</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="keyword">char16_t</span></code>
|
|
||||||
/ <code class="computeroutput"><span class="keyword">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_view</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Types:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">traits</span> <span class="identifier">traits_type</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">charT</span> <span class="identifier">value_type</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">pointer</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">const_pointer</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">reference</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="keyword">const</span> <span class="identifier">charT</span><span class="special">&</span> <span class="identifier">const_reference</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">const_pointer</span> <span class="identifier">const_iterator</span><span class="special">;</span> <span class="comment">// implementation defined</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">const_iterator</span> <span class="identifier">iterator</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse_iterator</span><span class="special"><</span><span class="identifier">const_iterator</span><span class="special">></span> <span class="identifier">const_reverse_iterator</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">const_reverse_iterator</span> <span class="identifier">reverse_iterator</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size_type</span><span class="special">;</span>
|
|
||||||
<span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">difference_type</span><span class="special">;</span>
|
|
||||||
<span class="keyword">static</span> <span class="identifier">BOOST_CONSTEXPR_OR_CONST</span> <span class="identifier">size_type</span> <span class="identifier">npos</span> <span class="special">=</span> <span class="identifier">size_type</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
Construction and copying:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_view</span> <span class="special">()</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span> <span class="comment">// Constructs empty string_view</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_view</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">basic_string_view</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">basic_string_view</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="identifier">basic_string_view</span> <span class="special">&</span><span class="identifier">rhs</span><span class="special">)</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</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_view</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="identifier">BOOST_NOEXCEPT</span><span class="special">;</span> <span class="comment">// Ctor from std::string</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_view</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">// Ctor from NULL-terminated string</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="identifier">basic_string_view</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">// Ctor from pointer, length pair</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
<code class="computeroutput"><span class="identifier">string_view</span></code> does not define
|
|
||||||
a move constructor or a move-assignment operator because copying a <code class="computeroutput"><span class="identifier">string_view</span></code> is just as cheap as moving one
|
|
||||||
would be.
|
|
||||||
</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_NOEXCEPT</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="identifier">BOOST_CONSTEXPR</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="identifier">BOOST_NOEXCEPT</span> <span class="special">;</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
Modifying the <code class="computeroutput"><span class="identifier">string_view</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="comment">// boost extension</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">BOOST_CXX14_CONSTEXPR</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>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">basic_string_view</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
Searching:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">rfind</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</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="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</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="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_first_not_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</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="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">npos</span><span class="special">)</span> <span class="keyword">const</span> <span class="identifier">BOOST_NOEXCEPT</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</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="keyword">const</span><span class="special">;</span>
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">size_type</span> <span class="identifier">find_last_not_of</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</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="identifier">BOOST_CONSTEXPR</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="comment">// boost extension</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">bool</span> <span class="identifier">starts_with</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <span class="comment">// boost extension</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</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="comment">// boost extension</span>
|
|
||||||
<span class="identifier">BOOST_CONSTEXPR</span> <span class="keyword">bool</span> <span class="identifier">ends_with</span><span class="special">(</span><span class="identifier">basic_string_view</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <span class="comment">// boost extension</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
String-like operations:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">></span> <span class="comment">// Only present if compiler supports C++11 explicit conversion</span>
|
|
||||||
<span class="keyword">explicit</span> <span class="keyword">operator</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="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Allocator</span> <span class="special">=</span> <span class="identifier">allocator</span><span class="special"><</span><span class="identifier">charT</span><span class="special">></span> <span class="special">></span> <span class="comment">// Default only present if compiler supports</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="comment">// C++11 default template parameters</span>
|
|
||||||
<span class="identifier">to_string</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">Allocator</span><span class="special">&</span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">())</span> <span class="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="identifier">size_type</span> <span class="identifier">copy</span><span class="special">(</span><span class="identifier">charT</span><span class="special">*</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">n</span><span class="special">,</span> <span class="identifier">size_type</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
||||||
|
|
||||||
<span class="identifier">BOOST_CXX14_CONSTEXPR</span> <span class="identifier">basic_string_view</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">// Create new string_view</span>
|
|
||||||
</pre>
|
|
||||||
<p>
|
|
||||||
Comparison:
|
|
||||||
</p>
|
|
||||||
<pre class="programlisting"><span class="identifier">To</span> <span class="identifier">be</span> <span class="identifier">supplied</span>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
||||||
<a name="string_view.compiler_support"></a><a class="link" href="string_view.html#string_view.compiler_support" title="Compiler Support">Compiler Support</a>
|
|
||||||
</h2></div></div></div>
|
|
||||||
<p>
|
|
||||||
This Boost implementation only requires a C++03 compliant compiler.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The actual Library Fundamentals specification assumes a C++14 compliant compiler,
|
|
||||||
so a few features are only present if actually supported by the compiler. Boost
|
|
||||||
macros such as BOOST_CONSTEXPR, BOOST_CXX14_CONSTEXPR, and BOOST_NOEXCEPT supply
|
|
||||||
certain features if supported by the compiler.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
||||||
<a name="string_view.history"></a><a class="link" href="string_view.html#string_view.history" title="History">History</a>
|
|
||||||
</h2></div></div></div>
|
|
||||||
<h4>
|
|
||||||
<a name="string_view.history.h0"></a>
|
|
||||||
<span class="phrase"><a name="string_view.history.boost_1_53"></a></span><a class="link" href="string_view.html#string_view.history.boost_1_53">boost
|
|
||||||
1.53</a>
|
|
||||||
</h4>
|
|
||||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
|
||||||
Introduced, based on 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>
|
|
||||||
</li></ul></div>
|
|
||||||
<h4>
|
|
||||||
<a name="string_view.history.h1"></a>
|
|
||||||
<span class="phrase"><a name="string_view.history.boost_1_60"></a></span><a class="link" href="string_view.html#string_view.history.boost_1_60">boost
|
|
||||||
1.60</a>
|
|
||||||
</h4>
|
|
||||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
|
||||||
Updated to reflect <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#string.view" target="_top">N4480:
|
|
||||||
ISO/IEC DTS 19568, Technical Specification - C++ Extensions for Library
|
|
||||||
Fundamentals</a>
|
|
||||||
</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: July 17, 2015 at 19:19:23 GMT</small></p></td>
|
|
||||||
<td align="right"><div class="copyright-footer"></div></td>
|
|
||||||
</tr></table>
|
|
||||||
<hr>
|
|
||||||
<div class="spirit-nav"></div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@@ -1,243 +0,0 @@
|
|||||||
[/
|
|
||||||
/ Copyright (c) 2012 Marshall Clow
|
|
||||||
/ Copyright (c) 2015 Beman Dawes
|
|
||||||
/
|
|
||||||
/ 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_View
|
|
||||||
[quickbook 1.5]
|
|
||||||
[authors [Clow, Marshall] [Dawes, Beman]]
|
|
||||||
[copyright 2012 Marshall Clow, 2015 Beman Dawes]
|
|
||||||
[license
|
|
||||||
Distributed under the Boost Software License, Version 1.0.
|
|
||||||
[@http://www.boost.org/LICENSE_1_0.txt]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
[/===============]
|
|
||||||
[section Overview]
|
|
||||||
[/===============]
|
|
||||||
|
|
||||||
Boost.StringView is an implementation of `string_view` as specified in [@
|
|
||||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#string.view N4480:
|
|
||||||
ISO/IEC DTS 19568, Technical Specification - C++ Extensions for Library Fundamentals].
|
|
||||||
|
|
||||||
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_view` is designed to solve these efficiency problems. A `string_view` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_view` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to.
|
|
||||||
|
|
||||||
A `string_view` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_view` is cheap to create and cheap to copy.
|
|
||||||
|
|
||||||
`string_view` 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_view` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_view`. Like `std::string`, `string_view` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end".
|
|
||||||
|
|
||||||
Because a `string_view` 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_view` refers to exists as long as the `string_view` does.
|
|
||||||
|
|
||||||
Note: The header actually contains a class template, `basic_string_view` and four typedefs:
|
|
||||||
|
|
||||||
template<class charT, class traits = char_traits<charT>>
|
|
||||||
class basic_string_view;
|
|
||||||
|
|
||||||
typedef basic_string_view<char> string_view;
|
|
||||||
typedef basic_string_view<char16_t> u16string_view;
|
|
||||||
typedef basic_string_view<char32_t> u32string_view;
|
|
||||||
typedef basic_string_view<wchar_t> wstring_view;
|
|
||||||
|
|
||||||
So you can have views of strings of any of the four built-in character types as well as strings of user-defined character-like type strings. For the sake of simple exposition, we concentrate on `string_view` (i.e. `char` strings) in this documentation.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
|
|
||||||
[/===============]
|
|
||||||
[section Examples]
|
|
||||||
[/===============]
|
|
||||||
|
|
||||||
Integrating `string_view` 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_view`.
|
|
||||||
|
|
||||||
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_view`:
|
|
||||||
|
|
||||||
boost::string_view extract_part ( boost::string_view 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_view`s created, and two `string_view`s copied, but those are cheap operations.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
|
|
||||||
[/=================]
|
|
||||||
[section:reference Reference ]
|
|
||||||
[/=================]
|
|
||||||
|
|
||||||
The header file "string_view.hpp" defines a class template `boost::basic_string_view`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` .
|
|
||||||
|
|
||||||
`#include <boost/utility/string_view.hpp>`
|
|
||||||
|
|
||||||
Types:
|
|
||||||
|
|
||||||
typedef traits traits_type;
|
|
||||||
typedef charT value_type;
|
|
||||||
typedef charT* pointer;
|
|
||||||
typedef const charT* const_pointer;
|
|
||||||
typedef charT& reference;
|
|
||||||
typedef const charT& const_reference;
|
|
||||||
typedef const_pointer const_iterator; // implementation 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);
|
|
||||||
|
|
||||||
Construction and copying:
|
|
||||||
|
|
||||||
BOOST_CONSTEXPR basic_string_view () BOOST_NOEXCEPT; // Constructs empty string_view
|
|
||||||
BOOST_CONSTEXPR basic_string_view (const basic_string_view &rhs) BOOST_NOEXCEPT;
|
|
||||||
basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT;
|
|
||||||
template<typename Allocator>
|
|
||||||
basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT; // Ctor from std::string
|
|
||||||
BOOST_CONSTEXPR basic_string_view(const charT* str); // Ctor from NULL-terminated string
|
|
||||||
BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len); // Ctor from pointer, length pair
|
|
||||||
|
|
||||||
`string_view` does not define a move constructor or a move-assignment operator because copying a `string_view` is just as cheap as moving one would be.
|
|
||||||
|
|
||||||
Basic container-like functions:
|
|
||||||
|
|
||||||
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT ;
|
|
||||||
|
|
||||||
// All iterators are const_iterators
|
|
||||||
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT ;
|
|
||||||
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT ;
|
|
||||||
const_reverse_iterator rbegin() const BOOST_NOEXCEPT ;
|
|
||||||
const_reverse_iterator crbegin() const BOOST_NOEXCEPT ;
|
|
||||||
const_reverse_iterator rend() const BOOST_NOEXCEPT ;
|
|
||||||
const_reverse_iterator crend() const BOOST_NOEXCEPT ;
|
|
||||||
|
|
||||||
Access to the individual elements (all of which are const):
|
|
||||||
|
|
||||||
BOOST_CONSTEXPR const charT& operator[](size_type pos) const ;
|
|
||||||
BOOST_CONSTEXPR 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 BOOST_NOEXCEPT ;
|
|
||||||
|
|
||||||
Modifying the `string_view` (but not the underlying data):
|
|
||||||
|
|
||||||
void clear(); // boost extension
|
|
||||||
BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n);
|
|
||||||
BOOST_CXX14_CONSTEXPR void remove_suffix(size_type n);
|
|
||||||
BOOST_CXX14_CONSTEXPR void swap(basic_string_view& s) BOOST_NOEXCEPT;
|
|
||||||
|
|
||||||
Searching:
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(basic_string_view s, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const;
|
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const;
|
|
||||||
|
|
||||||
BOOST_CONSTEXPR bool starts_with(charT c) const ; // boost extension
|
|
||||||
BOOST_CONSTEXPR bool starts_with(basic_string_view x) const ; // boost extension
|
|
||||||
BOOST_CONSTEXPR bool ends_with(charT c) const ; // boost extension
|
|
||||||
BOOST_CONSTEXPR bool ends_with(basic_string_view x) const ; // boost extension
|
|
||||||
|
|
||||||
String-like operations:
|
|
||||||
|
|
||||||
template<class Allocator> // Only present if compiler supports C++11 explicit conversion
|
|
||||||
explicit operator basic_string<charT, traits, Allocator>() const;
|
|
||||||
|
|
||||||
template<class Allocator = allocator<charT> > // Default only present if compiler supports
|
|
||||||
basic_string<charT, traits, Allocator> // C++11 default template parameters
|
|
||||||
to_string(const Allocator& a = Allocator()) const;
|
|
||||||
|
|
||||||
size_type copy(charT* s, size_type n, size_type pos = 0) const;
|
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos,
|
|
||||||
size_type n=npos) const ; // Create new string_view
|
|
||||||
|
|
||||||
Comparison:
|
|
||||||
|
|
||||||
To be supplied
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[/===============]
|
|
||||||
[section Compiler Support]
|
|
||||||
[/===============]
|
|
||||||
|
|
||||||
This Boost implementation only requires a C++03 compliant compiler.
|
|
||||||
|
|
||||||
The actual Library Fundamentals specification assumes a C++14 compliant compiler, so a few features are only present if actually supported by the compiler. Boost macros such as BOOST_CONSTEXPR, BOOST_CXX14_CONSTEXPR, and BOOST_NOEXCEPT supply certain features if supported by the compiler.
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
[/===============]
|
|
||||||
[section History]
|
|
||||||
[/===============]
|
|
||||||
|
|
||||||
[heading boost 1.53]
|
|
||||||
* Introduced, based on 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]
|
|
||||||
|
|
||||||
[heading boost 1.60]
|
|
||||||
* Updated to reflect [@
|
|
||||||
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4480.html#string.view N4480:
|
|
||||||
ISO/IEC DTS 19568, Technical Specification - C++ Extensions for Library Fundamentals]
|
|
||||||
|
|
||||||
[endsect]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,6 +1,7 @@
|
|||||||
// Boost operators.hpp header file ----------------------------------------//
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||||
|
// (C) Copyright Daniel Frey 2002-2016.
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
@@ -8,6 +9,8 @@
|
|||||||
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
|
// 22 Feb 16 Added ADL protection, preserve old work-arounds in
|
||||||
|
// operators_v1.hpp and clean up this file. (Daniel Frey)
|
||||||
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||||
// (Matthew Bradbury, fixes #4432)
|
// (Matthew Bradbury, fixes #4432)
|
||||||
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||||
@@ -24,8 +27,8 @@
|
|||||||
// additional classes for groups of related operators added;
|
// additional classes for groups of related operators added;
|
||||||
// workaround for empty base class optimization
|
// workaround for empty base class optimization
|
||||||
// bug of GCC 3.0 (Helmut Zeisel)
|
// bug of GCC 3.0 (Helmut Zeisel)
|
||||||
// 25 Jun 01 output_iterator_helper changes: removed default template
|
// 25 Jun 01 output_iterator_helper changes: removed default template
|
||||||
// parameters, added support for self-proxying, additional
|
// parameters, added support for self-proxying, additional
|
||||||
// documentation and tests (Aleksey Gurtovoy)
|
// documentation and tests (Aleksey Gurtovoy)
|
||||||
// 29 May 01 Added operator classes for << and >>. Added input and output
|
// 29 May 01 Added operator classes for << and >>. Added input and output
|
||||||
// iterator helper classes. Added classes to connect equality and
|
// iterator helper classes. Added classes to connect equality and
|
||||||
@@ -38,18 +41,18 @@
|
|||||||
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||||
// refactoring of compiler workarounds, additional documentation
|
// refactoring of compiler workarounds, additional documentation
|
||||||
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
||||||
// Dave Abrahams)
|
// Dave Abrahams)
|
||||||
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
||||||
// Jeremy Siek (Dave Abrahams)
|
// Jeremy Siek (Dave Abrahams)
|
||||||
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
||||||
// (Mark Rodgers)
|
// (Mark Rodgers)
|
||||||
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
||||||
// 10 Jun 00 Support for the base class chaining technique was added
|
// 10 Jun 00 Support for the base class chaining technique was added
|
||||||
// (Aleksey Gurtovoy). See documentation and the comments below
|
// (Aleksey Gurtovoy). See documentation and the comments below
|
||||||
// for the details.
|
// for the details.
|
||||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
||||||
// specializations of dividable, subtractable, modable (Ed Brey)
|
// specializations of dividable, subtractable, modable (Ed Brey)
|
||||||
// 17 Nov 99 Add comments (Beman Dawes)
|
// 17 Nov 99 Add comments (Beman Dawes)
|
||||||
// Remove unnecessary specialization of operators<> (Ed Brey)
|
// Remove unnecessary specialization of operators<> (Ed Brey)
|
||||||
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
||||||
@@ -60,8 +63,8 @@
|
|||||||
// 10 Nov 99 Initial version
|
// 10 Nov 99 Initial version
|
||||||
|
|
||||||
// 10 Jun 00:
|
// 10 Jun 00:
|
||||||
// An additional optional template parameter was added to most of
|
// An additional optional template parameter was added to most of
|
||||||
// operator templates to support the base class chaining technique (see
|
// operator templates to support the base class chaining technique (see
|
||||||
// documentation for the details). Unfortunately, a straightforward
|
// documentation for the details). Unfortunately, a straightforward
|
||||||
// implementation of this change would have broken compatibility with the
|
// implementation of this change would have broken compatibility with the
|
||||||
// previous version of the library by making it impossible to use the same
|
// previous version of the library by making it impossible to use the same
|
||||||
@@ -70,20 +73,28 @@
|
|||||||
// issue at the cost of some simplicity.
|
// issue at the cost of some simplicity.
|
||||||
//
|
//
|
||||||
// One of the complications is an existence of special auxiliary class template
|
// One of the complications is an existence of special auxiliary class template
|
||||||
// 'is_chained_base<>' (see 'detail' namespace below), which is used
|
// 'is_chained_base<>' (see 'operators_detail' namespace below), which is used
|
||||||
// to determine whether its template parameter is a library's operator template
|
// to determine whether its template parameter is a library's operator template
|
||||||
// or not. You have to specialize 'is_chained_base<>' for each new
|
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||||
// operator template you add to the library.
|
// operator template you add to the library.
|
||||||
//
|
//
|
||||||
// However, most of the non-trivial implementation details are hidden behind
|
// However, most of the non-trivial implementation details are hidden behind
|
||||||
// several local macros defined below, and as soon as you understand them,
|
// several local macros defined below, and as soon as you understand them,
|
||||||
// you understand the whole library implementation.
|
// you understand the whole library implementation.
|
||||||
|
|
||||||
#ifndef BOOST_OPERATORS_HPP
|
#ifndef BOOST_OPERATORS_HPP
|
||||||
#define BOOST_OPERATORS_HPP
|
#define BOOST_OPERATORS_HPP
|
||||||
|
|
||||||
|
// If old work-arounds are needed, refer to the preserved version without
|
||||||
|
// ADL protection.
|
||||||
|
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_USE_OPERATORS_V1)
|
||||||
|
#include "operators_v1.hpp"
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/iterator.hpp>
|
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
@@ -91,35 +102,30 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||||
# pragma warning( disable : 4284 ) // complaint about return type of
|
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||||
#endif // operator-> not begin a UDT
|
#endif // operator-> not begin a UDT
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <typename T> class empty_base {};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||||
// templates, which are explicitly targeted at the 1-type-argument and
|
// templates, which are explicitly targeted at the 1-type-argument and
|
||||||
// 2-type-argument operator forms, respectively. Some compilers get confused
|
// 2-type-argument operator forms, respectively.
|
||||||
// when inline friend functions are overloaded in namespaces other than the
|
|
||||||
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
|
|
||||||
// these templates must go in the global namespace.
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
#endif
|
namespace operators_impl
|
||||||
|
{
|
||||||
|
namespace operators_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T> class empty_base {};
|
||||||
|
|
||||||
|
} // namespace operators_detail
|
||||||
|
|
||||||
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||||
|
|
||||||
// Note that friend functions defined in a class are implicitly inline.
|
// Note that friend functions defined in a class are implicitly inline.
|
||||||
// See the C++ std, 11.4 [class.friend] paragraph 5
|
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct less_than_comparable2 : B
|
struct less_than_comparable2 : B
|
||||||
{
|
{
|
||||||
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||||
@@ -130,7 +136,7 @@ struct less_than_comparable2 : B
|
|||||||
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct less_than_comparable1 : B
|
struct less_than_comparable1 : B
|
||||||
{
|
{
|
||||||
friend bool operator>(const T& x, const T& y) { return y < x; }
|
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||||
@@ -138,7 +144,7 @@ struct less_than_comparable1 : B
|
|||||||
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct equality_comparable2 : B
|
struct equality_comparable2 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const U& y, const T& x) { return x == y; }
|
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
@@ -146,7 +152,7 @@ struct equality_comparable2 : B
|
|||||||
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct equality_comparable1 : B
|
struct equality_comparable1 : B
|
||||||
{
|
{
|
||||||
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||||
@@ -164,39 +170,39 @@ struct equality_comparable1 : B
|
|||||||
// If the compiler has no NRVO, this is the best symmetric
|
// If the compiler has no NRVO, this is the best symmetric
|
||||||
// implementation available.
|
// implementation available.
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
@@ -211,34 +217,34 @@ struct NAME##1 : B \
|
|||||||
// optimization opportunities to the compiler :)
|
// optimization opportunities to the compiler :)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const U& lhs, const T& rhs ) \
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
{ return T( lhs ) OP##= rhs; } \
|
{ return T( lhs ) OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
@@ -261,7 +267,7 @@ BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
|||||||
|
|
||||||
// incrementable and decrementable contributed by Jeremy Siek
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct incrementable : B
|
struct incrementable : B
|
||||||
{
|
{
|
||||||
friend T operator++(T& x, int)
|
friend T operator++(T& x, int)
|
||||||
@@ -274,7 +280,7 @@ private: // The use of this typedef works around a Borland bug
|
|||||||
typedef T incrementable_type;
|
typedef T incrementable_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct decrementable : B
|
struct decrementable : B
|
||||||
{
|
{
|
||||||
friend T operator--(T& x, int)
|
friend T operator--(T& x, int)
|
||||||
@@ -289,16 +295,16 @@ private: // The use of this typedef works around a Borland bug
|
|||||||
|
|
||||||
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct dereferenceable : B
|
struct dereferenceable : B
|
||||||
{
|
{
|
||||||
P operator->() const
|
P operator->() const
|
||||||
{
|
{
|
||||||
return &*static_cast<const T&>(*this);
|
return &*static_cast<const T&>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
|
template <class T, class I, class R, class B = operators_detail::empty_base<T> >
|
||||||
struct indexable : B
|
struct indexable : B
|
||||||
{
|
{
|
||||||
R operator[](I n) const
|
R operator[](I n) const
|
||||||
@@ -312,34 +318,34 @@ struct indexable : B
|
|||||||
|
|
||||||
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const U& rhs ) \
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( const T& lhs, const T& rhs ) \
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class U, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##2 : B \
|
struct NAME##2 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
template <class T, class B = operators_detail::empty_base<T> > \
|
||||||
struct NAME##1 : B \
|
struct NAME##1 : B \
|
||||||
{ \
|
{ \
|
||||||
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
@@ -349,7 +355,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
|||||||
|
|
||||||
#undef BOOST_BINARY_OPERATOR
|
#undef BOOST_BINARY_OPERATOR
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct equivalent2 : B
|
struct equivalent2 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const T& x, const U& y)
|
friend bool operator==(const T& x, const U& y)
|
||||||
@@ -358,7 +364,7 @@ struct equivalent2 : B
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct equivalent1 : B
|
struct equivalent1 : B
|
||||||
{
|
{
|
||||||
friend bool operator==(const T&x, const T&y)
|
friend bool operator==(const T&x, const T&y)
|
||||||
@@ -367,7 +373,7 @@ struct equivalent1 : B
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct partially_ordered2 : B
|
struct partially_ordered2 : B
|
||||||
{
|
{
|
||||||
friend bool operator<=(const T& x, const U& y)
|
friend bool operator<=(const T& x, const U& y)
|
||||||
@@ -384,7 +390,7 @@ struct partially_ordered2 : B
|
|||||||
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct partially_ordered1 : B
|
struct partially_ordered1 : B
|
||||||
{
|
{
|
||||||
friend bool operator>(const T& x, const T& y)
|
friend bool operator>(const T& x, const T& y)
|
||||||
@@ -397,161 +403,161 @@ struct partially_ordered1 : B
|
|||||||
|
|
||||||
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct totally_ordered2
|
struct totally_ordered2
|
||||||
: less_than_comparable2<T, U
|
: less_than_comparable2<T, U
|
||||||
, equality_comparable2<T, U, B
|
, equality_comparable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct totally_ordered1
|
struct totally_ordered1
|
||||||
: less_than_comparable1<T
|
: less_than_comparable1<T
|
||||||
, equality_comparable1<T, B
|
, equality_comparable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct additive2
|
struct additive2
|
||||||
: addable2<T, U
|
: addable2<T, U
|
||||||
, subtractable2<T, U, B
|
, subtractable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct additive1
|
struct additive1
|
||||||
: addable1<T
|
: addable1<T
|
||||||
, subtractable1<T, B
|
, subtractable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct multiplicative2
|
struct multiplicative2
|
||||||
: multipliable2<T, U
|
: multipliable2<T, U
|
||||||
, dividable2<T, U, B
|
, dividable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct multiplicative1
|
struct multiplicative1
|
||||||
: multipliable1<T
|
: multipliable1<T
|
||||||
, dividable1<T, B
|
, dividable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_multiplicative2
|
struct integer_multiplicative2
|
||||||
: multiplicative2<T, U
|
: multiplicative2<T, U
|
||||||
, modable2<T, U, B
|
, modable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_multiplicative1
|
struct integer_multiplicative1
|
||||||
: multiplicative1<T
|
: multiplicative1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct arithmetic2
|
struct arithmetic2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, multiplicative2<T, U, B
|
, multiplicative2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct arithmetic1
|
struct arithmetic1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, multiplicative1<T, B
|
, multiplicative1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_arithmetic2
|
struct integer_arithmetic2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, integer_multiplicative2<T, U, B
|
, integer_multiplicative2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct integer_arithmetic1
|
struct integer_arithmetic1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, integer_multiplicative1<T, B
|
, integer_multiplicative1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct bitwise2
|
struct bitwise2
|
||||||
: xorable2<T, U
|
: xorable2<T, U
|
||||||
, andable2<T, U
|
, andable2<T, U
|
||||||
, orable2<T, U, B
|
, orable2<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct bitwise1
|
struct bitwise1
|
||||||
: xorable1<T
|
: xorable1<T
|
||||||
, andable1<T
|
, andable1<T
|
||||||
, orable1<T, B
|
, orable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct unit_steppable
|
struct unit_steppable
|
||||||
: incrementable<T
|
: incrementable<T
|
||||||
, decrementable<T, B
|
, decrementable<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct shiftable2
|
struct shiftable2
|
||||||
: left_shiftable2<T, U
|
: left_shiftable2<T, U
|
||||||
, right_shiftable2<T, U, B
|
, right_shiftable2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct shiftable1
|
struct shiftable1
|
||||||
: left_shiftable1<T
|
: left_shiftable1<T
|
||||||
, right_shiftable1<T, B
|
, right_shiftable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ring_operators2
|
struct ring_operators2
|
||||||
: additive2<T, U
|
: additive2<T, U
|
||||||
, subtractable2_left<T, U
|
, subtractable2_left<T, U
|
||||||
, multipliable2<T, U, B
|
, multipliable2<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ring_operators1
|
struct ring_operators1
|
||||||
: additive1<T
|
: additive1<T
|
||||||
, multipliable1<T, B
|
, multipliable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_ring_operators2
|
struct ordered_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, totally_ordered2<T, U, B
|
, totally_ordered2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_ring_operators1
|
struct ordered_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, totally_ordered1<T, B
|
, totally_ordered1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct field_operators2
|
struct field_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
, dividable2_left<T, U, B
|
, dividable2_left<T, U, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct field_operators1
|
struct field_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T, B
|
, dividable1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_field_operators2
|
struct ordered_field_operators2
|
||||||
: field_operators2<T, U
|
: field_operators2<T, U
|
||||||
, totally_ordered2<T, U, B
|
, totally_ordered2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_field_operators1
|
struct ordered_field_operators1
|
||||||
: field_operators1<T
|
: field_operators1<T
|
||||||
, totally_ordered1<T, B
|
, totally_ordered1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidian_ring_operators2
|
struct euclidian_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
@@ -560,26 +566,26 @@ struct euclidian_ring_operators2
|
|||||||
, modable2_left<T, U, B
|
, modable2_left<T, U, B
|
||||||
> > > > > {};
|
> > > > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidian_ring_operators1
|
struct euclidian_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T
|
, dividable1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidian_ring_operators2
|
struct ordered_euclidian_ring_operators2
|
||||||
: totally_ordered2<T, U
|
: totally_ordered2<T, U
|
||||||
, euclidian_ring_operators2<T, U, B
|
, euclidian_ring_operators2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidian_ring_operators1
|
struct ordered_euclidian_ring_operators1
|
||||||
: totally_ordered1<T
|
: totally_ordered1<T
|
||||||
, euclidian_ring_operators1<T, B
|
, euclidian_ring_operators1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidean_ring_operators2
|
struct euclidean_ring_operators2
|
||||||
: ring_operators2<T, U
|
: ring_operators2<T, U
|
||||||
, dividable2<T, U
|
, dividable2<T, U
|
||||||
@@ -588,43 +594,43 @@ struct euclidean_ring_operators2
|
|||||||
, modable2_left<T, U, B
|
, modable2_left<T, U, B
|
||||||
> > > > > {};
|
> > > > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct euclidean_ring_operators1
|
struct euclidean_ring_operators1
|
||||||
: ring_operators1<T
|
: ring_operators1<T
|
||||||
, dividable1<T
|
, dividable1<T
|
||||||
, modable1<T, B
|
, modable1<T, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
template <class T, class U, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidean_ring_operators2
|
struct ordered_euclidean_ring_operators2
|
||||||
: totally_ordered2<T, U
|
: totally_ordered2<T, U
|
||||||
, euclidean_ring_operators2<T, U, B
|
, euclidean_ring_operators2<T, U, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct ordered_euclidean_ring_operators1
|
struct ordered_euclidean_ring_operators1
|
||||||
: totally_ordered1<T
|
: totally_ordered1<T
|
||||||
, euclidean_ring_operators1<T, B
|
, euclidean_ring_operators1<T, B
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct input_iteratable
|
struct input_iteratable
|
||||||
: equality_comparable1<T
|
: equality_comparable1<T
|
||||||
, incrementable<T
|
, incrementable<T
|
||||||
, dereferenceable<T, P, B
|
, dereferenceable<T, P, B
|
||||||
> > > {};
|
> > > {};
|
||||||
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> >
|
template <class T, class B = operators_detail::empty_base<T> >
|
||||||
struct output_iteratable
|
struct output_iteratable
|
||||||
: incrementable<T, B
|
: incrementable<T, B
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct forward_iteratable
|
struct forward_iteratable
|
||||||
: input_iteratable<T, P, B
|
: input_iteratable<T, P, B
|
||||||
> {};
|
> {};
|
||||||
|
|
||||||
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class B = operators_detail::empty_base<T> >
|
||||||
struct bidirectional_iteratable
|
struct bidirectional_iteratable
|
||||||
: forward_iteratable<T, P
|
: forward_iteratable<T, P
|
||||||
, decrementable<T, B
|
, decrementable<T, B
|
||||||
@@ -634,7 +640,7 @@ struct bidirectional_iteratable
|
|||||||
// which is an indirect base class of bidirectional_iterable,
|
// which is an indirect base class of bidirectional_iterable,
|
||||||
// random_access_iteratable must not be derived from totally_ordered1
|
// random_access_iteratable must not be derived from totally_ordered1
|
||||||
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||||
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
|
template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> >
|
||||||
struct random_access_iteratable
|
struct random_access_iteratable
|
||||||
: bidirectional_iteratable<T, P
|
: bidirectional_iteratable<T, P
|
||||||
, less_than_comparable1<T
|
, less_than_comparable1<T
|
||||||
@@ -642,124 +648,64 @@ struct random_access_iteratable
|
|||||||
, indexable<T, D, R, B
|
, indexable<T, D, R, B
|
||||||
> > > > {};
|
> > > > {};
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
} // namespace boost
|
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
|
|
||||||
//
|
|
||||||
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
|
||||||
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
|
||||||
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
|
|
||||||
// two-argument forms. Note that these macros expect to be invoked from within
|
|
||||||
// boost.
|
|
||||||
|
|
||||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
// The template is already in boost so we have nothing to do.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
|
||||||
|
|
||||||
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
# ifndef BOOST_NO_USING_TEMPLATE
|
|
||||||
|
|
||||||
// Bring the names in with a using-declaration
|
|
||||||
// to avoid stressing the compiler.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
|
||||||
|
|
||||||
# else
|
|
||||||
|
|
||||||
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
|
|
||||||
// from working, we are forced to use inheritance for that compiler.
|
|
||||||
# define BOOST_IMPORT_TEMPLATE4(template_name) \
|
|
||||||
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, V, W, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE3(template_name) \
|
|
||||||
template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, V, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, U, B> {};
|
|
||||||
|
|
||||||
# define BOOST_IMPORT_TEMPLATE1(template_name) \
|
|
||||||
template <class T, class B = ::boost::detail::empty_base<T> > \
|
|
||||||
struct template_name : ::template_name<T, B> {};
|
|
||||||
|
|
||||||
# endif // BOOST_NO_USING_TEMPLATE
|
|
||||||
|
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Here's where we put it all together, defining the xxxx forms of the templates
|
// Here's where we put it all together, defining the xxxx forms of the templates.
|
||||||
// in namespace boost. We also define specializations of is_chained_base<> for
|
// We also define specializations of is_chained_base<> for
|
||||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
// the xxxx, xxxx1, and xxxx2 templates.
|
||||||
// necessary.
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
namespace operators_detail
|
||||||
|
{
|
||||||
|
|
||||||
|
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||||
|
// didn't cope well with the more obvious non-type template parameter.
|
||||||
|
struct true_t {};
|
||||||
|
struct false_t {};
|
||||||
|
|
||||||
|
} // namespace operators_detail
|
||||||
|
|
||||||
// is_chained_base<> - a traits class used to distinguish whether an operator
|
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||||
// template argument is being used for base class chaining, or is specifying a
|
// template argument is being used for base class chaining, or is specifying a
|
||||||
// 2nd argument type.
|
// 2nd argument type.
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
// A type parameter is used instead of a plain bool because Borland's compiler
|
|
||||||
// didn't cope well with the more obvious non-type template parameter.
|
|
||||||
namespace detail {
|
|
||||||
struct true_t {};
|
|
||||||
struct false_t {};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
// Unspecialized version assumes that most types are not being used for base
|
// Unspecialized version assumes that most types are not being used for base
|
||||||
// class chaining. We specialize for the operator templates defined in this
|
// class chaining. We specialize for the operator templates defined in this
|
||||||
// library.
|
// library.
|
||||||
template<class T> struct is_chained_base {
|
template<class T> struct is_chained_base {
|
||||||
typedef ::boost::detail::false_t value;
|
typedef operators_detail::false_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace boost
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
|
// for a 4-type-argument operator template.
|
||||||
// Import a 4-type-argument operator template into boost (if necessary) and
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
template<class T, class U, class V, class W, class B> \
|
||||||
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
struct is_chained_base< template_name4<T, U, V, W, B> > { \
|
||||||
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
typedef operators_detail::true_t value; \
|
||||||
template<class T, class U, class V, class W, class B> \
|
|
||||||
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
|
|
||||||
typedef ::boost::detail::true_t value; \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 3-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 3-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
template<class T, class U, class V, class B> \
|
||||||
template<class T, class U, class V, class B> \
|
struct is_chained_base< template_name3<T, U, V, B> > { \
|
||||||
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
|
typedef operators_detail::true_t value; \
|
||||||
typedef ::boost::detail::true_t value; \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 2-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 2-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
template<class T, class U, class B> \
|
||||||
template<class T, class U, class B> \
|
struct is_chained_base< template_name2<T, U, B> > { \
|
||||||
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
|
typedef operators_detail::true_t value; \
|
||||||
typedef ::boost::detail::true_t value; \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import a 1-type-argument operator template into boost (if necessary) and
|
// Provide a specialization of 'is_chained_base<>'
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// for a 1-type-argument operator template.
|
||||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
template<class T, class B> \
|
||||||
template<class T, class B> \
|
struct is_chained_base< template_name1<T, B> > { \
|
||||||
struct is_chained_base< ::boost::template_name1<T, B> > { \
|
typedef operators_detail::true_t value; \
|
||||||
typedef ::boost::detail::true_t value; \
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||||
@@ -776,34 +722,34 @@ template<class T> struct is_chained_base {
|
|||||||
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
||||||
//
|
//
|
||||||
|
|
||||||
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||||
template <class T \
|
template <class T \
|
||||||
,class U = T \
|
,class U = T \
|
||||||
,class B = ::boost::detail::empty_base<T> \
|
,class B = operators_detail::empty_base<T> \
|
||||||
,class O = typename is_chained_base<U>::value \
|
,class O = typename is_chained_base<U>::value \
|
||||||
> \
|
> \
|
||||||
struct template_name : template_name##2<T, U, B> {}; \
|
struct template_name; \
|
||||||
\
|
\
|
||||||
template<class T, class U, class B> \
|
template<class T, class U, class B> \
|
||||||
struct template_name<T, U, B, ::boost::detail::true_t> \
|
struct template_name<T, U, B, operators_detail::false_t> \
|
||||||
: template_name##1<T, U> {}; \
|
: template_name##2<T, U, B> {}; \
|
||||||
\
|
\
|
||||||
template <class T, class B> \
|
template<class T, class U> \
|
||||||
struct template_name<T, T, B, ::boost::detail::false_t> \
|
struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \
|
||||||
: template_name##1<T, B> {}; \
|
: template_name##1<T, U> {}; \
|
||||||
\
|
\
|
||||||
template<class T, class U, class B, class O> \
|
template <class T, class B> \
|
||||||
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
|
struct template_name<T, T, B, operators_detail::false_t> \
|
||||||
typedef ::boost::detail::true_t value; \
|
: template_name##1<T, B> {}; \
|
||||||
}; \
|
\
|
||||||
\
|
template<class T, class U, class B, class O> \
|
||||||
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
struct is_chained_base< template_name<T, U, B, O> > { \
|
||||||
|
typedef operators_detail::true_t value; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||||
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||||
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||||
BOOST_OPERATOR_TEMPLATE(multipliable)
|
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||||
@@ -857,13 +803,7 @@ BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
|||||||
#undef BOOST_OPERATOR_TEMPLATE3
|
#undef BOOST_OPERATOR_TEMPLATE3
|
||||||
#undef BOOST_OPERATOR_TEMPLATE2
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
#undef BOOST_OPERATOR_TEMPLATE1
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE1
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE2
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE3
|
|
||||||
#undef BOOST_IMPORT_TEMPLATE4
|
|
||||||
|
|
||||||
// The following 'operators' classes can only be used portably if the derived class
|
|
||||||
// declares ALL of the required member operators.
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
struct operators2
|
struct operators2
|
||||||
: totally_ordered2<T,U
|
: totally_ordered2<T,U
|
||||||
@@ -891,13 +831,13 @@ template <class T,
|
|||||||
class R = V const &>
|
class R = V const &>
|
||||||
struct input_iterator_helper
|
struct input_iterator_helper
|
||||||
: input_iteratable<T, P
|
: input_iteratable<T, P
|
||||||
, boost::iterator<std::input_iterator_tag, V, D, P, R
|
, std::iterator<std::input_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
struct output_iterator_helper
|
struct output_iterator_helper
|
||||||
: output_iteratable<T
|
: output_iteratable<T
|
||||||
, boost::iterator<std::output_iterator_tag, void, void, void, void
|
, std::iterator<std::output_iterator_tag, void, void, void, void
|
||||||
> >
|
> >
|
||||||
{
|
{
|
||||||
T& operator*() { return static_cast<T&>(*this); }
|
T& operator*() { return static_cast<T&>(*this); }
|
||||||
@@ -911,7 +851,7 @@ template <class T,
|
|||||||
class R = V&>
|
class R = V&>
|
||||||
struct forward_iterator_helper
|
struct forward_iterator_helper
|
||||||
: forward_iteratable<T, P
|
: forward_iteratable<T, P
|
||||||
, boost::iterator<std::forward_iterator_tag, V, D, P, R
|
, std::iterator<std::forward_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
@@ -921,17 +861,17 @@ template <class T,
|
|||||||
class R = V&>
|
class R = V&>
|
||||||
struct bidirectional_iterator_helper
|
struct bidirectional_iterator_helper
|
||||||
: bidirectional_iteratable<T, P
|
: bidirectional_iteratable<T, P
|
||||||
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
||||||
> > {};
|
> > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
class D = std::ptrdiff_t,
|
class D = std::ptrdiff_t,
|
||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct random_access_iterator_helper
|
struct random_access_iterator_helper
|
||||||
: random_access_iteratable<T, P, D, R
|
: random_access_iteratable<T, P, D, R
|
||||||
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
|
, std::iterator<std::random_access_iterator_tag, V, D, P, R
|
||||||
> >
|
> >
|
||||||
{
|
{
|
||||||
friend D requires_difference_operator(const T& x, const T& y) {
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
@@ -939,10 +879,14 @@ struct random_access_iterator_helper
|
|||||||
}
|
}
|
||||||
}; // random_access_iterator_helper
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
|
} // namespace operators_impl
|
||||||
|
using namespace operators_impl;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#if defined(__sgi) && !defined(__GNUC__)
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
#pragma reset woff 1234
|
#pragma reset woff 1234
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
#endif // BOOST_OPERATORS_HPP
|
#endif // BOOST_OPERATORS_HPP
|
||||||
|
951
include/boost/operators_v1.hpp
Normal file
951
include/boost/operators_v1.hpp
Normal file
@@ -0,0 +1,951 @@
|
|||||||
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
|
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
// accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
// See http://www.boost.org/libs/utility/operators.htm for documentation.
|
||||||
|
|
||||||
|
// Revision History
|
||||||
|
// 22 Feb 16 Preserve old work-arounds. (Daniel Frey)
|
||||||
|
// 16 Dec 10 Limit warning suppression for 4284 to older versions of VC++
|
||||||
|
// (Matthew Bradbury, fixes #4432)
|
||||||
|
// 07 Aug 08 Added "euclidean" spelling. (Daniel Frey)
|
||||||
|
// 03 Apr 08 Make sure "convertible to bool" is sufficient
|
||||||
|
// for T::operator<, etc. (Daniel Frey)
|
||||||
|
// 24 May 07 Changed empty_base to depend on T, see
|
||||||
|
// http://svn.boost.org/trac/boost/ticket/979
|
||||||
|
// 21 Oct 02 Modified implementation of operators to allow compilers with a
|
||||||
|
// correct named return value optimization (NRVO) to produce optimal
|
||||||
|
// code. (Daniel Frey)
|
||||||
|
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
|
||||||
|
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
|
||||||
|
// 27 Aug 01 'left' form for non commutative operators added;
|
||||||
|
// additional classes for groups of related operators added;
|
||||||
|
// workaround for empty base class optimization
|
||||||
|
// bug of GCC 3.0 (Helmut Zeisel)
|
||||||
|
// 25 Jun 01 output_iterator_helper changes: removed default template
|
||||||
|
// parameters, added support for self-proxying, additional
|
||||||
|
// documentation and tests (Aleksey Gurtovoy)
|
||||||
|
// 29 May 01 Added operator classes for << and >>. Added input and output
|
||||||
|
// iterator helper classes. Added classes to connect equality and
|
||||||
|
// relational operators. Added classes for groups of related
|
||||||
|
// operators. Reimplemented example operator and iterator helper
|
||||||
|
// classes in terms of the new groups. (Daryle Walker, with help
|
||||||
|
// from Alexy Gurtovoy)
|
||||||
|
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
||||||
|
// supplied arguments from actually being used (Dave Abrahams)
|
||||||
|
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
||||||
|
// refactoring of compiler workarounds, additional documentation
|
||||||
|
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
|
||||||
|
// Dave Abrahams)
|
||||||
|
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
|
||||||
|
// Jeremy Siek (Dave Abrahams)
|
||||||
|
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
|
||||||
|
// (Mark Rodgers)
|
||||||
|
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
|
||||||
|
// 10 Jun 00 Support for the base class chaining technique was added
|
||||||
|
// (Aleksey Gurtovoy). See documentation and the comments below
|
||||||
|
// for the details.
|
||||||
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
|
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
|
||||||
|
// specializations of dividable, subtractable, modable (Ed Brey)
|
||||||
|
// 17 Nov 99 Add comments (Beman Dawes)
|
||||||
|
// Remove unnecessary specialization of operators<> (Ed Brey)
|
||||||
|
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
|
||||||
|
// operators.(Beman Dawes)
|
||||||
|
// 12 Nov 99 Add operators templates (Ed Brey)
|
||||||
|
// 11 Nov 99 Add single template parameter version for compilers without
|
||||||
|
// partial specialization (Beman Dawes)
|
||||||
|
// 10 Nov 99 Initial version
|
||||||
|
|
||||||
|
// 10 Jun 00:
|
||||||
|
// An additional optional template parameter was added to most of
|
||||||
|
// operator templates to support the base class chaining technique (see
|
||||||
|
// documentation for the details). Unfortunately, a straightforward
|
||||||
|
// implementation of this change would have broken compatibility with the
|
||||||
|
// previous version of the library by making it impossible to use the same
|
||||||
|
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
|
||||||
|
// an operator template. This implementation solves the backward-compatibility
|
||||||
|
// issue at the cost of some simplicity.
|
||||||
|
//
|
||||||
|
// One of the complications is an existence of special auxiliary class template
|
||||||
|
// 'is_chained_base<>' (see 'detail' namespace below), which is used
|
||||||
|
// to determine whether its template parameter is a library's operator template
|
||||||
|
// or not. You have to specialize 'is_chained_base<>' for each new
|
||||||
|
// operator template you add to the library.
|
||||||
|
//
|
||||||
|
// However, most of the non-trivial implementation details are hidden behind
|
||||||
|
// several local macros defined below, and as soon as you understand them,
|
||||||
|
// you understand the whole library implementation.
|
||||||
|
|
||||||
|
#ifndef BOOST_OPERATORS_V1_HPP
|
||||||
|
#define BOOST_OPERATORS_V1_HPP
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
|
# pragma set woff 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1600)
|
||||||
|
# pragma warning( disable : 4284 ) // complaint about return type of
|
||||||
|
#endif // operator-> not begin a UDT
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T> class empty_base {};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
// In this section we supply the xxxx1 and xxxx2 forms of the operator
|
||||||
|
// templates, which are explicitly targeted at the 1-type-argument and
|
||||||
|
// 2-type-argument operator forms, respectively. Some compilers get confused
|
||||||
|
// when inline friend functions are overloaded in namespaces other than the
|
||||||
|
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
|
||||||
|
// these templates must go in the global namespace.
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Basic operator classes (contributed by Dave Abrahams) ------------------//
|
||||||
|
|
||||||
|
// Note that friend functions defined in a class are implicitly inline.
|
||||||
|
// See the C++ std, 11.4 [class.friend] paragraph 5
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct less_than_comparable2 : B
|
||||||
|
{
|
||||||
|
friend bool operator<=(const T& x, const U& y) { return !static_cast<bool>(x > y); }
|
||||||
|
friend bool operator>=(const T& x, const U& y) { return !static_cast<bool>(x < y); }
|
||||||
|
friend bool operator>(const U& x, const T& y) { return y < x; }
|
||||||
|
friend bool operator<(const U& x, const T& y) { return y > x; }
|
||||||
|
friend bool operator<=(const U& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||||
|
friend bool operator>=(const U& x, const T& y) { return !static_cast<bool>(y > x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct less_than_comparable1 : B
|
||||||
|
{
|
||||||
|
friend bool operator>(const T& x, const T& y) { return y < x; }
|
||||||
|
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
|
||||||
|
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equality_comparable2 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const U& y, const T& x) { return x == y; }
|
||||||
|
friend bool operator!=(const U& y, const T& x) { return !static_cast<bool>(x == y); }
|
||||||
|
friend bool operator!=(const T& y, const U& x) { return !static_cast<bool>(y == x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equality_comparable1 : B
|
||||||
|
{
|
||||||
|
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// A macro which produces "name_2left" from "name".
|
||||||
|
#define BOOST_OPERATOR2_LEFT(name) name##2##_##left
|
||||||
|
|
||||||
|
// NRVO-friendly implementation (contributed by Daniel Frey) ---------------//
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
// This is the optimal implementation for ISO/ANSI C++,
|
||||||
|
// but it requires the compiler to implement the NRVO.
|
||||||
|
// If the compiler has no NRVO, this is the best symmetric
|
||||||
|
// implementation available.
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( rhs ); nrv OP##= lhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
// For compilers without NRVO the following code is optimal, but not
|
||||||
|
// symmetric! Note that the implementation of
|
||||||
|
// BOOST_OPERATOR2_LEFT(NAME) only looks cool, but doesn't provide
|
||||||
|
// optimization opportunities to the compiler :)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
friend T operator OP( const U& lhs, T rhs ) { return rhs OP##= lhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct BOOST_OPERATOR2_LEFT(NAME) : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const U& lhs, const T& rhs ) \
|
||||||
|
{ return T( lhs ) OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( multipliable, * )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( addable, + )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( subtractable, - )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( dividable, / )
|
||||||
|
BOOST_BINARY_OPERATOR_NON_COMMUTATIVE( modable, % )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( xorable, ^ )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( andable, & )
|
||||||
|
BOOST_BINARY_OPERATOR_COMMUTATIVE( orable, | )
|
||||||
|
|
||||||
|
#undef BOOST_BINARY_OPERATOR_COMMUTATIVE
|
||||||
|
#undef BOOST_BINARY_OPERATOR_NON_COMMUTATIVE
|
||||||
|
#undef BOOST_OPERATOR2_LEFT
|
||||||
|
|
||||||
|
// incrementable and decrementable contributed by Jeremy Siek
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct incrementable : B
|
||||||
|
{
|
||||||
|
friend T operator++(T& x, int)
|
||||||
|
{
|
||||||
|
incrementable_type nrv(x);
|
||||||
|
++x;
|
||||||
|
return nrv;
|
||||||
|
}
|
||||||
|
private: // The use of this typedef works around a Borland bug
|
||||||
|
typedef T incrementable_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct decrementable : B
|
||||||
|
{
|
||||||
|
friend T operator--(T& x, int)
|
||||||
|
{
|
||||||
|
decrementable_type nrv(x);
|
||||||
|
--x;
|
||||||
|
return nrv;
|
||||||
|
}
|
||||||
|
private: // The use of this typedef works around a Borland bug
|
||||||
|
typedef T decrementable_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct dereferenceable : B
|
||||||
|
{
|
||||||
|
P operator->() const
|
||||||
|
{
|
||||||
|
return &*static_cast<const T&>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class I, class R, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct indexable : B
|
||||||
|
{
|
||||||
|
R operator[](I n) const
|
||||||
|
{
|
||||||
|
return *(static_cast<const T&>(*this) + n);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// More operator classes (contributed by Daryle Walker) --------------------//
|
||||||
|
// (NRVO-friendly implementation contributed by Daniel Frey) ---------------//
|
||||||
|
|
||||||
|
#if defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const U& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( const T& lhs, const T& rhs ) \
|
||||||
|
{ T nrv( lhs ); nrv OP##= rhs; return nrv; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#else // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
#define BOOST_BINARY_OPERATOR( NAME, OP ) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##2 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const U& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct NAME##1 : B \
|
||||||
|
{ \
|
||||||
|
friend T operator OP( T lhs, const T& rhs ) { return lhs OP##= rhs; } \
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // defined(BOOST_HAS_NRVO) || defined(BOOST_FORCE_SYMMETRIC_OPERATORS)
|
||||||
|
|
||||||
|
BOOST_BINARY_OPERATOR( left_shiftable, << )
|
||||||
|
BOOST_BINARY_OPERATOR( right_shiftable, >> )
|
||||||
|
|
||||||
|
#undef BOOST_BINARY_OPERATOR
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equivalent2 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T& x, const U& y)
|
||||||
|
{
|
||||||
|
return !static_cast<bool>(x < y) && !static_cast<bool>(x > y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct equivalent1 : B
|
||||||
|
{
|
||||||
|
friend bool operator==(const T&x, const T&y)
|
||||||
|
{
|
||||||
|
return !static_cast<bool>(x < y) && !static_cast<bool>(y < x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct partially_ordered2 : B
|
||||||
|
{
|
||||||
|
friend bool operator<=(const T& x, const U& y)
|
||||||
|
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>=(const T& x, const U& y)
|
||||||
|
{ return static_cast<bool>(x > y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>(const U& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<(const U& x, const T& y)
|
||||||
|
{ return y > x; }
|
||||||
|
friend bool operator<=(const U& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y > x) || static_cast<bool>(y == x); }
|
||||||
|
friend bool operator>=(const U& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y < x) || static_cast<bool>(y == x); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct partially_ordered1 : B
|
||||||
|
{
|
||||||
|
friend bool operator>(const T& x, const T& y)
|
||||||
|
{ return y < x; }
|
||||||
|
friend bool operator<=(const T& x, const T& y)
|
||||||
|
{ return static_cast<bool>(x < y) || static_cast<bool>(x == y); }
|
||||||
|
friend bool operator>=(const T& x, const T& y)
|
||||||
|
{ return static_cast<bool>(y < x) || static_cast<bool>(x == y); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Combined operator classes (contributed by Daryle Walker) ----------------//
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct totally_ordered2
|
||||||
|
: less_than_comparable2<T, U
|
||||||
|
, equality_comparable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct totally_ordered1
|
||||||
|
: less_than_comparable1<T
|
||||||
|
, equality_comparable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct additive2
|
||||||
|
: addable2<T, U
|
||||||
|
, subtractable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct additive1
|
||||||
|
: addable1<T
|
||||||
|
, subtractable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct multiplicative2
|
||||||
|
: multipliable2<T, U
|
||||||
|
, dividable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct multiplicative1
|
||||||
|
: multipliable1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_multiplicative2
|
||||||
|
: multiplicative2<T, U
|
||||||
|
, modable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_multiplicative1
|
||||||
|
: multiplicative1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_arithmetic2
|
||||||
|
: additive2<T, U
|
||||||
|
, integer_multiplicative2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct integer_arithmetic1
|
||||||
|
: additive1<T
|
||||||
|
, integer_multiplicative1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bitwise2
|
||||||
|
: xorable2<T, U
|
||||||
|
, andable2<T, U
|
||||||
|
, orable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bitwise1
|
||||||
|
: xorable1<T
|
||||||
|
, andable1<T
|
||||||
|
, orable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct unit_steppable
|
||||||
|
: incrementable<T
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct shiftable2
|
||||||
|
: left_shiftable2<T, U
|
||||||
|
, right_shiftable2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct shiftable1
|
||||||
|
: left_shiftable1<T
|
||||||
|
, right_shiftable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ring_operators2
|
||||||
|
: additive2<T, U
|
||||||
|
, subtractable2_left<T, U
|
||||||
|
, multipliable2<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ring_operators1
|
||||||
|
: additive1<T
|
||||||
|
, multipliable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct field_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct field_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_field_operators2
|
||||||
|
: field_operators2<T, U
|
||||||
|
, totally_ordered2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_field_operators1
|
||||||
|
: field_operators1<T
|
||||||
|
, totally_ordered1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidian_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U
|
||||||
|
, modable2<T, U
|
||||||
|
, modable2_left<T, U, B
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidian_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidian_ring_operators2
|
||||||
|
: totally_ordered2<T, U
|
||||||
|
, euclidian_ring_operators2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidian_ring_operators1
|
||||||
|
: totally_ordered1<T
|
||||||
|
, euclidian_ring_operators1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidean_ring_operators2
|
||||||
|
: ring_operators2<T, U
|
||||||
|
, dividable2<T, U
|
||||||
|
, dividable2_left<T, U
|
||||||
|
, modable2<T, U
|
||||||
|
, modable2_left<T, U, B
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct euclidean_ring_operators1
|
||||||
|
: ring_operators1<T
|
||||||
|
, dividable1<T
|
||||||
|
, modable1<T, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidean_ring_operators2
|
||||||
|
: totally_ordered2<T, U
|
||||||
|
, euclidean_ring_operators2<T, U, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct ordered_euclidean_ring_operators1
|
||||||
|
: totally_ordered1<T
|
||||||
|
, euclidean_ring_operators1<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct input_iteratable
|
||||||
|
: equality_comparable1<T
|
||||||
|
, incrementable<T
|
||||||
|
, dereferenceable<T, P, B
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct output_iteratable
|
||||||
|
: incrementable<T, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct forward_iteratable
|
||||||
|
: input_iteratable<T, P, B
|
||||||
|
> {};
|
||||||
|
|
||||||
|
template <class T, class P, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct bidirectional_iteratable
|
||||||
|
: forward_iteratable<T, P
|
||||||
|
, decrementable<T, B
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
// To avoid repeated derivation from equality_comparable,
|
||||||
|
// which is an indirect base class of bidirectional_iterable,
|
||||||
|
// random_access_iteratable must not be derived from totally_ordered1
|
||||||
|
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
|
||||||
|
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base<T> >
|
||||||
|
struct random_access_iteratable
|
||||||
|
: bidirectional_iteratable<T, P
|
||||||
|
, less_than_comparable1<T
|
||||||
|
, additive2<T, D
|
||||||
|
, indexable<T, D, R, B
|
||||||
|
> > > > {};
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
} // namespace boost
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
|
||||||
|
//
|
||||||
|
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
|
||||||
|
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
|
||||||
|
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
|
||||||
|
// two-argument forms. Note that these macros expect to be invoked from within
|
||||||
|
// boost.
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
// The template is already in boost so we have nothing to do.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name)
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name)
|
||||||
|
|
||||||
|
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
# ifndef BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
|
// Bring the names in with a using-declaration
|
||||||
|
// to avoid stressing the compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
|
||||||
|
// from working, we are forced to use inheritance for that compiler.
|
||||||
|
# define BOOST_IMPORT_TEMPLATE4(template_name) \
|
||||||
|
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, V, W, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE3(template_name) \
|
||||||
|
template <class T, class U, class V, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, V, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
||||||
|
template <class T, class U, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, U, B> {};
|
||||||
|
|
||||||
|
# define BOOST_IMPORT_TEMPLATE1(template_name) \
|
||||||
|
template <class T, class B = ::boost::detail::empty_base<T> > \
|
||||||
|
struct template_name : ::template_name<T, B> {};
|
||||||
|
|
||||||
|
# endif // BOOST_NO_USING_TEMPLATE
|
||||||
|
|
||||||
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Here's where we put it all together, defining the xxxx forms of the templates
|
||||||
|
// in namespace boost. We also define specializations of is_chained_base<> for
|
||||||
|
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||||
|
// necessary.
|
||||||
|
//
|
||||||
|
|
||||||
|
// is_chained_base<> - a traits class used to distinguish whether an operator
|
||||||
|
// template argument is being used for base class chaining, or is specifying a
|
||||||
|
// 2nd argument type.
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
// A type parameter is used instead of a plain bool because Borland's compiler
|
||||||
|
// didn't cope well with the more obvious non-type template parameter.
|
||||||
|
namespace detail {
|
||||||
|
struct true_t {};
|
||||||
|
struct false_t {};
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
// Unspecialized version assumes that most types are not being used for base
|
||||||
|
// class chaining. We specialize for the operator templates defined in this
|
||||||
|
// library.
|
||||||
|
template<class T> struct is_chained_base {
|
||||||
|
typedef ::boost::detail::false_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
// Import a 4-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||||
|
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
||||||
|
template<class T, class U, class V, class W, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 3-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||||
|
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
||||||
|
template<class T, class U, class V, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 2-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
|
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
||||||
|
template<class T, class U, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// Import a 1-type-argument operator template into boost (if necessary) and
|
||||||
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
|
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
||||||
|
template<class T, class B> \
|
||||||
|
struct is_chained_base< ::boost::template_name1<T, B> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
};
|
||||||
|
|
||||||
|
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
|
||||||
|
// can be used for specifying both 1-argument and 2-argument forms. Requires the
|
||||||
|
// existence of two previously defined class templates named '<template_name>1'
|
||||||
|
// and '<template_name>2' which must implement the corresponding 1- and 2-
|
||||||
|
// argument forms.
|
||||||
|
//
|
||||||
|
// The template type parameter O == is_chained_base<U>::value is used to
|
||||||
|
// distinguish whether the 2nd argument to <template_name> is being used for
|
||||||
|
// base class chaining from another boost operator template or is describing a
|
||||||
|
// 2nd operand type. O == true_t only when U is actually an another operator
|
||||||
|
// template from the library. Partial specialization is used to select an
|
||||||
|
// implementation in terms of either '<template_name>1' or '<template_name>2'.
|
||||||
|
//
|
||||||
|
|
||||||
|
# define BOOST_OPERATOR_TEMPLATE(template_name) \
|
||||||
|
template <class T \
|
||||||
|
,class U = T \
|
||||||
|
,class B = ::boost::detail::empty_base<T> \
|
||||||
|
,class O = typename is_chained_base<U>::value \
|
||||||
|
> \
|
||||||
|
struct template_name : template_name##2<T, U, B> {}; \
|
||||||
|
\
|
||||||
|
template<class T, class U, class B> \
|
||||||
|
struct template_name<T, U, B, ::boost::detail::true_t> \
|
||||||
|
: template_name##1<T, U> {}; \
|
||||||
|
\
|
||||||
|
template <class T, class B> \
|
||||||
|
struct template_name<T, T, B, ::boost::detail::false_t> \
|
||||||
|
: template_name##1<T, B> {}; \
|
||||||
|
\
|
||||||
|
template<class T, class U, class B, class O> \
|
||||||
|
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
|
||||||
|
typedef ::boost::detail::true_t value; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(equality_comparable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(multipliable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(addable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(subtractable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(dividable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(modable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(modable2_left)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(xorable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(andable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(orable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE3(indexable)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(equivalent)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(partially_ordered)
|
||||||
|
|
||||||
|
BOOST_OPERATOR_TEMPLATE(totally_ordered)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(additive)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(multiplicative)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(arithmetic)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(bitwise)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(shiftable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(euclidean_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE(ordered_euclidean_ring_operators)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
|
||||||
|
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
|
||||||
|
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE4
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE3
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE1
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE2
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE3
|
||||||
|
#undef BOOST_IMPORT_TEMPLATE4
|
||||||
|
|
||||||
|
// The following 'operators' classes can only be used portably if the derived class
|
||||||
|
// declares ALL of the required member operators.
|
||||||
|
template <class T, class U>
|
||||||
|
struct operators2
|
||||||
|
: totally_ordered2<T,U
|
||||||
|
, integer_arithmetic2<T,U
|
||||||
|
, bitwise2<T,U
|
||||||
|
> > > {};
|
||||||
|
|
||||||
|
template <class T, class U = T>
|
||||||
|
struct operators : operators2<T, U> {};
|
||||||
|
|
||||||
|
template <class T> struct operators<T, T>
|
||||||
|
: totally_ordered<T
|
||||||
|
, integer_arithmetic<T
|
||||||
|
, bitwise<T
|
||||||
|
, unit_steppable<T
|
||||||
|
> > > > {};
|
||||||
|
|
||||||
|
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
|
||||||
|
// (Input and output iterator helpers contributed by Daryle Walker) -------//
|
||||||
|
// (Changed to use combined operator classes by Daryle Walker) ------------//
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V const *,
|
||||||
|
class R = V const &>
|
||||||
|
struct input_iterator_helper
|
||||||
|
: input_iteratable<T, P
|
||||||
|
, std::iterator<std::input_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct output_iterator_helper
|
||||||
|
: output_iteratable<T
|
||||||
|
, std::iterator<std::output_iterator_tag, void, void, void, void
|
||||||
|
> >
|
||||||
|
{
|
||||||
|
T& operator*() { return static_cast<T&>(*this); }
|
||||||
|
T& operator++() { return static_cast<T&>(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct forward_iterator_helper
|
||||||
|
: forward_iteratable<T, P
|
||||||
|
, std::iterator<std::forward_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct bidirectional_iterator_helper
|
||||||
|
: bidirectional_iteratable<T, P
|
||||||
|
, std::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
||||||
|
> > {};
|
||||||
|
|
||||||
|
template <class T,
|
||||||
|
class V,
|
||||||
|
class D = std::ptrdiff_t,
|
||||||
|
class P = V*,
|
||||||
|
class R = V&>
|
||||||
|
struct random_access_iterator_helper
|
||||||
|
: random_access_iteratable<T, P, D, R
|
||||||
|
, std::iterator<std::random_access_iterator_tag, V, D, P, R
|
||||||
|
> >
|
||||||
|
{
|
||||||
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
|
return x - y;
|
||||||
|
}
|
||||||
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#if defined(__sgi) && !defined(__GNUC__)
|
||||||
|
#pragma reset woff 1234
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BOOST_OPERATORS_V1_HPP
|
@@ -47,11 +47,11 @@
|
|||||||
// {}
|
// {}
|
||||||
// This macro should only persist within this file.
|
// This macro should only persist within this file.
|
||||||
|
|
||||||
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
|
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
|
||||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||||
explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
||||||
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
|
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
|
||||||
{} \
|
{} \
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
|
||||||
@@ -142,7 +142,8 @@ protected:
|
|||||||
: member()
|
: member()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
template < typename T0 > explicit base_from_member( T0 x0 ) : member( x0 ) {}
|
||||||
|
BOOST_PP_REPEAT_FROM_TO( 2, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||||
BOOST_PRIVATE_CTR_DEF, _ )
|
BOOST_PRIVATE_CTR_DEF, _ )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -27,6 +27,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||||
|
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
|
||||||
|
#define BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -57,26 +62,37 @@ namespace boost {
|
|||||||
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
||||||
|
|
||||||
// construct/copy
|
// construct/copy
|
||||||
BOOST_CONSTEXPR basic_string_ref ()
|
BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT
|
||||||
: ptr_(NULL), len_(0) {}
|
: ptr_(NULL), len_(0) {}
|
||||||
|
|
||||||
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs)
|
// by defaulting these functions, basic_string_ref becomes
|
||||||
|
// trivially copy/move constructible.
|
||||||
|
BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_string_ref& operator=(const basic_string_ref &rhs) {
|
basic_string_ref& operator=(const basic_string_ref &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_REF_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
|
{
|
||||||
ptr_ = rhs.ptr_;
|
ptr_ = rhs.ptr_;
|
||||||
len_ = rhs.len_;
|
len_ = rhs.len_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_string_ref(const charT* str)
|
basic_string_ref(const charT* str) BOOST_NOEXCEPT
|
||||||
: ptr_(str), len_(traits::length(str)) {}
|
: ptr_(str), len_(traits::length(str)) {}
|
||||||
|
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
|
basic_string_ref(const std::basic_string<charT, traits, Allocator>& str)
|
||||||
: ptr_(str.data()), len_(str.length()) {}
|
: ptr_(str.data()), len_(str.length()) {}
|
||||||
|
|
||||||
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len)
|
BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT
|
||||||
: ptr_(str), len_(len) {}
|
: ptr_(str), len_(len) {}
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
@@ -174,13 +190,13 @@ namespace boost {
|
|||||||
size_type rfind(basic_string_ref s) const {
|
size_type rfind(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
|
const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (),
|
||||||
s.crbegin (), s.crend (), traits::eq );
|
s.crbegin (), s.crend (), traits::eq );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type rfind(charT c) const {
|
size_type rfind(charT c) const {
|
||||||
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
|
const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (),
|
||||||
detail::string_ref_traits_eq<charT, traits> ( c ));
|
detail::string_ref_traits_eq<charT, traits> ( c ));
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_first_of(charT c) const { return find (c); }
|
size_type find_first_of(charT c) const { return find (c); }
|
||||||
@@ -195,7 +211,7 @@ namespace boost {
|
|||||||
size_type find_last_of(basic_string_ref s) const {
|
size_type find_last_of(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = std::find_first_of
|
const_reverse_iterator iter = std::find_first_of
|
||||||
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
|
( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter);
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_first_not_of(basic_string_ref s) const {
|
size_type find_first_not_of(basic_string_ref s) const {
|
||||||
@@ -212,21 +228,17 @@ namespace boost {
|
|||||||
|
|
||||||
size_type find_last_not_of(basic_string_ref s) const {
|
size_type find_last_not_of(basic_string_ref s) const {
|
||||||
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
|
const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s );
|
||||||
return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter );
|
return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type find_last_not_of(charT c) const {
|
size_type find_last_not_of(charT c) const {
|
||||||
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
|
for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter )
|
||||||
if ( !traits::eq ( c, *iter ))
|
if ( !traits::eq ( c, *iter ))
|
||||||
return reverse_distance ( this->crbegin (), iter );
|
return this->size() - 1 - std::distance(this->crbegin(), iter);
|
||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename r_iter>
|
|
||||||
size_type reverse_distance ( r_iter first, r_iter last ) const {
|
|
||||||
return len_ - 1 - std::distance ( first, last );
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
|
Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const {
|
||||||
@@ -405,7 +417,7 @@ namespace boost {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline void insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
inline void sr_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
||||||
enum { chunk_size = 8 };
|
enum { chunk_size = 8 };
|
||||||
charT fill_chars[chunk_size];
|
charT fill_chars[chunk_size];
|
||||||
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
||||||
@@ -416,19 +428,19 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
void insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
void sr_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
|
||||||
const std::size_t size = str.size();
|
const std::size_t size = str.size();
|
||||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
||||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
||||||
if (!align_left) {
|
if (!align_left) {
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sr_insert_fill_chars(os, alignment_size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sr_insert_fill_chars(os, alignment_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +456,7 @@ namespace boost {
|
|||||||
if (w <= size)
|
if (w <= size)
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
else
|
else
|
||||||
detail::insert_aligned(os, str);
|
detail::sr_insert_aligned(os, str);
|
||||||
os.width(0);
|
os.width(0);
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
|
@@ -30,6 +30,11 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406)
|
||||||
|
// GCC 4.6 cannot handle a defaulted function with noexcept specifier
|
||||||
|
#define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -38,7 +43,7 @@ namespace boost {
|
|||||||
class string_view_traits_eq {
|
class string_view_traits_eq {
|
||||||
public:
|
public:
|
||||||
string_view_traits_eq ( charT ch ) : ch_(ch) {}
|
string_view_traits_eq ( charT ch ) : ch_(ch) {}
|
||||||
bool operator () ( charT val ) const { return traits::eq ( ch_, val ); }
|
bool operator()( charT val ) const { return traits::eq (ch_, val); }
|
||||||
charT ch_;
|
charT ch_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -47,32 +52,43 @@ namespace boost {
|
|||||||
class basic_string_view {
|
class basic_string_view {
|
||||||
public:
|
public:
|
||||||
// types
|
// types
|
||||||
typedef traits traits_type;
|
typedef traits traits_type;
|
||||||
typedef charT value_type;
|
typedef charT value_type;
|
||||||
typedef charT* pointer;
|
typedef charT* pointer;
|
||||||
typedef const charT* const_pointer;
|
typedef const charT* const_pointer;
|
||||||
typedef charT& reference;
|
typedef charT& reference;
|
||||||
typedef const charT& const_reference;
|
typedef const charT& const_reference;
|
||||||
typedef const_pointer const_iterator; // impl-defined
|
typedef const_pointer const_iterator; // impl-defined
|
||||||
typedef const_iterator iterator;
|
typedef const_iterator iterator;
|
||||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||||
typedef const_reverse_iterator reverse_iterator;
|
typedef const_reverse_iterator reverse_iterator;
|
||||||
typedef std::size_t size_type;
|
typedef std::size_t size_type;
|
||||||
typedef std::ptrdiff_t difference_type;
|
typedef std::ptrdiff_t difference_type;
|
||||||
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
|
||||||
|
|
||||||
// construct/copy
|
// construct/copy
|
||||||
BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
|
BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT
|
||||||
: ptr_(NULL), len_(0) {}
|
: ptr_(NULL), len_(0) {}
|
||||||
|
|
||||||
|
// by defaulting these functions, basic_string_ref becomes
|
||||||
|
// trivially copy/move constructible.
|
||||||
BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
|
BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
: ptr_(rhs.ptr_), len_(rhs.len_) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT {
|
basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT
|
||||||
|
#ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS
|
||||||
|
= default;
|
||||||
|
#else
|
||||||
|
{
|
||||||
ptr_ = rhs.ptr_;
|
ptr_ = rhs.ptr_;
|
||||||
len_ = rhs.len_;
|
len_ = rhs.len_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
basic_string_view(const std::basic_string<charT, traits,
|
basic_string_view(const std::basic_string<charT, traits,
|
||||||
@@ -86,33 +102,34 @@ namespace boost {
|
|||||||
: ptr_(str), len_(len) {}
|
: ptr_(str), len_(len) {}
|
||||||
|
|
||||||
// iterators
|
// iterators
|
||||||
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
|
BOOST_CONSTEXPR const_iterator begin() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
|
BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
BOOST_CONSTEXPR const_iterator end() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
||||||
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
BOOST_CONSTEXPR const_iterator cend() const BOOST_NOEXCEPT { return ptr_ + len_; }
|
||||||
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator (end()); }
|
const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
|
||||||
const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator (end()); }
|
const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
|
||||||
const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator (begin()); }
|
const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
|
||||||
const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator (begin()); }
|
const_reverse_iterator crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
|
||||||
|
|
||||||
// capacity
|
// capacity
|
||||||
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
|
BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return len_; }
|
||||||
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
|
BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT { return len_; }
|
||||||
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; }
|
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; }
|
||||||
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
|
BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT { return len_ == 0; }
|
||||||
|
|
||||||
// element access
|
// element access
|
||||||
BOOST_CONSTEXPR const_reference operator[](size_type pos) const { return ptr_[pos]; }
|
BOOST_CONSTEXPR const_reference operator[](size_type pos) const BOOST_NOEXCEPT { return ptr_[pos]; }
|
||||||
|
|
||||||
BOOST_CONSTEXPR const_reference at(size_t pos) const {
|
BOOST_CONSTEXPR const_reference at(size_t pos) const {
|
||||||
if ( pos >= len_ )
|
return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")) : ptr_[pos];
|
||||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_view::at" ) );
|
// if ( pos >= len_ )
|
||||||
return ptr_[pos];
|
// BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_view::at" ) );
|
||||||
|
// return ptr_[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
|
BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; }
|
||||||
BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
|
BOOST_CONSTEXPR const_reference back() const { return ptr_[len_-1]; }
|
||||||
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
|
BOOST_CONSTEXPR const_pointer data() const BOOST_NOEXCEPT { return ptr_; }
|
||||||
|
|
||||||
// modifiers
|
// modifiers
|
||||||
void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
|
void clear() BOOST_NOEXCEPT { len_ = 0; } // Boost extension
|
||||||
@@ -135,9 +152,7 @@ namespace boost {
|
|||||||
std::swap(len_, s.len_);
|
std::swap(len_, s.len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// basic_string_view string operations
|
// basic_string_view string operations
|
||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
explicit operator std::basic_string<charT, traits, Allocator>() const {
|
explicit operator std::basic_string<charT, traits, Allocator>() const {
|
||||||
@@ -147,18 +162,23 @@ namespace boost {
|
|||||||
|
|
||||||
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
|
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
|
||||||
template<typename Allocator = std::allocator<charT> >
|
template<typename Allocator = std::allocator<charT> >
|
||||||
std::basic_string<charT, traits> to_string(const Allocator& a = Allocator()) const {
|
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a = Allocator()) const {
|
||||||
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
|
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::basic_string<charT, traits> to_string() const {
|
std::basic_string<charT, traits> to_string() const {
|
||||||
return std::basic_string<charT, traits>(begin(), end());
|
return std::basic_string<charT, traits>(begin(), end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Allocator>
|
||||||
|
std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const {
|
||||||
|
return std::basic_string<charT, traits, Allocator>(begin(), end(), a);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_type copy( charT* s, size_type n, size_type pos = 0 ) const {
|
size_type copy(charT* s, size_type n, size_type pos=0) const {
|
||||||
if ( pos > size())
|
if (pos > size())
|
||||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::copy" ) );
|
BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" ));
|
||||||
size_type rlen = (std::min)(n, len_ - pos);
|
size_type rlen = (std::min)(n, len_ - pos);
|
||||||
// use std::copy(begin() + pos, begin() + pos + rlen, s) rather than
|
// use std::copy(begin() + pos, begin() + pos + rlen, s) rather than
|
||||||
// std::copy_n(begin() + pos, rlen, s) to support pre-C++11 standard libraries
|
// std::copy_n(begin() + pos, rlen, s) to support pre-C++11 standard libraries
|
||||||
@@ -169,49 +189,55 @@ namespace boost {
|
|||||||
BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
|
BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const {
|
||||||
if ( pos > size())
|
if ( pos > size())
|
||||||
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
|
BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) );
|
||||||
if ( n == npos || pos + n > size())
|
if (n == npos || pos + n > size())
|
||||||
n = size () - pos;
|
n = size () - pos;
|
||||||
return basic_string_view ( data() + pos, n );
|
return basic_string_view(data() + pos, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
|
BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT {
|
||||||
const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_));
|
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 );
|
return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x)
|
||||||
const BOOST_NOEXCEPT {
|
const BOOST_NOEXCEPT {
|
||||||
return substr(pos1, n1).compare(x);
|
return substr(pos1, n1).compare(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
||||||
basic_string_view x, size_type pos2, size_type n2) const {
|
basic_string_view x, size_type pos2, size_type n2) const {
|
||||||
return substr(pos1, n1).compare(x.substr(pos2, n2));
|
return substr(pos1, n1).compare(x.substr(pos2, n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
|
BOOST_CXX14_CONSTEXPR int compare(const charT* x) const {
|
||||||
return compare(basic_string_view(x));
|
return compare(basic_string_view(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const {
|
||||||
return substr(pos1, n1).compare(basic_string_view(x));
|
return substr(pos1, n1).compare(basic_string_view(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1,
|
||||||
const charT* x, size_type n2) const {
|
const charT* x, size_type n2) const {
|
||||||
return substr(pos1, n1).compare(basic_string_view(x, n2));
|
return substr(pos1, n1).compare(basic_string_view(x, n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Searches
|
// Searches
|
||||||
|
BOOST_CONSTEXPR bool starts_with(charT c) const BOOST_NOEXCEPT { // Boost extension
|
||||||
BOOST_CONSTEXPR bool starts_with(charT c) const { // Boost extension
|
return !empty() && traits::eq(c, front());
|
||||||
return !empty() && traits::eq ( c, front());
|
|
||||||
}
|
|
||||||
BOOST_CONSTEXPR bool starts_with(basic_string_view x) const { // Boost extension
|
|
||||||
return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CONSTEXPR bool ends_with(charT c) const {
|
BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
|
||||||
return !empty() && traits::eq ( c, back()); // Boost extension
|
return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0;
|
||||||
}
|
}
|
||||||
BOOST_CONSTEXPR bool ends_with(basic_string_view x) const { // Boost extension
|
|
||||||
return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_,
|
BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT { // Boost extension
|
||||||
x.ptr_, x.len_ ) == 0;
|
return !empty() && traits::eq(c, back());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT { // Boost extension
|
||||||
|
return len_ >= x.len_ &&
|
||||||
|
traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find
|
// find
|
||||||
@@ -221,25 +247,25 @@ namespace boost {
|
|||||||
if (s.empty())
|
if (s.empty())
|
||||||
return pos;
|
return pos;
|
||||||
const_iterator iter = std::search(this->cbegin() + pos, this->cend(),
|
const_iterator iter = std::search(this->cbegin() + pos, this->cend(),
|
||||||
s.cbegin (), s.cend (), traits::eq );
|
s.cbegin (), s.cend (), traits::eq);
|
||||||
return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter );
|
return iter == this->cend () ? npos : std::distance(this->cbegin (), iter);
|
||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type find(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find(basic_string_view(&c, 1), pos); }
|
{ return find(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return find(basic_string_view(s, n), pos); }
|
{ return find(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const
|
BOOST_CXX14_CONSTEXPR size_type find(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find(basic_string_view(s), pos); }
|
{ return find(basic_string_view(s), pos); }
|
||||||
|
|
||||||
// rfind
|
// rfind
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
||||||
if (len_ < s.len_)
|
if (len_ < s.len_)
|
||||||
return npos;
|
return npos;
|
||||||
if (pos > len_ - s.len_)
|
if (pos > len_ - s.len_)
|
||||||
pos = len_ - s.len_;
|
pos = len_ - s.len_;
|
||||||
if (s.len_ == 0u) // an empty string is always found
|
if (s.len_ == 0u) // an empty string is always found
|
||||||
return pos;
|
return pos;
|
||||||
for (const charT* cur = ptr_ + pos;; --cur) {
|
for (const charT* cur = ptr_ + pos; ; --cur) {
|
||||||
if (traits::compare(cur, s.ptr_, s.len_) == 0)
|
if (traits::compare(cur, s.ptr_, s.len_) == 0)
|
||||||
return cur - ptr_;
|
return cur - ptr_;
|
||||||
if (cur == ptr_)
|
if (cur == ptr_)
|
||||||
@@ -248,9 +274,9 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return rfind(basic_string_view(&c, 1), pos); }
|
{ return rfind(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return rfind(basic_string_view(s, n), pos); }
|
{ return rfind(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const
|
BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return rfind(basic_string_view(s), pos); }
|
{ return rfind(basic_string_view(s), pos); }
|
||||||
|
|
||||||
// find_first_of
|
// find_first_of
|
||||||
@@ -263,9 +289,9 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find_first_of(basic_string_view(&c, 1), pos); }
|
{ return find_first_of(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return find_first_of(basic_string_view(s, n), pos); }
|
{ return find_first_of(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const
|
BOOST_CXX14_CONSTEXPR size_type find_first_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find_first_of(basic_string_view(s), pos); }
|
{ return find_first_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
// find_last_of
|
// find_last_of
|
||||||
@@ -282,9 +308,9 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return find_last_of(basic_string_view(&c, 1), pos); }
|
{ return find_last_of(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return find_last_of(basic_string_view(s, n), pos); }
|
{ return find_last_of(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const
|
BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return find_last_of(basic_string_view(s), pos); }
|
{ return find_last_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
// find_first_not_of
|
// find_first_not_of
|
||||||
@@ -298,15 +324,15 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find_first_not_of(basic_string_view(&c, 1), pos); }
|
{ return find_first_not_of(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return find_first_not_of(basic_string_view(s, n), pos); }
|
{ return find_first_not_of(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const
|
BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT
|
||||||
{ return find_first_not_of(basic_string_view(s), pos); }
|
{ return find_first_not_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
// find_last_not_of
|
// find_last_not_of
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT {
|
||||||
if (pos >= len_)
|
if (pos >= len_)
|
||||||
pos = len_ - 1;;
|
pos = len_ - 1;
|
||||||
if (s.len_ == 0u)
|
if (s.len_ == 0u)
|
||||||
return pos;
|
return pos;
|
||||||
pos = len_ - (pos+1);
|
pos = len_ - (pos+1);
|
||||||
@@ -315,27 +341,26 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return find_last_not_of(basic_string_view(&c, 1), pos); }
|
{ return find_last_not_of(basic_string_view(&c, 1), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT
|
||||||
{ return find_last_not_of(basic_string_view(s, n), pos); }
|
{ return find_last_not_of(basic_string_view(s, n), pos); }
|
||||||
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const
|
BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT
|
||||||
{ return find_last_not_of(basic_string_view(s), pos); }
|
{ return find_last_not_of(basic_string_view(s), pos); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename r_iter>
|
template <typename r_iter>
|
||||||
size_type reverse_distance ( r_iter first, r_iter last ) const {
|
size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT {
|
||||||
|
// Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw.
|
||||||
return len_ - 1 - std::distance ( first, last );
|
return len_ - 1 - std::distance ( first, last );
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
Iterator find_not_of ( Iterator first, Iterator last, basic_string_view s ) const {
|
Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT {
|
||||||
for ( ; first != last ; ++first )
|
for (; first != last ; ++first)
|
||||||
if ( 0 == traits::find ( s.ptr_, s.len_, *first ))
|
if ( 0 == traits::find(s.ptr_, s.len_, *first))
|
||||||
return first;
|
return first;
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const charT *ptr_;
|
const charT *ptr_;
|
||||||
std::size_t len_;
|
std::size_t len_;
|
||||||
};
|
};
|
||||||
@@ -345,15 +370,15 @@ namespace boost {
|
|||||||
// Equality
|
// Equality
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator==(basic_string_view<charT, traits> x,
|
inline bool operator==(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
if ( x.size () != y.size ()) return false;
|
if (x.size () != y.size ()) return false;
|
||||||
return x.compare(y) == 0;
|
return x.compare(y) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inequality
|
// Inequality
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator!=(basic_string_view<charT, traits> x,
|
inline bool operator!=(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
if ( x.size () != y.size ()) return true;
|
if ( x.size () != y.size ()) return true;
|
||||||
return x.compare(y) != 0;
|
return x.compare(y) != 0;
|
||||||
}
|
}
|
||||||
@@ -361,180 +386,180 @@ namespace boost {
|
|||||||
// Less than
|
// Less than
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<(basic_string_view<charT, traits> x,
|
inline bool operator<(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return x.compare(y) < 0;
|
return x.compare(y) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Greater than
|
// Greater than
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>(basic_string_view<charT, traits> x,
|
inline bool operator>(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return x.compare(y) > 0;
|
return x.compare(y) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Less than or equal to
|
// Less than or equal to
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<=(basic_string_view<charT, traits> x,
|
inline bool operator<=(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return x.compare(y) <= 0;
|
return x.compare(y) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Greater than or equal to
|
// Greater than or equal to
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>=(basic_string_view<charT, traits> x,
|
inline bool operator>=(basic_string_view<charT, traits> x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return x.compare(y) >= 0;
|
return x.compare(y) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "sufficient additional overloads of comparison functions"
|
// "sufficient additional overloads of comparison functions"
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator==(basic_string_view<charT, traits> x,
|
inline bool operator==(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x == basic_string_view<charT, traits>(y);
|
return x == basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator==(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator==(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) == y;
|
return basic_string_view<charT, traits>(x) == y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator==(basic_string_view<charT, traits> x,
|
inline bool operator==(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x == basic_string_view<charT, traits>(y);
|
return x == basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator==(const charT * x,
|
inline bool operator==(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) == y;
|
return basic_string_view<charT, traits>(x) == y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator!=(basic_string_view<charT, traits> x,
|
inline bool operator!=(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x != basic_string_view<charT, traits>(y);
|
return x != basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) != y;
|
return basic_string_view<charT, traits>(x) != y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator!=(basic_string_view<charT, traits> x,
|
inline bool operator!=(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x != basic_string_view<charT, traits>(y);
|
return x != basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator!=(const charT * x,
|
inline bool operator!=(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) != y;
|
return basic_string_view<charT, traits>(x) != y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator<(basic_string_view<charT, traits> x,
|
inline bool operator<(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x < basic_string_view<charT, traits>(y);
|
return x < basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator<(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator<(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) < y;
|
return basic_string_view<charT, traits>(x) < y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<(basic_string_view<charT, traits> x,
|
inline bool operator<(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x < basic_string_view<charT, traits>(y);
|
return x < basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<(const charT * x,
|
inline bool operator<(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) < y;
|
return basic_string_view<charT, traits>(x) < y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator>(basic_string_view<charT, traits> x,
|
inline bool operator>(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x > basic_string_view<charT, traits>(y);
|
return x > basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator>(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator>(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) > y;
|
return basic_string_view<charT, traits>(x) > y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>(basic_string_view<charT, traits> x,
|
inline bool operator>(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x > basic_string_view<charT, traits>(y);
|
return x > basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>(const charT * x,
|
inline bool operator>(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) > y;
|
return basic_string_view<charT, traits>(x) > y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator<=(basic_string_view<charT, traits> x,
|
inline bool operator<=(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x <= basic_string_view<charT, traits>(y);
|
return x <= basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) <= y;
|
return basic_string_view<charT, traits>(x) <= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<=(basic_string_view<charT, traits> x,
|
inline bool operator<=(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x <= basic_string_view<charT, traits>(y);
|
return x <= basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator<=(const charT * x,
|
inline bool operator<=(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) <= y;
|
return basic_string_view<charT, traits>(x) <= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator>=(basic_string_view<charT, traits> x,
|
inline bool operator>=(basic_string_view<charT, traits> x,
|
||||||
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {
|
||||||
return x >= basic_string_view<charT, traits>(y);
|
return x >= basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits, typename Allocator>
|
template<typename charT, typename traits, typename Allocator>
|
||||||
inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
|
inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) >= y;
|
return basic_string_view<charT, traits>(x) >= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>=(basic_string_view<charT, traits> x,
|
inline bool operator>=(basic_string_view<charT, traits> x,
|
||||||
const charT * y) BOOST_NOEXCEPT {
|
const charT * y) BOOST_NOEXCEPT {
|
||||||
return x >= basic_string_view<charT, traits>(y);
|
return x >= basic_string_view<charT, traits>(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
inline bool operator>=(const charT * x,
|
inline bool operator>=(const charT * x,
|
||||||
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
basic_string_view<charT, traits> y) BOOST_NOEXCEPT {
|
||||||
return basic_string_view<charT, traits>(x) >= y;
|
return basic_string_view<charT, traits>(x) >= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
inline void insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
inline void sv_insert_fill_chars(std::basic_ostream<charT, traits>& os, std::size_t n) {
|
||||||
enum { chunk_size = 8 };
|
enum { chunk_size = 8 };
|
||||||
charT fill_chars[chunk_size];
|
charT fill_chars[chunk_size];
|
||||||
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill());
|
||||||
@@ -545,19 +570,19 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class charT, class traits>
|
template<class charT, class traits>
|
||||||
void insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
|
void sv_insert_aligned(std::basic_ostream<charT, traits>& os, const basic_string_view<charT,traits>& str) {
|
||||||
const std::size_t size = str.size();
|
const std::size_t size = str.size();
|
||||||
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size;
|
||||||
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
|
||||||
if (!align_left) {
|
if (!align_left) {
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sv_insert_fill_chars(os, alignment_size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
if (os.good())
|
if (os.good())
|
||||||
detail::insert_fill_chars(os, alignment_size);
|
detail::sv_insert_fill_chars(os, alignment_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +599,7 @@ namespace boost {
|
|||||||
if (w <= size)
|
if (w <= size)
|
||||||
os.write(str.data(), size);
|
os.write(str.data(), size);
|
||||||
else
|
else
|
||||||
detail::insert_aligned(os, str);
|
detail::sv_insert_aligned(os, str);
|
||||||
os.width(0);
|
os.width(0);
|
||||||
}
|
}
|
||||||
return os;
|
return os;
|
||||||
|
@@ -38,11 +38,9 @@ namespace
|
|||||||
int true_value(int x) { return x; }
|
int true_value(int x) { return x; }
|
||||||
long true_value(long x) { return x; }
|
long true_value(long x) { return x; }
|
||||||
signed char true_value(signed char x) { return x; }
|
signed char true_value(signed char x) { return x; }
|
||||||
short true_value(short x) { return x; }
|
|
||||||
unsigned int true_value(unsigned int x) { return x; }
|
unsigned int true_value(unsigned int x) { return x; }
|
||||||
unsigned long true_value(unsigned long x) { return x; }
|
unsigned long true_value(unsigned long x) { return x; }
|
||||||
unsigned char true_value(unsigned char x) { return x; }
|
unsigned char true_value(unsigned char x) { return x; }
|
||||||
unsigned short true_value(unsigned short x) { return x; }
|
|
||||||
|
|
||||||
// verify the minimum requirements for some operators
|
// verify the minimum requirements for some operators
|
||||||
class convertible_to_bool
|
class convertible_to_bool
|
||||||
|
@@ -11,7 +11,7 @@ import testing ;
|
|||||||
alias unit_test_framework
|
alias unit_test_framework
|
||||||
: # sources
|
: # sources
|
||||||
/boost//unit_test_framework
|
/boost//unit_test_framework
|
||||||
;
|
;
|
||||||
|
|
||||||
# Please keep the tests ordered by filename
|
# Please keep the tests ordered by filename
|
||||||
test-suite utility
|
test-suite utility
|
||||||
@@ -20,7 +20,7 @@ test-suite utility
|
|||||||
[ run ../base_from_member_ref_test.cpp ]
|
[ run ../base_from_member_ref_test.cpp ]
|
||||||
[ run ../binary_test.cpp ]
|
[ run ../binary_test.cpp ]
|
||||||
[ run ../call_traits_test.cpp : -u ]
|
[ run ../call_traits_test.cpp : -u ]
|
||||||
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ]
|
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
||||||
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
||||||
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ]
|
||||||
[ run ../numeric_traits_test.cpp ]
|
[ run ../numeric_traits_test.cpp ]
|
||||||
@@ -32,7 +32,6 @@ test-suite utility
|
|||||||
[ run string_ref_test_io.cpp unit_test_framework ]
|
[ run string_ref_test_io.cpp unit_test_framework ]
|
||||||
[ run string_view_test1.cpp unit_test_framework ]
|
[ run string_view_test1.cpp unit_test_framework ]
|
||||||
[ run string_view_test2.cpp unit_test_framework ]
|
[ run string_view_test2.cpp unit_test_framework ]
|
||||||
[ run string_view_test3.cpp ]
|
|
||||||
[ run string_view_test_io.cpp unit_test_framework ]
|
[ run string_view_test_io.cpp unit_test_framework ]
|
||||||
[ run ../value_init_test.cpp ]
|
[ run ../value_init_test.cpp ]
|
||||||
[ run ../value_init_workaround_test.cpp ]
|
[ run ../value_init_workaround_test.cpp ]
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ImportGroup Label="PropertySheets" />
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup />
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>../../../../..</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<PostBuildEvent>
|
|
||||||
<Command>"$(TargetDir)\$(TargetName).exe"</Command>
|
|
||||||
</PostBuildEvent>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup />
|
|
||||||
</Project>
|
|
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 14
|
|
||||||
VisualStudioVersion = 14.0.22823.1
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_view_test3", "string_view_test3\string_view_test3.vcxproj", "{4921E3AB-4466-4592-BA7A-3460AD616956}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|x86 = Debug|x86
|
|
||||||
Release|x86 = Release|x86
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{4921E3AB-4466-4592-BA7A-3460AD616956}.Debug|x86.ActiveCfg = Debug|Win32
|
|
||||||
{4921E3AB-4466-4592-BA7A-3460AD616956}.Debug|x86.Build.0 = Debug|Win32
|
|
||||||
{4921E3AB-4466-4592-BA7A-3460AD616956}.Release|x86.ActiveCfg = Release|Win32
|
|
||||||
{4921E3AB-4466-4592-BA7A-3460AD616956}.Release|x86.Build.0 = Release|Win32
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
@@ -1,90 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
|
||||||
<Configuration>Debug</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
|
||||||
<Configuration>Release</Configuration>
|
|
||||||
<Platform>Win32</Platform>
|
|
||||||
</ProjectConfiguration>
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>{4921E3AB-4466-4592-BA7A-3460AD616956}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>string_view_test3</RootNamespace>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v140</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
<Import Project="..\common.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
<Import Project="..\common.props" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<Optimization>Disabled</Optimization>
|
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
|
||||||
<ClCompile>
|
|
||||||
<WarningLevel>Level3</WarningLevel>
|
|
||||||
<PrecompiledHeader>
|
|
||||||
</PrecompiledHeader>
|
|
||||||
<Optimization>MaxSpeed</Optimization>
|
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<SDLCheck>true</SDLCheck>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<SubSystem>Console</SubSystem>
|
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\..\string_view_test3.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
</ImportGroup>
|
|
||||||
</Project>
|
|
@@ -75,7 +75,6 @@ struct context
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -90,7 +89,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types)
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -134,7 +132,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
@@ -153,7 +150,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_ref< char_type > string_ref_type;
|
typedef boost::basic_string_ref< char_type > string_ref_type;
|
||||||
|
|
||||||
|
@@ -7,10 +7,6 @@
|
|||||||
For more information, see http://www.boost.org
|
For more information, see http://www.boost.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
|
||||||
# define _SCL_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@@ -7,14 +7,14 @@
|
|||||||
For more information, see http://www.boost.org
|
For more information, see http://www.boost.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
#include <new> // for placement new
|
||||||
# define _SCL_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring> // for std::strchr
|
#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
|
||||||
|
#include <cstring> // for std::strchr and std::strcmp
|
||||||
|
#include <cstdlib> // for std::malloc and std::free
|
||||||
|
|
||||||
#include <boost/utility/string_view.hpp>
|
#include <boost/utility/string_view.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
#define BOOST_TEST_MAIN
|
#define BOOST_TEST_MAIN
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
@@ -48,7 +48,7 @@ void ends_with ( const char *arg ) {
|
|||||||
if ( sz > 0 )
|
if ( sz > 0 )
|
||||||
BOOST_CHECK ( sr2.ends_with ( ch ));
|
BOOST_CHECK ( sr2.ends_with ( ch ));
|
||||||
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
|
BOOST_CHECK ( !sr2.ends_with ( ++ch ));
|
||||||
BOOST_CHECK ( sr2.ends_with ( string_view ()));
|
BOOST_CHECK ( sr2.ends_with ( string_view()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void starts_with ( const char *arg ) {
|
void starts_with ( const char *arg ) {
|
||||||
@@ -87,7 +87,7 @@ void reverse ( const char *arg ) {
|
|||||||
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
BOOST_CHECK ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This helper function eliminates signed vs. unsigned warnings
|
// This helper function eliminates signed vs. unsigned warnings
|
||||||
string_view::size_type ptr_diff ( const char *res, const char *base ) {
|
string_view::size_type ptr_diff ( const char *res, const char *base ) {
|
||||||
BOOST_CHECK ( res >= base );
|
BOOST_CHECK ( res >= base );
|
||||||
return static_cast<string_view::size_type> ( res - base );
|
return static_cast<string_view::size_type> ( res - base );
|
||||||
@@ -116,7 +116,7 @@ void find ( const char *arg ) {
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for pairs on characters (searching from the start)
|
// Look for pairs on characters (searching from the start)
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
p = arg;
|
p = arg;
|
||||||
while ( *p && *(p+1)) {
|
while ( *p && *(p+1)) {
|
||||||
@@ -130,29 +130,24 @@ void find ( const char *arg ) {
|
|||||||
p = arg;
|
p = arg;
|
||||||
// for all possible chars, see if we find them in the right place.
|
// 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
|
// Note that strchr will/might do the _wrong_ thing if we search for NULL
|
||||||
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
for ( unsigned char ch = 1u; ; ++ch ) {
|
|
||||||
string_view::size_type pos = sr1.find(ch);
|
string_view::size_type pos = sr1.find(ch);
|
||||||
const char *strp = std::strchr ( arg, ch );
|
const char *strp = std::strchr ( arg, ch );
|
||||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
|
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
|
||||||
if ( strp != NULL )
|
if ( strp != NULL )
|
||||||
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
||||||
if (ch == 255u)
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
p = arg;
|
p = arg;
|
||||||
// for all possible chars, see if we find them in the right place.
|
// 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
|
// Note that strchr will/might do the _wrong_ thing if we search for NULL
|
||||||
for ( unsigned char ch = 1u; ; ++ch ) {
|
for ( int ch = 1; ch < 256; ++ch ) {
|
||||||
string_view::size_type pos = sr1.rfind(ch);
|
string_view::size_type pos = sr1.rfind(ch);
|
||||||
const char *strp = std::strrchr ( arg, ch );
|
const char *strp = std::strrchr ( arg, ch );
|
||||||
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
|
BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos ));
|
||||||
if ( strp != NULL )
|
if ( strp != NULL )
|
||||||
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
BOOST_CHECK ( ptr_diff ( strp, arg ) == pos );
|
||||||
if (ch == 255u)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -250,6 +245,86 @@ void find ( const char *arg ) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class custom_allocator {
|
||||||
|
public:
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef void* void_pointer;
|
||||||
|
typedef const void* const_void_pointer;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
|
||||||
|
template<class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef custom_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
custom_allocator() BOOST_NOEXCEPT {}
|
||||||
|
template <typename U>
|
||||||
|
custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
|
||||||
|
|
||||||
|
pointer allocate(size_type n) const {
|
||||||
|
return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
|
||||||
|
}
|
||||||
|
void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
|
||||||
|
std::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer address(reference value) const BOOST_NOEXCEPT {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer address(const_reference value) const BOOST_NOEXCEPT {
|
||||||
|
return &value;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
|
||||||
|
return (~(size_type)0u) / sizeof(value_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
template <class U, class... Args>
|
||||||
|
void construct(U* ptr, Args&&... args) const {
|
||||||
|
::new((void*)ptr) U(static_cast<Args&&>(args)...);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class U, class V>
|
||||||
|
void construct(U* ptr, V&& value) const {
|
||||||
|
::new((void*)ptr) U(static_cast<V&&>(value));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
template <class U, class V>
|
||||||
|
void construct(U* ptr, const V& value) const {
|
||||||
|
::new((void*)ptr) U(value);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
void construct(U* ptr) const {
|
||||||
|
::new((void*)ptr) U();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
void destroy(U* ptr) const {
|
||||||
|
(void)ptr;
|
||||||
|
ptr->~U();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
template <typename T, typename U>
|
||||||
|
BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void to_string ( const char *arg ) {
|
void to_string ( const char *arg ) {
|
||||||
string_view sr1;
|
string_view sr1;
|
||||||
@@ -258,14 +333,17 @@ void to_string ( const char *arg ) {
|
|||||||
|
|
||||||
str1.assign ( arg );
|
str1.assign ( arg );
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
// str2 = sr1.to_string<std::allocator<char> > ();
|
// str2 = sr1.to_string<std::allocator<char> > ();
|
||||||
str2 = sr1.to_string ();
|
str2 = sr1.to_string ();
|
||||||
BOOST_CHECK ( str1 == str2 );
|
BOOST_CHECK ( str1 == str2 );
|
||||||
|
|
||||||
//#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
|
||||||
// std::string str3 = static_cast<std::string> ( sr1 );
|
BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
|
||||||
// BOOST_CHECK ( str1 == str3 );
|
|
||||||
//#endif
|
#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
|
||||||
|
std::string str4 = static_cast<std::string> ( sr1 );
|
||||||
|
BOOST_CHECK ( str1 == str4 );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void compare ( const char *arg ) {
|
void compare ( const char *arg ) {
|
||||||
@@ -275,11 +353,11 @@ void compare ( const char *arg ) {
|
|||||||
|
|
||||||
str1.assign ( arg );
|
str1.assign ( arg );
|
||||||
sr1 = arg;
|
sr1 = arg;
|
||||||
BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view
|
BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view
|
||||||
BOOST_CHECK ( sr1 == str1); // compare string and string_view
|
BOOST_CHECK ( sr1 == str1); // compare string and string_view
|
||||||
BOOST_CHECK ( str1 == sr1 ); // compare string_view and string
|
BOOST_CHECK ( str1 == sr1 ); // compare string_view and string
|
||||||
BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer
|
BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer
|
||||||
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view
|
BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view
|
||||||
|
|
||||||
if ( sr1.size () > 0 ) {
|
if ( sr1.size () > 0 ) {
|
||||||
(*str1.rbegin())++;
|
(*str1.rbegin())++;
|
||||||
|
@@ -1,482 +0,0 @@
|
|||||||
/*
|
|
||||||
<20> Copyright Beman Dawes 2015
|
|
||||||
|
|
||||||
Distributed under the Boost Software License, Version 1.0
|
|
||||||
See http://www.boost.org/LICENSE_1_0.txt
|
|
||||||
|
|
||||||
For more information, see http://www.boost.org
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SCL_SECURE_NO_WARNINGS
|
|
||||||
# define _SCL_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/utility/string_view.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cout
|
|
||||||
#include <boost/core/lightweight_test.hpp>
|
|
||||||
#include <boost/detail/lightweight_main.hpp>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
void swap_test()
|
|
||||||
{
|
|
||||||
std::cout << "swap test..." << std::endl;
|
|
||||||
|
|
||||||
std::string s1("abcdefg");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("xyz");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
boost::string_view sv1_org(sv1);
|
|
||||||
boost::string_view sv2_org(sv2);
|
|
||||||
boost::string_view sv3_org(sv3);
|
|
||||||
|
|
||||||
sv1.swap(sv2);
|
|
||||||
BOOST_TEST_EQ(sv1.data(), sv2_org.data());
|
|
||||||
BOOST_TEST_EQ(sv2.data(), sv1_org.data());
|
|
||||||
BOOST_TEST_EQ(sv1.size(), sv2_org.size());
|
|
||||||
BOOST_TEST_EQ(sv2.size(), sv1_org.size());
|
|
||||||
sv1.swap(sv2);
|
|
||||||
BOOST_TEST_EQ(sv1.data(), sv1_org.data());
|
|
||||||
BOOST_TEST_EQ(sv2.data(), sv2_org.data());
|
|
||||||
BOOST_TEST_EQ(sv1.size(), sv1_org.size());
|
|
||||||
BOOST_TEST_EQ(sv2.size(), sv2_org.size());
|
|
||||||
|
|
||||||
sv3.swap(sv1);
|
|
||||||
BOOST_TEST_EQ(sv3.data(), sv1_org.data());
|
|
||||||
BOOST_TEST_EQ(sv1.data(), sv3_org.data());
|
|
||||||
BOOST_TEST_EQ(sv3.size(), sv1_org.size());
|
|
||||||
BOOST_TEST_EQ(sv1.size(), sv3_org.size());
|
|
||||||
sv3.swap(sv1);
|
|
||||||
BOOST_TEST_EQ(sv1.data(), sv1_org.data());
|
|
||||||
BOOST_TEST_EQ(sv3.data(), sv3_org.data());
|
|
||||||
BOOST_TEST_EQ(sv1.size(), sv1_org.size());
|
|
||||||
BOOST_TEST_EQ(sv3.size(), sv3_org.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_test()
|
|
||||||
{
|
|
||||||
std::cout << "copy test..." << std::endl;
|
|
||||||
|
|
||||||
std::string s1("abcdefg");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
const std::size_t sz = 128u;
|
|
||||||
char a[sz];
|
|
||||||
|
|
||||||
std::fill(a, a + sz, 'x');
|
|
||||||
sv1.copy(a, sv1.size());
|
|
||||||
BOOST_TEST(std::memcmp(sv1.data(), &a, sv1.size()) == 0);
|
|
||||||
const char* p;
|
|
||||||
for (p = a + sv1.size();
|
|
||||||
p != a + sz && *p == 'x'; ++p) {}
|
|
||||||
BOOST_TEST(p == a + sz);
|
|
||||||
|
|
||||||
std::fill(a, a + sz, 'x');
|
|
||||||
sv1.copy(a, sv1.size()-2, 2);
|
|
||||||
BOOST_TEST(std::memcmp(sv1.data()+2, &a, sv1.size()-2) == 0);
|
|
||||||
for (p = a + sv1.size() - 2;
|
|
||||||
p != a + sz && *p == 'x'; ++p) {}
|
|
||||||
BOOST_TEST(p == a + sz);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compare_test()
|
|
||||||
{
|
|
||||||
std::cout << "compare test..." << std::endl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_test()
|
|
||||||
{
|
|
||||||
std::cout << "find test..." << std::endl;
|
|
||||||
|
|
||||||
// find - test two modified and two new signatures
|
|
||||||
std::string s1("ababcab");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("abc");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.find(sv3), s3.find(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3), s1.find(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.find(sv2), s3.find(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, sizeof(s1) + 2), s1.find(s3, sizeof(s1) + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, sizeof(s1) + 1), s1.find(s3, sizeof(s1) + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, sizeof(s1)), s1.find(s3, sizeof(s1)));
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, sizeof(s1)- 1), s1.find(s3, sizeof(s1)- 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv2), s1.find(s2));
|
|
||||||
for (std::string::size_type i = 0; i <= sizeof(s1) + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv2, i), s1.find(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= sizeof(s1) + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, i), s1.find(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= sizeof(s1) + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find('b', i), s1.find('b', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= sizeof(s1) + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= 4; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << " " << j << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find("abc", i, j), s1.find("abc", i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.find("abc"), s1.find("abc"));
|
|
||||||
for (std::string::size_type i = 0; i <= sizeof(s1) + 1; ++i)
|
|
||||||
BOOST_TEST_EQ(sv1.find("abc", i), s1.find("abc", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void rfind_test()
|
|
||||||
{
|
|
||||||
std::cout << "rfind test..." << std::endl;
|
|
||||||
|
|
||||||
// rfind - test two modified and two new signatures
|
|
||||||
std::string s1("ababcab");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("ab");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.rfind(sv3), s3.rfind(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv3), s1.rfind(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.rfind(sv2), s3.rfind(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, s1.size() + 2), s1.find(s3, s1.size() + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find(sv3, s1.size() + 1), s1.find(s3, s1.size() + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv3, s1.size()), s1.rfind(s3, s1.size()));
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv3, s1.size()- 1), s1.rfind(s3, s1.size()- 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv2), s1.rfind(s2));
|
|
||||||
for (std::string::size_type i = s1.size(); i <= s1.size(); --i)
|
|
||||||
{
|
|
||||||
// std::cout << i << ": " << sv1.rfind(sv2, i) << " " << s1.rfind(s2, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv2, i), s1.rfind(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.rfind(sv3, i), s1.rfind(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.rfind('b', i), s1.rfind('b', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= 4; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << " " << j << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.rfind("abc", i, j), s1.rfind("abc", i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.rfind("abc"), s1.rfind("abc"));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
BOOST_TEST_EQ(sv1.rfind("abc", i), s1.rfind("abc", i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_first_of_test()
|
|
||||||
{
|
|
||||||
std::cout << "find_first_of test..." << std::endl;
|
|
||||||
|
|
||||||
// find_first_of - test two modified and two new signatures
|
|
||||||
std::string s1("Hello World!");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("o");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
const char* s2c = "Good Bye";
|
|
||||||
boost::string_view sv2c(s2c);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// smoke test
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv2), s1.find_first_of(s2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv2, 5), s1.find_first_of(s2, 5));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(s2c), s1.find_first_of(s2c));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(s2c, 0, 4), s1.find_first_of(s2c, 0, 4));
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.find_first_of(sv3), s3.find_first_of(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3), s1.find_first_of(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.find_first_of(sv2), s3.find_first_of(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3, s1.size() + 2), s1.find_first_of(s3, s1.size() + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3, s1.size() + 1), s1.find_first_of(s3, s1.size() + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3, s1.size()), s1.find_first_of(s3, s1.size()));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3, s1.size() - 1), s1.find_first_of(s3, s1.size() - 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv2), s1.find_first_of(s2));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_of(sv2, i) << " " << s1.find_first_of(s2, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv2, i), s1.find_first_of(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_of(sv3, i) << " " << s1.find_first_of(s3, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(sv3, i), s1.find_first_of(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_of('o', i) << " " << s1.find_first_of('o', i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of('o', i), s1.find_first_of('o', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= std::strlen(s2c) + 1; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << "," << j << ": " << sv1.find_first_of(s2c, i, j) << " " << s1.find_first_of(s2c, i, j) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(s2c, i, j), s1.find_first_of(s2c, i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(s2c), s1.find_first_of(s2c));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_of(s2c, i) << " " << s1.find_first_of(s2c, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_of(s2c, i), s1.find_first_of(s2c, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_last_of_test()
|
|
||||||
{
|
|
||||||
std::cout << "find_last_of test..." << std::endl;
|
|
||||||
|
|
||||||
// find_last_of - test two modified and two new signatures
|
|
||||||
std::string s1("Hello World!");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("o");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
const char* s2c = "Good Bye";
|
|
||||||
boost::string_view sv2c(s2c);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// smoke test
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv2), s1.find_last_of(s2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv2, 5), s1.find_last_of(s2, 5));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(s2c), s1.find_last_of(s2c));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(s2c, 0, 4), s1.find_last_of(s2c, 0, 4));
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.find_last_of(sv3), s3.find_last_of(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3), s1.find_last_of(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.find_last_of(sv2), s3.find_last_of(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3, s1.size() + 2), s1.find_last_of(s3, s1.size() + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3, s1.size() + 1), s1.find_last_of(s3, s1.size() + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3, s1.size()), s1.find_last_of(s3, s1.size()));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3, s1.size() - 1), s1.find_last_of(s3, s1.size() - 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv2), s1.find_last_of(s2));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_of(sv2, i) << " " << s1.find_last_of(s2, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv2, i), s1.find_last_of(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_of(sv3, i) << " " << s1.find_last_of(s3, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(sv3, i), s1.find_last_of(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_of('o', i) << " " << s1.find_last_of('o', i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of('o', i), s1.find_last_of('o', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= std::strlen(s2c) + 1; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << "," << j << ": " << sv1.find_last_of(s2c, i, j) << " " << s1.find_last_of(s2c, i, j) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(s2c, i, j), s1.find_last_of(s2c, i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(s2c), s1.find_last_of(s2c));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_of(s2c, i) << " " << s1.find_last_of(s2c, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_of(s2c, i), s1.find_last_of(s2c, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_first_not_of_test()
|
|
||||||
{
|
|
||||||
std::cout << "find_first_not_of test..." << std::endl;
|
|
||||||
|
|
||||||
// find_first_not_of - test two modified and two new signatures
|
|
||||||
std::string s1("Hello World!");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("o");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
const char* s2c = "Good Bye";
|
|
||||||
boost::string_view sv2c(s2c);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// smoke test
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv2), s1.find_first_not_of(s2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv2, 5), s1.find_first_not_of(s2, 5));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(s2c), s1.find_first_not_of(s2c));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(s2c, 0, 4), s1.find_first_not_of(s2c, 0, 4));
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.find_first_not_of(sv3), s3.find_first_not_of(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3), s1.find_first_not_of(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.find_first_not_of(sv2), s3.find_first_not_of(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3, s1.size() + 2), s1.find_first_not_of(s3, s1.size() + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3, s1.size() + 1), s1.find_first_not_of(s3, s1.size() + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3, s1.size()), s1.find_first_not_of(s3, s1.size()));
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3, s1.size() - 1), s1.find_first_not_of(s3, s1.size() - 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv2), s1.find_first_not_of(s2));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_not_of(sv2, i) << " " << s1.find_first_not_of(s2, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv2, i), s1.find_first_not_of(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_not_of(sv3, i) << " " << s1.find_first_not_of(s3, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(sv3, i), s1.find_first_not_of(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_not_of('o', i) << " " << s1.find_first_not_of('o', i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of('o', i), s1.find_first_not_of('o', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= std::strlen(s2c) + 1; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << "," << j << ": " << sv1.find_first_not_of(s2c, i, j) << " " << s1.find_first_not_of(s2c, i, j) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(s2c, i, j), s1.find_first_not_of(s2c, i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(s2c), s1.find_first_not_of(s2c));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_first_not_of(s2c, i) << " " << s1.find_first_not_of(s2c, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_first_not_of(s2c, i), s1.find_first_not_of(s2c, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void find_last_not_of_test()
|
|
||||||
{
|
|
||||||
std::cout << "find_last_not_of test..." << std::endl;
|
|
||||||
|
|
||||||
// find_last_not_of - test two modified and two new signatures
|
|
||||||
std::string s1("Hello World!");
|
|
||||||
boost::string_view sv1(s1);
|
|
||||||
std::string s2("o");
|
|
||||||
boost::string_view sv2(s2);
|
|
||||||
const char* s2c = "Good Bye";
|
|
||||||
boost::string_view sv2c(s2c);
|
|
||||||
std::string s3;
|
|
||||||
boost::string_view sv3(s3);
|
|
||||||
|
|
||||||
// smoke test
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv2), s1.find_last_not_of(s2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv2, 5), s1.find_last_not_of(s2, 5));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(s2c), s1.find_last_not_of(s2c));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(s2c, 0, 4), s1.find_last_not_of(s2c, 0, 4));
|
|
||||||
|
|
||||||
// first signature
|
|
||||||
BOOST_TEST_EQ(sv3.find_last_not_of(sv3), s3.find_last_not_of(s3)); // both strings empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3), s1.find_last_not_of(s3)); // search string empty
|
|
||||||
BOOST_TEST_EQ(sv3.find_last_not_of(sv2), s3.find_last_not_of(s2)); // searched string empty
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3, s1.size() + 2), s1.find_last_not_of(s3, s1.size() + 2));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3, s1.size() + 1), s1.find_last_not_of(s3, s1.size() + 1));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3, s1.size()), s1.find_last_not_of(s3, s1.size()));
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3, s1.size() - 1), s1.find_last_not_of(s3, s1.size() - 1));
|
|
||||||
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv2), s1.find_last_not_of(s2));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_not_of(sv2, i) << " " << s1.find_last_not_of(s2, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv2, i), s1.find_last_not_of(s2, i));
|
|
||||||
}
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_not_of(sv3, i) << " " << s1.find_last_not_of(s3, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(sv3, i), s1.find_last_not_of(s3, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// second signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_not_of('o', i) << " " << s1.find_last_not_of('o', i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of('o', i), s1.find_last_not_of('o', i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// third signature
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
for (std::string::size_type j = 0; j <= std::strlen(s2c) + 1; ++j)
|
|
||||||
{
|
|
||||||
//std::cout << i << "," << j << ": " << sv1.find_last_not_of(s2c, i, j) << " " << s1.find_last_not_of(s2c, i, j) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(s2c, i, j), s1.find_last_not_of(s2c, i, j));
|
|
||||||
}
|
|
||||||
|
|
||||||
// fourth signature
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(s2c), s1.find_last_not_of(s2c));
|
|
||||||
for (std::string::size_type i = 0; i <= s1.size() + 1; ++i)
|
|
||||||
{
|
|
||||||
//std::cout << i << ": " << sv1.find_last_not_of(s2c, i) << " " << s1.find_last_not_of(s2c, i) << std::endl;
|
|
||||||
BOOST_TEST_EQ(sv1.find_last_not_of(s2c, i), s1.find_last_not_of(s2c, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unnamed namespace
|
|
||||||
|
|
||||||
int cpp_main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
// verify traits_type and const_pointer typedefs compile OK
|
|
||||||
BOOST_TEST(boost::string_view::traits_type::eq('x', 'x'));
|
|
||||||
BOOST_TEST_EQ(sizeof(boost::string_view::const_pointer), sizeof(&argc));
|
|
||||||
|
|
||||||
swap_test();
|
|
||||||
copy_test();
|
|
||||||
compare_test();
|
|
||||||
find_test();
|
|
||||||
rfind_test();
|
|
||||||
find_first_of_test();
|
|
||||||
find_last_of_test();
|
|
||||||
find_first_not_of_test();
|
|
||||||
find_last_not_of_test();
|
|
||||||
|
|
||||||
return boost::report_errors();
|
|
||||||
}
|
|
@@ -5,14 +5,14 @@
|
|||||||
* http://www.boost.org/LICENSE_1_0.txt)
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
/*!
|
/*!
|
||||||
* \file string_view_test_io.cpp
|
* \file string_ref_test_io.cpp
|
||||||
* \author Andrey Semashev
|
* \author Andrey Semashev
|
||||||
* \date 26.05.2013
|
* \date 26.05.2013
|
||||||
*
|
*
|
||||||
* \brief This header contains tests for stream operations of \c basic_string_view.
|
* \brief This header contains tests for stream operations of \c basic_string_ref.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE string_view_test_io
|
#define BOOST_TEST_MODULE string_ref_test_io
|
||||||
|
|
||||||
#include <boost/utility/string_view.hpp>
|
#include <boost/utility/string_view.hpp>
|
||||||
|
|
||||||
@@ -75,7 +75,6 @@ struct context
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
//typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_view< char_type > string_view_type;
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
@@ -90,7 +89,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types)
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
//typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_view< char_type > string_view_type;
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
@@ -98,35 +96,35 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
|
|
||||||
// Test for padding
|
// Test for padding
|
||||||
{
|
{
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for long padding
|
// Test for long padding
|
||||||
{
|
{
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that short width does not truncate the string
|
// Test that short width does not truncate the string
|
||||||
{
|
{
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,26 +132,24 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types)
|
|||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
//typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_view< char_type > string_view_type;
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
context< char_type > ctx;
|
context< char_type > ctx;
|
||||||
|
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test support for alignment
|
// Test support for alignment
|
||||||
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
||||||
{
|
{
|
||||||
typedef CharT char_type;
|
typedef CharT char_type;
|
||||||
//typedef std::basic_string< char_type > string_type;
|
|
||||||
typedef std::basic_ostringstream< char_type > ostream_type;
|
typedef std::basic_ostringstream< char_type > ostream_type;
|
||||||
typedef boost::basic_string_view< char_type > string_view_type;
|
typedef boost::basic_string_view< char_type > string_view_type;
|
||||||
|
|
||||||
@@ -161,23 +157,23 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types)
|
|||||||
|
|
||||||
// Left alignment
|
// Left alignment
|
||||||
{
|
{
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right alignment
|
// Right alignment
|
||||||
{
|
{
|
||||||
ostream_type strm_view;
|
ostream_type strm_ref;
|
||||||
strm_view << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
|
||||||
|
|
||||||
ostream_type strm_correct;
|
ostream_type strm_correct;
|
||||||
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
|
||||||
|
|
||||||
BOOST_CHECK(strm_view.str() == strm_correct.str());
|
BOOST_CHECK(strm_ref.str() == strm_correct.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user