aboutsummaryrefslogtreecommitdiff
path: root/arch/all/core/include/cdefs/utils.h
blob: ebfd93d95545c708d180b2a629fd73863319f360 (plain)
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
119
120
121
122
123
124
125
126
/* ****************************************************************************
 * C utilities.
 * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
 * ************************************************************************* */
#ifndef  _CDEFS_H
# error "This file should be included by `cdefs.h`!"
#endif
#include <cdefs/compiler.h>
#include <cdefs/features.h>

/* ************************************************************************* */
/*  C declaration                                                            */
/* ************************************************************************* */
/* On x86-32 targets, the 'cdecl' attribute causes the compiler to assume that
 * the calling function pops off the stack space used to pass arguments. */

#if !defined(__STDC__) || !__STDC__
# define __cdecl
#else
# define __cdecl cdecl
#endif
/* ************************************************************************* */
/*  Declaration arguments                                                    */
/* ************************************************************************* */
/* ANSI C does not have arguments in function declarations. */

#if __USE_C89
# define _OF(_ARGS) _ARGS
#else
# define _OF(_ARGS) ()
#endif
/* ************************************************************************* */
/*  C++ C declarations                                                       */
/* ************************************************************************* */
/* C++ needs to know that types and declarations are C, not C++. */

#if __USE_CXX98
# define __BEGIN_DECLS  extern "C" {
# define   __END_DECLS  }
#else
# define __BEGIN_DECLS
# define   __END_DECLS
#endif
/* ************************************************************************* */
/*  C++ namespaces management                                                */
/* ************************************************************************* */
/* The standard library needs the function from the ISO C90 standard in
 * the `std` namespace.
 * At the same time, we want to be safe for future changes and we include
 * the ISO C99 code in the non-standard namespace `__c99`.
 * The C++ wrapper header take case of adding the definition to
 * the global namespace. */

#if __USE_CXX98
# define __BEGIN_NAMESPACE_STD        namespace std {
# define __USING_NAMESPACE_STD(_NAME) using std::_NAME;
# define   __END_NAMESPACE_STD        }

# define __BEGIN_NAMESPACE_C99        namespace __c99 {
# define __USING_NAMESPACE_C99        using __c99::_NAME;
# define   __END_NAMESPACE_C99        }
#else
# define __BEGIN_NAMESPACE_STD
# define __USING_NAMESPACE_STD(_NAME)
# define   __END_NAMESPACE_STD

# define __BEGIN_NAMESPACE_C99
# define   __END_NAMESPACE_C99
# define __USING_NAMESPACE_C99
#endif
/* ************************************************************************* */
/*  Optimize conditions                                                      */
/* ************************************************************************* */
/* Use these macros to optimize a little the produced assembly. */

#ifndef    likely
# define   likely(_COND) (_COND)
#endif
#ifndef  unlikely
# define unlikely(_COND) (_COND)
#endif
/* ************************************************************************* */
/*  __concat: Catenate things in macros                                      */
/* ************************************************************************* */
#ifdef  __concat
# undef __concat
#endif
#ifdef  __concat_
# undef __concat_
#endif
#define __concat_(_X, _Y) _X ## _Y
#define __concat(_X, _Y)  __concat_(_X, _Y)
/* ************************************************************************* */
/*  __count_va_args: count number of elements in __VA_ARGS__                 */
/* ************************************************************************* */
#ifdef  __count_va_args
# undef __count_va_args
#endif
#if defined(__GNUC__) && __USE_C99
/* This is something that should work, although I don't really understand the
 * trick yet. Source: http://stackoverflow.com/a/2124385/6541022 */

# define __count_va_args(...) \
	__count_va_args_(__VA_ARGS__, __count_va_args_rseq_N())
# define __count_va_args_(...) __count_va_args_N(__VA_ARGS__)

# define __count_va_args_N( \
	 _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, _N, ...) _N
# define __count_va_args_rseq_N() \
	63, 62, 61, 60, 59, 58, 57, 56, 55, 54, \
	53, 52, 51, 50, 49, 48, 47, 46, 45, 44, \
	43, 42, 41, 40, 39, 38, 37, 36, 35, 34, \
	33, 32, 31, 30, 29, 28, 27, 26, 25, 24, \
	23, 22, 21, 20, 19, 18, 17, 16, 15, 14, \
	13, 12, 11, 10,  9,  8,  7,  6,  5,  4, \
	 3,  2,  1,  0

#elif __STDC_VERSION__ >= 199901L
# define __count_va_args(...) (0)
#endif