VLink
2.0.0
A high-performance communication middleware
载入中...
搜索中...
未找到
macros.h
浏览该文件的文档.
1
/*
2
* Copyright (C) 2026 by Thun Lu. All rights reserved.
3
* Author: Thun Lu <thun.lu@zohomail.cn>
4
* Repo: https://github.com/thun-res/vlink
5
* _ __ __ _ __
6
* | | / / / / (_) ____ / /__
7
* | | / / / / / / / __ \ / //_/
8
* | |/ / / /___ / / / / / / / ,<
9
* |___/ /_____/ /_/ /_/ /_/ /_/|_|
10
*
11
* Licensed under the Apache License, Version 2.0 (the "License");
12
* you may not use this file except in compliance with the License.
13
* You may obtain a copy of the License at
14
*
15
* http://www.apache.org/licenses/LICENSE-2.0
16
*
17
* Unless required by applicable law or agreed to in writing, software
18
* distributed under the License is distributed on an "AS IS" BASIS,
19
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
* See the License for the specific language governing permissions and
21
* limitations under the License.
22
*/
23
24
/**
25
* @file macros.h
26
* @brief Platform-independent macro definitions for the VLink library.
27
*
28
* @details
29
* This header provides a unified set of macros used throughout VLink to handle
30
* platform differences, visibility control, branch prediction hints, and common
31
* class-level utilities such as singleton enforcement and copy-prevention.
32
*
33
* The macros are grouped as follows:
34
*
35
* | Group | Macros | Purpose |
36
* | ------------------ | ---------------------------------------------- | ---------------------------------- |
37
* | Symbol visibility | VLINK_EXPORT, VLINK_EXPORT_AND_ALIGNED | DLL export / visibility control |
38
* | Branch hints | VLINK_LIKELY, VLINK_UNLIKELY, VLIKELY, ... | Branch prediction optimization |
39
* | Copy prevention | VLINK_DISALLOW_COPY_AND_ASSIGN | Disable copy constructor/operator |
40
* | Singleton guard | VLINK_SINGLETON_CHECK, VLINK_SINGLETON_DECLARE | Enforce single-instance classes |
41
* | String utilities | VLINK_MACRO_STRING_IFY, VLINK_MACRO_STRING_GET | Stringify macro tokens |
42
* | Constant check | VLINK_ASSERT_CONSTANT | Static-assert constant string args |
43
*
44
* @note
45
* - All macros are designed to be no-ops when the relevant feature is unavailable
46
* (e.g., VLINK_LIKELY falls back to a plain cast on platforms without __builtin_expect).
47
* - The VLINK_EXPORT macro must be included before any class or function declaration
48
* that needs to be part of the public ABI.
49
* - VLINK_SINGLETON_CHECK enforces that a class can only ever be instantiated once
50
* per process via a static atomic flag; any second instantiation will throw
51
* std::runtime_error.
52
*
53
* @par Example
54
* @code
55
* // Marking a class as exported:
56
* class VLINK_EXPORT MyClass final { ... };
57
*
58
* // Preventing copy and assignment:
59
* class MyClass {
60
* VLINK_DISALLOW_COPY_AND_ASSIGN(MyClass)
61
* };
62
*
63
* // Branch prediction hint:
64
* if VLIKELY(ptr != nullptr) {
65
* ptr->do_something();
66
* }
67
* @endcode
68
*/
69
70
#pragma once
71
72
// export
73
#undef VLINK_EXPORT
74
#ifdef VLINK_LIBRARY_STATIC
75
#define VLINK_EXPORT
76
#elif defined(_WIN32) || defined(__CYGWIN__)
77
#ifdef VLINK_LIBRARY
78
/// @cond INTERNAL
79
#define VLINK_EXPORT __declspec(dllexport)
80
#else
81
#define VLINK_EXPORT __declspec(dllimport)
82
/// @endcond
83
#endif
84
#else
85
#define VLINK_EXPORT __attribute__((visibility("default")))
86
#endif
87
88
// align
89
#undef VLINK_EXPORT_AND_ALIGNED
90
#ifdef _MSC_VER
91
#define VLINK_EXPORT_AND_ALIGNED(align_num) VLINK_EXPORT __declspec(align(align_num))
92
#else
93
/**
94
* @def VLINK_EXPORT_AND_ALIGNED(align_num)
95
* @brief Marks a class or variable as both exported and aligned to the given byte boundary.
96
*
97
* @details
98
* On MSVC this expands to @c __declspec(align(align_num));
99
* on GCC/Clang it expands to @c __attribute__((aligned(align_num))).
100
*
101
* @param align_num The required alignment in bytes (must be a power of two).
102
*/
103
#define VLINK_EXPORT_AND_ALIGNED(align_num) VLINK_EXPORT __attribute__((aligned(align_num)))
104
#endif
105
106
// win32
107
#if defined(_WIN32) && !defined(WIN32_LEAN_AND_MEAN)
108
#define WIN32_LEAN_AND_MEAN
109
#endif
110
111
// msvc
112
#ifdef _MSC_VER
113
#ifndef _CRT_SECURE_NO_WARNINGS
114
#define _CRT_SECURE_NO_WARNINGS
// NOLINT(bugprone-reserved-identifier, readability-identifier-naming)
115
#endif
116
#pragma warning(disable : 4065)
117
#pragma warning(disable : 4251)
118
#pragma warning(disable : 4244)
119
#pragma warning(disable : 4267)
120
#pragma warning(disable : 4324)
121
#pragma warning(disable : 4702)
122
#pragma warning(disable : 4819)
123
#pragma warning(disable : 4840)
124
#pragma warning(disable : 4996)
125
#endif
126
127
// __has_builtin
128
#ifndef __has_builtin
129
#define __has_builtin(x) 0
130
#endif
131
132
#ifdef __cplusplus
133
#if __cplusplus >= 202002L
134
/**
135
* @def VLINK_LIKELY(x)
136
* @brief Hints to the compiler that expression @p x is very likely to be true.
137
*
138
* @details
139
* Under C++20 this expands to the @c [[likely]] attribute; under earlier standards
140
* on GCC/Clang it uses @c __builtin_expect; on MSVC it is a no-op.
141
*
142
* @param x A boolean expression.
143
*/
144
#define VLINK_LIKELY(x) (x) [[likely]]
145
/**
146
* @def VLINK_UNLIKELY(x)
147
* @brief Hints to the compiler that expression @p x is very unlikely to be true.
148
*
149
* @details
150
* Under C++20 this expands to the @c [[unlikely]] attribute; under earlier standards
151
* on GCC/Clang it uses @c __builtin_expect; on MSVC it is a no-op.
152
*
153
* @param x A boolean expression.
154
*/
155
#define VLINK_UNLIKELY(x) (x) [[unlikely]]
156
#else
157
#ifdef _WIN32
158
#define VLINK_LIKELY(x) (x)
159
#define VLINK_UNLIKELY(x) (x)
160
#else
161
#define VLINK_LIKELY(x) (__builtin_expect(!!(x), 1))
162
#define VLINK_UNLIKELY(x) (__builtin_expect(!!(x), 0))
163
#endif
164
#endif
165
#else
166
#define VLINK_LIKELY(x) (x)
167
#define VLINK_UNLIKELY(x) (x)
168
#endif
169
170
/**
171
* @def VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
172
* @brief Deletes the copy constructor and copy-assignment operator of @p classname.
173
*
174
* @details
175
* Place this macro in the private section of a class to prevent accidental copying.
176
* It expands to:
177
* @code
178
* classname(const classname&) = delete;
179
* classname& operator=(const classname&) = delete;
180
* @endcode
181
*
182
* @param classname The unqualified name of the enclosing class.
183
*/
184
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname) \
185
classname(const classname&) = delete; \
186
classname& operator=(const classname&) = delete;
187
188
/**
189
* @def VLINK_SINGLETON_CHECK(classname)
190
* @brief Injects a compile-time and run-time singleton enforcement guard.
191
*
192
* @details
193
* This macro:
194
* - Uses @c static_assert to verify that @p classname is @c final and has a
195
* private (non-default-constructible-from-outside) constructor.
196
* - Uses a @c std::atomic_flag to guarantee that the constructor is only invoked
197
* once per process. A second instantiation throws @c std::runtime_error.
198
*
199
* @note Must be placed in the @c private section of the class body.
200
*
201
* @param classname The unqualified name of the class being protected.
202
*/
203
#define VLINK_SINGLETON_CHECK(classname) \
204
private: \
205
struct ConstructorChecker { \
206
inline ConstructorChecker() { \
207
static_assert(std::is_final_v<classname>, "Constructor must be final."); \
208
static_assert(!std::is_default_constructible_v<classname>, "Constructor must be private."); \
209
\
210
static std::atomic_flag flag; \
211
\
212
if VLINK_UNLIKELY (flag.test_and_set()) { \
213
throw std::runtime_error("Constructor has been instantiated."); \
214
} \
215
} \
216
}; \
217
\
218
ConstructorChecker constructor_checker_;
219
220
/**
221
* @def VLINK_SINGLETON_DECLARE(classname)
222
* @brief Declares a complete Meyer's-singleton @c get() method with safety guards.
223
*
224
* @details
225
* Combines VLINK_SINGLETON_CHECK with a public static @c get() accessor that
226
* returns a reference to the single static instance. The constructor must be
227
* @c private and @c final, otherwise the embedded @c static_assert will fail.
228
*
229
* @param classname The unqualified name of the singleton class.
230
*
231
* @par Example
232
* @code
233
* class MyService final {
234
* VLINK_SINGLETON_DECLARE(MyService)
235
* public:
236
* void do_work();
237
* private:
238
* MyService() = default;
239
* };
240
*
241
* MyService::get().do_work();
242
* @endcode
243
*/
244
#define VLINK_SINGLETON_DECLARE(classname) \
245
public: \
246
inline static classname& get() { \
247
static classname singleton = classname(); \
248
return singleton; \
249
} \
250
\
251
private: \
252
VLINK_SINGLETON_CHECK(classname) \
253
VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
254
255
/**
256
* @def VLINK_MACRO_STRING_IFY(name)
257
* @brief Converts @p name to a C string literal using the preprocessor stringification operator.
258
*
259
* @param name A macro token (not a string literal) to stringify.
260
*/
261
#define VLINK_MACRO_STRING_IFY(name) #name
262
263
/**
264
* @def VLINK_MACRO_STRING_GET(name)
265
* @brief Stringifies the expanded value of macro @p name (two-level expansion).
266
*
267
* @details
268
* This two-step macro ensures that @p name is fully expanded before
269
* stringification. Use this instead of VLINK_MACRO_STRING_IFY when @p name
270
* is itself a macro that should be expanded first.
271
*
272
* @param name A macro whose expansion will be converted to a string literal.
273
*/
274
#define VLINK_MACRO_STRING_GET(name) VLINK_MACRO_STRING_IFY(name)
275
276
#if __has_builtin(__builtin_constant_p)
277
/**
278
* @def VLINK_ASSERT_CONSTANT(msg)
279
* @brief Asserts (at compile time) that @p msg is a constant string literal.
280
*
281
* @details
282
* On compilers that support @c __builtin_constant_p this expands to a
283
* @c static_assert; on others it is a no-op.
284
*
285
* @param msg The expression to check for compile-time constancy.
286
*/
287
#define VLINK_ASSERT_CONSTANT(msg) static_assert(__builtin_constant_p(msg), "Must be a constant string literal.");
288
#else
289
#define VLINK_ASSERT_CONSTANT(msg)
290
#endif
291
292
#if !defined(VLIKELY) && !defined(VUNLIKELY)
293
/**
294
* @def VLIKELY(...)
295
* @brief Shorthand alias for VLINK_LIKELY. Hints that the expression is likely true.
296
*/
297
#define VLIKELY(...) VLINK_LIKELY(__VA_ARGS__)
298
/**
299
* @def VUNLIKELY(...)
300
* @brief Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
301
*/
302
#define VUNLIKELY(...) VLINK_UNLIKELY(__VA_ARGS__)
303
#endif
include
vlink
base
macros.h
制作者
1.16.1