From e763315b55ad2afdfee5712ba1ef417a571a0ec8 Mon Sep 17 00:00:00 2001 From: Daryle Walker Date: Sat, 11 Feb 2012 18:27:02 +0000 Subject: [PATCH] Updated boost::base_from_member for C++2011. [SVN r76982] --- base_from_member.html | 51 ++++++++++++++++------ include/boost/utility/base_from_member.hpp | 12 ++++- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/base_from_member.html b/base_from_member.html index 21ee6d2..df4add2 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.

Synopsis

+#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,27 @@ 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 variadic template arguments and r-value reference 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.

+ +

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 +202,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.

Usage

@@ -323,11 +345,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.)

Credits

@@ -360,9 +385,9 @@ with the exact pointer type used in switcher's constructor.


-

Revised: 28 August 2004

+

Revised: 11 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/include/boost/utility/base_from_member.hpp b/include/boost/utility/base_from_member.hpp index 04aabb5..8148077 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,6 +10,7 @@ #ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP #define BOOST_UTILITY_BASE_FROM_MEMBER_HPP +#include #include #include #include @@ -68,12 +69,21 @@ class base_from_member protected: MemberType member; +#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL) + template + 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