mirror of
				https://github.com/boostorg/utility.git
				synced 2025-10-31 16:31:48 +01:00 
			
		
		
		
	Compare commits
	
		
			59 Commits
		
	
	
		
			string_vie
			...
			boost-1.65
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 792d0538d2 | ||
|  | 06ae661775 | ||
|  | d9d076874e | ||
|  | e25d85446e | ||
|  | 5bc9e47688 | ||
|  | ec50f22b8b | ||
|  | 592382dc61 | ||
|  | 6cf9c22cf1 | ||
|  | 33475f87e4 | ||
|  | 21261a8630 | ||
|  | 7d60e8e378 | ||
|  | 10ff4d4fcd | ||
|  | 89bf74beee | ||
|  | bfdcce0f97 | ||
|  | 330b49d602 | ||
|  | 68b26cddbe | ||
|  | 6c4ab93573 | ||
|  | 0876da45db | ||
|  | 00f02167e3 | ||
|  | 9960d9f395 | ||
|  | ccfd741c0a | ||
|  | c5c479d49c | ||
|  | 3e8f73c6ac | ||
|  | 38121f2af3 | ||
|  | 38b536ff05 | ||
|  | 9ae6492af9 | ||
|  | 816607e212 | ||
|  | a3ab942bc2 | ||
|  | 0f1f793caf | ||
|  | ff445c0ece | ||
|  | 9fae8be166 | ||
|  | b90a28f0e1 | ||
|  | febca584d9 | ||
|  | 21dc552cf9 | ||
|  | fda210f597 | ||
|  | 3d853b0e83 | ||
|  | 4814d1ebfe | ||
|  | e5932ebb08 | ||
|  | 93a2e25092 | ||
|  | 39577f86d1 | ||
|  | 8392991c46 | ||
|  | c5b1256650 | ||
|  | c56dd13592 | ||
|  | 181f302ee4 | ||
|  | 287844fe76 | ||
|  | 3982b6d633 | ||
|  | 0b492bee9c | ||
|  | a9236d00a9 | ||
|  | 4313bfc323 | ||
|  | f61c94e812 | ||
|  | 1dfacff7ec | ||
|  | a25ac4550b | ||
|  | d767054a79 | ||
|  | 08a1b7da61 | ||
|  | 8ab8e36dcf | ||
|  | 1caa745dd7 | ||
|  | cf5ad341ed | ||
|  | 1f6de83fe2 | ||
|  | cb6500161b | 
							
								
								
									
										400
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,400 @@ | ||||
| # Copyright 2016, 2017 Peter Dimov | ||||
| # Distributed under the Boost Software License, Version 1.0. | ||||
| # (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| language: cpp | ||||
|  | ||||
| sudo: false | ||||
|  | ||||
| python: "2.7" | ||||
|  | ||||
| os: | ||||
|   - linux | ||||
|   - osx | ||||
|  | ||||
| branches: | ||||
|   only: | ||||
|     - master | ||||
|     - develop | ||||
|  | ||||
| env: | ||||
|   matrix: | ||||
|     - BOGUS_JOB=true | ||||
|  | ||||
| matrix: | ||||
|  | ||||
|   exclude: | ||||
|     - env: BOGUS_JOB=true | ||||
|  | ||||
|   include: | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++ CXXSTD=c++03 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-4.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       dist: trusty | ||||
|       env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - g++-7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.5 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.5 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.6 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.6 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|             - libstdc++-5-dev | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-3.9 | ||||
|             - libstdc++-5-dev | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.9 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++03 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++11 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++14 | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|             - libstdc++-6-dev | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: linux | ||||
|       env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=c++1z | ||||
|       addons: | ||||
|         apt: | ||||
|           packages: | ||||
|             - clang-4.0 | ||||
|             - libstdc++-6-dev | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-trusty-4.0 | ||||
|  | ||||
|     - os: osx | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++03 | ||||
|  | ||||
|     - os: osx | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++11 | ||||
|  | ||||
|     - os: osx | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++14 | ||||
|  | ||||
|     - os: osx | ||||
|       env: TOOLSET=clang COMPILER=clang++ CXXSTD=c++1z | ||||
|  | ||||
| install: | ||||
|   - cd .. | ||||
|   - git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root | ||||
|   - cd boost-root | ||||
|   - git submodule update --init tools/build | ||||
|   - git submodule update --init libs/config | ||||
|   - git submodule update --init tools/boostdep | ||||
|   - cp -r $TRAVIS_BUILD_DIR/* libs/utility | ||||
|   - python tools/boostdep/depinst/depinst.py utility | ||||
|   - ./bootstrap.sh | ||||
|   - ./b2 headers | ||||
|  | ||||
| script: | ||||
|   - |- | ||||
|     echo "using $TOOLSET : : $COMPILER : <cxxflags>-std=$CXXSTD ;" > ~/user-config.jam | ||||
|   - ./b2 libs/utility/test toolset=$TOOLSET | ||||
|  | ||||
| notifications: | ||||
|   email: | ||||
|     on_success: always | ||||
| @@ -118,21 +118,10 @@ boostbook standalone_string_ref | ||||
|         <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 | ||||
|      ; | ||||
| ############################################################################### | ||||
| alias boostdoc ; | ||||
| explicit boostdoc ; | ||||
| alias boostrelease : | ||||
|     standalone_base_from_member standalone_compressed_pair | ||||
|     standalone_declval standalone_string_ref ; | ||||
| explicit boostrelease ; | ||||
|   | ||||
| @@ -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,8 +1,11 @@ | ||||
| //  Boost next_prior.hpp header file  ---------------------------------------// | ||||
|  | ||||
| //  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost | ||||
| //  Software License, Version 1.0. (See accompanying file | ||||
| //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
| //  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. | ||||
| //  Copyright (c) Andrey Semashev 2017 | ||||
| // | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  (See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| //  See http://www.boost.org/libs/utility for documentation. | ||||
|  | ||||
| @@ -13,17 +16,14 @@ | ||||
| #define BOOST_NEXT_PRIOR_HPP_INCLUDED | ||||
|  | ||||
| #include <iterator> | ||||
| #if defined(_MSC_VER) && _MSC_VER <= 1310 | ||||
| #include <boost/mpl/and.hpp> | ||||
| #include <boost/type_traits/is_integral.hpp> | ||||
| #endif | ||||
| #include <boost/type_traits/is_unsigned.hpp> | ||||
| #include <boost/type_traits/integral_promotion.hpp> | ||||
| #include <boost/type_traits/make_signed.hpp> | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/core/enable_if.hpp> | ||||
| #include <boost/type_traits/has_plus.hpp> | ||||
| #include <boost/type_traits/has_plus_assign.hpp> | ||||
| #include <boost/type_traits/has_minus.hpp> | ||||
| #include <boost/type_traits/has_minus_assign.hpp> | ||||
| #include <boost/iterator/advance.hpp> | ||||
| #include <boost/iterator/reverse_iterator.hpp> | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| @@ -39,18 +39,36 @@ namespace boost { | ||||
|  | ||||
| namespace next_prior_detail { | ||||
|  | ||||
| template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value > | ||||
| struct next_impl2 | ||||
| // The trait attempts to detect if the T type is an iterator. Class-type iterators are assumed | ||||
| // to have the nested type iterator_category. Strictly speaking, this is not required to be the | ||||
| // case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category). | ||||
| // Still, this is a good heuristic in practice, and we can't do anything better anyway. | ||||
| // Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is | ||||
| // required to be only present for iterators. | ||||
| template< typename T, typename Void = void > | ||||
| struct is_iterator | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
|         std::advance(x, n); | ||||
|         return x; | ||||
|     } | ||||
|     static BOOST_CONSTEXPR_OR_CONST bool value = false; | ||||
| }; | ||||
|  | ||||
| template< typename T > | ||||
| struct is_iterator< T, typename enable_if_has_type< typename T::iterator_category >::type > | ||||
| { | ||||
|     static BOOST_CONSTEXPR_OR_CONST bool value = true; | ||||
| }; | ||||
|  | ||||
| template< typename T > | ||||
| struct is_iterator< T*, void > | ||||
| { | ||||
|     static BOOST_CONSTEXPR_OR_CONST bool value = true; | ||||
| }; | ||||
|  | ||||
|  | ||||
| template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value > | ||||
| struct next_plus_impl; | ||||
|  | ||||
| template< typename T, typename Distance > | ||||
| struct next_impl2< T, Distance, true > | ||||
| struct next_plus_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
| @@ -58,15 +76,14 @@ struct next_impl2< T, Distance, true > | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value > | ||||
| struct next_impl1 : | ||||
|     public next_impl2< T, Distance > | ||||
| struct next_plus_assign_impl : | ||||
|     public next_plus_impl< T, Distance > | ||||
| { | ||||
| }; | ||||
|  | ||||
| template< typename T, typename Distance > | ||||
| struct next_impl1< T, Distance, true > | ||||
| struct next_plus_assign_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
| @@ -75,47 +92,28 @@ struct next_impl1< T, Distance, true > | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| template< | ||||
|     typename T, | ||||
|     typename Distance, | ||||
|     typename PromotedDistance = typename integral_promotion< Distance >::type, | ||||
| #if !defined(_MSC_VER) || _MSC_VER > 1310 | ||||
|     bool IsUInt = is_unsigned< PromotedDistance >::value | ||||
| #else | ||||
|     // MSVC 7.1 has problems with applying is_unsigned to non-integral types | ||||
|     bool IsUInt = mpl::and_< is_integral< PromotedDistance >, is_unsigned< PromotedDistance > >::value | ||||
| #endif | ||||
| > | ||||
| struct prior_impl3 | ||||
| template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value > | ||||
| struct next_advance_impl : | ||||
|     public next_plus_assign_impl< T, Distance > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
|         std::advance(x, -n); | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template< typename T, typename Distance, typename PromotedDistance > | ||||
| struct prior_impl3< T, Distance, PromotedDistance, true > | ||||
| template< typename T, typename Distance > | ||||
| struct next_advance_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
|         typedef typename make_signed< PromotedDistance >::type signed_distance; | ||||
|         std::advance(x, -static_cast< signed_distance >(static_cast< PromotedDistance >(n))); | ||||
|         boost::iterators::advance(x, n); | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value > | ||||
| struct prior_impl2 : | ||||
|     public prior_impl3< T, Distance > | ||||
| { | ||||
| }; | ||||
| struct prior_minus_impl; | ||||
|  | ||||
| template< typename T, typename Distance > | ||||
| struct prior_impl2< T, Distance, true > | ||||
| struct prior_minus_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
| @@ -123,15 +121,14 @@ struct prior_impl2< T, Distance, true > | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value > | ||||
| struct prior_impl1 : | ||||
|     public prior_impl2< T, Distance > | ||||
| struct prior_minus_assign_impl : | ||||
|     public prior_minus_impl< T, Distance > | ||||
| { | ||||
| }; | ||||
|  | ||||
| template< typename T, typename Distance > | ||||
| struct prior_impl1< T, Distance, true > | ||||
| struct prior_minus_assign_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
| @@ -140,6 +137,24 @@ struct prior_impl1< T, Distance, true > | ||||
|     } | ||||
| }; | ||||
|  | ||||
| template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value > | ||||
| struct prior_advance_impl : | ||||
|     public prior_minus_assign_impl< T, Distance > | ||||
| { | ||||
| }; | ||||
|  | ||||
| template< typename T, typename Distance > | ||||
| struct prior_advance_impl< T, Distance, true > | ||||
| { | ||||
|     static T call(T x, Distance n) | ||||
|     { | ||||
|         // Avoid negating n to sidestep possible integer overflow | ||||
|         boost::iterators::reverse_iterator< T > rx(x); | ||||
|         boost::iterators::advance(rx, n); | ||||
|         return rx.base(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } // namespace next_prior_detail | ||||
|  | ||||
| template <class T> | ||||
| @@ -148,7 +163,7 @@ inline T next(T x) { return ++x; } | ||||
| template <class T, class Distance> | ||||
| inline T next(T x, Distance n) | ||||
| { | ||||
|     return next_prior_detail::next_impl1< T, Distance >::call(x, n); | ||||
|     return next_prior_detail::next_advance_impl< T, Distance >::call(x, n); | ||||
| } | ||||
|  | ||||
| template <class T> | ||||
| @@ -157,7 +172,7 @@ inline T prior(T x) { return --x; } | ||||
| template <class T, class Distance> | ||||
| inline T prior(T x, Distance n) | ||||
| { | ||||
|     return next_prior_detail::prior_impl1< T, Distance >::call(x, n); | ||||
|     return next_prior_detail::prior_advance_impl< T, Distance >::call(x, n); | ||||
| } | ||||
|  | ||||
| } // namespace boost | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| //  Boost operators.hpp header file  ----------------------------------------// | ||||
|  | ||||
| //  (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 | ||||
| //  accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
| @@ -8,6 +9,8 @@ | ||||
| //  See http://www.boost.org/libs/utility/operators.htm for documentation. | ||||
|  | ||||
| //  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++ | ||||
| //            (Matthew Bradbury, fixes #4432) | ||||
| //  07 Aug 08 Added "euclidean" spelling. (Daniel Frey) | ||||
| @@ -24,8 +27,8 @@ | ||||
| //            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  | ||||
| //  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 | ||||
| @@ -38,18 +41,18 @@ | ||||
| //  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)  | ||||
| //            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.  | ||||
| //            (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)  | ||||
| //            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 | ||||
| @@ -60,8 +63,8 @@ | ||||
| //  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  | ||||
| // 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 | ||||
| @@ -70,20 +73,28 @@ | ||||
| // 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 | ||||
| // 'is_chained_base<>' (see 'operators_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  | ||||
| // 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  | ||||
| // 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.  | ||||
| // you understand the whole library implementation. | ||||
|  | ||||
| #ifndef 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/iterator.hpp> | ||||
| #include <boost/detail/workaround.hpp> | ||||
|  | ||||
| #if defined(__sgi) && !defined(__GNUC__) | ||||
| @@ -91,35 +102,30 @@ | ||||
| #endif | ||||
|  | ||||
| #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 | ||||
|  | ||||
| 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. | ||||
| // 2-type-argument operator forms, respectively. | ||||
|  | ||||
| #ifndef BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
| 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) ------------------// | ||||
|  | ||||
| //  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> > | ||||
| template <class T, class U, class B = operators_detail::empty_base<T> > | ||||
| struct less_than_comparable2 : B | ||||
| { | ||||
|      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); } | ||||
| }; | ||||
|  | ||||
| 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 | ||||
| { | ||||
|      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); } | ||||
| }; | ||||
|  | ||||
| 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 | ||||
| { | ||||
|      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); } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| template <class T, class B = operators_detail::empty_base<T> > | ||||
| struct equality_comparable1 : B | ||||
| { | ||||
|      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 | ||||
| // 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_COMMUTATIVE( NAME, OP )                   \ | ||||
| template <class T, class U, class B = operators_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 = operators_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> >  \ | ||||
| template <class T, class U, class B = operators_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> >  \ | ||||
| template <class T, class U, class B = operators_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> >           \ | ||||
| template <class T, class B = operators_detail::empty_base<T> >          \ | ||||
| struct NAME##1 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   friend T operator OP( const T& lhs, const T& rhs )                    \ | ||||
| @@ -211,34 +217,34 @@ struct NAME##1 : B                                                      \ | ||||
| // optimization opportunities to the compiler :) | ||||
|  | ||||
| #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                                                      \ | ||||
| {                                                                       \ | ||||
|   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> >           \ | ||||
| template <class T, class B = operators_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> >  \ | ||||
| template <class T, class U, class B = operators_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> >  \ | ||||
| template <class T, class U, class B = operators_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> >           \ | ||||
| template <class T, class B = operators_detail::empty_base<T> >          \ | ||||
| struct NAME##1 : B                                                      \ | ||||
| {                                                                       \ | ||||
|   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 | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| template <class T, class B = operators_detail::empty_base<T> > | ||||
| struct incrementable : B | ||||
| { | ||||
|   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; | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| template <class T, class B = operators_detail::empty_base<T> > | ||||
| struct decrementable : B | ||||
| { | ||||
|   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) ------------------// | ||||
|  | ||||
| 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 | ||||
| { | ||||
|   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 | ||||
| { | ||||
|   R operator[](I n) const | ||||
| @@ -312,34 +318,34 @@ struct indexable : B | ||||
|  | ||||
| #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; }                              \ | ||||
| #define BOOST_BINARY_OPERATOR( NAME, OP )                               \ | ||||
| template <class T, class U, class B = operators_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 = operators_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; }       \ | ||||
| #define BOOST_BINARY_OPERATOR( NAME, OP )                               \ | ||||
| template <class T, class U, class B = operators_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 = operators_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) | ||||
| @@ -349,7 +355,7 @@ BOOST_BINARY_OPERATOR( right_shiftable, >> ) | ||||
|  | ||||
| #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 | ||||
| { | ||||
|   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 | ||||
| { | ||||
|   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 | ||||
| { | ||||
|   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); } | ||||
| }; | ||||
|  | ||||
| template <class T, class B = ::boost::detail::empty_base<T> > | ||||
| template <class T, class B = operators_detail::empty_base<T> > | ||||
| struct partially_ordered1 : B | ||||
| { | ||||
|   friend bool operator>(const T& x, const T& y) | ||||
| @@ -397,161 +403,161 @@ struct partially_ordered1 : B | ||||
|  | ||||
| //  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 | ||||
|     : less_than_comparable2<T, U | ||||
|     , 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 | ||||
|     : less_than_comparable1<T | ||||
|     , 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 | ||||
|     : addable2<T, U | ||||
|     , 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 | ||||
|     : addable1<T | ||||
|     , 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 | ||||
|     : multipliable2<T, U | ||||
|     , 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 | ||||
|     : multipliable1<T | ||||
|     , 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 | ||||
|     : multiplicative2<T, U | ||||
|     , 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 | ||||
|     : multiplicative1<T | ||||
|     , 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 | ||||
|     : additive2<T, U | ||||
|     , 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 | ||||
|     : additive1<T | ||||
|     , 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 | ||||
|     : additive2<T, U | ||||
|     , 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 | ||||
|     : additive1<T | ||||
|     , 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 | ||||
|     : xorable2<T, U | ||||
|     , andable2<T, U | ||||
|     , 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 | ||||
|     : xorable1<T | ||||
|     , andable1<T | ||||
|     , 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 | ||||
|     : incrementable<T | ||||
|     , 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 | ||||
|     : left_shiftable2<T, U | ||||
|     , 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 | ||||
|     : left_shiftable1<T | ||||
|     , 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 | ||||
|     : additive2<T, U | ||||
|     , subtractable2_left<T, U | ||||
|     , 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 | ||||
|     : additive1<T | ||||
|     , 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 | ||||
|     : ring_operators2<T, U | ||||
|     , 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 | ||||
|     : ring_operators1<T | ||||
|     , 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 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
|     , 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 | ||||
|     : ring_operators1<T | ||||
|     , 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 | ||||
|     : field_operators2<T, U | ||||
|     , 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 | ||||
|     : field_operators1<T | ||||
|     , 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 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
| @@ -560,26 +566,26 @@ struct euclidian_ring_operators2 | ||||
|     , 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 | ||||
|     : ring_operators1<T | ||||
|     , dividable1<T | ||||
|     , 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 | ||||
|     : totally_ordered2<T, U | ||||
|     , 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 | ||||
|     : totally_ordered1<T | ||||
|     , 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 | ||||
|     : ring_operators2<T, U | ||||
|     , dividable2<T, U | ||||
| @@ -588,43 +594,43 @@ struct euclidean_ring_operators2 | ||||
|     , 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 | ||||
|     : ring_operators1<T | ||||
|     , dividable1<T | ||||
|     , 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 | ||||
|     : totally_ordered2<T, U | ||||
|     , 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 | ||||
|     : totally_ordered1<T | ||||
|     , 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 | ||||
|     : equality_comparable1<T | ||||
|     , incrementable<T | ||||
|     , 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 | ||||
|     : 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 | ||||
|     : 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 | ||||
|     : forward_iteratable<T, P | ||||
|     , decrementable<T, B | ||||
| @@ -634,7 +640,7 @@ struct bidirectional_iteratable | ||||
| //  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> > | ||||
| template <class T, class P, class D, class R, class B = operators_detail::empty_base<T> > | ||||
| struct random_access_iteratable | ||||
|     : bidirectional_iteratable<T, P | ||||
|     , less_than_comparable1<T | ||||
| @@ -642,124 +648,64 @@ struct random_access_iteratable | ||||
|     , 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. | ||||
| // Here's where we put it all together, defining the xxxx forms of the templates. | ||||
| // We also define specializations of is_chained_base<> for | ||||
| // the xxxx, xxxx1, and xxxx2 templates. | ||||
| // | ||||
|  | ||||
| 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 | ||||
| // 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; | ||||
|   typedef operators_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;                            \ | ||||
| // Provide a specialization of 'is_chained_base<>' | ||||
| // for a 4-type-argument operator template. | ||||
| # define BOOST_OPERATOR_TEMPLATE4(template_name4)           \ | ||||
|   template<class T, class U, class V, class W, class B>     \ | ||||
|   struct is_chained_base< template_name4<T, U, V, W, B> > { \ | ||||
|     typedef operators_detail::true_t value;                 \ | ||||
|   }; | ||||
|  | ||||
| // Import a 3-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' 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;                            \ | ||||
| // Provide a specialization of 'is_chained_base<>' | ||||
| // for a 3-type-argument operator template. | ||||
| # define BOOST_OPERATOR_TEMPLATE3(template_name3)        \ | ||||
|   template<class T, class U, class V, class B>           \ | ||||
|   struct is_chained_base< template_name3<T, U, V, B> > { \ | ||||
|     typedef operators_detail::true_t value;              \ | ||||
|   }; | ||||
|  | ||||
| // Import a 2-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' 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;                         \ | ||||
| // Provide a specialization of 'is_chained_base<>' | ||||
| // for a 2-type-argument operator template. | ||||
| # define BOOST_OPERATOR_TEMPLATE2(template_name2)     \ | ||||
|   template<class T, class U, class B>                 \ | ||||
|   struct is_chained_base< template_name2<T, U, B> > { \ | ||||
|     typedef operators_detail::true_t value;           \ | ||||
|   }; | ||||
|  | ||||
| // Import a 1-type-argument operator template into boost (if necessary) and | ||||
| // provide a specialization of 'is_chained_base<>' 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;                         \ | ||||
| // Provide a specialization of 'is_chained_base<>' | ||||
| // for a 1-type-argument operator template. | ||||
| # define BOOST_OPERATOR_TEMPLATE1(template_name1)  \ | ||||
|   template<class T, class B>                       \ | ||||
|   struct is_chained_base< template_name1<T, B> > { \ | ||||
|     typedef operators_detail::true_t value;        \ | ||||
|   }; | ||||
|  | ||||
| // 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'. | ||||
| // | ||||
|  | ||||
| # 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)                         \ | ||||
| # define BOOST_OPERATOR_TEMPLATE(template_name)                                       \ | ||||
| template <class T                                                                     \ | ||||
|          ,class U = T                                                                 \ | ||||
|          ,class B = operators_detail::empty_base<T>                                   \ | ||||
|          ,class O = typename is_chained_base<U>::value                                \ | ||||
|          >                                                                            \ | ||||
| struct template_name;                                                                 \ | ||||
|                                                                                       \ | ||||
| template<class T, class U, class B>                                                   \ | ||||
| struct template_name<T, U, B, operators_detail::false_t>                              \ | ||||
|   : template_name##2<T, U, B> {};                                                     \ | ||||
|                                                                                       \ | ||||
| template<class T, class U>                                                            \ | ||||
| struct template_name<T, U, operators_detail::empty_base<T>, operators_detail::true_t> \ | ||||
|   : template_name##1<T, U> {};                                                        \ | ||||
|                                                                                       \ | ||||
| template <class T, class B>                                                           \ | ||||
| struct template_name<T, T, B, operators_detail::false_t>                              \ | ||||
|   : template_name##1<T, B> {};                                                        \ | ||||
|                                                                                       \ | ||||
| template<class T, class U, class B, class O>                                          \ | ||||
| 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) | ||||
|  | ||||
|  | ||||
|  | ||||
| namespace boost { | ||||
|      | ||||
| BOOST_OPERATOR_TEMPLATE(less_than_comparable) | ||||
| BOOST_OPERATOR_TEMPLATE(equality_comparable) | ||||
| BOOST_OPERATOR_TEMPLATE(multipliable) | ||||
| @@ -857,13 +803,7 @@ BOOST_OPERATOR_TEMPLATE4(random_access_iteratable) | ||||
| #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 | ||||
| @@ -891,13 +831,13 @@ template <class T, | ||||
|           class R = V const &> | ||||
| struct input_iterator_helper | ||||
|   : 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> | ||||
| struct output_iterator_helper | ||||
|   : 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); } | ||||
| @@ -911,7 +851,7 @@ template <class T, | ||||
|           class R = V&> | ||||
| struct forward_iterator_helper | ||||
|   : 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, | ||||
| @@ -921,17 +861,17 @@ template <class T, | ||||
|           class R = V&> | ||||
| struct bidirectional_iterator_helper | ||||
|   : 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, | ||||
|           class V,  | ||||
|           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 | ||||
|   , 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) { | ||||
| @@ -939,10 +879,14 @@ struct random_access_iterator_helper | ||||
|   } | ||||
| }; // random_access_iterator_helper | ||||
|  | ||||
| } // namespace operators_impl | ||||
| using namespace operators_impl; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #if defined(__sgi) && !defined(__GNUC__) | ||||
| #pragma reset woff 1234 | ||||
| #endif | ||||
|  | ||||
| #endif // BOOST_NO_OPERATORS_IN_NAMESPACE | ||||
| #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 | ||||
| @@ -14,8 +14,8 @@ | ||||
| #include <boost/utility/binary.hpp> | ||||
| #include <boost/utility/enable_if.hpp> | ||||
| #include <boost/utility/identity_type.hpp> | ||||
| #include <boost/checked_delete.hpp> | ||||
| #include <boost/core/checked_delete.hpp> | ||||
| #include <boost/core/noncopyable.hpp> | ||||
| #include <boost/next_prior.hpp> | ||||
| #include <boost/noncopyable.hpp> | ||||
|  | ||||
| #endif  // BOOST_UTILITY_HPP | ||||
|   | ||||
| @@ -47,11 +47,11 @@ | ||||
| //         {} | ||||
| // This macro should only persist within this file. | ||||
|  | ||||
| #define BOOST_PRIVATE_CTR_DEF( z, n, data )                            \ | ||||
|     template < BOOST_PP_ENUM_PARAMS(n, typename T) >                   \ | ||||
|     explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) )  \ | ||||
|         : member( BOOST_PP_ENUM_PARAMS(n, x) )                         \ | ||||
|         {}                                                             \ | ||||
| #define BOOST_PRIVATE_CTR_DEF( z, n, data )                   \ | ||||
|     template < BOOST_PP_ENUM_PARAMS(n, typename T) >          \ | ||||
|     base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) )  \ | ||||
|         : member( BOOST_PP_ENUM_PARAMS(n, x) )                \ | ||||
|         {}                                                    \ | ||||
|     /**/ | ||||
|  | ||||
|  | ||||
| @@ -142,7 +142,8 @@ protected: | ||||
|         : 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, _ ) | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -33,8 +33,12 @@ bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y ) | ||||
| } | ||||
|  | ||||
| template<class OptionalPointee> | ||||
| struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> | ||||
| struct equal_pointees_t | ||||
| { | ||||
|   typedef bool result_type; | ||||
|   typedef OptionalPointee first_argument_type; | ||||
|   typedef OptionalPointee second_argument_type; | ||||
|  | ||||
|   bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const | ||||
|     { return equal_pointees(x,y) ; } | ||||
| } ; | ||||
| @@ -56,8 +60,12 @@ bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y ) | ||||
| } | ||||
|  | ||||
| template<class OptionalPointee> | ||||
| struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> | ||||
| struct less_pointees_t | ||||
| { | ||||
|   typedef bool result_type; | ||||
|   typedef OptionalPointee first_argument_type; | ||||
|   typedef OptionalPointee second_argument_type; | ||||
|  | ||||
|   bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const | ||||
|     { return less_pointees(x,y) ; } | ||||
| } ; | ||||
|   | ||||
| @@ -201,6 +201,11 @@ struct tr1_result_of_impl<F, FArgs, false> | ||||
| #define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>)) | ||||
| #include BOOST_PP_ITERATE() | ||||
|  | ||||
| #if 0 | ||||
| // inform dependency trackers, as they can't see through macro includes | ||||
| #include <boost/utility/detail/result_of_iterate.hpp> | ||||
| #endif | ||||
|  | ||||
| #else | ||||
| #  define BOOST_NO_RESULT_OF 1 | ||||
| #endif | ||||
|   | ||||
| @@ -27,6 +27,11 @@ | ||||
| #include <string> | ||||
| #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 detail { | ||||
| @@ -57,26 +62,44 @@ namespace boost { | ||||
|         static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); | ||||
|  | ||||
|         // construct/copy | ||||
|         BOOST_CONSTEXPR basic_string_ref () | ||||
|         BOOST_CONSTEXPR basic_string_ref () BOOST_NOEXCEPT | ||||
|             : 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_) {} | ||||
| #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_; | ||||
|             len_ = rhs.len_; | ||||
|             return *this; | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         basic_string_ref(const charT* str) | ||||
|         basic_string_ref(const charT* str) BOOST_NOEXCEPT | ||||
|             : ptr_(str), len_(traits::length(str)) {} | ||||
|  | ||||
|         template<typename Allocator> | ||||
|         basic_string_ref(const std::basic_string<charT, traits, Allocator>& str) | ||||
|             : ptr_(str.data()), len_(str.length()) {} | ||||
|  | ||||
|         BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) | ||||
| // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| //         // Constructing a string_ref from a temporary string is a bad idea | ||||
| //         template<typename Allocator> | ||||
| //         basic_string_ref(      std::basic_string<charT, traits, Allocator>&&) | ||||
| //             = delete; | ||||
| // #endif | ||||
|  | ||||
|         BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) BOOST_NOEXCEPT | ||||
|             : ptr_(str), len_(len) {} | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
| @@ -139,9 +162,7 @@ namespace boost { | ||||
|         basic_string_ref substr(size_type pos, size_type n=npos) const { | ||||
|             if ( pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) ); | ||||
|             if ( n == npos || pos + n > size()) | ||||
|                 n = size () - pos; | ||||
|             return basic_string_ref ( data() + pos, n ); | ||||
|             return basic_string_ref(data() + pos, (std::min)(size() - pos, n)); | ||||
|             } | ||||
|  | ||||
|         int compare(basic_string_ref x) const { | ||||
| @@ -174,13 +195,13 @@ namespace boost { | ||||
|         size_type rfind(basic_string_ref s) const { | ||||
|             const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), | ||||
|                                                 s.crbegin (), s.crend (), traits::eq ); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             return iter == this->crend () ? npos : (std::distance(iter, this->crend()) - s.size()); | ||||
|             } | ||||
|  | ||||
|         size_type rfind(charT c) const { | ||||
|             const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), | ||||
|                                     detail::string_ref_traits_eq<charT, traits> ( c )); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); | ||||
|             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter)); | ||||
|             } | ||||
|  | ||||
|         size_type find_first_of(charT c) const { return  find (c); } | ||||
| @@ -195,7 +216,7 @@ namespace boost { | ||||
|         size_type find_last_of(basic_string_ref s) const { | ||||
|             const_reverse_iterator iter = std::find_first_of | ||||
|                 ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq ); | ||||
|             return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); | ||||
|             return iter == this->crend () ? npos : (this->size() - 1 - std::distance(this->crbegin(), iter)); | ||||
|             } | ||||
|  | ||||
|         size_type find_first_not_of(basic_string_ref s) const { | ||||
| @@ -212,21 +233,17 @@ namespace boost { | ||||
|  | ||||
|         size_type find_last_not_of(basic_string_ref s) const { | ||||
|             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 { | ||||
|             for ( const_reverse_iterator iter = this->crbegin (); iter != this->crend (); ++iter ) | ||||
|                 if ( !traits::eq ( c, *iter )) | ||||
|                     return reverse_distance ( this->crbegin (), iter ); | ||||
|                     return this->size() - 1 - std::distance(this->crbegin(), iter); | ||||
|             return npos; | ||||
|             } | ||||
|  | ||||
|     private: | ||||
|         template <typename r_iter> | ||||
|         size_type reverse_distance ( r_iter first, r_iter last ) const { | ||||
|             return len_ - 1 - std::distance ( first, last ); | ||||
|             } | ||||
|  | ||||
|         template <typename Iterator> | ||||
|         Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const { | ||||
| @@ -405,7 +422,7 @@ namespace boost { | ||||
|     namespace detail { | ||||
|  | ||||
|         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 }; | ||||
|             charT fill_chars[chunk_size]; | ||||
|             std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill()); | ||||
| @@ -416,19 +433,19 @@ namespace boost { | ||||
|             } | ||||
|  | ||||
|         template<class charT, class traits> | ||||
|         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 alignment_size = static_cast< std::size_t >(os.width()) - size; | ||||
|             const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left; | ||||
|             if (!align_left) { | ||||
|                 detail::insert_fill_chars(os, alignment_size); | ||||
|                 detail::sr_insert_fill_chars(os, alignment_size); | ||||
|                 if (os.good()) | ||||
|                     os.write(str.data(), size); | ||||
|                 } | ||||
|             else { | ||||
|                 os.write(str.data(), size); | ||||
|                 if (os.good()) | ||||
|                     detail::insert_fill_chars(os, alignment_size); | ||||
|                     detail::sr_insert_fill_chars(os, alignment_size); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -444,7 +461,7 @@ namespace boost { | ||||
|             if (w <= size) | ||||
|                 os.write(str.data(), size); | ||||
|             else | ||||
|                 detail::insert_aligned(os, str); | ||||
|                 detail::sr_insert_aligned(os, str); | ||||
|             os.width(0); | ||||
|             } | ||||
|         return os; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* | ||||
|    <20> Copyright (c) Marshall Clow 2012-2015. | ||||
|    <20> Copyright Beman Dawes 2015 | ||||
|    Copyright (c) Marshall Clow 2012-2015. | ||||
|    Copyright (c) Beman Dawes 2015 | ||||
|  | ||||
|    Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
| @@ -30,6 +30,11 @@ | ||||
| #include <cstring> | ||||
| #include <iosfwd> | ||||
|  | ||||
| #if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || (defined(BOOST_GCC) && ((BOOST_GCC+0) / 100) <= 406) | ||||
| // GCC 4.6 cannot handle a defaulted function with noexcept specifier | ||||
| #define BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
| #endif | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     namespace detail { | ||||
| @@ -38,7 +43,7 @@ namespace boost { | ||||
|         class string_view_traits_eq { | ||||
|         public: | ||||
|             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_; | ||||
|             }; | ||||
|         } | ||||
| @@ -47,37 +52,54 @@ namespace boost { | ||||
|     class basic_string_view { | ||||
|     public: | ||||
|       // types | ||||
|       typedef traits traits_type; | ||||
|       typedef charT value_type; | ||||
|       typedef charT* pointer; | ||||
|       typedef const charT* const_pointer; | ||||
|       typedef charT& reference; | ||||
|       typedef const charT& const_reference; | ||||
|       typedef const_pointer const_iterator; // impl-defined | ||||
|       typedef const_iterator iterator; | ||||
|       typedef traits                                traits_type; | ||||
|       typedef charT                                 value_type; | ||||
|       typedef charT*                                pointer; | ||||
|       typedef const charT*                          const_pointer; | ||||
|       typedef charT&                                reference; | ||||
|       typedef const charT&                          const_reference; | ||||
|       typedef const_pointer                         const_iterator; // impl-defined | ||||
|       typedef const_iterator                        iterator; | ||||
|       typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | ||||
|       typedef const_reverse_iterator reverse_iterator; | ||||
|       typedef std::size_t size_type; | ||||
|       typedef std::ptrdiff_t difference_type; | ||||
|       static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); | ||||
|       typedef const_reverse_iterator                reverse_iterator; | ||||
|       typedef std::size_t                           size_type; | ||||
|       typedef std::ptrdiff_t                        difference_type; | ||||
|       static BOOST_CONSTEXPR_OR_CONST size_type     npos = size_type(-1); | ||||
|  | ||||
|       // construct/copy | ||||
|       BOOST_CONSTEXPR basic_string_view() BOOST_NOEXCEPT | ||||
|         : ptr_(NULL), len_(0) {} | ||||
|  | ||||
|       // by defaulting these functions, basic_string_ref becomes | ||||
|       //  trivially copy/move constructible. | ||||
|       BOOST_CONSTEXPR basic_string_view(const basic_string_view &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|         = default; | ||||
| #else | ||||
|         : ptr_(rhs.ptr_), len_(rhs.len_) {} | ||||
| #endif | ||||
|  | ||||
|       basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT { | ||||
|       basic_string_view& operator=(const basic_string_view &rhs) BOOST_NOEXCEPT | ||||
| #ifndef BOOST_STRING_VIEW_NO_CXX11_DEFAULTED_NOEXCEPT_FUNCTIONS | ||||
|             = default; | ||||
| #else | ||||
|         { | ||||
|         ptr_ = rhs.ptr_; | ||||
|         len_ = rhs.len_; | ||||
|         return *this; | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|       template<typename Allocator> | ||||
|         basic_string_view(const std::basic_string<charT, traits, | ||||
|           Allocator>& str) BOOST_NOEXCEPT | ||||
|         : ptr_(str.data()), len_(str.length()) {} | ||||
|         basic_string_view(const std::basic_string<charT, traits, Allocator>& str) BOOST_NOEXCEPT | ||||
|           : ptr_(str.data()), len_(str.length()) {} | ||||
|  | ||||
| // #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| //       // Constructing a string_view from a temporary string is a bad idea | ||||
| //       template<typename Allocator> | ||||
| //         basic_string_view(      std::basic_string<charT, traits, Allocator>&&) | ||||
| //           = delete; | ||||
| // #endif | ||||
|  | ||||
|       BOOST_CONSTEXPR basic_string_view(const charT* str) | ||||
|         : ptr_(str), len_(traits::length(str)) {} | ||||
| @@ -86,33 +108,31 @@ namespace boost { | ||||
|         : ptr_(str), len_(len) {} | ||||
|  | ||||
|         // iterators | ||||
|         BOOST_CONSTEXPR const_iterator   begin() const BOOST_NOEXCEPT {  return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator  cbegin() const BOOST_NOEXCEPT {  return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator     end() const BOOST_NOEXCEPT {  return ptr_ + len_; } | ||||
|         BOOST_CONSTEXPR const_iterator    cend() const BOOST_NOEXCEPT {  return ptr_ + len_; } | ||||
|                 const_reverse_iterator  rbegin() const BOOST_NOEXCEPT {  return const_reverse_iterator (end()); } | ||||
|                 const_reverse_iterator crbegin() const BOOST_NOEXCEPT {  return const_reverse_iterator (end()); } | ||||
|                 const_reverse_iterator    rend() const BOOST_NOEXCEPT {  return const_reverse_iterator (begin()); } | ||||
|                 const_reverse_iterator   crend() const BOOST_NOEXCEPT {  return const_reverse_iterator (begin()); } | ||||
|         BOOST_CONSTEXPR const_iterator   begin() const BOOST_NOEXCEPT { return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator  cbegin() const BOOST_NOEXCEPT { return ptr_; } | ||||
|         BOOST_CONSTEXPR const_iterator     end() const BOOST_NOEXCEPT { return ptr_ + len_; } | ||||
|         BOOST_CONSTEXPR const_iterator    cend() const BOOST_NOEXCEPT { return ptr_ + len_; } | ||||
|                 const_reverse_iterator  rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } | ||||
|                 const_reverse_iterator crbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); } | ||||
|                 const_reverse_iterator    rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } | ||||
|                 const_reverse_iterator   crend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); } | ||||
|  | ||||
|         // capacity | ||||
|         BOOST_CONSTEXPR size_type size()     const BOOST_NOEXCEPT {  return len_; } | ||||
|         BOOST_CONSTEXPR size_type length()   const BOOST_NOEXCEPT {  return len_; } | ||||
|         BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {  return len_; } | ||||
|         BOOST_CONSTEXPR bool empty()         const BOOST_NOEXCEPT {  return len_ == 0; } | ||||
|         BOOST_CONSTEXPR size_type size()     const BOOST_NOEXCEPT { return len_; } | ||||
|         BOOST_CONSTEXPR size_type length()   const BOOST_NOEXCEPT { return len_; } | ||||
|         BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT { return len_; } | ||||
|         BOOST_CONSTEXPR bool empty()         const BOOST_NOEXCEPT { return len_ == 0; } | ||||
|  | ||||
|         // element access | ||||
|         BOOST_CONSTEXPR const_reference operator[](size_type pos) const { 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 { | ||||
|             if ( pos >= len_ ) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_view::at" ) ); | ||||
|             return ptr_[pos]; | ||||
|             return pos >= len_ ? BOOST_THROW_EXCEPTION(std::out_of_range("boost::string_view::at")), ptr_[0] : ptr_[pos]; | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR const_reference front() const { return ptr_[0]; } | ||||
|         BOOST_CONSTEXPR const_reference back()  const { return ptr_[len_-1]; } | ||||
|         BOOST_CONSTEXPR const_pointer data()  const BOOST_NOEXCEPT { return ptr_; } | ||||
|         BOOST_CONSTEXPR const_reference front() const                { return ptr_[0]; } | ||||
|         BOOST_CONSTEXPR const_reference back()  const                { return ptr_[len_-1]; } | ||||
|         BOOST_CONSTEXPR const_pointer data()    const BOOST_NOEXCEPT { return ptr_; } | ||||
|  | ||||
|         // modifiers | ||||
|         void clear() BOOST_NOEXCEPT { len_ = 0; }          // Boost extension | ||||
| @@ -135,9 +155,7 @@ namespace boost { | ||||
|             std::swap(len_, s.len_); | ||||
|             } | ||||
|  | ||||
|  | ||||
|         // basic_string_view string operations | ||||
|   | ||||
| #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
|         template<typename Allocator> | ||||
|         explicit operator std::basic_string<charT, traits, Allocator>() const { | ||||
| @@ -147,71 +165,78 @@ namespace boost { | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS | ||||
|         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); | ||||
|             } | ||||
| #else | ||||
|         std::basic_string<charT, traits> to_string() const { | ||||
|             return std::basic_string<charT, traits>(begin(), end()); | ||||
|             } | ||||
|  | ||||
|         template<typename Allocator> | ||||
|         std::basic_string<charT, traits, Allocator> to_string(const Allocator& a) const { | ||||
|             return std::basic_string<charT, traits, Allocator>(begin(), end(), a); | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|         size_type copy( charT* s, size_type n, size_type pos = 0 ) const { | ||||
|             if ( pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::copy" ) ); | ||||
|         size_type copy(charT* s, size_type n, size_type pos=0) const { | ||||
|             if (pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION(std::out_of_range("string_view::copy" )); | ||||
|             size_type rlen = (std::min)(n, len_ - pos); | ||||
|             // 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(begin() + pos, begin() + pos + rlen, s); | ||||
|     		traits_type::copy(s, data() + pos, rlen); | ||||
|             return rlen; | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const { | ||||
|             if ( pos > size()) | ||||
|                 BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) ); | ||||
|             if ( n == npos || pos + n > size()) | ||||
|                 n = size () - pos; | ||||
|             return basic_string_view ( data() + pos, n ); | ||||
|             return basic_string_view(data() + pos, (std::min)(size() - pos, n)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(basic_string_view x) const BOOST_NOEXCEPT { | ||||
|             const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_)); | ||||
|             return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 ); | ||||
|             const int cmp = traits::compare(ptr_, x.ptr_, (std::min)(len_, x.len_)); | ||||
|             return cmp != 0 ? cmp : (len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, basic_string_view x) | ||||
|           const BOOST_NOEXCEPT { | ||||
|             return substr(pos1, n1).compare(x); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, | ||||
|           basic_string_view x, size_type pos2, size_type n2) const { | ||||
|             return substr(pos1, n1).compare(x.substr(pos2, n2)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(const charT* x) const { | ||||
|             return compare(basic_string_view(x)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, const charT* x) const { | ||||
|             return substr(pos1, n1).compare(basic_string_view(x)); | ||||
|             } | ||||
|  | ||||
|         BOOST_CXX14_CONSTEXPR int compare(size_type pos1, size_type n1, | ||||
|           const charT* x, size_type n2) const { | ||||
|             return substr(pos1, n1).compare(basic_string_view(x, n2)); | ||||
|             } | ||||
|  | ||||
|         //  Searches | ||||
|  | ||||
|         BOOST_CONSTEXPR bool starts_with(charT c) const {  // Boost extension | ||||
|             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 starts_with(charT c) const BOOST_NOEXCEPT {              // Boost extension | ||||
|             return !empty() && traits::eq(c, front()); | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR bool ends_with(charT c) const { | ||||
|             return !empty() && traits::eq ( c, back());  // Boost extension | ||||
|         BOOST_CONSTEXPR bool starts_with(basic_string_view x) const BOOST_NOEXCEPT {  // Boost extension | ||||
|             return len_ >= x.len_ && traits::compare(ptr_, x.ptr_, x.len_) == 0; | ||||
|             } | ||||
|         BOOST_CONSTEXPR bool ends_with(basic_string_view x) const {  // Boost extension | ||||
|             return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, | ||||
|               x.ptr_, x.len_ ) == 0; | ||||
|  | ||||
|         BOOST_CONSTEXPR bool ends_with(charT c) const BOOST_NOEXCEPT {                // Boost extension | ||||
|             return !empty() && traits::eq(c, back()); | ||||
|             } | ||||
|  | ||||
|         BOOST_CONSTEXPR bool ends_with(basic_string_view x) const BOOST_NOEXCEPT {    // Boost extension | ||||
|             return len_ >= x.len_ && | ||||
|                traits::compare(ptr_ + len_ - x.len_, x.ptr_, x.len_) == 0; | ||||
|             } | ||||
|  | ||||
|         //  find | ||||
| @@ -221,25 +246,25 @@ namespace boost { | ||||
|             if (s.empty()) | ||||
|               return pos; | ||||
|             const_iterator iter = std::search(this->cbegin() + pos, this->cend(), | ||||
|                                                s.cbegin (), s.cend (), traits::eq ); | ||||
|             return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); | ||||
|                                                s.cbegin (), s.cend (), traits::eq); | ||||
|             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 | ||||
|             { 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); } | ||||
|         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); } | ||||
|  | ||||
|         //  rfind | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { | ||||
|             if (len_ < s.len_) | ||||
|               return npos; | ||||
|             if (pos > len_ - s.len_)  | ||||
|             if (pos > len_ - s.len_) | ||||
|               pos = len_ - s.len_; | ||||
|             if (s.len_ == 0u)     // an empty string is always found | ||||
|               return pos; | ||||
|             for (const charT* cur = ptr_ + pos;; --cur) { | ||||
|             for (const charT* cur = ptr_ + pos; ; --cur) { | ||||
|                 if (traits::compare(cur, s.ptr_, s.len_) == 0) | ||||
|                   return cur - ptr_; | ||||
|                 if (cur == ptr_) | ||||
| @@ -248,9 +273,9 @@ namespace boost { | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type rfind(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return rfind(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_first_of | ||||
| @@ -263,9 +288,9 @@ namespace boost { | ||||
|             } | ||||
|         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); } | ||||
|         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); } | ||||
|         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); } | ||||
|  | ||||
|         //  find_last_of | ||||
| @@ -282,9 +307,9 @@ namespace boost { | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_of(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_first_not_of | ||||
| @@ -298,15 +323,15 @@ namespace boost { | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(charT c, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_first_not_of(const charT* s, size_type pos = 0) const BOOST_NOEXCEPT | ||||
|             { return find_first_not_of(basic_string_view(s), pos); } | ||||
|  | ||||
|         //  find_last_not_of | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(basic_string_view s, size_type pos = npos) const BOOST_NOEXCEPT { | ||||
|             if (pos >= len_) | ||||
|               pos = len_ - 1;; | ||||
|               pos = len_ - 1; | ||||
|             if (s.len_ == 0u) | ||||
|               return pos; | ||||
|             pos = len_ - (pos+1); | ||||
| @@ -315,27 +340,26 @@ namespace boost { | ||||
|             } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(charT c, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(&c, 1), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos, size_type n) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(s, n), pos); } | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const | ||||
|         BOOST_CXX14_CONSTEXPR size_type find_last_not_of(const charT* s, size_type pos = npos) const BOOST_NOEXCEPT | ||||
|             { return find_last_not_of(basic_string_view(s), pos); } | ||||
|  | ||||
|     private: | ||||
|         template <typename r_iter> | ||||
|         size_type reverse_distance ( r_iter first, r_iter last ) const { | ||||
|         size_type reverse_distance(r_iter first, r_iter last) const BOOST_NOEXCEPT { | ||||
|         // Portability note here: std::distance is not NOEXCEPT, but calling it with a string_view::reverse_iterator will not throw. | ||||
|             return len_ - 1 - std::distance ( first, last ); | ||||
|             } | ||||
|  | ||||
|         template <typename Iterator> | ||||
|         Iterator find_not_of ( Iterator first, Iterator last, basic_string_view s ) const { | ||||
|             for ( ; first != last ; ++first ) | ||||
|                 if ( 0 == traits::find ( s.ptr_, s.len_, *first )) | ||||
|         Iterator find_not_of(Iterator first, Iterator last, basic_string_view s) const BOOST_NOEXCEPT { | ||||
|             for (; first != last ; ++first) | ||||
|                 if ( 0 == traits::find(s.ptr_, s.len_, *first)) | ||||
|                     return first; | ||||
|             return last; | ||||
|             } | ||||
|  | ||||
|  | ||||
|  | ||||
|         const charT *ptr_; | ||||
|         std::size_t len_; | ||||
|         }; | ||||
| @@ -344,197 +368,197 @@ namespace boost { | ||||
| //  Comparison operators | ||||
| //  Equality | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator==(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         if ( x.size () != y.size ()) return false; | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         if (x.size () != y.size ()) return false; | ||||
|         return x.compare(y) == 0; | ||||
|         } | ||||
|  | ||||
| //  Inequality | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator!=(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         if ( x.size () != y.size ()) return true; | ||||
|         return x.compare(y) != 0; | ||||
|         } | ||||
|  | ||||
| //  Less than | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) < 0; | ||||
|         } | ||||
|  | ||||
| //  Greater than | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) > 0; | ||||
|         } | ||||
|  | ||||
| //  Less than or equal to | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<=(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) <= 0; | ||||
|         } | ||||
|  | ||||
| //  Greater than or equal to | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>=(basic_string_view<charT, traits> x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return x.compare(y) >= 0; | ||||
|         } | ||||
|  | ||||
| // "sufficient additional overloads of comparison functions" | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator==(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x == basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator==(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) == y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator==(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(basic_string_view<charT, traits> x, | ||||
|                                               const charT * y) BOOST_NOEXCEPT { | ||||
|         return x == basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator==(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator==(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) == y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator!=(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x != basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) != y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator!=(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x != basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator!=(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator!=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) != y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator<(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x < basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator<(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) < y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(basic_string_view<charT, traits> x, | ||||
|                           const charT * y) BOOST_NOEXCEPT { | ||||
|         return x < basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<(const charT * x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) < y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator>(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                     const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x > basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator>(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                 basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) > y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(basic_string_view<charT, traits> x, | ||||
|                           const charT * y) BOOST_NOEXCEPT { | ||||
|         return x > basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>(const charT * x, | ||||
|                           basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) > y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator<=(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x <= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) <= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<=(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x <= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator<=(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator<=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) <= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator>=(basic_string_view<charT, traits> x, | ||||
|       const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                      const std::basic_string<charT, traits, Allocator> & y) BOOST_NOEXCEPT { | ||||
|         return x >= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits, typename Allocator> | ||||
|     inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(const std::basic_string<charT, traits, Allocator> & x, | ||||
|                                  basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) >= y; | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>=(basic_string_view<charT, traits> x, | ||||
|       const charT * y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(basic_string_view<charT, traits> x, | ||||
|                            const charT * y) BOOST_NOEXCEPT { | ||||
|         return x >= basic_string_view<charT, traits>(y); | ||||
|         } | ||||
|  | ||||
|     template<typename charT, typename traits> | ||||
|     inline bool operator>=(const charT * x, | ||||
|       basic_string_view<charT, traits> y) BOOST_NOEXCEPT {  | ||||
|     inline BOOST_CXX14_CONSTEXPR bool operator>=(const charT * x, | ||||
|                            basic_string_view<charT, traits> y) BOOST_NOEXCEPT { | ||||
|         return basic_string_view<charT, traits>(x) >= y; | ||||
|         } | ||||
|  | ||||
|     namespace detail { | ||||
|  | ||||
|         template<class charT, class traits> | ||||
|         inline void 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 }; | ||||
|             charT fill_chars[chunk_size]; | ||||
|             std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill()); | ||||
| @@ -545,19 +569,19 @@ namespace boost { | ||||
|             } | ||||
|  | ||||
|         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 alignment_size = static_cast< std::size_t >(os.width()) - size; | ||||
|             const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left; | ||||
|             if (!align_left) { | ||||
|                 detail::insert_fill_chars(os, alignment_size); | ||||
|                 detail::sv_insert_fill_chars(os, alignment_size); | ||||
|                 if (os.good()) | ||||
|                     os.write(str.data(), size); | ||||
|                 } | ||||
|             else { | ||||
|                 os.write(str.data(), size); | ||||
|                 if (os.good()) | ||||
|                     detail::insert_fill_chars(os, alignment_size); | ||||
|                     detail::sv_insert_fill_chars(os, alignment_size); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -574,7 +598,7 @@ namespace boost { | ||||
|             if (w <= size) | ||||
|                 os.write(str.data(), size); | ||||
|             else | ||||
|                 detail::insert_aligned(os, str); | ||||
|                 detail::sv_insert_aligned(os, str); | ||||
|             os.width(0); | ||||
|             } | ||||
|         return os; | ||||
|   | ||||
| @@ -11,38 +11,46 @@ import testing ; | ||||
| alias unit_test_framework | ||||
|     : # sources | ||||
|         /boost//unit_test_framework | ||||
|     ;         | ||||
|  | ||||
| # Please keep the tests ordered by filename | ||||
| test-suite utility | ||||
|     : | ||||
|         [ run ../base_from_member_test.cpp ] | ||||
|         [ run ../base_from_member_ref_test.cpp ] | ||||
|         [ run ../binary_test.cpp ] | ||||
|         [ run ../call_traits_test.cpp : -u ] | ||||
|         [ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static : -u ] | ||||
|         [ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ run ../numeric_traits_test.cpp ] | ||||
|         [ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ] | ||||
|         [ compile result_of_test.cpp ] | ||||
|         [ run ../shared_iterator_test.cpp ] | ||||
|         [ run string_ref_test1.cpp unit_test_framework ] | ||||
|         [ run string_ref_test2.cpp unit_test_framework ] | ||||
|         [ run string_ref_test_io.cpp unit_test_framework ] | ||||
|         [ run string_view_test1.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 ../value_init_test.cpp ] | ||||
|         [ run ../value_init_workaround_test.cpp ] | ||||
|         [ run ../initialized_test.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail1.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail2.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail3.cpp ] | ||||
|         [ compile-fail ../initialized_test_fail1.cpp ] | ||||
|         [ compile-fail ../initialized_test_fail2.cpp ] | ||||
|  | ||||
|         [ run ../generator_iterator_test.cpp ] | ||||
|     ; | ||||
|  | ||||
| run base_from_member_test.cpp ; | ||||
| run base_from_member_ref_test.cpp ; | ||||
|  | ||||
| run binary_test.cpp ; | ||||
|  | ||||
| run call_traits_test.cpp : -u ; | ||||
|  | ||||
| run compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ; | ||||
|  | ||||
| run iterators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ; | ||||
|  | ||||
| run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ; | ||||
|  | ||||
| run numeric_traits_test.cpp ; | ||||
|  | ||||
| run operators_test.cpp ../../test/build//boost_test_exec_monitor/<link>static ; | ||||
|  | ||||
| compile result_of_test.cpp ; | ||||
|  | ||||
| run shared_iterator_test.cpp ; | ||||
|  | ||||
| # compile-fail string_ref_from_rvalue.cpp ; | ||||
| run string_ref_test1.cpp unit_test_framework ; | ||||
| run string_ref_test2.cpp unit_test_framework ; | ||||
| run string_ref_test_io.cpp unit_test_framework ; | ||||
| # compile-fail string_view_from_rvalue.cpp ; | ||||
| compile string_view_constexpr_test1.cpp ; | ||||
| run string_view_test1.cpp unit_test_framework ; | ||||
| run string_view_test2.cpp unit_test_framework ; | ||||
| run string_view_test_io.cpp unit_test_framework ; | ||||
|  | ||||
| run value_init_test.cpp ; | ||||
| run value_init_workaround_test.cpp ; | ||||
| run initialized_test.cpp ; | ||||
| compile-fail value_init_test_fail1.cpp ; | ||||
| compile-fail value_init_test_fail2.cpp ; | ||||
| compile-fail value_init_test_fail3.cpp ; | ||||
| compile-fail initialized_test_fail1.cpp ; | ||||
| compile-fail initialized_test_fail2.cpp ; | ||||
|  | ||||
| run generator_iterator_test.cpp ; | ||||
|   | ||||
| @@ -18,7 +18,7 @@ | ||||
| 
 | ||||
| #include <boost/utility/base_from_member.hpp>  // for boost::base_from_member
 | ||||
| 
 | ||||
| #include <functional>  // for std::binary_function, std::less
 | ||||
| #include <functional>  // for std::less
 | ||||
| #include <iostream>    // for std::cout (std::ostream, std::endl indirectly)
 | ||||
| #include <set>         // for std::set
 | ||||
| #include <typeinfo>    // for std::type_info
 | ||||
| @@ -46,7 +46,6 @@ template < typename T > | ||||
| 
 | ||||
| // A custom comparison type is needed
 | ||||
| struct object_id_compare | ||||
|     : std::binary_function<object_id, object_id, bool> | ||||
| { | ||||
|     bool  operator ()( object_id const &a, object_id const &b ) const; | ||||
| 
 | ||||
| @@ -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> | ||||
| @@ -86,6 +86,13 @@ int test_main(int, char*[]) | ||||
|     BOOST_REQUIRE(minus_n_unsigned_test(x.begin(), x.end(), x.size())); | ||||
|     BOOST_REQUIRE(minus_n_unsigned_test(y.begin(), y.end(), y.size())); | ||||
|  | ||||
|     BOOST_REQUIRE(plus_one_test(x.rbegin(), x.rend(), y.begin())); | ||||
|     BOOST_REQUIRE(plus_n_test(x.rbegin(), x.rend(), y.begin())); | ||||
|     BOOST_REQUIRE(minus_one_test(x.rbegin(), x.rend(), y.end())); | ||||
|     BOOST_REQUIRE(minus_n_test(x.rbegin(), x.rend(), y.end())); | ||||
|     BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), x.size())); | ||||
|     BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), y.size())); | ||||
|  | ||||
|     // Tests with integers | ||||
|     BOOST_REQUIRE(boost::next(5) == 6); | ||||
|     BOOST_REQUIRE(boost::next(5, 7) == 12); | ||||
|   | ||||
| @@ -38,11 +38,9 @@ namespace | ||||
|     int true_value(int x) { return x; } | ||||
|     long true_value(long 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 long true_value(unsigned long 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
 | ||||
|     class convertible_to_bool | ||||
							
								
								
									
										28
									
								
								test/string_ref_from_rvalue.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								test/string_ref_from_rvalue.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2017. | ||||
|  | ||||
|    Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
|     For more information, see http://www.boost.org | ||||
| */ | ||||
|  | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
|  | ||||
| #include <boost/utility/string_ref.hpp> | ||||
|  | ||||
| #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| #error "Unsupported test" | ||||
| #endif | ||||
|  | ||||
| #include "boost/test/minimal.hpp" | ||||
|  | ||||
| std::string makeatemp() { return "abc"; } | ||||
|  | ||||
| int test_main(int, char **) | ||||
| { | ||||
|   boost::basic_string_ref<char> sv(makeatemp()); | ||||
|   return 0; | ||||
| } | ||||
| @@ -83,7 +83,7 @@ void reverse ( const char *arg ) { | ||||
|     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_ref::size_type ptr_diff ( const char *res, const char *base ) { | ||||
|     BOOST_CHECK ( res >= base ); | ||||
|     return static_cast<string_ref::size_type> ( res - base ); | ||||
| @@ -112,7 +112,7 @@ void find ( const char *arg ) { | ||||
|       ++p; | ||||
|       } | ||||
|  | ||||
| //	Look for pairs on characters (searching from the start) | ||||
| // Look for pairs on characters (searching from the start) | ||||
|     sr1 = arg; | ||||
|     p = arg; | ||||
|     while ( *p && *(p+1)) { | ||||
| @@ -249,7 +249,7 @@ void to_string ( const char *arg ) { | ||||
|  | ||||
|     str1.assign ( arg ); | ||||
|     sr1 = arg; | ||||
| //	str2 = sr1.to_string<std::allocator<char> > (); | ||||
| // str2 = sr1.to_string<std::allocator<char> > (); | ||||
|     str2 = sr1.to_string (); | ||||
|     BOOST_CHECK ( str1 == str2 ); | ||||
|  | ||||
| @@ -266,11 +266,11 @@ void compare ( const char *arg ) { | ||||
|  | ||||
|     str1.assign ( arg ); | ||||
|     sr1 = arg; | ||||
|     BOOST_CHECK ( sr1  == sr1);	    // compare string_ref and string_ref | ||||
|     BOOST_CHECK ( sr1  == str1);	// compare string and string_ref | ||||
|     BOOST_CHECK ( str1 == sr1 );	// compare string_ref and string | ||||
|     BOOST_CHECK ( sr1  == arg );	// compare string_ref and pointer | ||||
|     BOOST_CHECK ( arg  == sr1 );	// compare pointer and string_ref | ||||
|     BOOST_CHECK ( sr1  == sr1);     // compare string_ref and string_ref | ||||
|     BOOST_CHECK ( sr1  == str1);    // compare string and string_ref | ||||
|     BOOST_CHECK ( str1 == sr1 );    // compare string_ref and string | ||||
|     BOOST_CHECK ( sr1  == arg );    // compare string_ref and pointer | ||||
|     BOOST_CHECK ( arg  == sr1 );    // compare pointer and string_ref | ||||
|  | ||||
|     if ( sr1.size () > 0 ) { | ||||
|         (*str1.rbegin())++; | ||||
|   | ||||
| @@ -75,7 +75,6 @@ struct context | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_ref< char_type > string_ref_type; | ||||
|  | ||||
| @@ -90,7 +89,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types) | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_ref< char_type > string_ref_type; | ||||
|  | ||||
| @@ -134,7 +132,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types) | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_ref< char_type > string_ref_type; | ||||
|  | ||||
| @@ -153,7 +150,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types) | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_ref< char_type > string_ref_type; | ||||
|  | ||||
|   | ||||
							
								
								
									
										121
									
								
								test/string_view_constexpr_test1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								test/string_view_constexpr_test1.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2017-2017. | ||||
|  | ||||
|    Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
|     For more information, see http://www.boost.org | ||||
| */ | ||||
|  | ||||
| #include <new>        // for placement new | ||||
| #include <iostream> | ||||
| #include <cstddef>    // for NULL, std::size_t, std::ptrdiff_t | ||||
| #include <cstring>    // for std::strchr and std::strcmp | ||||
| #include <cstdlib>    // for std::malloc and std::free | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/utility/string_view.hpp> | ||||
|  | ||||
| #define BOOST_TEST_MAIN | ||||
| #include <boost/test/unit_test.hpp> | ||||
|  | ||||
|  | ||||
| #if __cplusplus < 201402L | ||||
| BOOST_AUTO_TEST_CASE( test_main ) {} | ||||
| #else | ||||
|  | ||||
| struct constexpr_char_traits | ||||
| { | ||||
|     typedef char		    char_type; | ||||
|     typedef int   			int_type; | ||||
|     typedef std::streamoff	off_type; | ||||
|     typedef std::streampos	pos_type; | ||||
|     typedef std::mbstate_t	state_type; | ||||
|  | ||||
|     static void assign(char_type& c1, const char_type& c2) noexcept { c1 = c2; } | ||||
|     static constexpr bool eq(char_type c1, char_type c2) noexcept   { return c1 == c2; } | ||||
|     static constexpr bool lt(char_type c1, char_type c2) noexcept   { return c1 < c2; } | ||||
|  | ||||
|     static constexpr int              compare(const char_type* s1, const char_type* s2, size_t n) noexcept; | ||||
|     static constexpr size_t           length(const char_type* s) noexcept; | ||||
|     static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept; | ||||
|     static constexpr char_type*       move(char_type* s1, const char_type* s2, size_t n) noexcept; | ||||
|     static constexpr char_type*       copy(char_type* s1, const char_type* s2, size_t n) noexcept; | ||||
|     static constexpr char_type*       assign(char_type* s, size_t n, char_type a) noexcept; | ||||
|  | ||||
|     static constexpr int_type  not_eof(int_type c) noexcept { return eq_int_type(c, eof()) ? ~eof() : c; } | ||||
|     static constexpr char_type to_char_type(int_type c) noexcept              { return char_type(c); } | ||||
|     static constexpr int_type  to_int_type(char_type c) noexcept              { return int_type(c); } | ||||
|     static constexpr bool      eq_int_type(int_type c1, int_type c2) noexcept { return c1 == c2; } | ||||
|     static constexpr int_type  eof() noexcept                                 { return EOF; } | ||||
| }; | ||||
|  | ||||
| //	yields: | ||||
| //		0 if for each i in [0,n), X::eq(s1[i],s2[i]) is true;  | ||||
| //		else, a negative value if, for some j in [0,n), X::lt(s1[j],s2[j]) is true and | ||||
| //			for each i in [0,j) X::eq(s2[i],s2[i]) is true; | ||||
| //		else a positive value. | ||||
| constexpr int constexpr_char_traits::compare(const char_type* s1, const char_type* s2, size_t n) noexcept | ||||
| { | ||||
|     for (; n != 0; --n, ++s1, ++s2) | ||||
|     { | ||||
|         if (lt(*s1, *s2)) | ||||
|             return -1; | ||||
|         if (lt(*s2, *s1)) | ||||
|             return 1; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| //	yields: the smallest i such that X::eq(s[i],charT()) is true. | ||||
| constexpr size_t constexpr_char_traits::length(const char_type* s) noexcept | ||||
| { | ||||
|     size_t len = 0; | ||||
|     for (; !eq(*s, char_type(0)); ++s) | ||||
|         ++len; | ||||
|     return len; | ||||
| } | ||||
|  | ||||
| typedef boost::basic_string_view<char, constexpr_char_traits> string_view; | ||||
|  | ||||
| BOOST_AUTO_TEST_CASE( test_main ) | ||||
| { | ||||
|     constexpr string_view sv1; | ||||
|     constexpr string_view sv2{"abc", 3}; // ptr, len | ||||
|     constexpr string_view sv3{"def"}; 	 // ptr | ||||
|  | ||||
| 	constexpr const char *s1 = ""; | ||||
| 	constexpr const char *s2 = "abc"; | ||||
| 	 | ||||
| 	static_assert( (sv1 == sv1), "" ); | ||||
| 	 | ||||
| 	static_assert(!(sv1 == sv2), "" );     | ||||
| 	static_assert( (sv1 != sv2), "" );     | ||||
| 	static_assert( (sv1 <  sv2), "" );     | ||||
| 	static_assert( (sv1 <= sv2), "" );     | ||||
| 	static_assert(!(sv1 >  sv2), "" );     | ||||
| 	static_assert(!(sv1 >= sv2), "" );     | ||||
|  | ||||
| 	static_assert(!(s1 == sv2), "" );     | ||||
| 	static_assert( (s1 != sv2), "" );     | ||||
| 	static_assert( (s1 <  sv2), "" );     | ||||
| 	static_assert( (s1 <= sv2), "" );     | ||||
| 	static_assert(!(s1 >  sv2), "" );     | ||||
| 	static_assert(!(s1 >= sv2), "" );     | ||||
|  | ||||
| 	static_assert(!(sv1 == s2), "" );     | ||||
| 	static_assert( (sv1 != s2), "" );     | ||||
| 	static_assert( (sv1 <  s2), "" );     | ||||
| 	static_assert( (sv1 <= s2), "" );     | ||||
| 	static_assert(!(sv1 >  s2), "" );     | ||||
| 	static_assert(!(sv1 >= s2), "" );     | ||||
|  | ||||
| 	static_assert( sv1.compare(sv2)  < 0, "" );     | ||||
| 	static_assert( sv1.compare(sv1) == 0, "" );     | ||||
| 	static_assert( sv3.compare(sv1)  > 0, "" );     | ||||
|  | ||||
| 	static_assert( sv1.compare(s2)  < 0, "" );     | ||||
| 	static_assert( sv1.compare(s1) == 0, "" );     | ||||
| 	static_assert( sv3.compare(s1)  > 0, "" );     | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										28
									
								
								test/string_view_from_rvalue.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								test/string_view_from_rvalue.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|    Copyright (c) Marshall Clow 2017. | ||||
|  | ||||
|    Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
|     For more information, see http://www.boost.org | ||||
| */ | ||||
|  | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
|  | ||||
| #include <boost/utility/string_view.hpp> | ||||
|  | ||||
| #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) | ||||
| #error "Unsupported test" | ||||
| #endif | ||||
|  | ||||
| #include "boost/test/minimal.hpp" | ||||
|  | ||||
| std::string makeatemp() { return "abc"; } | ||||
|  | ||||
| int test_main(int, char **) | ||||
| { | ||||
|   boost::basic_string_view<char> sv(makeatemp()); | ||||
|   return 0; | ||||
| } | ||||
| @@ -7,10 +7,6 @@ | ||||
|     For more information, see http://www.boost.org | ||||
| */ | ||||
|  | ||||
| #ifndef _SCL_SECURE_NO_WARNINGS | ||||
| # define _SCL_SECURE_NO_WARNINGS | ||||
| #endif | ||||
|  | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
|   | ||||
| @@ -7,14 +7,14 @@ | ||||
|     For more information, see http://www.boost.org | ||||
| */ | ||||
|  | ||||
| #ifndef _SCL_SECURE_NO_WARNINGS | ||||
| # define _SCL_SECURE_NO_WARNINGS | ||||
| #endif | ||||
|  | ||||
| #include <new>        // for placement new | ||||
| #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/config.hpp> | ||||
|  | ||||
| #define BOOST_TEST_MAIN | ||||
| #include <boost/test/unit_test.hpp> | ||||
| @@ -48,7 +48,7 @@ void ends_with ( const char *arg ) { | ||||
|     if ( sz > 0 ) | ||||
|       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 ) { | ||||
| @@ -87,7 +87,7 @@ void reverse ( const char *arg ) { | ||||
|     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 ) { | ||||
|     BOOST_CHECK ( res >= base ); | ||||
|     return static_cast<string_view::size_type> ( res - base ); | ||||
| @@ -116,7 +116,7 @@ void find ( const char *arg ) { | ||||
|       ++p; | ||||
|       } | ||||
|  | ||||
| //	Look for pairs on characters (searching from the start) | ||||
| //  Look for pairs on characters (searching from the start) | ||||
|     sr1 = arg; | ||||
|     p = arg; | ||||
|     while ( *p && *(p+1)) { | ||||
| @@ -130,29 +130,24 @@ void find ( const char *arg ) { | ||||
|     p = arg; | ||||
| //  for all possible chars, see if we find them in the right place. | ||||
| //  Note that strchr will/might do the _wrong_ thing if we search for NULL | ||||
|  | ||||
|     for ( unsigned char ch = 1u; ; ++ch ) { | ||||
|     for ( int ch = 1; ch < 256; ++ch ) { | ||||
|         string_view::size_type pos = sr1.find(ch); | ||||
|         const char *strp = std::strchr ( arg, ch ); | ||||
|         BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos )); | ||||
|         if ( strp != NULL ) | ||||
|             BOOST_CHECK ( ptr_diff ( strp, arg ) == pos ); | ||||
|         if (ch == 255u) | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     sr1 = arg; | ||||
|     p = arg; | ||||
| //  for all possible chars, see if we find them in the right place. | ||||
| //  Note that strchr will/might do the _wrong_ thing if we search for NULL | ||||
|     for ( unsigned char ch = 1u; ; ++ch ) { | ||||
|     for ( int ch = 1; ch < 256; ++ch ) { | ||||
|         string_view::size_type pos = sr1.rfind(ch); | ||||
|         const char *strp = std::strrchr ( arg, ch ); | ||||
|         BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos )); | ||||
|         if ( strp != NULL ) | ||||
|             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 ) { | ||||
|     string_view sr1; | ||||
| @@ -258,14 +333,17 @@ void to_string ( const char *arg ) { | ||||
|  | ||||
|     str1.assign ( arg ); | ||||
|     sr1 = arg; | ||||
| //	str2 = sr1.to_string<std::allocator<char> > (); | ||||
| //  str2 = sr1.to_string<std::allocator<char> > (); | ||||
|     str2 = sr1.to_string (); | ||||
|     BOOST_CHECK ( str1 == str2 ); | ||||
|  | ||||
| //#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
| //    std::string str3 = static_cast<std::string> ( sr1 ); | ||||
| //    BOOST_CHECK ( str1 == str3 ); | ||||
| //#endif | ||||
|     std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>()); | ||||
|     BOOST_CHECK ( std::strcmp(str1.c_str(), str3.c_str()) == 0 ); | ||||
|  | ||||
| #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS | ||||
|     std::string str4 = static_cast<std::string> ( sr1 ); | ||||
|     BOOST_CHECK ( str1 == str4 ); | ||||
| #endif | ||||
|     } | ||||
|  | ||||
| void compare ( const char *arg ) { | ||||
| @@ -275,11 +353,11 @@ void compare ( const char *arg ) { | ||||
|  | ||||
|     str1.assign ( arg ); | ||||
|     sr1 = arg; | ||||
|     BOOST_CHECK ( sr1  == sr1);	    // compare string_view and string_view | ||||
|     BOOST_CHECK ( sr1  == str1);	// compare string and string_view | ||||
|     BOOST_CHECK ( str1 == sr1 );	// compare string_view and string | ||||
|     BOOST_CHECK ( sr1  == arg );	// compare string_view and pointer | ||||
|     BOOST_CHECK ( arg  == sr1 );	// compare pointer and string_view | ||||
|     BOOST_CHECK ( sr1  == sr1);    // compare string_view and string_view | ||||
|     BOOST_CHECK ( sr1  == str1);   // compare string and string_view | ||||
|     BOOST_CHECK ( str1 == sr1 );   // compare string_view and string | ||||
|     BOOST_CHECK ( sr1  == arg );   // compare string_view and pointer | ||||
|     BOOST_CHECK ( arg  == sr1 );   // compare pointer and string_view | ||||
|  | ||||
|     if ( sr1.size () > 0 ) { | ||||
|         (*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) | ||||
|  */ | ||||
| /*! | ||||
|  * \file   string_view_test_io.cpp | ||||
|  * \file   string_ref_test_io.cpp | ||||
|  * \author Andrey Semashev | ||||
|  * \date   26.05.2013 | ||||
|  * | ||||
|  * \brief  This header contains tests for stream operations of \c basic_string_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> | ||||
|  | ||||
| @@ -75,7 +75,6 @@ struct context | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     //typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_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) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     //typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_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 | ||||
|     { | ||||
|         ostream_type strm_view; | ||||
|         strm_view << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|         ostream_type strm_ref; | ||||
|         strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|         ostream_type strm_correct; | ||||
|         strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end; | ||||
|  | ||||
|         BOOST_CHECK(strm_view.str() == strm_correct.str()); | ||||
|         BOOST_CHECK(strm_ref.str() == strm_correct.str()); | ||||
|     } | ||||
|  | ||||
|     // Test for long padding | ||||
|     { | ||||
|         ostream_type strm_view; | ||||
|         strm_view << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end; | ||||
|         ostream_type strm_ref; | ||||
|         strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|         ostream_type strm_correct; | ||||
|         strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end; | ||||
|  | ||||
|         BOOST_CHECK(strm_view.str() == strm_correct.str()); | ||||
|         BOOST_CHECK(strm_ref.str() == strm_correct.str()); | ||||
|     } | ||||
|  | ||||
|     // Test that short width does not truncate the string | ||||
|     { | ||||
|         ostream_type strm_view; | ||||
|         strm_view << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end; | ||||
|         ostream_type strm_ref; | ||||
|         strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|         ostream_type strm_correct; | ||||
|         strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end; | ||||
|  | ||||
|         BOOST_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) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     //typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_view< char_type > string_view_type; | ||||
|  | ||||
|     context< char_type > ctx; | ||||
|  | ||||
|     ostream_type strm_view; | ||||
|     strm_view << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|     ostream_type strm_ref; | ||||
|     strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|     ostream_type strm_correct; | ||||
|     strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end; | ||||
|  | ||||
|     BOOST_CHECK(strm_view.str() == strm_correct.str()); | ||||
|     BOOST_CHECK(strm_ref.str() == strm_correct.str()); | ||||
| } | ||||
|  | ||||
| // Test support for alignment | ||||
| BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types) | ||||
| { | ||||
|     typedef CharT char_type; | ||||
|     //typedef std::basic_string< char_type > string_type; | ||||
|     typedef std::basic_ostringstream< char_type > ostream_type; | ||||
|     typedef boost::basic_string_view< char_type > string_view_type; | ||||
|  | ||||
| @@ -161,23 +157,23 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types) | ||||
|  | ||||
|     // Left alignment | ||||
|     { | ||||
|         ostream_type strm_view; | ||||
|         strm_view << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|         ostream_type strm_ref; | ||||
|         strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|         ostream_type strm_correct; | ||||
|         strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end; | ||||
|  | ||||
|         BOOST_CHECK(strm_view.str() == strm_correct.str()); | ||||
|         BOOST_CHECK(strm_ref.str() == strm_correct.str()); | ||||
|     } | ||||
|  | ||||
|     // Right alignment | ||||
|     { | ||||
|         ostream_type strm_view; | ||||
|         strm_view << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|         ostream_type strm_ref; | ||||
|         strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; | ||||
|  | ||||
|         ostream_type strm_correct; | ||||
|         strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end; | ||||
|  | ||||
|         BOOST_CHECK(strm_view.str() == strm_correct.str()); | ||||
|         BOOST_CHECK(strm_ref.str() == strm_correct.str()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -132,7 +132,7 @@ int main() | ||||
|   const unsigned num_failures = | ||||
|     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) + | ||||
|     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) + | ||||
| 	FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()); | ||||
|     FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()); | ||||
| 
 | ||||
| #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED | ||||
|   // One or more failures are expected.
 | ||||
		Reference in New Issue
	
	Block a user