Assert when we try to use an incomplete type on a trait which requires complete types as arguments.

This prevents some traits from doing the wrong thing (ie compiling but giving the wrong answer when handed an incomplete type.
See https://svn.boost.org/trac10/ticket/12285.
A by-product of this is we add is_complete as a new trait.
This commit is contained in:
jzmaddock
2018-02-04 10:03:30 +00:00
parent 85a03d3453
commit ac351390b2
35 changed files with 572 additions and 17 deletions

View File

@ -13,6 +13,10 @@
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/static_assert.hpp>
#if defined(BOOST_NO_CXX11_DECLTYPE)
#include <boost/type_traits/detail/common_type_impl.hpp>
@ -75,6 +79,7 @@ struct common_type: common_type<typename common_type<T1, T2>::type, T3, T4, T5,
template<class T> struct common_type<T>: boost::decay<T>
{
BOOST_STATIC_ASSERT_MSG(::boost::is_complete<T>::value || ::boost::is_void<T>::value || ::boost::is_array<T>::value, "Arguments to common_type must both be complete types");
};
// two arguments
@ -138,6 +143,8 @@ template<class T1, class T2> struct common_type_decay_helper<T1, T2, T1, T2>: co
template<class T1, class T2> struct common_type<T1, T2>: type_traits_detail::common_type_decay_helper<T1, T2>
{
BOOST_STATIC_ASSERT_MSG(::boost::is_complete<T1>::value || ::boost::is_void<T1>::value || ::boost::is_array<T1>::value, "Arguments to common_type must both be complete types");
BOOST_STATIC_ASSERT_MSG(::boost::is_complete<T2>::value || ::boost::is_void<T2>::value || ::boost::is_array<T2>::value, "Arguments to common_type must both be complete types");
};
} // namespace boost

View File

@ -15,6 +15,8 @@
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_destructible.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
namespace boost{
@ -27,12 +29,19 @@ namespace boost{
}
template <class T> struct has_nothrow_destructor : public detail::has_nothrow_destructor_imp<T, boost::is_destructible<T>::value>{};
template <class T, std::size_t N> struct has_nothrow_destructor<T[N]> : public has_nothrow_destructor<T>{};
template <class T> struct has_nothrow_destructor : public detail::has_nothrow_destructor_imp<T, boost::is_destructible<T>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to has_nothrow_destructor must be complete types");
};
template <class T, std::size_t N> struct has_nothrow_destructor<T[N]> : public has_nothrow_destructor<T>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to has_nothrow_destructor must be complete types");
};
template <class T> struct has_nothrow_destructor<T&> : public integral_constant<bool, false>{};
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <class T> struct has_nothrow_destructor<T&&> : public integral_constant<bool, false>{};
#endif
template <> struct has_nothrow_destructor<void> : public false_type {};
}
#else

View File

@ -12,6 +12,8 @@
#include <cstddef> // size_t
#include <boost/type_traits/integral_constant.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
namespace boost{
@ -39,7 +41,10 @@ namespace boost{
}
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)>{};
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)>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_assignable must be complete types");
};
template <class T, std::size_t N, class U> struct is_assignable<T[N], U> : public is_assignable<T, U>{};
template <class T, std::size_t N, class U> struct is_assignable<T(&)[N], U> : public is_assignable<T&, U>{};
template <class T, class U> struct is_assignable<T[], U> : public is_assignable<T, U>{};
@ -57,7 +62,10 @@ namespace boost{
namespace boost{
// We don't know how to implement this:
template <class T, class U> struct is_assignable : public integral_constant<bool, false>{};
template <class T, class U> struct is_assignable : public integral_constant<bool, false>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_assignable must be complete types");
};
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>{};
template <class T, class U> struct is_assignable<const T&, U> : public integral_constant<bool, false>{};
template <class U> struct is_assignable<void, U> : public integral_constant<bool, false>{};

View File

@ -0,0 +1,81 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt).
//
// See http://www.boost.org/libs/type_traits for most recent version including documentation.
#ifndef BOOST_TT_IS_COMPLETE_HPP_INCLUDED
#define BOOST_TT_IS_COMPLETE_HPP_INCLUDED
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_function.hpp>
/*
* CAUTION:
* ~~~~~~~~
*
* THIS TRAIT EXISTS SOLELY TO GENERATE HARD ERRORS WHEN A ANOTHER TRAIT
* WHICH REQUIRES COMPLETE TYPES AS ARGUMENTS IS PASSED AN INCOMPLETE TYPE
*
* DO NOT MAKE GENERAL USE OF THIS TRAIT, AS THE COMPLETENESS OF A TYPE
* VARIES ACROSS TRANSLATION UNITS AS WELL AS WITHIN A SINGLE UNIT.
*
*/
namespace boost {
#ifndef BOOST_NO_SFINAE_EXPR
namespace detail{
template <unsigned N>
struct ok_tag { double d; char c[N]; };
template <class T>
ok_tag<sizeof(T)> check_is_complete(int);
template <class T>
char check_is_complete(...);
}
template <class T> struct is_complete
: public integral_constant<bool, ::boost::is_function<typename boost::remove_reference<T>::type>::value || (sizeof(detail::check_is_complete<T>(0)) != sizeof(char))> {};
#elif !defined(BOOST_NO_SFINAE)
namespace detail
{
template <class T>
struct is_complete_imp
{
template <class U, class = decltype(sizeof(std::declval< U >())) >
static type_traits::yes_type check(U*);
template <class U>
static type_traits::no_type check(...);
static const bool value = sizeof(check<T>(0)) == sizeof(type_traits::yes_type);
};
} // namespace detail
template <class T>
struct is_complete : std::integral_constant<bool, ::boost::is_function<typename boost::remove_reference<T>::type>::value || detail::is_complete_imp<T>::value>
{};
template <class T>
struct is_complete<T&> : is_complete<T> {};
#else
template <class T> struct is_complete
: public integral_constant<bool, true> {};
#endif
} // namespace boost
#endif // BOOST_TT_IS_COMPLETE_HPP_INCLUDED

View File

@ -18,6 +18,8 @@
#include <boost/type_traits/is_default_constructible.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
#define BOOST_TT_IS_CONSTRUCTIBLE_CONFORMING 1
@ -45,8 +47,14 @@ namespace boost{
}
template <class T, class ...Args> struct is_constructible : public integral_constant<bool, sizeof(detail::is_constructible_imp::test<T, Args...>(0)) == sizeof(boost::type_traits::yes_type)>{};
template <class T, class Arg> struct is_constructible<T, Arg> : public integral_constant<bool, is_destructible<T>::value && sizeof(detail::is_constructible_imp::test1<T, Arg>(0)) == sizeof(boost::type_traits::yes_type)>{};
template <class T, class ...Args> struct is_constructible : public integral_constant<bool, sizeof(detail::is_constructible_imp::test<T, Args...>(0)) == sizeof(boost::type_traits::yes_type)>
{
BOOST_STATIC_ASSERT_MSG(::boost::is_complete<T>::value, "The target type must be complete in order to test for constructibility");
};
template <class T, class Arg> struct is_constructible<T, Arg> : public integral_constant<bool, is_destructible<T>::value && sizeof(detail::is_constructible_imp::test1<T, Arg>(0)) == sizeof(boost::type_traits::yes_type)>
{
BOOST_STATIC_ASSERT_MSG(::boost::is_complete<T>::value, "The target type must be complete in order to test for constructibility");
};
template <class Ref, class Arg> struct is_constructible<Ref&, Arg> : public integral_constant<bool, sizeof(detail::is_constructible_imp::ref_test<Ref&>(boost::declval<Arg>())) == sizeof(boost::type_traits::yes_type)>{};
template <class Ref, class Arg> struct is_constructible<Ref&&, Arg> : public integral_constant<bool, sizeof(detail::is_constructible_imp::ref_test<Ref&&>(boost::declval<Arg>())) == sizeof(boost::type_traits::yes_type)>{};

View File

@ -15,6 +15,10 @@
#include <boost/type_traits/intrinsics.hpp>
#include <boost/type_traits/integral_constant.hpp>
#ifndef BOOST_IS_CONVERTIBLE
#include <boost/type_traits/is_complete.hpp>
#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/detail/config.hpp>
#include <boost/type_traits/is_array.hpp>
@ -474,7 +478,11 @@ template <class From> struct is_convertible_impl_dispatch<From, void volatile> :
} // namespace detail
template <class From, class To>
struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value> {};
struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<To>::value || boost::is_void<To>::value || boost::is_array<To>::value, "Destination argument type to is_convertible must be a complete type");
BOOST_STATIC_ASSERT_MSG(boost::is_complete<From>::value || boost::is_void<From>::value || boost::is_array<From>::value, "From argument type to is_convertible must be a complete type");
};
#else

View File

@ -12,6 +12,8 @@
#include <cstddef> // size_t
#include <boost/type_traits/integral_constant.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
#include <boost/type_traits/is_abstract.hpp>
@ -51,9 +53,15 @@ namespace boost{
}
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
template <class T> struct is_default_constructible : public integral_constant<bool, detail::is_default_constructible_abstract_filter<T, boost::is_abstract<T>::value>::value>{};
template <class T> struct is_default_constructible : public integral_constant<bool, detail::is_default_constructible_abstract_filter<T, boost::is_abstract<T>::value>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_default_constructible must be complete types");
};
#else
template <class T> struct is_default_constructible : public integral_constant<bool, sizeof(detail::is_default_constructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>{};
template <class T> struct is_default_constructible : public integral_constant<bool, sizeof(detail::is_default_constructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_default_constructible must be complete types");
};
#endif
template <class T, std::size_t N> struct is_default_constructible<T[N]> : public is_default_constructible<T>{};
template <class T> struct is_default_constructible<T[]> : public is_default_constructible<T>{};

View File

@ -12,6 +12,8 @@
#include <cstddef> // size_t
#include <boost/type_traits/integral_constant.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
@ -32,7 +34,10 @@ namespace boost{
}
template <class T> struct is_destructible : public integral_constant<bool, sizeof(detail::is_destructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>{};
template <class T> struct is_destructible : public integral_constant<bool, sizeof(detail::is_destructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_destructible must be complete types");
};
#else
@ -42,7 +47,10 @@ namespace boost{
namespace boost{
// We don't know how to implement this:
template <class T> struct is_destructible : public integral_constant<bool, is_pod<T>::value || is_class<T>::value>{};
template <class T> struct is_destructible : public integral_constant<bool, is_pod<T>::value || is_class<T>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_destructible must be complete types");
};
#endif
template <> struct is_destructible<void> : public false_type{};

View File

@ -10,6 +10,8 @@
#include <boost/config.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
namespace boost
{
@ -18,6 +20,7 @@ namespace boost
template<class T, class = void, class = void, class = void, class = void, class = void, class = void> struct is_list_constructible: false_type
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_list_constructible must be complete types");
};
#else
@ -32,6 +35,7 @@ template<class T, class... A> false_type is_list_constructible_impl( ... );
template<class T, class... A> struct is_list_constructible: decltype( type_traits_detail::is_list_constructible_impl<T, A...>(0) )
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_list_constructible must be complete types");
};
#endif

View File

@ -18,13 +18,18 @@
#include <boost/type_traits/is_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
namespace boost {
#ifdef BOOST_IS_NOTHROW_MOVE_ASSIGN
template <class T>
struct is_nothrow_move_assignable : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_ASSIGN(T)>{};
struct is_nothrow_move_assignable : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_ASSIGN(T)>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_assignable must be complete types");
};
template <class T> struct is_nothrow_move_assignable<T const> : public false_type{};
template <class T> struct is_nothrow_move_assignable<T volatile> : public false_type{};
template <class T> struct is_nothrow_move_assignable<T const volatile> : public false_type{};
@ -50,7 +55,10 @@ struct false_or_cpp11_noexcept_move_assignable <
}
template <class T>
struct is_nothrow_move_assignable : public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_assignable<T>::value>{};
struct is_nothrow_move_assignable : public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_assignable<T>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_assignable must be complete types");
};
template <class T> struct is_nothrow_move_assignable<T const> : public ::boost::false_type {};
template <class T> struct is_nothrow_move_assignable<T const volatile> : public ::boost::false_type{};
@ -64,7 +72,10 @@ template <class T> struct is_nothrow_move_assignable<T&&> : public ::boost::fals
template <class T>
struct is_nothrow_move_assignable : public integral_constant<bool,
(::boost::has_trivial_move_assign<T>::value || ::boost::has_nothrow_assign<T>::value) && ! ::boost::is_array<T>::value>{};
(::boost::has_trivial_move_assign<T>::value || ::boost::has_nothrow_assign<T>::value) && ! ::boost::is_array<T>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_assignable must be complete types");
};
#endif

View File

@ -16,13 +16,18 @@
#include <boost/type_traits/intrinsics.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_IS_NOTHROW_MOVE_CONSTRUCT
namespace boost {
template <class T>
struct is_nothrow_move_constructible : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T)>{};
struct is_nothrow_move_constructible : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T)>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_constructible must be complete types");
};
template <class T> struct is_nothrow_move_constructible<volatile T> : public ::boost::false_type {};
template <class T> struct is_nothrow_move_constructible<const volatile T> : public ::boost::false_type{};
@ -47,7 +52,10 @@ struct false_or_cpp11_noexcept_move_constructible <
}
template <class T> struct is_nothrow_move_constructible
: public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_constructible<T>::value>{};
: public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_constructible<T>::value>
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_constructible must be complete types");
};
template <class T> struct is_nothrow_move_constructible<volatile T> : public ::boost::false_type {};
template <class T> struct is_nothrow_move_constructible<const volatile T> : public ::boost::false_type{};
@ -66,7 +74,9 @@ template <class T>
struct is_nothrow_move_constructible
: public integral_constant<bool,
(::boost::has_trivial_move_constructor<T>::value || ::boost::has_nothrow_copy<T>::value) && !::boost::is_array<T>::value>
{};
{
BOOST_STATIC_ASSERT_MSG(boost::is_complete<T>::value, "Arguments to is_nothrow_move_constructible must be complete types");
};
#endif

View File

@ -39,6 +39,10 @@ rule all-tests {
{
result += [ run $(source) ] ;
}
for local source in [ glob compile_fail/*.cpp ]
{
result += [ compile-fail $(source) ] ;
}
#
# These traits have both intrinsic support, and a std conforming version, test a version with intrinsics disabled for better code coverage:
#

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/common_type.hpp>
#include "../test.hpp"
int main()
{
return sizeof(boost::common_type<int, incomplete_type>::type);
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/common_type.hpp>
#include "../test.hpp"
int main()
{
return sizeof(boost::common_type<incomplete_type, int>::type);
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/has_nothrow_assign.hpp>
#include "../test.hpp"
int main()
{
return boost::has_nothrow_assign<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/has_nothrow_constructor.hpp>
#include "../test.hpp"
int main()
{
return boost::has_nothrow_constructor<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/has_nothrow_copy.hpp>
#include "../test.hpp"
int main()
{
return boost::has_nothrow_copy<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/has_nothrow_destructor.hpp>
#include "../test.hpp"
int main()
{
return boost::has_nothrow_destructor<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_assignable.hpp>
#include "../test.hpp"
int main()
{
return boost::is_assignable<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_base_of.hpp>
#include "../test.hpp"
int main()
{
return boost::is_base_of<UDT, incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_constructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_constructible<incomplete_type, int>::value;
}

View File

@ -0,0 +1,19 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_convertible.hpp>
#include "../test.hpp"
#if defined(CI_SUPPRESS_KNOWN_ISSUES) && defined(BOOST_MSVC) && (BOOST_MSVC <= 1800)
#error "Sorry check doesn't work"
#endif
int main()
{
return boost::is_convertible<incomplete_type, UDT>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_convertible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_convertible<UDT, incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_copy_assignable.hpp>
#include "../test.hpp"
int main()
{
return boost::is_copy_assignable<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_copy_constructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_copy_constructible<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_default_constructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_default_constructible<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_destructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_destructible<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_empty.hpp>
#include "../test.hpp"
int main()
{
return boost::is_empty<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_list_constructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_list_constructible<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_nothrow_move_assignable.hpp>
#include "../test.hpp"
int main()
{
return boost::is_nothrow_move_assignable<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include "../test.hpp"
int main()
{
return boost::is_nothrow_move_constructible<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_polymorphic.hpp>
#include "../test.hpp"
int main()
{
return boost::is_polymorphic<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_stateless.hpp>
#include "../test.hpp"
int main()
{
return boost::is_stateless<incomplete_type>::value;
}

View File

@ -0,0 +1,15 @@
// (C) Copyright John Maddock 2017.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# include <boost/type_traits/is_virtual_base_of.hpp>
#include "../test.hpp"
int main()
{
return boost::is_virtual_base_of<UDT, incomplete_type>::value;
}

55
test/is_complete_test.cpp Normal file
View File

@ -0,0 +1,55 @@
// (C) Copyright John Maddock 2000.
// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifdef TEST_STD
# include <type_traits>
#else
# include <boost/type_traits/is_complete.hpp>
#endif
#include "test.hpp"
#include "check_integral_constant.hpp"
TT_TEST_BEGIN(is_complete)
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const&>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile&>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile&>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile*>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int[2]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const[3]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int volatile[2][3]>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int const volatile[4][5][6]>::value, true);
#ifndef BOOST_NO_SFINAE
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<int[]>::value, false);
#endif
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<enum_UDT>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<UDT>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<f1>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<mf1>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<cmf>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<mf8>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<union_UDT>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<test_abc1>::value, true);
#ifndef BOOST_NO_SFINAE
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<incomplete_type>::value, false);
#endif
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<polymorphic_base>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<virtual_inherit6>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<foo0_t>::value, true);
BOOST_CHECK_INTEGRAL_CONSTANT(::tt::is_complete<foo4_t>::value, true);
TT_TEST_END