From f75776df33ab438479cb2377f34968eee02e79e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Thu, 26 Jan 2017 17:56:50 +0100 Subject: [PATCH] Add cpp_alias_template --- include/cppast/cpp_alias_template.hpp | 40 ++++++++++++++ include/cppast/cpp_entity_kind.hpp | 2 + include/cppast/cpp_template.hpp | 76 +++++++++++++++++++++++++++ src/cpp_alias_template.cpp | 14 +++++ src/cpp_entity_kind.cpp | 4 ++ src/visitor.cpp | 3 ++ 6 files changed, 139 insertions(+) create mode 100644 include/cppast/cpp_alias_template.hpp create mode 100644 include/cppast/cpp_template.hpp create mode 100644 src/cpp_alias_template.cpp diff --git a/include/cppast/cpp_alias_template.hpp b/include/cppast/cpp_alias_template.hpp new file mode 100644 index 0000000..2cdd216 --- /dev/null +++ b/include/cppast/cpp_alias_template.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#ifndef CPPAST_CPP_ALIAS_TEMPLATE_HPP_INCLUDED +#define CPPAST_CPP_ALIAS_TEMPLATE_HPP_INCLUDED + +#include +#include + +namespace cppast +{ + /// A [cppast::cpp_entity]() modelling a C++ alias template. + class cpp_alias_template final : public cpp_template + { + public: + /// Builder for [cppast::cpp_alias_template](). + class builder : public basic_builder + { + public: + using basic_builder::basic_builder; + }; + + /// \returns A reference to the type alias that is being templated. + const cpp_type_alias& type_alias() const noexcept + { + return static_cast(*begin()); + } + + private: + cpp_alias_template(std::string name, std::unique_ptr alias) + : cpp_template(std::move(name), std::unique_ptr(alias.release())) + { + } + + cpp_entity_kind do_get_entity_kind() const noexcept override; + }; +} // namespace cppast + +#endif // CPPAST_CPP_ALIAS_TEMPLATE_HPP_INCLUDED diff --git a/include/cppast/cpp_entity_kind.hpp b/include/cppast/cpp_entity_kind.hpp index 5e8489e..2e77e46 100644 --- a/include/cppast/cpp_entity_kind.hpp +++ b/include/cppast/cpp_entity_kind.hpp @@ -44,6 +44,8 @@ namespace cppast template_type_parameter_t, non_type_template_parameter_t, + alias_template_t, + count, }; diff --git a/include/cppast/cpp_template.hpp b/include/cppast/cpp_template.hpp new file mode 100644 index 0000000..7152d82 --- /dev/null +++ b/include/cppast/cpp_template.hpp @@ -0,0 +1,76 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#ifndef CPPAST_CPP_TEMPLATE_HPP_INCLUDED +#define CPPAST_CPP_TEMPLATE_HPP_INCLUDED + +#include +#include +#include + +namespace cppast +{ + /// Base class for all entities modelling a C++ template of some kind. + /// + /// It is a container of a single [cppast::cpp_entity]() that is the entity being templated. + class cpp_template : public cpp_entity, public cpp_entity_container + { + public: + /// \returns An iteratable object iterating over the [cppast::cpp_template_parameter]() entities. + /// \notes These may be empty for a full specialization. + detail::iteratable_intrusive_list parameter_types() const noexcept + { + return type_safe::ref(parameters_); + } + + protected: + /// Builder class for templates. + /// + /// Inherit from it to provide additional setter. + template + class basic_builder + { + public: + /// \effects Sets the name and the entity that is begin templated. + basic_builder(std::string name, std::unique_ptr templ) + : template_entity(new T(name, std::move(templ))) + { + } + + /// \effects Adds a parameter. + void add_parameter(std::unique_ptr parameter) + { + static_cast(*template_entity) + .parameters_.push_back(*template_entity, std::move(parameter)); + } + + /// \effects Registers the template. + /// \returns The finished template. + std::unique_ptr finish(const cpp_entity_index& idx, cpp_entity_id id) + { + idx.register_entity(std::move(id), type_safe::cref(*template_entity)); + return std::move(template_entity); + } + + protected: + basic_builder() = default; + ~basic_builder() noexcept = default; + + std::unique_ptr template_entity; + }; + + /// \effects Sets the name of the template and the entity to be templated. + /// \notes It does not include the parameters. + cpp_template(std::string name, std::unique_ptr entity) + : cpp_entity(std::move(name)) + { + add_child(std::move(entity)); + } + + private: + detail::intrusive_list parameters_; + }; +} // namespace cppast + +#endif // CPPAST_CPP_TEMPLATE_HPP_INCLUDED diff --git a/src/cpp_alias_template.cpp b/src/cpp_alias_template.cpp new file mode 100644 index 0000000..f907b41 --- /dev/null +++ b/src/cpp_alias_template.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2017 Jonathan Müller +// This file is subject to the license terms in the LICENSE file +// found in the top-level directory of this distribution. + +#include + +#include + +using namespace cppast; + +cpp_entity_kind cpp_alias_template::do_get_entity_kind() const noexcept +{ + return cpp_entity_kind::alias_template_t; +} diff --git a/src/cpp_entity_kind.cpp b/src/cpp_entity_kind.cpp index f3edc00..21b82ea 100644 --- a/src/cpp_entity_kind.cpp +++ b/src/cpp_entity_kind.cpp @@ -65,6 +65,9 @@ const char* cppast::to_string(cpp_entity_kind kind) noexcept case cpp_entity_kind::non_type_template_parameter_t: return "non type template parameter"; + case cpp_entity_kind::alias_template_t: + return "alias template"; + case cpp_entity_kind::count: break; } @@ -101,6 +104,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::alias_template_t: case cpp_entity_kind::count: break; } diff --git a/src/visitor.cpp b/src/visitor.cpp index 28f7421..40953d8 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -57,6 +58,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::alias_template_t: + return handle_container(e, cb, functor); case cpp_entity_kind::namespace_alias_t: case cpp_entity_kind::using_directive_t: