none_t is no loner constructible from literal 0

This caused problems because:
optional<T> o = 0;
always worked. But often it would create an uninitialized optional.
This commit is contained in:
Andrzej Krzemienski
2014-11-22 01:18:25 +01:00
parent 5435021ea4
commit 53e53171c4
7 changed files with 63 additions and 5 deletions

View File

@ -30,7 +30,7 @@
<p> <p>
Type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is Type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
<a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a>. Two optional <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a>. Two optional
objects containing a value compare in the same as their contained values. objects containing a value compare in the same way as their contained values.
The uninitialized state of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> The uninitialized state of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is treated as a distinct value, equal to itself, and unequal to any value is treated as a distinct value, equal to itself, and unequal to any value
of type <code class="computeroutput"><span class="identifier">T</span></code>: of type <code class="computeroutput"><span class="identifier">T</span></code>:

View File

@ -108,8 +108,9 @@
It is possible that this parameter is not specified; such situation is no error. It is possible that this parameter is not specified; such situation is no error.
It is valid to not specify the parameter and in that case the program is supposed It is valid to not specify the parameter and in that case the program is supposed
to behave slightly differently. Also, suppose that any possible value of type to behave slightly differently. Also, suppose that any possible value of type
<code class="computeroutput"><span class="keyword">int</span></code> is a valid value for <code class="computeroutput"><span class="string">"MaxValue"</span></code>, so we cannot jut use <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code> to represent <code class="computeroutput"><span class="keyword">int</span></code> is a valid value for <code class="computeroutput"><span class="string">"MaxValue"</span></code>, so we cannot just use
the absence of the parameter in the config file. <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code>
to represent the absence of the parameter in the config file.
</p> </p>
<h4> <h4>
<a name="optional.introduction.h1"></a> <a name="optional.introduction.h1"></a>
@ -133,7 +134,7 @@
</div> </div>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: September 12, 2014 at 09:54:26 GMT</small></p></td> <td align="left"><p><small>Last revised: November 21, 2014 at 23:32:40 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@ -1,4 +1,5 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal. // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2014 Andrzej Krzemienski.
// //
// 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
@ -20,7 +21,31 @@
namespace boost { namespace boost {
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
none_t const none = (static_cast<none_t>(0)) ; none_t const none = (static_cast<none_t>(0)) ;
#else
namespace detail { namespace optional_detail {
// the trick here is to make boost::none defined once as a global but in a header file
template <typename T>
struct none_instance
{
static const T instance;
};
template <typename T>
const T none_instance<T>::instance = T(); // global, but because 'tis a template, no cpp file required
} } // namespace detail::optional_detail
namespace {
// TU-local
const none_t& none = detail::optional_detail::none_instance<none_t>::instance;
}
#endif
} // namespace boost } // namespace boost

View File

@ -1,4 +1,5 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal. // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2014 Andrzej Krzemienski.
// //
// Use, modification, and distribution is subject to the Boost Software // Use, modification, and distribution is subject to the Boost Software
// 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
@ -14,9 +15,12 @@
namespace boost { namespace boost {
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
namespace detail { struct none_helper{}; } namespace detail { struct none_helper{}; }
typedef int detail::none_helper::*none_t ; typedef int detail::none_helper::*none_t ;
#else
class none_t {};
#endif
} // namespace boost } // namespace boost

View File

@ -41,6 +41,7 @@ import testing ;
[ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ] [ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ]
[ compile-fail optional_test_fail_convert_from_null.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ] [ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ] [ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
; ;

View File

@ -51,6 +51,8 @@ using boost::get_pointer ;
// via the safe_bool operator. // via the safe_bool operator.
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
#define BOOST_OPTIONAL_NO_NULL_COMPARE #define BOOST_OPTIONAL_NO_NULL_COMPARE
#else
#define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere
#endif #endif
#define ARG(T) (static_cast< T const* >(0)) #define ARG(T) (static_cast< T const* >(0))

View File

@ -0,0 +1,25 @@
// Copyright (C) 2014, Andrzej Krzemienski.
//
// 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)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct NoInitFromNull{};
void test_conversion_from_null()
{
boost::optional<NoInitFromNull> opt = 0;
}