https://gcc.gnu.org/g:91f4550e1700b7fcc15baa37cbcd517cc02dc975
commit r15-5832-g91f4550e1700b7fcc15baa37cbcd517cc02dc975 Author: Jonathan Wakely <jwak...@redhat.com> Date: Mon Nov 25 13:52:19 2024 +0000 libstdc++: Move std::monostate to <utility> for C++26 (P0472R2) Another C++26 paper just approved in Wrocław. The std::monostate class is defined in <variant> since C++17, but for C++26 it should also be available in <utility>. libstdc++-v3/ChangeLog: * include/Makefile.am: Add bits/monostate.h. * include/Makefile.in: Regenerate. * include/std/utility: Include <bits/monostate.h>. * include/std/variant (monostate, hash<monostate>): Move definitions to ... * include/bits/monostate.h: New file. * testsuite/20_util/headers/utility/synopsis.cc: Add monostate and hash<monostate> declarations. * testsuite/20_util/monostate/requirements.cc: New test. Diff: --- libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/monostate.h | 78 ++++++++++++++++++++++ libstdc++-v3/include/std/utility | 4 ++ libstdc++-v3/include/std/variant | 31 +-------- .../testsuite/20_util/headers/utility/synopsis.cc | 5 ++ .../testsuite/20_util/monostate/requirements.cc | 38 +++++++++++ 7 files changed, 128 insertions(+), 30 deletions(-) diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 422a0f4bd0a8..6efd3cd5f1c8 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -133,6 +133,7 @@ bits_freestanding = \ ${bits_srcdir}/iterator_concepts.h \ ${bits_srcdir}/max_size_type.h \ ${bits_srcdir}/memoryfwd.h \ + ${bits_srcdir}/monostate.h \ ${bits_srcdir}/move.h \ ${bits_srcdir}/out_ptr.h \ ${bits_srcdir}/predefined_ops.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 9fd4ab4848c3..3b5f93ce185d 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -488,6 +488,7 @@ bits_freestanding = \ ${bits_srcdir}/iterator_concepts.h \ ${bits_srcdir}/max_size_type.h \ ${bits_srcdir}/memoryfwd.h \ + ${bits_srcdir}/monostate.h \ ${bits_srcdir}/move.h \ ${bits_srcdir}/out_ptr.h \ ${bits_srcdir}/predefined_ops.h \ diff --git a/libstdc++-v3/include/bits/monostate.h b/libstdc++-v3/include/bits/monostate.h new file mode 100644 index 000000000000..b6da720669a2 --- /dev/null +++ b/libstdc++-v3/include/bits/monostate.h @@ -0,0 +1,78 @@ +// Definition of std::monostate for <variant> and <utility> -*- C++ -*- + +// Copyright (C) 2016-2024 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file bits/monostate.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{utility} + */ + +#ifndef _GLIBCXX_MONOSTATE_H +#define _GLIBCXX_MONOSTATE_H 1 + +#include <bits/version.h> + +#ifdef __glibcxx_variant // C++ >= 17 + +#include <bits/functional_hash.h> +#if __cplusplus >= 202002L +# include <compare> +#endif + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + struct monostate { }; + + constexpr bool operator==(monostate, monostate) noexcept { return true; } +#ifdef __cpp_lib_three_way_comparison + constexpr strong_ordering + operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } +#else + constexpr bool operator!=(monostate, monostate) noexcept { return false; } + constexpr bool operator<(monostate, monostate) noexcept { return false; } + constexpr bool operator>(monostate, monostate) noexcept { return false; } + constexpr bool operator<=(monostate, monostate) noexcept { return true; } + constexpr bool operator>=(monostate, monostate) noexcept { return true; } +#endif + + template<> + struct hash<monostate> + { +#if __cplusplus < 202002L + using result_type [[__deprecated__]] = size_t; + using argument_type [[__deprecated__]] = monostate; +#endif + + size_t + operator()(const monostate&) const noexcept + { + constexpr size_t __magic_monostate_hash = -7777; + return __magic_monostate_hash; + } + }; + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // __glibcxx_variant +#endif /* _GLIBCXX_MONOSTATE_H */ diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility index 877e9a85c717..6b2943c821b3 100644 --- a/libstdc++-v3/include/std/utility +++ b/libstdc++-v3/include/std/utility @@ -81,6 +81,10 @@ #include <ext/numeric_traits.h> // __is_standard_integer, __int_traits #endif +#if __cplusplus > 202302L +# include <bits/monostate.h> +#endif + #define __glibcxx_want_addressof_constexpr #define __glibcxx_want_as_const #define __glibcxx_want_constexpr_algorithms diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 32e539980839..f46b553d78e4 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -45,6 +45,7 @@ #include <bits/exception_defines.h> #include <bits/functional_hash.h> #include <bits/invoke.h> +#include <bits/monostate.h> #include <bits/parse_numbers.h> // _Select_int #include <bits/stl_iterator_base_funcs.h> #include <bits/stl_construct.h> @@ -65,7 +66,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename... _Types> class tuple; template<typename... _Types> class variant; - template <typename> struct hash; template<typename _Variant> struct variant_size; @@ -1232,8 +1232,6 @@ namespace __variant return std::get_if<__n>(__ptr); } - struct monostate { }; - namespace __detail::__variant { template<typename _Ret, typename _Vp, typename _Op> @@ -1354,8 +1352,6 @@ namespace __detail::__variant }); } - constexpr bool operator==(monostate, monostate) noexcept { return true; } - #ifdef __cpp_lib_three_way_comparison template<typename... _Types> requires (three_way_comparable<_Types> && ...) @@ -1371,15 +1367,6 @@ namespace __detail::__variant return __l <=> __r; }); } - - constexpr strong_ordering - operator<=>(monostate, monostate) noexcept { return strong_ordering::equal; } -#else - constexpr bool operator!=(monostate, monostate) noexcept { return false; } - constexpr bool operator<(monostate, monostate) noexcept { return false; } - constexpr bool operator>(monostate, monostate) noexcept { return false; } - constexpr bool operator<=(monostate, monostate) noexcept { return true; } - constexpr bool operator>=(monostate, monostate) noexcept { return true; } #endif template<typename _Visitor, typename... _Variants> @@ -2030,22 +2017,6 @@ namespace __detail::__variant #endif { }; - template<> - struct hash<monostate> - { -#if __cplusplus < 202002L - using result_type [[__deprecated__]] = size_t; - using argument_type [[__deprecated__]] = monostate; -#endif - - size_t - operator()(const monostate&) const noexcept - { - constexpr size_t __magic_monostate_hash = -7777; - return __magic_monostate_hash; - } - }; - template<typename... _Types> struct __is_fast_hash<hash<variant<_Types...>>> : bool_constant<(__is_fast_hash<_Types>::value && ...)> diff --git a/libstdc++-v3/testsuite/20_util/headers/utility/synopsis.cc b/libstdc++-v3/testsuite/20_util/headers/utility/synopsis.cc index 51e88b70f514..73c3b51fa44c 100644 --- a/libstdc++-v3/testsuite/20_util/headers/utility/synopsis.cc +++ b/libstdc++-v3/testsuite/20_util/headers/utility/synopsis.cc @@ -137,6 +137,11 @@ namespace std { struct in_place_t; template<class> struct in_place_type_t; template<size_t> struct in_place_index_t; + +#if __cplusplus > 202302L + struct monostate; + template<> struct hash<monostate>; +#endif #endif #endif } diff --git a/libstdc++-v3/testsuite/20_util/monostate/requirements.cc b/libstdc++-v3/testsuite/20_util/monostate/requirements.cc new file mode 100644 index 000000000000..c385862c8857 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/monostate/requirements.cc @@ -0,0 +1,38 @@ +// { dg-do compile { target c++17 } } + +#if __cplusplus <= 202302L +# include <variant> +#else +# include <utility> +#endif + +void +test01() +{ + static_assert( std::is_nothrow_default_constructible_v<std::monostate> ); + static_assert( std::is_nothrow_copy_constructible_v<std::monostate> ); + static_assert( std::is_nothrow_copy_assignable_v<std::monostate> ); + static_assert( std::is_nothrow_destructible_v<std::monostate> ); +} + +void +test02() +{ +#ifdef __cpp_lib_three_way_comparison + static_assert( std::is_eq(std::monostate{} <=> std::monostate{}) ); +#endif + static_assert( std::monostate{} == std::monostate{} ); + static_assert( std::monostate{} <= std::monostate{} ); + static_assert( std::monostate{} >= std::monostate{} ); + static_assert( !(std::monostate{} != std::monostate{}) ); + static_assert( !(std::monostate{} < std::monostate{}) ); + static_assert( !(std::monostate{} > std::monostate{}) ); +} + +void +test03() +{ + std::monostate m; + std::hash<std::monostate> h; + static_assert( std::is_same_v<decltype(h(m)), std::size_t> ); +}