TrajoptLib
Library for generating time-optimal trajectories for FRC robots.
Loading...
Searching...
No Matches
symbol_exports.hpp
1
// Copyright (c) TrajoptLib contributors
2
3
#pragma once
4
5
#ifdef _WIN32
6
#ifdef _MSC_VER
7
#pragma warning(disable : 4251)
8
#endif
9
10
#ifdef TRAJOPT_EXPORTS
11
#ifdef __GNUC__
12
#define TRAJOPT_DLLEXPORT __attribute__((dllexport))
13
#else
14
#define TRAJOPT_DLLEXPORT __declspec(dllexport)
15
#endif
16
17
#elif defined(TRAJOPT_IMPORTS)
18
19
#ifdef __GNUC__
20
#define TRAJOPT_DLLEXPORT __attribute__((dllimport))
21
#else
22
#define TRAJOPT_DLLEXPORT __declspec(dllimport)
23
#endif
24
25
#else
26
#define TRAJOPT_DLLEXPORT
27
#endif
28
29
#else
// _WIN32
30
31
#ifdef TRAJOPT_EXPORTS
32
#define TRAJOPT_DLLEXPORT __attribute__((visibility("default")))
33
#else
34
#define TRAJOPT_DLLEXPORT
35
#endif
36
37
#endif
// _WIN32
38
39
// Synopsis
40
//
41
// This header provides macros for using FOO_EXPORT macros with explicit
42
// template instantiation declarations and definitions.
43
// Generally, the FOO_EXPORT macros are used at declarations,
44
// and GCC requires them to be used at explicit instantiation declarations,
45
// but MSVC requires __declspec(dllexport) to be used at the explicit
46
// instantiation definitions instead.
47
48
// Usage
49
//
50
// In a header file, write:
51
//
52
// extern template class EXPORT_TEMPLATE_DECLARE(FOO_EXPORT) foo<bar>;
53
//
54
// In a source file, write:
55
//
56
// template class EXPORT_TEMPLATE_DEFINE(FOO_EXPORT) foo<bar>;
57
58
// Implementation notes
59
//
60
// The implementation of this header uses some subtle macro semantics to
61
// detect what the provided FOO_EXPORT value was defined as and then
62
// to dispatch to appropriate macro definitions. Unfortunately,
63
// MSVC's C preprocessor is rather non-compliant and requires special
64
// care to make it work.
65
//
66
// Issue 1.
67
//
68
// #define F(x)
69
// F()
70
//
71
// MSVC emits warning C4003 ("not enough actual parameters for macro
72
// 'F'), even though it's a valid macro invocation. This affects the
73
// macros below that take just an "export" parameter, because export
74
// may be empty.
75
//
76
// As a workaround, we can add a dummy parameter and arguments:
77
//
78
// #define F(x,_)
79
// F(,)
80
//
81
// Issue 2.
82
//
83
// #define F(x) G##x
84
// #define Gj() ok
85
// F(j())
86
//
87
// The correct replacement for "F(j())" is "ok", but MSVC replaces it
88
// with "Gj()". As a workaround, we can pass the result to an
89
// identity macro to force MSVC to look for replacements again. (This
90
// is why EXPORT_TEMPLATE_STYLE_3 exists.)
91
92
#define EXPORT_TEMPLATE_DECLARE(export) \
93
EXPORT_TEMPLATE_INVOKE(DECLARE, EXPORT_TEMPLATE_STYLE(export, ), export)
94
#define EXPORT_TEMPLATE_DEFINE(export) \
95
EXPORT_TEMPLATE_INVOKE(DEFINE, EXPORT_TEMPLATE_STYLE(export, ), export)
96
97
// INVOKE is an internal helper macro to perform parameter replacements
98
// and token pasting to chain invoke another macro. E.g.,
99
// EXPORT_TEMPLATE_INVOKE(DECLARE, DEFAULT, FOO_EXPORT)
100
// will export to call
101
// EXPORT_TEMPLATE_DECLARE_DEFAULT(FOO_EXPORT, )
102
// (but with FOO_EXPORT expanded too).
103
#define EXPORT_TEMPLATE_INVOKE(which, style, export) \
104
EXPORT_TEMPLATE_INVOKE_2(which, style, export)
105
#define EXPORT_TEMPLATE_INVOKE_2(which, style, export) \
106
EXPORT_TEMPLATE_##which##_##style(export, )
107
108
// Default style is to apply the FOO_EXPORT macro at declaration sites.
109
#define EXPORT_TEMPLATE_DECLARE_DEFAULT(export, _) export
110
#define EXPORT_TEMPLATE_DEFINE_DEFAULT(export, _)
111
112
// The "MSVC hack" style is used when FOO_EXPORT is defined
113
// as __declspec(dllexport), which MSVC requires to be used at
114
// definition sites instead.
115
#define EXPORT_TEMPLATE_DECLARE_MSVC_HACK(export, _)
116
#define EXPORT_TEMPLATE_DEFINE_MSVC_HACK(export, _) export
117
118
// EXPORT_TEMPLATE_STYLE is an internal helper macro that identifies which
119
// export style needs to be used for the provided FOO_EXPORT macro definition.
120
// "", "__attribute__(...)", and "__declspec(dllimport)" are mapped
121
// to "DEFAULT"; while "__declspec(dllexport)" is mapped to "MSVC_HACK".
122
//
123
// It's implemented with token pasting to transform the __attribute__ and
124
// __declspec annotations into macro invocations. E.g., if FOO_EXPORT is
125
// defined as "__declspec(dllimport)", it undergoes the following sequence of
126
// macro substitutions:
127
// EXPORT_TEMPLATE_STYLE(FOO_EXPORT, )
128
// EXPORT_TEMPLATE_STYLE_2(__declspec(dllimport), )
129
// EXPORT_TEMPLATE_STYLE_3(EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport))
130
// EXPORT_TEMPLATE_STYLE_MATCH__declspec(dllimport)
131
// EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport
132
// DEFAULT
133
#define EXPORT_TEMPLATE_STYLE(export, _) EXPORT_TEMPLATE_STYLE_2(export, )
134
#define EXPORT_TEMPLATE_STYLE_2(export, _) \
135
EXPORT_TEMPLATE_STYLE_3( \
136
EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA##export)
137
#define EXPORT_TEMPLATE_STYLE_3(style) style
138
139
// Internal helper macros for EXPORT_TEMPLATE_STYLE.
140
//
141
// XXX: C++ reserves all identifiers containing "__" for the implementation,
142
// but "__attribute__" and "__declspec" already contain "__" and the token-paste
143
// operator can only add characters; not remove them. To minimize the risk of
144
// conflict with implementations, we include "foj3FJo5StF0OvIzl7oMxA" (a random
145
// 128-bit string, encoded in Base64) in the macro name.
146
#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA DEFAULT
147
#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__attribute__(...) \
148
DEFAULT
149
#define EXPORT_TEMPLATE_STYLE_MATCH_foj3FJo5StF0OvIzl7oMxA__declspec(arg) \
150
EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_##arg
151
152
// Internal helper macros for EXPORT_TEMPLATE_STYLE.
153
#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllexport MSVC_HACK
154
#define EXPORT_TEMPLATE_STYLE_MATCH_DECLSPEC_dllimport DEFAULT
include
trajopt
util
symbol_exports.hpp
Generated on
for TrajoptLib by
1.15.0