From 853a13242542356226f38da87dce97f4fc7e52a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sun, 5 Feb 2017 20:46:13 +0100 Subject: [PATCH] Add cpp_template_instantiation_type --- include/cppast/cpp_function_template.hpp | 12 ++-- include/cppast/cpp_template.hpp | 80 +++++++++++++++++++++--- include/cppast/cpp_type.hpp | 1 + src/cpp_type.cpp | 1 + 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/include/cppast/cpp_function_template.hpp b/include/cppast/cpp_function_template.hpp index 0f81ea9..167e727 100644 --- a/include/cppast/cpp_function_template.hpp +++ b/include/cppast/cpp_function_template.hpp @@ -43,8 +43,8 @@ namespace cppast { public: /// Builder for [cppast::cpp_function_template_specialization](). - class builder : public specialization_builder + class builder + : public specialization_builder { public: using specialization_builder::specialization_builder; @@ -60,17 +60,15 @@ namespace cppast } private: - cpp_function_template_specialization( - std::unique_ptr func, - type_safe::object_ref primary) + cpp_function_template_specialization(std::unique_ptr func, + cpp_template_ref primary) : cpp_template_specialization(std::unique_ptr(func.release()), primary) { } cpp_entity_kind do_get_entity_kind() const noexcept override; - friend specialization_builder; + friend specialization_builder; }; } // namespace cppast diff --git a/include/cppast/cpp_template.hpp b/include/cppast/cpp_template.hpp index d404b13..c74cfe5 100644 --- a/include/cppast/cpp_template.hpp +++ b/include/cppast/cpp_template.hpp @@ -71,14 +71,73 @@ namespace cppast detail::intrusive_list parameters_; }; + /// A [cppast::cpp_type]() representing an instantiation of a [cppast::cpp_template](). + class cpp_template_instantiation_type final : public cpp_type + { + public: + /// Builds a [cppast::cpp_template_instantiation](). + class builder + { + public: + /// \effects Sets the primary template being instantiated. + builder(cpp_template_ref templ) + : result_(new cpp_template_instantiation_type(std::move(templ))) + { + } + + /// \effects Adds the next argument. + void add_argument(cpp_template_argument arg) + { + result_->arguments_.push_back(std::move(arg)); + } + + /// \returns The finished instantiation. + std::unique_ptr finish() + { + return std::move(result_); + } + + private: + std::unique_ptr result_; + }; + + /// \returns A reference to the template that is being instantiated. + /// \notes It could also point to a specialization, + /// this is just the *primary* template. + const cpp_template_ref& primary_template() const noexcept + { + return templ_; + } + + /// \returns An iteratable object iterating over the [cppast::cpp_template_argument]()s. + /// \exclude return + const std::vector& arguments() const noexcept + { + return arguments_; + } + + private: + cpp_template_instantiation_type(cpp_template_ref ref) : templ_(std::move(ref)) + { + } + + cpp_type_kind do_get_kind() const noexcept override + { + return cpp_type_kind::template_instantiation; + } + + std::vector arguments_; + cpp_template_ref templ_; + }; + /// Base class for all entities modelling a C++ template specialization. class cpp_template_specialization : public cpp_template { public: /// \returns A reference to the template that is being specialized. - const cpp_template& primary_template() const noexcept + cpp_template_ref primary_template() const noexcept { - return *templ_; + return cpp_template_ref(templ_, name()); } /// \returns An iteratable object iterating over the [cppast::cpp_template_argument]()s. @@ -99,13 +158,12 @@ namespace cppast /// Builder class for specializations. /// /// Inherit from it to provide additional setter. - template + template class specialization_builder : public basic_builder { public: /// \effects Sets the entity that is being templated and the primary template. - specialization_builder(std::unique_ptr entity, - type_safe::object_ref templ) + specialization_builder(std::unique_ptr entity, const cpp_template_ref& templ) { this->template_entity = std::unique_ptr(new T(std::move(entity), templ)); } @@ -123,15 +181,17 @@ namespace cppast }; /// \effects Sets the entity that is being templated and the primary template. - cpp_template_specialization(std::unique_ptr entity, - type_safe::object_ref templ) - : cpp_template(std::move(entity)), templ_(templ) + cpp_template_specialization(std::unique_ptr entity, + const cpp_template_ref& templ) + : cpp_template(std::move(entity)), templ_(templ.id()) { + DEBUG_ASSERT(templ.name() == entity->name(), detail::precondition_error_handler{}, + "invalid name of template ref"); } private: - std::vector arguments_; - type_safe::object_ref templ_; + std::vector arguments_; + cpp_entity_id templ_; }; } // namespace cppast diff --git a/include/cppast/cpp_type.hpp b/include/cppast/cpp_type.hpp index 741c5aa..b9ce686 100644 --- a/include/cppast/cpp_type.hpp +++ b/include/cppast/cpp_type.hpp @@ -28,6 +28,7 @@ namespace cppast member_object, template_parameter, + template_instantiation, unexposed, }; diff --git a/src/cpp_type.cpp b/src/cpp_type.cpp index 3d9007a..9d5e074 100644 --- a/src/cpp_type.cpp +++ b/src/cpp_type.cpp @@ -102,6 +102,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::template_instantiation: case cpp_type_kind::unexposed: // no further check required/possible break;