|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r71905 - in sandbox/conversion/boost/conversion: . boost std
From: vicente.botet_at_[hidden]
Date: 2011-05-12 16:33:12
Author: viboes
Date: 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
New Revision: 71905
URL: http://svn.boost.org/trac/boost/changeset/71905
Log:
Added some new functions discusses on the ML
Added:
sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp (contents, props changed)
sandbox/conversion/boost/conversion/try_assign_to.hpp (contents, props changed)
sandbox/conversion/boost/conversion/try_convert_to.hpp (contents, props changed)
Text files modified:
sandbox/conversion/boost/conversion/assign_to.hpp | 26 +++----
sandbox/conversion/boost/conversion/boost/optional.hpp | 99 +++++++++++++++++++---------
sandbox/conversion/boost/conversion/convert_to.hpp | 15 ++++
sandbox/conversion/boost/conversion/include.hpp | 3
sandbox/conversion/boost/conversion/std/string.hpp | 137 ++++++++++++++++++++++++++++-----------
5 files changed, 194 insertions(+), 86 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-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -35,15 +35,14 @@
#include <boost/conversion/convert_to.hpp>
namespace boost {
- #ifdef FWD
- template <typename Target, typename Source>
- Target& assign_to(Target& to, const Source& from, boost::dummy::base_tag<Target> const& p=boost::dummy::base_tag<Target>());
- #endif
namespace conversion {
namespace partial_specialization_workaround {
+ //! struct used when overloading can not be applied.
template < typename To, typename From >
struct assign_to
{
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
+ //! @Throws Whatever the underlying the assignment operator of the @c To class throws..
inline static To& apply(To& to, const From& from)
{
to = from;
@@ -53,15 +52,13 @@
template < typename To, typename From, std::size_t N >
struct assign_to<To[N],From[N]>
{
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator on each one of the array elements.
+ //! @Throws Whatever the underlying the assignment operator of the @c To class throws..
inline static To*& apply(To(&to)[N], const From(& from)[N])
{
for (std::size_t i = 0; i < N; ++i)
{
- #ifdef FWD
- boost::assign_to<To>(to[i] , from[i]);
- #else
to[i] = boost::convert_to<To>(from[i]);
- #endif
}
return to;
}
@@ -69,6 +66,11 @@
}
+ //! @brief Default @c assign_to overload, used when ADL fails.
+ //!
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
+ //! @Throws Whatever the underlying the assignment operator of the @c To class throws..
+ //! Forwards the call to the overload workarround, which can yet be specialized by the user for standard C++ types.
template < typename To, typename From >
To& assign_to(To& to, const From& from, dummy::type_tag<To> const&)
{
@@ -90,13 +92,9 @@
//! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
//! @Throws Whatever the underlying the assignment operator of the @c To class throws..
- //! This function can be partialy specialized on compilers supporting it.
+ //! This function can be partially specialized on compilers supporting it.
template <typename Target, typename Source>
- Target& assign_to(Target& to, const Source& from, boost::dummy::base_tag<Target> const& p
-#ifndef FWD
- =boost::dummy::base_tag<Target>()
-#endif
- )
+ Target& assign_to(Target& to, const Source& from, boost::dummy::base_tag<Target> const& p =boost::dummy::base_tag<Target>())
{
(void)p;
return conversion_impl::assign_to_impl<Target, Source>(to, from);
Modified: sandbox/conversion/boost/conversion/boost/optional.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/boost/optional.hpp (original)
+++ sandbox/conversion/boost/conversion/boost/optional.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -26,42 +26,75 @@
namespace boost {
- #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
- namespace conversion { namespace partial_specialization_workaround {
- template < class Target, class Source>
- struct convert_to< optional<Target>, optional<Source> > {
- inline static optional<Target> apply(optional<Source> const & from)
- {
- return (from?optional<Target>(boost::convert_to<Target>(from.get())):optional<Target>());
- }
- };
- template < class Target, class Source>
- struct assign_to< optional<Target>, optional<Source> > {
- inline static optional<Target>& apply(optional<Target>& to, const optional<Source>& from)
- {
- to = from?boost::convert_to<Target>(from.get()):optional<Target>();
- return to;
- }
- };
-
- }}
- #else
- template < class Target, class Source>
- inline optional<Target> convert_to(optional<Source> const & from
- , boost::dummy::type_tag<optional<Target> > const&)
- {
- return (from?optional<Target>(boost::convert_to<Target>(from.get())):optional<Target>());
+ #ifdef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+ namespace conversion {
+ namespace partial_specialization_workaround {
+ template < class Target, class Source>
+ struct convert_to< optional<Target>, optional<Source> > {
+ inline static optional<Target> apply(optional<Source> const & from)
+ {
+ return (from?optional<Target>(boost::convert_to<Target>(from.get())):optional<Target>());
+ }
+ };
+
+ template < class Target, class Source>
+ struct convert_to< optional<Target>, Source >
+ {
+ inline static optional<Target> apply(Source const & from)
+ {
+ try
+ {
+ return optional<Target>(boost::convert_to<Target>(from));
+ }
+ catch (...)
+ {
+ return optional<Target>();
+ }
+ }
+ };
+
+ template < class Target, class Source>
+ struct assign_to< optional<Target>, optional<Source> > {
+ inline static optional<Target>& apply(optional<Target>& to, const optional<Source>& from)
+ {
+ to = from?boost::convert_to<Target>(from.get()):optional<Target>();
+ return to;
+ }
+ };
+
}
-
- template < class Target, class Source>
- inline optional<Target>& assign_to(optional<Target>& to, const optional<Source>& from
- , boost::dummy::type_tag<optional<Target> > const&
- )
+ }
+#else
+ template < class Target, class Source>
+ inline optional<Target> convert_to(optional<Source> const & from
+ , boost::dummy::type_tag<optional<Target> > const&)
+ {
+ return (from?optional<Target>(boost::convert_to<Target>(from.get())):optional<Target>());
+ }
+
+ template < class Target, class Source>
+ inline optional<Target> convert_to(Source const & from
+ , boost::dummy::type_tag<optional<Target> > const&)
+ {
+ try
{
- to = from?boost::convert_to<Target>(from.get()):optional<Target>();
- return to;
+ return optional<Target>(boost::convert_to<Target>(from));
+ }
+ catch (...)
+ {
+ return optional<Target>();
}
- #endif
+ }
+
+ template < class Target, class Source>
+ inline optional<Target>& assign_to(optional<Target>& to, const optional<Source>& from
+ , boost::dummy::type_tag<optional<Target> > const&
+ )
+ {
+ to = from?boost::convert_to<Target>(from.get()):optional<Target>();
+ return to;
+ }
+#endif
}
#endif
Modified: sandbox/conversion/boost/conversion/convert_to.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/convert_to.hpp (original)
+++ sandbox/conversion/boost/conversion/convert_to.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -34,13 +34,19 @@
namespace boost {
namespace dummy {
+ //! base tag used to overload a function returning T.
template <typename T> struct base_tag { };
+ //! base tag used to overload a function returning T that takes precedence respect to &c base_tag<T>.
template <typename T> struct type_tag : public base_tag<T> {};
}
namespace conversion {
namespace partial_specialization_workaround {
+ //! struct used when overloading can not be applied.
+
template < typename To, typename From >
struct convert_to {
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @Throws Whatever the underlying conversion @c To operator of the @c From class or the copy constructor of the @c To class throws.
inline static To apply(const From& val)
{
return To((val));
@@ -48,6 +54,11 @@
};
}
+ //! @brief Default @c convert_to_or_fallback overload, used when ADL fails.
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @Throws Whatever the underlying conversion @c To operator of the @c From class or the copy constructor of the @c To class throws.
+ //! Forwards the call to the overload workarround, which can yet be specialized by the user for standard C++ types.
template < typename To, typename From >
To convert_to(const From& val, dummy::type_tag<To> const&) {
return conversion::partial_specialization_workaround::convert_to<To,From>::apply(val);
@@ -67,7 +78,9 @@
//!
//! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
//! @Throws Whatever the underlying conversion @c To operator of the @c From class or the copy constructor of the @c To class throws.
- //! This function can be partialy specialized on compilers supporting it. A trick is used to partialy specialize on the return type by adding a dummy parameter.
+ //!
+ //! 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>
Target convert_to(Source const& from, boost::dummy::base_tag<Target> const& p=boost::dummy::base_tag<Target>()) {
(void)p;
Added: sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp
==============================================================================
--- (empty file)
+++ sandbox/conversion/boost/conversion/convert_to_or_fallback.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2011. 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)
+//
+// See http://www.boost.org/libs/conversion for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+/*!
+ \file
+ \brief
+ Defines the free function @c convert_to_or_fallback.
+
+ The @c convert_to_or_fallback function converts the @c from parameter to a @c To type. If the conversion fails the fallback value is used to construct a To @c instance.
+
+ The default implementation applies the conversion @c To operator of the @c From class or
+ the copy constructor of the @c To class. When an exception is thrown the falback is returned.
+ Of course if both exist the conversion is ambiguous.
+ A user adapting another type could need to specialize the @c convert_to_or_fallback free function if the default behavior is not satisfactory.
+
+The user can add the @c convert_to_or_fallback overloading on any namespace found by ADL from the @c Source or the @c Target.
+A trick is used to overload on the return type by adding a dummy parameter having the Target.
+
+But sometimes, as it is the case for the standard classes,
+we can not add new functions on the std namespace, so we need a different technique.
+
+The technique consists in partially specialize on the function @c convert_to_or_fallback on the @c boost::conversion namespace.
+For compilers for which we can not partially specialize a function a trick is used: instead of calling directly to the @c convert_to_or_fallback member function,
+@c convert_to_or_fallback calls to the static operation apply on a class with the same name in the namespace @c partial_specialization_workaround.
+Thus the user can specialize partially this class.
+ */
+
+#ifndef BOOST_CONVERSION_CONVERT_TO_HPP
+#define BOOST_CONVERSION_CONVERT_TO_HPP
+
+#include <boost/conversion/convert_to.hpp>
+
+namespace boost {
+ namespace conversion {
+ namespace partial_specialization_workaround {
+ //! <c>struct convert_to_or_fallback</c> used when overloading can not be applied.
+ //! This struct can be specialized by the user.
+ template < typename To, typename From, typename Fallback>
+ struct convert_to_or_fallback {
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @Returns the converted value if the conversion suceeds or the fallback.
+ //! @NoThows
+ inline static To apply(const From& val, Fallback const& fallback)
+ {
+ try
+ {
+ return boost::convert_to<To>(val);
+ }
+ catch (...)
+ {
+ return To((fallback));
+ }
+ }
+ };
+ }
+
+ //! @brief Default @c convert_to_or_fallback overload, used when ADL fails.
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @Returns the converted value if the conversion suceeds or the fallback.
+ //! @NoThows
+ //! Forwards the call to the overload workarround, which can yet be specialized by the user for standard C++ types.
+ template < typename To, typename From, typename Fallback >
+ To convert_to_or_fallback(const From& val, Fallback const& fallback, dummy::type_tag<To> const&) {
+ return conversion::partial_specialization_workaround::convert_to_or_fallback<To,From>::apply(val, fallback);
+ }
+ }
+#if !defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
+ namespace conversion_impl {
+ template <typename Target, typename Source, typename Fallback>
+ Target convert_to_or_fallback_impl(Source const& from, Fallback const& fallback) {
+ using namespace boost::conversion;
+ //use boost::conversion::convert_to_or_fallback if ADL fails
+ return convert_to_or_fallback(from, fallback, boost::dummy::type_tag<Target>());
+ }
+ }
+#endif
+
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @Returns the converted value if the conversion suceeds or the fallback.
+ //! @NoThows
+ //!
+ //! 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, boost::dummy::base_tag<Target> const& p=boost::dummy::base_tag<Target>()) {
+ (void)p;
+ return conversion_impl::convert_to_or_fallback_impl<Target>(from, fallback);
+ }
+
+}
+
+#endif
+
Modified: sandbox/conversion/boost/conversion/include.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/include.hpp (original)
+++ sandbox/conversion/boost/conversion/include.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -22,5 +22,8 @@
#include <boost/conversion/convert_to_via.hpp>
#include <boost/conversion/ca_wrapper.hpp>
#include <boost/conversion/pack.hpp>
+#include <boost/conversion/try_convert_to.hpp>
+#include <boost/conversion/convert_to_or_fallback.hpp>
+#include <boost/conversion/try_assign_to.hpp>
#endif
Modified: sandbox/conversion/boost/conversion/std/string.hpp
==============================================================================
--- sandbox/conversion/boost/conversion/std/string.hpp (original)
+++ sandbox/conversion/boost/conversion/std/string.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -20,54 +20,115 @@
#include <string>
#include <boost/conversion/convert_to.hpp>
#include <boost/conversion/assign_to.hpp>
-#if defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
#include <boost/lexical_cast.hpp>
#else
#include <boost/convert/convert.hpp>
#endif
namespace boost {
-namespace conversion {
+ namespace conversion {
// std namespace can not be overloaded
namespace partial_specialization_workaround {
+
+ template<typename T, typename CharT, typename Traits, typename Alloc>
+ struct convert_to< std::basic_string<CharT,Traits,Alloc>, T > {
+ inline static std::basic_string<CharT,Traits,Alloc> apply(T const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<std::basic_string<CharT,Traits,Alloc> >(from);
+#else
+ return convert<std::basic_string<CharT,Traits,Alloc> >::from(from);
+#endif
+ }
+ };
+ template<typename T, typename CharT, typename Traits, typename Alloc>
+ struct convert_to< T, std::basic_string<CharT,Traits,Alloc> > {
+ inline static T apply(std::basic_string<CharT,Traits,Alloc> const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<T>(from);
+#else
+ return convert<T>::from(from);
+#endif
+ }
+ };
- template<typename T, typename CharT, typename Traits, typename Alloc>
- struct convert_to< std::basic_string<CharT,Traits,Alloc>, T > {
- inline static std::basic_string<CharT,Traits,Alloc> apply(T const & from)
- {
-#if defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
- return lexical_cast<std::basic_string<CharT,Traits,Alloc> >(from);
-#else
- return convert<std::basic_string<CharT,Traits,Alloc> >::from(from);
-#endif
- }
- };
- template<typename T, typename CharT, typename Traits, typename Alloc>
- struct assign_to< std::basic_string<CharT,Traits,Alloc>, T > {
- inline static std::basic_string<CharT,Traits,Alloc>& apply(std::basic_string<CharT,Traits,Alloc>& to, const T& from)
- {
- to = convert<std::basic_string<CharT,Traits,Alloc> >::from(from);
- return to;
- }
- };
- template<typename T, typename CharT, typename Traits, typename Alloc>
- struct convert_to< T, std::basic_string<CharT,Traits,Alloc>> {
- inline static T apply(std::basic_string<CharT,Traits,Alloc> const & from)
- {
- return convert<T>::from(from);
- }
- };
- template<typename T, typename CharT, typename Traits, typename Alloc>
- struct assign_to< T, std::basic_string<CharT,Traits,Alloc>> {
- inline static void apply(T& to, const std::basic_string<CharT,Traits,Alloc>& from)
- {
- to = convert<T>::from(from);
- return to;
- }
- };
-
+ template<typename T, typename CharT, typename Traits, typename Alloc>
+ struct assign_to< std::basic_string<CharT,Traits,Alloc>, T > {
+ inline static std::basic_string<CharT,Traits,Alloc>&
+ apply(std::basic_string<CharT,Traits,Alloc>& to, const T& from)
+ {
+ to = boost::convert_to<std::basic_string<CharT,Traits,Alloc> >(from);
+ return to;
+ }
+ };
+ template<typename T, typename CharT, typename Traits, typename Alloc>
+ struct assign_to< T, std::basic_string<CharT,Traits,Alloc> > {
+ inline static T&
+ apply(T& to, const std::basic_string<CharT,Traits,Alloc>& from)
+ {
+ to = boost::convert_to<T>(from);
+ return to;
+ }
+ };
+
+#if 0
+ template<typename CharT, typename Traits, typename Alloc>
+ struct convert_to< std::basic_string<CharT,Traits,Alloc>, bool > {
+ inline static std::basic_string<CharT,Traits,Alloc>
+ apply(bool const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<std::basic_string<CharT,Traits,Alloc> >(from);
+#else
+ return convert<std::basic_string<CharT,Traits,Alloc> >::from(from);
+#endif
+ }
+ };
+
+ template<typename CharT, typename Traits, typename Alloc>
+ struct convert_to< bool, std::basic_string<CharT,Traits,Alloc> > {
+ inline static bool
+ apply(std::basic_string<CharT,Traits,Alloc> const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<bool>(from);
+#else
+ return convert<bool>::from(from);
+#endif
+ }
+ };
+#endif
+ template<>
+ struct convert_to< std::string, bool > {
+ inline static std::string
+ apply(bool const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<std::string >(from);
+#else
+ return convert<std::string>::from(from);
+#endif
+ }
+ };
+
+ template<>
+ struct convert_to< bool, std::string > {
+ inline static bool
+ apply(std::string const & from)
+ {
+#if !defined(BOOST_CONVERSION_USE_CONVERT)
+ return lexical_cast<bool>(from);
+#else
+ return convert<bool>::from(from);
+#endif
+ }
+ };
+
}
-}}
+ }
+}
#endif
Added: sandbox/conversion/boost/conversion/try_assign_to.hpp
==============================================================================
--- (empty file)
+++ sandbox/conversion/boost/conversion/try_assign_to.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -0,0 +1,132 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2011. 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)
+//
+// See http://www.boost.org/libs/conversion for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+/*!
+ \file
+ \brief
+ Defines the free function @c try_assign_to.
+
+The function @c try_assign_to assigns the @c from parameter to the @c to parameter. Return @c true if assignation done and @c false otherwise.
+The default implementation applies the the assignment operator of the @c To class.
+A user adapting another type could need to specialize the @c try_assign_to free function if the default behavior is not satisfactory ot if it can improve the performances
+
+The user can add the @c try_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,
+so we need a different technique.
+
+The technique consists in partially specialize on the function @c try_assign_to on the @c boost::conversion namespace.
+For compilers for which we can not partially specialize a function a trick is used:
+instead of calling directly to the @c try_assign_to member function, @c try_assign_to calls to the static operation apply
+on a class with the same name in the namespace @c partial_specialization_workaround.
+Thus the user can specialize partially this class.
+
+ */
+
+#ifndef BOOST_CONVERSION_TRY_ASSIGN_TO_HPP
+#define BOOST_CONVERSION_TRY_ASSIGN_TO_HPP
+
+#include <cstddef> //for std::size_t
+#include <boost/conversion/convert_to.hpp>
+#include <boost/conversion/assign_to.hpp>
+
+namespace boost {
+ namespace conversion {
+ namespace partial_specialization_workaround {
+ //! <c>struct try_assign_to</c> used when overloading can not be applied.
+ //! This struct can be specialized by the user.
+ template < typename To, typename From >
+ struct try_assign_to
+ {
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
+ //! @NoThrows
+ //! @Return the converted value if sucess or the fallback when conversion fails.
+ inline static bool apply(To& to, const From& from)
+ {
+ To rollback = to;
+ try
+ {
+ to = from;
+ return true;
+ }
+ catch (...)
+ {
+ to = rollback;
+ return false;
+ }
+ }
+ };
+ template < typename To, typename From, std::size_t N >
+ struct try_assign_to<To[N],From[N]>
+ {
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator on each vector element.
+ //! @NoThrows
+ //! @Return the converted value if sucess or the fallback when conversion fails.
+ inline static bool apply(To(&to)[N], const From(& from)[N])
+ {
+ To rollback[N];
+ boost::assign_to<To>(to, rollback);
+ try
+ {
+ for (std::size_t i = 0; i < N; ++i)
+ {
+ boost::assign_to<To>(to[i] , from[i]);
+ }
+ return true;
+ }
+ catch (...)
+ {
+ boost::assign_to<To>(rollback,to);
+ return false;
+ }
+ }
+ };
+ }
+
+
+ //! @brief Default @c try_assign_to overload, used when ADL fails.
+ //!
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
+ //! @NoThrows
+ //! @Return the converted value if sucess or the fallback when conversion fails.
+ //! Forwards the call to the overload workarround, which can yet be specialized by the user for standard C++ types.
+ template < typename To, typename From >
+ bool try_assign_to(To& to, const From& from, dummy::type_tag<To> const&)
+ {
+ return conversion::partial_specialization_workaround::try_assign_to<To,From>::apply(to, from);
+ }
+ }
+
+#if !defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
+ namespace conversion_impl {
+ template <typename Target, typename Source>
+ bool try_assign_to_impl(Target& to, const Source& from)
+ {
+ using namespace boost::conversion;
+ //use boost::conversion::try_assign_to if ADL fails
+ return try_assign_to(to, from, boost::dummy::type_tag<Target>());
+ }
+ }
+#endif
+
+ //! @Effects Converts the @c from parameter to the @c to parameter, using by default the assigment operator.
+ //! @NoThrows
+ //! @Return the converted value if sucess 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, boost::dummy::base_tag<Target> const& p=boost::dummy::base_tag<Target>()
+ )
+ {
+ (void)p;
+ return conversion_impl::try_assign_to_impl<Target, Source>(to, from);
+ }
+}
+
+#endif
+
Added: sandbox/conversion/boost/conversion/try_convert_to.hpp
==============================================================================
--- (empty file)
+++ sandbox/conversion/boost/conversion/try_convert_to.hpp 2011-05-12 16:33:10 EDT (Thu, 12 May 2011)
@@ -0,0 +1,102 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Vicente J. Botet Escriba 2009. 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)
+//
+// See http://www.boost.org/libs/conversion for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+/*!
+ \file
+ \brief
+ Defines the free function @c try_convert_to.
+
+ The @c try_convert_to function converts the @c from parameter to a @c To type and returns an optional<To>, uninitialized if conversion fails.
+
+ The default implementation applies the conversion @c To operator of the @c From class or
+ the copy constructor of the @c To class on a try-catch block and returns optional with the converted value if suceeds and an uninitialized optional otherwise.
+ Of course if both exist the conversion is ambiguous.
+ A user adapting specific types could need to specialize the @c try_convert_to free function if the default behavior is not satisfactory or if the specialization can perform better.
+
+The user can add the @c try_convert_to overloading on any namespace found by ADL from the @c Source or the @c Target.
+A trick is used to overload on the return type by adding a dummy parameter having the Target.
+
+But sometimes, as it is the case for the standard classes,
+we can not add new functions on the std namespace, so we need a different technique.
+
+The technique consists in partially specialize on the function @c try_convert_to on the @c boost::conversion namespace.
+For compilers for which we can not partially specialize a function a trick is used: instead of calling directly to the @c try_convert_to member function,
+@c try_convert_to calls to the static operation apply on a class with the same name in the namespace @c partial_specialization_workaround.
+Thus the user can specialize partially this class.
+ */
+
+#ifndef BOOST_CONVERSION_TRY_CONVERT_TO_HPP
+#define BOOST_CONVERSION_TRY_CONVERT_TO_HPP
+
+#include <boost/conversion/convert_to.hpp>
+#include <boost/optional.hpp>
+
+namespace boost {
+ namespace conversion {
+ namespace partial_specialization_workaround {
+ //! <c>struct try_convert_to</c> used when overloading can not be applied.
+ //! This struct can be specialized by the user.
+ template < typename To, typename From >
+ struct try_convert_to {
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @NoThrow
+ //! @Returns A optional<Ratget> uninitialized when conversion fails.
+ inline static optional<To> apply(const From& val)
+ {
+ try
+ {
+ return make_optional(boost::convert_to<To>(val));
+ }
+ catch (...)
+ {
+ return optional<To>();
+ }
+ }
+ };
+ }
+
+ //! @brief Default @c try_convert_to overload, used when ADL fails.
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To type, using by default the conversion operator or copy constructor.
+ //! @NoThrow
+ //! @Returns A optional<Target> uninitialized when conversion fails.
+ //! Forwards the call to the overload workarround, which can yet be specialized by the user for standard C++ types.
+ template < typename To, typename From >
+ optional<To> try_convert_to(const From& val, dummy::type_tag<To> const&) {
+ return conversion::partial_specialization_workaround::try_convert_to<To,From>::apply(val);
+ }
+ }
+#if !defined(BOOST_CONVERSION_DOXYGEN_INVOKED)
+ namespace conversion_impl {
+ template <typename Target, typename Source>
+ optional<Target> try_convert_to_impl(Source const& from) {
+ using namespace boost::conversion;
+ //use boost::conversion::try_convert_to if ADL fails
+ return try_convert_to(from, boost::dummy::type_tag<Target>());
+ }
+ }
+#endif
+
+ //!
+ //! @Effects Converts the @c from parameter to an instance of the @c To 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, boost::dummy::base_tag<Target> const& p=boost::dummy::base_tag<Target>()) {
+ (void)p;
+ return conversion_impl::try_convert_to_impl<Target>(from);
+ }
+
+}
+
+#endif
+
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