1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-04-28 06:33:36 +00:00

stdcountof-h: New module.

* lib/stdcountof.in.h: New file.
* m4/stdcountof_h.m4: New file.
* modules/stdcountof-h: New file.
This commit is contained in:
Bruno Haible
2025-06-02 23:42:17 +02:00
parent df7978ac7f
commit 8617124d25
4 changed files with 165 additions and 0 deletions

View File

@@ -1,3 +1,10 @@
2025-06-02 Bruno Haible <bruno@clisp.org>
stdcountof-h: New module.
* lib/stdcountof.in.h: New file.
* m4/stdcountof_h.m4: New file.
* modules/stdcountof-h: New file.
2025-06-02 Bruno Haible <bruno@clisp.org>
stddef-h: Fix compilation errors in C++ mode (regression 2025-05-27).

95
lib/stdcountof.in.h Normal file
View File

@@ -0,0 +1,95 @@
/* 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 */

24
m4/stdcountof_h.m4 Normal file
View File

@@ -0,0 +1,24 @@
# 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
])

39
modules/stdcountof-h Normal file
View File

@@ -0,0 +1,39 @@
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