fmt中几个技法

发布时间:2024年01月12日

最简状态机实现


struct {
  state current_state = state::start;
  FMT_CONSTEXPR void operator()(state s, bool valid = true) {
    if (current_state >= s || !valid)
      throw_format_error("invalid format specifier");
    current_state = s;
  }
} enter_state;

2336:       enter_state(state::align);
2344:       enter_state(state::sign, in(arg_type, sint_set | float_set));
2360:       enter_state(state::hash, is_arithmetic_type(arg_type));
2365:       enter_state(state::zero);
2387:       enter_state(state::width);
2392:       enter_state(state::precision,
2399:       enter_state(state::locale, is_arithmetic_type(arg_type));
2457:       enter_state(state::align, align != align::none);

函数内声明类,并处理业务

  struct writer {
    FMT_CONSTEXPR void operator()(const Char* from, const Char* to) {
      if (from == to) return;
      for (;;) {
        const Char* p = nullptr;
        if (!find<IS_CONSTEXPR>(from, to, Char('}'), p))
          return handler_.on_text(from, to);
        ++p;
        if (p == to || *p != '}')
          return handler_.on_error("unmatched '}' in format string");
        handler_.on_text(from, p);
        from = p + 1;
      }
    }
    Handler& handler_;
  } write = {handler};

  while (begin != end) {
    // Doing two passes with memchr (one for '{' and another for '}') is up to
    // 2.5x faster than the naive one-pass implementation on big format strings.
    const Char* p = begin;
    if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, Char('{'), p))
      return write(begin, end);
    write(begin, p);
    begin = parse_replacement_field(p, end, handler);
  }

搜索字节

std::memchr 是 C++ 标准库中的一个函数,它用于在一段内存中搜索指定的字节值。

函数签名如下:

void* memchr(const void* ptr, int value, std::size_t num);

参数说明:

  • ptr:指向要搜索的内存块的起始地址。
  • value:要搜索的字节值,作为整数表示。
  • num:要搜索的字节数。

函数功能:

  • std::memchr 在给定的 ptr 指向的内存块中搜索 value 所表示的字节值。
  • 它会扫描 num 个字节,直到找到第一个匹配的字节值或扫描完整个内存块。
  • 如果找到匹配的字节值,它将返回指向该字节的指针。
  • 如果没有找到匹配的字节值,它将返回 nullptr

std::memchr 是一个 C 风格的函数,可以用于处理任意类型的内存块,而不仅限于字符数据。它在很多情况下很有用,比如在处理二进制数据、搜索特定字节模式等场景。

需要注意的是,std::memchr 函数返回的指针类型是 void*,这意味着需要将其转换为适当的类型才能访问所找到的字节。在 C++ 中,可以通过使用 reinterpret_cast 或将其转换为其他类型的指针,以便进行进一步的操作。

以下是一个示例,展示了如何使用 std::memchr 函数在内存块中搜索特定的字节值:

#include <iostream>
#include <cstring>

int main() {
    const char* str = "Hello, World!";
    std::size_t size = std::strlen(str);

    char target = 'W';
    void* result = std::memchr(str, target, size);

    if (result != nullptr) {
        std::ptrdiff_t position = static_cast<char*>(result) - str;
        std::cout << "Found at position: " << position << std::endl;
    } else {
        std::cout << "Not found!" << std::endl;
    }

    return 0;
}

在上述示例中,我们使用 std::memchr 函数在字符串 str 中搜索字节值 'W'。如果找到匹配的字节,我们计算其相对于起始地址 str 的位置,并输出结果。如果没有找到匹配的字节,我们输出 “Not found!”。

模板别名

template <typename T, typename Context>
using has_formatter =
std::is_constructible<typename Context::template formatter_type>;

这段代码使用了模板别名(template alias)和模板元编程中的 std::is_constructible 类型特性来定义了一个模板元函数 has_formatter

has_formatter 是一个模板元函数,它接受两个模板参数 TContext。该模板元函数使用 typename Context::template formatter_type<T> 来访问 Context 类型中的嵌套类型 formatter_type<T>

然后,使用 std::is_constructible 类型特性来判断是否可以通过调用 formatter_type<T> 的构造函数来构造一个对象。std::is_constructible 是一个类型特性,用于检查给定的类型是否可以通过特定的参数列表进行构造。

通过将 has_formatter 定义为一个模板别名(using),可以使用 has_formatter<T, Context>::value 来获取类型特性的值,该值表示是否可以构造 formatter_type<T> 对象。

这种技术通常用于编译时的条件编程,通过在模板实例化期间进行类型检查和分支选择,从而根据类型特性实现不同的行为。

以下是一个使用示例:

#include <iostream>
#include <type_traits>

struct Context {
    template <typename T>
    struct formatter_type {
        formatter_type() {
            std::cout << "Constructing formatter for type T" << std::endl;
        }
    };
};

// 检查是否具有 formatter_type<T> 类型的构造函数
template <typename T, typename Context>
using has_formatter =
    std::is_constructible<typename Context::template formatter_type<T>>;

int main() {
    std::cout << std::boolalpha;
    std::cout << "has_formatter<int, Context>: "
              << has_formatter<int, Context>::value << std::endl;
    std::cout << "has_formatter<double, Context>: "
              << has_formatter<double, Context>::value << std::endl;

    return 0;
}

在上述示例中,Context 类定义了一个嵌套的模板类型 formatter_type。然后,使用 has_formatter 模板别名来检查是否可以构造 formatter_type<T> 对象。根据模板参数 T 的不同,我们可以看到不同的构造函数被调用。

文章来源:https://blog.csdn.net/qq_33882435/article/details/135549145
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。