diff --git a/include/cppast/cpp_enum.hpp b/include/cppast/cpp_enum.hpp index aae1965..e8b10d2 100644 --- a/include/cppast/cpp_enum.hpp +++ b/include/cppast/cpp_enum.hpp @@ -64,9 +64,9 @@ namespace cppast { 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)) + builder(std::string name, bool scoped, std::unique_ptr type, + bool explicit_type) + : enum_(new cpp_enum(std::move(name), std::move(type), explicit_type, scoped)) { } @@ -105,11 +105,16 @@ namespace cppast 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 + /// \returns A reference to the underlying [cppast::cpp_type]() of the enum. + const cpp_type& underlying_type() const noexcept { - return type_safe::opt_cref(type_.get()); + return *type_; + } + + /// \returns Whether or not the underlying type is explictly given. + bool has_explicit_type() const noexcept + { + return type_given_; } /// \returns Whether or not it is a scoped enumeration (i.e. an `enum class`). @@ -119,8 +124,11 @@ namespace cppast } private: - cpp_enum(std::string name, std::unique_ptr type, bool scoped) - : cpp_entity(std::move(name)), type_(std::move(type)), scoped_(scoped) + cpp_enum(std::string name, std::unique_ptr type, bool type_given, bool scoped) + : cpp_entity(std::move(name)), + type_(std::move(type)), + scoped_(scoped), + type_given_(type_given) { } @@ -131,7 +139,7 @@ namespace cppast type_safe::optional do_get_scope_name() const override; std::unique_ptr type_; - bool scoped_; + bool scoped_, type_given_; }; } // namespace cppast diff --git a/src/code_generator.cpp b/src/code_generator.cpp index 337357a..07a0645 100644 --- a/src/code_generator.cpp +++ b/src/code_generator.cpp @@ -205,10 +205,10 @@ namespace if (e.is_scoped()) output << whitespace << keyword("class"); output << whitespace << identifier(e.name()); - if (e.underlying_type()) + if (e.has_explicit_type()) { output << newl << punctuation(":"); - detail::write_type(output, e.underlying_type().value(), ""); + detail::write_type(output, e.underlying_type(), ""); } if (e.is_definition()) diff --git a/src/libclang/enum_parser.cpp b/src/libclang/enum_parser.cpp index 45d59fe..bcb4e3d 100644 --- a/src/libclang/enum_parser.cpp +++ b/src/libclang/enum_parser.cpp @@ -53,12 +53,11 @@ namespace detail::skip_attribute(stream); auto& name = stream.get().value(); - std::unique_ptr type; - if (detail::skip_if(stream, ":")) - // parse type, explictly given one - type = detail::parse_type(context, cur, clang_getEnumDeclIntegerType(cur)); + // parse type + auto type = detail::parse_type(context, cur, clang_getEnumDeclIntegerType(cur)); + auto type_given = detail::skip_if(stream, ":"); - return cpp_enum::builder(name.c_str(), scoped, std::move(type)); + return cpp_enum::builder(name.c_str(), scoped, std::move(type), type_given); } } diff --git a/test/cpp_enum.cpp b/test/cpp_enum.cpp index f6153e0..8b7c96c 100644 --- a/test/cpp_enum.cpp +++ b/test/cpp_enum.cpp @@ -54,7 +54,7 @@ enum c : int; REQUIRE(e.is_definition()); REQUIRE(!e.is_declaration()); REQUIRE(!e.is_scoped()); - REQUIRE(!e.underlying_type()); + REQUIRE(!e.has_explicit_type()); auto no_vals = 0u; for (auto& val : e) @@ -96,9 +96,8 @@ enum c : int; if (e.is_definition()) { - REQUIRE(e.underlying_type()); - REQUIRE(equal_types(idx, e.underlying_type().value(), - *cpp_builtin_type::build(cpp_int))); + REQUIRE(e.has_explicit_type()); + REQUIRE(equal_types(idx, e.underlying_type(), *cpp_builtin_type::build(cpp_int))); auto no_vals = 0u; for (auto& val : e) @@ -125,7 +124,7 @@ enum c : int; } else if (e.is_declaration()) { - REQUIRE(!e.underlying_type()); // no underlying type, implicit int + REQUIRE(!e.has_explicit_type()); // no underlying type, implicit int REQUIRE(count_children(e) == 0u); auto definition = get_definition(idx, e); @@ -141,9 +140,8 @@ enum c : int; REQUIRE(e.is_declaration()); REQUIRE(!e.is_definition()); REQUIRE(!e.is_scoped()); - REQUIRE(e.underlying_type().has_value()); - REQUIRE( - equal_types(idx, e.underlying_type().value(), *cpp_builtin_type::build(cpp_int))); + REQUIRE(e.has_explicit_type()); + REQUIRE(equal_types(idx, e.underlying_type(), *cpp_builtin_type::build(cpp_int))); REQUIRE(count_children(e) == 0u); auto definition = get_definition(idx, e);