Added emplace(void) for older compilers

This commit is contained in:
Andrzej Krzemienski
2015-05-15 16:27:40 +02:00
parent 339202a8fb
commit 8ca74951b0
7 changed files with 65 additions and 33 deletions

View File

@ -621,8 +621,10 @@ __SPACE__
of type `T` with `std::forward<Args>(args)...`.
* [*Postconditions: ] `*this` is [_initialized].
* [*Throws:] Whatever the selected `T`'s constructor throws.
* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`. On compilers that do not support variadic templates, the signature falls back to single-argument: `template<class Arg> void emplace(Arg&& arg)`. On compilers that do not support rvalue references, the signature falls back to two overloads: taking `const` and non-`const` lvalue reference.
* [*Exception Safety:] If an exception is thrown during the initialization of `T`, `*this` is ['uninitialized].
* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`.
On compilers that do not support variadic templates, the signature falls back to two overloads:`template<class Arg> void emplace(Arg&& arg)` and `void emplace()`.
On compilers that do not support rvalue references, the signature falls back to three overloads: taking `const` and non-`const` lvalue reference, and third with empty function argument list.
* [*Example:]
``
T v;

View File

@ -1336,23 +1336,26 @@
<li class="listitem">
<span class="bold"><strong>Throws:</strong></span> Whatever the selected <code class="computeroutput"><span class="identifier">T</span></code>'s constructor throws.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
need not be <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
or <code class="computeroutput"><span class="identifier">MoveAssignable</span></code>.
On compilers that do not support variadic templates, the signature
falls back to single-argument: <code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span>
<span class="identifier">Arg</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">emplace</span><span class="special">(</span><span class="identifier">Arg</span><span class="special">&amp;&amp;</span> <span class="identifier">arg</span><span class="special">)</span></code>. On compilers that do not support
rvalue references, the signature falls back to two overloads: taking
<code class="computeroutput"><span class="keyword">const</span></code> and non-<code class="computeroutput"><span class="keyword">const</span></code> lvalue reference.
</li>
<li class="listitem">
<span class="bold"><strong>Exception Safety:</strong></span> If an exception
is thrown during the initialization of <code class="computeroutput"><span class="identifier">T</span></code>,
<code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
is <span class="emphasis"><em>uninitialized</em></span>.
</li>
<li class="listitem">
<span class="bold"><strong>Notes:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
need not be <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
or <code class="computeroutput"><span class="identifier">MoveAssignable</span></code>.
On compilers that do not support variadic templates, the signature
falls back to two overloads:<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span>
<span class="identifier">Arg</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">emplace</span><span class="special">(</span><span class="identifier">Arg</span><span class="special">&amp;&amp;</span> <span class="identifier">arg</span><span class="special">)</span></code> and <code class="computeroutput"><span class="keyword">void</span>
<span class="identifier">emplace</span><span class="special">()</span></code>.
On compilers that do not support rvalue references, the signature falls
back to three overloads: taking <code class="computeroutput"><span class="keyword">const</span></code>
and non-<code class="computeroutput"><span class="keyword">const</span></code> lvalue reference,
and third with empty function argument list.
</li>
<li class="listitem">
<span class="bold"><strong>Example:</strong></span>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span><span class="special">;</span>

View File

@ -146,7 +146,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: March 13, 2015 at 21:52:15 GMT</small></p></td>
<td align="left"><p><small>Last revised: May 15, 2015 at 14:16:05 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>

View File

@ -18,12 +18,14 @@
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
#include <new>
#include <algorithm>
#include <iosfwd>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/core/addressof.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/core/explicit_operator_bool.hpp>
#include <boost/core/swap.hpp>
#include <boost/optional/bad_optional_access.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
@ -47,13 +49,7 @@
#include <boost/detail/reference_content.hpp>
#include <boost/move/utility.hpp>
#include <boost/none.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/utility/compare_pointees.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/in_place_factory.hpp>
#include <boost/utility/swap.hpp>
#include <boost/optional/optional_fwd.hpp>
@ -506,6 +502,13 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
m_initialized = true ;
}
void emplace_assign ()
{
destroy();
::new (m_storage.address()) internal_type();
m_initialized = true ;
}
#else
template<class Arg>
void emplace_assign ( const Arg& arg )
@ -515,13 +518,20 @@ class optional_base : public optional_tag
m_initialized = true ;
}
template<class Arg>
template<class Arg>
void emplace_assign ( Arg& arg )
{
destroy();
::new (m_storage.address()) internal_type( arg );
m_initialized = true ;
}
void emplace_assign ()
{
destroy();
::new (m_storage.address()) internal_type();
m_initialized = true ;
}
#endif
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
@ -976,6 +986,11 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( boost::forward<Arg>(arg) );
}
void emplace ()
{
this->emplace_assign();
}
#else
template<class Arg>
void emplace ( const Arg& arg )
@ -988,6 +1003,11 @@ class optional : public optional_detail::optional_base<T>
{
this->emplace_assign( arg );
}
void emplace ()
{
this->emplace_assign();
}
#endif
void swap( optional & arg )
@ -1448,9 +1468,9 @@ struct swap_selector<true>
return;
if( !hasX )
x = boost::in_place();
x.emplace();
else if ( !hasY )
y = boost::in_place();
y.emplace();
// Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
boost::swap(x.get(),y.get());

View File

@ -1,15 +1,16 @@
# Boost.Optional Library test Jamfile
# Boost.Optional Library test Jamfile
#
# Copyright (C) 2003, Fernando Luis Cacciola Carballal.
# Copyright (C) 2003, Fernando Luis Cacciola Carballal.
# Copyright (C) 2014, 2015 Andrzej Krzemienski
#
# This material is provided "as is", with absolutely no warranty expressed
# or implied. Any use is at your own risk.
# Use, modification, and distribution is subject to the Boost Software
# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
# Permission to use or copy this software for any purpose is hereby granted
# without fee, provided the above notices are retained on all copies.
# Permission to modify the code and to distribute modified code is granted,
# provided the above notices are retained, and a notice that the code was
# modified is included with the above copyright notice.
# See http://www.boost.org/libs/optional for documentation.
#
# You are welcome to contact the author at:
# akrzemi1@gmail.com
#
import testing ;

View File

@ -145,11 +145,16 @@ void test_clear_on_throw()
void test_no_assignment_on_emplacement()
{
optional<const std::string> os;
optional<const std::string> os, ot;
BOOST_TEST(!os);
os.emplace("wow");
BOOST_TEST(os);
BOOST_TEST_EQ(*os, "wow");
BOOST_TEST(!ot);
ot.emplace();
BOOST_TEST(ot);
BOOST_TEST_EQ(*ot, "");
}
int main()

View File

@ -15,6 +15,7 @@
//
#include "boost/optional/optional.hpp"
#include "boost/utility/in_place_factory.hpp"
#ifdef __BORLANDC__
#pragma hdrstop