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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits