root/lib/c++defs.h

/* [<][>][^][v][top][bottom][index][help] */
     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 #define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
   104   _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
   105 #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
   106   _GL_EXTERN_C rettype rpl_func parameters_and_attributes
   107 
   108 /* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
   109    declares the system function, named func, with the given prototype,
   110    consisting of return type, parameters, and attributes.
   111    Example:
   112      _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
   113                                   _GL_ARG_NONNULL ((1)));
   114  */
   115 #define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
   116   _GL_EXTERN_C rettype func parameters_and_attributes
   117 
   118 /* _GL_CXXALIAS_RPL (func, rettype, parameters);
   119    declares a C++ alias called GNULIB_NAMESPACE::func
   120    that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
   121    Example:
   122      _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
   123 
   124    Wrapping rpl_func in an object with an inline conversion operator
   125    avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
   126    actually used in the program.  */
   127 #define _GL_CXXALIAS_RPL(func,rettype,parameters) \
   128   _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
   129 #if defined __cplusplus && defined GNULIB_NAMESPACE
   130 # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
   131     namespace GNULIB_NAMESPACE                                \
   132     {                                                         \
   133       static const struct _gl_ ## func ## _wrapper            \
   134       {                                                       \
   135         typedef rettype (*type) parameters;                   \
   136                                                               \
   137         inline operator type () const                         \
   138         {                                                     \
   139           return ::rpl_func;                                  \
   140         }                                                     \
   141       } func = {};                                            \
   142     }                                                         \
   143     _GL_EXTERN_C int _gl_cxxalias_dummy
   144 #else
   145 # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
   146     _GL_EXTERN_C int _gl_cxxalias_dummy
   147 #endif
   148 
   149 /* _GL_CXXALIAS_MDA (func, rettype, parameters);
   150    is to be used when func is a Microsoft deprecated alias, on native Windows.
   151    It declares a C++ alias called GNULIB_NAMESPACE::func
   152    that redirects to _func, if GNULIB_NAMESPACE is defined.
   153    Example:
   154      _GL_CXXALIAS_MDA (open, int, (const char *filename, int flags, ...));
   155  */
   156 #define _GL_CXXALIAS_MDA(func,rettype,parameters) \
   157   _GL_CXXALIAS_RPL_1 (func, _##func, rettype, parameters)
   158 
   159 /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
   160    is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
   161    except that the C function rpl_func may have a slightly different
   162    declaration.  A cast is used to silence the "invalid conversion" error
   163    that would otherwise occur.  */
   164 #if defined __cplusplus && defined GNULIB_NAMESPACE
   165 # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
   166     namespace GNULIB_NAMESPACE                                     \
   167     {                                                              \
   168       static const struct _gl_ ## func ## _wrapper                 \
   169       {                                                            \
   170         typedef rettype (*type) parameters;                        \
   171                                                                    \
   172         inline operator type () const                              \
   173         {                                                          \
   174           return reinterpret_cast<type>(::rpl_func);               \
   175         }                                                          \
   176       } func = {};                                                 \
   177     }                                                              \
   178     _GL_EXTERN_C int _gl_cxxalias_dummy
   179 #else
   180 # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
   181     _GL_EXTERN_C int _gl_cxxalias_dummy
   182 #endif
   183 
   184 /* _GL_CXXALIAS_MDA_CAST (func, rettype, parameters);
   185    is like  _GL_CXXALIAS_MDA (func, rettype, parameters);
   186    except that the C function func may have a slightly different declaration.
   187    A cast is used to silence the "invalid conversion" error that would
   188    otherwise occur.  */
   189 #define _GL_CXXALIAS_MDA_CAST(func,rettype,parameters) \
   190   _GL_CXXALIAS_RPL_CAST_1 (func, _##func, rettype, parameters)
   191 
   192 /* _GL_CXXALIAS_SYS (func, rettype, parameters);
   193    declares a C++ alias called GNULIB_NAMESPACE::func
   194    that redirects to the system provided function func, if GNULIB_NAMESPACE
   195    is defined.
   196    Example:
   197      _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
   198 
   199    Wrapping func in an object with an inline conversion operator
   200    avoids a reference to func unless GNULIB_NAMESPACE::func is
   201    actually used in the program.  */
   202 #if defined __cplusplus && defined GNULIB_NAMESPACE
   203 # define _GL_CXXALIAS_SYS(func,rettype,parameters)            \
   204     namespace GNULIB_NAMESPACE                                \
   205     {                                                         \
   206       static const struct _gl_ ## func ## _wrapper            \
   207       {                                                       \
   208         typedef rettype (*type) parameters;                   \
   209                                                               \
   210         inline operator type () const                         \
   211         {                                                     \
   212           return ::func;                                      \
   213         }                                                     \
   214       } func = {};                                            \
   215     }                                                         \
   216     _GL_EXTERN_C int _gl_cxxalias_dummy
   217 #else
   218 # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
   219     _GL_EXTERN_C int _gl_cxxalias_dummy
   220 #endif
   221 
   222 /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
   223    is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
   224    except that the C function func may have a slightly different declaration.
   225    A cast is used to silence the "invalid conversion" error that would
   226    otherwise occur.  */
   227 #if defined __cplusplus && defined GNULIB_NAMESPACE
   228 # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
   229     namespace GNULIB_NAMESPACE                          \
   230     {                                                   \
   231       static const struct _gl_ ## func ## _wrapper      \
   232       {                                                 \
   233         typedef rettype (*type) parameters;             \
   234                                                         \
   235         inline operator type () const                   \
   236         {                                               \
   237           return reinterpret_cast<type>(::func);        \
   238         }                                               \
   239       } func = {};                                      \
   240     }                                                   \
   241     _GL_EXTERN_C int _gl_cxxalias_dummy
   242 #else
   243 # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
   244     _GL_EXTERN_C int _gl_cxxalias_dummy
   245 #endif
   246 
   247 /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
   248    is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
   249    except that the C function is picked among a set of overloaded functions,
   250    namely the one with rettype2 and parameters2.  Two consecutive casts
   251    are used to silence the "cannot find a match" and "invalid conversion"
   252    errors that would otherwise occur.  */
   253 #if defined __cplusplus && defined GNULIB_NAMESPACE
   254   /* The outer cast must be a reinterpret_cast.
   255      The inner cast: When the function is defined as a set of overloaded
   256      functions, it works as a static_cast<>, choosing the designated variant.
   257      When the function is defined as a single variant, it works as a
   258      reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
   259 # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
   260     namespace GNULIB_NAMESPACE                                                \
   261     {                                                                         \
   262       static const struct _gl_ ## func ## _wrapper                            \
   263       {                                                                       \
   264         typedef rettype (*type) parameters;                                   \
   265                                                                               \
   266         inline operator type () const                                         \
   267         {                                                                     \
   268           return reinterpret_cast<type>((rettype2 (*) parameters2)(::func));  \
   269         }                                                                     \
   270       } func = {};                                                            \
   271     }                                                                         \
   272     _GL_EXTERN_C int _gl_cxxalias_dummy
   273 #else
   274 # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
   275     _GL_EXTERN_C int _gl_cxxalias_dummy
   276 #endif
   277 
   278 /* _GL_CXXALIASWARN (func);
   279    causes a warning to be emitted when ::func is used but not when
   280    GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
   281    variants.  */
   282 #if defined __cplusplus && defined GNULIB_NAMESPACE
   283 # define _GL_CXXALIASWARN(func) \
   284    _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
   285 # define _GL_CXXALIASWARN_1(func,namespace) \
   286    _GL_CXXALIASWARN_2 (func, namespace)
   287 /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
   288    we enable the warning only when not optimizing.  */
   289 # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
   290 #  define _GL_CXXALIASWARN_2(func,namespace) \
   291     _GL_WARN_ON_USE (func, \
   292                      "The symbol ::" #func " refers to the system function. " \
   293                      "Use " #namespace "::" #func " instead.")
   294 # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
   295 #  define _GL_CXXALIASWARN_2(func,namespace) \
   296      extern __typeof__ (func) func
   297 # else
   298 #  define _GL_CXXALIASWARN_2(func,namespace) \
   299      _GL_EXTERN_C int _gl_cxxalias_dummy
   300 # endif
   301 #else
   302 # define _GL_CXXALIASWARN(func) \
   303     _GL_EXTERN_C int _gl_cxxalias_dummy
   304 #endif
   305 
   306 /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
   307    causes a warning to be emitted when the given overloaded variant of ::func
   308    is used but not when GNULIB_NAMESPACE::func is used.  */
   309 #if defined __cplusplus && defined GNULIB_NAMESPACE
   310 # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
   311    _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
   312                         GNULIB_NAMESPACE)
   313 # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
   314    _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
   315 /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
   316    we enable the warning only when not optimizing.  */
   317 # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
   318 #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
   319     _GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
   320                          "The symbol ::" #func " refers to the system function. " \
   321                          "Use " #namespace "::" #func " instead.")
   322 # else
   323 #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
   324      _GL_EXTERN_C int _gl_cxxalias_dummy
   325 # endif
   326 #else
   327 # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
   328     _GL_EXTERN_C int _gl_cxxalias_dummy
   329 #endif
   330 
   331 #endif /* _GL_CXXDEFS_H */

/* [<][>][^][v][top][bottom][index][help] */