common.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /// @file
  2. /// Common functionality.
  3. #ifndef SOPHUS_COMMON_HPP
  4. #define SOPHUS_COMMON_HPP
  5. #include <cmath>
  6. #include <cstdio>
  7. #include <cstdlib>
  8. #include <random>
  9. #include <type_traits>
  10. #include <eigen3/Eigen/Core>
  11. #if !defined(SOPHUS_DISABLE_ENSURES)
  12. #include "formatstring.hpp"
  13. #endif //!defined(SOPHUS_DISABLE_ENSURES)
  14. // following boost's assert.hpp
  15. #undef SOPHUS_ENSURE
  16. // ENSURES are similar to ASSERTS, but they are always checked for (including in
  17. // release builds). At the moment there are no ASSERTS in Sophus which should
  18. // only be used for checks which are performance critical.
  19. #ifdef __GNUC__
  20. #define SOPHUS_FUNCTION __PRETTY_FUNCTION__
  21. #elif (_MSC_VER >= 1310)
  22. #define SOPHUS_FUNCTION __FUNCTION__
  23. #else
  24. #define SOPHUS_FUNCTION "unknown"
  25. #endif
  26. // Make sure this compiles with older versions of Eigen which do not have
  27. // EIGEN_DEVICE_FUNC defined.
  28. #ifndef EIGEN_DEVICE_FUNC
  29. #define EIGEN_DEVICE_FUNC
  30. #endif
  31. // NVCC on windows has issues with defaulting the Map specialization constructors, so
  32. // special case that specific platform case.
  33. #if defined(_MSC_VER) && defined(__CUDACC__)
  34. #define SOPHUS_WINDOW_NVCC_FALLBACK
  35. #endif
  36. #define SOPHUS_FUNC EIGEN_DEVICE_FUNC
  37. #if defined(SOPHUS_DISABLE_ENSURES)
  38. #define SOPHUS_ENSURE(expr, ...) ((void)0)
  39. #elif defined(SOPHUS_ENABLE_ENSURE_HANDLER)
  40. namespace Sophus {
  41. void ensureFailed(char const* function, char const* file, int line,
  42. char const* description);
  43. }
  44. #define SOPHUS_ENSURE(expr, ...) \
  45. ((expr) ? ((void)0) \
  46. : ::Sophus::ensureFailed( \
  47. SOPHUS_FUNCTION, __FILE__, __LINE__, \
  48. Sophus::details::FormatString(__VA_ARGS__).c_str()))
  49. #else
  50. // LCOV_EXCL_START
  51. namespace Sophus {
  52. template <class... Args>
  53. SOPHUS_FUNC void defaultEnsure(char const* function, char const* file, int line,
  54. char const* description, Args&&... args) {
  55. std::printf("Sophus ensure failed in function '%s', file '%s', line %d.\n",
  56. function, file, line);
  57. #ifdef __CUDACC__
  58. std::printf("%s", description);
  59. #else
  60. std::cout << details::FormatString(description, std::forward<Args>(args)...)
  61. << std::endl;
  62. std::abort();
  63. #endif
  64. }
  65. } // namespace Sophus
  66. // LCOV_EXCL_STOP
  67. #define SOPHUS_ENSURE(expr, ...) \
  68. ((expr) ? ((void)0) \
  69. : Sophus::defaultEnsure(SOPHUS_FUNCTION, __FILE__, __LINE__, \
  70. ##__VA_ARGS__))
  71. #endif
  72. namespace Sophus {
  73. template <class Scalar>
  74. struct Constants {
  75. SOPHUS_FUNC static Scalar epsilon() { return Scalar(1e-10); }
  76. SOPHUS_FUNC static Scalar epsilonSqrt() {
  77. using std::sqrt;
  78. return sqrt(epsilon());
  79. }
  80. SOPHUS_FUNC static Scalar pi() {
  81. return Scalar(3.141592653589793238462643383279502884);
  82. }
  83. };
  84. template <>
  85. struct Constants<float> {
  86. SOPHUS_FUNC static float constexpr epsilon() {
  87. return static_cast<float>(1e-5);
  88. }
  89. SOPHUS_FUNC static float epsilonSqrt() { return std::sqrt(epsilon()); }
  90. SOPHUS_FUNC static float constexpr pi() {
  91. return 3.141592653589793238462643383279502884f;
  92. }
  93. };
  94. /// Nullopt type of lightweight optional class.
  95. struct nullopt_t {
  96. explicit constexpr nullopt_t() {}
  97. };
  98. constexpr nullopt_t nullopt{};
  99. /// Lightweight optional implementation which requires ``T`` to have a
  100. /// default constructor.
  101. ///
  102. /// TODO: Replace with std::optional once Sophus moves to c++17.
  103. ///
  104. template <class T>
  105. class optional {
  106. public:
  107. optional() : is_valid_(false) {}
  108. optional(nullopt_t) : is_valid_(false) {}
  109. optional(T const& type) : type_(type), is_valid_(true) {}
  110. explicit operator bool() const { return is_valid_; }
  111. T const* operator->() const {
  112. SOPHUS_ENSURE(is_valid_, "must be valid");
  113. return &type_;
  114. }
  115. T* operator->() {
  116. SOPHUS_ENSURE(is_valid_, "must be valid");
  117. return &type_;
  118. }
  119. T const& operator*() const {
  120. SOPHUS_ENSURE(is_valid_, "must be valid");
  121. return type_;
  122. }
  123. T& operator*() {
  124. SOPHUS_ENSURE(is_valid_, "must be valid");
  125. return type_;
  126. }
  127. private:
  128. T type_;
  129. bool is_valid_;
  130. };
  131. template <bool B, class T = void>
  132. using enable_if_t = typename std::enable_if<B, T>::type;
  133. template <class G>
  134. struct IsUniformRandomBitGenerator {
  135. static const bool value = std::is_unsigned<typename G::result_type>::value &&
  136. std::is_unsigned<decltype(G::min())>::value &&
  137. std::is_unsigned<decltype(G::max())>::value;
  138. };
  139. } // namespace Sophus
  140. #endif // SOPHUS_COMMON_HPP