forked from OSchip/llvm-project
Made a stab at has_default_constructor. Got it mostly working for g++-4.0, but only works for scalar types on clang. Ultimately this needs a compiler-supported is_constructible which clang is missing, and won't be able to use until it gets variadic templates.
llvm-svn: 113225
This commit is contained in:
parent
f0ea222255
commit
ba6f71b030
|
@ -1637,6 +1637,80 @@ struct __is_constructible<false, _A[], _Args...>
|
||||||
: public false_type
|
: public false_type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct has_default_constructor
|
||||||
|
: public is_constructible<_Tp>
|
||||||
|
{};
|
||||||
|
|
||||||
|
#else // _LIBCPP_HAS_NO_ADVANCED_SFINAE
|
||||||
|
|
||||||
|
// template <class T> struct is_constructible0;
|
||||||
|
|
||||||
|
// main is_constructible0 test
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
decltype((_STD::move(_Tp()), true_type()))
|
||||||
|
__is_constructible0_test(_Tp&);
|
||||||
|
|
||||||
|
false_type
|
||||||
|
__is_constructible0_test(__any);
|
||||||
|
|
||||||
|
template <bool, class _Tp>
|
||||||
|
struct __is_constructible0_imp // false, _Tp is not a scalar
|
||||||
|
: public common_type
|
||||||
|
<
|
||||||
|
decltype(__is_constructible0_test(declval<_Tp&>()))
|
||||||
|
>::type
|
||||||
|
{};
|
||||||
|
|
||||||
|
// handle scalars and reference types
|
||||||
|
|
||||||
|
// Scalars are default constructible, references are not
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct __is_constructible0_imp<true, _Tp>
|
||||||
|
: public is_scalar<_Tp>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// Treat scalars and reference types separately
|
||||||
|
|
||||||
|
template <bool, class _Tp>
|
||||||
|
struct __is_constructible0_void_check
|
||||||
|
: public __is_constructible0_imp<is_scalar<_Tp>::value || is_reference<_Tp>::value,
|
||||||
|
_Tp>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// If any of T or Args is void, is_constructible should be false
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct __is_constructible0_void_check<true, _Tp>
|
||||||
|
: public false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
// has_default_constructor entry point
|
||||||
|
|
||||||
|
template <class _Tp>
|
||||||
|
struct has_default_constructor
|
||||||
|
: public __is_constructible0_void_check<is_void<_Tp>::value
|
||||||
|
|| is_abstract<_Tp>::value,
|
||||||
|
_Tp>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// Array types are default constructible if their element type
|
||||||
|
// is default constructible
|
||||||
|
|
||||||
|
template <class _A, size_t _N>
|
||||||
|
struct __is_constructible0_imp<false, _A[_N]>
|
||||||
|
: public has_default_constructor<typename remove_all_extents<_A>::type>
|
||||||
|
{};
|
||||||
|
|
||||||
|
// Incomplete array types are not constructible
|
||||||
|
|
||||||
|
template <class _A>
|
||||||
|
struct __is_constructible0_imp<false, _A[]>
|
||||||
|
: public false_type
|
||||||
|
{};
|
||||||
|
|
||||||
#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
|
#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
|
||||||
|
|
||||||
template <class _Tp> struct __is_zero_default_constructible
|
template <class _Tp> struct __is_zero_default_constructible
|
||||||
|
|
|
@ -13,7 +13,58 @@
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
template <class T, bool Result>
|
||||||
|
void test_has_default_constructor()
|
||||||
|
{
|
||||||
|
static_assert(std::has_default_constructor<T>::value == Result, "");
|
||||||
|
static_assert(std::has_default_constructor<const T>::value == Result, "");
|
||||||
|
static_assert(std::has_default_constructor<volatile T>::value == Result, "");
|
||||||
|
static_assert(std::has_default_constructor<const volatile T>::value == Result, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
class Empty
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class NotEmpty
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~NotEmpty();
|
||||||
|
};
|
||||||
|
|
||||||
|
union Union {};
|
||||||
|
|
||||||
|
struct bit_zero
|
||||||
|
{
|
||||||
|
int : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Abstract
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Abstract() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct A
|
||||||
|
{
|
||||||
|
A();
|
||||||
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
#error has_default_constructor not implemented
|
test_has_default_constructor<void, false>();
|
||||||
|
test_has_default_constructor<int&, false>();
|
||||||
|
test_has_default_constructor<char[], false>();
|
||||||
|
test_has_default_constructor<Abstract, false>();
|
||||||
|
|
||||||
|
test_has_default_constructor<A, true>();
|
||||||
|
test_has_default_constructor<Union, true>();
|
||||||
|
test_has_default_constructor<Empty, true>();
|
||||||
|
test_has_default_constructor<int, true>();
|
||||||
|
test_has_default_constructor<double, true>();
|
||||||
|
test_has_default_constructor<int*, true>();
|
||||||
|
test_has_default_constructor<const int*, true>();
|
||||||
|
test_has_default_constructor<char[3], true>();
|
||||||
|
test_has_default_constructor<NotEmpty, true>();
|
||||||
|
test_has_default_constructor<bit_zero, true>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ class Empty
|
||||||
|
|
||||||
class NotEmpty
|
class NotEmpty
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual ~NotEmpty();
|
virtual ~NotEmpty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ struct bit_zero
|
||||||
|
|
||||||
class Abstract
|
class Abstract
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
virtual ~Abstract() = 0;
|
virtual ~Abstract() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue