--- /dev/null
+/* Copyright 2025 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ This program 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
+
+#ifndef _GL_STDCOUNTOF_H
+#define _GL_STDCOUNTOF_H
+
+#if defined __cplusplus
+/* Get size_t. */
+# include <stddef.h>
+#endif
+
+/* Returns the number of elements of the array A, as a value of type size_t.
+ Example declarations of arrays:
+ extern int a[];
+ extern int a[10];
+ static int a[10][20];
+ void func () { int a[10]; ... }
+ Attempts to produce an error if A is a pointer, e.g. in
+ void func (int a[10]) { ... }
+ */
+#define countof(a) \
+ (sizeof (a) / sizeof (a[0]) + 0 * _gl_verify_is_array (a))
+
+/* Attempts to verify that A is an array. */
+#if defined __cplusplus
+/* Borrowed from verify.h. */
+# if !GNULIB_defined_struct__gl_verify_type
+template <int w>
+ struct _gl_verify_type {
+ unsigned int _gl_verify_error_if_negative: w;
+ };
+# define GNULIB_defined_struct__gl_verify_type 1
+# endif
+# if __cplusplus >= 201103L
+# if 1
+ /* Use decltype. */
+/* Default case. */
+template <typename T>
+ struct _gl_array_type_test { static const int is_array = -1; };
+/* Unbounded arrays. */
+template <typename T>
+ struct _gl_array_type_test<T[]> { static const int is_array = 1; };
+/* Bounded arrays. */
+template <typename T, size_t N>
+ struct _gl_array_type_test<T[N]> { static const int is_array = 1; };
+# define _gl_verify_is_array(a) \
+ sizeof (_gl_verify_type<_gl_array_type_test<decltype(a)>::is_array>)
+# else
+ /* Use template argument deduction.
+ Use sizeof to get a constant expression from an unknown type. */
+/* Default case. */
+template <typename T>
+ struct _gl_array_type_test { double large; };
+/* Unbounded arrays. */
+template <typename T>
+ struct _gl_array_type_test<T[]> { char small; };
+/* Bounded arrays. */
+template <typename T, size_t N>
+ struct _gl_array_type_test<T[N]> { char small; };
+/* The T& parameter is essential here: it prevents decay (array-to-pointer
+ conversion). */
+template <typename T> _gl_array_type_test<T> _gl_array_type_test_helper(T&);
+# define _gl_verify_is_array(a) \
+ sizeof (_gl_verify_type<(sizeof (_gl_array_type_test_helper(a)) < sizeof (double) ? 1 : -1)>)
+# endif
+# else
+/* The compiler does not have the necessary functionality. */
+# define _gl_verify_is_array(a) 0
+# endif
+#else
+/* In C, we can use typeof and __builtin_types_compatible_p. */
+# if _GL_GNUC_PREREQ (3, 1) || defined __clang__
+# define _gl_verify_is_array(a) \
+ sizeof (struct { unsigned int _gl_verify_error_if_negative : __builtin_types_compatible_p (typeof (a), typeof (&*(a))) ? -1 : 1; })
+# else
+/* The compiler does not have the necessary built-ins. */
+# define _gl_verify_is_array(a) 0
+# endif
+#endif
+
+#endif /* _GL_STDCOUNTOF_H */
--- /dev/null
+# stdcountof_h.m4
+# serial 1
+dnl Copyright 2025 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl This file is offered as-is, without any warranty.
+
+AC_DEFUN_ONCE([gl_STDCOUNTOF_H],
+[
+ AC_CHECK_HEADERS_ONCE([stdcountof.h])
+ if test $ac_cv_header_stdcountof_h = yes; then
+ HAVE_STDCOUNTOF_H=1
+ else
+ HAVE_STDCOUNTOF_H=0
+ fi
+ AC_SUBST([HAVE_STDCOUNTOF_H])
+
+ if test $HAVE_STDCOUNTOF_H = 1; then
+ GL_GENERATE_STDCOUNTOF_H=false
+ else
+ GL_GENERATE_STDCOUNTOF_H=true
+ fi
+])
--- /dev/null
+Description:
+An <stdcountof.h> that is like C23.
+
+Files:
+lib/stdcountof.in.h
+m4/stdcountof_h.m4
+
+Depends-on:
+gen-header
+
+configure.ac:
+gl_STDCOUNTOF_H
+gl_CONDITIONAL_HEADER([stdcountof.h])
+AC_PROG_MKDIR_P
+
+Makefile.am:
+BUILT_SOURCES += $(STDCOUNTOF_H)
+
+# We need the following in order to create <stdcountof.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDCOUNTOF_H
+stdcountof.h: stdcountof.in.h $(top_builddir)/config.status
+@NMD@ $(AM_V_GEN)$(MKDIR_P) '%reldir%'
+ $(gl_V_at)$(SED_HEADER_STDOUT) $(srcdir)/stdcountof.in.h > $@-t
+ $(AM_V_at)mv $@-t $@
+else
+stdcountof.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stdcountof.h stdcountof.h-t
+
+Include:
+<stdcountof.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+Bruno Haible