From edb132981a653bb25477e539525f55bec617ea73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Wed, 1 Feb 2017 21:04:53 +0100 Subject: [PATCH] Add cpp_template_template_parameter --- include/cppast/cpp_entity_kind.hpp | 4 + include/cppast/cpp_namespace.hpp | 3 +- include/cppast/cpp_template_parameter.hpp | 93 ++++++++++++++++++++++- src/cpp_entity_kind.cpp | 41 ++++++++++ src/cpp_template_parameter.cpp | 11 +++ src/cpp_type.cpp | 1 + src/visitor.cpp | 3 + 7 files changed, 153 insertions(+), 3 deletions(-) diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index 2e77e46..c23a4bb 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -43,6 +43,7 @@ namespace cppast template_type_parameter_t, non_type_template_parameter_t, + template_template_parameter_t, alias_template_t, @@ -54,6 +55,9 @@ namespace cppast /// \returns Whether or not a given entity kind is a C++ type. bool is_type(cpp_entity_kind kind) noexcept; + + /// \returns Whether or not a given entity kind is a C++ template. + bool is_template(cpp_entity_kind kind) noexcept; } // namespace cppast #endif // CPPAST_CPP_ENTITY_KIND_HPP_INCLUDED diff --git a/include/cppast/cpp_namespace.hpp b/include/cppast/cpp_namespace.hpp index 13810eb..cbbe7ca 100644 --- a/include/cppast/cpp_namespace.hpp +++ b/include/cppast/cpp_namespace.hpp @@ -36,8 +36,7 @@ namespace cppast /// \effects Registers the namespace in the [cppast::cpp_entity_index](), /// using the given [cppast::cpp_entity_id](). /// \returns The finished namespace. - std::unique_ptr finish(const cpp_entity_index& idx, - cpp_entity_id id) noexcept + std::unique_ptr finish(const cpp_entity_index& idx, cpp_entity_id id) { idx.register_entity(std::move(id), type_safe::ref(*namespace_)); return std::move(namespace_); diff --git a/include/cppast/cpp_template_parameter.hpp b/include/cppast/cpp_template_parameter.hpp index 54ec1b7..ac8219e 100644 --- a/include/cppast/cpp_template_parameter.hpp +++ b/include/cppast/cpp_template_parameter.hpp @@ -5,7 +5,10 @@ #ifndef CPPAST_CPP_TEMPLATE_PARAMETER_HPP_INCLUDED #define CPPAST_CPP_TEMPLATE_PARAMETER_HPP_INCLUDED +#include + #include +#include #include namespace cppast @@ -124,7 +127,7 @@ namespace cppast cpp_template_type_parameter_ref parameter_; }; - /// A [cppast::cpp_entity]() modelling a non-type template parameter. + /// A [cppast::cpp_entity]() modelling a C++ non-type template parameter. class cpp_non_type_template_parameter final : public cpp_template_parameter, public cpp_variable_base { @@ -146,6 +149,94 @@ namespace cppast cpp_entity_kind do_get_entity_kind() const noexcept override; }; + + /// \exclude + namespace detail + { + struct cpp_template_ref_predicate + { + bool operator()(const cpp_entity& e); + }; + } // namespace detail + + class cpp_template; + + /// A reference to a [cppast::cpp_template](). + using cpp_template_ref = basic_cpp_entity_ref; + + /// A [cppast::cpp_entity]() modelling a C++ template template parameter. + class cpp_template_template_parameter final + : public cpp_template_parameter, + public cpp_entity_container + { + public: + /// Builds a [cppast::cpp_template_template_parameter](). + class builder + { + public: + /// \effects Sets the name and whether it is variadic. + builder(std::string name, bool variadic) + : parameter_(new cpp_template_template_parameter(std::move(name), variadic)) + { + } + + /// \effects Sets the keyword, + /// default is [cpp_template_keyword::keyword_class](). + void keyword(cpp_template_keyword kw) + { + parameter_->keyword_ = kw; + } + + /// \effects Adds a parameter to the template. + void add_parameter(std::unique_ptr param) + { + parameter_->add_child(std::move(param)); + } + + /// \effects Sets the default template. + void default_template(cpp_template_ref templ) + { + parameter_->default_ = std::move(templ); + } + + /// \effects Registers the parameter in the [cppast::cpp_entity_index](), + /// using the given [cppast::cpp_entity_id](). + /// \returns The finished parameter. + std::unique_ptr finish(const cpp_entity_index& idx, + cpp_entity_id id) + { + idx.register_entity(std::move(id), type_safe::ref(*parameter_)); + return std::move(parameter_); + } + + private: + std::unique_ptr parameter_; + }; + + /// \returns The keyword used in the template parameter. + cpp_template_keyword keyword() const noexcept + { + return keyword_; + } + + /// \returns A [ts::optional]() that is the default template. + type_safe::optional default_template() const noexcept + { + return default_; + } + + private: + cpp_template_template_parameter(std::string name, bool variadic) + : cpp_template_parameter(std::move(name), variadic), + keyword_(cpp_template_keyword::keyword_class) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + + type_safe::optional default_; + cpp_template_keyword keyword_; + }; } // namespace cppast #endif // CPPAST_CPP_TEMPLATE_PARAMETER_HPP_INCLUDED diff --git a/src/cpp_entity_kind.cpp b/src/cpp_entity_kind.cpp index 21b82ea..7986c0d 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -64,6 +64,8 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept return "template type parameter"; case cpp_entity_kind::non_type_template_parameter_t: return "non type template parameter"; + case cpp_entity_kind::template_template_parameter_t: + return "template template parameter"; case cpp_entity_kind::alias_template_t: return "alias template"; @@ -104,6 +106,7 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept case cpp_entity_kind::destructor_t: case cpp_entity_kind::template_type_parameter_t: case cpp_entity_kind::non_type_template_parameter_t: + case cpp_entity_kind::template_template_parameter_t: case cpp_entity_kind::alias_template_t: case cpp_entity_kind::count: break; @@ -111,3 +114,41 @@ bool cppast::is_type(cpp_entity_kind kind) noexcept return false; } + +bool cppast::is_template(cpp_entity_kind kind) noexcept +{ + switch (kind) + { + case cpp_entity_kind::alias_template_t: + return true; + + case cpp_entity_kind::file_t: + case cpp_entity_kind::language_linkage_t: + case cpp_entity_kind::namespace_t: + case cpp_entity_kind::namespace_alias_t: + case cpp_entity_kind::using_directive_t: + case cpp_entity_kind::using_declaration_t: + case cpp_entity_kind::type_alias_t: + case cpp_entity_kind::enum_t: + case cpp_entity_kind::enum_value_t: + case cpp_entity_kind::class_t: + case cpp_entity_kind::access_specifier_t: + case cpp_entity_kind::base_class_t: + case cpp_entity_kind::variable_t: + case cpp_entity_kind::member_variable_t: + case cpp_entity_kind::bitfield_t: + case cpp_entity_kind::function_parameter_t: + case cpp_entity_kind::function_t: + case cpp_entity_kind::member_function_t: + case cpp_entity_kind::conversion_op_t: + case cpp_entity_kind::constructor_t: + case cpp_entity_kind::destructor_t: + case cpp_entity_kind::template_type_parameter_t: + case cpp_entity_kind::non_type_template_parameter_t: + case cpp_entity_kind::template_template_parameter_t: + case cpp_entity_kind::count: + break; + } + + return false; +} diff --git a/src/cpp_template_parameter.cpp b/src/cpp_template_parameter.cpp index 1370d47..375b8cd 100644 --- a/src/cpp_template_parameter.cpp +++ b/src/cpp_template_parameter.cpp @@ -3,6 +3,7 @@ // found in the top-level directory of this distribution. #include + #include using namespace cppast; @@ -55,3 +56,13 @@ cpp_entity_kind cpp_non_type_template_parameter::do_get_entity_kind() const noex { return cpp_entity_kind::non_type_template_parameter_t; } + +bool detail::cpp_template_ref_predicate::operator()(const cpp_entity& e) +{ + return is_template(e.kind()); +} + +cpp_entity_kind cpp_template_template_parameter::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::template_template_parameter_t; +} diff --git a/src/cpp_type.cpp b/src/cpp_type.cpp index 0ddf58b..df6f715 100644 --- a/src/cpp_type.cpp +++ b/src/cpp_type.cpp @@ -101,6 +101,7 @@ bool cppast::is_valid(const cpp_type& type) noexcept case cpp_type_kind::builtin: case cpp_type_kind::user_defined: + case cpp_type_kind::template_parameter: case cpp_type_kind::unexposed: // no further check required/possible break; diff --git a/src/visitor.cpp b/src/visitor.cpp index 40953d8..b3015fb 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace cppast; @@ -58,6 +59,8 @@ bool detail::visit(const cpp_entity& e, detail::visitor_callback_t cb, void* fun return handle_container(e, cb, functor); case cpp_entity_kind::constructor_t: return handle_container(e, cb, functor); + case cpp_entity_kind::template_template_parameter_t: + return handle_container(e, cb, functor); case cpp_entity_kind::alias_template_t: return handle_container(e, cb, functor);