From a2c54165bd9d83cef677e25ea601481fe440f108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20M=C3=BCller?= Date: Sat, 21 Jan 2017 22:44:53 +0100 Subject: [PATCH] Add cpp_enum and cpp_enum_value --- include/cppast/cpp_entity_type.hpp | 3 + include/cppast/cpp_enum.hpp | 114 +++++++++++++++++++++++ include/cppast/cpp_namespace.hpp | 2 +- include/cppast/detail/intrusive_list.hpp | 2 +- src/cpp_entity_type.cpp | 4 + src/cpp_enum.cpp | 19 ++++ 6 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 include/cppast/cpp_enum.hpp create mode 100644 src/cpp_enum.cpp diff --git a/include/cppast/cpp_entity_type.hpp b/include/cppast/cpp_entity_type.hpp index 8fb0ea5..12b8542 100644 --- a/include/cppast/cpp_entity_type.hpp +++ b/include/cppast/cpp_entity_type.hpp @@ -19,6 +19,9 @@ namespace cppast using_directive_t, using_declaration_t, + enum_t, + enum_value_t, + count, }; diff --git a/include/cppast/cpp_enum.hpp b/include/cppast/cpp_enum.hpp new file mode 100644 index 0000000..cdea2d6 --- /dev/null +++ b/include/cppast/cpp_enum.hpp @@ -0,0 +1,114 @@ +// 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_ENUM_HPP_INCLUDED +#define CPPAST_CPP_ENUM_HPP_INCLUDED + +#include + +#include + +#include +#include +#include +#include +#include + +namespace cppast +{ + /// A [cppast::cpp_entity]() modelling the value of an [cppast::cpp_enum](). + class cpp_enum_value final : public cpp_entity + { + public: + /// \returns A newly created and registered enum value. + /// \notes `value` may be `nullptr`, in which case the enum has an implicit value. + static std::unique_ptr build( + const cpp_entity_index& idx, cpp_entity_id id, std::string name, + std::unique_ptr value = nullptr) + { + auto result = std::unique_ptr( + new cpp_enum_value(std::move(name), std::move(value))); + idx.register_entity(std::move(id), type_safe::ref(*result)); + return result; + } + + /// \returns A [ts::optional_ref]() to the [cppast::cpp_expression]() that is the enum value. + /// \notes It only has an associated expression if the value is explictly given. + type_safe::optional_ref value() const noexcept + { + return type_safe::opt_cref(value_.get()); + } + + private: + cpp_enum_value(std::string name, std::unique_ptr value) + : cpp_entity(std::move(name)), value_(std::move(value)) + { + } + + cpp_entity_type do_get_entity_type() const noexcept override; + + std::unique_ptr value_; + }; + + /// A [cppast::cpp_entity]() modelling a C++ enumeration. + class cpp_enum final : public cpp_entity, public cpp_entity_container + { + public: + /// Builds a [cppast::cpp_enum](). + class builder + { + public: + /// \effects Sets the name, underlying type and whether it is scoped. + /// \notes The underlying type may be `nullptr` if it is not explictly given. + builder(std::string name, bool scoped, std::unique_ptr type = nullptr) + : enum_(new cpp_enum(std::move(name), std::move(type), scoped)) + { + } + + /// \effects Adds a [cppast::cpp_enum_value](). + void add_value(std::unique_ptr value) + { + enum_->add_child(std::move(value)); + } + + /// \effects Registers the enum in the [cppast::cpp_entity_index](), + /// using the given [cppast::cpp_entity_id](). + /// \returns The finished enum. + std::unique_ptr finish(const cpp_entity_index& idx, cpp_entity_id id) noexcept + { + idx.register_entity(std::move(id), type_safe::ref(*enum_)); + return std::move(enum_); + } + + private: + std::unique_ptr enum_; + }; + + /// \returns A [ts::optional_ref]() to the underlying [cppast::cpp_type]() of the enum. + /// \notes It only has an associated underlying type if it is not explictly given. + type_safe::optional_ref underlying_type() const noexcept + { + return type_safe::opt_cref(type_.get()); + } + + /// \returns Whether or not it is a scoped enumeration (i.e. an `enum class`). + bool is_scoped() const noexcept + { + return scoped_; + } + + private: + cpp_enum(std::string name, std::unique_ptr type, bool scoped) + : cpp_entity(std::move(name)), type_(std::move(type)), scoped_(scoped) + { + } + + cpp_entity_type do_get_entity_type() const noexcept override; + + std::unique_ptr type_; + bool scoped_; + }; +} // namespace cppast + +#endif // CPPAST_CPP_ENUM_HPP_INCLUDED diff --git a/include/cppast/cpp_namespace.hpp b/include/cppast/cpp_namespace.hpp index f76cbe4..e92f251 100644 --- a/include/cppast/cpp_namespace.hpp +++ b/include/cppast/cpp_namespace.hpp @@ -33,7 +33,7 @@ namespace cppast namespace_->add_child(std::move(child)); } - /// \effects Registers the file in the [cppast::cpp_entity_index](), + /// \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, diff --git a/include/cppast/detail/intrusive_list.hpp b/include/cppast/detail/intrusive_list.hpp index c7e0015..ee68e89 100644 --- a/include/cppast/detail/intrusive_list.hpp +++ b/include/cppast/detail/intrusive_list.hpp @@ -45,7 +45,7 @@ namespace cppast { static_assert(std::is_base_of::value, "must be a base"); obj.next_ = std::move(node); - return obj.next_.get(); + return static_cast(obj.next_.get()); } template diff --git a/src/cpp_entity_type.cpp b/src/cpp_entity_type.cpp index 4cc4ab6..7fec11a 100644 --- a/src/cpp_entity_type.cpp +++ b/src/cpp_entity_type.cpp @@ -10,11 +10,15 @@ bool cppast::is_type(cpp_entity_type type) noexcept { switch (type) { + case cpp_entity_type::enum_t: + return true; + case cpp_entity_type::file_t: case cpp_entity_type::namespace_t: case cpp_entity_type::namespace_alias_t: case cpp_entity_type::using_directive_t: case cpp_entity_type::using_declaration_t: + case cpp_entity_type::enum_value_t: case cpp_entity_type::count: break; } diff --git a/src/cpp_enum.cpp b/src/cpp_enum.cpp new file mode 100644 index 0000000..2e84cea --- /dev/null +++ b/src/cpp_enum.cpp @@ -0,0 +1,19 @@ +// 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_type cpp_enum_value::do_get_entity_type() const noexcept +{ + return cpp_entity_type::enum_value_t; +} + +cpp_entity_type cpp_enum::do_get_entity_type() const noexcept +{ + return cpp_entity_type::enum_t; +}