Add basic concept support (#144)
This commit is contained in:
parent
f3e399573f
commit
a937efbcbc
21 changed files with 396 additions and 16 deletions
|
|
@ -14,6 +14,7 @@ set(tests
|
|||
cpp_attribute.cpp
|
||||
cpp_class.cpp
|
||||
cpp_class_template.cpp
|
||||
cpp_concept.cpp
|
||||
cpp_enum.cpp
|
||||
cpp_friend.cpp
|
||||
cpp_function.cpp
|
||||
|
|
|
|||
85
test/cpp_concept.cpp
Normal file
85
test/cpp_concept.cpp
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (C) 2017-2022 Jonathan Müller and cppast contributors
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <cppast/cpp_concept.hpp>
|
||||
|
||||
#include <cppast/cpp_function_template.hpp>
|
||||
|
||||
#include "test_parser.hpp"
|
||||
|
||||
using namespace cppast;
|
||||
|
||||
TEST_CASE("cpp_concept")
|
||||
{
|
||||
if (libclang_parser::libclang_minor_version() < 60)
|
||||
return;
|
||||
|
||||
auto code = R"(
|
||||
#include <concepts>
|
||||
|
||||
/// template<typename T>
|
||||
/// concept a = requires(T t, int i)
|
||||
/// {
|
||||
/// {t.a()};
|
||||
/// {t.b()} -> std::copy_constructible;
|
||||
/// {t.c(i)} -> std::same_as<int>;
|
||||
/// typename T::inner;
|
||||
/// };
|
||||
template<typename T>
|
||||
concept a = requires(T t, int i)
|
||||
{
|
||||
{t.a()};
|
||||
{t.b()} -> std::copy_constructible;
|
||||
{t.c(i)} -> std::same_as<int>;
|
||||
typename T::inner;
|
||||
};
|
||||
|
||||
/// template<typename T>
|
||||
/// concept b = a<T> && std::constructible_from<T, int>;
|
||||
template<typename T>
|
||||
concept b = a<T> && std::constructible_from<T, int>;
|
||||
|
||||
/// template<typename T>
|
||||
/// void f1(T param);
|
||||
template<typename T>
|
||||
requires a<T>
|
||||
void f1(T param);
|
||||
|
||||
/// template<b T>
|
||||
/// void f2(T param);
|
||||
template<b T>
|
||||
void f2(T param);
|
||||
|
||||
/// template<std::convertible_to<int> T>
|
||||
/// void f3(T param);
|
||||
template<std::convertible_to<int> 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<cpp_concept>(*file, [&](const cpp_concept& con) {}, false);
|
||||
REQUIRE(count == 2u);
|
||||
|
||||
count = test_visit<cpp_function_template>(*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<const cpp_template_type_parameter&>(*tfunc.parameters().begin()).keyword()
|
||||
== cpp_template_keyword::keyword_typename);
|
||||
}
|
||||
else if (tfunc.name() == "f2" || tfunc.name() == "f3")
|
||||
{
|
||||
REQUIRE(static_cast<const cpp_template_type_parameter&>(*tfunc.parameters().begin())
|
||||
.keyword()
|
||||
== cpp_template_keyword::concept_contraint);
|
||||
}
|
||||
});
|
||||
|
||||
REQUIRE(count == 3u);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue