Point Cloud Library (PCL)
1.15.1
Toggle main menu visibility
Loading...
Searching...
No Matches
pcl
pcl_macros.h
Go to the documentation of this file.
1
/*
2
* Software License Agreement (BSD License)
3
*
4
* Point Cloud Library (PCL) - www.pointclouds.org
5
* Copyright (c) 2010-2012, Willow Garage, Inc.
6
*
7
* All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
*
13
* * Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* * Redistributions in binary form must reproduce the above
16
* copyright notice, this list of conditions and the following
17
* disclaimer in the documentation and/or other materials provided
18
* with the distribution.
19
* * Neither the name of the copyright holder(s) nor the names of its
20
* contributors may be used to endorse or promote products derived
21
* from this software without specific prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
* POSSIBILITY OF SUCH DAMAGE.
35
*/
36
37
#pragma once
38
39
/**
40
* \file pcl/pcl_macros.h
41
*
42
* \brief Defines all the PCL and non-PCL macros used
43
* \ingroup common
44
*/
45
46
#if defined __INTEL_COMPILER
47
#pragma warning disable 2196 2536 279
48
#endif
49
50
#if defined _MSC_VER
51
// 4244 : conversion from 'type1' to 'type2', possible loss of data
52
// 4661 : no suitable definition provided for explicit template instantiation request
53
// 4503 : decorated name length exceeded, name was truncated
54
// 4146 : unary minus operator applied to unsigned type, result still unsigned
55
#pragma warning (disable: 4018 4244 4267 4521 4251 4661 4305 4503 4146)
56
#endif
57
58
#ifndef _USE_MATH_DEFINES
59
#define _USE_MATH_DEFINES
60
#endif
61
#include <cmath>
62
#include <cstdlib>
63
#include <iostream>
64
65
// We need to check for GCC version, because GCC releases before 9 were implementing an
66
// OpenMP 3.1 data sharing rule, even OpenMP 4 is supported, so a plain OpenMP version 4 check
67
// isn't enough (see https://www.gnu.org/software/gcc/gcc-9/porting_to.html#ompdatasharing)
68
#if (defined _OPENMP && (_OPENMP <= 201307)) || (defined __GNUC__ && (__GNUC__ >= 6 && __GNUC__ < 9))
69
#define OPENMP_LEGACY_CONST_DATA_SHARING_RULE 1
70
#else
71
#define OPENMP_LEGACY_CONST_DATA_SHARING_RULE 0
72
#endif
73
74
#include <pcl/pcl_config.h>
75
76
#include <boost/preprocessor/arithmetic/add.hpp>
77
#include <boost/preprocessor/comparison/equal.hpp>
78
#include <boost/preprocessor/comparison/less.hpp>
79
#include <boost/preprocessor/control/if.hpp>
80
#include <boost/preprocessor/stringize.hpp>
81
82
// MSVC < 2019 have issues:
83
// * can't short-circuiting logic in macros
84
// * don't define standard macros
85
// => this leads to annoying C4067 warnings (see https://developercommunity.visualstudio.com/content/problem/327796/-has-cpp-attribute-emits-warning-is-wrong-highligh.html)
86
#if defined(_MSC_VER)
87
// nvcc on msvc can't work with [[deprecated]]
88
#if !defined(__CUDACC__)
89
#define _PCL_DEPRECATED_IMPL(Message) [[deprecated(Message)]]
90
#else
91
#define _PCL_DEPRECATED_IMPL(Message)
92
#endif
93
#elif __has_cpp_attribute(deprecated)
94
#define _PCL_DEPRECATED_IMPL(Message) [[deprecated(Message)]]
95
#else
96
#warning "You need to implement _PCL_DEPRECATED_IMPL for this compiler"
97
#define _PCL_DEPRECATED_IMPL(Message)
98
#endif
99
100
// Macro for pragma operator
101
#if (defined (__GNUC__) || defined(__clang__))
102
#define PCL_PRAGMA(x) _Pragma (#x)
103
#elif _MSC_VER
104
#define PCL_PRAGMA(x) __pragma (#x)
105
#else
106
#define PCL_PRAGMA
107
#endif
108
109
// Macro for emitting pragma warning for deprecated headers
110
#if (defined (__GNUC__) || defined(__clang__))
111
#define _PCL_DEPRECATED_HEADER_IMPL(Message) PCL_PRAGMA (message Message)
112
#elif _MSC_VER
113
#define _PCL_DEPRECATED_HEADER_IMPL(Message) PCL_PRAGMA (warning (Message))
114
#else
115
#warning "You need to implement _PCL_DEPRECATED_HEADER_IMPL for this compiler"
116
#define _PCL_DEPRECATED_HEADER_IMPL(Message)
117
#endif
118
119
// NOLINTBEGIN(bugprone-macro-parentheses)
120
/**
121
* \brief A handy way to inform the user of the removal deadline
122
*/
123
#define _PCL_PREPARE_REMOVAL_MESSAGE(Major, Minor, Msg) \
124
Msg " (It will be removed in PCL " BOOST_PP_STRINGIZE(Major.Minor) ")"
125
// NOLINTEND(bugprone-macro-parentheses)
126
127
/**
128
* \brief Tests for Minor < PCL_MINOR_VERSION
129
* \details When PCL VERSION is of format `34.12.99`, this macro behaves as if it is
130
* already `34.13.0`, and allows for smoother transition for maintainers
131
*/
132
#define _PCL_COMPAT_MINOR_VERSION(Minor, IfPass, IfFail) \
133
BOOST_PP_IF(BOOST_PP_EQUAL(PCL_REVISION_VERSION, 99), \
134
BOOST_PP_IF(BOOST_PP_LESS(BOOST_PP_ADD(PCL_MINOR_VERSION, 1), Minor), IfPass, IfFail), \
135
BOOST_PP_IF(BOOST_PP_LESS(PCL_MINOR_VERSION, Minor), IfPass, IfFail))
136
137
/**
138
* \brief Tests for Major == PCL_MAJOR_VERSION
139
* \details When PCL VERSION is of format `34.99.12`, this macro behaves as if it is
140
* already `35.0.0`, and allows for smoother transition for maintainers
141
*/
142
#define _PCL_COMPAT_MAJOR_VERSION(Major, IfPass, IfFail) \
143
BOOST_PP_IF(BOOST_PP_EQUAL(PCL_MINOR_VERSION, 99), \
144
BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_ADD(PCL_MAJOR_VERSION, 1), Major), IfPass, IfFail), \
145
BOOST_PP_IF(BOOST_PP_EQUAL(PCL_MAJOR_VERSION, Major), IfPass, IfFail))
146
147
/**
148
* \brief macro for compatibility across compilers and help remove old deprecated
149
* items for the Major.Minor release
150
*
151
* \details compiler errors of `unneeded_deprecation` and `major_version_mismatch`
152
* are hints to the developer that those items can be safely removed.
153
* Behavior of PCL_DEPRECATED(1, 99, "Not needed anymore")
154
* * till PCL 1.98: "Not needed anymore (It will be removed in PCL 1.99)"
155
* * PCL 1.99 onwards: compiler error with "unneeded_deprecation"
156
* * PCL 2.0 onwards: compiler error with "major_version_mismatch"
157
*/
158
#define PCL_DEPRECATED(Major, Minor, Message) \
159
_PCL_COMPAT_MAJOR_VERSION( \
160
Major, \
161
_PCL_COMPAT_MINOR_VERSION( \
162
Minor, \
163
_PCL_DEPRECATED_IMPL(_PCL_PREPARE_REMOVAL_MESSAGE(Major, Minor, Message)), \
164
unneeded_deprecation), \
165
major_version_mismatch)
166
167
/**
168
* \brief macro for compatibility across compilers and help remove old deprecated
169
* headers for the Major.Minor release
170
*
171
* \details compiler errors of `unneeded_header` and `major_version_mismatch`
172
* are hints to the developer that those items can be safely removed.
173
* Behavior of PCL_DEPRECATED_HEADER(1, 99, "Use file <newfile.h> instead.")
174
* * till PCL 1.98: "This header is deprecated. Use file <newfile.h> instead. (It will be removed in PCL 1.99)"
175
* * PCL 1.99 onwards: compiler error with "unneeded_header"
176
* * PCL 2.0 onwards: compiler error with "major_version_mismatch"
177
*/
178
#define PCL_DEPRECATED_HEADER(Major, Minor, Message) \
179
_PCL_COMPAT_MAJOR_VERSION( \
180
Major, \
181
_PCL_COMPAT_MINOR_VERSION( \
182
Minor, \
183
_PCL_DEPRECATED_HEADER_IMPL(_PCL_PREPARE_REMOVAL_MESSAGE( \
184
Major, \
185
Minor, \
186
"This header is deprecated. " Message)), \
187
unneeded_header), \
188
major_version_mismatch)
189
190
#if defined _WIN32
191
// Define math constants, without including math.h, to prevent polluting global namespace with old math methods
192
// Copied from math.h
193
// Check for M_2_SQRTPI since the cmath header on mingw-w64 doesn't seem to define
194
// _MATH_DEFINES_DEFINED when included with _USE_MATH_DEFINES
195
#if !defined _MATH_DEFINES_DEFINED && !defined M_2_SQRTPI
196
#define _MATH_DEFINES_DEFINED
197
198
#define M_E 2.71828182845904523536
// e
199
#define M_LOG2E 1.44269504088896340736
// log2(e)
200
#define M_LOG10E 0.434294481903251827651
// log10(e)
201
#define M_LN2 0.693147180559945309417
// ln(2)
202
#define M_LN10 2.30258509299404568402
// ln(10)
203
#define M_PI 3.14159265358979323846
// pi
204
#define M_PI_2 1.57079632679489661923
// pi/2
205
#define M_PI_4 0.785398163397448309616
// pi/4
206
#define M_1_PI 0.318309886183790671538
// 1/pi
207
#define M_2_PI 0.636619772367581343076
// 2/pi
208
#define M_2_SQRTPI 1.12837916709551257390
// 2/sqrt(pi)
209
#define M_SQRT2 1.41421356237309504880
// sqrt(2)
210
#define M_SQRT1_2 0.707106781186547524401
// 1/sqrt(2)
211
#endif
212
213
#if defined _MSC_VER
214
// Stupid. This should be removed when all the PCL dependencies have min/max fixed.
215
#ifndef NOMINMAX
216
#define NOMINMAX
217
#endif
218
219
#define __PRETTY_FUNCTION__ __FUNCSIG__
220
#endif
221
#endif
// defined _WIN32
222
223
#ifndef DEG2RAD
224
#define DEG2RAD(x) ((x)*0.017453293)
225
#endif
226
227
#ifndef RAD2DEG
228
#define RAD2DEG(x) ((x)*57.29578)
229
#endif
230
231
/** \brief Macro that maps version information given by major.minor.patch to a linear integer value to enable easy comparison
232
*/
233
#define PCL_LINEAR_VERSION(major,minor,patch) ((major)<<16|(minor)<<8|(patch))
234
235
/** Win32 doesn't seem to have rounding functions.
236
* Therefore implement our own versions of these functions here.
237
*/
238
239
__inline
double
240
pcl_round
(
double
number)
241
{
242
return
(number < 0.0 ? std::ceil (number - 0.5) : std::floor (number + 0.5));
243
}
244
__inline
float
245
pcl_round
(
float
number)
246
{
247
return
(number < 0.0f ? std::ceil (number - 0.5f) : std::floor (number + 0.5f));
248
}
249
250
#ifdef __GNUC__
251
#define pcl_lrint(x) (lrint(static_cast<double> (x)))
252
#define pcl_lrintf(x) (lrintf(static_cast<float> (x)))
253
#else
254
#define pcl_lrint(x) (static_cast<long int>(pcl_round(x)))
255
#define pcl_lrintf(x) (static_cast<long int>(pcl_round(x)))
256
#endif
257
258
#ifdef WIN32
259
#define pcl_sleep(x) Sleep(1000*(x))
260
#else
261
#define pcl_sleep(x) sleep(x)
262
#endif
263
264
#ifndef PVAR
265
#define PVAR(s) \
266
#s << " = " << (s) << std::flush
267
#endif
268
#ifndef PVARN
269
#define PVARN(s) \
270
#s << " = " << (s) << "\n"
271
#endif
272
#ifndef PVARC
273
#define PVARC(s) \
274
#s << " = " << (s) << ", " << std::flush
275
#endif
276
#ifndef PVARS
277
#define PVARS(s) \
278
#s << " = " << (s) << " " << std::flush
279
#endif
280
#ifndef PVARA
281
#define PVARA(s) \
282
#s << " = " << RAD2DEG(s) << "deg" << std::flush
283
#endif
284
#ifndef PVARAN
285
#define PVARAN(s) \
286
#s << " = " << RAD2DEG(s) << "deg\n"
287
#endif
288
#ifndef PVARAC
289
#define PVARAC(s) \
290
#s << " = " << RAD2DEG(s) << "deg, " << std::flush
291
#endif
292
#ifndef PVARAS
293
#define PVARAS(s) \
294
#s << " = " << RAD2DEG(s) << "deg " << std::flush
295
#endif
296
297
#define FIXED(s) \
298
std::fixed << (s) << std::resetiosflags(std::ios_base::fixed)
299
300
#ifndef ERASE_STRUCT
301
#define ERASE_STRUCT(var) memset(&(var), 0, sizeof(var))
302
#endif
303
304
#ifndef ERASE_ARRAY
305
#define ERASE_ARRAY(var, size) memset(var, 0, (size)*sizeof(*(var)))
306
#endif
307
308
#ifndef SET_ARRAY
309
#define SET_ARRAY(var, value, size) { for (decltype(size) i = 0; i < (size); ++i) (var)[i]=value; }
310
#endif
311
312
#ifndef PCL_EXTERN_C
313
#ifdef __cplusplus
314
#define PCL_EXTERN_C extern "C"
315
#else
316
#define PCL_EXTERN_C
317
#endif
318
#endif
319
320
#if defined WIN32 || defined _WIN32 || defined WINCE || defined __MINGW32__
321
#ifdef PCLAPI_EXPORTS
322
#define PCL_EXPORTS __declspec(dllexport)
323
#else
324
#define PCL_EXPORTS
325
#endif
326
#else
327
#ifdef PCL_SYMBOL_VISIBILITY_HIDDEN
328
#define PCL_EXPORTS __attribute__ ((visibility ("default")))
329
#else
330
#define PCL_EXPORTS
331
#endif
332
#endif
333
334
#if defined WIN32 || defined _WIN32
335
#define PCL_CDECL __cdecl
336
#define PCL_STDCALL __stdcall
337
#else
338
#define PCL_CDECL
339
#define PCL_STDCALL
340
#endif
341
342
#ifndef PCLAPI
343
#define PCLAPI(rettype) PCL_EXTERN_C PCL_EXPORTS rettype PCL_CDECL
344
#endif
345
346
//for clang cf. http://clang.llvm.org/docs/LanguageExtensions.html
347
#ifndef __has_extension
348
#define __has_extension(x) 0
// Compatibility with pre-3.0 compilers.
349
#endif
350
351
#if defined (__GNUC__) || defined (__PGI) || defined (__IBMCPP__) || defined (__SUNPRO_CC)
352
#define PCL_ALIGN(alignment) __attribute__((aligned(alignment)))
353
#elif defined (_MSC_VER)
354
#define PCL_ALIGN(alignment) __declspec(align(alignment))
355
#else
356
#error Alignment not supported on your platform
357
#endif
358
359
#if defined(__GLIBC__) && PCL_LINEAR_VERSION(__GLIBC__,__GLIBC_MINOR__,0)>PCL_LINEAR_VERSION(2,8,0)
360
#define GLIBC_MALLOC_ALIGNED 1
361
#else
362
#define GLIBC_MALLOC_ALIGNED 0
363
#endif
364
365
#if defined(__FreeBSD__) && !defined(__arm__) && !defined(__mips__)
366
#define FREEBSD_MALLOC_ALIGNED 1
367
#else
368
#define FREEBSD_MALLOC_ALIGNED 0
369
#endif
370
371
#if defined(__APPLE__) || defined(_WIN64) || GLIBC_MALLOC_ALIGNED || FREEBSD_MALLOC_ALIGNED
372
#define MALLOC_ALIGNED 1
373
#endif
374
375
#if defined (HAVE_MM_MALLOC)
376
// Intel compiler defines an incompatible _mm_malloc signature
377
#if defined(__INTEL_COMPILER)
378
#include <malloc.h>
379
#else
380
#include <mm_malloc.h>
381
#endif
382
#endif
383
384
namespace
pcl
{
385
386
inline
void
*
387
aligned_malloc
(std::size_t size)
388
{
389
void
* ptr;
390
#if defined(MALLOC_ALIGNED)
391
ptr = std::malloc(size);
392
#elif defined(HAVE_POSIX_MEMALIGN)
393
if
(posix_memalign(&ptr, 16, size))
394
ptr = 0;
395
#elif defined(HAVE_MM_MALLOC)
396
ptr = _mm_malloc(size, 16);
397
#elif defined(_MSC_VER)
398
ptr = _aligned_malloc(size, 16);
399
#elif defined(ANDROID)
400
ptr = memalign(16, size);
401
#else
402
#error aligned_malloc not supported on your platform
403
ptr = 0;
404
#endif
405
return
(ptr);
406
}
407
408
inline
void
409
aligned_free
(
void
* ptr)
410
{
411
#if defined(MALLOC_ALIGNED) || defined(HAVE_POSIX_MEMALIGN)
412
std::free(ptr);
413
#elif defined(HAVE_MM_MALLOC)
414
_mm_free(ptr);
415
#elif defined(_MSC_VER)
416
_aligned_free(ptr);
417
#elif defined(ANDROID)
418
free(ptr);
419
#else
420
#error aligned_free not supported on your platform
421
#endif
422
}
423
424
}
// namespace pcl
425
426
/**
427
* \brief Macro to add a no-op or a fallthrough attribute based on compiler feature
428
*
429
* \ingroup common
430
*/
431
#if (__cplusplus >= 201703L) || (defined(_MSC_VER) && (_MSC_VER >= 1910) && (_MSVC_LANG >= 201703L))
432
#define PCL_FALLTHROUGH [[fallthrough]];
433
#elif defined(__clang__)
434
#define PCL_FALLTHROUGH [[clang::fallthrough]];
435
#elif defined(__GNUC__) && (__GNUC__ >= 7)
436
#define PCL_FALLTHROUGH [[gnu::fallthrough]];
437
#else
438
#define PCL_FALLTHROUGH
439
#endif
440
441
#if (__cplusplus >= 201703L) || (defined(_MSC_VER) && (_MSC_VER >= 1911) && (_MSVC_LANG >= 201703L))
442
#define PCL_NODISCARD [[nodiscard]]
443
#elif defined(__clang__) && (PCL_LINEAR_VERSION(__clang_major__, __clang_minor__, 0) >= PCL_LINEAR_VERSION(3, 9, 0))
444
#define PCL_NODISCARD [[clang::warn_unused_result]]
445
#elif defined(__GNUC__)
446
#define PCL_NODISCARD [[gnu::warn_unused_result]]
447
#else
448
#define PCL_NODISCARD
449
#endif
450
451
#ifdef __cpp_if_constexpr
452
#define PCL_IF_CONSTEXPR(x) if constexpr(x)
453
#else
454
#define PCL_IF_CONSTEXPR(x) if (x)
455
#endif
456
457
// [[unlikely]] can be used on any conditional branch, but __builtin_expect is restricted to the evaluation point
458
// This makes it quite difficult to create a single macro for switch and while/if
459
/**
460
* @def PCL_CONDITION_UNLIKELY
461
* @brief Tries to inform the compiler to optimize codegen assuming that the condition will probably evaluate to false
462
* @note Prefer using `PCL_{IF,WHILE}_UNLIKELY`
463
* @warning This can't be used with switch statements
464
* @details This tries to help the compiler optimize for the unlikely case.
465
* Most compilers assume that the condition would evaluate to true in if and while loops (reference needed)
466
* As such the opposite of this macro (PCL_CONDITION_LIKELY) will not result in significant performance improvement
467
*
468
* Some sample usage:
469
* @code{.cpp}
470
* if PCL_CONDITION_UNLIKELY(x == 0) { return; } else { throw std::runtime_error("some error"); }
471
* //
472
* while PCL_CONDITION_UNLIKELY(wait_for_result) { sleep(1); } // busy wait, with minimal chances of waiting
473
* @endcode
474
*/
475
#if __has_cpp_attribute(unlikely)
476
#define PCL_CONDITION_UNLIKELY(x) (static_cast<bool>(x)) [[unlikely]]
477
#elif defined(__GNUC__)
478
#define PCL_CONDITION_UNLIKELY(x) (__builtin_expect(static_cast<bool>(x), 0))
479
#elif defined(__clang__) && (PCL_LINEAR_VERSION(__clang_major__, __clang_minor__, 0) >= PCL_LINEAR_VERSION(3, 9, 0))
480
#define PCL_CONDITION_UNLIKELY(x) (__builtin_expect(static_cast<bool>(x), 0))
481
#else
// MSVC has no such alternative
482
#define PCL_CONDITION_UNLIKELY(x) (x)
483
#endif
484
485
#define PCL_IF_UNLIKELY(x) if PCL_CONDITION_UNLIKELY(x)
486
#define PCL_WHILE_UNLIKELY(x) while PCL_CONDITION_UNLIKELY(x)
pcl
Definition
convolution.h:46
pcl::aligned_malloc
void * aligned_malloc(std::size_t size)
Definition
pcl_macros.h:387
pcl::aligned_free
void aligned_free(void *ptr)
Definition
pcl_macros.h:409
pcl_round
__inline double pcl_round(double number)
Win32 doesn't seem to have rounding functions.
Definition
pcl_macros.h:240