File: stdcountof.in.h

package info (click to toggle)
coreutils 9.10-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 70,560 kB
  • sloc: ansic: 253,546; sh: 30,931; perl: 8,141; yacc: 1,846; makefile: 198; python: 47; sed: 16
file content (118 lines) | stat: -rw-r--r-- 4,298 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* Copyright 2025-2026 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 _@GUARD_PREFIX@_STDCOUNTOF_H

#if __GNUC__ >= 3
@PRAGMA_SYSTEM_HEADER@
#endif
@PRAGMA_COLUMNS@

/* The include_next requires a split double-inclusion guard.  */
#if (defined __cplusplus ? @CXX_HAVE_STDCOUNTOF_H@ : @HAVE_STDCOUNTOF_H@)
# @INCLUDE_NEXT@ @NEXT_STDCOUNTOF_H@
#else

#ifndef _@GUARD_PREFIX@_STDCOUNTOF_H
#define _@GUARD_PREFIX@_STDCOUNTOF_H

/* This file uses _GL_GNUC_PREREQ.  */
#if !_GL_CONFIG_H_INCLUDED
 #error "Please include config.h first."
#endif

/* Get size_t.  */
#include <stddef.h>

/* 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(...) \
  ((size_t) (sizeof (__VA_ARGS__) / sizeof (__VA_ARGS__)[0] \
             + 0 * _gl_verify_is_array (__VA_ARGS__)))

/* 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; };
/* String literals.  */
template <typename T, size_t N>
  struct _gl_array_type_test<T const (&)[N]> { static const int is_array = 1; };
#   define _gl_verify_is_array(...) \
     sizeof (_gl_verify_type<_gl_array_type_test<decltype(__VA_ARGS__)>::is_array>)
#  else
  /* Use template argument deduction.
     Use sizeof to get a constant expression from an unknown type.
     Note: This approach does not work for countof (((int[]) { a, b, c })).  */
/* 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(...) \
     sizeof (_gl_verify_type<(sizeof (_gl_array_type_test_helper(__VA_ARGS__)) < sizeof (double) ? 1 : -1)>)
#  endif
# else
/* The compiler does not have the necessary functionality.  */
#  define _gl_verify_is_array(...) 0
# endif
#else
/* In C, we can use typeof and __builtin_types_compatible_p.  */
/* Work around clang bug <https://github.com/llvm/llvm-project/issues/143284>.  */
# if _GL_GNUC_PREREQ (3, 1) && ! defined __clang__ /* || defined __clang__ */
#  define _gl_verify_is_array(...) \
    sizeof (struct { unsigned int _gl_verify_error_if_negative : __builtin_types_compatible_p (typeof (__VA_ARGS__), typeof (&*(__VA_ARGS__))) ? -1 : 1; })
# else
/* The compiler does not have the necessary built-ins.  */
#  define _gl_verify_is_array(...) 0
# endif
#endif

#endif /* _@GUARD_PREFIX@_STDCOUNTOF_H */
#endif
#endif /* _@GUARD_PREFIX@_STDCOUNTOF_H */