Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73143 - in sandbox/conversion/boost/conversion/type_traits: . boost/fusion std
From: vicente.botet_at_[hidden]
Date: 2011-07-16 07:54:58


Author: viboes
Date: 2011-07-16 07:54:57 EDT (Sat, 16 Jul 2011)
New Revision: 73143
URL: http://svn.boost.org/trac/boost/changeset/73143

Log:
conversion: is_explicitly_convertible uses now an independent implementation from is_constructible, based on static_cast.
Text files modified:
   sandbox/conversion/boost/conversion/type_traits/boost/fusion/tuple.hpp | 11 ++
   sandbox/conversion/boost/conversion/type_traits/is_constructible.hpp | 85 ++++++++++-----
   sandbox/conversion/boost/conversion/type_traits/is_explicitly_convertible.hpp | 211 ++++++++++++++++++++++++++++++++++++++-
   sandbox/conversion/boost/conversion/type_traits/std/utility.hpp | 5
   4 files changed, 272 insertions(+), 40 deletions(-)

Modified: sandbox/conversion/boost/conversion/type_traits/boost/fusion/tuple.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/type_traits/boost/fusion/tuple.hpp (original)
+++ sandbox/conversion/boost/conversion/type_traits/boost/fusion/tuple.hpp 2011-07-16 07:54:57 EDT (Sat, 16 Jul 2011)
@@ -17,6 +17,7 @@
 
 #include <boost/conversion/type_traits/is_assignable.hpp>
 #include <boost/conversion/type_traits/is_constructible.hpp>
+#include <boost/conversion/type_traits/is_explicitly_convertible.hpp>
 #include <boost/fusion/tuple.hpp>
 
 
@@ -45,6 +46,16 @@
       {};
 
   template <class A1, class A2, class B1, class B2>
+ struct is_explicitly_convertible< fusion::tuple<A1,A2>, fusion::tuple<B1,B2> >
+ : integral_constant<bool, is_explicitly_convertible<A1,B1>::value && is_explicitly_convertible<A2,B2>::value >
+ {};
+
+ template <class A1, class A2, class A3, class B1, class B2, class B3>
+ struct is_explicitly_convertible< fusion::tuple<A1,A2,A3>, fusion::tuple<B1,B2,B3> >
+ : integral_constant<bool, is_explicitly_convertible<A1,B1>::value && is_explicitly_convertible<A2,B2>::value&& is_explicitly_convertible<A3,B3>::value >
+ {};
+
+ template <class A1, class A2, class B1, class B2>
   struct is_assignable< fusion::tuple<A1,A2>, fusion::tuple<B1,B2> >
       : integral_constant<bool, is_assignable<A1,B1>::value && is_assignable<A2,B2>::value >
         {};

Modified: sandbox/conversion/boost/conversion/type_traits/is_constructible.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/type_traits/is_constructible.hpp (original)
+++ sandbox/conversion/boost/conversion/type_traits/is_constructible.hpp 2011-07-16 07:54:57 EDT (Sat, 16 Jul 2011)
@@ -137,31 +137,38 @@
   namespace type_traits_detail_is_constructible {
 #if defined BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_DECLTYPE
 
+ // specific test functions for 0 args which are not templates
     template <class T>
     decltype((T(), true_type()))
     test0(T&);
     false_type
     test0(any);
 
+ // specific positive test functions for #Args>0
 #define M1(z,n,t) declval<A##n>()
 
-#define M0(z,n,t) \
+#define M0(z,n,t) \
   template <class T, BOOST_PP_ENUM_PARAMS(n, class A)> \
- decltype((T(BOOST_PP_ENUM(n, M1, ~)), true_type())) \
+ decltype((T(BOOST_PP_ENUM(n, M1, ~)), true_type())) \
   test##n(T&, BOOST_PP_ENUM_PARAMS(n, A));
 
 BOOST_PP_REPEAT_FROM_TO(1,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
 #undef M1
 
-#define M0(z,n,t) \
- template <BOOST_PP_ENUM_PARAMS(n, class A)> \
- false_type \
+ // specific negative test functions for #Args>0
+#define M0(z,n,t) \
+ template <BOOST_PP_ENUM_PARAMS(n, class A)> \
+ false_type \
   test##n(any, BOOST_PP_ENUM_PARAMS(n, A));
 
- BOOST_PP_REPEAT_FROM_TO(1,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
+BOOST_PP_REPEAT_FROM_TO(1,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
 
+
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference
+// depend is whether T(declval<Args>() ...) is well formed
+
 #define M1(z,n,t) declval<A##n>()
 #define M0(z,n,t) \
     template <bool, class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
@@ -175,27 +182,28 @@
 #undef M0
 #undef M1
 
-//////////////
-
-
 #elif defined BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_SIZEOF
 
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference
+// and at least 1 arg:
+// depend is whether X(declval<Args>() ...) is well formed
 
 #define M1(z,n,t) declval<A##n>()
 
 #define M0(z,n,t) \
-template<bool, class T, BOOST_PP_ENUM_PARAMS(n, class A)> \
-struct imp##n \
+template<bool, class T, BOOST_PP_ENUM_PARAMS(n, class A)> \
+struct imp##n \
 { \
     template<class X> \
- static type_traits_detail_is_constructible::yes_type \
- test(type_traits_detail_is_constructible::dummy<sizeof(X(BOOST_PP_ENUM(n, M1, ~)))>*); \
+ static type_traits_detail_is_constructible::yes_type \
+ test(type_traits_detail_is_constructible::dummy<sizeof(X(BOOST_PP_ENUM(n, M1, ~)))>*); \
                                                                                                     \
     template<class X> \
     static type_traits_detail_is_constructible::no_type \
     test(...); \
                                                                                                     \
- static const bool value = sizeof(test<T>(0)) == sizeof(type_traits_detail_is_constructible::yes_type); \
+ static const bool value = \
+ sizeof(test<T>(0)) == sizeof(type_traits_detail_is_constructible::yes_type); \
     typedef boost::integral_constant<bool,value> type; \
 };
 
@@ -205,6 +213,9 @@
 
 #if ! defined BOOST_CONVERSION_NO_IS_DEFAULT_CONSTRUCTIBLE
 
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference
+// and no arg:
+// depend is whether X() seen as a constructor call is well formed
     template<bool, class T>
     struct imp0
     {
@@ -225,38 +236,48 @@
 
 #else
 
-#define M0(z,n,t) \
-template<bool, class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
-struct imp##n \
- : boost::false_type \
-{ \
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference when
+// the compiler doesn't support any know technique that
+// allows to detect if X(declval<Args>() ...) is well formed
+// always false. The user of the library needs to specialize this trait for its owns types.
+
+#define M0(z,n,t) \
+template<bool, class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
+struct imp##n \
+ : boost::false_type \
+{ \
 };
 
     BOOST_PP_REPEAT_FROM_TO(0,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
 
 #endif
-//////////////
 
+// specialization for scalar or reference with 1 arg: depend is the arg is scalar
       template <class T>
       struct imp0<true, T>
           : public is_scalar<T>
           {};
 
+// specialization for scalar or reference with 1 arg: depend is the arg is convertible to the type
       template <class T, class A1>
       struct imp1<true, T, A1>
           : public is_convertible<A1, T>
           {};
+// specialization for scalar or reference with multiple args: always false
 
-#define M0(z,n,t) \
-template <class T, BOOST_PP_ENUM_PARAMS(n, class A)>\
+#define M0(z,n,t) \
+template <class T, BOOST_PP_ENUM_PARAMS(n, class A)> \
 struct imp##n<true, T, BOOST_PP_ENUM_PARAMS(n, A) > \
- : public false_type \
+ : public false_type \
   {};
 
 BOOST_PP_REPEAT_FROM_TO(2,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
 
+// specialization for NOT void, abstract, function or any of the parameters is void:
+ // depends on whether the type is scalar or reference
+
 #define M0(z,n,t) \
   template <bool, class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
   struct void_check##n \
@@ -267,6 +288,7 @@
 BOOST_PP_REPEAT(BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
 
+// specialization for void, abstract, function or any of the parameters is void: always false
 #define M0(z,n,t) \
   template <class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
   struct void_check##n<true, T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, A)> \
@@ -277,6 +299,7 @@
 #undef M0
 
 
+// specialization for unbounded arrays: always false
 
 #define M0(z,n,t) \
   template <class A BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
@@ -289,12 +312,13 @@
 
   }
 
-#if 1
+
+// defines is_constructible, depending on whether T is void, abstract, function or any of the parameters is void
 #define M1(z,n,t) || is_void<A##n>::value
 
 #define M0(z,n,t) \
   template <class T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class A)> \
- struct is_constructible<T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, A)> \
+ struct is_constructible<T BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, A)> \
     : public type_traits_detail_is_constructible::void_check##n<is_void<T>::value \
               || is_abstract<T>::value || is_function<T>::value \
               BOOST_PP_REPEAT(n, M1, ~), \
@@ -303,18 +327,19 @@
 
 BOOST_PP_REPEAT(BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)
 #undef M0
-#endif
 
   namespace type_traits_detail_is_constructible {
+ // specialization for bounded arrays without arguments: depends on the type
     template <class A, std::size_t N>
     struct imp0<false, A[N]>
         : public boost::is_constructible<typename remove_all_extents<A>::type>
         {};
 
-#define M0(z,n,t) \
- template <class A, std::size_t N, BOOST_PP_ENUM_PARAMS(n, class A)> \
- struct imp##n<false, A[N], BOOST_PP_ENUM_PARAMS(n, A)> \
- : public false_type \
+ // specialization for bounded arrays with arguments: always false
+#define M0(z,n,t) \
+ template <class A, std::size_t N, BOOST_PP_ENUM_PARAMS(n, class A)> \
+ struct imp##n<false, A[N], BOOST_PP_ENUM_PARAMS(n, A)> \
+ : public false_type \
       {};
 
     BOOST_PP_REPEAT_FROM_TO(1,BOOST_CONVERSION_TT_IS_CONSTRUCTIBLE_ARITY_MAX, M0, ~)

Modified: sandbox/conversion/boost/conversion/type_traits/is_explicitly_convertible.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/type_traits/is_explicitly_convertible.hpp (original)
+++ sandbox/conversion/boost/conversion/type_traits/is_explicitly_convertible.hpp 2011-07-16 07:54:57 EDT (Sat, 16 Jul 2011)
@@ -16,30 +16,221 @@
 #ifndef BOOST_CONVERSION_TT_IS_EXPLICITLY_CONVERTIBLE_HPP
 #define BOOST_CONVERSION_TT_IS_EXPLICITLY_CONVERTIBLE_HPP
 
-#include <boost/conversion/type_traits/is_constructible.hpp>
-
+#if defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
 namespace boost {
 
   /**
- * States if @c Source is explicitly convertible to @c Target.
+ * States if @c Source is is_explicitly_convertible to @c Target.
    *
- * Condition: @c is_constructible<Target, Source>::value is @c true.
+ * Condition: @c true_type if and only if the following would be well-formed for
+ * some invented function f:
    *
+ * Target f() {
+ * return static_cast<Target>(decval<Source>());
+ * }
+ *
+ * @Requires @c Source and @ Target must be complete types, (possibly cv-qualified) void, or arrays of unknown bound.
    */
+ template < class Source, class Target>
+ struct is_explicitly_convertible
+ {};
+
+ //! Macro stating if the compiler doesn't support the features needed to define the @c is_explicitly_convertible type trait.
+ #define BOOST_CONVERSION_NO_IS_EXPLICIT_CONVERTIBLE
+
+
+}
+#else
+#include <boost/conversion/type_traits/is_constructible.hpp>
+
+#if 0
+
+
+namespace boost {
+
   template <class Source, class Target>
   struct is_explicitly_convertible : is_constructible<Target, Source> {};
-
-#if !defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
- /**
- * Specialization for void source
- */
   template <class Target>
   struct is_explicitly_convertible<void,Target> : false_type {};
-#endif
 
 
 }
 
+#else
+
+#include <boost/config.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/utility/declval.hpp>
+#include <cstddef>
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/common_type.hpp>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_abstract.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/remove_all_extents.hpp>
+
+
+#if ! defined BOOST_NO_DECLTYPE
+ #if defined _MSC_VER
+ #if ! defined BOOST_NO_SFINAE_EXPR
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_SIZEOF
+ #else
+ #define BOOST_CONVERSION_NO_IS_EXPLICIT_CONVERTIBLE
+ #endif
+ #elif defined __clang__
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_DECLTYPE
+ #elif defined __GNUC__
+ #if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )
+ #if ! defined BOOST_NO_SFINAE_EXPR
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_SIZEOF
+ #else
+ #define BOOST_CONVERSION_NO_IS_EXPLICIT_CONVERTIBLE
+ #endif
+ #else
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_DECLTYPE
+ #endif
+ #else
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_DECLTYPE
+ #endif
+#elif ! defined BOOST_NO_SFINAE_EXPR
+ #define BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_SIZEOF
+#else
+ #define BOOST_CONVERSION_NO_IS_EXPLICIT_CONVERTIBLE
+#endif
+
+#if defined BOOST_CONVERSION_NO_IS_EXPLICIT_CONVERTIBLE
+//#error
+#endif
+namespace boost {
+ namespace type_traits_detail_is_explicitly_convertible {
+ //! type used instead of ... to accept any type
+ struct any {
+ template <typename T>
+ any(T);
+ };
+
+ //! type useful to compare with the sizeof
+ typedef char yes_type;
+ //! type useful to compare with the sizeof
+ struct no_type { char a[2]; };
+
+ //! type useful to accept a sizeof as parameter
+ template<std::size_t N>
+ struct dummy;
+ }
+
+
+ namespace type_traits_detail_is_explicitly_convertible {
+#if defined BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_DECLTYPE
+
+ // specific positive test functions
+ template <class S, class T>
+ decltype((static_cast<T>(declval<S>()), true_type()))
+ test(T&, S);
+
+ // specific negative test functions
+ template <class S>
+ false_type
+ test(any, S);
+
+// specialization for NOT void, abstract, function or any of the parameters is void, scalar or reference
+// depends on whether static_cast<T>(declval<S>()) is well formed
+
+ template <bool, class S, class T>
+ struct imp
+ : public common_type<decltype(test(declval<T&>(), declval<S>()))>::type
+ {};
+
+
+#elif defined BOOST_CONVERSION_IS_CONSTRUCTIBLE_USES_SIZEOF
+
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference
+// depends on whether static_cast<T>(declval<Args>() ...) is well formed
+
+template<bool, class S, class T>
+struct imp
+{
+ template<class X>
+ static type_traits_detail_is_explicitly_convertible::yes_type
+ test(type_traits_detail_is_explicitly_convertible::dummy<sizeof(static_cast<X>(declval<S>()))>*);
+
+ template<class X>
+ static type_traits_detail_is_explicitly_convertible::no_type
+ test(...);
+
+ static const bool value =
+ sizeof(test<T>(0)) == sizeof(type_traits_detail_is_explicitly_convertible::yes_type);
+ typedef boost::integral_constant<bool,value> type;
+};
+
+
+#else
+
+// specialization for void, abstract, function or any of the parameters is void, scalar or reference when
+// the compiler doesn't support any know technique that
+// allows to detect if static_cast<Target>(declval<Source>()) is well formed
+// always false. The user of the library needs to specialize this trait for its owns types.
+
+template<bool, class S, class T>
+struct imp
+ : boost::false_type
+{
+};
+
+
+#endif
+
+
+// specialization for scalar or reference: depend on the source is convertible to the target
+ template <class S, class T>
+ struct imp<true, S, T>
+ : public integral_constant<bool,is_constructible<T,S>::value || imp<false,S,T>::value >
+ {};
+
+// specialization for NOT void, abstract, function or any of the parameters is void:
+ // depends on whether the type is scalar or reference
+
+ template <bool, class S, class T>
+ struct void_check
+ : public imp<is_scalar<T>::value || is_reference<T>::value,
+ S, T>
+ {};
+
+
+// specialization for void, abstract, function or any of the parameters is void: always false
+ template <class S, class T>
+ struct void_check<true, S, T>
+ : public false_type
+ {};
+
+
+// specialization for unbounded arrays: always false
+
+ template <class S, class A>
+ struct imp<false, S, A[]>
+ : public false_type
+ {};
+
+ }
+
+
+// defines is_explicitly_convertible, depending on whether T is void, abstract, function or any of the parameters is void
+ template <class S, class T>
+ struct is_explicitly_convertible
+ : public type_traits_detail_is_explicitly_convertible::void_check<is_void<T>::value
+ || is_abstract<T>::value || is_function<T>::value
+ || is_void<S>::value,
+ S, T>
+ {};
+
 
+}
+
+#endif
+#endif
 #endif
 

Modified: sandbox/conversion/boost/conversion/type_traits/std/utility.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/type_traits/std/utility.hpp (original)
+++ sandbox/conversion/boost/conversion/type_traits/std/utility.hpp 2011-07-16 07:54:57 EDT (Sat, 16 Jul 2011)
@@ -17,6 +17,7 @@
 
 #include <boost/conversion/type_traits/is_assignable.hpp>
 #include <boost/conversion/type_traits/is_constructible.hpp>
+#include <boost/conversion/type_traits/is_explicitly_convertible.hpp>
 #include <utility>
 
 
@@ -47,6 +48,10 @@
   struct is_constructible< std::pair<A1,A2>, std::pair<B1,B2> >
     : integral_constant<bool, is_constructible<A1,B1>::value && is_constructible<A2,B2>::value >
       {};
+ template <class A1, class A2, class B1, class B2>
+ struct is_explicitly_convertible< std::pair<A1,A2>, std::pair<B1,B2> >
+ : integral_constant<bool, is_explicitly_convertible<A1,B1>::value && is_explicitly_convertible<A2,B2>::value >
+ {};
 
   template <class A1, class A2, class B1, class B2>
   struct is_assignable< std::pair<A1,A2>, std::pair<B1,B2> >


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk