// Copyright (C) 2017-2022 Jonathan Müller and cppast contributors // SPDX-License-Identifier: MIT #include #include #include "test_parser.hpp" using namespace cppast; TEST_CASE("cpp_concept") { if (libclang_parser::libclang_minor_version() < 60) return; auto code = R"( #include /// template /// concept a = requires(T t, int i) /// { /// {t.a()}; /// {t.b()} -> std::copy_constructible; /// {t.c(i)} -> std::same_as; /// typename T::inner; /// }; template concept a = requires(T t, int i) { {t.a()}; {t.b()} -> std::copy_constructible; {t.c(i)} -> std::same_as; typename T::inner; }; /// template /// concept b = a && std::constructible_from; template concept b = a && std::constructible_from; /// template /// void f1(T param); template requires a void f1(T param); /// template /// void f2(T param); template void f2(T param); /// template T> /// void f3(T param); template T> void f3(T param); )"; cpp_entity_index idx; auto file = parse(idx, "cpp_concept.cpp", code, false, cppast::cpp_standard::cpp_20); auto count = test_visit(*file, [&](const cpp_concept& con) {}, false); REQUIRE(count == 2u); count = test_visit(*file, [&](const cpp_function_template& tfunc) { REQUIRE(is_templated(tfunc.function())); REQUIRE(!tfunc.scope_name()); check_template_parameters(tfunc, {{cpp_entity_kind::template_type_parameter_t, "T"}}); if(tfunc.name() == "f1") { REQUIRE( static_cast(*tfunc.parameters().begin()).keyword() == cpp_template_keyword::keyword_typename); } else if (tfunc.name() == "f2" || tfunc.name() == "f3") { REQUIRE(static_cast(*tfunc.parameters().begin()) .keyword() == cpp_template_keyword::concept_contraint); } }); REQUIRE(count == 3u); }