common.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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 <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. #define SOPHUS_FUNC EIGEN_DEVICE_FUNC
  32. #if defined(SOPHUS_DISABLE_ENSURES)
  33. #define SOPHUS_ENSURE(expr, ...) ((void)0)
  34. #elif defined(SOPHUS_ENABLE_ENSURE_HANDLER)
  35. namespace Sophus {
  36. void ensureFailed(char const* function, char const* file, int line,
  37. char const* description);
  38. }
  39. #define SOPHUS_ENSURE(expr, ...) \
  40. ((expr) ? ((void)0) \
  41. : ::Sophus::ensureFailed( \
  42. SOPHUS_FUNCTION, __FILE__, __LINE__, \
  43. Sophus::details::FormatString(__VA_ARGS__).c_str()))
  44. #else
  45. // LCOV_EXCL_START
  46. namespace Sophus {
  47. template <class... Args>
  48. SOPHUS_FUNC void defaultEnsure(char const* function, char const* file, int line,
  49. char const* description, Args&&... args) {
  50. std::printf("Sophus ensure failed in function '%s', file '%s', line %d.\n",
  51. function, file, line);
  52. #ifdef __CUDACC__
  53. std::printf("%s", description);
  54. #else
  55. std::cout << details::FormatString(description, std::forward<Args>(args)...)
  56. << std::endl;
  57. std::abort();
  58. #endif
  59. }
  60. } // namespace Sophus
  61. // LCOV_EXCL_STOP
  62. #define SOPHUS_ENSURE(expr, ...) \
  63. ((expr) ? ((void)0) \
  64. : Sophus::defaultEnsure(SOPHUS_FUNCTION, __FILE__, __LINE__, \
  65. ##__VA_ARGS__))
  66. #endif
  67. namespace Sophus {
  68. template <class Scalar>
  69. struct Constants {
  70. SOPHUS_FUNC static Scalar epsilon() { return Scalar(1e-10); }
  71. SOPHUS_FUNC static Scalar epsilonSqrt() {
  72. using std::sqrt;
  73. return sqrt(epsilon());
  74. }
  75. SOPHUS_FUNC static Scalar pi() {
  76. return Scalar(3.141592653589793238462643383279502884);
  77. }
  78. };
  79. template <>
  80. struct Constants<float> {
  81. SOPHUS_FUNC static float constexpr epsilon() {
  82. return static_cast<float>(1e-5);
  83. }
  84. SOPHUS_FUNC static float epsilonSqrt() { return std::sqrt(epsilon()); }
  85. SOPHUS_FUNC static float constexpr pi() {
  86. return 3.141592653589793238462643383279502884f;
  87. }
  88. };
  89. /// Nullopt type of lightweight optional class.
  90. struct nullopt_t {
  91. explicit constexpr nullopt_t() {}
  92. };
  93. constexpr nullopt_t nullopt{};
  94. /// Lightweight optional implementation which requires ``T`` to have a
  95. /// default constructor.
  96. ///
  97. /// TODO: Replace with std::optional once Sophus moves to c++17.
  98. ///
  99. template <class T>
  100. class optional {
  101. public:
  102. optional() : is_valid_(false) {}
  103. optional(nullopt_t) : is_valid_(false) {}
  104. optional(T const& type) : type_(type), is_valid_(true) {}
  105. explicit operator bool() const { return is_valid_; }
  106. T const* operator->() const {
  107. SOPHUS_ENSURE(is_valid_, "must be valid");
  108. return &type_;
  109. }
  110. T* operator->() {
  111. SOPHUS_ENSURE(is_valid_, "must be valid");
  112. return &type_;
  113. }
  114. T const& operator*() const {
  115. SOPHUS_ENSURE(is_valid_, "must be valid");
  116. return type_;
  117. }
  118. T& operator*() {
  119. SOPHUS_ENSURE(is_valid_, "must be valid");
  120. return type_;
  121. }
  122. private:
  123. T type_;
  124. bool is_valid_;
  125. };
  126. template <bool B, class T = void>
  127. using enable_if_t = typename std::enable_if<B, T>::type;
  128. template <class G>
  129. struct IsUniformRandomBitGenerator {
  130. static const bool value = std::is_unsigned<typename G::result_type>::value &&
  131. std::is_unsigned<decltype(G::min())>::value &&
  132. std::is_unsigned<decltype(G::max())>::value;
  133. };
  134. } // namespace Sophus
  135. #endif // SOPHUS_COMMON_HPP