forked from boostorg/optional
Compare commits
9 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
2c839e600b | |||
3ebabcb2d8 | |||
63f6e7f45e | |||
43eac5bb12 | |||
74674531c8 | |||
a4572497be | |||
951b49f992 | |||
1afed544db | |||
66c366d18a |
0
doc/html/boostbook.css
Executable file → Normal file
0
doc/html/boostbook.css
Executable file → Normal file
@ -22,7 +22,7 @@ Distributed under the Boost Software License, Version 1.0.
|
|||||||
[/ Cited Boost resources ]
|
[/ Cited Boost resources ]
|
||||||
|
|
||||||
[def __BOOST_VARIANT__ [@../../../variant/index.html Boost.Variant]]
|
[def __BOOST_VARIANT__ [@../../../variant/index.html Boost.Variant]]
|
||||||
[def __BOOST_TRIBOOL__ [@../../../tribool/index.html boost::tribool]]
|
[def __BOOST_TRIBOOL__ [@../../../../doc/html/tribool.html boost::tribool]]
|
||||||
|
|
||||||
[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html OptionalPointee]]
|
[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html OptionalPointee]]
|
||||||
[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html Copy Constructible]]
|
[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html Copy Constructible]]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@ -9,6 +9,9 @@
|
|||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
//
|
//
|
||||||
|
// Revisions:
|
||||||
|
// 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
|
||||||
|
//
|
||||||
#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
|
#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
|
||||||
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
|
#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
|
||||||
|
|
||||||
@ -19,6 +22,7 @@
|
|||||||
#include "boost/assert.hpp"
|
#include "boost/assert.hpp"
|
||||||
#include "boost/type.hpp"
|
#include "boost/type.hpp"
|
||||||
#include "boost/type_traits/alignment_of.hpp"
|
#include "boost/type_traits/alignment_of.hpp"
|
||||||
|
#include "boost/type_traits/has_nothrow_constructor.hpp"
|
||||||
#include "boost/type_traits/type_with_alignment.hpp"
|
#include "boost/type_traits/type_with_alignment.hpp"
|
||||||
#include "boost/type_traits/remove_reference.hpp"
|
#include "boost/type_traits/remove_reference.hpp"
|
||||||
#include "boost/type_traits/is_reference.hpp"
|
#include "boost/type_traits/is_reference.hpp"
|
||||||
@ -28,6 +32,7 @@
|
|||||||
#include "boost/detail/reference_content.hpp"
|
#include "boost/detail/reference_content.hpp"
|
||||||
#include "boost/none.hpp"
|
#include "boost/none.hpp"
|
||||||
#include "boost/utility/compare_pointees.hpp"
|
#include "boost/utility/compare_pointees.hpp"
|
||||||
|
#include "boost/utility/in_place_factory.hpp"
|
||||||
|
|
||||||
#include "boost/optional/optional_fwd.hpp"
|
#include "boost/optional/optional_fwd.hpp"
|
||||||
|
|
||||||
@ -571,6 +576,14 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
return *this ;
|
return *this ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void swap( optional & arg )
|
||||||
|
{
|
||||||
|
// allow for Koenig lookup
|
||||||
|
using boost::swap ;
|
||||||
|
swap(*this, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns a reference to the value if this is initialized, otherwise,
|
// Returns a reference to the value if this is initialized, otherwise,
|
||||||
// the behaviour is UNDEFINED
|
// the behaviour is UNDEFINED
|
||||||
// No-throw
|
// No-throw
|
||||||
@ -878,44 +891,77 @@ namespace optional_detail {
|
|||||||
#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
#define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// optional's swap:
|
template<bool use_default_constructor> struct swap_selector;
|
||||||
// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified.
|
|
||||||
// If only one is initialized, calls U.reset(*I), THEN I.reset().
|
template<>
|
||||||
// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset)
|
struct swap_selector<true>
|
||||||
// If both are uninitialized, do nothing (no-throw)
|
|
||||||
template<class T>
|
|
||||||
inline
|
|
||||||
void optional_swap ( optional<T>& x, optional<T>& y )
|
|
||||||
{
|
|
||||||
if ( !x && !!y )
|
|
||||||
{
|
{
|
||||||
x.reset(*y);
|
template<class T>
|
||||||
y.reset();
|
static void optional_swap ( optional<T>& x, optional<T>& y )
|
||||||
}
|
{
|
||||||
else if ( !!x && !y )
|
bool hasX = x;
|
||||||
{
|
bool hasY = y;
|
||||||
y.reset(*x);
|
|
||||||
x.reset();
|
if ( !hasX && !hasY )
|
||||||
}
|
return;
|
||||||
else if ( !!x && !!y )
|
|
||||||
{
|
if( !hasX )
|
||||||
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
|
x = boost::in_place();
|
||||||
|
else if ( !hasY )
|
||||||
|
y = boost::in_place();
|
||||||
|
|
||||||
|
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
|
||||||
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
||||||
// allow for Koenig lookup
|
// allow for Koenig lookup
|
||||||
using std::swap ;
|
using std::swap ;
|
||||||
#endif
|
#endif
|
||||||
swap(*x,*y);
|
swap(*x,*y);
|
||||||
}
|
|
||||||
}
|
if( !hasX )
|
||||||
|
y = boost::none ;
|
||||||
|
else if( !hasY )
|
||||||
|
x = boost::none ;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct swap_selector<false>
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
static void optional_swap ( optional<T>& x, optional<T>& y )
|
||||||
|
{
|
||||||
|
if ( !x && !!y )
|
||||||
|
{
|
||||||
|
x = *y;
|
||||||
|
y = boost::none ;
|
||||||
|
}
|
||||||
|
else if ( !!x && !y )
|
||||||
|
{
|
||||||
|
y = *x ;
|
||||||
|
x = boost::none ;
|
||||||
|
}
|
||||||
|
else if ( !!x && !!y )
|
||||||
|
{
|
||||||
|
// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
|
||||||
|
#ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
|
||||||
|
// allow for Koenig lookup
|
||||||
|
using std::swap ;
|
||||||
|
#endif
|
||||||
|
swap(*x,*y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace optional_detail
|
} // namespace optional_detail
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
|
||||||
|
|
||||||
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
||||||
{
|
{
|
||||||
optional_detail::optional_swap(x,y);
|
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@ -9,6 +9,9 @@
|
|||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
//
|
//
|
||||||
|
// Revisions:
|
||||||
|
// 10 May 2008 (added swap related forward declaration) Niels Dekker
|
||||||
|
//
|
||||||
#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
||||||
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
||||||
|
|
||||||
@ -16,6 +19,10 @@ namespace boost {
|
|||||||
|
|
||||||
template<class T> class optional ;
|
template<class T> class optional ;
|
||||||
|
|
||||||
|
template<class T> void swap ( optional<T>& , optional<T>& ) ;
|
||||||
|
|
||||||
|
template<class T> struct optional_swap_should_use_default_constructor ;
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
Automatic redirection failed, please go to
|
Automatic redirection failed, please go to
|
||||||
<a href="doc/optional.html">doc/html/index.html</a>. <hr>
|
<a href="doc/html/index.html">doc/html/index.html</a>. <hr>
|
||||||
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
|
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
|
||||||
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@ -9,6 +9,9 @@
|
|||||||
// You are welcome to contact the author at:
|
// You are welcome to contact the author at:
|
||||||
// fernando_cacciola@hotmail.com
|
// fernando_cacciola@hotmail.com
|
||||||
//
|
//
|
||||||
|
// Revisions:
|
||||||
|
// 12 May 2008 (added more swap tests)
|
||||||
|
//
|
||||||
#include<iostream>
|
#include<iostream>
|
||||||
#include<stdexcept>
|
#include<stdexcept>
|
||||||
#include<string>
|
#include<string>
|
||||||
@ -16,6 +19,8 @@
|
|||||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||||
|
|
||||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||||
|
#include "boost/mpl/bool.hpp"
|
||||||
|
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||||
|
|
||||||
#include "boost/optional/optional.hpp"
|
#include "boost/optional/optional.hpp"
|
||||||
|
|
||||||
@ -927,6 +932,337 @@ void test_conversions2()
|
|||||||
BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
|
BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace optional_swap_test
|
||||||
|
{
|
||||||
|
class default_ctor_exception : public std::exception {} ;
|
||||||
|
class copy_ctor_exception : public std::exception {} ;
|
||||||
|
class assignment_exception : public std::exception {} ;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Base class for swap test classes. Its assignment should not be called, when swapping
|
||||||
|
// optional<T> objects. (The default std::swap would do so.)
|
||||||
|
//
|
||||||
|
class base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"The assignment should not be used while swapping!");
|
||||||
|
throw assignment_exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~base_class_with_forbidden_assignment() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class without default constructor
|
||||||
|
//
|
||||||
|
class class_without_default_ctor : public base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char data;
|
||||||
|
explicit class_without_default_ctor(char arg) : data(arg) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class whose default constructor should not be used by optional::swap!
|
||||||
|
//
|
||||||
|
class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char data;
|
||||||
|
explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
|
||||||
|
|
||||||
|
class_whose_default_ctor_should_not_be_used()
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"This default constructor should not be used while swapping!");
|
||||||
|
throw default_ctor_exception();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class whose default constructor should be used by optional::swap.
|
||||||
|
// Its copy constructor should be avoided!
|
||||||
|
//
|
||||||
|
class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char data;
|
||||||
|
explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
|
||||||
|
|
||||||
|
class_whose_default_ctor_should_be_used() : data('\0') { }
|
||||||
|
|
||||||
|
class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||||
|
throw copy_ctor_exception();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class template whose default constructor should be used by optional::swap.
|
||||||
|
// Its copy constructor should be avoided!
|
||||||
|
//
|
||||||
|
template <class T>
|
||||||
|
class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T data;
|
||||||
|
explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { }
|
||||||
|
|
||||||
|
template_whose_default_ctor_should_be_used() : data('\0') { }
|
||||||
|
|
||||||
|
template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||||
|
throw copy_ctor_exception();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Class whose explicit constructor should be used by optional::swap.
|
||||||
|
// Its other constructors should be avoided!
|
||||||
|
//
|
||||||
|
class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char data;
|
||||||
|
explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { }
|
||||||
|
|
||||||
|
class_whose_explicit_ctor_should_be_used()
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"This default constructor should not be used while swapping!");
|
||||||
|
throw default_ctor_exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &)
|
||||||
|
{
|
||||||
|
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
|
||||||
|
throw copy_ctor_exception();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
|
||||||
|
{
|
||||||
|
std::swap(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
|
||||||
|
{
|
||||||
|
std::swap(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
|
||||||
|
{
|
||||||
|
std::swap(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs)
|
||||||
|
{
|
||||||
|
std::swap(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs)
|
||||||
|
{
|
||||||
|
std::swap(lhs.data, rhs.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// optional<T>::swap should be customized when neither the copy constructor
|
||||||
|
// nor the default constructor of T are supposed to be used when swapping, e.g.,
|
||||||
|
// for the following type T = class_whose_explicit_ctor_should_be_used.
|
||||||
|
//
|
||||||
|
void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y)
|
||||||
|
{
|
||||||
|
bool hasX = x;
|
||||||
|
bool hasY = y;
|
||||||
|
|
||||||
|
if ( !hasX && !hasY )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !hasX )
|
||||||
|
x = boost::in_place('\0');
|
||||||
|
else if ( !hasY )
|
||||||
|
y = boost::in_place('\0');
|
||||||
|
|
||||||
|
optional_swap_test::swap(*x,*y);
|
||||||
|
|
||||||
|
if( !hasX )
|
||||||
|
y = boost::none ;
|
||||||
|
else if( !hasY )
|
||||||
|
x = boost::none ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // End of namespace optional_swap_test.
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compile time tweaking on whether or not swap should use the default constructor:
|
||||||
|
//
|
||||||
|
|
||||||
|
template <> struct optional_swap_should_use_default_constructor<
|
||||||
|
optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ;
|
||||||
|
|
||||||
|
template <> struct optional_swap_should_use_default_constructor<
|
||||||
|
optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ;
|
||||||
|
|
||||||
|
template <class T> struct optional_swap_should_use_default_constructor<
|
||||||
|
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Specialization of boost::swap:
|
||||||
|
//
|
||||||
|
template <>
|
||||||
|
void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y)
|
||||||
|
{
|
||||||
|
optional_swap_test::swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Specializations of std::swap:
|
||||||
|
//
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y)
|
||||||
|
{
|
||||||
|
optional_swap_test::swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y)
|
||||||
|
{
|
||||||
|
optional_swap_test::swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y)
|
||||||
|
{
|
||||||
|
optional_swap_test::swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y)
|
||||||
|
{
|
||||||
|
optional_swap_test::swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tests whether the swap function works properly for optional<T>.
|
||||||
|
// Assumes that T has one data member, of type char.
|
||||||
|
// Returns true iff the test is passed.
|
||||||
|
//
|
||||||
|
template <class T>
|
||||||
|
bool test_swap_function( T const* )
|
||||||
|
{
|
||||||
|
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
optional<T> obj1;
|
||||||
|
optional<T> obj2('a');
|
||||||
|
|
||||||
|
// Self-swap should not have any effect.
|
||||||
|
swap(obj1, obj1);
|
||||||
|
swap(obj2, obj2);
|
||||||
|
BOOST_CHECK(!obj1);
|
||||||
|
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||||
|
|
||||||
|
// Call non-member swap.
|
||||||
|
swap(obj1, obj2);
|
||||||
|
|
||||||
|
// Test if obj1 and obj2 are really swapped.
|
||||||
|
BOOST_CHECK(!!obj1 && obj1->data == 'a');
|
||||||
|
BOOST_CHECK(!obj2);
|
||||||
|
|
||||||
|
// Call non-member swap one more time.
|
||||||
|
swap(obj1, obj2);
|
||||||
|
|
||||||
|
// Test if obj1 and obj2 are swapped back.
|
||||||
|
BOOST_CHECK(!obj1);
|
||||||
|
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||||
|
}
|
||||||
|
catch(const std::exception &)
|
||||||
|
{
|
||||||
|
// The swap function should not throw, for our test cases.
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tests whether the optional<T>::swap member function works properly.
|
||||||
|
// Assumes that T has one data member, of type char.
|
||||||
|
// Returns true iff the test is passed.
|
||||||
|
//
|
||||||
|
template <class T>
|
||||||
|
bool test_swap_member_function( T const* )
|
||||||
|
{
|
||||||
|
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
optional<T> obj1;
|
||||||
|
optional<T> obj2('a');
|
||||||
|
|
||||||
|
// Self-swap should not have any effect.
|
||||||
|
obj1.swap(obj1);
|
||||||
|
obj2.swap(obj2);
|
||||||
|
BOOST_CHECK(!obj1);
|
||||||
|
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||||
|
|
||||||
|
// Call member swap.
|
||||||
|
obj1.swap(obj2);
|
||||||
|
|
||||||
|
// Test if obj1 and obj2 are really swapped.
|
||||||
|
BOOST_CHECK(!!obj1 && obj1->data == 'a');
|
||||||
|
BOOST_CHECK(!obj2);
|
||||||
|
|
||||||
|
// Call member swap one more time.
|
||||||
|
obj1.swap(obj2);
|
||||||
|
|
||||||
|
// Test if obj1 and obj2 are swapped back.
|
||||||
|
BOOST_CHECK(!obj1);
|
||||||
|
BOOST_CHECK(!!obj2 && obj2->data == 'a');
|
||||||
|
}
|
||||||
|
catch(const std::exception &)
|
||||||
|
{
|
||||||
|
// The optional<T>::swap member function should not throw, for our test cases.
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
return boost::minimal_test::errors_counter() == counter_before_test ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tests compile time tweaking of swap, by means of
|
||||||
|
// optional_swap_should_use_default_constructor.
|
||||||
|
//
|
||||||
|
void test_swap_tweaking()
|
||||||
|
{
|
||||||
|
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||||
|
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||||
|
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
|
||||||
|
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
|
||||||
|
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
|
||||||
|
}
|
||||||
|
|
||||||
int test_main( int, char* [] )
|
int test_main( int, char* [] )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -936,6 +1272,7 @@ int test_main( int, char* [] )
|
|||||||
test_no_implicit_conversions();
|
test_no_implicit_conversions();
|
||||||
test_conversions1();
|
test_conversions1();
|
||||||
test_conversions2();
|
test_conversions2();
|
||||||
|
test_swap_tweaking();
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user