is_assignable.hpp 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // (C) Copyright John Maddock 2015.
  2. // Use, modification and distribution are subject to the Boost Software License,
  3. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt).
  5. //
  6. // See http://www.boost.org/libs/type_traits for most recent version including documentation.
  7. #ifndef BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED
  8. #define BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED
  9. #include <cstddef> // size_t
  10. #include <boost/type_traits/integral_constant.hpp>
  11. #include <boost/detail/workaround.hpp>
  12. #include <boost/type_traits/is_complete.hpp>
  13. #include <boost/static_assert.hpp>
  14. namespace boost{
  15. template <class T, class U = T> struct is_assignable;
  16. }
  17. #if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
  18. #include <boost/type_traits/detail/yes_no_type.hpp>
  19. #include <boost/type_traits/declval.hpp>
  20. namespace boost{
  21. namespace detail{
  22. struct is_assignable_imp
  23. {
  24. template<typename T, typename U, typename = decltype(boost::declval<T>() = boost::declval<U>())>
  25. static boost::type_traits::yes_type test(int);
  26. template<typename, typename>
  27. static boost::type_traits::no_type test(...);
  28. };
  29. }
  30. template <class T, class U> struct is_assignable : public integral_constant<bool, sizeof(detail::is_assignable_imp::test<T, U>(0)) == sizeof(boost::type_traits::yes_type)>
  31. {
  32. BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_assignable must be complete types");
  33. };
  34. template <class T, std::size_t N, class U> struct is_assignable<T[N], U> : public is_assignable<T, U>{};
  35. template <class T, std::size_t N, class U> struct is_assignable<T(&)[N], U> : public is_assignable<T&, U>{};
  36. template <class T, class U> struct is_assignable<T[], U> : public is_assignable<T, U>{};
  37. template <class T, class U> struct is_assignable<T(&)[], U> : public is_assignable<T&, U>{};
  38. template <class U> struct is_assignable<void, U> : public integral_constant<bool, false>{};
  39. template <class U> struct is_assignable<void const, U> : public integral_constant<bool, false>{};
  40. template <class U> struct is_assignable<void volatile, U> : public integral_constant<bool, false>{};
  41. template <class U> struct is_assignable<void const volatile, U> : public integral_constant<bool, false>{};
  42. #else
  43. #include <boost/type_traits/has_trivial_assign.hpp>
  44. #include <boost/type_traits/remove_reference.hpp>
  45. namespace boost{
  46. // We don't know how to implement this:
  47. template <class T, class U> struct is_assignable : public integral_constant<bool, false>
  48. {
  49. BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_assignable must be complete types");
  50. };
  51. template <class T, class U> struct is_assignable<T&, U> : public integral_constant<bool, is_pod<T>::value && is_pod<typename remove_reference<U>::type>::value>{};
  52. template <class T, class U> struct is_assignable<const T&, U> : public integral_constant<bool, false>{};
  53. template <class U> struct is_assignable<void, U> : public integral_constant<bool, false>{};
  54. template <class U> struct is_assignable<void const, U> : public integral_constant<bool, false>{};
  55. template <class U> struct is_assignable<void volatile, U> : public integral_constant<bool, false>{};
  56. template <class U> struct is_assignable<void const volatile, U> : public integral_constant<bool, false>{};
  57. /*
  58. template <> struct is_assignable<void, void> : public integral_constant<bool, false>{};
  59. template <> struct is_assignable<void const, void const> : public integral_constant<bool, false>{};
  60. template <> struct is_assignable<void volatile, void volatile> : public integral_constant<bool, false>{};
  61. template <> struct is_assignable<void const volatile, void const volatile> : public integral_constant<bool, false>{};
  62. */
  63. #endif
  64. } // namespace boost
  65. #endif // BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED