From e33f8b0055bb78072337d65ab1e5cbf6517221bd Mon Sep 17 00:00:00 2001
From: Andrey Semashev
Date: Sun, 8 Sep 2013 19:28:44 +0000
Subject: [PATCH] Merged new added components from trunk. Merged other
sublibraries which tests are passing for a long time as well.
[SVN r85613]
---
base_from_member.html | 53 ++++++--
call_traits_test.cpp | 8 +-
doc/Jamfile.v2 | 23 +++-
doc/explicit_operator_bool.qbk | 68 ++++++++++
include/boost/utility/base_from_member.hpp | 73 +++++++++-
include/boost/utility/declval.hpp | 41 +++---
.../utility/detail/result_of_iterate.hpp | 25 +++-
include/boost/utility/empty_deleter.hpp | 43 ++++++
.../boost/utility/explicit_operator_bool.hpp | 128 ++++++++++++++++++
include/boost/utility/result_of.hpp | 29 ++--
index.html | 12 +-
test/Jamfile.v2 | 5 +
test/explicit_operator_bool.cpp | 54 ++++++++
...it_operator_bool_compile_fail_conv_int.cpp | 40 ++++++
..._operator_bool_compile_fail_conv_pvoid.cpp | 40 ++++++
...icit_operator_bool_compile_fail_delete.cpp | 40 ++++++
...licit_operator_bool_compile_fail_shift.cpp | 40 ++++++
test/result_of_test.cpp | 14 +-
utility.htm | 40 ++++++
value_init_test.cpp | 87 ++++++------
20 files changed, 756 insertions(+), 107 deletions(-)
create mode 100644 doc/explicit_operator_bool.qbk
create mode 100644 include/boost/utility/empty_deleter.hpp
create mode 100644 include/boost/utility/explicit_operator_bool.hpp
create mode 100644 test/explicit_operator_bool.cpp
create mode 100644 test/explicit_operator_bool_compile_fail_conv_int.cpp
create mode 100644 test/explicit_operator_bool_compile_fail_conv_pvoid.cpp
create mode 100644 test/explicit_operator_bool_compile_fail_delete.cpp
create mode 100644 test/explicit_operator_bool_compile_fail_shift.cpp
diff --git a/base_from_member.html b/base_from_member.html
index 21ee6d2..07e144e 100644
--- a/base_from_member.html
+++ b/base_from_member.html
@@ -129,6 +129,8 @@ particular member type does not need to concern itself with the integer.
+#include <type_traits> // exposition only
+
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
#endif
@@ -139,6 +141,11 @@ class boost::base_from_member
protected:
MemberType member;
+#if C++2011 is in use
+ template< typename ...T >
+ explicit constexpr base_from_member( T&& ...x )
+ noexcept( std::is_nothrow_constructible<MemberType, T...>::value );
+#else
base_from_member();
template< typename T1 >
@@ -154,6 +161,7 @@ protected:
typename T10 >
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
T8 x8, T9 x9, T10 x10 );
+#endif
};
@@ -166,13 +174,29 @@ value of zero if it is omitted. The class template has a protected
data member called member that the derived class can use
for later base classes (or itself).
-There is a default constructor and several constructor member
-templates. These constructor templates can take as many arguments
-(currently up to ten) as possible and pass them to a constructor of
-the data member. Since C++ does not allow any way to explicitly state
+
If the appropriate features of C++2011 are present, there will be a single
+constructor template. It implements "perfect forwarding" to the best
+constructor call of member
(if any). The constructor template is
+marked both constexpr
and explicit
. The former will
+be ignored if the corresponding inner constructor call (of member
)
+does not have the marker. The latter binds the other way; always taking
+effect, even when the inner constructor call does not have the marker. The
+constructor template propagates the noexcept
status of the inner
+constructor call. (The constructor template has a trailing parameter with a
+default value that disables the template when its signature is too close to the
+signatures of the automatically-defined non-template copy- and/or
+move-constructors of base_from_member
.)
+
+On earlier-standard compilers, there is a default constructor and several
+constructor member templates. These constructor templates can take as many
+arguments (currently up to ten) as possible and pass them to a constructor of
+the data member.
+
+Since C++ does not allow any way to explicitly state
the template parameters of a templated constructor, make sure that
the arguments are already close as possible to the actual type used in
-the data member's desired constructor.
+the data member's desired constructor. Explicit conversions may be
+necessary.
The BOOST_BASE_FROM_MEMBER_MAX_ARITY macro constant specifies
the maximum argument length for the constructor templates. The constant
@@ -180,7 +204,7 @@ may be overridden if more (or less) argument configurations are needed. The
constant may be read for code that is expandable like the class template and
needs to maintain the same maximum size. (Example code would be a class that
uses this class template as a base class for a member with a flexible set of
-constructors.)
+constructors.) This constant is ignored when C++2011 features are present.
@@ -323,11 +347,14 @@ constructor argument for pbase0_type
is converted from
argument for pbase2_type
is converted from int
to double
. The second constructor argument for
pbase3_type
is a special case of necessary conversion; all
-forms of the null-pointer literal in C++ also look like compile-time
-integral expressions, so C++ always interprets such code as an integer
-when it has overloads that can take either an integer or a pointer. The
-last conversion is necessary for the compiler to call a constructor form
-with the exact pointer type used in switcher
's constructor.
+forms of the null-pointer literal in C++ (except nullptr
from
+C++2011) also look like compile-time integral expressions, so C++ always
+interprets such code as an integer when it has overloads that can take either
+an integer or a pointer. The last conversion is necessary for the compiler to
+call a constructor form with the exact pointer type used in
+switcher
's constructor. (If C++2011's nullptr
is
+used, it still needs a conversion if multiple pointer types can be accepted in
+a constructor call but std::nullptr_t
cannot.)
@@ -360,9 +387,9 @@ with the exact pointer type used in switcher
's constructor.
-Revised: 28 August 2004
+Revised: 16 February 2012
-Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and distribution
+
Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and distribution
are subject to the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
diff --git a/call_traits_test.cpp b/call_traits_test.cpp
index 72852c4..9e49b68 100644
--- a/call_traits_test.cpp
+++ b/call_traits_test.cpp
@@ -210,8 +210,10 @@ int main()
comparible_UDT u;
c1(u);
call_traits_checker c2;
+ call_traits_checker c2b;
int i = 2;
c2(i);
+ c2b(one);
int* pi = &i;
int a[2] = {1,2};
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
@@ -292,7 +294,11 @@ int main()
BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits::reference);
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits::const_reference);
BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits::param_type);
-
+ // test enum:
+ BOOST_CHECK_TYPE(enum_UDT, boost::call_traits::value_type);
+ BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits::reference);
+ BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits::const_reference);
+ BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits::param_type);
return 0;
}
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
index a0ff034..a734cb2 100644
--- a/doc/Jamfile.v2
+++ b/doc/Jamfile.v2
@@ -6,7 +6,7 @@
project : requirements
# Path for links to Boost:
boost.root=../../../..
-
+
# Some general style settings:
table.footnote.number.format=1
footnote.number.format=1
@@ -59,7 +59,6 @@ boostbook standalone_declval
toc.max.depth=1
# How far down we go with TOC's
generate.section.toc.level=1
-
;
xml string_ref : string_ref.qbk ;
@@ -79,5 +78,23 @@ boostbook standalone_string_ref
toc.max.depth=1
# How far down we go with TOC's
generate.section.toc.level=1
-
+ ;
+
+xml explicit_operator_bool : explicit_operator_bool.qbk ;
+boostbook standalone_explicit_operator_bool
+ :
+ explicit_operator_bool
+ :
+ # File name of HTML output:
+ root.filename=explicit_operator_bool
+ # How far down we chunk nested sections, basically all of them:
+ chunk.section.depth=0
+ # Don't put the first section on the same page as the TOC:
+ chunk.first.sections=0
+ # How far down sections get TOC's
+ toc.section.depth=1
+ # Max depth in each TOC:
+ toc.max.depth=1
+ # How far down we go with TOC's
+ generate.section.toc.level=1
;
diff --git a/doc/explicit_operator_bool.qbk b/doc/explicit_operator_bool.qbk
new file mode 100644
index 0000000..4a7e4b1
--- /dev/null
+++ b/doc/explicit_operator_bool.qbk
@@ -0,0 +1,68 @@
+[/
+ / Copyright (c) 2013 Andrey Semashev
+ /
+ / 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)
+ /]
+
+[article BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL
+ [quickbook 1.5]
+ [authors [Semashev, Andrey]]
+ [copyright 2013 Andrey Semashev]
+ [license
+ 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])
+ ]
+]
+
+[/===============]
+[section Overview]
+[/===============]
+
+`BOOST_EXPLICIT_OPERATOR_BOOL()` and `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` are compatibility helper macros that expand to an explicit conversion operator to `bool`. For compilers not supporting explicit conversion operators introduced in C++11 the macros expand to a conversion operator that implements the [@http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool safe bool idiom]. In case if the compiler is not able to handle safe bool idiom well the macros expand to a regular conversion operator to `bool`.
+
+[endsect]
+
+
+[/===============]
+[section Examples]
+[/===============]
+
+Both macros are intended to be placed within a user's class definition. The generated conversion operators will be implemented in terms of `operator!()` that should be defined by user in this class. In case of `BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()` the generated conversion operator will be declared `constexpr` which requires the corresponding `operator!()` to also be `constexpr`.
+
+ template< typename T >
+ class my_ptr
+ {
+ T* m_p;
+
+ public:
+ BOOST_EXPLICIT_OPERATOR_BOOL()
+
+ bool operator!() const
+ {
+ return !m_p;
+ }
+ };
+
+Now `my_ptr` can be used in conditional expressions, similarly to a regular pointer:
+
+ my_ptr< int > p;
+ if (p)
+ std::cout << "true" << std::endl;
+
+[endsect]
+
+[/===============]
+[section History]
+[/===============]
+
+[heading boost 1.55]
+
+* The macro was extracted from Boost.Log.
+
+[endsect]
+
+
+
+
diff --git a/include/boost/utility/base_from_member.hpp b/include/boost/utility/base_from_member.hpp
index 04aabb5..e32ecb8 100644
--- a/include/boost/utility/base_from_member.hpp
+++ b/include/boost/utility/base_from_member.hpp
@@ -1,6 +1,6 @@
// boost utility/base_from_member.hpp header file --------------------------//
-// Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and
+// Copyright 2001, 2003, 2004, 2012 Daryle Walker. Use, modification, and
// distribution are subject to the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or a copy at
// .)
@@ -10,10 +10,15 @@
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
+#include
#include
#include
#include
#include
+#include
+#include
+#include
+#include
// Base-from-member arity configuration macro ------------------------------//
@@ -53,6 +58,59 @@
namespace boost
{
+namespace detail
+{
+
+// Type-unmarking class template -------------------------------------------//
+
+// Type-trait to get the raw type, i.e. the type without top-level reference nor
+// cv-qualification, from a type expression. Mainly for function arguments, any
+// reference part is stripped first.
+
+// Contributed by Daryle Walker
+
+template < typename T >
+struct remove_cv_ref
+{
+ typedef typename ::boost::remove_cv::type>::type type;
+
+}; // boost::detail::remove_cv_ref
+
+// Unmarked-type comparison class template ---------------------------------//
+
+// Type-trait to check if two type expressions have the same raw type.
+
+// Contributed by Daryle Walker, based on a work-around by Luc Danton
+
+template < typename T, typename U >
+struct is_related
+ : public ::boost::is_same<
+ typename ::boost::detail::remove_cv_ref::type,
+ typename ::boost::detail::remove_cv_ref::type >
+{};
+
+// Enable-if-on-unidentical-unmarked-type class template -------------------//
+
+// Enable-if on the first two type expressions NOT having the same raw type.
+
+// Contributed by Daryle Walker, based on a work-around by Luc Danton
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+template
+struct enable_if_unrelated
+ : public ::boost::enable_if_c
+{};
+
+template
+struct enable_if_unrelated
+ : public ::boost::disable_if< ::boost::detail::is_related >
+{};
+#endif
+
+} // namespace boost::detail
+
+
// Base-from-member class template -----------------------------------------//
// Helper to initialize a base object so a derived class can use this
@@ -68,12 +126,25 @@ class base_from_member
protected:
MemberType member;
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
+ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && \
+ !(defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 4))
+ template ::type>
+ explicit BOOST_CONSTEXPR base_from_member( T&& ...x )
+ BOOST_NOEXCEPT_IF( BOOST_NOEXCEPT_EXPR(::new ((void*) 0) MemberType(
+ static_cast(x)... )) ) // no std::is_nothrow_constructible...
+ : member( static_cast(x)... ) // ...nor std::forward needed
+ {}
+#else
base_from_member()
: member()
{}
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
BOOST_PRIVATE_CTR_DEF, _ )
+#endif
}; // boost::base_from_member
diff --git a/include/boost/utility/declval.hpp b/include/boost/utility/declval.hpp
index d74610c..a4ab2c8 100644
--- a/include/boost/utility/declval.hpp
+++ b/include/boost/utility/declval.hpp
@@ -1,49 +1,44 @@
-// common_type.hpp ---------------------------------------------------------//
+// declval.hpp -------------------------------------------------------------//
// Copyright 2010 Vicente J. Botet Escriba
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
-#ifndef BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
-#define BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
+#ifndef BOOST_UTILITY_DECLVAL_HPP
+#define BOOST_UTILITY_DECLVAL_HPP
#include
//----------------------------------------------------------------------------//
#include
-//#include
//----------------------------------------------------------------------------//
// //
// C++03 implementation of //
+// 20.2.4 Function template declval [declval] //
// Written by Vicente J. Botet Escriba //
-//~ 20.3.4 Function template declval [declval]
-//~ 1 The library provides the function template declval to simplify the definition of expressions which occur as
-//~ unevaluated operands.
-//~ 2 Remarks: If this function is used, the program is ill-formed.
-//~ 3 Remarks: The template parameter T of declval may be an incomplete type.
-//~ [ Example:
-
-//~ template
-//~ decltype(static_cast(declval())) convert(From&&);
-
-//~ declares a function template convert which only participats in overloading if the type From can be
-//~ explicitly converted to type To. For another example see class template common_type (20.7.6.6). —end
-//~ example ]
// //
+// 1 The library provides the function template declval to simplify the
+// definition of expressions which occur as unevaluated operands.
+// 2 Remarks: If this function is used, the program is ill-formed.
+// 3 Remarks: The template parameter T of declval may be an incomplete type.
+// [ Example:
+//
+// template
+// decltype(static_cast(declval())) convert(From&&);
+//
+// declares a function template convert which only participates in overloading
+// if the type From can be explicitly converted to type To. For another example
+// see class template common_type (20.9.7.6). -end example ]
//----------------------------------------------------------------------------//
namespace boost {
-//#if !defined(BOOST_NO_RVALUE_REFERENCES)
template
typename add_rvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand
-//#else
-// template
-// typename add_lvalue_reference::type declval() BOOST_NOEXCEPT; // as unevaluated operand
-//#endif
+
} // namespace boost
-#endif // BOOST_TYPE_TRAITS_EXT_DECLVAL__HPP
+#endif // BOOST_UTILITY_DECLVAL_HPP
diff --git a/include/boost/utility/detail/result_of_iterate.hpp b/include/boost/utility/detail/result_of_iterate.hpp
index 17fd4d5..5192172 100644
--- a/include/boost/utility/detail/result_of_iterate.hpp
+++ b/include/boost/utility/detail/result_of_iterate.hpp
@@ -38,10 +38,25 @@ struct tr1_result_of
#endif
#ifdef BOOST_RESULT_OF_USE_DECLTYPE
-
-// Uses declval following N3225 20.7.7.6 when F is not a pointer.
template
-struct result_of
+struct result_of
+ : detail::cpp0x_result_of { };
+#endif // BOOST_RESULT_OF_USE_DECLTYPE
+
+#ifdef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
+template
+struct result_of
+ : mpl::if_, detail::has_result >,
+ tr1_result_of,
+ detail::cpp0x_result_of >::type { };
+#endif // BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
+
+#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
+
+namespace detail {
+
+template
+struct cpp0x_result_of
: mpl::if_<
is_member_function_pointer
, detail::tr1_result_of_impl<
@@ -54,8 +69,6 @@ struct result_of
>::type
{};
-namespace detail {
-
#ifdef BOOST_NO_SFINAE_EXPR
template
@@ -139,7 +152,7 @@ struct cpp0x_result_of_impl
diff --git a/include/boost/utility/empty_deleter.hpp b/include/boost/utility/empty_deleter.hpp
new file mode 100644
index 0000000..ba919cd
--- /dev/null
+++ b/include/boost/utility/empty_deleter.hpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file empty_deleter.hpp
+ * \author Andrey Semashev
+ * \date 22.04.2007
+ *
+ * This header contains an \c empty_deleter implementation. This is an empty
+ * function object that receives a pointer and does nothing with it.
+ * Such empty deletion strategy may be convenient, for example, when
+ * constructing shared_ptrs that point to some object that should not be
+ * deleted (i.e. a variable on the stack or some global singleton, like std::cout).
+ */
+
+#ifndef BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
+#define BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
+
+#include
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+//! A function object that does nothing and can be used as an empty deleter for \c shared_ptr
+struct empty_deleter
+{
+ //! Function object result type
+ typedef void result_type;
+ /*!
+ * Does nothing
+ */
+ void operator() (const volatile void*) const BOOST_NOEXCEPT {}
+};
+
+} // namespace boost
+
+#endif // BOOST_UTILITY_EMPTY_DELETER_HPP_INCLUDED_
diff --git a/include/boost/utility/explicit_operator_bool.hpp b/include/boost/utility/explicit_operator_bool.hpp
new file mode 100644
index 0000000..650caff
--- /dev/null
+++ b/include/boost/utility/explicit_operator_bool.hpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright Andrey Semashev 2007 - 2013.
+ * 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)
+ */
+/*!
+ * \file explicit_operator_bool.hpp
+ * \author Andrey Semashev
+ * \date 08.03.2009
+ *
+ * This header defines a compatibility macro that implements an unspecified
+ * \c bool operator idiom, which is superseded with explicit conversion operators in
+ * C++11.
+ */
+
+#ifndef BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
+#define BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
+
+#include
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+/*!
+ * \brief The macro defines an explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement operator!,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE explicit operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+/*!
+ * \brief The macro defines a constexpr explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement operator!,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
+#define BOOST_NO_UNSPECIFIED_BOOL
+#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+
+#if !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+namespace boost {
+
+namespace detail {
+
+#if !defined(_MSC_VER) && !defined(__IBMCPP__)
+
+ struct unspecified_bool
+ {
+ // NOTE TO THE USER: If you see this in error messages then you tried
+ // to apply an unsupported operator on the object that supports
+ // explicit conversion to bool.
+ struct OPERATORS_NOT_ALLOWED;
+ static void true_value(OPERATORS_NOT_ALLOWED*) {}
+ };
+ typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#else
+
+ // MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't
+ struct unspecified_bool
+ {
+ // NOTE TO THE USER: If you see this in error messages then you tried
+ // to apply an unsupported operator on the object that supports
+ // explicit conversion to bool.
+ struct OPERATORS_NOT_ALLOWED;
+ void true_value(OPERATORS_NOT_ALLOWED*) {}
+ };
+ typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#endif
+
+} // namespace detail
+
+} // namespace boost
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\
+ {\
+ return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+ }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const\
+ {\
+ return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+ }
+
+#else // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+ BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const\
+ {\
+ return !this->operator! ();\
+ }
+
+#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#endif // BOOST_UTILITY_EXPLICIT_OPERATOR_BOOL_HPP_INCLUDED_
diff --git a/include/boost/utility/result_of.hpp b/include/boost/utility/result_of.hpp
index 97e9618..a530c3a 100644
--- a/include/boost/utility/result_of.hpp
+++ b/include/boost/utility/result_of.hpp
@@ -38,18 +38,27 @@
// Use the decltype-based version of result_of by default if the compiler
// supports N3276 .
-// The user can force the choice by defining either BOOST_RESULT_OF_USE_DECLTYPE or
-// BOOST_RESULT_OF_USE_TR1, but not both!
-#if defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)
-# error Both BOOST_RESULT_OF_USE_DECLTYPE and BOOST_RESULT_OF_USE_TR1 cannot be defined at the same time.
+// The user can force the choice by defining BOOST_RESULT_OF_USE_DECLTYPE,
+// BOOST_RESULT_OF_USE_TR1, or BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK but not more than one!
+#if (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1)) || \
+ (defined(BOOST_RESULT_OF_USE_DECLTYPE) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)) || \
+ (defined(BOOST_RESULT_OF_USE_TR1) && defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK))
+# error More than one of BOOST_RESULT_OF_USE_DECLTYPE, BOOST_RESULT_OF_USE_TR1 and \
+ BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK cannot be defined at the same time.
+#endif
+
+#if defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK) && defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
+# error Cannot fallback to decltype if BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE is not defined.
#endif
#ifndef BOOST_RESULT_OF_USE_TR1
# ifndef BOOST_RESULT_OF_USE_DECLTYPE
-# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
-# define BOOST_RESULT_OF_USE_DECLTYPE
-# else
-# define BOOST_RESULT_OF_USE_TR1
+# ifndef BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
+# ifndef BOOST_NO_CXX11_DECLTYPE_N3276 // this implies !defined(BOOST_NO_CXX11_DECLTYPE)
+# define BOOST_RESULT_OF_USE_DECLTYPE
+# else
+# define BOOST_RESULT_OF_USE_TR1
+# endif
# endif
# endif
#endif
@@ -64,8 +73,12 @@ namespace detail {
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
+BOOST_MPL_HAS_XXX_TEMPLATE_DEF(result)
+
template struct tr1_result_of_impl;
+template struct cpp0x_result_of;
+
#ifdef BOOST_NO_SFINAE_EXPR
// There doesn't seem to be any other way to turn this off such that the presence of
diff --git a/index.html b/index.html
index 367fa93..41c8c15 100644
--- a/index.html
+++ b/index.html
@@ -14,22 +14,29 @@
But that doesn't mean there isn't useful stuff here. Take a look:
+ addressof
assert
base_from_member
+ BOOST_BINARY
call_traits
checked_delete
compressed_pair
current_function
declval
enable_if
- iterator_adaptors
- generator iterator adaptors
+ in_place_factory
+ iterator_adaptors
+ generator iterator adaptors
+ next/prior
+ noncopyable
operators
+ result_of
swap
throw_exception
utility
string_ref
value_init
+ BOOST_EXPLICIT_OPERATOR_BOOL and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL
@@ -43,4 +50,3 @@
07 November, 2006