Point Cloud Library (PCL)  1.15.0-dev
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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)
void aligned_free(void *ptr)
Definition: pcl_macros.h:409
void * aligned_malloc(std::size_t size)
Definition: pcl_macros.h:387
__inline double pcl_round(double number)
Win32 doesn't seem to have rounding functions.
Definition: pcl_macros.h:240