/// @file /// Common functionality. #ifndef SOPHUS_COMMON_HPP #define SOPHUS_COMMON_HPP #include #include #include #include #include #include #if !defined(SOPHUS_DISABLE_ENSURES) #include "formatstring.hpp" #endif //!defined(SOPHUS_DISABLE_ENSURES) // following boost's assert.hpp #undef SOPHUS_ENSURE // ENSURES are similar to ASSERTS, but they are always checked for (including in // release builds). At the moment there are no ASSERTS in Sophus which should // only be used for checks which are performance critical. #ifdef __GNUC__ #define SOPHUS_FUNCTION __PRETTY_FUNCTION__ #elif (_MSC_VER >= 1310) #define SOPHUS_FUNCTION __FUNCTION__ #else #define SOPHUS_FUNCTION "unknown" #endif // Make sure this compiles with older versions of Eigen which do not have // EIGEN_DEVICE_FUNC defined. #ifndef EIGEN_DEVICE_FUNC #define EIGEN_DEVICE_FUNC #endif // NVCC on windows has issues with defaulting the Map specialization constructors, so // special case that specific platform case. #if defined(_MSC_VER) && defined(__CUDACC__) #define SOPHUS_WINDOW_NVCC_FALLBACK #endif #define SOPHUS_FUNC EIGEN_DEVICE_FUNC #if defined(SOPHUS_DISABLE_ENSURES) #define SOPHUS_ENSURE(expr, ...) ((void)0) #elif defined(SOPHUS_ENABLE_ENSURE_HANDLER) namespace Sophus { void ensureFailed(char const* function, char const* file, int line, char const* description); } #define SOPHUS_ENSURE(expr, ...) \ ((expr) ? ((void)0) \ : ::Sophus::ensureFailed( \ SOPHUS_FUNCTION, __FILE__, __LINE__, \ Sophus::details::FormatString(__VA_ARGS__).c_str())) #else // LCOV_EXCL_START namespace Sophus { template SOPHUS_FUNC void defaultEnsure(char const* function, char const* file, int line, char const* description, Args&&... args) { std::printf("Sophus ensure failed in function '%s', file '%s', line %d.\n", function, file, line); #ifdef __CUDACC__ std::printf("%s", description); #else std::cout << details::FormatString(description, std::forward(args)...) << std::endl; std::abort(); #endif } } // namespace Sophus // LCOV_EXCL_STOP #define SOPHUS_ENSURE(expr, ...) \ ((expr) ? ((void)0) \ : Sophus::defaultEnsure(SOPHUS_FUNCTION, __FILE__, __LINE__, \ ##__VA_ARGS__)) #endif namespace Sophus { template struct Constants { SOPHUS_FUNC static Scalar epsilon() { return Scalar(1e-10); } SOPHUS_FUNC static Scalar epsilonSqrt() { using std::sqrt; return sqrt(epsilon()); } SOPHUS_FUNC static Scalar pi() { return Scalar(3.141592653589793238462643383279502884); } }; template <> struct Constants { SOPHUS_FUNC static float constexpr epsilon() { return static_cast(1e-5); } SOPHUS_FUNC static float epsilonSqrt() { return std::sqrt(epsilon()); } SOPHUS_FUNC static float constexpr pi() { return 3.141592653589793238462643383279502884f; } }; /// Nullopt type of lightweight optional class. struct nullopt_t { explicit constexpr nullopt_t() {} }; constexpr nullopt_t nullopt{}; /// Lightweight optional implementation which requires ``T`` to have a /// default constructor. /// /// TODO: Replace with std::optional once Sophus moves to c++17. /// template class optional { public: optional() : is_valid_(false) {} optional(nullopt_t) : is_valid_(false) {} optional(T const& type) : type_(type), is_valid_(true) {} explicit operator bool() const { return is_valid_; } T const* operator->() const { SOPHUS_ENSURE(is_valid_, "must be valid"); return &type_; } T* operator->() { SOPHUS_ENSURE(is_valid_, "must be valid"); return &type_; } T const& operator*() const { SOPHUS_ENSURE(is_valid_, "must be valid"); return type_; } T& operator*() { SOPHUS_ENSURE(is_valid_, "must be valid"); return type_; } private: T type_; bool is_valid_; }; template using enable_if_t = typename std::enable_if::type; template struct IsUniformRandomBitGenerator { static const bool value = std::is_unsigned::value && std::is_unsigned::value && std::is_unsigned::value; }; } // namespace Sophus #endif // SOPHUS_COMMON_HPP