CaseyCarter created this revision. CaseyCarter added reviewers: mclow.lists, EricWF.
Like the title says, the first batch of tests. I'll stop at three chunks for now - that should be enough to get some reviewer feedback and keep me busy making changes. https://reviews.llvm.org/D49122 Files: test/std/concepts/concepts.lang/concept.commonref/common_reference.pass.cpp test/std/concepts/concepts.lang/concept.convertibleto/convertible_to.pass.cpp test/std/concepts/concepts.lang/concept.derivedfrom/derived_from.pass.cpp test/std/concepts/concepts.lang/concept.same/same.pass.cpp test/std/concepts/lit.local.cfg
Index: test/std/concepts/lit.local.cfg =================================================================== --- /dev/null +++ test/std/concepts/lit.local.cfg @@ -0,0 +1,9 @@ +# If the compiler doesn't support concepts, mark all of the tests under +# this directory as unsupported. +if 'concepts' not in config.available_features: + config.unsupported = True +elif 'fconcepts' in config.available_features: + # The compiler supports concepts only with the flag - require it. + import copy + config.test_format.cxx = copy.deepcopy(config.test_format.cxx) + config.test_format.cxx.compile_flags += ['-fconcepts'] Index: test/std/concepts/concepts.lang/concept.same/same.pass.cpp =================================================================== --- /dev/null +++ test/std/concepts/concepts.lang/concept.same/same.pass.cpp @@ -0,0 +1,75 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <concepts> +#include <type_traits> + +static_assert(std::Same<int, int>); +static_assert(std::Same<double, double>); +static_assert(!std::Same<double, int>); +static_assert(!std::Same<int, double>); + +// Test that `Same<A,B>` subsumes `Same<B,A>` (with reversed args). +template <class A, class B> + requires std::Same<B, A> +constexpr bool foo() { + return false; +} + +template <class A, class B> + requires std::Same<A, B> && std::is_integral_v<A> +constexpr bool foo() { + return true; +} + +static_assert(!foo<int*, int*>()); +static_assert(foo<int, int>()); + +template <class T, class U> +void test_same() { + static_assert( std::Same<T, U>); + static_assert(!std::Same<const T, U>); + static_assert(!std::Same<T, const U>); + static_assert( std::Same<const T, const U>); +} + +template <class T, class U> +void test_same_ref() { + static_assert(std::Same<T, U>); + static_assert(std::Same<const T, U>); + static_assert(std::Same<T, const U>); + static_assert(std::Same<const T, const U>); +} + +template <class T, class U> +void test_not_same() { + static_assert(!std::Same<T, U>); +} + +struct Class +{ + ~Class(); +}; + +int main() { + test_same<int, int>(); + test_same<void, void>(); + test_same<Class, Class>(); + test_same<int*, int*>(); + test_same_ref<int&, int&>(); + + test_not_same<int, void>(); + test_not_same<void, Class>(); + test_not_same<Class, int*>(); + test_not_same<int*, int&>(); + test_not_same<int&, int>(); +} Index: test/std/concepts/concepts.lang/concept.derivedfrom/derived_from.pass.cpp =================================================================== --- /dev/null +++ test/std/concepts/concepts.lang/concept.derivedfrom/derived_from.pass.cpp @@ -0,0 +1,48 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <concepts> +#include <type_traits> + +#include "test_macros.h" + +template <class Derived, class Base> +void test_derived_from() { + static_assert(std::DerivedFrom<Derived, Base>); + static_assert(std::DerivedFrom<const Derived, Base>); + static_assert(std::DerivedFrom<Derived, const Base>); + static_assert(std::DerivedFrom<const Derived, const Base>); +} + +template <class Derived, class Base> +void test_not_derived_from() { + static_assert(!std::DerivedFrom<Derived, Base>); +} + +struct B {}; +struct B1 : B {}; +struct B2 : B {}; +struct D : private B1, private B2 {}; + +int main() { + test_derived_from<B1, B>(); + test_derived_from<B2, B>(); + test_derived_from<B, B>(); + + test_not_derived_from<D, B>(); + test_not_derived_from<D, B1>(); + test_not_derived_from<D, B2>(); + test_not_derived_from<B, D>(); + test_not_derived_from<D&, B&>(); + test_not_derived_from<D[3], B[3]>(); + test_not_derived_from<int, int>(); +} Index: test/std/concepts/concepts.lang/concept.convertibleto/convertible_to.pass.cpp =================================================================== --- /dev/null +++ test/std/concepts/concepts.lang/concept.convertibleto/convertible_to.pass.cpp @@ -0,0 +1,298 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <cassert> +#include <concepts> + +template <class From, class To> +void test_convertible_to() { + static_assert(std::ConvertibleTo<From, To>); + static_assert(std::ConvertibleTo<const From, To>); + static_assert(std::ConvertibleTo<From, const To>); + static_assert(std::ConvertibleTo<const From, const To>); +} + +template <class From, class To> +void test_not_convertible_to() { + static_assert(!std::ConvertibleTo<From, To>); + static_assert(!std::ConvertibleTo<const From, To>); + static_assert(!std::ConvertibleTo<From, const To>); + static_assert(!std::ConvertibleTo<const From, const To>); +} + +using Function = void(); +using ConstFunction = void() const; +using Array = char[1]; + +struct StringType { + StringType(const char*) {} +}; + +class NonCopyable { + NonCopyable(NonCopyable&); +}; + +template <typename T> +class CannotInstantiate { + enum { X = T::ThisExpressionWillBlowUp }; +}; + +namespace X { + struct A { A() = default; A(int) {} }; + + enum class result { + exact, convertible, unrelated + }; + + result f(A) { + return result::exact; + } + + template <std::ConvertibleTo<A> T> + result f(T&&) { + return result::convertible; + } + + template <class T> + result f(T) { + return result::unrelated; + } +} // unnamed namespace + +int main() { + // void + test_convertible_to<void, void>(); + test_not_convertible_to<void, Function>(); + test_not_convertible_to<void, Function&>(); + test_not_convertible_to<void, Function*>(); + test_not_convertible_to<void, Array>(); + test_not_convertible_to<void, Array&>(); + test_not_convertible_to<void, char>(); + test_not_convertible_to<void, char&>(); + test_not_convertible_to<void, char*>(); + test_not_convertible_to<char, void>(); + + // Function + test_not_convertible_to<Function, void>(); + test_not_convertible_to<Function, Function>(); + test_convertible_to<Function, Function&>(); + test_convertible_to<Function, Function*>(); + test_convertible_to<Function, Function*const>(); + + static_assert(std::ConvertibleTo<Function, Function&&>); + + test_not_convertible_to<Function, Array>(); + test_not_convertible_to<Function, Array&>(); + test_not_convertible_to<Function, char>(); + test_not_convertible_to<Function, char&>(); + test_not_convertible_to<Function, char*>(); + + // Function& + test_not_convertible_to<Function&, void>(); + test_not_convertible_to<Function&, Function>(); + test_convertible_to<Function&, Function&>(); + + test_convertible_to<Function&, Function*>(); + test_not_convertible_to<Function&, Array>(); + test_not_convertible_to<Function&, Array&>(); + test_not_convertible_to<Function&, char>(); + test_not_convertible_to<Function&, char&>(); + test_not_convertible_to<Function&, char*>(); + + // Function* + test_not_convertible_to<Function*, void>(); + test_not_convertible_to<Function*, Function>(); + test_not_convertible_to<Function*, Function&>(); + test_convertible_to<Function*, Function*>(); + + test_not_convertible_to<Function*, Array>(); + test_not_convertible_to<Function*, Array&>(); + test_not_convertible_to<Function*, char>(); + test_not_convertible_to<Function*, char&>(); + test_not_convertible_to<Function*, char*>(); + + // Non-referencable function type + static_assert(!std::ConvertibleTo<ConstFunction, Function>); + static_assert(!std::ConvertibleTo<ConstFunction, Function*>); + static_assert(!std::ConvertibleTo<ConstFunction, Function&>); + static_assert(!std::ConvertibleTo<ConstFunction, Function&&>); + static_assert(!std::ConvertibleTo<Function*, ConstFunction>); + static_assert(!std::ConvertibleTo<Function&, ConstFunction>); + static_assert(!std::ConvertibleTo<ConstFunction, ConstFunction>); + static_assert(!std::ConvertibleTo<ConstFunction, void>); + + // Array + test_not_convertible_to<Array, void>(); + test_not_convertible_to<Array, Function>(); + test_not_convertible_to<Array, Function&>(); + test_not_convertible_to<Array, Function*>(); + test_not_convertible_to<Array, Array>(); + + static_assert(!std::ConvertibleTo<Array, Array&>); + static_assert( std::ConvertibleTo<Array, const Array&>); + static_assert(!std::ConvertibleTo<Array, const volatile Array&>); + + static_assert(!std::ConvertibleTo<const Array, Array&>); + static_assert( std::ConvertibleTo<const Array, const Array&>); + static_assert(!std::ConvertibleTo<Array, volatile Array&>); + static_assert(!std::ConvertibleTo<Array, const volatile Array&>); + + static_assert( std::ConvertibleTo<Array, Array&&>); + static_assert( std::ConvertibleTo<Array, const Array&&>); + static_assert( std::ConvertibleTo<Array, volatile Array&&>); + static_assert( std::ConvertibleTo<Array, const volatile Array&&>); + static_assert( std::ConvertibleTo<const Array, const Array&&>); + static_assert(!std::ConvertibleTo<Array&, Array&&>); + static_assert(!std::ConvertibleTo<Array&&, Array&>); + + test_not_convertible_to<Array, char>(); + test_not_convertible_to<Array, char&>(); + + static_assert(std::ConvertibleTo<Array, char*>); + static_assert(std::ConvertibleTo<Array, const char*>); + static_assert(std::ConvertibleTo<Array, char* const>); + static_assert(std::ConvertibleTo<Array, char* const volatile>); + + static_assert(!std::ConvertibleTo<const Array, char*>); + static_assert( std::ConvertibleTo<const Array, const char*>); + + static_assert(!std::ConvertibleTo<char[42][42], char*>); + static_assert(!std::ConvertibleTo<char[][1], char*>); + + // Array& + test_not_convertible_to<Array&, void>(); + test_not_convertible_to<Array&, Function>(); + test_not_convertible_to<Array&, Function&>(); + test_not_convertible_to<Array&, Function*>(); + test_not_convertible_to<Array&, Array>(); + + static_assert( std::ConvertibleTo<Array&, Array&>); + static_assert( std::ConvertibleTo<Array&, const Array&>); + static_assert(!std::ConvertibleTo<const Array&, Array&>); + static_assert( std::ConvertibleTo<const Array&, const Array&>); + + test_not_convertible_to<Array&, char>(); + test_not_convertible_to<Array&, char&>(); + + static_assert( std::ConvertibleTo<Array&, char*>); + static_assert( std::ConvertibleTo<Array&, const char*>); + static_assert(!std::ConvertibleTo<const Array&, char*>); + static_assert( std::ConvertibleTo<const Array&, const char*>); + + static_assert(std::ConvertibleTo<Array, StringType>); + static_assert(std::ConvertibleTo<char(&)[], StringType>); + + // char + test_not_convertible_to<char, void>(); + test_not_convertible_to<char, Function>(); + test_not_convertible_to<char, Function&>(); + test_not_convertible_to<char, Function*>(); + test_not_convertible_to<char, Array>(); + test_not_convertible_to<char, Array&>(); + + test_convertible_to<char, char>(); + + static_assert(!std::ConvertibleTo<char, char&>); + static_assert( std::ConvertibleTo<char, const char&>); + static_assert(!std::ConvertibleTo<const char, char&>); + static_assert( std::ConvertibleTo<const char, const char&>); + + test_not_convertible_to<char, char*>(); + + // char& + test_not_convertible_to<char&, void>(); + test_not_convertible_to<char&, Function>(); + test_not_convertible_to<char&, Function&>(); + test_not_convertible_to<char&, Function*>(); + test_not_convertible_to<char&, Array>(); + test_not_convertible_to<char&, Array&>(); + + test_convertible_to<char&, char>(); + + static_assert( std::ConvertibleTo<char&, char&>); + static_assert( std::ConvertibleTo<char&, const char&>); + static_assert(!std::ConvertibleTo<const char&, char&>); + static_assert( std::ConvertibleTo<const char&, const char&>); + + test_not_convertible_to<char&, char*>(); + + // char* + test_not_convertible_to<char*, void>(); + test_not_convertible_to<char*, Function>(); + test_not_convertible_to<char*, Function&>(); + test_not_convertible_to<char*, Function*>(); + test_not_convertible_to<char*, Array>(); + test_not_convertible_to<char*, Array&>(); + + test_not_convertible_to<char*, char>(); + test_not_convertible_to<char*, char&>(); + + static_assert( std::ConvertibleTo<char*, char*>); + static_assert( std::ConvertibleTo<char*, const char*>); + static_assert(!std::ConvertibleTo<const char*, char*>); + static_assert( std::ConvertibleTo<const char*, const char*>); + + // NonCopyable + static_assert( std::ConvertibleTo<NonCopyable&, NonCopyable&>); + static_assert( std::ConvertibleTo<NonCopyable&, const NonCopyable&>); + static_assert( std::ConvertibleTo<NonCopyable&, const volatile NonCopyable&>); + static_assert( std::ConvertibleTo<NonCopyable&, volatile NonCopyable&>); + static_assert( std::ConvertibleTo<const NonCopyable&, const NonCopyable&>); + static_assert( std::ConvertibleTo<const NonCopyable&, const volatile NonCopyable&>); + static_assert( std::ConvertibleTo<volatile NonCopyable&, const volatile NonCopyable&>); + static_assert( std::ConvertibleTo<const volatile NonCopyable&, const volatile NonCopyable&>); + static_assert(!std::ConvertibleTo<const NonCopyable&, NonCopyable&>); + + test_not_convertible_to<NonCopyable&, NonCopyable>(); + + // Ensure that CannotInstantiate is not instantiated by is_convertible when it is not needed. + // For example CannotInstantiate is instatiated as a part of ADL lookup for arguments of type CannotInstantiate*. + static_assert(std::ConvertibleTo<CannotInstantiate<int>*, CannotInstantiate<int>*>); + + { + using namespace X; + assert(f(A{}) == result::exact); + { const A a{}; assert(f(a) == result::exact); } + assert(f(42) == result::convertible); + assert(f("foo") == result::unrelated); + } + + { + struct B {}; + struct D : B {}; + + test_convertible_to<B, B>(); + test_convertible_to<D, D>(); + test_convertible_to<D, B>(); + test_not_convertible_to<B, D>(); + } + + { + struct Z; + struct X { + X() = default; + explicit X(Z) = delete; + }; + struct Y1 { + operator X() const; + }; + struct Y2 { + explicit operator X() const; + }; + struct Z { + operator X() const; + }; + test_convertible_to<Y1, X>(); // Both implicitly and explicitly convertible + test_not_convertible_to<Y2, X>(); // Only explicitly convertible + test_not_convertible_to<Z, X>(); // Only implicitly convertible + } +} Index: test/std/concepts/concepts.lang/concept.commonref/common_reference.pass.cpp =================================================================== --- /dev/null +++ test/std/concepts/concepts.lang/concept.commonref/common_reference.pass.cpp @@ -0,0 +1,173 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +#include <concepts> +#include <functional> +#include <type_traits> + +using std::CommonReference; +using std::void_t; + +template <class, class = void> +constexpr bool is_trait = false; +template <class T> +constexpr bool is_trait<T, std::void_t<typename T::type>> = true; + +struct X {}; +struct Y { explicit Y(X){} }; + +namespace std +{ + template <> struct common_type<X, Y> { using type = Y; }; + template <> struct common_type<Y, X> { using type = Y; }; +} + +static_assert(std::is_same<std::common_reference_t<int&&, int const&, int volatile&>, int const volatile&>()); +static_assert(std::is_same<std::common_reference_t<int&&, int const&, float&>, float>()); +static_assert(!is_trait<std::common_reference<int, short, int, char*>>); + +static_assert(std::is_same<std::common_reference_t<int, short>, int>::value); +static_assert(std::is_same<std::common_reference_t<int, short&>, int>::value); +static_assert(std::is_same<std::common_reference_t<int&, short&>, int>::value); +static_assert(std::is_same<std::common_reference_t<int&, short>, int>::value); + +// tricky volatile reference case +static_assert(std::is_same<std::common_reference_t<int&&, int volatile&>, int>::value); +static_assert(std::is_same<std::common_reference_t<int volatile&, int&&>, int>::value); +static_assert(std::is_same<std::common_reference_t<int const volatile&&, int volatile&&>, int const volatile&&>::value); +static_assert(std::is_same<std::common_reference_t<int&&, int const&, int volatile&>, int const volatile&>()); + +// Array types?? Yup! +static_assert(std::is_same<std::common_reference_t<int (&)[10], int (&&)[10]>, int const(&)[10]>::value); +static_assert(std::is_same<std::common_reference_t<int const (&)[10], int volatile (&)[10]>, int const volatile(&)[10]>::value); +static_assert(std::is_same<std::common_reference_t<int (&)[10], int (&)[11]>, int *>::value); + +struct X2 {}; +struct Y2 {}; +struct Z2 {}; + +namespace std +{ + template <> + struct common_type<X2, Y2> + { + using type = Z2; + }; + template <> + struct common_type<Y2, X2> + { + using type = Z2; + }; +} // namespace std + +template <class T, class U> +void test_common_ref() { + static_assert(CommonReference<T, U>); + static_assert(CommonReference<U, T>); +} + +template <class T, class U> +void test_not_common_ref() { + static_assert(!CommonReference<T, U>); + static_assert(!CommonReference<U, T>); +} + +int main() { + test_common_ref<int, int>(); + test_common_ref<int, double>(); + test_common_ref<double, int>(); + test_common_ref<double, double>(); + test_not_common_ref<void, int>(); + test_not_common_ref<int*, int>(); + test_common_ref<void*, int*>(); + test_common_ref<double,long long>(); + test_common_ref<void, void>(); + + test_not_common_ref<X, Y>(); + + { + struct AA { + AA() = default; + AA(AA&&) = delete; + AA(AA const&) = delete; + }; + struct BB : AA { }; + + test_common_ref<AA&, BB&>(); + test_common_ref<AA&&, BB&&>(); + test_not_common_ref<AA, BB>(); + } + + { + struct B {}; + struct D : B {}; + + test_common_ref<B&, D&>(); + test_common_ref<B&, D const&>(); + test_common_ref<B const&, D&>(); + test_common_ref<B const&, D const&>(); + + test_common_ref<B&&, D&&>(); + test_common_ref<B&&, D const&&>(); + test_common_ref<B const&&, D&&>(); + test_common_ref<B const&&, D const&&>(); + + test_common_ref<B&, D&&>(); + test_common_ref<B&, D const&&>(); + test_common_ref<B const&, D&&>(); + test_common_ref<B const&, D const&&>(); + + test_common_ref<B&&, D&>(); + test_common_ref<B&&, D const&>(); + test_common_ref<B const&&, D&>(); + test_common_ref<B const&&, D const&>(); + + test_common_ref<B&&, D&&>(); + test_common_ref<B&&, D const&&>(); + test_common_ref<B const&&, D&&>(); + test_common_ref<B const&&, D const&&>(); + } + + { + // https://github.com/ericniebler/stl2/issues/338 + struct MyIntRef { MyIntRef(int&); }; + test_common_ref<int&, MyIntRef>(); + } + + { + struct noncopyable { + noncopyable() = default; + noncopyable(noncopyable&&) = default; + noncopyable& operator=(noncopyable&&) = default; + }; + struct noncopyable2 : noncopyable {}; + + test_not_common_ref<noncopyable const&, noncopyable>(); + test_common_ref<noncopyable const&, noncopyable&>(); + test_not_common_ref<noncopyable2 const&, noncopyable>(); + test_common_ref<noncopyable2 const&, noncopyable&&>(); + test_not_common_ref<noncopyable const&, noncopyable2>(); + test_common_ref<noncopyable const&, noncopyable2 const&>(); + } + + { + static_assert(std::is_same_v<Z2, + std::common_reference_t<X2&, Y2 const&>>); + test_not_common_ref<X2&, Y2 const&>(); + } + + { + struct B {}; + struct C { C() = default; C(B); C(int); }; + test_common_ref<B, C>(); + } +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits