Tweaks from libstdc++-v3 reflection patch review.

This commit is contained in:
Jakub Jelinek
2025-11-15 11:14:00 +01:00
committed by Marek Polacek
parent b0cde4d637
commit 6ed71bbf5d
9 changed files with 79 additions and 175 deletions

View File

@@ -33,6 +33,11 @@
#pragma GCC system_header
#endif
#define __glibcxx_want_reflection
#include <bits/version.h>
#if __glibcxx_reflection >= 202506L // C++ >= 26 && __cpp_impl_reflection
#include <array>
#include <initializer_list>
#include <optional>
@@ -42,11 +47,6 @@
#include <string_view>
#include <vector>
#define __glibcxx_want_reflection
#include <bits/version.h>
#if __glibcxx_reflection >= 202506L // C++ >= 26 && __cpp_impl_reflection
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -94,15 +94,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
source_location _M_where;
public:
consteval exception(u8string_view __what, info __from,
source_location __where
= source_location::current()) noexcept
consteval
exception(u8string_view __what, info __from,
source_location __where = source_location::current()) noexcept
: _M_what{_S_exception_cvt_from_utf8(__what)}, _M_u8what{__what},
_M_from{__from}, _M_where{__where} {}
consteval exception(string_view __what, info __from,
source_location __where
= source_location::current()) noexcept
consteval
exception(string_view __what, info __from,
source_location __where = source_location::current()) noexcept
: _M_what{__what}, _M_u8what{_S_exception_cvt_to_utf8(__what)},
_M_from{__from}, _M_where{__where} {}
@@ -112,7 +112,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
exception& operator=(const exception&) = default;
exception& operator=(exception&&) = default;
consteval const char *what() const noexcept override
consteval const char*
what() const noexcept override
{
// If u8string is not empty and string is empty, conversion
// from UTF-8 to ordinary literal encoding failed.
@@ -128,10 +129,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Helper special template metafunctions to convert from UTF-8 to
// ordinary literal encoding and vice versa. On conversion failure
// they just return an empty {,u8}string_view.
template<ranges::input_range _R>
static consteval u8string_view _S_exception_cvt_to_utf8(_R&&);
template<ranges::input_range _R>
static consteval string_view _S_exception_cvt_from_utf8(_R&&);
template<ranges::input_range _Rg>
static consteval u8string_view _S_exception_cvt_to_utf8(_Rg&&);
template<ranges::input_range _Rg>
static consteval string_view _S_exception_cvt_from_utf8(_Rg&&);
};
// [meta.reflection.operators], operator representations
@@ -363,15 +364,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval _Tp extract(info);
// [meta.reflection.substitute], reflection substitution
template<class _R>
concept reflection_range = ranges::input_range<_R>
&& same_as<ranges::range_value_t<_R>, info>
&& same_as<remove_cvref_t<ranges::range_reference_t<_R>>, info>;
template<class _Rg>
concept reflection_range = ranges::input_range<_Rg>
&& same_as<ranges::range_value_t<_Rg>, info>
&& same_as<remove_cvref_t<ranges::range_reference_t<_Rg>>, info>;
template<reflection_range _R = initializer_list<info>>
consteval bool can_substitute(info, _R&&);
template<reflection_range _R = initializer_list<info>>
consteval info substitute(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool can_substitute(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info substitute(info, _Rg&&);
// [meta.reflection.result], expression result reflection
template<typename _Tp>
@@ -385,11 +386,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval info reflect_function(_Tp&);
// [meta.reflection.array], promoting to static storage arrays
template<ranges::input_range _R>
consteval info reflect_constant_string(_R&&);
template<ranges::input_range _Rg>
consteval info reflect_constant_string(_Rg&&);
template<ranges::input_range _R>
consteval info reflect_constant_array(_R&&);
template<ranges::input_range _Rg>
consteval info reflect_constant_array(_Rg&&);
// [meta.reflection.define.aggregate], class definition generation
struct data_member_options {
@@ -416,8 +417,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
consteval info data_member_spec(info, data_member_options);
consteval bool is_data_member_spec(info);
template<reflection_range _R = initializer_list<info>>
consteval info define_aggregate(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info define_aggregate(info, _Rg&&);
// associated with [meta.unary.cat], primary type categories
consteval bool is_void_type(info);
@@ -462,8 +463,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_unbounded_array_type(info);
consteval bool is_scoped_enum_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_constructible_type(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_constructible_type(info, _Rg&&);
consteval bool is_default_constructible_type(info);
consteval bool is_copy_constructible_type(info);
consteval bool is_move_constructible_type(info);
@@ -477,8 +478,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_destructible_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_trivially_constructible_type(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_trivially_constructible_type(info, _Rg&&);
consteval bool is_trivially_default_constructible_type(info);
consteval bool is_trivially_copy_constructible_type(info);
consteval bool is_trivially_move_constructible_type(info);
@@ -488,8 +489,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_trivially_move_assignable_type(info);
consteval bool is_trivially_destructible_type(info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_nothrow_constructible_type(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_constructible_type(info, _Rg&&);
consteval bool is_nothrow_default_constructible_type(info);
consteval bool is_nothrow_copy_constructible_type(info);
consteval bool is_nothrow_move_constructible_type(info);
@@ -525,15 +526,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
consteval bool is_layout_compatible_type(info, info);
consteval bool is_pointer_interconvertible_base_of_type(info, info);
template<reflection_range _R = initializer_list<info>>
consteval bool is_invocable_type(info, _R&&);
template<reflection_range _R = initializer_list<info>>
consteval bool is_invocable_r_type(info, info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_invocable_type(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_invocable_r_type(info, info, _Rg&&);
template<reflection_range _R = initializer_list<info>>
consteval bool is_nothrow_invocable_type(info, _R&&);
template<reflection_range _R = initializer_list<info>>
consteval bool is_nothrow_invocable_r_type(info, info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_invocable_type(info, _Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval bool is_nothrow_invocable_r_type(info, info, _Rg&&);
// associated with [meta.trans.cv], const-volatile modifications
consteval info remove_const(info);
@@ -563,13 +564,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// associated with [meta.trans.other], other transformations
consteval info remove_cvref(info);
consteval info decay(info);
template<reflection_range _R = initializer_list<info>>
consteval info common_type(_R&&);
template<reflection_range _R = initializer_list<info>>
consteval info common_reference(_R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info common_type(_Rg&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info common_reference(_Rg&&);
consteval info underlying_type(info);
template<reflection_range _R = initializer_list<info>>
consteval info invoke_result(info, _R&&);
template<reflection_range _Rg = initializer_list<info>>
consteval info invoke_result(info, _Rg&&);
consteval info unwrap_reference(info);
consteval info unwrap_ref_decay(info);
@@ -597,6 +598,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"or complete class type reflection",
^^access_context::via);
#else
asm("");
return *this;
#endif
}
@@ -606,19 +608,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} // namespace meta
// [meta.define.static], promoting to static storage strings
template<ranges::input_range _R>
consteval const ranges::range_value_t<_R>*
define_static_string(_R&& __r)
template<ranges::input_range _Rg>
consteval const ranges::range_value_t<_Rg>*
define_static_string(_Rg&& __r)
{
auto __str = meta::reflect_constant_string(__r);
return meta::extract<const ranges::range_value_t<_R>*>(__str);
return meta::extract<const ranges::range_value_t<_Rg>*>(__str);
}
template<ranges::input_range _R>
consteval span<const ranges::range_value_t<_R>>
define_static_array(_R&& __r)
template<ranges::input_range _Rg>
consteval span<const ranges::range_value_t<_Rg>>
define_static_array(_Rg&& __r)
{
using _Tp = ranges::range_value_t<_R>;
using _Tp = ranges::range_value_t<_Rg>;
auto __array = meta::reflect_constant_array(__r);
auto __type = meta::type_of(__array);
if (meta::is_array_type(__type))

View File

@@ -834,19 +834,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
/// is_fundamental
template<typename _Tp>
struct is_fundamental
: public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
is_null_pointer<_Tp>
#if __cpp_impl_reflection >= 202500L
template<typename _Tp>
struct is_fundamental
: public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
is_null_pointer<_Tp>, is_reflection<_Tp>>::type
{ };
#else
template<typename _Tp>
struct is_fundamental
: public __or_<is_arithmetic<_Tp>, is_void<_Tp>,
is_null_pointer<_Tp>>::type
{ };
, is_reflection<_Tp>
#endif
>::type
{ };
/// is_object
#if _GLIBCXX_USE_BUILTIN_TRAIT(__is_object)
@@ -3561,8 +3557,15 @@ template <typename _Tp>
#if __cpp_impl_reflection >= 202500L // C++ >= 26
template <typename _Tp>
inline constexpr bool is_reflection_v =
is_reflection<_Tp>::value;
inline constexpr bool is_reflection_v = false;
template <>
inline constexpr bool is_reflection_v<decltype(^^int)> = true;
template <>
inline constexpr bool is_reflection_v<const decltype(^^int)> = true;
template <>
inline constexpr bool is_reflection_v<volatile decltype(^^int)> = true;
template <>
inline constexpr bool is_reflection_v<const volatile decltype(^^int)> = true;
#endif
template <typename _Tp>

View File

@@ -1,23 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>

View File

@@ -1,24 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>

View File

@@ -1,23 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <type_traits>
#include <testsuite_tr1.h>

View File

@@ -1,23 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>

View File

@@ -1,24 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>

View File

@@ -1,23 +1,6 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <type_traits>
#include <testsuite_tr1.h>

View File

@@ -335,6 +335,9 @@ static_assert(!is_convertible_v<const int&, int&>
static_assert(is_reflection_v<decltype(^^int)>
&& is_reflection<decltype(^^int)>::value, "");
static_assert(!is_reflection_v<int> && !is_reflection<int>::value, "");
static_assert(is_consteval_only_v<decltype(^^int)>
&& is_consteval_only<decltype(^^int)>::value, "");
static_assert(!is_consteval_only_v<int> && !is_consteval_only<int>::value, "");
#endif
static_assert(negation_v<false_type>, "");