committing on behalf of the author Valentyn Yukhymenko: implement std::meta::is_explicit

Signed-off-by: mlevine55 <mlevine55@bloomberg.net>
This commit is contained in:
mlevine55
2025-10-16 10:57:51 -04:00
committed by Marek Polacek
parent dc939a43c2
commit 4b67ad0feb
3 changed files with 96 additions and 0 deletions

View File

@@ -1316,6 +1316,27 @@ eval_is_user_declared (tree r)
return boolean_false_node;
}
/* Process std::meta::is_explicit.
Returns: true if r represents
a member function that is declared explicit.
Otherwise, false.
If r represents a member function template
that is declared explicit, is_explicit(r)
is still false because in general such queries
for templates cannot be answered. */
static tree
eval_is_explicit (tree r)
{
r = MAYBE_BASELINK_FUNCTIONS (r);
r = OVL_FIRST (r);
if (TREE_CODE (r) == FUNCTION_DECL && DECL_NONCONVERTING_P (r))
return boolean_true_node;
else
return boolean_false_node;
}
/* Process std::meta::is_bit_field.
Returns: true if r represents a bit-field, or if r represents a data member
description (T,N,A,W,NUA) for which W is not _|_.. Otherwise, false. */
@@ -4598,6 +4619,8 @@ process_metafunction (const constexpr_ctx *ctx, tree call,
return eval_is_user_provided (h);
if (!strcmp (ident, "user_declared"))
return eval_is_user_declared (h);
if (!strcmp (ident, "explicit"))
return eval_is_explicit (h);
if (!strcmp (ident, "bit_field"))
return eval_is_bit_field (h);
if (!strcmp (ident, "enumerator"))

View File

@@ -0,0 +1,72 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Test std::meta::is_explicit.
#include <meta>
class Test {
public:
explicit Test(int)
{
int a;
static_assert (std::meta::is_explicit (std::meta::parent_of (^^a)));
}
Test(double)
{
int a;
static_assert (!std::meta::is_explicit (std::meta::parent_of (^^a)));
}
explicit operator bool();
operator int();
template<typename T>
explicit operator double();
void member_function();
virtual void virtual_function();
template <typename T>
void template_function(T param);
};
void function();
static_assert (std::meta::is_explicit (^^Test::Test)); // { dg-error "cannot take the reflection of an overload set" }
static_assert (!std::meta::is_explicit (^^Test::~Test));
static_assert (std::meta::is_explicit (^^Test::operator bool));
static_assert (!std::meta::is_explicit (^^Test::operator int));
static_assert (!std::meta::is_explicit (^^Test::operator double));
static_assert (!std::meta::is_explicit (^^Test::member_function));
static_assert (!std::meta::is_explicit (^^Test::virtual_function));
static_assert (!std::meta::is_explicit (^^Test::template_function));
static_assert (!std::meta::is_explicit (^^Test::template_function<int>));
static_assert (!std::meta::is_explicit (^^function));
static_assert (!std::meta::is_explicit (^^Test));
static_assert (!std::meta::is_explicit (^^::));
class Base {
public:
explicit operator int();
};
class Derived : public Base {
public:
explicit operator double();
operator bool();
};
static_assert (std::meta::is_explicit (^^Derived::operator int));
static_assert (std::meta::is_explicit (^^Derived::operator double));
static_assert (!std::meta::is_explicit (^^Derived::operator bool));
class EmptyClass {};
static_assert (!std::meta::is_explicit (^^EmptyClass::EmptyClass)); // { dg-error "cannot take the reflection of an overload set" }

View File

@@ -179,6 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_defaulted(info);
consteval bool is_user_provided(info);
consteval bool is_user_declared(info);
consteval bool is_explicit(info);
consteval bool is_bit_field(info);
consteval bool is_enumerator(info);