Always expose underlying type of enum

This commit is contained in:
Jonathan Müller 2017-04-06 11:51:31 +02:00
commit 251e9abf5f
4 changed files with 30 additions and 25 deletions

View file

@ -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<cpp_type> type = nullptr)
: enum_(new cpp_enum(std::move(name), std::move(type), scoped))
builder(std::string name, bool scoped, std::unique_ptr<cpp_type> 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<cpp_enum> 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<const cpp_type> 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<cpp_type> type, bool scoped)
: cpp_entity(std::move(name)), type_(std::move(type)), scoped_(scoped)
cpp_enum(std::string name, std::unique_ptr<cpp_type> 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<std::string> do_get_scope_name() const override;
std::unique_ptr<cpp_type> type_;
bool scoped_;
bool scoped_, type_given_;
};
} // namespace cppast

View file

@ -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())

View file

@ -53,12 +53,11 @@ namespace
detail::skip_attribute(stream);
auto& name = stream.get().value();
std::unique_ptr<cpp_type> 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);
}
}

View file

@ -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);