Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/g++.dg/concepts/generic-fn.C @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/g++.dg/concepts/generic-fn.C Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,157 @@ +// { dg-do run } +// { dg-options "-std=c++17 -fconcepts" } + +#include <cassert> +#include <type_traits> + +template<typename T> + concept bool C() { return __is_class(T); } + +template<typename T> + concept bool Type() { return true; } + +struct S { }; + +int called; + +// Basic terse notation +void f(auto x) { called = 1; } +void g(C x) { called = 2; } + +// Overloading generic functions +void h(auto x) { called = 1; } +void h(C x) { called = 2; } + +void p(auto x); +void p(C x); + +struct S1 { + void f1(auto x) { called = 1; } + void f2(C x) { called = 2; } + + void f3(auto x) { called = 1; } + void f3(C x) { called = 2; } +}; + +template<C T> + struct S2 { + void f1(auto x) { called = 1; } + void f2(C x) { called = 2; } + + void f3(auto x) { called = 1; } + void f3(C x) { called = 2; } + + void h1(auto x); + void h2(C x); + + void h3(auto x); + void h3(C x); + + template<C U> + void g1(T t, U u) { called = 1; } + + template<C U> + void g2(T t, U u); + }; + + +void ptr(C*) { called = 1; } +void ptr(const C*) { called = 2; } + +void ref(C&) { called = 1; } +void ref(const C&) { called = 2; } + +void +fwd_lvalue_ref(Type&& x) { + using T = decltype(x); + static_assert(std::is_lvalue_reference<T>::value, "not an lvlaue reference"); +} + +void +fwd_const_lvalue_ref(Type&& x) { + using T = decltype(x); + static_assert(std::is_lvalue_reference<T>::value, "not an lvalue reference"); + using U = typename std::remove_reference<T>::type; + static_assert(std::is_const<U>::value, "not const-qualified"); +} + +void fwd_rvalue_ref(Type&& x) { + using T = decltype(x); + static_assert(std::is_rvalue_reference<T>::value, "not an rvalue reference"); +} + +// Make sure we can use nested names speicifers for concept names. +namespace N { + template<typename T> + concept bool C() { return true; } +} // namesspace N + +void foo(N::C x) { } + +int main() { + S s; + const S cs; + + f(0); assert(called == 1); + g(s); assert(called == 2); + + h(0); assert(called == 1); + h(s); assert(called == 2); + + S1 s1; + s1.f1(0); assert(called == 1); + s1.f2(s); assert(called == 2); + + s1.f3(0); assert(called == 1); + s1.f3(s); assert(called == 2); + + S2<S> s2; + s2.f1(0); assert(called == 1); + s2.f2(s); assert(called == 2); + + s2.f3(0); assert(called == 1); + s2.f3(s); assert(called == 2); + + s2.h1(0); assert(called == 1); + s2.h2(s); assert(called == 2); + + s2.h3(0); assert(called == 1); + s2.h3(s); assert(called == 2); + + s2.g1(s, s); assert(called == 1); + s2.g2(s, s); assert(called == 2); + + ptr(&s); assert(called == 1); + ptr(&cs); assert(called == 2); + + ref(s); assert(called == 1); + ref(cs); assert(called == 2); + + // Check forwarding problems + fwd_lvalue_ref(s); + fwd_const_lvalue_ref(cs); + fwd_rvalue_ref(S()); + + foo(0); +} + +// Test that decl/def matching works. + +void p(auto x) { called = 1; } +void p(C x) { called = 2; } + +template<C T> + void S2<T>::h1(auto x) { called = 1; } + +template<C T> + void S2<T>::h2(C x) { called = 2; } + +template<C T> + void S2<T>::h3(auto x) { called = 1; } + +template<C T> + void S2<T>::h3(C x) { called = 2; } + +template<C T> + template<C U> + void S2<T>::g2(T t, U u) { called = 2; }