Move __is_specialization_of to bits/utility.h

Message ID CALtZhhOSG=zEGFEkY3-xDraVcXmKoBL6gznmVO+zOuxcQKt9xA@mail.gmail.com
State New
Headers
Series Move __is_specialization_of to bits/utility.h |

Commit Message

Frederick Virchanza Gotham Jan. 11, 2026, 12:47 p.m. UTC
  Currently the definition of the C++ template "__is_specialization_of"
is inside the header file "std/format".

I propose two reasons to move this to "bits/utility.h":

(1) To avoid code duplication, as other parts of libstdc++ may need it
in the future. Currently my implementation of "std::chimeric_ptr"
requires it.
(2) At some point, "std::is_specialization_of" will be added to
libstdc++, so again we want to avoid code duplication.

Note that when it's moved from 'std/format' to 'bits/utility.h', it
needs to be protected with "if __cplusplus >= 201402L".

Here is the patch:

From 76712db0fd1c7ab8c9067b344e6e3398ae3a053c Mon Sep 17 00:00:00 2001
From: Thomas PK Healy
Date: Thu, 8 Jan 2026 10:34:03 +0000
Subject: [PATCH] Relocate __is_specialization_of to bits/utility.h header
---
 libstdc++-v3/include/bits/utility.h | 7 +++++++
 libstdc++-v3/include/std/format     | 6 ------
 2 files changed, 7 insertions(+), 6 deletions(-)
  

Comments

Jonathan Wakely Jan. 11, 2026, 1:21 p.m. UTC | #1
On Sun, 11 Jan 2026 at 12:46, Frederick Virchanza Gotham
<cauldwell.thomas@gmail.com> wrote:
>
> Currently the definition of the C++ template "__is_specialization_of"
> is inside the header file "std/format".
>
> I propose two reasons to move this to "bits/utility.h":
>
> (1) To avoid code duplication, as other parts of libstdc++ may need it
> in the future. Currently my implementation of "std::chimeric_ptr"
> requires it.

We don't need to make changes for out-of-tree patches, the change can
live in your branch.

> (2) At some point, "std::is_specialization_of" will be added to
> libstdc++, so again we want to avoid code duplication.

std::is_specialization_of is unlikely to happen until it can handle
non-type template parameters, and our __is_specialization_of won't be
compatible with it.



>
> Note that when it's moved from 'std/format' to 'bits/utility.h', it
> needs to be protected with "if __cplusplus >= 201402L".
>
> Here is the patch:
>
> From 76712db0fd1c7ab8c9067b344e6e3398ae3a053c Mon Sep 17 00:00:00 2001
> From: Thomas PK Healy
> Date: Thu, 8 Jan 2026 10:34:03 +0000
> Subject: [PATCH] Relocate __is_specialization_of to bits/utility.h header
> ---
>  libstdc++-v3/include/bits/utility.h | 7 +++++++
>  libstdc++-v3/include/std/format     | 6 ------
>  2 files changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/utility.h
> b/libstdc++-v3/include/bits/utility.h
> index bd6b18d54dd3f..ec70d495587ea 100644
> --- a/libstdc++-v3/include/bits/utility.h
> +++ b/libstdc++-v3/include/bits/utility.h
> @@ -329,6 +329,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>      inline constexpr bool __is_nontype_v<nontype_t<__val>> = true;
>  #endif
>
> +#if __cplusplus >= 201402L
> +  template<typename _Tp, template<typename...> class _Class>
> +    constexpr bool __is_specialization_of = false;
> +  template<template<typename...> class _Class, typename... _Args>
> +    constexpr bool __is_specialization_of<_Class<_Args...>, _Class> = true;
> +#endif
> +
>  _GLIBCXX_END_NAMESPACE_VERSION
>  } // namespace
>
> diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
> index 2e4463c65969b..50315c6e9a778 100644
> --- a/libstdc++-v3/include/std/format
> +++ b/libstdc++-v3/include/std/format
> @@ -427,12 +427,6 @@ namespace __format
>        size_t _M_num_args = 0;
>      };
>
> -/// @cond undocumented
> -  template<typename _Tp, template<typename...> class _Class>
> -    constexpr bool __is_specialization_of = false;
> -  template<template<typename...> class _Class, typename... _Args>
> -    constexpr bool __is_specialization_of<_Class<_Args...>, _Class> = true;
> -
>  namespace __format
>  {
>    // pre: first != last
>
  

Patch

diff --git a/libstdc++-v3/include/bits/utility.h
b/libstdc++-v3/include/bits/utility.h
index bd6b18d54dd3f..ec70d495587ea 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -329,6 +329,13 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline constexpr bool __is_nontype_v<nontype_t<__val>> = true;
 #endif

+#if __cplusplus >= 201402L
+  template<typename _Tp, template<typename...> class _Class>
+    constexpr bool __is_specialization_of = false;
+  template<template<typename...> class _Class, typename... _Args>
+    constexpr bool __is_specialization_of<_Class<_Args...>, _Class> = true;
+#endif
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 2e4463c65969b..50315c6e9a778 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -427,12 +427,6 @@  namespace __format
       size_t _M_num_args = 0;
     };

-/// @cond undocumented
-  template<typename _Tp, template<typename...> class _Class>
-    constexpr bool __is_specialization_of = false;
-  template<template<typename...> class _Class, typename... _Args>
-    constexpr bool __is_specialization_of<_Class<_Args...>, _Class> = true;
-
 namespace __format
 {
   // pre: first != last