1#ifndef AWS_COMMON_MACROS_H
2#define AWS_COMMON_MACROS_H
3/*
4 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License").
7 * You may not use this file except in compliance with the License.
8 * A copy of the License is located at
9 *
10 * http://aws.amazon.com/apache2.0
11 *
12 * or in the "license" file accompanying this file. This file is distributed
13 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14 * express or implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 */
17
18#ifdef __cplusplus
19# define AWS_EXTERN_C_BEGIN extern "C" {
20# define AWS_EXTERN_C_END }
21#else
22# define AWS_EXTERN_C_BEGIN
23# define AWS_EXTERN_C_END
24#endif /* __cplusplus */
25
26#define AWS_CONCAT(A, B) A##B
27#define AWS_STATIC_ASSERT0(cond, msg) typedef char AWS_CONCAT(static_assertion_, msg)[(!!(cond)) * 2 - 1]
28#define AWS_STATIC_ASSERT1(cond, line) AWS_STATIC_ASSERT0(cond, AWS_CONCAT(at_line_, line))
29#define AWS_STATIC_ASSERT(cond) AWS_STATIC_ASSERT1(cond, __LINE__)
30
31/* https://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion */
32#define GLUE(x, y) x y
33
34#define RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, count, ...) count
35#define EXPAND_ARGS(args) RETURN_ARG_COUNT args
36#define COUNT_ARGS_MAX5(...) EXPAND_ARGS((__VA_ARGS__, 5, 4, 3, 2, 1, 0))
37
38#define OVERLOAD_MACRO2(name, count) name##count
39#define OVERLOAD_MACRO1(name, count) OVERLOAD_MACRO2(name, count)
40#define OVERLOAD_MACRO(name, count) OVERLOAD_MACRO1(name, count)
41
42#define CALL_OVERLOAD(name, ...) GLUE(OVERLOAD_MACRO(name, COUNT_ARGS_MAX5(__VA_ARGS__)), (__VA_ARGS__))
43
44#define CALL_OVERLOAD_TEST1(x) x
45#define CALL_OVERLOAD_TEST2(x, y) y
46#define CALL_OVERLOAD_TEST3(x, y, z) z
47#define CALL_OVERLOAD_TEST(...) CALL_OVERLOAD(CALL_OVERLOAD_TEST, __VA_ARGS__)
48AWS_STATIC_ASSERT(CALL_OVERLOAD_TEST(1) == 1);
49AWS_STATIC_ASSERT(CALL_OVERLOAD_TEST(1, 2) == 2);
50AWS_STATIC_ASSERT(CALL_OVERLOAD_TEST(1, 2, 3) == 3);
51
52#define AWS_CACHE_LINE 64
53/**
54 * Format macro for strings of a specified length.
55 * Allows non null-terminated strings to be used with the printf family of functions.
56 * Ex: printf("scheme is " PRInSTR, 4, "http://example.org"); // ouputs: "scheme is http"
57 */
58#define PRInSTR "%.*s"
59
60#if defined(_MSC_VER)
61# include <malloc.h>
62# define AWS_ALIGNED_TYPEDEF(from, to, alignment) typedef __declspec(align(alignment)) from to
63# define AWS_LIKELY(x) x
64# define AWS_UNLIKELY(x) x
65# define AWS_FORCE_INLINE __forceinline
66# define AWS_VARIABLE_LENGTH_ARRAY(type, name, length) type *name = _alloca(sizeof(type) * (length))
67# define AWS_DECLSPEC_NORETURN __declspec(noreturn)
68# define AWS_ATTRIBUTE_NORETURN
69#else
70# if defined(__GNUC__) || defined(__clang__)
71# define AWS_ALIGNED_TYPEDEF(from, to, alignment) typedef from to __attribute__((aligned(alignment)))
72# define AWS_TYPE_OF(a) __typeof__(a)
73# define AWS_LIKELY(x) __builtin_expect(!!(x), 1)
74# define AWS_UNLIKELY(x) __builtin_expect(!!(x), 0)
75# define AWS_FORCE_INLINE __attribute__((always_inline))
76# define AWS_DECLSPEC_NORETURN
77# define AWS_ATTRIBUTE_NORETURN __attribute__((noreturn))
78# if defined(__cplusplus)
79# define AWS_VARIABLE_LENGTH_ARRAY(type, name, length) type *name = alloca(sizeof(type) * (length))
80# else
81# define AWS_VARIABLE_LENGTH_ARRAY(type, name, length) type name[length];
82# endif /* defined(__cplusplus) */
83# endif /* defined(__GNUC__) || defined(__clang__) */
84#endif /* defined(_MSC_VER) */
85
86/* If this is C++, restrict isn't supported. If this is not at least C99 on gcc and clang, it isn't supported.
87 * If visual C++ building in C mode, the restrict definition is __restrict.
88 * This just figures all of that out based on who's including this header file. */
89#if defined(__cplusplus)
90# define AWS_RESTRICT
91#else
92# if defined(_MSC_VER)
93# define AWS_RESTRICT __restrict
94# else
95# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
96# define AWS_RESTRICT restrict
97# else
98# define AWS_RESTRICT
99# endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
100# endif /* defined(_MSC_VER) */
101#endif /* defined(__cplusplus) */
102
103#if defined(_MSC_VER)
104# define AWS_THREAD_LOCAL __declspec(thread)
105#else
106# define AWS_THREAD_LOCAL __thread
107#endif
108
109#define AWS_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
110/**
111 * from a pointer and a type of the struct containing the node
112 * this will get you back to the pointer of the object. member is the name of
113 * the instance of struct aws_linked_list_node in your struct.
114 */
115#define AWS_CONTAINER_OF(ptr, type, member) ((type *)((uint8_t *)(ptr)-offsetof(type, member)))
116
117#endif /* AWS_COMMON_MACROS_H */
118