1// RUN: rm -rf %t 2// RUN: mkdir -p %t 3// RUN: split-file %s %t 4// 5// RUN: %clang_cc1 -std=c++20 %t/invocable.cppm -emit-module-interface -o %t/invocable.pcm 6// RUN: %clang_cc1 -std=c++20 %t/lambda.cppm -emit-module-interface -o %t/lambda.pcm -fprebuilt-module-path=%t 7// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify 8// 9// RUN: %clang_cc1 -std=c++20 %t/invocable.cppm -emit-reduced-module-interface -o %t/invocable.pcm 10// RUN: %clang_cc1 -std=c++20 %t/lambda.cppm -emit-reduced-module-interface -o %t/lambda.pcm -fprebuilt-module-path=%t 11// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify 12 13//--- invocable.cppm 14export module invocable; 15export template <class _Fn, class... _Args> 16concept invocable = requires(_Fn&& __fn, _Args&&... __args) { 17 _Fn(__args...); 18}; 19 20export template <class _Fn, class _Args> 21constexpr bool is_callable(_Fn&& __fn, _Args&& __args) { 22 return invocable<_Fn, _Args>; 23} 24 25export template <class _Fn> 26struct Callable : _Fn { 27 constexpr explicit Callable(_Fn &&__fn) : _Fn(static_cast<_Fn&&>(__fn)) {} 28 29 template <class _Args> 30 constexpr auto operator()(_Args&& __args) { 31 return _Fn(__args); 32 } 33}; 34 35//--- lambda.cppm 36export module lambda; 37import invocable; 38export constexpr auto l = Callable([](auto &&x){}); 39 40//--- test.cc 41// expected-no-diagnostics 42import invocable; 43import lambda; 44 45static_assert(is_callable(l, 4) == true); 46