is_complete.hpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // (C) Copyright John Maddock 2017.
  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_COMPLETE_HPP_INCLUDED
  8. #define BOOST_TT_IS_COMPLETE_HPP_INCLUDED
  9. #include <boost/type_traits/declval.hpp>
  10. #include <boost/type_traits/integral_constant.hpp>
  11. #include <boost/type_traits/remove_reference.hpp>
  12. #include <boost/type_traits/is_function.hpp>
  13. #include <boost/type_traits/detail/yes_no_type.hpp>
  14. #include <boost/config/workaround.hpp>
  15. /*
  16. * CAUTION:
  17. * ~~~~~~~~
  18. *
  19. * THIS TRAIT EXISTS SOLELY TO GENERATE HARD ERRORS WHEN A ANOTHER TRAIT
  20. * WHICH REQUIRES COMPLETE TYPES AS ARGUMENTS IS PASSED AN INCOMPLETE TYPE
  21. *
  22. * DO NOT MAKE GENERAL USE OF THIS TRAIT, AS THE COMPLETENESS OF A TYPE
  23. * VARIES ACROSS TRANSLATION UNITS AS WELL AS WITHIN A SINGLE UNIT.
  24. *
  25. */
  26. namespace boost {
  27. //
  28. // We will undef this if the trait isn't fully functional:
  29. //
  30. #define BOOST_TT_HAS_WORKING_IS_COMPLETE
  31. #if !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40600)
  32. namespace detail{
  33. template <unsigned N>
  34. struct ok_tag { double d; char c[N]; };
  35. template <class T>
  36. ok_tag<sizeof(T)> check_is_complete(int);
  37. template <class T>
  38. char check_is_complete(...);
  39. }
  40. template <class T> struct is_complete
  41. : public integral_constant<bool, ::boost::is_function<typename boost::remove_reference<T>::type>::value || (sizeof(boost::detail::check_is_complete<T>(0)) != sizeof(char))> {};
  42. #elif !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
  43. namespace detail
  44. {
  45. template <class T>
  46. struct is_complete_imp
  47. {
  48. template <class U, class = decltype(sizeof(boost::declval< U >())) >
  49. static type_traits::yes_type check(U*);
  50. template <class U>
  51. static type_traits::no_type check(...);
  52. static const bool value = sizeof(check<T>(0)) == sizeof(type_traits::yes_type);
  53. };
  54. } // namespace detail
  55. template <class T>
  56. struct is_complete : boost::integral_constant<bool, ::boost::is_function<typename boost::remove_reference<T>::type>::value || ::boost::detail::is_complete_imp<T>::value>
  57. {};
  58. template <class T>
  59. struct is_complete<T&> : boost::is_complete<T> {};
  60. #else
  61. template <class T> struct is_complete
  62. : public boost::integral_constant<bool, true> {};
  63. #undef BOOST_TT_HAS_WORKING_IS_COMPLETE
  64. #endif
  65. } // namespace boost
  66. #endif // BOOST_TT_IS_COMPLETE_HPP_INCLUDED