Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r72376 - in sandbox/conversion/boost/conversion: . fp
From: vicente.botet_at_[hidden]
Date: 2011-06-03 10:39:55


Author: viboes
Date: 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
New Revision: 72376
URL: http://svn.boost.org/trac/boost/changeset/72376

Log:
Conversion: Start adding enabling condition SFINAE
Text files modified:
   sandbox/conversion/boost/conversion/assign_to.hpp | 57 +++++++++++++++++++++++++++++++++------
   sandbox/conversion/boost/conversion/convert_to.hpp | 53 +++++++++++++++++++++++++-----------
   sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp | 16 ++++------
   sandbox/conversion/boost/conversion/fp/convert_to.hpp | 3 +
   sandbox/conversion/boost/conversion/try_assign_to.hpp | 4 --
   sandbox/conversion/boost/conversion/try_convert_to.hpp | 5 --
   6 files changed, 96 insertions(+), 42 deletions(-)

Modified: sandbox/conversion/boost/conversion/assign_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/assign_to.hpp (original)
+++ sandbox/conversion/boost/conversion/assign_to.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -10,11 +10,15 @@
 /*!
  @file
  @brief
- Defines the free function @c assign_to.
+ Defines the free function @c assign_to and its customization point @c assigner.
 
 The function @c assign_to assigns the @c from parameter to the @c to parameter.
-The default implementation uses the @c convert_to to convert the source to the target and use the copy assignment of the @c Target class.
+The default implementation of the @c assigner uses the @c convert_to to convert the source to the target and
+uses the copy assignment of the @c Target class.
+ */
 
+#if defined(BOOST_CONVERSION_DOUBLE_CP)
+/**
 A user adapting another type could need to specialize the @c assign_to free function if the default behavior is not satisfactory.
 The user can add the @c assign_to overloading on the namespace of the Source or Target classes.
 But sometimes as it is the case for the standard classes, we can not add new functions on the std namespace,
@@ -22,12 +26,17 @@
 the @c boost::conversion::overload_workaround namespace.
 
  */
+#endif
 
 #ifndef BOOST_CONVERSION_ASSIGN_TO_HPP
 #define BOOST_CONVERSION_ASSIGN_TO_HPP
 
 #include <cstddef> //for std::size_t
 #include <boost/conversion/convert_to.hpp>
+#include <boost/utility/enable_if.hpp>
+//#include <boost/conversion/tt/is_copy_constructible.hpp>
+//#include <boost/conversion/tt/is_copy_constructible.hpp>
+//#include <boost/conversion/tt/is_extrinsic_convertible.hpp>
 
 namespace boost {
   namespace conversion {
@@ -35,19 +44,48 @@
     //! @tparam Target target type of the conversion.
     //! @tparam Source source type of the conversion.
     //! @tparam Enable A dummy template parameter that can be used for SFINAE.
+
+#if defined(BOOST_CONVERSION_ENABLE_CND)
+ template < typename Target, typename Source, class Enable = void>
+ struct assigner;
+ template < typename Target, typename Source>
+ struct assigner<Target, Source
+ , typename enable_if_c<
+ is_copy_constructible<Target>::value
+ && is_extrinsic_convertible<Source,Target>::value
+ && ! is_assignable<Source,Target>::value
+ >::type
+ >
+#else
     template < typename Target, typename Source, class Enable = void>
     struct assigner
+#endif
     {
       //! @Requires @c Target must be CopyAssinable and @c ::boost::conversion::convert_to<Target>(from) must be well formed.
- //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assignment operator.
- //! @Throws Whatever the underlying assignment operator of the @c Target class throws.
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assignment operator.
+ //! @Throws Whatever the underlying assignment operator of the @c Target class throws.
       Target& operator()(Target& to, const Source& from)
       {
         to = ::boost::conversion::convert_to<Target>(from);
         return to;
       }
     };
-
+#if defined(BOOST_CONVERSION_ENABLE_CND)
+ template < typename Target, typename Source>
+ struct assigner<Target,Source
+ , typename enable_if<is_assignable<Target, Source> >::type
+ >
+ {
+ //! @Requires @c Target must be Assinable from Source.
+ //! @Effects Assigns the @c from parameter to the @c to parameter.
+ //! @Throws Whatever the underlying assignment operator of the @c Target class throws.
+ Target& operator()(Target& to, const Source& from)
+ {
+ to = from;
+ return to;
+ }
+ };
+#endif
     //! partial specialization for c-array types.
     template < typename Target, typename Source, std::size_t N >
     struct assigner<Target[N],Source[N],void>
@@ -87,7 +125,7 @@
     Target& assign_to_impl(Target& to, const Source& from)
     {
       using namespace boost::conversion_impl_2;
- //use boost::conversion::assign_to if ADL fails
+ //use boost::conversion_impl_2::assign_to if ADL fails
       return assign_to(to, from);
     }
   }
@@ -96,6 +134,8 @@
   namespace conversion {
 
     //! @brief Extrinsic assign function.
+ //! Assigns the @c Source parameter to the @c Target one.
+ //! This function can be seen as an emulation of free function overload of the assignment operator.
     //! @tparam Target target type of the conversion.
     //! @tparam Source source type of the conversion.
     //!
@@ -103,9 +143,8 @@
     //! @Param{to,target of the conversion}
     //! @Param{from,source of the conversion}
 
- //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assignment operator.
- //! @Throws Whatever the underlying the assignment operator of the @c Target class throws..
- //! This function can be overloaded by the user.
+ //! @Effects The ones of the assigner customization point.
+ //! @Throws Whatever the assigner customization point throws.
 
     template <typename Target, typename Source>
     Target& assign_to(Target& to, const Source& from)

Modified: sandbox/conversion/boost/conversion/convert_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/convert_to.hpp (original)
+++ sandbox/conversion/boost/conversion/convert_to.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -9,13 +9,16 @@
 //////////////////////////////////////////////////////////////////////////////
 /**
  * @file
- * @brief Defines the free function @c convert_to.
+ * @brief Defines the free function @c convert_to and its customization point @c converter.
  *
  * The @c convert_to function converts the @c from parameter to a @c Target type.
- * The default implementation applies the conversion @c Target operator of the @c Source class or
+ * The default implementation of @ converter applies the conversion @c Target operator of the @c Source class or
  * the copy constructor of the @c Target class.
  * Of course if both exist the conversion is ambiguous.
  *
+ */
+#if defined(BOOST_CONVERSION_DOUBLE_CP)
+/**
  * A user adapting another type could need to overload the @c convert_to free function
  * if the default behavior is not satisfactory.
  * The user can add the @c convert_to overloading on any namespace found by ADL from the @c Source or the @c Target.
@@ -26,14 +29,19 @@
  * In this case the user can partially specialize the @c boost::conversion::overload_workaround::convert_to struct.
  *
  */
+#endif
 
 #ifndef BOOST_CONVERSION_CONVERT_TO_HPP
 #define BOOST_CONVERSION_CONVERT_TO_HPP
 
-#include <boost/mpl/bool.hpp>
+//#include <boost/mpl/bool.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+//#include <boost/conversion/tt/is_explicit_constructible.hpp>
+//#include <boost/conversion/tt/is_extrinsic_convertible.hpp>
 
 namespace boost {
+
   namespace conversion {
 #if defined(BOOST_CONVERSION_DOUBLE_CP)
     namespace dummy {
@@ -57,15 +65,28 @@
     //! The nested type @c type is a mpl boolean which default to @c mpl::false_.
     //! Specific specialization would make this meta-function to be @c mpl::true_.
     template <typename T, typename Enabled=void>
- struct enable_functor : mpl::false_ {};
+ struct enable_functor : false_type {};
 
     //! Customization point for @convert_to.
     //! @tparam Target target type of the conversion.
     //! @tparam Source source type of the conversion.
     //! @tparam Enable A dummy template parameter that can be used for SFINAE.
 
+#if defined(BOOST_CONVERSION_ENABLE_CND)
+ template < typename Target, typename Source, class Enable = void >
+ struct converter;
+ template < typename Target, typename Source >
+ struct converter<Target, Source
+ , typename enable_if_c<
+ is_explicit_constructible<Target, const Source&>::value
+ or is_explicitly_convertible<Source,Target>::value
+ >::type
+ >
+#else
     template < typename Target, typename Source, class Enable = void >
- struct converter {
+ struct converter
+#endif
+ {
       //! @Requires @c Target must be CopyConstructible from @c Source or @c Source convertible to @c Target
       //! @Effects Converts the @c from parameter to an instance of the @c Target type, using by default the conversion operator or copy constructor.
       //! @Throws Whatever the underlying conversion @c Target operator of the @c Source class or the copy constructor of the @c Target class throws.
@@ -84,16 +105,18 @@
       //! @Throws Whatever the underlying conversion @c Target operator of the @c Source class or the copy constructor of the @c Target class throws.
       //! Forwards the call to the overload workaround, which can yet be specialized by the user for standard C++ types.
       template < typename Target, typename Source >
- Target convert_to(const Source& from, dummy::type_tag<Target> const&) {
+ Target convert_to(const Source& from, dummy::type_tag<Target> const&)
+ {
         return conversion::converter<Target,Source>()(from);
       }
     }
 
     namespace impl {
       template <typename Target, typename Source>
- Target convert_to_impl(Source const& from) {
+ Target convert_to_impl(Source const& from)
+ {
         using namespace boost::conversion::impl_2;
- //use boost::conversion::convert_to if ADL fails
+ //use boost::conversion::impl_2::convert_to if ADL fails
         return convert_to(from, dummy::type_tag<Target>());
       }
     }
@@ -101,19 +124,16 @@
 #endif
 
     //! @brief Extrinsic conversion function.
- //!
+ //! Converts the @c from parameter to an instance of the @c Target type.
+ //! This function can be seen as an emulation of free function overload of the conversion operator.
     //! @tparam Target target type of the conversion.
     //! @tparam Source source type of the conversion.
     //!
     //! @Params
     //! @Param{source,source of the conversion}
     //!
- //! @Effects Converts the @c from parameter to an instance of the @c Target type, using by default the conversion operator or copy constructor.
- //! @Throws Whatever the underlying conversion @c Target operator of the @c Source class or the copy constructor of the @c Target class throws.
- //!
- //! This function can be overloaded by the user.
- //! A trick is used to overload on the return type by adding a defaulted dummy parameter.
- //! Specializations must overload on @c dummy::type_tag<Target>
+ //! @Returns The result of @c converter customization point.
+ //! @Throws Whatever the @c converter call operator throws.
     //!
     //! This function doesn't participate on overload resolution when @c conversion::enable_functor<Source>::type is mpl::true_.
     template <typename Target, typename Source>
@@ -122,7 +142,8 @@
 #else
     Target
 #endif
- convert_to(Source const& from) {
+ convert_to(Source const& from)
+ {
 #if defined(BOOST_CONVERSION_DOUBLE_CP)
       return boost::conversion::impl::convert_to_impl<Target>(from);
 #else

Modified: sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp (original)
+++ sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -45,10 +45,9 @@
     template < typename Target, typename Source, typename Fallback, class Enable = void>
     struct converter_or_fallbacker {
       //!
- //! @Requires @c Target must be CopyConstructible and @c ::boost::conversion::convert_to<Target>(from) must be well formed.
- //! @Effects Converts the @c from parameter to an instance of the @c Target type, using by default the conversion operator or copy constructor.
- //! @Returns the converted value if the conversion succeeds or the fallback.
- //! @NoThrow
+ //! @Requires @c Fallback must be convertible to @c Target and @c ::boost::conversion::convert_to<Target>(from) must be well formed.
+ //! @Returns The converted value if the conversion succeeds or the fallback.
+ //! @Throws Whatever the conversion from @c Fallback to @c Target can throws when the conversion fails.
       Target operator()(const Source& val, Fallback const& fallback)
       {
         try
@@ -82,23 +81,22 @@
       template <typename Target, typename Source, typename Fallback>
       Target convert_to_or_fallback_impl(Source const& from, Fallback const& fallback) {
         using namespace boost::conversion::impl_2;
- //use boost::conversion::convert_to_or_fallback if ADL fails
+ //use boost::conversion::impl_2::convert_to_or_fallback if ADL fails
         return convert_to_or_fallback(from, fallback, dummy::type_tag<Target>());
       }
     }
 #endif
 #endif
 
+ //! @brief Extrinsic conversion function with fallback.
+ //! Converts the @c from parameter to an instance of the @c Target type.
     //! @tparam Target target type of the conversion.
     //! @tparam Source source type of the conversion.
     //! @tparam Fallback type of the fallback value which must be explicitly convertible to @c Target.
     //!
- //! @Effects Converts the @c from parameter to an instance of the @c Target type, using by default the conversion operator or copy constructor.
     //! @Returns the converted value if the conversion succeeds or the fallback.
- //! @NoThrow
+ //! @Throws Whatever the conversion from @c Fallback to @c Target can throws when the conversion fails.
     //!
- //! This function can be partially specialized on compilers supporting it.
- //! A trick is used to partially specialize on the return type by adding a dummy parameter.
     template <typename Target, typename Source, typename Fallback>
     Target convert_to_or_fallback(Source const& from, Fallback const& fallback) {
 #if defined(BOOST_CONVERSION_DOUBLE_CP)

Modified: sandbox/conversion/boost/conversion/fp/convert_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/fp/convert_to.hpp (original)
+++ sandbox/conversion/boost/conversion/fp/convert_to.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -26,6 +26,7 @@
 #include <boost/proto/transform/lazy.hpp>
 #include <boost/phoenix/core/is_actor.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/integral_constant.hpp>
 
 #if !defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
 
@@ -44,7 +45,7 @@
 
     //! The nested type @ type is @c mpl::true_.
     template <typename T>
- struct enable_functor<T, typename enable_if<phoenix::is_actor<T> >::type> : mpl::true_ {};
+ struct enable_functor<T, typename enable_if<phoenix::is_actor<T> >::type> : true_type {};
 
     namespace detail {
       struct convert_to_eval

Modified: sandbox/conversion/boost/conversion/try_assign_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/try_assign_to.hpp (original)
+++ sandbox/conversion/boost/conversion/try_assign_to.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -113,7 +113,7 @@
     bool try_assign_to_impl(Target& to, const Source& from)
     {
       using namespace boost::conversion_impl_2;
- //use boost::conversion::try_assign_to if ADL fails
+ //use boost::conversion_impl_2::try_assign_to if ADL fails
       return try_assign_to(to, from);
     }
   }
@@ -126,8 +126,6 @@
     //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assignment operator.
     //! @NoThrow
     //! @Returns the converted value if success or the fallback when conversion fails.
- //!
- //! This function can be partially specialized on compilers supporting it.
     template <typename Target, typename Source>
     bool try_assign_to(Target& to, const Source& from)
     {

Modified: sandbox/conversion/boost/conversion/try_convert_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/try_convert_to.hpp (original)
+++ sandbox/conversion/boost/conversion/try_convert_to.hpp 2011-06-03 10:39:54 EDT (Fri, 03 Jun 2011)
@@ -81,7 +81,7 @@
       template <typename Target, typename Source>
       optional<Target> try_convert_to_impl(Source const& from) {
         using namespace boost::conversion::impl_2;
- //use boost::conversion::try_convert_to if ADL fails
+ //use boost::conversion::impl_2::try_convert_to if ADL fails
         return try_convert_to(from, dummy::type_tag<Target>());
       }
     }
@@ -94,9 +94,6 @@
     //! @Effects Converts the @c from parameter to an instance of the @c Target type, using by default the conversion operator or copy constructor.
     //! @NoThrow
     //! @Returns A optional<Target> uninitialized when conversion fails.
- //!
- //! This function can be overloaded by the user for specific types.
- //! A trick is used to partially specialize on the return type by adding a dummy parameter.
     template <typename Target, typename Source>
     optional<Target> try_convert_to(Source const& from) {
 #if defined(BOOST_CONVERSION_DOUBLE_CP)


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