abseil strings/strip 源码分析
Revision:
- lts_2022_06_23
- 273292d1cfc0a94a65082ee350509af1d113344d
absl/strings/strip.h
absl/strings/ascii.h
strip 系列函数有点类似其他语言/库中常见的 trim 系列函数,但是又不完全一致。
StripPrefix/StripSuffix
1 | // StripPrefix() |
strip 要求完全匹配,所以配合 StartsWith()/EndsWith()
和 string_view
的 remove_prefix()/remove_suffix()
让实现变得非常的 trivial。
ConsumePrefix/ConsumeSuffix
1 | inline bool ConsumePrefix(absl::string_view* str, absl::string_view expected) { |
这两个函数是修改入参版本的 strip,并且唯一的好处是可以直接通过返回值来判断是否进行了 strip。
实际上我个人觉得这两个函数有点多余:
- string_view 本身是一个非常轻巧的类型,直接通过返回值再复制并没有什么开销
- 而可以通过直接比较返回的 sv 的 size 来判断是否发生了 strip
不过说起来我过去的经历中并没有遇到需要感知是否 strip 的场景
Strip (ASCII) Whitespaces
对于需要把一个字符串左边/右边或者两边的空白符去掉的函数在 ascii.h
中,因为移除的是 ascii whitespaces…
1 | // Returns absl::string_view with whitespace stripped from the beginning of the |
1 | // Array of bitfields holding character information. Each bit value corresponds |
这部分代码都很简单,可以发现:
- 每款函数有两个重载,返回
string_view
的非修改版和接受std::string*
的原地修改版
Google C++ Style Guide 要求修改参数的类型要用T*
而不是T&
在这里占了重载的便宜… - 不管 strip 哪个方向,用的都是
std::find_if_not()
这个算法函数,区别在于迭代器类型和substr()/erase()
的处理 - ascii whitespace 利用的是函数
absl::ascii_isspace()
这个函数的是显示查表。absl 给 0 ~ 255 每个 ascii 值进行了属性bit编码,例如这里的属于 whitespace 一类在 bit(1 << 3)会被设置。 - 注意
StripAsciiWhitespace()
是先 strip trailing 的再 strip leading 的,这里是一个有意的优化