mirror of
https://github.com/boostorg/utility.git
synced 2025-10-05 21:40:59 +02:00
Compare commits
112 Commits
svn-branch
...
boost-1.46
Author | SHA1 | Date | |
---|---|---|---|
|
3a1ac407c0 | ||
|
8176af84e1 | ||
|
71e78a0081 | ||
|
f7e4b0e399 | ||
|
b7d4b6edae | ||
|
fb1d2effef | ||
|
94b91e8c92 | ||
|
d7cf3628f7 | ||
|
a4b8043e68 | ||
|
b273cd3914 | ||
|
ca7db1f361 | ||
|
b4a08fc80e | ||
|
9da96d9737 | ||
|
a991936c96 | ||
|
6239e685a2 | ||
|
2a7e81e07f | ||
|
e601fcb9c9 | ||
|
f29a5db08e | ||
|
22743ee125 | ||
|
e3c982287a | ||
|
13da21e7b1 | ||
|
82e1111bb8 | ||
|
b3ffef536d | ||
|
9339b32178 | ||
|
3770221507 | ||
|
e2c98762db | ||
|
e6cb3a77ee | ||
|
bbccfbbab4 | ||
|
8af4250c3c | ||
|
e30889304c | ||
|
b4dee80e61 | ||
|
74a6a693d3 | ||
|
bf713ad47a | ||
|
76b17c497b | ||
|
a47dce770c | ||
|
dab1e8e522 | ||
|
3de5974419 | ||
|
7eb1536590 | ||
|
583422cda2 | ||
|
9339431e03 | ||
|
ee146a02a1 | ||
|
c131cbd0b2 | ||
|
f2349baf7d | ||
|
f8bef7ba95 | ||
|
e54cbf3053 | ||
|
8745ca628a | ||
|
ba61e9d796 | ||
|
d5291d08b8 | ||
|
afe74fffbc | ||
|
61755605af | ||
|
cd12e322bd | ||
|
09a0137016 | ||
|
a1d3ec6c53 | ||
|
5be3004e6c | ||
|
d387905150 | ||
|
b514e40733 | ||
|
8cb975feb7 | ||
|
ffe151458e | ||
|
4003a9f74a | ||
|
211eb04f33 | ||
|
e57213b298 | ||
|
51f9adbfa1 | ||
|
eaaf17a88f | ||
|
48cfd42123 | ||
|
76aa5d2f27 | ||
|
ce67dde4f0 | ||
|
a69e872a91 | ||
|
e3640e45c2 | ||
|
b7cd171b2b | ||
|
b2e6a82adb | ||
|
390372294a | ||
|
ffbbf38e12 | ||
|
9e73b2c6ae | ||
|
633832e872 | ||
|
862cb2a4e0 | ||
|
b012f16ee5 | ||
|
3d96ab26d4 | ||
|
8652bf51ec | ||
|
9168cb9c61 | ||
|
e1991374ae | ||
|
d0ee9a7c28 | ||
|
10e83b490b | ||
|
4b24dba257 | ||
|
7a036f6f3a | ||
|
e632b0fb1f | ||
|
17bee9d43f | ||
|
492a8ad213 | ||
|
8827b8ed8b | ||
|
8849fbc52d | ||
|
50bc75a802 | ||
|
9b52e49fda | ||
|
ab479794f3 | ||
|
97b8966337 | ||
|
88099a882f | ||
|
d5554eb6d7 | ||
|
13bdfb8bbd | ||
|
74462349c2 | ||
|
6aa648d315 | ||
|
9ff18c2c96 | ||
|
d5ea07c737 | ||
|
aa0096bf42 | ||
|
005c2f3cc8 | ||
|
09f7aab52d | ||
|
30a40f9f76 | ||
|
d9f8bae673 | ||
|
3c7b409460 | ||
|
ee3551e8dc | ||
|
95da2e90de | ||
|
6dd93ab916 | ||
|
505d419a1b | ||
|
d968b5f5b9 | ||
|
d809d4e832 |
@@ -1,31 +0,0 @@
|
|||||||
#----------------------------------------------------------------------------
|
|
||||||
# This file was automatically generated from the original CMakeLists.txt file
|
|
||||||
# Add a variable to hold the headers for the library
|
|
||||||
set (lib_headers
|
|
||||||
assert.hpp
|
|
||||||
call_traits.hpp
|
|
||||||
checked_delete.hpp
|
|
||||||
compressed_pair.hpp
|
|
||||||
current_function.hpp
|
|
||||||
operators.hpp
|
|
||||||
throw_exception.hpp
|
|
||||||
utility.hpp
|
|
||||||
utility
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add a library target to the build system
|
|
||||||
boost_library_project(
|
|
||||||
utility
|
|
||||||
# SRCDIRS
|
|
||||||
TESTDIRS test
|
|
||||||
HEADERS ${lib_headers}
|
|
||||||
# DOCDIRS
|
|
||||||
DESCRIPTION "Various small utilities for C++ programming."
|
|
||||||
MODULARIZED
|
|
||||||
AUTHORS "David Abrahams <dave -at- boostpro.com>"
|
|
||||||
"Brad King"
|
|
||||||
"Douglas Gregor <doug.gregor -at- gmail.com>"
|
|
||||||
# MAINTAINERS
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
@@ -281,7 +281,7 @@ object_id_compare::operator ()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return a.second->before( *b.second );
|
return a.second->before( *b.second ) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,10 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Note: This file tests every single valid bit-grouping on its own, and some
|
Note: This file tests every single valid bit-grouping on its own, and some
|
||||||
random combinations of bit-groupings.
|
random combinations of bit-groupings.
|
||||||
|
@@ -21,6 +21,10 @@
|
|||||||
#include <libs/type_traits/test/test.hpp>
|
#include <libs/type_traits/test/test.hpp>
|
||||||
#include <libs/type_traits/test/check_type.hpp>
|
#include <libs/type_traits/test/check_type.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
|
||||||
|
#endif
|
||||||
|
|
||||||
// a way prevent warnings for unused variables
|
// a way prevent warnings for unused variables
|
||||||
template<class T> inline void unused_variable(const T&) {}
|
template<class T> inline void unused_variable(const T&) {}
|
||||||
|
|
||||||
@@ -52,7 +56,8 @@ struct contained
|
|||||||
const_reference const_get()const { return v_; }
|
const_reference const_get()const { return v_; }
|
||||||
// pass value:
|
// pass value:
|
||||||
void call(param_type){}
|
void call(param_type){}
|
||||||
|
private:
|
||||||
|
contained& operator=(const contained&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
@@ -77,6 +82,8 @@ struct contained<T[N]>
|
|||||||
reference get() { return v_; }
|
reference get() { return v_; }
|
||||||
const_reference const_get()const { return v_; }
|
const_reference const_get()const { return v_; }
|
||||||
void call(param_type){}
|
void call(param_type){}
|
||||||
|
private:
|
||||||
|
contained& operator=(const contained&);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -197,7 +204,7 @@ struct comparible_UDT
|
|||||||
bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
|
bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[ ])
|
int main()
|
||||||
{
|
{
|
||||||
call_traits_checker<comparible_UDT> c1;
|
call_traits_checker<comparible_UDT> c1;
|
||||||
comparible_UDT u;
|
comparible_UDT u;
|
||||||
|
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>
|
@@ -6,14 +6,6 @@
|
|||||||
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
|
#ifndef UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||||
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
|
#define UUID_1D94A7C6054E11DB9804B622A1EF5492
|
||||||
|
|
||||||
#include <boost/exception/diagnostic_information.hpp>
|
#error The header <boost/exception.hpp> has been deprecated. Please #include <boost/exception/all.hpp> instead.
|
||||||
#include <boost/exception/error_info.hpp>
|
|
||||||
#include <boost/exception/exception.hpp>
|
|
||||||
#include <boost/exception/get_error_info.hpp>
|
|
||||||
#include <boost/exception/info.hpp>
|
|
||||||
#include <boost/exception/info_tuple.hpp>
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||||
#include <boost/exception_ptr.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// 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:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// 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
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// 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:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// 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:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -10,7 +10,30 @@
|
|||||||
# error Boost result_of - do not include this file!
|
# error Boost result_of - do not include this file!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(BOOST_HAS_DECLTYPE)
|
// CWPro8 requires an argument in a function type specialization
|
||||||
|
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
||||||
|
# define BOOST_RESULT_OF_ARGS void
|
||||||
|
#else
|
||||||
|
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 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
|
// As of N2588, C++0x result_of only supports function call
|
||||||
// expressions of the form f(x). This precludes support for member
|
// expressions of the form f(x). This precludes support for member
|
||||||
@@ -21,11 +44,11 @@ template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
|||||||
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
struct result_of<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
: mpl::if_<
|
: mpl::if_<
|
||||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
||||||
, detail::result_of_impl<
|
, detail::tr1_result_of_impl<
|
||||||
typename remove_cv<F>::type,
|
typename remove_cv<F>::type,
|
||||||
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
typename remove_cv<F>::type(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)), false
|
||||||
>
|
>
|
||||||
, detail::result_of_decltype_impl<
|
, detail::cpp0x_result_of_impl<
|
||||||
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
>
|
>
|
||||||
>::type
|
>::type
|
||||||
@@ -39,7 +62,7 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
class result_of_decltype_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
class cpp0x_result_of_impl<F(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T))>
|
||||||
{
|
{
|
||||||
static F f;
|
static F f;
|
||||||
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
|
BOOST_PP_REPEAT(BOOST_PP_ITERATION(), BOOST_RESULT_OF_STATIC_MEMBERS, _)
|
||||||
@@ -49,34 +72,18 @@ public:
|
|||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
#else // defined(BOOST_HAS_DECLTYPE)
|
#else // defined(BOOST_NO_DECLTYPE)
|
||||||
|
|
||||||
// CWPro8 requires an argument in a function type specialization
|
|
||||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
|
||||||
# define BOOST_RESULT_OF_ARGS void
|
|
||||||
#else
|
|
||||||
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||||
: mpl::if_<
|
: tr1_result_of<F(BOOST_RESULT_OF_ARGS)> { };
|
||||||
mpl::or_< is_pointer<F>, is_member_function_pointer<F> >
|
|
||||||
, boost::detail::result_of_impl<
|
|
||||||
typename remove_cv<F>::type,
|
|
||||||
typename remove_cv<F>::type(BOOST_RESULT_OF_ARGS),
|
|
||||||
(boost::detail::has_result_type<F>::value)>
|
|
||||||
, boost::detail::result_of_impl<
|
|
||||||
F,
|
|
||||||
F(BOOST_RESULT_OF_ARGS),
|
|
||||||
(boost::detail::has_result_type<F>::value)> >::type { };
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef BOOST_RESULT_OF_ARGS
|
#endif // defined(BOOST_NO_DECLTYPE)
|
||||||
|
|
||||||
#endif // defined(BOOST_HAS_DECLTYPE)
|
#undef BOOST_RESULT_OF_ARGS
|
||||||
|
|
||||||
#if BOOST_PP_ITERATION() >= 1
|
#if BOOST_PP_ITERATION() >= 1
|
||||||
|
|
||||||
@@ -84,14 +91,14 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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;
|
typedef R type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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;
|
typedef R type;
|
||||||
};
|
};
|
||||||
@@ -99,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))
|
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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)),
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||||
FArgs, false>
|
FArgs, false>
|
||||||
{
|
{
|
||||||
@@ -108,7 +115,7 @@ struct result_of_impl<R (T0::*)
|
|||||||
|
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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))
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
const,
|
const,
|
||||||
FArgs, false>
|
FArgs, false>
|
||||||
@@ -118,7 +125,7 @@ struct result_of_impl<R (T0::*)
|
|||||||
|
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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))
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
volatile,
|
volatile,
|
||||||
FArgs, false>
|
FArgs, false>
|
||||||
@@ -128,7 +135,7 @@ struct result_of_impl<R (T0::*)
|
|||||||
|
|
||||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
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))
|
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||||
const volatile,
|
const volatile,
|
||||||
FArgs, false>
|
FArgs, false>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// 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:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -30,14 +30,15 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
|
|
||||||
template<typename F> struct result_of;
|
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)
|
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
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 result_of_decltype_impl;
|
template<typename F> struct cpp0x_result_of_impl;
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
struct result_of_void_impl
|
struct result_of_void_impl
|
||||||
@@ -60,10 +61,10 @@ struct result_of_void_impl<R (&)(void)>
|
|||||||
// Determine the return type of a function pointer or pointer to member.
|
// Determine the return type of a function pointer or pointer to member.
|
||||||
template<typename F, typename FArgs>
|
template<typename F, typename FArgs>
|
||||||
struct result_of_pointer
|
struct result_of_pointer
|
||||||
: result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
: tr1_result_of_impl<typename remove_cv<F>::type, FArgs, false> { };
|
||||||
|
|
||||||
template<typename F, typename FArgs>
|
template<typename F, typename FArgs>
|
||||||
struct result_of_impl<F, FArgs, true>
|
struct tr1_result_of_impl<F, FArgs, true>
|
||||||
{
|
{
|
||||||
typedef typename F::result_type type;
|
typedef typename F::result_type type;
|
||||||
};
|
};
|
||||||
@@ -79,7 +80,7 @@ struct result_of_nested_result : F::template result<FArgs>
|
|||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename F, typename 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>,
|
: mpl::if_<is_function_with_no_args<FArgs>,
|
||||||
result_of_void_impl<F>,
|
result_of_void_impl<F>,
|
||||||
result_of_nested_result<F, FArgs> >::type
|
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
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
// 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:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
|
@@ -9,6 +9,8 @@
|
|||||||
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
// 23 May 2008 (Fixed operator= const issue, added initialized_value) Niels Dekker, Fernando Cacciola
|
||||||
// 21 Ago 2008 (Added swap) 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
|
// 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
|
#ifndef BOOST_UTILITY_VALUE_INIT_21AGO2002_HPP
|
||||||
#define 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
|
// contains. More details on these issues are at libs/utility/value_init.htm
|
||||||
|
|
||||||
#include <boost/aligned_storage.hpp>
|
#include <boost/aligned_storage.hpp>
|
||||||
|
#include <boost/config.hpp> // For BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
#include <boost/type_traits/cv_traits.hpp>
|
#include <boost/type_traits/cv_traits.hpp>
|
||||||
@@ -28,10 +31,39 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <new>
|
#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 {
|
namespace boost {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class value_initialized
|
class initialized
|
||||||
{
|
{
|
||||||
private :
|
private :
|
||||||
struct wrapper
|
struct wrapper
|
||||||
@@ -40,6 +72,18 @@ class value_initialized
|
|||||||
typename
|
typename
|
||||||
#endif
|
#endif
|
||||||
remove_const<T>::type data;
|
remove_const<T>::type data;
|
||||||
|
|
||||||
|
wrapper()
|
||||||
|
:
|
||||||
|
data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapper(T const & arg)
|
||||||
|
:
|
||||||
|
data(arg)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable
|
mutable
|
||||||
@@ -55,30 +99,25 @@ class value_initialized
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
|
|
||||||
value_initialized()
|
initialized()
|
||||||
{
|
{
|
||||||
|
#if BOOST_DETAIL_VALUE_INIT_WORKAROUND
|
||||||
std::memset(&x, 0, sizeof(x));
|
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
|
#endif
|
||||||
new (wrapper_address()) wrapper();
|
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())));
|
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.
|
// Assignment is only allowed when T is non-const.
|
||||||
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
BOOST_STATIC_ASSERT( ! is_const<T>::value );
|
||||||
@@ -86,7 +125,7 @@ class value_initialized
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~value_initialized()
|
~initialized()
|
||||||
{
|
{
|
||||||
wrapper_address()->wrapper::~wrapper();
|
wrapper_address()->wrapper::~wrapper();
|
||||||
}
|
}
|
||||||
@@ -101,17 +140,81 @@ class value_initialized
|
|||||||
return wrapper_address()->data;
|
return wrapper_address()->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(value_initialized & arg)
|
void swap(initialized & arg)
|
||||||
{
|
{
|
||||||
::boost::swap( this->data(), arg.data() );
|
::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>
|
template<class T>
|
||||||
@@ -119,6 +222,7 @@ T const& get ( value_initialized<T> const& x )
|
|||||||
{
|
{
|
||||||
return x.data() ;
|
return x.data() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T& get ( value_initialized<T>& x )
|
T& get ( value_initialized<T>& x )
|
||||||
{
|
{
|
||||||
@@ -138,7 +242,7 @@ class initialized_value_t
|
|||||||
|
|
||||||
template <class T> operator T() const
|
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
|
} // namespace boost
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
<a href="checked_delete.html">checked_delete</a><br>
|
<a href="checked_delete.html">checked_delete</a><br>
|
||||||
<a href="compressed_pair.htm">compressed_pair</a><br>
|
<a href="compressed_pair.htm">compressed_pair</a><br>
|
||||||
<a href="current_function.html">current_function</a><br>
|
<a href="current_function.html">current_function</a><br>
|
||||||
|
<a href="doc/html/declval.html">declval</a><br>
|
||||||
<a href="enable_if.html">enable_if</a><br>
|
<a href="enable_if.html">enable_if</a><br>
|
||||||
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
<a href="iterator_adaptors.htm">iterator_adaptors</a><br>
|
||||||
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
<a href="generator_iterator.htm">generator iterator adaptors</a><br>
|
||||||
@@ -40,3 +41,4 @@
|
|||||||
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
@@ -1 +0,0 @@
|
|||||||
boost_module(utility DEPENDS iterator exception detail )
|
|
@@ -70,7 +70,7 @@ struct ref_wrapper
|
|||||||
|
|
||||||
struct copy_counter {
|
struct copy_counter {
|
||||||
static int count_;
|
static int count_;
|
||||||
copy_counter(copy_counter const& other) {
|
copy_counter(copy_counter const& /*other*/) {
|
||||||
++count_;
|
++count_;
|
||||||
}
|
}
|
||||||
copy_counter() {}
|
copy_counter() {}
|
||||||
|
@@ -7,7 +7,11 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Page header -->
|
<!-- Page header -->
|
||||||
|
<h2>
|
||||||
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/>
|
<img src="../../boost.png" alt="C++ Boost" align="middle" width="277" height="86"/>
|
||||||
|
Header <<a href="../../boost/swap.hpp">boost/swap.hpp</a>>
|
||||||
|
</h2>
|
||||||
|
|
||||||
<h1>Swap</h1>
|
<h1>Swap</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -84,9 +88,9 @@
|
|||||||
|
|
||||||
<!-- Copyright info -->
|
<!-- Copyright info -->
|
||||||
<hr/>
|
<hr/>
|
||||||
<p>Revised: 15 November 2008</p>
|
<p>Revised: 08 September 2009</p>
|
||||||
<p>
|
<p>
|
||||||
Copyright 2007, 2008 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0.
|
Copyright 2007 - 2009 Joseph Gauterin. Use, modification, and distribution are subject to the Boost Software License, Version 1.0.
|
||||||
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)
|
(See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at <<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2008 Joseph Gauterin, Niels Dekker
|
// Copyright (c) 2008 - 2010 Joseph Gauterin, Niels Dekker
|
||||||
//
|
//
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
int test_main(int, char*[])
|
int test_main(int, char*[])
|
||||||
{
|
{
|
||||||
typedef std::bitset<8> bitset_type;
|
typedef std::bitset<8> bitset_type;
|
||||||
const bitset_type initial_value1 = 1ul;
|
const bitset_type initial_value1 = 1;
|
||||||
const bitset_type initial_value2 = 2ul;
|
const bitset_type initial_value2 = 2;
|
||||||
|
|
||||||
bitset_type object1 = initial_value1;
|
bitset_type object1 = initial_value1;
|
||||||
bitset_type object2 = initial_value2;
|
bitset_type object2 = initial_value2;
|
||||||
|
@@ -1,38 +0,0 @@
|
|||||||
boost_additional_test_dependencies(utility BOOST_DEPENDS test)
|
|
||||||
|
|
||||||
boost_test_run(addressof_test ../addressof_test.cpp)
|
|
||||||
boost_test_run(assert_test ../assert_test.cpp)
|
|
||||||
boost_test_run(base_from_member_test ../base_from_member_test.cpp)
|
|
||||||
boost_test_run(binary_search_test ../binary_search_test.cpp)
|
|
||||||
boost_test_run(call_traits_test ../call_traits_test.cpp ARGS -u)
|
|
||||||
boost_test_compile_fail(checked_delete_test ../checked_delete_test.cpp)
|
|
||||||
boost_test_run(compressed_pair_test
|
|
||||||
../compressed_pair_test
|
|
||||||
DEPENDS boost_test_exec_monitor)
|
|
||||||
boost_test_run(current_function_test ../current_function_test.cpp)
|
|
||||||
boost_test_run(iterators_test
|
|
||||||
../iterators_test.cpp
|
|
||||||
DEPENDS boost_test_exec_monitor)
|
|
||||||
boost_test_run(next_prior_test DEPENDS boost_test_exec_monitor)
|
|
||||||
boost_test_compile_fail(noncopyable_test ../noncopyable_test.cpp)
|
|
||||||
boost_test_run(numeric_traits_test ../numeric_traits_test.cpp)
|
|
||||||
if (${CMAKE_SYSTEM} MATCHES "FreeBSD-.*")
|
|
||||||
boost_test_compile_fail("operators_test_compilerbug")
|
|
||||||
elseif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*")
|
|
||||||
boost_test_run(operators_test
|
|
||||||
../operators_test.cpp
|
|
||||||
DEPENDS boost_test_exec_monitor)
|
|
||||||
endif(${CMAKE_SYSTEM} MATCHES "FreeBSD-.*")
|
|
||||||
boost_test_compile(ref_ct_test ../ref_ct_test.cpp)
|
|
||||||
boost_test_run(ref_test
|
|
||||||
../ref_test.cpp
|
|
||||||
DEPENDS boost_test_exec_monitor)
|
|
||||||
boost_test_compile(result_of_test)
|
|
||||||
boost_test_run(shared_iterator_test ../shared_iterator_test.cpp)
|
|
||||||
boost_test_run(value_init_test ../value_init_test.cpp)
|
|
||||||
boost_test_compile_fail(value_init_test_fail1
|
|
||||||
../value_init_test_fail1.cpp)
|
|
||||||
boost_test_compile_fail(value_init_test_fail2
|
|
||||||
../value_init_test_fail2.cpp)
|
|
||||||
boost_test_compile_fail(value_init_test_fail3
|
|
||||||
../value_init_test_fail3.cpp)
|
|
@@ -32,9 +32,13 @@ test-suite utility
|
|||||||
[ compile result_of_test.cpp ]
|
[ compile result_of_test.cpp ]
|
||||||
[ run ../shared_iterator_test.cpp ]
|
[ run ../shared_iterator_test.cpp ]
|
||||||
[ run ../value_init_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_fail1.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail1.cpp ]
|
||||||
|
[ compile-fail ../initialized_test_fail2.cpp ]
|
||||||
[ run ../verify_test.cpp ]
|
[ run ../verify_test.cpp ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
0
test/next_prior_test.cpp
Executable file → Normal file
0
test/next_prior_test.cpp
Executable file → Normal file
@@ -5,6 +5,8 @@
|
|||||||
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#define BOOST_RESULT_OF_USE_DECLTYPE
|
||||||
|
|
||||||
// For more information, see http://www.boost.org/libs/utility
|
// For more information, see http://www.boost.org/libs/utility
|
||||||
#include <boost/utility/result_of.hpp>
|
#include <boost/utility/result_of.hpp>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -131,9 +133,21 @@ int main()
|
|||||||
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>(double)>::type, int>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::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
|
// Prior to decltype, result_of could not deduce the return type
|
||||||
// nullary function objects unless they exposed a result_type.
|
// nullary function objects unless they exposed a result_type.
|
||||||
#if defined(BOOST_HAS_DECLTYPE)
|
#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<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<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<int_result_of_template<void>(void)>::type, int>::value));
|
||||||
@@ -145,11 +159,14 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT((is_same<result_of<volatile 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));
|
||||||
#endif
|
#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
|
// Prior to decltype, result_of ignored a nested result<> if
|
||||||
// result_type was defined. After decltype, result_of deduces the
|
// result_type was defined. After decltype, result_of deduces the
|
||||||
// actual return type of the function object, ignoring both
|
// actual return type of the function object, ignoring both
|
||||||
// result<> and result_type.
|
// result<> and result_type.
|
||||||
#if defined(BOOST_HAS_DECLTYPE)
|
#if !defined(BOOST_NO_DECLTYPE)
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(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));
|
BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
|
||||||
#else
|
#else
|
||||||
@@ -168,6 +185,17 @@ int main()
|
|||||||
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(void)>::type, int>::value));
|
BOOST_STATIC_ASSERT((is_same<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<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<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<volatile result_of_member_function_template(double)>::type, volatile double>::value));
|
||||||
@@ -177,11 +205,23 @@ int main()
|
|||||||
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 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<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);
|
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(int)>::type, int>::value));
|
||||||
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
|
BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
|
||||||
|
|
||||||
#if defined(BOOST_HAS_DECLTYPE)
|
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(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<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<const no_result_type_or_result_of(double)>::type, short>::value));
|
||||||
|
98
utility.htm
98
utility.htm
@@ -151,37 +151,95 @@ void f() {
|
|||||||
<code>result_of<F(T1, T2, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)>::type</code> defines the result type
|
T<em>N</em>)>::type</code> defines the result type
|
||||||
of the expression <code>f(t1, t2,
|
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,
|
the type <code>F</code> to be a function pointer,
|
||||||
function reference, member function pointer, or class
|
function reference, member function pointer, or class
|
||||||
type.</p> <p>If your compiler does not support
|
type. By default, <em>N</em> may be any value between 0 and
|
||||||
<code>decltype</code>, then when <code>F</code> is a
|
10. To change the upper limit, define the macro
|
||||||
class type with a member type <code>result_type</code>,
|
<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, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)></code> is
|
T<em>N</em>)></code> is
|
||||||
<code>F::result_type</code>. When <code>F</code>
|
<code>F::result_type</code>. When <code>F</code> does
|
||||||
does not contain <code>result_type</code>,
|
not contain <code>result_type</code>,
|
||||||
<code>result_of<F(T1, T2, ...,
|
<code>result_of<F(T1, T2, ...,
|
||||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||||
T2, ..., T<em>N</em>)>::type</code> when
|
T2, ..., T<em>N</em>)>::type</code> when
|
||||||
<code><em>N</em> > 0</code> or <code>void</code>
|
<code><em>N</em> > 0</code> or <code>void</code>
|
||||||
when <code><em>N</em> = 0</code>. For additional
|
when <code><em>N</em> = 0</code>. Note that it is the
|
||||||
information about <code>result_of</code>, see the
|
responsibility of the programmer to ensure that
|
||||||
C++ Library Technical Report, <a
|
function objects accurately advertise their result
|
||||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
|
type via this protocol, as in the following
|
||||||
or, for motivation and design rationale, the <code>result_of</code> <a
|
example.</p>
|
||||||
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
|
||||||
|
|
||||||
<p>Class template <code>result_of</code> resides in
|
<blockquote>
|
||||||
the header <code><<a
|
<pre>struct functor {
|
||||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
|
template<class> struct result;
|
||||||
default, <em>N</em> may be any value between 0 and
|
|
||||||
10. To change the upper limit, define the macro
|
template<class F, class T>
|
||||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
struct result<F(T)> {
|
||||||
value for <em>N</em>.</p>
|
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>
|
<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>
|
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||||
|
144
value_init.htm
144
value_init.htm
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#val_init"><code>template class value_initialized<T></code></a></li>
|
<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>
|
<li><a href="#initialized_value"><code>initialized_value</code></a></li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
@@ -123,6 +124,12 @@ constructed by the following declaration:
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
<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>
|
The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
|
||||||
allows value-initializing a variable as follows:
|
allows value-initializing a variable as follows:
|
||||||
<pre>
|
<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
|
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,
|
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.
|
and the type of object you would like to have value-initialized.
|
||||||
Compilers usually support value-initialization for built-in types properly.
|
All compilers we have tested so far support value-initialization for arithmetic types properly.
|
||||||
But objects of user-defined types that involve <em>aggregates</em> may <em>in some cases</em>
|
However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
|
||||||
be partially, or even entirely left uninitialized, when they should be value-initialized.
|
should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
|
||||||
|
go wrong on various compilers.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
We have encountered issues regarding value-initialization on compilers by
|
At the moment of writing, May 2010, the following reported issues regarding
|
||||||
Microsoft, Sun, Borland, and GNU. Here is a list of bug reports on those issues:
|
value-initialization are still there in current compiler releases:
|
||||||
<table summary="Compiler bug reports regarding value-initialization" border="0" cellpadding="7" cellspacing="1" >
|
<ul>
|
||||||
<tr><td>
|
<li>
|
||||||
<a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744">
|
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
|
||||||
Microsoft Feedback ID 100744 - Value-initialization in new-expression</a>
|
Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
|
||||||
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005-07-28
|
<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">
|
<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
|
||||||
GCC Bug 30111 - Value-initialization of POD base class doesn't initialize members</a>
|
Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
|
||||||
<br>Reported by Jonathan Wakely, 2006-12-07
|
<br>Reported by Sylvester Hesp, 2009
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916">
|
<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
|
||||||
GCC Bug 33916 - Default constructor fails to initialize array members</a>
|
Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
|
||||||
<br>Reported by Michael Elizabeth Chastain, 2007-10-26
|
<br>Reported by Alex Vakulenko, 2009
|
||||||
<br>
|
</li><li>
|
||||||
<a href="http://qc.codegear.com/wc/qcmain.aspx?d=51854">
|
<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
|
||||||
Borland Report 51854 - Value-initialization: POD struct should be zero-initialized</a>
|
Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
|
||||||
<br>Reported by Niels Dekker (LKEB, Leiden University Medical Center), 2007-09-11
|
<br>Reported by Niels Dekker (LKEB), 2010
|
||||||
<br>
|
</li><li>
|
||||||
</td></tr></table>
|
<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>
|
</p><p>
|
||||||
|
|
||||||
New versions of <code>value_initialized</code>
|
New versions of <code>value_initialized</code>
|
||||||
(Boost release version 1.35 or higher)
|
(Boost release version 1.35 or higher)
|
||||||
offer a workaround to these issues: <code>value_initialized</code> will now clear
|
offer a workaround to these issues: <code>value_initialized</code> may now clear
|
||||||
its internal data, prior to constructing the object that it contains.
|
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>
|
</p>
|
||||||
|
|
||||||
<h2><a name="types"></a>Types and objects</h2>
|
<h2><a name="types"></a>Types and objects</h2>
|
||||||
@@ -313,7 +348,7 @@ non-member function <code>get()</code>: </p>
|
|||||||
|
|
||||||
<h3>Warning:</h3>
|
<h3>Warning:</h3>
|
||||||
|
|
||||||
<p>The <code>value_initialized</code> implementation of Boost version 1.38.0 and older
|
<p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
|
||||||
allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
|
allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
|
||||||
both by its conversion operator and its <code>data()</code> member function. For example:</p>
|
both by its conversion operator and its <code>data()</code> member function. For example:</p>
|
||||||
|
|
||||||
@@ -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>
|
<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>
|
<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
|
||||||
|
|
||||||
<pre>
|
<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
|
<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.
|
for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
|
||||||
</p>
|
</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>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
|
||||||
</p>
|
</p>
|
||||||
<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
|
<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>
|
</p>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
<p>Revised 20 February 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
|
<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>
|
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
|
||||||
@@ -418,4 +502,4 @@ for Boost release version 1.35 (2008), offering a workaround to various compiler
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -29,9 +29,9 @@
|
|||||||
//
|
//
|
||||||
struct POD
|
struct POD
|
||||||
{
|
{
|
||||||
POD () : c(0), i(0), f(0) {}
|
POD () : f(0), c(0), i(0){}
|
||||||
|
|
||||||
POD ( char c_, int i_, float f_ ) : c(c_), i(i_), f(f_) {}
|
POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {}
|
||||||
|
|
||||||
friend std::ostream& operator << ( std::ostream& os, POD const& pod )
|
friend std::ostream& operator << ( std::ostream& os, POD const& pod )
|
||||||
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
|
{ return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
|
||||||
@@ -291,7 +291,7 @@ int test_main(int, char **)
|
|||||||
{
|
{
|
||||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
BOOST_CHECK ( test( 0,1234 ) ) ;
|
||||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
||||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78) ) ) ;
|
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||||
|
|
||||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||||
|
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