mirror of
				https://github.com/boostorg/utility.git
				synced 2025-10-31 16:31:48 +01:00 
			
		
		
		
	Compare commits
	
		
			169 Commits
		
	
	
		
			boost-1.43
			...
			svn-branch
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6a93732f6b | ||
|  | 58bb88d4bd | ||
|  | 11d50ecb9f | ||
|  | 636283d7c2 | ||
|  | 1df0bf80bc | ||
|  | 71e78a0081 | ||
|  | f7e4b0e399 | ||
|  | fb1d2effef | ||
|  | 94b91e8c92 | ||
|  | a4b8043e68 | ||
|  | b4a08fc80e | ||
|  | 9da96d9737 | ||
|  | a991936c96 | ||
|  | 6239e685a2 | ||
|  | e601fcb9c9 | ||
|  | f29a5db08e | ||
|  | 22743ee125 | ||
|  | e3c982287a | ||
|  | 82e1111bb8 | ||
|  | 9339b32178 | ||
|  | 3770221507 | ||
|  | e6cb3a77ee | ||
|  | bbccfbbab4 | ||
|  | 74a6a693d3 | ||
|  | bf713ad47a | ||
|  | 76b17c497b | ||
|  | 3de5974419 | ||
|  | 7eb1536590 | ||
|  | 9339431e03 | ||
|  | f2349baf7d | ||
|  | 8745ca628a | ||
|  | ba61e9d796 | ||
|  | afe74fffbc | ||
|  | 09a0137016 | ||
|  | a1d3ec6c53 | ||
|  | 5be3004e6c | ||
|  | d387905150 | ||
|  | b514e40733 | ||
|  | b02677375f | ||
|  | 61a6015b5a | ||
|  | 682032a340 | ||
|  | 67afd7e315 | ||
|  | 75cf20cace | ||
|  | 91385ac627 | ||
|  | 61e9b93f7c | ||
|  | d97b303777 | ||
|  | 3900e8ece4 | ||
|  | e27fc4a853 | ||
|  | f7aa9a8935 | ||
|  | 0af1959b30 | ||
|  | 5f0cf4f5de | ||
|  | 0282c8a141 | ||
|  | 6725719bd9 | ||
|  | 97e11b024e | ||
|  | 118e473a3d | ||
|  | d4b6193f94 | ||
|  | d420c98a53 | ||
|  | d153ab4daa | ||
|  | 561f83b991 | ||
|  | 57124703f9 | ||
|  | 53f6d10652 | ||
|  | ebe853ff2f | ||
|  | 487a5c1ea5 | ||
|  | c4338b1ce8 | ||
|  | ddd8a58ae0 | ||
|  | 28061ba3a8 | ||
|  | 5d53e3f837 | ||
|  | e86ce1cb1f | ||
|  | f15c96ffb0 | ||
|  | a487f72329 | ||
|  | 9f08ed6de0 | ||
|  | 2077d0dace | ||
|  | 7f2348269b | ||
|  | 6b6e1c3252 | ||
|  | 55f303baec | ||
|  | d264005c11 | ||
|  | 2cde009bb1 | ||
|  | 7bfb7c8a61 | ||
|  | 5c42397244 | ||
|  | 782c132d99 | ||
|  | 36899afa3f | ||
|  | 7e3e326faf | ||
|  | 7019e18149 | ||
|  | 49faf23433 | ||
|  | 62836f2928 | ||
|  | 1ecf3ceb74 | ||
|  | 2aa48414c9 | ||
|  | d215f2176c | ||
|  | c286d62223 | ||
|  | 3fd0ea6e75 | ||
|  | b050431638 | ||
|  | b311fcefb2 | ||
|  | 899c92420c | ||
|  | 64a0e0cb20 | ||
|  | ece6992540 | ||
|  | 6098304ea8 | ||
|  | 28fff2d821 | ||
|  | 0ce3885d59 | ||
|  | 1823481d96 | ||
|  | cce5d77d2b | ||
|  | 3c5c2bc107 | ||
|  | 177ee78bbb | ||
|  | f1ec0c4d04 | ||
|  | 4a564744fe | ||
|  | 67f3ca090a | ||
|  | 8efae71f4a | ||
|  | ad0bcf4a00 | ||
|  | f1c86c35c4 | ||
|  | a5b85eda07 | ||
|  | bafe37fdab | ||
|  | be50b95508 | ||
|  | 96d573d6ca | ||
|  | 2412b864d6 | ||
|  | 94865eabe6 | ||
|  | 50268d1b29 | ||
|  | ad9108c1dc | ||
|  | 691e4b6c34 | ||
|  | 28596e678d | ||
|  | 1beca24dd8 | ||
|  | 721764937f | ||
|  | a511007d0f | ||
|  | 8ce58b1675 | ||
|  | 9ed68b8321 | ||
|  | 79bbf71d0d | ||
|  | ac93de7c1b | ||
|  | d731b8e1c5 | ||
|  | ac1567b3fc | ||
|  | c1fd670480 | ||
|  | 01274cf6ac | ||
|  | 8080673977 | ||
|  | a470b591fb | ||
|  | e1a63495b6 | ||
|  | 7300ac83f1 | ||
|  | 882d38c2c7 | ||
|  | 33041ad664 | ||
|  | 6a2aa822f8 | ||
|  | 09ab16bfc1 | ||
|  | ec46e40809 | ||
|  | b3a971e7e9 | ||
|  | 7ddb559887 | ||
|  | ea8c99b1d5 | ||
|  | 56b0846099 | ||
|  | 42e0001370 | ||
|  | cd8f85afee | ||
|  | bddd52c4b9 | ||
|  | 8f03aeac4e | ||
|  | 3bb2568fad | ||
|  | 01e91a3799 | ||
|  | 55f3c351a3 | ||
|  | 3f72b10182 | ||
|  | 71cb8cb574 | ||
|  | c950825ef4 | ||
|  | 66ca84a45d | ||
|  | 06404f7d39 | ||
|  | 2d860e2574 | ||
|  | 66514f61ff | ||
|  | 63cde4d3fd | ||
|  | 1950f292df | ||
|  | 92a0602190 | ||
|  | c9a3ab1d04 | ||
|  | 0782034333 | ||
|  | 0808883f3c | ||
|  | 2f69501e55 | ||
|  | 5b83f641a8 | ||
|  | c730ab4ffb | ||
|  | e55610a0d0 | ||
|  | bf968794c9 | ||
|  | ce6e9c6698 | ||
|  | 7ac180ed54 | 
							
								
								
									
										68
									
								
								doc/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								doc/Jamfile.v2
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
|  | ||||
| # Copyright John Maddock 2005. Use, modification, and distribution are | ||||
| # subject to the Boost Software License, Version 1.0. (See accompanying | ||||
| # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| project : requirements | ||||
|         # Path for links to Boost: | ||||
|         <xsl:param>boost.root=../../../.. | ||||
|          | ||||
|         # Some general style settings: | ||||
|         <xsl:param>table.footnote.number.format=1 | ||||
|         <xsl:param>footnote.number.format=1 | ||||
|  | ||||
|         # HTML options first: | ||||
|         # Use graphics not text for navigation: | ||||
|         <xsl:param>navig.graphics=1 | ||||
|        # PDF Options: | ||||
|         # TOC Generation: this is needed for FOP-0.9 and later: | ||||
|         <xsl:param>fop1.extensions=0 | ||||
|         <xsl:param>xep.extensions=1 | ||||
|         # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9! | ||||
|         <xsl:param>fop.extensions=0 | ||||
|         # No indent on body text: | ||||
|         <xsl:param>body.start.indent=0pt | ||||
|         # Margin size: | ||||
|         <xsl:param>page.margin.inner=0.5in | ||||
|         # Margin size: | ||||
|         <xsl:param>page.margin.outer=0.5in | ||||
|         # Paper type = A4 | ||||
|         <xsl:param>paper.type=A4 | ||||
|         # Yes, we want graphics for admonishments: | ||||
|         <xsl:param>admon.graphics=1 | ||||
|         # Set this one for PDF generation *only*: | ||||
|         # default pnd graphics are awful in PDF form, | ||||
|         # better use SVG's instead: | ||||
|         <format>pdf:<xsl:param>admon.graphics.extension=".svg" | ||||
|         <format>pdf:<xsl:param>admon.graphics.path=$(boost-images)/ | ||||
|         <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/utility/doc/html | ||||
| ; | ||||
|  | ||||
| using quickbook ; | ||||
|  | ||||
| path-constant boost-images : ../../../doc/src/images ; | ||||
|  | ||||
| xml declval : declval.qbk ; | ||||
| boostbook standalone | ||||
|     : | ||||
|         declval | ||||
|     : | ||||
|         # File name of HTML output: | ||||
|         <xsl:param>root.filename=declval | ||||
|         # 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 | ||||
|          | ||||
|      ; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										104
									
								
								doc/declval.qbk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								doc/declval.qbk
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| [/ | ||||
|  / Copyright (c) 2008 Howard Hinnant | ||||
|  / Copyright (c) 2008 Beman Dawes | ||||
|  / Copyright (c) 2009-20010 Vicente J. Botet Escriba | ||||
|  / | ||||
|  / 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 Declval | ||||
|     [quickbook 1.5] | ||||
|     [authors [Hinnant, Howard]] | ||||
|     [authors [Dawes, Beman]] | ||||
|     [authors [Botet Escriba, Vicente J.]] | ||||
|     [copyright 2008 Howard Hinnant] | ||||
|     [copyright 2008 Beman Dawes] | ||||
|     [copyright 2009-2010 Vicente J. Botet Escriba] | ||||
|     [license | ||||
|         Distributed under the Boost Software License, Version 1.0. | ||||
|         (See accompanying file LICENSE_1_0.txt or copy at | ||||
|         [@http://www.boost.org/LICENSE_1_0.txt]) | ||||
|     ] | ||||
| ] | ||||
|  | ||||
| [/===============] | ||||
| [section Overview] | ||||
| [/===============] | ||||
|  | ||||
| The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958:  | ||||
| Moving Swap Forward]. Here follows a rewording of this chapter. | ||||
|  | ||||
| With the provision of decltype, late-specified return types, and default template-arguments for function templates a  | ||||
| new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale.  | ||||
| Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration  | ||||
|  | ||||
|   template<class T> | ||||
|   T&& declval(); // not used | ||||
|    | ||||
| as part of the function template declaration  | ||||
|  | ||||
|   template<class To, class From> | ||||
|   decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
|    | ||||
| or as part of a class template definition  | ||||
|  | ||||
|   template<class> class result_of; | ||||
|  | ||||
|   template<class Fn, class... ArgTypes> | ||||
|   struct result_of<Fn(ArgTypes...)>  | ||||
|   { | ||||
|     typedef decltype(declval<Fn>()(declval<ArgTypes>()...)) type; | ||||
|   }; | ||||
|    | ||||
| The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function.  | ||||
| The name is supposed to direct the reader's attention to the fact that the expression `declval<T>()` is an lvalue if and only if  | ||||
| T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to  | ||||
|  | ||||
|   template<class T> | ||||
|   typename std::add_rvalue_reference<T>::type declval(); // not used | ||||
|    | ||||
| which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()`  | ||||
| already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C==0x standard.  | ||||
|  | ||||
| The provision of a new library component that allows the production of values in unevaluated expressions is considered as  | ||||
| important to realize constrained templates in C++0x where concepts are not available.  | ||||
| This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.  | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
| [/=================] | ||||
| [section:reference Reference ] | ||||
| [/=================] | ||||
|  | ||||
| `#include <boost/utility/declval.hpp>` | ||||
|  | ||||
|     namespace boost { | ||||
|  | ||||
|         template <typename T> | ||||
|         typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand | ||||
|  | ||||
|     }  // namespace boost | ||||
|  | ||||
|  | ||||
| The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands. | ||||
|  | ||||
|         template <typename T> | ||||
|         typename add_rvalue_reference<T>::type declval(); | ||||
|  | ||||
| [*Remarks:] If this function is used, the program is ill-formed. | ||||
|  | ||||
| [*Remarks:] The template parameter T of declval may be an incomplete type. | ||||
|  | ||||
| [*Example:] | ||||
|  | ||||
|     template <class To, class From> | ||||
|     decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
|  | ||||
| Declares a function template convert which only participats in overloading if the type From can be explicitly converted to type To.  | ||||
|  | ||||
| [endsect] | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										163
									
								
								doc/html/declval.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								doc/html/declval.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | ||||
| <title>Declval</title> | ||||
| <link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css"> | ||||
| <meta name="generator" content="DocBook XSL Stylesheets V1.74.0"> | ||||
| <link rel="home" href="declval.html" title="Declval"> | ||||
| </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" lang="en"> | ||||
| <div class="titlepage"> | ||||
| <div> | ||||
| <div><h2 class="title"> | ||||
| <a name="declval"></a>Declval</h2></div> | ||||
| <div><div class="authorgroup"> | ||||
| <div class="author"><h3 class="author"> | ||||
| <span class="firstname">Howard</span> <span class="surname">Hinnant</span> | ||||
| </h3></div> | ||||
| <div class="author"><h3 class="author"> | ||||
| <span class="firstname">Beman</span> <span class="surname">Dawes</span> | ||||
| </h3></div> | ||||
| <div class="author"><h3 class="author"> | ||||
| <span class="firstname">Vicente J.</span> <span class="surname">Botet Escriba</span> | ||||
| </h3></div> | ||||
| </div></div> | ||||
| <div><p class="copyright">Copyright © 2008 Howard Hinnant</p></div> | ||||
| <div><p class="copyright">Copyright © 2008 Beman Dawes</p></div> | ||||
| <div><p class="copyright">Copyright © 2009 -2010 Vicente J. Botet Escriba</p></div> | ||||
| <div><div class="legalnotice"> | ||||
| <a name="id879409"></a><p> | ||||
|         Distributed under the Boost Software License, Version 1.0. (See accompanying | ||||
|         file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>) | ||||
|       </p> | ||||
| </div></div> | ||||
| </div> | ||||
| <hr> | ||||
| </div> | ||||
| <div class="toc"> | ||||
| <p><b>Table of Contents</b></p> | ||||
| <dl> | ||||
| <dt><span class="section"><a href="declval.html#declval.overview">Overview</a></span></dt> | ||||
| <dt><span class="section"><a href="declval.html#declval.reference"> Reference </a></span></dt> | ||||
| </dl> | ||||
| </div> | ||||
| <div class="section" lang="en"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="declval.overview"></a><a class="link" href="declval.html#declval.overview" title="Overview">Overview</a> | ||||
| </h2></div></div></div> | ||||
| <p> | ||||
|       The motivation for <code class="computeroutput"><span class="identifier">declval</span></code> | ||||
|       was introduced in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value" target="_top">N2958: | ||||
|       Moving Swap Forward</a>. Here follows a rewording of this chapter. | ||||
|     </p> | ||||
| <p> | ||||
|       With the provision of decltype, late-specified return types, and default template-arguments | ||||
|       for function templates a new generation of SFINAE patterns will emerge to at | ||||
|       least partially compensate the lack of concepts on the C++0x timescale. Using | ||||
|       this technique, it is sometimes necessary to obtain an object of a known type | ||||
|       in a non-using context, e.g. given the declaration | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="identifier">T</span><span class="special">&&</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used | ||||
| </span></pre> | ||||
| <p> | ||||
|       as part of the function template declaration | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span> | ||||
| <span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       or as part of a class template definition | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">></span> <span class="keyword">class</span> <span class="identifier">result_of</span><span class="special">;</span> | ||||
|  | ||||
| <span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">class</span><span class="special">...</span> <span class="identifier">ArgTypes</span><span class="special">></span> | ||||
| <span class="keyword">struct</span> <span class="identifier">result_of</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">(</span><span class="identifier">ArgTypes</span><span class="special">...)></span>  | ||||
| <span class="special">{</span> | ||||
|   <span class="keyword">typedef</span> <span class="identifier">decltype</span><span class="special">(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">Fn</span><span class="special">>()(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">ArgTypes</span><span class="special">>()...))</span> <span class="identifier">type</span><span class="special">;</span> | ||||
| <span class="special">};</span> | ||||
| </pre> | ||||
| <p> | ||||
|       The role of the function template declval() is a transformation of a type T | ||||
|       into a value without using or evaluating this function. The name is supposed | ||||
|       to direct the reader's attention to the fact that the expression <code class="computeroutput"><span class="identifier">declval</span><span class="special"><</span><span class="identifier">T</span><span class="special">>()</span></code> is | ||||
|       an lvalue if and only if T is an lvalue-reference, otherwise an rvalue. To | ||||
|       extend the domain of this function we can do a bit better by changing its declaration | ||||
|       to | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">// not used | ||||
| </span></pre> | ||||
| <p> | ||||
|       which ensures that we can also use cv void as template parameter. The careful | ||||
|       reader might have noticed that <code class="computeroutput"><span class="identifier">declval</span><span class="special">()</span></code> already exists under the name create() as | ||||
|       part of the definition of the semantics of the type trait is_convertible in | ||||
|       the C==0x standard. | ||||
|     </p> | ||||
| <p> | ||||
|       The provision of a new library component that allows the production of values | ||||
|       in unevaluated expressions is considered as important to realize constrained | ||||
|       templates in C++0x where concepts are not available. This extremely light-weight | ||||
|       function is expected to be part of the daily tool-box of the C++0x programmer. | ||||
|     </p> | ||||
| </div> | ||||
| <div class="section" lang="en"> | ||||
| <div class="titlepage"><div><div><h2 class="title" style="clear: both"> | ||||
| <a name="declval.reference"></a><a class="link" href="declval.html#declval.reference" title="Reference"> Reference </a> | ||||
| </h2></div></div></div> | ||||
| <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">declval</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code> | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> | ||||
|  | ||||
|     <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> | ||||
|     <span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> <span class="comment">//noexcept; // as unevaluated operand | ||||
| </span> | ||||
| <span class="special">}</span>  <span class="comment">// namespace boost | ||||
| </span></pre> | ||||
| <p> | ||||
|       The library provides the function template declval to simplify the definition | ||||
|       of expressions which occur as unevaluated operands. | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> | ||||
| <span class="keyword">typename</span> <span class="identifier">add_rvalue_reference</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">declval</span><span class="special">();</span> | ||||
| </pre> | ||||
| <p> | ||||
|       <span class="bold"><strong>Remarks:</strong></span> If this function is used, the program | ||||
|       is ill-formed. | ||||
|     </p> | ||||
| <p> | ||||
|       <span class="bold"><strong>Remarks:</strong></span> The template parameter T of declval | ||||
|       may be an incomplete type. | ||||
|     </p> | ||||
| <p> | ||||
|       <span class="bold"><strong>Example:</strong></span> | ||||
|     </p> | ||||
| <pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">To</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">From</span><span class="special">></span> | ||||
| <span class="identifier">decltype</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">To</span><span class="special">>(</span><span class="identifier">declval</span><span class="special"><</span><span class="identifier">From</span><span class="special">>()))</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">From</span><span class="special">&&);</span> | ||||
| </pre> | ||||
| <p> | ||||
|       Declares a function template convert which only participats in overloading | ||||
|       if the type From can be explicitly converted to type To. | ||||
|     </p> | ||||
| </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: September 16, 2010 at 16:19:10 GMT</small></p></td> | ||||
| <td align="right"><div class="copyright-footer"></div></td> | ||||
| </tr></table> | ||||
| <hr> | ||||
| <div class="spirit-nav"></div> | ||||
| </body> | ||||
| </html> | ||||
| @@ -13,6 +13,12 @@ | ||||
| //  See http://www.boost.org/libs/utility/assert.html for documentation. | ||||
| // | ||||
|  | ||||
| // | ||||
| // Stop inspect complaining about use of 'assert': | ||||
| // | ||||
| // boostinspect:naassert_macro | ||||
| // | ||||
|  | ||||
| #undef BOOST_ASSERT | ||||
|  | ||||
| #if defined(BOOST_DISABLE_ASSERTS) | ||||
|   | ||||
| @@ -8,6 +8,8 @@ | ||||
| //  See http://www.boost.org/libs/utility/operators.htm for documentation. | ||||
|  | ||||
| //  Revision History | ||||
| //  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) | ||||
| @@ -88,7 +90,7 @@ | ||||
| #   pragma set woff 1234 | ||||
| #endif | ||||
|  | ||||
| #if defined(BOOST_MSVC) | ||||
| #if BOOST_WORKAROUND(BOOST_MSVC, < 1600) | ||||
| #   pragma warning( disable : 4284 ) // complaint about return type of  | ||||
| #endif                               // operator-> not begin a UDT | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
| // 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/lib/optional for documentation. | ||||
| // See http://www.boost.org/libs/optional for documentation. | ||||
| // | ||||
| // You are welcome to contact the author at: | ||||
| //  fernando_cacciola@hotmail.com | ||||
|   | ||||
							
								
								
									
										44
									
								
								include/boost/utility/declval.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								include/boost/utility/declval.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| //  common_type.hpp  ---------------------------------------------------------// | ||||
|  | ||||
| //  Copyright 2010 Vicente J. Botet Escriba | ||||
|  | ||||
| //  Distributed under the Boost Software License, Version 1.0. | ||||
| //  See http://www.boost.org/LICENSE_1_0.txt | ||||
|  | ||||
| #ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP | ||||
| #define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
|  | ||||
| //----------------------------------------------------------------------------// | ||||
|  | ||||
| #include <boost/type_traits/add_rvalue_reference.hpp> | ||||
|  | ||||
| //----------------------------------------------------------------------------// | ||||
| //                                                                            // | ||||
| //                           C++03 implementation of                          // | ||||
| //                          Written by Vicente J. Botet Escriba               // | ||||
| //~ 20.3.4 Function template declval [declval] | ||||
| //~ 1 The library provides the function template declval to simplify the definition of expressions which occur as | ||||
| //~ unevaluated operands. | ||||
| //~ 2 Remarks: If this function is used, the program is ill-formed. | ||||
| //~ 3 Remarks: The template parameter T of declval may be an incomplete type. | ||||
| //~ [ Example: | ||||
|  | ||||
| //~ template <class To, class From> | ||||
| //~ decltype(static_cast<To>(declval<From>())) convert(From&&); | ||||
|  | ||||
| //~ declares a function template convert which only participats in overloading if the type From can be | ||||
| //~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). <20>end | ||||
| //~ example ] | ||||
| //                                                                            // | ||||
| //----------------------------------------------------------------------------// | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
|     template <typename T> | ||||
|     typename add_rvalue_reference<T>::type declval(); //noexcept; // as unevaluated operand | ||||
|  | ||||
| }  // namespace boost | ||||
|  | ||||
| #endif  // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP | ||||
| @@ -5,7 +5,7 @@ | ||||
| // 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/lib/optional for documentation. | ||||
| // See http://www.boost.org/libs/optional for documentation. | ||||
| // | ||||
| // You are welcome to contact the author at: | ||||
| //  fernando_cacciola@hotmail.com | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| // 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/lib/optional for documentation. | ||||
| // See http://www.boost.org/libs/optional for documentation. | ||||
| // | ||||
| // You are welcome to contact the author at: | ||||
| //  fernando_cacciola@hotmail.com | ||||
|   | ||||
| @@ -20,10 +20,69 @@ | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : boost::detail::result_of_impl<F, F(BOOST_RESULT_OF_ARGS), (boost::detail::has_result_type<F>::value)> {}; | ||||
| struct tr1_result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : mpl::if_< | ||||
|           mpl::or_< is_pointer<F>, is_member_function_pointer<F> > | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type,  | ||||
|             typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),  | ||||
|             (boost::detail::has_result_type<F>::value)> | ||||
|         , boost::detail::tr1_result_of_impl< | ||||
|             F, | ||||
|             F(BOOST_RESULT_OF_ARGS),  | ||||
|             (boost::detail::has_result_type<F>::value)> >::type { }; | ||||
| #endif | ||||
|  | ||||
| #if !defined(BOOST_NO_DECLTYPE) && defined(BOOST_RESULT_OF_USE_DECLTYPE) | ||||
|  | ||||
| // As of N2588, C++0x result_of only supports function call | ||||
| // expressions of the form f(x). This precludes support for member | ||||
| // function pointers, which are invoked with expressions of the form | ||||
| // o->*f(x). This implementation supports both. | ||||
| template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> | ||||
|     : mpl::if_< | ||||
|           mpl::or_< is_pointer<F>, is_member_function_pointer<F> > | ||||
|         , detail::tr1_result_of_impl< | ||||
|             typename remove_cv<F>::type,  | ||||
|             typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false | ||||
|           > | ||||
|         , detail::cpp0x_result_of_impl< | ||||
|               F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|           > | ||||
|       >::type | ||||
| {}; | ||||
|  | ||||
| namespace detail { | ||||
|  | ||||
| # define BOOST_RESULT_OF_STATIC_MEMBERS(z, n, _) \ | ||||
|      static T ## n t ## n; \ | ||||
|   /**/ | ||||
|  | ||||
| template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| class cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))> | ||||
| { | ||||
|   static F f; | ||||
|   BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _) | ||||
| public: | ||||
|   typedef decltype(f(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),t))) type; | ||||
| }; | ||||
|  | ||||
| } // namespace detail  | ||||
|  | ||||
| #else // defined(BOOST_NO_DECLTYPE) | ||||
|  | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of<F(BOOST_RESULT_OF_ARGS)> | ||||
|     : tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { }; | ||||
| #endif | ||||
|  | ||||
| #endif // defined(BOOST_NO_DECLTYPE) | ||||
|  | ||||
| #undef BOOST_RESULT_OF_ARGS | ||||
|  | ||||
| #if BOOST_PP_ITERATION() >= 1  | ||||
| @@ -32,14 +91,14 @@ namespace detail { | ||||
|  | ||||
| template<typename R,  typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| struct tr1_result_of_impl<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| template<typename R,  typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| struct tr1_result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs, false> | ||||
| { | ||||
|   typedef R type; | ||||
| }; | ||||
| @@ -47,7 +106,7 @@ struct result_of_impl<R (&)(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), FArgs | ||||
| #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) | ||||
| template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (T0::*) | ||||
| struct tr1_result_of_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)), | ||||
|                  FArgs, false> | ||||
| { | ||||
| @@ -56,7 +115,7 @@ struct result_of_impl<R (T0::*) | ||||
|  | ||||
| template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (T0::*) | ||||
| struct tr1_result_of_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      const, | ||||
|                  FArgs, false> | ||||
| @@ -66,7 +125,7 @@ struct result_of_impl<R (T0::*) | ||||
|  | ||||
| template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (T0::*) | ||||
| struct tr1_result_of_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      volatile, | ||||
|                  FArgs, false> | ||||
| @@ -76,7 +135,7 @@ struct result_of_impl<R (T0::*) | ||||
|  | ||||
| template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) | ||||
|          BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)> | ||||
| struct result_of_impl<R (T0::*) | ||||
| struct tr1_result_of_impl<R (T0::*) | ||||
|                      (BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)) | ||||
|                      const volatile, | ||||
|                  FArgs, false> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| // 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/lib/optional for documentation. | ||||
| // See http://www.boost.org/libs/optional for documentation. | ||||
| // | ||||
| // You are welcome to contact the author at: | ||||
| //  fernando_cacciola@hotmail.com | ||||
|   | ||||
| @@ -10,13 +10,18 @@ | ||||
| #define BOOST_RESULT_OF_HPP | ||||
|  | ||||
| #include <boost/config.hpp> | ||||
| #include <boost/type_traits/ice.hpp> | ||||
| #include <boost/type.hpp> | ||||
| #include <boost/preprocessor.hpp> | ||||
| #include <boost/preprocessor/iteration/iterate.hpp>  | ||||
| #include <boost/preprocessor/punctuation/comma_if.hpp>  | ||||
| #include <boost/preprocessor/repetition/enum_params.hpp>  | ||||
| #include <boost/preprocessor/repetition/enum_shifted_params.hpp>  | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/mpl/has_xxx.hpp> | ||||
| #include <boost/mpl/if.hpp> | ||||
| #include <boost/mpl/bool.hpp> | ||||
| #include <boost/mpl/or.hpp> | ||||
| #include <boost/type_traits/is_pointer.hpp> | ||||
| #include <boost/type_traits/is_member_function_pointer.hpp> | ||||
| #include <boost/type_traits/remove_cv.hpp> | ||||
|  | ||||
| #ifndef BOOST_RESULT_OF_NUM_ARGS | ||||
| #  define BOOST_RESULT_OF_NUM_ARGS 10 | ||||
| @@ -25,13 +30,15 @@ | ||||
| namespace boost { | ||||
|  | ||||
| template<typename F> struct result_of; | ||||
| template<typename F> struct tr1_result_of; // a TR1-style implementation of result_of | ||||
|  | ||||
| #if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) | ||||
| namespace detail { | ||||
|  | ||||
| BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) | ||||
|  | ||||
| template<typename F, typename FArgs, bool HasResultType> struct result_of_impl; | ||||
| template<typename F, typename FArgs, bool HasResultType> struct tr1_result_of_impl; | ||||
| template<typename F> struct cpp0x_result_of_impl; | ||||
|  | ||||
| template<typename F> | ||||
| struct result_of_void_impl | ||||
| @@ -51,8 +58,13 @@ struct result_of_void_impl<R (&)(void)> | ||||
|   typedef R type; | ||||
| }; | ||||
|  | ||||
| // Determine the return type of a function pointer or pointer to member. | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_impl<F, FArgs, true> | ||||
| struct result_of_pointer | ||||
|   : tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { }; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct tr1_result_of_impl<F, FArgs, true> | ||||
| { | ||||
|   typedef typename F::result_type type; | ||||
| }; | ||||
| @@ -68,7 +80,7 @@ struct result_of_nested_result : F::template result<FArgs> | ||||
| {}; | ||||
|  | ||||
| template<typename F, typename FArgs> | ||||
| struct result_of_impl<F, FArgs, false> | ||||
| struct tr1_result_of_impl<F, FArgs, false> | ||||
|   : mpl::if_<is_function_with_no_args<FArgs>, | ||||
|              result_of_void_impl<F>, | ||||
|              result_of_nested_result<F, FArgs> >::type | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| // 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/lib/optional for documentation. | ||||
| // See http://www.boost.org/libs/optional for documentation. | ||||
| // | ||||
| // You are welcome to contact the author at: | ||||
| //  fernando_cacciola@hotmail.com | ||||
|   | ||||
| @@ -9,6 +9,8 @@ | ||||
| // 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola | ||||
| // 21 Ago 2008 (Added swap) Niels Dekker, Fernando Cacciola | ||||
| // 20 Feb 2009 (Fixed logical const-ness issues) Niels Dekker, Fernando Cacciola | ||||
| // 03 Apr 2010 (Added initialized<T>, suggested by Jeffrey Hellrung, fixing #3472) Niels Dekker | ||||
| // 30 May 2010 (Made memset call conditional, fixing #3869) Niels Dekker | ||||
| // | ||||
| #ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP | ||||
| #define BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP | ||||
| @@ -20,6 +22,7 @@ | ||||
| // contains. More details on these issues are at libs/utility/value_init.htm | ||||
|  | ||||
| #include <boost/aligned_storage.hpp> | ||||
| #include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION. | ||||
| #include <boost/detail/workaround.hpp> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/type_traits/cv_traits.hpp> | ||||
| @@ -28,10 +31,39 @@ | ||||
| #include <cstring> | ||||
| #include <new> | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(push) | ||||
| #if _MSC_VER >= 1310 | ||||
| // It is safe to ignore the following warning from MSVC 7.1 or higher: | ||||
| // "warning C4351: new behavior: elements of array will be default initialized" | ||||
| #pragma warning(disable: 4351) | ||||
| // It is safe to ignore the following MSVC warning, which may pop up when T is  | ||||
| // a const type: "warning C4512: assignment operator could not be generated". | ||||
| #pragma warning(disable: 4512) | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| #ifdef BOOST_NO_COMPLETE_VALUE_INITIALIZATION | ||||
|   // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED  | ||||
|   // suggests that a workaround should be applied, because of compiler issues  | ||||
|   // regarding value-initialization. | ||||
|   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED | ||||
| #endif | ||||
|  | ||||
| // Implementation detail: The macro BOOST_DETAIL_VALUE_INIT_WORKAROUND | ||||
| // switches the value-initialization workaround either on or off. | ||||
| #ifndef BOOST_DETAIL_VALUE_INIT_WORKAROUND | ||||
|   #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED | ||||
|   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 1 | ||||
|   #else | ||||
|   #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
| namespace boost { | ||||
|  | ||||
| template<class T> | ||||
| class value_initialized | ||||
| class initialized | ||||
| { | ||||
|   private : | ||||
|     struct wrapper | ||||
| @@ -40,6 +72,18 @@ class value_initialized | ||||
|       typename | ||||
| #endif  | ||||
|       remove_const<T>::type data; | ||||
|  | ||||
|       wrapper() | ||||
|       : | ||||
|       data() | ||||
|       { | ||||
|       } | ||||
|  | ||||
|       wrapper(T const & arg) | ||||
|       : | ||||
|       data(arg) | ||||
|       { | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|     mutable | ||||
| @@ -55,30 +99,25 @@ class value_initialized | ||||
|  | ||||
|   public : | ||||
|  | ||||
|     value_initialized() | ||||
|     initialized() | ||||
|     { | ||||
| #if BOOST_DETAIL_VALUE_INIT_WORKAROUND | ||||
|       std::memset(&x, 0, sizeof(x)); | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(push) | ||||
| #if _MSC_VER >= 1310 | ||||
| // When using MSVC 7.1 or higher, the following placement new expression may trigger warning C4345: | ||||
| // "behavior change: an object of POD type constructed with an initializer of the form () | ||||
| // will be default-initialized".  It is safe to ignore this warning when using value_initialized. | ||||
| #pragma warning(disable: 4345) | ||||
| #endif | ||||
| #endif | ||||
|       new (wrapper_address()) wrapper(); | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|     value_initialized(value_initialized const & arg) | ||||
|     initialized(initialized const & arg) | ||||
|     { | ||||
|       new (wrapper_address()) wrapper( static_cast<wrapper const &>(*(arg.wrapper_address()))); | ||||
|     } | ||||
|  | ||||
|     value_initialized & operator=(value_initialized const & arg) | ||||
|     explicit initialized(T const & arg) | ||||
|     { | ||||
|       new (wrapper_address()) wrapper(arg); | ||||
|     } | ||||
|  | ||||
|     initialized & operator=(initialized const & arg) | ||||
|     { | ||||
|       // Assignment is only allowed when T is non-const. | ||||
|       BOOST_STATIC_ASSERT( ! is_const<T>::value ); | ||||
| @@ -86,7 +125,7 @@ class value_initialized | ||||
|       return *this; | ||||
|     } | ||||
|  | ||||
|     ~value_initialized() | ||||
|     ~initialized() | ||||
|     { | ||||
|       wrapper_address()->wrapper::~wrapper(); | ||||
|     } | ||||
| @@ -101,17 +140,81 @@ class value_initialized | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     void swap(value_initialized & arg) | ||||
|     void swap(initialized & arg) | ||||
|     { | ||||
|       ::boost::swap( this->data(), arg.data() ); | ||||
|     } | ||||
|  | ||||
|     operator T const &() const { return this->data(); } | ||||
|     operator T const &() const | ||||
|     { | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
|     operator T&() { return this->data(); } | ||||
|     operator T&() | ||||
|     { | ||||
|       return wrapper_address()->data; | ||||
|     } | ||||
|  | ||||
| } ; | ||||
|  | ||||
| template<class T> | ||||
| T const& get ( initialized<T> const& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| T& get ( initialized<T>& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| void swap ( initialized<T> & lhs, initialized<T> & rhs ) | ||||
| { | ||||
|   lhs.swap(rhs) ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| class value_initialized | ||||
| { | ||||
|   private : | ||||
|  | ||||
|     // initialized<T> does value-initialization by default. | ||||
|     initialized<T> m_data; | ||||
|  | ||||
|   public : | ||||
|      | ||||
|     value_initialized() | ||||
|     : | ||||
|     m_data() | ||||
|     { } | ||||
|      | ||||
|     T const & data() const | ||||
|     { | ||||
|       return m_data.data(); | ||||
|     } | ||||
|  | ||||
|     T& data() | ||||
|     { | ||||
|       return m_data.data(); | ||||
|     } | ||||
|  | ||||
|     void swap(value_initialized & arg) | ||||
|     { | ||||
|       m_data.swap(arg.m_data); | ||||
|     } | ||||
|  | ||||
|     operator T const &() const | ||||
|     { | ||||
|       return m_data; | ||||
|     } | ||||
|  | ||||
|     operator T&() | ||||
|     { | ||||
|       return m_data; | ||||
|     } | ||||
| } ; | ||||
|  | ||||
|  | ||||
| template<class T> | ||||
| @@ -119,6 +222,7 @@ T const& get ( value_initialized<T> const& x ) | ||||
| { | ||||
|   return x.data() ; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| T& get ( value_initialized<T>& x ) | ||||
| { | ||||
| @@ -138,7 +242,7 @@ class initialized_value_t | ||||
|      | ||||
|     template <class T> operator T() const | ||||
|     { | ||||
|       return get( value_initialized<T>() ); | ||||
|       return initialized<T>().data(); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @@ -147,5 +251,8 @@ initialized_value_t const initialized_value = {} ; | ||||
|  | ||||
| } // namespace boost | ||||
|  | ||||
| #ifdef BOOST_MSVC | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										12
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								index.html
									
									
									
									
									
								
							| @@ -14,20 +14,28 @@ | ||||
| 		<p>But that doesn't mean there isn't useful stuff here. Take a look:</p> | ||||
| 		<blockquote> | ||||
| 			<p> | ||||
| 				<a href="utility.htm#addressof">addressof</a><br> | ||||
| 				<a href="assert.html">assert</a><br> | ||||
| 				<a href="base_from_member.html">base_from_member</a><br> | ||||
| 				<a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a><br> | ||||
| 				<a href="call_traits.htm">call_traits</a><br> | ||||
| 				<a href="checked_delete.html">checked_delete</a><br> | ||||
| 				<a href="compressed_pair.htm">compressed_pair</a><br> | ||||
| 				<a href="current_function.html">current_function</a><br> | ||||
| 				<a href="enable_if.html">enable_if</a><br> | ||||
|             <a href="doc/html/declval.html">declval</a><br> | ||||
|             <a href="enable_if.html">enable_if</a><br> | ||||
| 				<a href="in_place_factories.html">in_place_factory</a><br> | ||||
|             <a href="iterator_adaptors.htm">iterator_adaptors</a><br> | ||||
|             <a href="generator_iterator.htm">generator iterator adaptors</a><br> | ||||
| 				<a href="utility.htm#functions_next_prior">next/prior</a><br> | ||||
| 				<a href="utility.htm#Class_noncopyable">noncopyable</a><br> | ||||
| 				<a href="operators.htm">operators</a><br> | ||||
| 				<a href="utility.htm#result_of">result_of</a><br> | ||||
| 				<a href="swap.html">swap</a><br> | ||||
| 				<a href="throw_exception.html">throw_exception</a><br> | ||||
| 				<a href="utility.htm">utility</a><br> | ||||
|                 <a href="value_init.htm">value_init</a></p> | ||||
|             <a href="value_init.htm">value_init</a> | ||||
|          </p> | ||||
| 		</blockquote> | ||||
| 		<hr> | ||||
| 		<p>© Copyright Beman Dawes, 2001</p> | ||||
|   | ||||
							
								
								
									
										116
									
								
								initialized_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								initialized_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| // Copyright 2010, Niels Dekker. | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| // Test program for boost::initialized<T>. | ||||
| // | ||||
| // 2 May 2010 (Created) Niels Dekker | ||||
|  | ||||
| #include <boost/utility/value_init.hpp> | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace | ||||
| { | ||||
|   // Typical use case for boost::initialized<T>: A generic class that  | ||||
|   // holds a value of type T, which must be initialized by either  | ||||
|   // value-initialization or direct-initialization. | ||||
|   template <class T> class key_value_pair | ||||
|   { | ||||
|     std::string m_key; | ||||
|     boost::initialized<T> m_value; | ||||
|   public: | ||||
|   | ||||
|     // Value-initializes the object held by m_value. | ||||
|     key_value_pair() { } | ||||
|  | ||||
|     // Value-initializes the object held by m_value. | ||||
|     explicit key_value_pair(const std::string& key) | ||||
|     : | ||||
|     m_key(key) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     // Direct-initializes the object held by m_value. | ||||
|     key_value_pair(const std::string& key, const T& value) | ||||
|     : | ||||
|     m_key(key), m_value(value) | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     const T& get_value() const | ||||
|     { | ||||
|       return m_value; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|  | ||||
|   // Tells whether the argument is value-initialized. | ||||
|   bool is_value_initialized(const int& arg) | ||||
|   { | ||||
|     return arg == 0; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Tells whether the argument is value-initialized. | ||||
|   bool is_value_initialized(const std::string& arg) | ||||
|   { | ||||
|     return arg.empty(); | ||||
|   } | ||||
|  | ||||
|   struct foo | ||||
|   { | ||||
|     int data; | ||||
|   }; | ||||
|  | ||||
|   bool operator==(const foo& lhs, const foo& rhs) | ||||
|   { | ||||
|     return lhs.data == rhs.data; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   // Tells whether the argument is value-initialized. | ||||
|   bool is_value_initialized(const foo& arg) | ||||
|   { | ||||
|     return arg.data == 0; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   template <class T> | ||||
|   void test_key_value_pair(const T& magic_value) | ||||
|   { | ||||
|     // The value component of a default key_value_pair must be value-initialized. | ||||
|     key_value_pair<T> default_key_value_pair; | ||||
|     BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) ); | ||||
|  | ||||
|     // The value component of a key_value_pair that only has its key explicitly specified | ||||
|     // must also be value-initialized. | ||||
|     BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) ); | ||||
|  | ||||
|     // However, the value component of the following key_value_pair must be  | ||||
|     // "magic_value", as it must be direct-initialized. | ||||
|     BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value ); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| // Tests boost::initialize for a fundamental type, a type with a | ||||
| // user-defined constructor, and a user-defined type without  | ||||
| // a user-defined constructor. | ||||
| int main() | ||||
| { | ||||
|  | ||||
|   const int magic_number = 42; | ||||
|   test_key_value_pair(magic_number); | ||||
|  | ||||
|   const std::string magic_string = "magic value"; | ||||
|   test_key_value_pair(magic_string); | ||||
|  | ||||
|   const foo magic_foo = { 42 }; | ||||
|   test_key_value_pair(magic_foo); | ||||
|  | ||||
|   return boost::report_errors(); | ||||
| } | ||||
							
								
								
									
										33
									
								
								initialized_test_fail1.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								initialized_test_fail1.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| // Copyright 2010, Niels Dekker. | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| // Test program for boost::initialized<T>. Must fail to compile. | ||||
| // | ||||
| // Initial: 2 May 2010 | ||||
|  | ||||
| #include <boost/utility/value_init.hpp> | ||||
|  | ||||
| namespace | ||||
| { | ||||
|   void direct_initialize_from_int() | ||||
|   { | ||||
|     // Okay: initialized<T> supports direct-initialization from T. | ||||
|     boost::initialized<int> direct_initialized_int(1); | ||||
|   } | ||||
|  | ||||
|   void copy_initialize_from_int() | ||||
|   { | ||||
|     // The following line should not compile, because initialized<T>  | ||||
|     // was not intended to supports copy-initialization from T. | ||||
|     boost::initialized<int> copy_initialized_int = 1; | ||||
|   } | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   // This should fail to compile, so there is no need to call any function. | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										37
									
								
								initialized_test_fail2.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								initialized_test_fail2.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // Copyright 2010, Niels Dekker. | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| // Test program for boost::initialized<T>. Must fail to compile. | ||||
| // | ||||
| // Initial: 2 May 2010 | ||||
|  | ||||
| #include <boost/utility/value_init.hpp> | ||||
|  | ||||
| namespace | ||||
| { | ||||
|   void from_value_initialized_to_initialized() | ||||
|   { | ||||
|     boost::value_initialized<int> value_initialized_int; | ||||
|  | ||||
|     // Okay: initialized<T> can be initialized by value_initialized<T>. | ||||
|     boost::initialized<int> initialized_int(value_initialized_int); | ||||
|   } | ||||
|  | ||||
|   void from_initialized_to_value_initialized() | ||||
|   { | ||||
|     boost::initialized<int> initialized_int(13); | ||||
|  | ||||
|     // The following line should not compile, because initialized<T> | ||||
|     // should not be convertible to value_initialized<T>. | ||||
|     boost::value_initialized<int> value_initialized_int(initialized_int); | ||||
|   } | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   // This should fail to compile, so there is no need to call any function. | ||||
|   return 0; | ||||
| } | ||||
| @@ -32,9 +32,13 @@ test-suite utility | ||||
|         [ compile result_of_test.cpp ] | ||||
|         [ run ../shared_iterator_test.cpp ] | ||||
|         [ run ../value_init_test.cpp ] | ||||
|         [ run ../value_init_workaround_test.cpp ] | ||||
|         [ run ../initialized_test.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail1.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail2.cpp ] | ||||
|         [ compile-fail ../value_init_test_fail3.cpp ] | ||||
|         [ compile-fail ../initialized_test_fail1.cpp ] | ||||
|         [ compile-fail ../initialized_test_fail2.cpp ] | ||||
|         [ run ../verify_test.cpp ] | ||||
|     ; | ||||
|  | ||||
|   | ||||
| @@ -5,41 +5,109 @@ | ||||
| //  1.0. (See accompanying file LICENSE_1_0.txt or copy at | ||||
| //  http://www.boost.org/LICENSE_1_0.txt) | ||||
|  | ||||
| #define BOOST_RESULT_OF_USE_DECLTYPE | ||||
|  | ||||
| // For more information, see http://www.boost.org/libs/utility | ||||
| #include <boost/utility/result_of.hpp> | ||||
| #include <utility> | ||||
| #include <boost/static_assert.hpp> | ||||
| #include <boost/type_traits/is_same.hpp> | ||||
|  | ||||
| struct int_result_type { typedef int result_type; }; | ||||
| struct int_result_type | ||||
| { | ||||
|   typedef int result_type; | ||||
|   result_type operator()(float); | ||||
| }; | ||||
|  | ||||
| struct int_result_of | ||||
| { | ||||
|   template<typename F> struct result { typedef int type; }; | ||||
|   result<int_result_of(double)>::type operator()(double); | ||||
|   result<const int_result_of(double)>::type operator()(double) const; | ||||
|   result<int_result_of()>::type operator()(); | ||||
|   result<volatile int_result_of()>::type operator()() volatile; | ||||
| }; | ||||
|  | ||||
| struct int_result_type_and_float_result_of | ||||
| struct int_result_type_and_float_result_of_and_char_return | ||||
| { | ||||
|   typedef int result_type; | ||||
|   template<typename F> struct result { typedef float type; }; | ||||
|   char operator()(char); | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_type_template { typedef int result_type; }; | ||||
| struct int_result_type_template | ||||
| { | ||||
|   typedef int result_type; | ||||
|   result_type operator()(float); | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_of_template | ||||
| { | ||||
|   template<typename F> struct result; | ||||
|   template<typename This, typename That> struct result<This(That)> { typedef int type; }; | ||||
|   typename result<int_result_of_template<T>(double)>::type operator()(double); | ||||
|   typename result<const int_result_of_template<T>(double)>::type operator()(double) const; | ||||
|   typename result<int_result_of_template<T>(double)>::type operator()(); | ||||
|   typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct int_result_type_and_float_result_of_template | ||||
| struct int_result_type_and_float_result_of_and_char_return_template | ||||
| { | ||||
|   typedef int result_type; | ||||
|   template<typename F> struct result; | ||||
|   template<typename This, typename That> struct result<This(That)> { typedef float type; }; | ||||
|   char operator()(char); | ||||
| }; | ||||
|  | ||||
| struct result_of_member_function_template | ||||
| { | ||||
|   template<typename F> struct result; | ||||
|  | ||||
|   template<typename This, typename That> struct result<This(That)> { typedef That type; }; | ||||
|   template<class T> typename result<result_of_member_function_template(T)>::type operator()(T); | ||||
|  | ||||
|   template<typename This, typename That> struct result<const This(That)> { typedef const That type; }; | ||||
|   template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const; | ||||
|  | ||||
|   template<typename This, typename That> struct result<volatile This(That)> { typedef volatile That type; }; | ||||
|   template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile; | ||||
|  | ||||
|   template<typename This, typename That> struct result<const volatile This(That)> { typedef const volatile That type; }; | ||||
|   template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile; | ||||
|  | ||||
|   template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; }; | ||||
|   template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T); | ||||
|  | ||||
|   template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; }; | ||||
|   template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T); | ||||
|  | ||||
|   template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; }; | ||||
|   template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T); | ||||
|  | ||||
|   template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; }; | ||||
|   template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T); | ||||
| }; | ||||
|  | ||||
| struct no_result_type_or_result_of | ||||
| { | ||||
|   int operator()(double); | ||||
|   short operator()(double) const; | ||||
|   unsigned int operator()(); | ||||
|   unsigned short operator()() volatile; | ||||
|   const unsigned short operator()() const volatile; | ||||
| }; | ||||
|  | ||||
| template<typename T> | ||||
| struct no_result_type_or_result_of_template | ||||
| { | ||||
|   int operator()(double); | ||||
|   short operator()(double) const; | ||||
|   unsigned int operator()(); | ||||
|   unsigned short operator()() volatile; | ||||
|   const unsigned short operator()() const volatile; | ||||
| }; | ||||
|  | ||||
| struct X {}; | ||||
| @@ -60,16 +128,52 @@ int main() | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); | ||||
|  | ||||
|   // Prior to decltype, result_of could not deduce the return type | ||||
|   // nullary function objects unless they exposed a result_type. | ||||
| #if !defined(BOOST_NO_DECLTYPE) | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value)); | ||||
| #else | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_template<void>(char)>::type, int>::value)); | ||||
| #endif | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); | ||||
|  | ||||
|   // Prior to decltype, result_of ignored a nested result<> if | ||||
|   // result_type was defined. After decltype, result_of deduces the | ||||
|   // actual return type of the function object, ignoring both | ||||
|   // result<> and result_type. | ||||
| #if !defined(BOOST_NO_DECLTYPE) | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value)); | ||||
| #else | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value)); | ||||
| #endif | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));  | ||||
| @@ -81,5 +185,54 @@ int main() | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, const double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, const double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, volatile double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, const volatile double>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value)); | ||||
|  | ||||
|   typedef int (*pf_t)(int); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value)); | ||||
|  | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value)); | ||||
|  | ||||
| #if !defined(BOOST_NO_DECLTYPE) | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of(void)>::type, unsigned int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of(double)>::type, short>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of(void)>::type, unsigned short>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of(void)>::type, const unsigned short>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(double)>::type, int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_of_template<void>(void)>::type, unsigned int>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_of_template<void>(double)>::type, short>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_of_template<void>(void)>::type, unsigned short>::value)); | ||||
|   BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_of_template<void>(void)>::type, const unsigned short>::value)); | ||||
| #endif | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										94
									
								
								utility.htm
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								utility.htm
									
									
									
									
									
								
							| @@ -151,35 +151,95 @@ void f() { | ||||
|                 <code>result_of<F(T1, T2, ..., | ||||
|                 T<em>N</em>)>::type</code> defines the result type | ||||
|                 of the expression <code>f(t1, t2, | ||||
|                 ...,t<em>N</em>)</code>. The implementation permits | ||||
|                 ...,t<em>N</em>)</code>. This implementation permits | ||||
|                 the type <code>F</code> to be a function pointer, | ||||
|                 function reference, member function pointer, or class | ||||
|                 type. When <code>F</code> is a class type with a | ||||
|                 type. By default, <em>N</em> may be any value between 0 and | ||||
|                 10. To change the upper limit, define the macro | ||||
|                 <code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum | ||||
|                 value for <em>N</em>. Class template <code>result_of</code> | ||||
|                 resides in the header <code><<a | ||||
|                 href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>.</p> | ||||
|  | ||||
|                 <p>If your compiler supports <code>decltype</code>, | ||||
|                 then you can enable automatic result type deduction by | ||||
|                 defining the macro <code>BOOST_RESULT_OF_USE_DECLTYPE</code>, | ||||
|                 as in the following example.</p> | ||||
|  | ||||
|                 <blockquote> | ||||
|                 <pre>#define BOOST_RESULT_OF_USE_DECLTYPE | ||||
| #include <boost/utility/result_of.hpp> | ||||
|  | ||||
| struct functor { | ||||
|     template<class T> | ||||
|     T operator()(T x) | ||||
|     { | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| typedef boost::result_of< | ||||
|     functor(int) | ||||
| >::type type;</pre> | ||||
|                 </blockquote> | ||||
|  | ||||
|                 <p>If <code>decltype</code> is not enabled, | ||||
|                 then automatic result type deduction of function | ||||
|                 objects is not possible. Instead, <code>result_of</code> | ||||
|                 uses the following protocol to allow the programmer to | ||||
|                 specify a type. When <code>F</code> is a class type with a | ||||
|                 member type <code>result_type</code>, | ||||
|                 <code>result_of<F(T1, T2, ..., | ||||
|                 T<em>N</em>)></code> is | ||||
|                 <code>F::result_type</code>. Otherwise, | ||||
|                 <code>F::result_type</code>. When <code>F</code> does | ||||
|                 not contain <code>result_type</code>, | ||||
|                 <code>result_of<F(T1, T2, ..., | ||||
|                 T<em>N</em>)></code> is <code>F::result<F(T1, | ||||
|                 T2, ..., T<em>N</em>)>::type</code> when | ||||
|                 <code><em>N</em> > 0</code> or <code>void</code> | ||||
|                 when <code><em>N</em> = 0</code>. For additional | ||||
|                 information about <code>result_of</code>, see the | ||||
|                 C++ Library Technical Report, <a | ||||
|                 href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>, | ||||
|                 or, for motivation and design rationale, the <code>result_of</code> <a | ||||
|                 href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p> | ||||
|                 when <code><em>N</em> = 0</code>. Note that it is the | ||||
|                 responsibility of the programmer to ensure that | ||||
|                 function objects accurately advertise their result | ||||
|                 type via this protocol, as in the following | ||||
|                 example.</p> | ||||
|  | ||||
|                 <p>Class template <code>result_of</code> resides in | ||||
|                 the header <code><<a | ||||
|                 href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By | ||||
|                 default, <em>N</em> may be any value between 0 and | ||||
|                 10. To change the upper limit, define the macro | ||||
|                 <code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum | ||||
|                 value for <em>N</em>.</p> | ||||
|                 <blockquote> | ||||
|                 <pre>struct functor { | ||||
|     template<class> struct result; | ||||
|  | ||||
|     template<class F, class T> | ||||
|     struct result<F(T)> { | ||||
|         typedef T type; | ||||
|     }; | ||||
|  | ||||
|     template<class T> | ||||
|     T operator()(T x) | ||||
|     { | ||||
|         return x; | ||||
|     } | ||||
| }; | ||||
|  | ||||
| typedef boost::result_of< | ||||
|     functor(int) | ||||
| >::type type;</pre> | ||||
|                 </blockquote> | ||||
|  | ||||
|                 <a name="BOOST_NO_RESULT_OF"></a> | ||||
|                 <p>This implementation of <code>result_of</code> requires class template partial specialization, the ability to parse function types properly, and support for SFINAE. If <code>result_of</code> is not supported by your compiler, including the header <code>boost/utility/result_of.hpp</code> will define the macro <code>BOOST_NO_RESULT_OF</code>. Contributed by Doug Gregor.</p> | ||||
|                 <p>This implementation of <code>result_of</code> | ||||
|                 requires class template partial specialization, the | ||||
|                 ability to parse function types properly, and support | ||||
|                 for SFINAE. If <code>result_of</code> is not supported | ||||
|                 by your compiler, including the header  | ||||
|                 <code>boost/utility/result_of.hpp</code> will | ||||
|                 define the macro <code>BOOST_NO_RESULT_OF</code>.</p> | ||||
|  | ||||
|                 <p>For additional information | ||||
|                 about <code>result_of</code>, see the C++ Library | ||||
|                 Technical Report, | ||||
|                 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>, | ||||
|                 or, for motivation and design rationale, | ||||
|                 the <code>result_of</code> <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p> | ||||
|                 Contributed by Doug Gregor.</p> | ||||
|  | ||||
| 		<h2>Class templates for the Base-from-Member Idiom</h2> | ||||
| 		<p>See <a href="base_from_member.html">separate documentation</a>.</p> | ||||
|   | ||||
							
								
								
									
										140
									
								
								value_init.htm
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								value_init.htm
									
									
									
									
									
								
							| @@ -33,6 +33,7 @@ | ||||
|                     | ||||
| <ul> | ||||
|           <li><a href="#val_init"><code>template class value_initialized<T></code></a></li> | ||||
|           <li><a href="#initialized"><code>template class initialized<T></code></a></li> | ||||
|           <li><a href="#initialized_value"><code>initialized_value</code></a></li> | ||||
|                     | ||||
| </ul> | ||||
| @@ -123,6 +124,12 @@ constructed by the following declaration: | ||||
| </pre> | ||||
| </p> | ||||
| <p> | ||||
| The template <a href="#initialized"><code>initialized</code></a> | ||||
| offers both value-initialization and direct-initialization. | ||||
| It is especially useful as a data member type, allowing the very same object | ||||
| to be either direct-initialized or value-initialized. | ||||
| </p> | ||||
| <p> | ||||
| The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a> | ||||
| allows value-initializing a variable as follows: | ||||
| <pre> | ||||
| @@ -216,37 +223,65 @@ it <em>may</em> in practice still be left uninitialized, because of those | ||||
| compiler issues! It's hard to make a general statement on what those issues | ||||
| are like, because they depend on the compiler you are using, its version number, | ||||
| and the type of object you would like to have value-initialized. | ||||
| Compilers usually support value-initialization for built-in types properly. | ||||
| But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em> | ||||
| be partially, or even entirely left uninitialized, when they should be value-initialized. | ||||
| All compilers we have tested so far support value-initialization for arithmetic types properly. | ||||
| However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they  | ||||
| should be value-initialized. Value-initialization of objects of a pointer-to-member type may also | ||||
| go wrong on various compilers.  | ||||
| </p> | ||||
| <p> | ||||
| We have encountered issues regarding value-initialization on compilers by | ||||
| Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues: | ||||
| <table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" > | ||||
| <tr><td> | ||||
| <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744"> | ||||
| Microsoft Feedback ID 100744 - Value-initialization in new-expression</a> | ||||
| <br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28 | ||||
| <br> | ||||
| <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111"> | ||||
| GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a> | ||||
| <br>Reported by Jonathan Wakely, 2006-12-07  | ||||
| <br> | ||||
| <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916"> | ||||
| GCC Bug 33916 - Default constructor fails to initialize array members</a> | ||||
| <br>Reported by Michael Elizabeth Chastain, 2007-10-26 | ||||
| <br> | ||||
| <a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854"> | ||||
| Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a> | ||||
| <br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11 | ||||
| <br> | ||||
| </td></tr></table> | ||||
| At the moment of writing, May 2010, the following reported issues regarding  | ||||
| value-initialization are still there in current compiler releases: | ||||
| <ul> | ||||
| <li> | ||||
| <a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744"> | ||||
| Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a> | ||||
| <br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005 | ||||
| </li><li> | ||||
| <a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295"> | ||||
| Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a> | ||||
| <br>Reported by Sylvester Hesp, 2009 | ||||
| </li><li> | ||||
| <a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606"> | ||||
| Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a> | ||||
| <br>Reported by Alex Vakulenko, 2009 | ||||
| </li><li> | ||||
| <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751"> | ||||
| Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a> | ||||
| <br>Reported by Niels Dekker (LKEB), 2010 | ||||
| </li><li> | ||||
| <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851"> | ||||
| Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a> | ||||
| <br>Reported by Niels Dekker, 2010 | ||||
| </li><li> | ||||
| <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279"> | ||||
| Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a> | ||||
| <br>Reported by Niels Dekker, 2010 | ||||
| </li><li> | ||||
| Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate. | ||||
| <br>Reported to Steve Clamage by Niels Dekker, 2010 | ||||
| </li><li> | ||||
| IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate. | ||||
| <br>Reported to Michael Wong by Niels Dekker, 2010 | ||||
| </li><li> | ||||
| Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error | ||||
| on Intel 11.1. | ||||
| <br>Reported by John Maddock, 2010 | ||||
| </li> | ||||
| </ul> | ||||
| Note that all known GCC issues regarding value-initialization are | ||||
| fixed with GCC version 4.4, including | ||||
| <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>. | ||||
| Clang also has completely implemented value-initialization, as far as we know, | ||||
| now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.  | ||||
| </p><p> | ||||
|  | ||||
| New versions of <code>value_initialized</code> | ||||
| (Boost release version 1.35 or higher) | ||||
| offer a workaround to these issues: <code>value_initialized</code> will now clear | ||||
| its internal data, prior to constructing the object that it contains. | ||||
| offer a workaround to these issues: <code>value_initialized</code> may now clear | ||||
| its internal data, prior to constructing the object that it contains. It will do | ||||
| so for those compilers that need to have such a workaround, based on the | ||||
| <a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects" | ||||
| >compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION. | ||||
| </p> | ||||
|                     | ||||
| <h2><a name="types"></a>Types and objects</h2> | ||||
| @@ -340,6 +375,52 @@ the wrapped object is always performed with the <code>get()</code> idiom:</p> | ||||
|                     | ||||
| <pre>value_initialized<int> x ;<br>get(x) = 1 ; // OK<br><br>value_initialized<int const> cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int> const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized<int const> const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre> | ||||
|  | ||||
| <h2><a name="initialized"><code>template class initialized<T></code></a></h2> | ||||
|                     | ||||
| <pre>namespace boost {<br><br>template<class T><br>class initialized<br>{ | ||||
| <br>  public : | ||||
| <br>    initialized() : x() {} | ||||
| <br>    explicit initialized(T const & arg) : x(arg) {} | ||||
| <br>    operator T const &() const; | ||||
| <br>    operator T&(); | ||||
| <br>    T const &data() const; | ||||
| <br>    T& data(); | ||||
| <br>    void swap( value_initialized<T>& ); | ||||
| <br> | ||||
| <br>  private : | ||||
| <br>    <i>unspecified</i> x ; | ||||
| <br>} ; | ||||
| <br> | ||||
| <br>template<class T> | ||||
| <br>T const& get ( initialized<T> const& x ); | ||||
| <br> | ||||
| <br>template<class T> | ||||
| <br>T& get ( initialized<T>& x ); | ||||
| <br> | ||||
| <br>} // namespace boost | ||||
| <br></pre> | ||||
|  | ||||
| The template class <code>boost::initialized<T></code> supports both value-initialization | ||||
| and direct-initialization, so its interface is a superset of the interface | ||||
| of <code>value_initialized<T></code>: Its default-constructor  | ||||
| value-initializes the wrapped object just like the default-constructor of | ||||
| <code>value_initialized<T></code>, but <code>boost::initialized<T></code> | ||||
| also offers an extra <code>explicit</code> | ||||
| constructor, which direct-initializes the wrapped object by the specified value. | ||||
| <p> | ||||
|  | ||||
| <code>initialized<T></code> is especially useful when the wrapped | ||||
| object must be either value-initialized or direct-initialized, depending on | ||||
| runtime conditions. For example, <code>initialized<T></code> could | ||||
| hold the value of a data member that may be value-initialized by some | ||||
| constructors, and direct-initialized by others. | ||||
| On the other hand, if it is known beforehand that the | ||||
| object must <i>always</i> be value-initialized, <code>value_initialized<T></code> | ||||
| may be preferable. And if the object must always be | ||||
| direct-initialized, none of the two wrappers really needs to be used. | ||||
| </p> | ||||
|   | ||||
|  | ||||
| <h2><a name="initialized_value"><code>initialized_value</code></a></h2> | ||||
|  | ||||
| <pre> | ||||
| @@ -399,6 +480,9 @@ Special thanks to Björn Karlsson who carefully edited and completed this do | ||||
| <p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker | ||||
| for Boost release version 1.35 (2008), offering a workaround to various compiler issues. | ||||
|      </p> | ||||
| <p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and  | ||||
|   Jeffrey Hellrung. | ||||
|      </p> | ||||
| <p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008). | ||||
|      </p> | ||||
| <p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>, | ||||
| @@ -407,9 +491,9 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler | ||||
|      </p> | ||||
|                      | ||||
| <hr>           | ||||
| <p>Revised 03 October 2009</p> | ||||
| <p>Revised 30 May 2010</p> | ||||
|                     | ||||
| <p>© Copyright Fernando Cacciola, 2002, 2009.</p> | ||||
| <p>© Copyright Fernando Cacciola, 2002 - 2010.</p> | ||||
|                     | ||||
| <p>Distributed under the Boost Software License, Version 1.0. See | ||||
| <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p> | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
| #pragma hdrstop | ||||
| #endif | ||||
|  | ||||
| #include "boost/test/minimal.hpp" | ||||
| #include <boost/detail/lightweight_test.hpp> | ||||
|  | ||||
| // | ||||
| // Sample POD type | ||||
| @@ -215,7 +215,7 @@ template<class T> | ||||
| void check_initialized_value ( T const& y ) | ||||
| { | ||||
|   T initializedValue = boost::initialized_value ; | ||||
|   BOOST_CHECK ( y == initializedValue ) ; | ||||
|   BOOST_TEST ( y == initializedValue ) ; | ||||
| } | ||||
|  | ||||
| #ifdef  __BORLANDC__ | ||||
| @@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& ) | ||||
| template<class T> | ||||
| bool test ( T const& y, T const& z ) | ||||
| { | ||||
|   const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); | ||||
|   const int errors_before_test = boost::detail::test_errors(); | ||||
|  | ||||
|   check_initialized_value(y); | ||||
|  | ||||
|   boost::value_initialized<T> x ; | ||||
|   BOOST_CHECK ( y == x ) ; | ||||
|   BOOST_CHECK ( y == boost::get(x) ) ; | ||||
|   BOOST_TEST ( y == x ) ; | ||||
|   BOOST_TEST ( y == boost::get(x) ) ; | ||||
|  | ||||
|   static_cast<T&>(x) = z ; | ||||
|   boost::get(x) = z ; | ||||
|   BOOST_CHECK ( x == z ) ; | ||||
|   BOOST_TEST ( x == z ) ; | ||||
|  | ||||
|   boost::value_initialized<T> const x_c ; | ||||
|   BOOST_CHECK ( y == x_c ) ; | ||||
|   BOOST_CHECK ( y == boost::get(x_c) ) ; | ||||
|   BOOST_TEST ( y == x_c ) ; | ||||
|   BOOST_TEST ( y == boost::get(x_c) ) ; | ||||
|   T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ; | ||||
|   x_c_ref = z ; | ||||
|   BOOST_CHECK ( x_c == z ) ; | ||||
|   BOOST_TEST ( x_c == z ) ; | ||||
|  | ||||
|   boost::value_initialized<T> const copy1 = x; | ||||
|   BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ; | ||||
|   BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ; | ||||
|  | ||||
|   boost::value_initialized<T> copy2; | ||||
|   copy2 = x; | ||||
|   BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ; | ||||
|   BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ; | ||||
|    | ||||
|   boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> ); | ||||
|   BOOST_CHECK ( y == *ptr ) ; | ||||
|   BOOST_TEST ( y == *ptr ) ; | ||||
|  | ||||
| #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) | ||||
|   boost::value_initialized<T const> cx ; | ||||
|   BOOST_CHECK ( y == cx ) ; | ||||
|   BOOST_CHECK ( y == boost::get(cx) ) ; | ||||
|   BOOST_TEST ( y == cx ) ; | ||||
|   BOOST_TEST ( y == boost::get(cx) ) ; | ||||
|  | ||||
|   boost::value_initialized<T const> const cx_c ; | ||||
|   BOOST_CHECK ( y == cx_c ) ; | ||||
|   BOOST_CHECK ( y == boost::get(cx_c) ) ; | ||||
|   BOOST_TEST ( y == cx_c ) ; | ||||
|   BOOST_TEST ( y == boost::get(cx_c) ) ; | ||||
| #endif | ||||
|  | ||||
|   return boost::minimal_test::errors_counter() == counter_before_test ; | ||||
|   return boost::detail::test_errors() == errors_before_test ; | ||||
| } | ||||
|  | ||||
| int test_main(int, char **) | ||||
| int main(int, char **) | ||||
| { | ||||
|   BOOST_CHECK ( test( 0,1234 ) ) ; | ||||
|   BOOST_CHECK ( test( 0.0,12.34 ) ) ; | ||||
|   BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ; | ||||
|   BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; | ||||
|   BOOST_TEST ( test( 0,1234 ) ) ; | ||||
|   BOOST_TEST ( test( 0.0,12.34 ) ) ; | ||||
|   BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ; | ||||
|   BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ; | ||||
|  | ||||
|   NonPOD NonPOD_object( std::string("NonPOD_object") ); | ||||
|   BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ; | ||||
|   BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ; | ||||
|  | ||||
|   AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 }; | ||||
|   AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 }; | ||||
|   BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); | ||||
|   BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) ); | ||||
|  | ||||
|   StringAndInt stringAndInt0; | ||||
|   StringAndInt stringAndInt1; | ||||
|   stringAndInt0.i = 0; | ||||
|   stringAndInt1.i = 1; | ||||
|   stringAndInt1.s = std::string("1"); | ||||
|   BOOST_CHECK ( test(stringAndInt0, stringAndInt1) ); | ||||
|   BOOST_TEST ( test(stringAndInt0, stringAndInt1) ); | ||||
|  | ||||
|   StructWithDestructor structWithDestructor0; | ||||
|   StructWithDestructor structWithDestructor1; | ||||
|   structWithDestructor0.i = 0; | ||||
|   structWithDestructor1.i = 1; | ||||
|   BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) ); | ||||
|   BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) ); | ||||
|  | ||||
|   StructWithVirtualFunction structWithVirtualFunction0; | ||||
|   StructWithVirtualFunction structWithVirtualFunction1; | ||||
|   structWithVirtualFunction0.i = 0; | ||||
|   structWithVirtualFunction1.i = 1; | ||||
|   BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); | ||||
|   BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) ); | ||||
|  | ||||
|   DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0; | ||||
|   DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1; | ||||
|   static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct; | ||||
|   static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct; | ||||
|   BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); | ||||
|   BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) ); | ||||
|  | ||||
|   AggregatePODStructWrapper aggregatePODStructWrapper0; | ||||
|   AggregatePODStructWrapper aggregatePODStructWrapper1; | ||||
|   aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct; | ||||
|   aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct; | ||||
|   BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); | ||||
|   BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) ); | ||||
|  | ||||
|   ArrayOfBytes zeroInitializedArrayOfBytes = { 0 }; | ||||
|   boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes; | ||||
|   BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); | ||||
|   BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0); | ||||
|  | ||||
|   boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2; | ||||
|   valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes; | ||||
|   BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); | ||||
|   BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0); | ||||
|  | ||||
|   boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1; | ||||
|   BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed); | ||||
|   BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called); | ||||
|   BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed); | ||||
|   BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called); | ||||
|  | ||||
|   boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1); | ||||
|   BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed); | ||||
|   BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called); | ||||
|   BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed); | ||||
|   BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called); | ||||
|  | ||||
|   boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3; | ||||
|   copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1); | ||||
|   BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed); | ||||
|   BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called); | ||||
|   BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed); | ||||
|   BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called); | ||||
|  | ||||
|   boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1; | ||||
|   boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2; | ||||
|   get(swapFunctionCallTester1).data = 1; | ||||
|   get(swapFunctionCallTester2).data = 2; | ||||
|   boost::swap(swapFunctionCallTester1, swapFunctionCallTester2); | ||||
|   BOOST_CHECK( get(swapFunctionCallTester1).data == 2 ); | ||||
|   BOOST_CHECK( get(swapFunctionCallTester2).data == 1 ); | ||||
|   BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called ); | ||||
|   BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called ); | ||||
|   BOOST_TEST( get(swapFunctionCallTester1).data == 2 ); | ||||
|   BOOST_TEST( get(swapFunctionCallTester2).data == 1 ); | ||||
|   BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called ); | ||||
|   BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called ); | ||||
|  | ||||
|   return 0; | ||||
|   return boost::report_errors(); | ||||
| } | ||||
|  | ||||
|  | ||||
| unsigned int expected_failures = 0; | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										144
									
								
								value_init_workaround_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								value_init_workaround_test.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| // Copyright 2010, Niels Dekker. | ||||
| // | ||||
| // 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) | ||||
| // | ||||
| // Test program for the boost::value_initialized<T> workaround. | ||||
| // | ||||
| // 17 June 2010 (Created) Niels Dekker | ||||
|  | ||||
| // Switch the workaround off, before inluding "value_init.hpp". | ||||
| #define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0 | ||||
| #include <boost/utility/value_init.hpp> | ||||
|  | ||||
| #include <iostream>  // For cout. | ||||
| #include <cstdlib>  // For EXIT_SUCCESS and EXIT_FAILURE. | ||||
|  | ||||
| namespace | ||||
| { | ||||
|   struct empty_struct | ||||
|   { | ||||
|   }; | ||||
|  | ||||
|   // A POD aggregate struct derived from an empty struct. | ||||
|   // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295, | ||||
|   // "VC++ does not value-initialize members of derived classes without  | ||||
|   // user-declared constructor", reported in 2009 by Sylvester Hesp: | ||||
|   // https://connect.microsoft.com/VisualStudio/feedback/details/484295 | ||||
|   struct derived_struct: empty_struct | ||||
|   { | ||||
|     int data; | ||||
|   }; | ||||
|  | ||||
|   bool is_value_initialized(const derived_struct& arg) | ||||
|   { | ||||
|     return arg.data == 0; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   class virtual_destructor_holder | ||||
|   { | ||||
|   public: | ||||
|     int i; | ||||
|     virtual ~virtual_destructor_holder() | ||||
|     { | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   bool is_value_initialized(const virtual_destructor_holder& arg) | ||||
|   { | ||||
|     return arg.i == 0; | ||||
|   } | ||||
|  | ||||
|   // Equivalent to the Stats class from GCC Bug 33916, | ||||
|   // "Default constructor fails to initialize array members", reported in 2007 by | ||||
|   // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 | ||||
|   // and fixed for GCC 4.2.4. | ||||
|   class private_int_array_pair | ||||
|   { | ||||
|     friend bool is_value_initialized(const private_int_array_pair& arg); | ||||
|   private: | ||||
|     int first[12]; | ||||
|     int second[12]; | ||||
|   }; | ||||
|  | ||||
|   bool is_value_initialized(const private_int_array_pair& arg) | ||||
|   { | ||||
|     for ( unsigned i = 0; i < 12; ++i) | ||||
|     { | ||||
|       if ( (arg.first[i] != 0) || (arg.second[i] != 0) ) | ||||
|       { | ||||
|         return false; | ||||
|       } | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool is_value_initialized(const T(& arg)[2]) | ||||
|   { | ||||
|     return | ||||
|       is_value_initialized(arg[0]) && | ||||
|       is_value_initialized(arg[1]); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool is_value_initialized(const boost::value_initialized<T>& arg) | ||||
|   { | ||||
|     return is_value_initialized(arg.data()); | ||||
|   } | ||||
|  | ||||
|   // Returns zero when the specified object is value-initializated, and one otherwise. | ||||
|   // Prints a message to standard output if the value-initialization has failed. | ||||
|   template <class T> | ||||
|   unsigned failed_to_value_initialized(const T& object, const char *const object_name) | ||||
|   { | ||||
|     if ( is_value_initialized(object) ) | ||||
|     { | ||||
|       return 0u; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl; | ||||
|       return 1u; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| // A macro that passed both the name and the value of the specified object to | ||||
| // the function above here. | ||||
| #define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value) | ||||
|  | ||||
|   // Equivalent to the dirty_stack() function from GCC Bug 33916, | ||||
|   // "Default constructor fails to initialize array members", reported in 2007 by | ||||
|   // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 | ||||
|   void dirty_stack() | ||||
|   { | ||||
|     unsigned char array_on_stack[4096]; | ||||
|     for (unsigned i = 0; i < sizeof(array_on_stack); ++i) | ||||
|     { | ||||
|       array_on_stack[i] = 0x11; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() | ||||
| { | ||||
|   dirty_stack(); | ||||
|  | ||||
|   // TODO More types may be added later. | ||||
|   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>()); | ||||
|  | ||||
| #ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED | ||||
|   // One or more failures are expected. | ||||
|   return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE; | ||||
| #else | ||||
|   // No failures are expected. | ||||
|   return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE; | ||||
| #endif | ||||
| } | ||||
		Reference in New Issue
	
	Block a user