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

ops/2024/12/19 4:46:25/

这段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命名空间

http://www.ppmy.cn/ops/143080.html

相关文章

Python爬虫获取商品销量详情

在这个数据驱动的时代&#xff0c;获取商品销量详情已经不再是简单的点击和浏览。我们需要的是速度、效率&#xff0c;还有一点点的...偷偷摸摸。没错&#xff0c;今天我们要聊的是如何使用Python爬虫来“偷窥”商品销量详情。别担心&#xff0c;我们保证一切都是合法合规的&am…

revit转gltf,revit转3dtiles,如何将Revit模型转为3DTiles格式并在Cesiumjs中高效可视化

Revit模型导出gltf、glb与3dtiles有多种方式&#xff0c;但一般的商业工具收费普遍较高&#xff1a;Cesiumlab导出3dTile格式数据&#xff0c;Cesiumlab暂时可试用3天&#xff0c;会员版收费每年800&#xff1b;BimAngleEngine导出3dTile格式数据BimAngleEngine暂时可试用30天&…

CTFHUB靶场关于SSRF保姆级攻略

一.内网访问 输入127.0.0.1/flag.php 二.伪协议读取文件 输入?urlfile:///var/www/html/flag.php 右键页面查看源代码 三.端口扫描 尝试一下index.php&#xff0c;没有显示&#xff0c;说明有这个文件 上方题中提示我们端口在8000-9000中我们用burp suite抓包&#xff0c;开启…

Mysql笔记

windows安装记录Windows中Mysql安装-CSDN博客 用到的库 通过网盘分享的文件&#xff1a;atguigudb.sql 链接: https://pan.baidu.com/s/1YfC20c2vK9odn-XRJJwUJw 提取码: utk7 --来自百度网盘超级会员v5的分享 Mysql4中表关联关系 1.1对1,比较少用,因为完全可以一张表,当有…

pytest -s执行的路径

pytest -s执行的路径&#xff1a; 直接写pytest -s&#xff0c;表示从当前路径下开始执行全部.py的文件。 执行具体指定文件&#xff1a;pytest -s .\testXdist\test_dandu.py 下面这样执行pytest -s 会报找不到文件或没权限访问&#xff0c; 必须要加上具体文件路径pytest -s…

鸿蒙Next状态管理最佳实践

在鸿蒙Next应用开发中&#xff0c;合理的状态管理是确保应用性能和响应性的关键。以下是基于最佳实践的详细阐述&#xff0c;每个实践都包含反例分析和正例改进&#xff0c;并提供了相应的代码示例。 一、使用ObjectLink代替Prop减少不必要的深拷贝 &#xff08;一&#xff0…

jvm 常用命令

jmap -dump:formatb,file 将堆内存进行文件导出&#xff0c;但是jvm为了保留数据一致性&#xff0c;可能会卡顿&#xff0c;并且导出前会进行一次fullGC&#xff0c; 实验&#xff1a;6G的最大堆应用 导出30s左右 查看gc 日志 jstat -gc pid 查看堆存活对象 jmap -histo:…

MATLAB 数据/fig图 自动保存并自动 添加时间戳后后缀

文章目录 数据保存fig图保存 数据保存 示例代码如下 % 获取当前日期和时间 currentDateTime datetime(now, Format, yyyyMMdd); dateTimeStr datestr(currentDateTime); % 替换破折号和冒号为下划线 dateTimeStr strrep(dateTimeStr, {:}, _); dateTimeStr cell2mat(date…