【C++】sophus : common.hpp 丰富的字符串格式化、日志记录和数学常量处理功能 (七)...

这段C++代码实现了一个名为Sophus的库,提供了各种实用功能。主要内容包括:

  1. 宏定义和条件编译

  • 使用条件编译定义了一些宏,用于在不同编译器下处理函数名称等。

  • 定义了用于格式化字符串和打印日志的宏。

  • 定义了用于运行时断言的宏,支持自定义处理程序或默认处理模式。

命名空间

  • 代码定义了两个命名空间:Sophus 和 details,用于组织和封装功能。

模板类和函数

  • IsStreamable

    类模板:用于检测类型T是否支持流输出操作。

  • ArgToStream

    类模板:将参数输出到字符串流。

  • formatStream

    函数模板:用于格式化字符串,并支持可变参数。

  • formatString

    函数模板:封装了formatStream,返回格式化后的字符串。

常量结构体

  • Constants

    模板结构体:定义了一些数学常量和函数,如epsilon和pi。对float类型进行了特化处理。

辅助结构体

  • IsUniformRandomBitGenerator

    结构体模板:用于检测类型G是否为均匀随机比特生成器。

通过这些实现,Sophus库提供了丰富的字符串格式化、日志记录和数学常量处理功能。

/// @file  // 文件注释:这是文件头部注释,表明该文件的功能。/// Common functionality.  // 文件注释:这段代码实现了常用功能。#pragma once  // 防止文件被多次包含#include <cmath>  // 引入用于数学计算的标准库#include <cstdio>  // 引入标准输入输出库#include <cstdlib>  // 引入标准库(包括内存管理、随机数生成等)#include <optional>  // 引入可选类型库#include <random>  // 引入随机数库#include <type_traits>  // 引入类型特性库#include <Eigen/Core>  // 引入Eigen库的核心模块#ifdef __GNUC__  // 检查是否使用GNU编译器#define SOPHUS_FUNCTION __PRETTY_FUNCTION__  // 使用__PRETTY_FUNCTION__定义函数名#elif (_MSC_VER >= 1310)  // 检查是否使用微软编译器且版本号大于等于1310#define SOPHUS_FUNCTION __FUNCTION__  // 使用__FUNCTION__定义函数名#else#define SOPHUS_FUNCTION "unknown"  // 否则定义函数名为“unknown”#endifnamespace Sophus {  // 定义Sophus命名空间namespace details {  // 定义details命名空间// Following: http://stackoverflow.com/a/22759544  // 注释:参考自StackOverflow的链接template <class T>  // 模板定义class IsStreamable {  // IsStreamable类,用于检测是否可流输出 private:  template <class TT>  static auto test(int)      -> decltype(std::declval<std::stringstream&>() << std::declval<TT>(),                  std::true_type());  // 使用SFINAE检测流输出操作是否有效  template <class>  static auto test(...) -> std::false_type;  // 默认情况为std::false_type public:  static bool const value = decltype(test<T>(0))::value;  // 根据检测结果确定value的值};template <class T>class ArgToStream {  // ArgToStream类,用于将参数输出到流 public:  static void impl(std::stringstream& stream, T&& arg) {    stream << std::forward<T>(arg);  // 将参数转发并输出到流  }};inline void formatStream(std::stringstream& stream, char const* text) {  stream << text;  // 将文本直接输出到流  return;}// Following: http://en.cppreference.com/w/cpp/language/parameter_pack  // 注释:参考cppreference上的链接template <class T, typename... Args>void formatStream(std::stringstream& stream, char const* text, T&& arg,                  Args&&... args) {  static_assert(IsStreamable<T>::value,                "One of the args has no ostream overload!");  // 静态断言,确保参数可流输出  for (; *text != '\0'; ++text) {  // 遍历文本字符    if (*text == '{' && *(text + 1) == '}') {  // 检测占位符{}      ArgToStream<T&&>::impl(stream, std::forward<T>(arg));  // 输出参数到流      formatStream(stream, text + 2, std::forward<Args>(args)...);  // 递归调用处理剩余参数      return;    }    stream << *text;  // 输出文本字符到流  }  stream << "\nFormat-Warning: There are " << sizeof...(Args) + 1         << " args unused.";  // 警告:未使用的参数  return;}template <class... Args>std::string formatString(char const* text, Args&&... args) {  std::stringstream stream;  // 创建字符串流  formatStream(stream, text, std::forward<Args>(args)...);  // 格式化文本并输出到流  return stream.str();  // 返回格式化后的字符串}inline std::string formatString() { return std::string(); }  // 空参数重载,返回空字符串}  // namespace details}  // namespace Sophus#define SOPHUS_DETAILS_FMT_STR(description, ...) \  ::Sophus::details::formatString(description, ##__VA_ARGS__)  // 定义宏,用于格式化字符串#define SOPHUS_DETAILS_FMT_PRINT(description, ...) \  std::printf(                                     \      "%s\n",                                      \      ::Sophus::details::formatString(description, ##__VA_ARGS__).c_str())  // 定义宏,用于格式化并输出字符串#define SOPHUS_DETAILS_FMT_LOG(description, ...) \  std::printf(                                   \      "[%s:%d] %s\n", __FILE__, __LINE__,        \      ::Sophus::details::formatString(description, ##__VA_ARGS__).c_str())  // 定义宏,用于格式化并输出带文件和行号的日志信息// FARM_ENSURE (aka runtime asserts). There are two modes:// 1. SOPHUS_ENABLE_ENSURE_HANDLER: custom ensure handle  // 模式1:自定义ENSURE处理程序// 2. default mode: log on ENSURE message and panic  // 模式2:默认模式,在ENSURE消息上记录日志并中止//#if defined(SOPHUS_ENABLE_ENSURE_HANDLER)// 1. custom ensure handle, e.g., throw an exception//// One needs to link against a custom ensure handler.namespace Sophus {void ensureFailed(char const* function, char const* file, int line,                  char const* description);  // 声明ensureFailed函数}#define SOPHUS_ENSURE_FAILED(description, ...) \  ::Sophus::ensureFailed(                      \      SOPHUS_FUNCTION, __FILE__, __LINE__,     \      ::Sophus::details::formatString(description, ##__VA_ARGS__).c_str())  // 定义宏,调用自定义的ENSURE失败处理程序#else  // 1. custom ensure handle// 2. default mode: log on ENSURE message and panic#define SOPHUS_ENSURE_FAILED(description, ...)            \  do {                                                    \    SOPHUS_DETAILS_FMT_LOG("SOPHUS_ENSURE failed:");      \    SOPHUS_DETAILS_FMT_PRINT(description, ##__VA_ARGS__); \    std::abort();                                         \  } while (false)  // 定义宏,在ENSURE失败时记录日志并中止程序#endif  // 2. default mode#ifdef __CUDACC__  // 检查是否使用CUDA编译器#define SOPHUS_ENSURE(expr, description, ...)                                  \  do {                                                                         \    if (!(expr)) {                                                             \      std::printf("Sophus ensure failed in file '%s', line %d.\n", __FILE__,   \                  __LINE__);                                                   \      std::printf("%s", description);                                          \      /* there is no std::abort in cuda kernels, hence we just print the error \       * message here*/                                                        \    }                                                                          \  } while (false)  // 定义宏,在CUDA中处理ENSURE失败情况,打印错误信息#else#define SOPHUS_ENSURE(expr, description, ...)           \  do {                                                  \    if (!(expr)) {                                      \      SOPHUS_ENSURE_FAILED(description, ##__VA_ARGS__); \    }                                                   \  } while (false)  // 定义宏,在普通情况下处理ENSURE失败情况#endif// Make sure this compiles with older versions of Eigen which do not have// EIGEN_DEVICE_FUNC defined.  // 注释:确保与旧版本的Eigen库兼容#ifndef EIGEN_DEVICE_FUNC#define EIGEN_DEVICE_FUNC  // 定义EIGEN_DEVICE_FUNC宏#endif// NVCC on windows has issues with defaulting the Map specialization// constructors, so special case that specific platform case.  // 注释:在Windows上的NVCC存在默认Map特化构造函数的问题#if defined(_MSC_VER) && defined(__CUDACC__)#define SOPHUS_WINDOW_NVCC_FALLBACK  // 定义特殊情况下的回退宏#endif#define SOPHUS_FUNC EIGEN_DEVICE_FUNC  // 定义SOPHUS_FUNC为EIGEN_DEVICE_FUNCnamespace Sophus {template <class Scalar>struct Constants {  // 常量结构体模板  SOPHUS_FUNC static Scalar epsilon() { return Scalar(1e-10); }  // epsilon常量  SOPHUS_FUNC static Scalar epsilonPlus() {    return epsilon() * (Scalar(1.) + epsilon());  // epsilonPlus常量  }  SOPHUS_FUNC static Scalar epsilonSqrt() {    using std::sqrt;    return sqrt(epsilon());  // epsilonSqrt常量  }  SOPHUS_FUNC static Scalar pi() {    return Scalar(3.141592653589793238462643383279502884);  // pi常量  }};template <>struct Constants<float> {  // 对float类型特化常量结构  SOPHUS_FUNC static float constexpr epsilon() {    return static_cast<float>(1e-5);  // epsilon常量  }  SOPHUS_FUNC static float epsilonPlus() {    return epsilon() * (1.f + epsilon());  // epsilonPlus常量  }  SOPHUS_FUNC static float epsilonSqrt() { return std::sqrt(epsilon()); }  // epsilonSqrt常量  SOPHUS_FUNC static float constexpr pi() {    return 3.141592653589793238462643383279502884f;  // pi常量  }};template <class G>struct IsUniformRandomBitGenerator {  // 检查G是否为均匀随机比特生成器  static const bool value = std::is_unsigned<typename G::result_type>::value &&                            std::is_unsigned<decltype(G::min())>::value &&                            std::is_unsigned<decltype(G::max())>::value;  // 确保G的结果类型和最小值、最大值类型都是无符号类型};}  // namespace Sophus  // 结束Sophus命名空间
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值