https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71579

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This seems to work OK:

namespace std {

template <class _Tp>
  struct __is_complete_impl
  {
    template <class _Up, size_t = sizeof(_Up)>
      static true_type
      _S_test(int);

    template <class _Up>
      static false_type
      _S_test(...);

    using type = decltype(_S_test<_Tp>(0));
  };

template<typename _Tp>
  using __is_complete = typename __is_complete_impl<_Tp>::type;

template<typename _Tp>
  using __is_cv_void = is_void<typename remove_cv<_Tp>::type>;

template<typename _Tp>
  using __is_complete_or_void = __or_<__is_cv_void<_Tp>, __is_complete<_Tp>>;

template<typename _Tp, bool = is_array<_Tp>::value>
  struct __is_aoub : false_type { };

template<typename _Tp>
  struct __is_aoub<_Tp, true> : __bool_constant<extent<_Tp>::value == 0> { };

template<typename _Tp>
  using __is_complete_or_void_or_aoub
    = __or_<__is_complete_or_void<_Tp>, __is_aoub<_Tp>>;
}

// ...
template<typename _Tp, typename... _Args>
  struct is_constructible
  : public std::__is_constructible_impl<_Tp, _Args...>::type
  {
    static_assert( std::__and_<std::__is_complete_or_void_or_aoub<_Tp>,
        std::__is_complete_or_void_or_aoub<_Args>...>::value,
        "all types must be complete, void, or arrays of unknown bound");
  };

Reply via email to