explicit_conversion.hpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright Vicente J. Botet Escriba 2009-2011
  3. // Copyright 2012 John Maddock. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_MP_EXPLICIT_CONVERTIBLE_HPP
  7. #define BOOST_MP_EXPLICIT_CONVERTIBLE_HPP
  8. #include <boost/type_traits/is_convertible.hpp>
  9. #include <boost/utility/declval.hpp>
  10. namespace boost{ namespace multiprecision{ namespace detail{
  11. template <int N>
  12. struct dummy_size{};
  13. template<typename S, typename T>
  14. struct has_generic_interconversion
  15. {
  16. typedef typename mpl::if_c<
  17. is_number<S>::value && is_number<T>::value,
  18. typename mpl::if_c<
  19. number_category<S>::value == number_kind_integer,
  20. typename mpl::if_c<
  21. number_category<T>::value == number_kind_integer
  22. || number_category<T>::value == number_kind_floating_point
  23. || number_category<T>::value == number_kind_rational
  24. || number_category<T>::value == number_kind_fixed_point,
  25. mpl::true_,
  26. mpl::false_
  27. >::type,
  28. typename mpl::if_c<
  29. number_category<S>::value == number_kind_rational,
  30. typename mpl::if_c<
  31. number_category<T>::value == number_kind_rational
  32. || number_category<T>::value == number_kind_rational,
  33. mpl::true_,
  34. mpl::false_
  35. >::type,
  36. typename mpl::if_c<
  37. number_category<T>::value == number_kind_floating_point,
  38. mpl::true_,
  39. mpl::false_
  40. >::type
  41. >::type
  42. >::type,
  43. mpl::false_
  44. >::type type;
  45. };
  46. template<typename S, typename T>
  47. struct is_explicitly_convertible_imp
  48. {
  49. #ifndef BOOST_NO_SFINAE_EXPR
  50. template<typename S1, typename T1>
  51. static type_traits::yes_type selector(dummy_size<sizeof(static_cast<T1>(declval<S1>()))>*);
  52. template<typename S1, typename T1>
  53. static type_traits::no_type selector(...);
  54. static const bool value = sizeof(selector<S,T>(0)) == sizeof(type_traits::yes_type);
  55. typedef boost::integral_constant<bool,value> type;
  56. #else
  57. typedef typename has_generic_interconversion<S, T>::type gen_type;
  58. typedef mpl::bool_<boost::is_convertible<S, T>::value || gen_type::value> type;
  59. #endif
  60. };
  61. template<typename From, typename To>
  62. struct is_explicitly_convertible : public is_explicitly_convertible_imp<From, To>::type
  63. {
  64. };
  65. }}} // namespaces
  66. #endif