(root)/
tar-1.35/
gnu/
c++defs.h
       1  /* C++ compatible function declaration macros.
       2     Copyright (C) 2010-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify it
       5     under the terms of the GNU Lesser General Public License as published
       6     by the Free Software Foundation; either version 2 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #ifndef _GL_CXXDEFS_H
      18  #define _GL_CXXDEFS_H
      19  
      20  /* Begin/end the GNULIB_NAMESPACE namespace.  */
      21  #if defined __cplusplus && defined GNULIB_NAMESPACE
      22  # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
      23  # define _GL_END_NAMESPACE }
      24  #else
      25  # define _GL_BEGIN_NAMESPACE
      26  # define _GL_END_NAMESPACE
      27  #endif
      28  
      29  /* The three most frequent use cases of these macros are:
      30  
      31     * For providing a substitute for a function that is missing on some
      32       platforms, but is declared and works fine on the platforms on which
      33       it exists:
      34  
      35         #if @GNULIB_FOO@
      36         # if !@HAVE_FOO@
      37         _GL_FUNCDECL_SYS (foo, ...);
      38         # endif
      39         _GL_CXXALIAS_SYS (foo, ...);
      40         _GL_CXXALIASWARN (foo);
      41         #elif defined GNULIB_POSIXCHECK
      42         ...
      43         #endif
      44  
      45     * For providing a replacement for a function that exists on all platforms,
      46       but is broken/insufficient and needs to be replaced on some platforms:
      47  
      48         #if @GNULIB_FOO@
      49         # if @REPLACE_FOO@
      50         #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
      51         #   undef foo
      52         #   define foo rpl_foo
      53         #  endif
      54         _GL_FUNCDECL_RPL (foo, ...);
      55         _GL_CXXALIAS_RPL (foo, ...);
      56         # else
      57         _GL_CXXALIAS_SYS (foo, ...);
      58         # endif
      59         _GL_CXXALIASWARN (foo);
      60         #elif defined GNULIB_POSIXCHECK
      61         ...
      62         #endif
      63  
      64     * For providing a replacement for a function that exists on some platforms
      65       but is broken/insufficient and needs to be replaced on some of them and
      66       is additionally either missing or undeclared on some other platforms:
      67  
      68         #if @GNULIB_FOO@
      69         # if @REPLACE_FOO@
      70         #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
      71         #   undef foo
      72         #   define foo rpl_foo
      73         #  endif
      74         _GL_FUNCDECL_RPL (foo, ...);
      75         _GL_CXXALIAS_RPL (foo, ...);
      76         # else
      77         #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
      78         _GL_FUNCDECL_SYS (foo, ...);
      79         #  endif
      80         _GL_CXXALIAS_SYS (foo, ...);
      81         # endif
      82         _GL_CXXALIASWARN (foo);
      83         #elif defined GNULIB_POSIXCHECK
      84         ...
      85         #endif
      86  */
      87  
      88  /* _GL_EXTERN_C declaration;
      89     performs the declaration with C linkage.  */
      90  #if defined __cplusplus
      91  # define _GL_EXTERN_C extern "C"
      92  #else
      93  # define _GL_EXTERN_C extern
      94  #endif
      95  
      96  /* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
      97     declares a replacement function, named rpl_func, with the given prototype,
      98     consisting of return type, parameters, and attributes.
      99     Example:
     100       _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
     101                                    _GL_ARG_NONNULL ((1)));
     102  
     103     Note: Attributes, such as _GL_ATTRIBUTE_DEPRECATED, are supported in front
     104     of a _GL_FUNCDECL_RPL invocation only in C mode, not in C++ mode.  (That's
     105     because
     106       [[...]] extern "C" <declaration>;
     107     is invalid syntax in C++.)
     108   */
     109  #define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
     110    _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
     111  #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
     112    _GL_EXTERN_C rettype rpl_func parameters_and_attributes
     113  
     114  /* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
     115     declares the system function, named func, with the given prototype,
     116     consisting of return type, parameters, and attributes.
     117     Example:
     118       _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
     119                                    _GL_ARG_NONNULL ((1)));
     120   */
     121  #define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
     122    _GL_EXTERN_C rettype func parameters_and_attributes
     123  
     124  /* _GL_CXXALIAS_RPL (func, rettype, parameters);
     125     declares a C++ alias called GNULIB_NAMESPACE::func
     126     that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
     127     Example:
     128       _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
     129  
     130     Wrapping rpl_func in an object with an inline conversion operator
     131     avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
     132     actually used in the program.  */
     133  #define _GL_CXXALIAS_RPL(func,rettype,parameters) \
     134    _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
     135  #if defined __cplusplus && defined GNULIB_NAMESPACE
     136  # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
     137      namespace GNULIB_NAMESPACE                                \
     138      {                                                         \
     139        static const struct _gl_ ## func ## _wrapper            \
     140        {                                                       \
     141          typedef rettype (*type) parameters;                   \
     142                                                                \
     143          inline operator type () const                         \
     144          {                                                     \
     145            return ::rpl_func;                                  \
     146          }                                                     \
     147        } func = {};                                            \
     148      }                                                         \
     149      _GL_EXTERN_C int _gl_cxxalias_dummy
     150  #else
     151  # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
     152      _GL_EXTERN_C int _gl_cxxalias_dummy
     153  #endif
     154  
     155  /* _GL_CXXALIAS_MDA (func, rettype, parameters);
     156     is to be used when func is a Microsoft deprecated alias, on native Windows.
     157     It declares a C++ alias called GNULIB_NAMESPACE::func
     158     that redirects to _func, if GNULIB_NAMESPACE is defined.
     159     Example:
     160       _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
     161   */
     162  #define _GL_CXXALIAS_MDA(func,rettype,parameters) \
     163    _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
     164  
     165  /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
     166     is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
     167     except that the C function rpl_func may have a slightly different
     168     declaration.  A cast is used to silence the "invalid conversion" error
     169     that would otherwise occur.  */
     170  #if defined __cplusplus && defined GNULIB_NAMESPACE
     171  # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
     172      namespace GNULIB_NAMESPACE                                     \
     173      {                                                              \
     174        static const struct _gl_ ## func ## _wrapper                 \
     175        {                                                            \
     176          typedef rettype (*type) parameters;                        \
     177                                                                     \
     178          inline operator type () const                              \
     179          {                                                          \
     180            return reinterpret_cast<type>(::rpl_func);               \
     181          }                                                          \
     182        } func = {};                                                 \
     183      }                                                              \
     184      _GL_EXTERN_C int _gl_cxxalias_dummy
     185  #else
     186  # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
     187      _GL_EXTERN_C int _gl_cxxalias_dummy
     188  #endif
     189  
     190  /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
     191     is like  _GL_CXXALIAS_MDA (func, rettype, parameters);
     192     except that the C function func may have a slightly different declaration.
     193     A cast is used to silence the "invalid conversion" error that would
     194     otherwise occur.  */
     195  #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
     196    _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
     197  
     198  /* _GL_CXXALIAS_SYS (func, rettype, parameters);
     199     declares a C++ alias called GNULIB_NAMESPACE::func
     200     that redirects to the system provided function func, if GNULIB_NAMESPACE
     201     is defined.
     202     Example:
     203       _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
     204  
     205     Wrapping func in an object with an inline conversion operator
     206     avoids a reference to func unless GNULIB_NAMESPACE::func is
     207     actually used in the program.  */
     208  #if defined __cplusplus && defined GNULIB_NAMESPACE
     209  # define _GL_CXXALIAS_SYS(func,rettype,parameters)            \
     210      namespace GNULIB_NAMESPACE                                \
     211      {                                                         \
     212        static const struct _gl_ ## func ## _wrapper            \
     213        {                                                       \
     214          typedef rettype (*type) parameters;                   \
     215                                                                \
     216          inline operator type () const                         \
     217          {                                                     \
     218            return ::func;                                      \
     219          }                                                     \
     220        } func = {};                                            \
     221      }                                                         \
     222      _GL_EXTERN_C int _gl_cxxalias_dummy
     223  #else
     224  # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
     225      _GL_EXTERN_C int _gl_cxxalias_dummy
     226  #endif
     227  
     228  /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
     229     is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
     230     except that the C function func may have a slightly different declaration.
     231     A cast is used to silence the "invalid conversion" error that would
     232     otherwise occur.  */
     233  #if defined __cplusplus && defined GNULIB_NAMESPACE
     234  # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
     235      namespace GNULIB_NAMESPACE                          \
     236      {                                                   \
     237        static const struct _gl_ ## func ## _wrapper      \
     238        {                                                 \
     239          typedef rettype (*type) parameters;             \
     240                                                          \
     241          inline operator type () const                   \
     242          {                                               \
     243            return reinterpret_cast<type>(::func);        \
     244          }                                               \
     245        } func = {};                                      \
     246      }                                                   \
     247      _GL_EXTERN_C int _gl_cxxalias_dummy
     248  #else
     249  # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
     250      _GL_EXTERN_C int _gl_cxxalias_dummy
     251  #endif
     252  
     253  /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
     254     is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
     255     except that the C function is picked among a set of overloaded functions,
     256     namely the one with rettype2 and parameters2.  Two consecutive casts
     257     are used to silence the "cannot find a match" and "invalid conversion"
     258     errors that would otherwise occur.  */
     259  #if defined __cplusplus && defined GNULIB_NAMESPACE
     260    /* The outer cast must be a reinterpret_cast.
     261       The inner cast: When the function is defined as a set of overloaded
     262       functions, it works as a static_cast<>, choosing the designated variant.
     263       When the function is defined as a single variant, it works as a
     264       reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
     265  # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
     266      namespace GNULIB_NAMESPACE                                                \
     267      {                                                                         \
     268        static const struct _gl_ ## func ## _wrapper                            \
     269        {                                                                       \
     270          typedef rettype (*type) parameters;                                   \
     271                                                                                \
     272          inline operator type () const                                         \
     273          {                                                                     \
     274            return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \
     275          }                                                                     \
     276        } func = {};                                                            \
     277      }                                                                         \
     278      _GL_EXTERN_C int _gl_cxxalias_dummy
     279  #else
     280  # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
     281      _GL_EXTERN_C int _gl_cxxalias_dummy
     282  #endif
     283  
     284  /* _GL_CXXALIASWARN (func);
     285     causes a warning to be emitted when ::func is used but not when
     286     GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
     287     variants.  */
     288  #if defined __cplusplus && defined GNULIB_NAMESPACE
     289  # define _GL_CXXALIASWARN(func) \
     290     _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
     291  # define _GL_CXXALIASWARN_1(func,namespace) \
     292     _GL_CXXALIASWARN_2 (func, namespace)
     293  /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
     294     we enable the warning only when not optimizing.  */
     295  # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
     296  #  define _GL_CXXALIASWARN_2(func,namespace) \
     297      _GL_WARN_ON_USE (func, \
     298                       "The symbol ::" #func " refers to the system function. " \
     299                       "Use " #namespace "::" #func " instead.")
     300  # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
     301  #  define _GL_CXXALIASWARN_2(func,namespace) \
     302       extern __typeof__ (func) func
     303  # else
     304  #  define _GL_CXXALIASWARN_2(func,namespace) \
     305       _GL_EXTERN_C int _gl_cxxalias_dummy
     306  # endif
     307  #else
     308  # define _GL_CXXALIASWARN(func) \
     309      _GL_EXTERN_C int _gl_cxxalias_dummy
     310  #endif
     311  
     312  /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
     313     causes a warning to be emitted when the given overloaded variant of ::func
     314     is used but not when GNULIB_NAMESPACE::func is used.  */
     315  #if defined __cplusplus && defined GNULIB_NAMESPACE
     316  # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
     317     _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
     318                          GNULIB_NAMESPACE)
     319  # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
     320     _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
     321  /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
     322     we enable the warning only when not optimizing.  */
     323  # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
     324  #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
     325      _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
     326                           "The symbol ::" #func " refers to the system function. " \
     327                           "Use " #namespace "::" #func " instead.")
     328  # else
     329  #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
     330       _GL_EXTERN_C int _gl_cxxalias_dummy
     331  # endif
     332  #else
     333  # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
     334      _GL_EXTERN_C int _gl_cxxalias_dummy
     335  #endif
     336  
     337  #endif /* _GL_CXXDEFS_H */