MSVC templated constructor/assignment problem fixed.

[SVN r17062]
This commit is contained in:
Fernando Cacciola
2003-01-28 14:38:00 +00:00
parent 9461f09cb8
commit 4456cc1660
2 changed files with 29 additions and 41 deletions

View File

@ -25,14 +25,8 @@
#include "boost/type_traits/alignment_of.hpp" #include "boost/type_traits/alignment_of.hpp"
#include "boost/type_traits/type_with_alignment.hpp" #include "boost/type_traits/type_with_alignment.hpp"
// MSVC6.0 doesn't like separated templated contructor/assignment,
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1200 ) // 1200 == VC++ 6.0
#define BOOST_OPTIONAL_NO_CONVERTIONS
#endif
namespace boost namespace boost
{ {
namespace optional_detail namespace optional_detail
{ {
template <class T> template <class T>
@ -80,17 +74,8 @@ class optional
construct(val); construct(val);
} }
// Creates a deep copy of another optional<T> // NOTE: MSVC needs templated versions first
// Can throw if T::T(T const&) does
optional ( optional const& rhs )
:
m_initialized(false)
{
if ( rhs )
construct(*rhs);
}
#ifndef BOOST_OPTIONAL_NO_CONVERTIONS
// Creates a deep copy of another convertible optional<U> // Creates a deep copy of another convertible optional<U>
// Requires a valid conversion from U to T. // Requires a valid conversion from U to T.
// Can throw if T::T(U const&) does // Can throw if T::T(U const&) does
@ -102,27 +87,21 @@ class optional
if ( rhs ) if ( rhs )
construct(*rhs); construct(*rhs);
} }
#endif
// Creates a deep copy of another optional<T>
// Can throw if T::T(T const&) does
optional ( optional const& rhs )
:
m_initialized(false)
{
if ( rhs )
construct(*rhs);
}
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)
~optional() { destroy() ; } ~optional() { destroy() ; }
// Assigns from another optional<T> (deep-copies the rhs value)
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
optional& operator= ( optional const& rhs )
{
destroy(); // no-throw
if ( rhs )
{
// An exception can be thrown here.
// It it happens, THIS will be left uninitialized.
construct(*rhs);
}
return *this ;
}
#ifndef BOOST_OPTIONAL_NO_CONVERTIONS
// Assigns from another convertible optional<U> (converts && deep-copies the rhs value) // Assigns from another convertible optional<U> (converts && deep-copies the rhs value)
// Requires a valid conversion from U to T. // Requires a valid conversion from U to T.
// Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
@ -139,7 +118,22 @@ class optional
} }
return *this ; return *this ;
} }
#endif
// Assigns from another optional<T> (deep-copies the rhs value)
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
optional& operator= ( optional const& rhs )
{
destroy(); // no-throw
if ( rhs )
{
// An exception can be thrown here.
// It it happens, THIS will be left uninitialized.
construct(*rhs);
}
return *this ;
}
// Destroys the current value, if any, leaving this UNINITIALIZED // Destroys the current value, if any, leaving this UNINITIALIZED
// No-throw (assuming T::~T() doesn't) // No-throw (assuming T::~T() doesn't)

View File

@ -876,7 +876,6 @@ void test_no_implicit_conversions()
test_no_implicit_conversions_impl(p); test_no_implicit_conversions_impl(p);
} }
#ifndef BOOST_OPTIONAL_NO_CONVERTIONS
struct A {} ; struct A {} ;
void test_conversions() void test_conversions()
{ {
@ -895,7 +894,6 @@ void test_conversions()
opt3 = opt2 ; opt3 = opt2 ;
BOOST_CHECK(*opt3 == d); BOOST_CHECK(*opt3 == d);
} }
#endif
int test_main( int, char* [] ) int test_main( int, char* [] )
{ {
@ -904,11 +902,7 @@ int test_main( int, char* [] )
test_with_class_type(); test_with_class_type();
test_with_builtin_types(); test_with_builtin_types();
test_no_implicit_conversions(); test_no_implicit_conversions();
#ifndef BOOST_OPTIONAL_NO_CONVERTIONS
test_conversions(); test_conversions();
#endif
} }
catch ( ... ) catch ( ... )
{ {