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    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 */

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