Point Cloud Library (PCL) 1.15.0
Loading...
Searching...
No Matches
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
240pcl_round (double number)
241{
242 return (number < 0.0 ? std::ceil (number - 0.5) : std::floor (number + 0.5));
243}
244__inline float
245pcl_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
384namespace pcl {
385
386inline void*
387aligned_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
408inline void
409aligned_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)
void * aligned_malloc(std::size_t size)
Definition pcl_macros.h:387
void aligned_free(void *ptr)
Definition pcl_macros.h:409
__inline double pcl_round(double number)
Win32 doesn't seem to have rounding functions.
Definition pcl_macros.h:240