sgi_stl源码学习,官方文档3.2.3String package字符串封装,未完待续
https://www.boost.org/sgi/stl/character_traits.html
char_traits<char>
char_traits<wchar_t>
traits翻译为特征、特性类,一般是指某种类型的特性类应该提供的一组接口、类型定义。
web页面描述了一些接口要求。感觉没有什么特别的。直接看代码吧
char_traits.h文件中,以下两个头文件不在sgi stl范围内,属于c标准库的范围
在vs中创建一个空工程,#include “…/stl/char_traits.h” 后,就可以在vs中跳转过去,看到的是windows的实现。
#include <string.h>
#include <wchar.h>
以上两个头文件定义了strcpy_s、_memccpy之类的基础C函数,说明STL中的一些函数间接使用了C函数
__char_traits_base 定义了char类型的比较、赋值、拷贝、查找、求长度等基础函数
template <class _CharT, class _IntT> class __char_traits_base {
public:typedef _CharT char_type;typedef _IntT int_type;
#ifdef __STL_USE_NEW_IOSTREAMS //这个没用上,暂时可以不管typedef streamoff off_type;typedef streampos pos_type;typedef mbstate_t state_type;
#endif /* __STL_USE_NEW_IOSTREAMS */static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; }static bool eq(const _CharT& __c1, const _CharT& __c2) { return __c1 == __c2; }static bool lt(const _CharT& __c1, const _CharT& __c2) { return __c1 < __c2; }static int compare(const _CharT* __s1, const _CharT* __s2, size_t __n) {for (size_t __i = 0; __i < __n; ++__i)if (!eq(__s1[__i], __s2[__i]))return __s1[__i] < __s2[__i] ? -1 : 1;return 0;}static size_t length(const _CharT* __s) {const _CharT __nullchar = _CharT();//默认构造函数必须置0(概念上可以不为0,定义无歧义空值即可)size_t __i;for (__i = 0; !eq(__s[__i], __nullchar); ++__i) {}return __i;}static const _CharT* find(const _CharT* __s, size_t __n, const _CharT& __c) {//此处传值或许更好,编译器优化后可能无差别for ( ; __n > 0 ; ++__s, --__n)if (eq(*__s, __c))return __s;return 0;}static _CharT* move(_CharT* __s1, const _CharT* __s2, size_t __n) {memmove(__s1, __s2, __n * sizeof(_CharT));//__n 是__s1 __s2的sizereturn __s1;} static _CharT* copy(_CharT* __s1, const _CharT* __s2, size_t __n) {memcpy(__s1, __s2, __n * sizeof(_CharT));return __s1;} static _CharT* assign(_CharT* __s, size_t __n, _CharT __c) {for (size_t __i = 0; __i < __n; ++__i)__s[__i] = __c;return __s;}static int_type not_eof(const int_type& __c) {return !eq_int_type(__c, eof()) ? __c : 0;}static char_type to_char_type(const int_type& __c) {return static_cast<char_type>(__c);}static int_type to_int_type(const char_type& __c) {return static_cast<int_type>(__c);}static bool eq_int_type(const int_type& __c1, const int_type& __c2) {return __c1 == __c2;}static int_type eof() {return static_cast<int_type>(-1);//-1为无效值,大文件实际应该为long long -1}
};
POD表示"Plain Old Data"(简单老数据),衍生概念是指可简单拷贝内存复制对象的结构体,含有指针的就不适合简单拷贝。
char_traits不适用与非POD类型。
template <class _CharT> class char_traits //特化版本,与后面的char_traits<char>特化不一样,此处实际还没确定类型: public __char_traits_base<_CharT, _CharT>
{};
__STL_TEMPLATE_NULL class char_traits<char> //char的特化版本,重载了几个函数,典型的是调用C函数的几个: public __char_traits_base<char, int>{
public:static char_type to_char_type(const int_type& __c) {return static_cast<char_type>(static_cast<unsigned char>(__c));}static int_type to_int_type(const char_type& __c) {return static_cast<unsigned char>(__c);}static int compare(const char* __s1, const char* __s2, size_t __n) { return memcmp(__s1, __s2, __n); } static size_t length(const char* __s) { return strlen(__s); }static void assign(char& __c1, const char& __c2) { __c1 = __c2; }static char* assign(char* __s, size_t __n, char __c){ memset(__s, __c, __n); return __s; }
};
wchar_t版本特化,wint_t实际是unsigned short
__STL_TEMPLATE_NULL class char_traits<wchar_t>: public __char_traits_base<wchar_t, wint_t>{};
basic_string在string中定义,web说明中没有很复杂,基本就是template <class _CharT, class _Traits, class _Alloc>三个的组合
实际代码如下
#pragma set woff 1174 //这种用法比较少见,据说是ms vs才支持的关闭告警语法
#pragma set woff 1375
// A helper class to use a char_traits as a function object.将char_traits用作函数对象
template <class _Traits>
struct _Not_within_traits //是否在内部找得到: public unary_function<typename _Traits::char_type, bool>{typedef const typename _Traits::char_type* _Pointer;const _Pointer _M_first;const _Pointer _M_last;_Not_within_traits(_Pointer __f, _Pointer __l) : _M_first(__f), _M_last(__l) {}bool operator()(const typename _Traits::char_type& __x) const {//找到了就在string内有__x,否则_Not_within_traitsreturn find_if(_M_first, _M_last, bind1st(_Eq_traits<_Traits>(), __x)) == _M_last;}//bind1st存储了op和1st参数,变成了一个一元仿函数对象,再去操作序列中的元素。
};
template <class _InputIter, class _Predicate>
inline _InputIter find_if(_InputIter __first, _InputIter __last,_Predicate __pred,input_iterator_tag){while (__first != __last && !__pred(*__first))//遇到相等就停,不等于就循环下去++__first;return __first;
}
template <class _Traits>
struct _Eq_traits: public binary_function<typename _Traits::char_type,typename _Traits::char_type,bool>{bool operator()(const typename _Traits::char_type& __x,const typename _Traits::char_type& __y) const{ return _Traits::eq(__x, __y); }//实际就是判断是否相等。封装是为了编译期检查?
};
template <class _Arg1, class _Arg2, class _Result>
struct binary_function { //二元函数typedef _Arg1 first_argument_type;typedef _Arg2 second_argument_type;typedef _Result result_type;
};
template <class _Operation, class _Tp>//_Operation == _Eq_traits<_Traits>()
inline binder1st<_Operation> //返回值是一个函数对象,编译后可能是函数指针,或者内联
bind1st(const _Operation& __fn, const _Tp& __x) {typedef typename _Operation::first_argument_type _Arg1_type;return binder1st<_Operation>(__fn, _Arg1_type(__x));//说明__x是__fn的第一个参数
}
template <class _Operation>
class binder1st : public unary_function<typename _Operation::second_argument_type,typename _Operation::result_type> {
protected:_Operation op;//操作的存储,使得当前类替代了被绑定的操作(操作的递归替换)typename _Operation::first_argument_type value;//降元的本质就是将部分存到仿函数内部。
public:binder1st(const _Operation& __x,const typename _Operation::first_argument_type& __y): op(__x), value(__y) {}//bind1st(_Eq_traits<_Traits>(), __x)把第一个参数绑定,实际是存储起来typename _Operation::result_typeoperator()(const typename _Operation::second_argument_type& __x) const {//与第二个参数进行操作(eg:判断是否相等)return op(value, __x); }
};
前面这段代码比较难看懂的是以下这句
return find_if(_M_first, _M_last, bind1st(_Eq_traits<_Traits>(), __x)) == _M_last;
//bind1st存储了op和1st参数,变成了一个一元仿函数对象,再去操作序列中的元素。
//find_if返回值是序列的指针,指针指向的对象满足bind1st绑定后的一元仿函数(返回值true)
find_if这种函数只接受一元仿函数,bind1st实现了操作降元(二元操作降到一元操作),类似降元都可以模仿着写,本质就是将第一个元存到仿函数内部。
// General base class.
template <class _Tp, class _Alloc, bool _S_instanceless>//instanceless _Alloc是否无实例
class _String_alloc_base { //提供内存管理
public:typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;//new delete仿函数类型定义allocator_type get_allocator() const { return _M_data_allocator; }//获得内部的new delete仿函数对象_String_alloc_base(const allocator_type& __a): _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
protected:_Tp* _M_allocate(size_t __n){ return _M_data_allocator.allocate(__n); }//newvoid _M_deallocate(_Tp* __p, size_t __n) {if (__p)_M_data_allocator.deallocate(__p, __n); //delete}
protected:allocator_type _M_data_allocator; //仿函数对象(默认false,无实例的false,就是此处有_Alloc示例)此处占内存_Tp* _M_start;//起始指针_Tp* _M_finish;//已用范围的尾部指针_Tp* _M_end_of_storage; //标识最大容量指针
};
_String_alloc_base 的特化版本
// Specialization for instanceless allocators.
template <class _Tp, class _Alloc>
class _String_alloc_base<_Tp,_Alloc,true> {
public:typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;//此处无实例化,就是定义allocator_typeallocator_type get_allocator() const { return allocator_type(); }_String_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
protected:typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Alloc_type;_Tp* _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }void _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n); }
protected:_Tp* _M_start;_Tp* _M_finish;_Tp* _M_end_of_storage;
};
template <class _Tp, class _Alloc>
class _String_base : public _String_alloc_base<_Tp, _Alloc,_Alloc_traits<_Tp, _Alloc>::_S_instanceless>{
protected:typedef _String_alloc_base<_Tp, _Alloc,_Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base;typedef typename _Base::allocator_type allocator_type;void _M_allocate_block(size_t __n) { if (__n <= max_size()) {_M_start = _M_allocate(__n);_M_finish = _M_start;_M_end_of_storage = _M_start + __n;}else_M_throw_length_error();}void _M_deallocate_block() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); } size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; }_String_base(const allocator_type& __a) : _Base(__a) { } _String_base(const allocator_type& __a, size_t __n) : _Base(__a){ _M_allocate_block(__n); }~_String_base() { _M_deallocate_block(); }void _M_throw_length_error() const;//两种异常之一。类外定义,防止内联?void _M_throw_out_of_range() const;//两种异常之一
};
// Helper functions for exception handling.
template <class _Tp, class _Alloc>
void _String_base<_Tp,_Alloc>::_M_throw_length_error() const {__STL_THROW(length_error("basic_string"));//两种异常之一
}
template <class _Tp, class _Alloc>
void _String_base<_Tp, _Alloc>::_M_throw_out_of_range() const {__STL_THROW(out_of_range("basic_string"));//两种异常之一
}
未完待续
相关文章:

sgi_stl源码学习,官方文档3.2.3String package字符串封装,未完待续
https://www.boost.org/sgi/stl/character_traits.html char_traits<char> char_traits<wchar_t>traits翻译为特征、特性类,一般是指某种类型的特性类应该提供的一组接口、类型定义。 web页面描述了一些接口要求。感觉没有什么特别的。直接看代码吧 c…...

从JavaScript到Java(一):基础知识
Hello World Java和JavaScript虽然有不同的特点,但在一些概念和知识点上是相似的。本文从JavaScript开发者的角度出发,帮助你理解Java基础知识(反过来也行)。 // 解释型 console.log("Hello, World!");// 编译型 pub…...

Android编舞者类Choreographer小结
Android编舞者类Choreographer小结 作用 编舞者类的作用主要是控制绘制节奏,用于发起一次vsync垂直同步信号的监听,当垂直同步信号来的时候会回调注册的Runnable或者FramCallback Choreographer对象获取 Choreographer对象是通过它的getInstance方法…...

大专升本科难度大吗 需要考哪些科目
大专学历可以通过自考和成考提升学历到本科,自考的考试科目有12-16门左右,考试内容不难,但是考试周期长,需要考生通过所有课程才能申请毕业。成考专升本考试科目有政治,外语和专业课,考试内容简单ÿ…...

考研复试-英语问答+解答
每个问题2~3min 一、 1.考官问问题,没听明白 I’m sorry, I didn’t hear that clearly. May I ask you to repeat it, please? Sorry, I have no clear idea about this question for now, but I will think about it later. And if possible, I want to discuss …...

python 文件相关的操作 常用函数(读文件、写文件、文件的追加内容、修改文件内容、复制文件、按行读取文件、with open) json文件的读取
常用函数:open(打开文件),read(读文件到程序中),write(写程序中的变量到文件),close(关闭文件) 示例1:读文件(…...

python 系列 06 -生成及解析二维码
0 说明 二维码不止一种,本文介绍最常见的QR二维码。由于不能发二维码截图,所以所有的执行结果都隐去了。完整版本可以移步到此查看:https://vblogs.cn/momo1938/article?id0407576070659864 1 安装包 python 可以使用qrcode来生成二维码&…...

2023第二届中国绿色钢铁国际峰会
会议背景 钢铁是当今世界上最常用的金属,普遍应用于世界各国基础设施建设与机械、汽车、飞机、船舶、家电等产品的生产制造中。但是,随着各国政府与行业净零排放目标的确立,钢铁行业的减排降碳也成为了关注焦点。据世界钢铁协会称,…...

java 高考志愿填报系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目
一、源码特点 java 高考志愿填报系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0…...

机器学习 vs 深度学习:了解两者的异同
在人工智能领域中,机器学习和深度学习是两个重要的概念。尽管它们都可以用于处理复杂的数据和任务,但它们在其基本原理、算法和应用方面有着显著的不同之处。在本文中,我们将详细介绍机器学习和深度学习的定义、原理、算法和应用,…...

流行的 DAW编曲软件FL Studio 21 有什么新功能?
FL Studio 21 对流行的 DAW 和音乐制作软件进行了多项更新。最重要的变化包括:更快、更精确的音频包络和带有自动交叉推子的增益控制;一个能够标记、制作自定义颜色的标签和访问在线内容的新浏览器,以及一个带有可视化和擦除功能的内嵌音频播…...

【Java】抽象类和接口
抽象类和接口抽象类抽象类的概念抽象类语法抽象类的注意事项抽象类的作用接口接口的概念语法规则接口使用接口注意实现多个接口接口间的继承接口使用实例给对象数组排序Clonable 接口和深拷贝浅拷贝深拷贝抽象类和接口的区别抽象类 抽象类的概念 在面向对象的概念中ÿ…...

Lora:Low-Rank Adapation of Large Language models
Lora:Low-Rank Adapation of Large Language modelsIntroductionMethodExperiment代码Introduction 这篇论文最初与21.06上传与arXiv,作者指出在当时,NLP的一个重要范式是先训练一个通用领域的模型然后在通过微调适应不同的领域与数据&#…...

洛谷-P8466 [Aya Round 1 A] 幻想乡扑克游戏
题目:P8466 [Aya Round 1 A] 幻想乡扑克游戏 题目描述: 题目描述 斗地主是一种使用 �A 到 �K 加上大小王的共 5454 张扑克牌来进行的游戏,其中大小王各一张,其它数码牌各四张。在斗地主中,牌的…...

HBase性能优化方法总结
1. 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个region写数据,直到这个region足够大了才进行切分。一种可以加快批量写入速度的方…...

Linux基础内容(16)—— 文件系统
Linux基础内容(15)—— 缓冲区https://blog.csdn.net/m0_63488627/article/details/129824563?spm1001.2014.3001.5501 目录 1.基础知识 2.磁盘的存储原理 1.物理结构 2.存储结构 3.逻辑结构 1.基础知识 之前介绍的全是进程打开的文件是如何执行…...

Vue自定义事件
自定义事件 通以上代码不难发现,数据项在Vue的实例中, 但删除操作要在组件中完成, 那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了, Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题…...

Java SE 基础 (6) 第一个Java程序
开发环境已经搭建完毕,可以开发我们第一个Java程序了。 Java程序开发三步骤:编写、编译、运行。 编写Java源程序 public class HelloWord {public static void main(String[] args) {System.out.println("HelloWord!");} } 第一个 HelloWo…...

P1004 [NOIP2000 提高组] 方格取数
题目描述 设有 ��NN 的方格图 (�≤9)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00。如下图所示(见样例): 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0…...

Leetcode.1024 视频拼接
题目链接 Leetcode.1024 视频拼接 Rating : 1746 题目描述 你将会获得一系列视频片段,这些片段来自于一项持续时长为 time秒的体育赛事。这些片段可能有所重叠,也可能长度不一。 使用数组 clips描述所有的视频片段,其中 clips[i…...

20个华为路由器常用的Python脚本,网工写自动化脚本时候可以参考!
你好,这里是网络技术联盟站。 昨天给大家介绍了10个华为交换机的Python脚本: 10个华为华为交换机常用的Python脚本,网络工程师收藏! 大家反响不错,后期我会陆续出一下思科、H3C、锐捷等厂商的脚本,前期会…...

【kubernetes云原生】k8s资源管理命令与Namespace使用详解
目录 一、前言 二、k8s概述 三、k8s常用操作管理命令 3.1 kubectl 命令用法 3.2 常用控制台管理命令演示 3.2.1 获取全部节点信息 3.2.2 获取当前集群下全部pod 3.2.3 查看某个pod信息 3.2.4 获取当前集群下的所有namespace信息 3.2.5 查看当前集群下已创建的资源 3…...

String源码深度刨析
前言 我们将从源码角度深度分析特点,来提升对他们的了解以及设计。 String、StringBuilder、StringBuffer的常见面试题及四大区别可以参考:String、StringBuilder、StringBuffer的四大区别解析 String public final class Stringimplements java.io.Se…...

FreeRTOS - 消息队列
一.消息队列的概念及应用消息队列(queue):可以在任务与任务间、中断和任务间传递消息,实现任务接收来自其他任务或中断的不固定的消息1.1任务需求1、使用消息队列检测串口输入2、通过串口发送字符串openled1,openled2&…...

怎样正确做 Web 应用的压力测试?
环境 首先环境是非常重要的,需要尽可能跟生产环境靠近。 比方说,使用同样的nginx版本,php的话需要启用fpm,zend-optimizer等等,参数配置也最好跟生产环境保持一致。 当然,php的版本更加需要保持一致&#x…...

php mysql大学生求职招聘资源信息网zkfdzkf67a8
1.系统登录:系统登录是用户访问系统的路口,设计了系统登录界面,包括用户名、密码和验证码,然后对登录进来的用户判断身份信息,判断是管理员用户还是普通用户。 2.系统用户管理:不管是…...

2023上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书
2023上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书 A模块基础设施设置/安全加固(200分) 一、项目和任务描述: 假定你是某企业的网络安全工程师,对于企业的服务器系统,根据任务要求确保各服务正常运行&…...

Spring事务源码:创建代理类
参考文章: 《Spring事务源码解析之tx:annotation-driven标签解析》 《Spring 源码解析—事务执行》 参考资料: 《Spring AOP源码:开启注解读取》 《Spring AOP源码2:查找增强器》 《Spring AOP源码3:实现代理》 …...

java14 使用增强的模式匹配切换表达式
野旷天低树,江清月近人。——唐代杜甫《月夜忆舍弟》 使用增强的模式匹配切换表达式(Switch Expressions with Enhanced Pattern Matching) Java 14中引入的“Switch Expressions with Enhanced Pattern Matching”这个功能。 这个功能可以让我们在使用switch cas…...

python【正则表达式】
正则表达式 1.正则的作用 正则表达式式一种可以让复杂的字符串变得简单的工具。 写正则表达式的时候就是用正则符号来描述字符串规则。 2.正则语法 需要导入模块 from re import fullmatch, findall, search2.1.第一类:匹配类符号 1)普通字符—在…...