forked from boostorg/utility
Compare commits
15 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
4d917003e2 | ||
|
a991936c96 | ||
|
6239e685a2 | ||
|
e601fcb9c9 | ||
|
f29a5db08e | ||
|
22743ee125 | ||
|
e3c982287a | ||
|
82e1111bb8 | ||
|
9339b32178 | ||
|
3770221507 | ||
|
e6cb3a77ee | ||
|
bbccfbbab4 | ||
|
74a6a693d3 | ||
|
bf713ad47a | ||
|
76b17c497b |
@@ -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>
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
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,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;
|
||||||
|
@@ -32,9 +32,12 @@ 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 ../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));
|
||||||
|
140
value_init.htm
140
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>
|
||||||
@@ -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 03 October 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>
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "boost/test/minimal.hpp"
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sample POD type
|
// Sample POD type
|
||||||
@@ -215,7 +215,7 @@ template<class T>
|
|||||||
void check_initialized_value ( T const& y )
|
void check_initialized_value ( T const& y )
|
||||||
{
|
{
|
||||||
T initializedValue = boost::initialized_value ;
|
T initializedValue = boost::initialized_value ;
|
||||||
BOOST_CHECK ( y == initializedValue ) ;
|
BOOST_TEST ( y == initializedValue ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
@@ -245,128 +245,125 @@ void check_initialized_value( NonPOD const& )
|
|||||||
template<class T>
|
template<class T>
|
||||||
bool test ( T const& y, T const& z )
|
bool test ( T const& y, T const& z )
|
||||||
{
|
{
|
||||||
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
|
const int errors_before_test = boost::detail::test_errors();
|
||||||
|
|
||||||
check_initialized_value(y);
|
check_initialized_value(y);
|
||||||
|
|
||||||
boost::value_initialized<T> x ;
|
boost::value_initialized<T> x ;
|
||||||
BOOST_CHECK ( y == x ) ;
|
BOOST_TEST ( y == x ) ;
|
||||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
BOOST_TEST ( y == boost::get(x) ) ;
|
||||||
|
|
||||||
static_cast<T&>(x) = z ;
|
static_cast<T&>(x) = z ;
|
||||||
boost::get(x) = z ;
|
boost::get(x) = z ;
|
||||||
BOOST_CHECK ( x == z ) ;
|
BOOST_TEST ( x == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const x_c ;
|
boost::value_initialized<T> const x_c ;
|
||||||
BOOST_CHECK ( y == x_c ) ;
|
BOOST_TEST ( y == x_c ) ;
|
||||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
BOOST_TEST ( y == boost::get(x_c) ) ;
|
||||||
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
|
||||||
x_c_ref = z ;
|
x_c_ref = z ;
|
||||||
BOOST_CHECK ( x_c == z ) ;
|
BOOST_TEST ( x_c == z ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> const copy1 = x;
|
boost::value_initialized<T> const copy1 = x;
|
||||||
BOOST_CHECK ( boost::get(copy1) == boost::get(x) ) ;
|
BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T> copy2;
|
boost::value_initialized<T> copy2;
|
||||||
copy2 = x;
|
copy2 = x;
|
||||||
BOOST_CHECK ( boost::get(copy2) == boost::get(x) ) ;
|
BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
|
||||||
|
|
||||||
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
boost::shared_ptr<boost::value_initialized<T> > ptr( new boost::value_initialized<T> );
|
||||||
BOOST_CHECK ( y == *ptr ) ;
|
BOOST_TEST ( y == *ptr ) ;
|
||||||
|
|
||||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||||
boost::value_initialized<T const> cx ;
|
boost::value_initialized<T const> cx ;
|
||||||
BOOST_CHECK ( y == cx ) ;
|
BOOST_TEST ( y == cx ) ;
|
||||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
BOOST_TEST ( y == boost::get(cx) ) ;
|
||||||
|
|
||||||
boost::value_initialized<T const> const cx_c ;
|
boost::value_initialized<T const> const cx_c ;
|
||||||
BOOST_CHECK ( y == cx_c ) ;
|
BOOST_TEST ( y == cx_c ) ;
|
||||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
BOOST_TEST ( y == boost::get(cx_c) ) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return boost::minimal_test::errors_counter() == counter_before_test ;
|
return boost::detail::test_errors() == errors_before_test ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_main(int, char **)
|
int main(int, char **)
|
||||||
{
|
{
|
||||||
BOOST_CHECK ( test( 0,1234 ) ) ;
|
BOOST_TEST ( test( 0,1234 ) ) ;
|
||||||
BOOST_CHECK ( test( 0.0,12.34 ) ) ;
|
BOOST_TEST ( test( 0.0,12.34 ) ) ;
|
||||||
BOOST_CHECK ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
|
||||||
BOOST_CHECK ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
|
||||||
|
|
||||||
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
NonPOD NonPOD_object( std::string("NonPOD_object") );
|
||||||
BOOST_CHECK ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
|
||||||
|
|
||||||
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
|
||||||
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
|
||||||
BOOST_CHECK ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
|
||||||
|
|
||||||
StringAndInt stringAndInt0;
|
StringAndInt stringAndInt0;
|
||||||
StringAndInt stringAndInt1;
|
StringAndInt stringAndInt1;
|
||||||
stringAndInt0.i = 0;
|
stringAndInt0.i = 0;
|
||||||
stringAndInt1.i = 1;
|
stringAndInt1.i = 1;
|
||||||
stringAndInt1.s = std::string("1");
|
stringAndInt1.s = std::string("1");
|
||||||
BOOST_CHECK ( test(stringAndInt0, stringAndInt1) );
|
BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
|
||||||
|
|
||||||
StructWithDestructor structWithDestructor0;
|
StructWithDestructor structWithDestructor0;
|
||||||
StructWithDestructor structWithDestructor1;
|
StructWithDestructor structWithDestructor1;
|
||||||
structWithDestructor0.i = 0;
|
structWithDestructor0.i = 0;
|
||||||
structWithDestructor1.i = 1;
|
structWithDestructor1.i = 1;
|
||||||
BOOST_CHECK ( test(structWithDestructor0, structWithDestructor1) );
|
BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
|
||||||
|
|
||||||
StructWithVirtualFunction structWithVirtualFunction0;
|
StructWithVirtualFunction structWithVirtualFunction0;
|
||||||
StructWithVirtualFunction structWithVirtualFunction1;
|
StructWithVirtualFunction structWithVirtualFunction1;
|
||||||
structWithVirtualFunction0.i = 0;
|
structWithVirtualFunction0.i = 0;
|
||||||
structWithVirtualFunction1.i = 1;
|
structWithVirtualFunction1.i = 1;
|
||||||
BOOST_CHECK ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
|
||||||
|
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
|
||||||
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
|
||||||
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_CHECK ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
|
||||||
|
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
AggregatePODStructWrapper aggregatePODStructWrapper0;
|
||||||
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
AggregatePODStructWrapper aggregatePODStructWrapper1;
|
||||||
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
|
||||||
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
|
||||||
BOOST_CHECK ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
|
||||||
|
|
||||||
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
|
||||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
|
||||||
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
|
||||||
BOOST_CHECK (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester1).is_assignment_called);
|
BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_CHECK ( get(copyFunctionCallTester2).is_copy_constructed);
|
BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester2).is_assignment_called);
|
BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
|
||||||
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
|
||||||
BOOST_CHECK ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
|
||||||
BOOST_CHECK ( get(copyFunctionCallTester3).is_assignment_called);
|
BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
|
||||||
|
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
|
||||||
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
|
||||||
get(swapFunctionCallTester1).data = 1;
|
get(swapFunctionCallTester1).data = 1;
|
||||||
get(swapFunctionCallTester2).data = 2;
|
get(swapFunctionCallTester2).data = 2;
|
||||||
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
|
||||||
BOOST_CHECK( get(swapFunctionCallTester1).data == 2 );
|
BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester2).data == 1 );
|
BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester1).is_custom_swap_called );
|
BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
|
||||||
BOOST_CHECK( get(swapFunctionCallTester2).is_custom_swap_called );
|
BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
|
||||||
|
|
||||||
return 0;
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user