├── CMakeLists.txt ├── README.md ├── class ├── lesson10 │ ├── makefile │ ├── mmap_test.cpp │ ├── mmap_test2.cpp │ ├── mmap_test3.cpp │ └── mytest.txt ├── lesson11 │ ├── local_socket.cpp │ ├── local_socket_client.cpp │ ├── makefile │ ├── udp_client.cpp │ └── udp_server.cpp ├── lesson12 │ └── test.cpp ├── lesson4 │ ├── chrono_test.cpp │ ├── compute.cpp │ ├── fork_test.cpp │ ├── hello.cpp │ ├── makefile │ ├── multi-process.cpp │ ├── multi-thread.cpp │ └── world_test.go ├── lesson5 │ └── README.md ├── lesson6 │ ├── README.md │ ├── alarm_test.cpp │ ├── client.cpp │ ├── makefile │ ├── server.cpp │ ├── setitimer_test.cpp │ ├── setitimer_test2.cpp │ ├── time_heap.cpp │ └── time_wheel.cpp ├── lesson8 │ ├── basic_io.cpp │ ├── fifo_read.cpp │ ├── fifo_write.cpp │ ├── hello.txt │ ├── makefile │ ├── mmap.cpp │ ├── non_blocking.cpp │ └── pipe_test.cpp └── rust_learn │ ├── cf1760A.rs │ ├── rust_study.md │ ├── test_1.rs │ └── test_2.rs ├── config └── a.txt ├── docs ├── Linux.md ├── Linux高性能服务器编程 (游双 著) (z-lib.org).pdf └── helper.md ├── file └── minidb │ └── minidb.data ├── include ├── db.h ├── db_file.h ├── entry.h ├── gmock │ ├── gmock-actions.h │ ├── gmock-cardinalities.h │ ├── gmock-function-mocker.h │ ├── gmock-matchers.h │ ├── gmock-more-actions.h │ ├── gmock-more-matchers.h │ ├── gmock-nice-strict.h │ ├── gmock-spec-builders.h │ ├── gmock.h │ └── internal │ │ ├── custom │ │ ├── README.md │ │ ├── gmock-generated-actions.h │ │ ├── gmock-matchers.h │ │ └── gmock-port.h │ │ ├── gmock-internal-utils.h │ │ ├── gmock-port.h │ │ └── gmock-pp.h ├── gtest │ ├── gtest-assertion-result.h │ ├── gtest-death-test.h │ ├── gtest-matchers.h │ ├── gtest-message.h │ ├── gtest-param-test.h │ ├── gtest-printers.h │ ├── gtest-spi.h │ ├── gtest-test-part.h │ ├── gtest-typed-test.h │ ├── gtest.h │ ├── gtest_pred_impl.h │ ├── gtest_prod.h │ └── internal │ │ ├── custom │ │ ├── README.md │ │ ├── gtest-port.h │ │ ├── gtest-printers.h │ │ └── gtest.h │ │ ├── gtest-death-test-internal.h │ │ ├── gtest-filepath.h │ │ ├── gtest-internal.h │ │ ├── gtest-param-util.h │ │ ├── gtest-port-arch.h │ │ ├── gtest-port.h │ │ ├── gtest-string.h │ │ └── gtest-type-util.h ├── index │ └── skiplist.h └── utils.h ├── lib ├── libgmock.a ├── libgmock_main.a ├── libgtest.a └── libgtest_main.a └── src ├── db.cpp ├── db_file.cpp ├── entry.cpp ├── index └── skiplist.cpp └── main.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.21) 2 | project(server) 3 | # C++17编译标准 4 | set(CMAKE_CXX_STANDARD 17) 5 | set(ROOT_DIR ${CMAKE_SOURCE_DIR}) 6 | # 添加头文件 7 | include_directories(include) 8 | include_directories(include/index) 9 | # 指定外部引用文件的搜索路径 10 | link_directories(${ROOT_DIR}/lib) 11 | # 添加源文件 12 | aux_source_directory(${ROOT_DIR}/src DIR_SRCS) 13 | aux_source_directory(${ROOT_DIR}/src/index DIR_SRCS_INDEX) 14 | aux_source_directory(${ROOT_DIR}/src/gtest DIR_GTEST) 15 | aux_source_directory(${ROOT_DIR}/src/gmock DIR_GMOCK) 16 | 17 | # 需要编译的源文件 18 | add_executable(server ${DIR_GTEST} ${DIR_SRCS} ${DIR_GMOCK} ${DIR_SRCS_INDEX}) 19 | # 链接外部库 20 | target_link_libraries(server libgtest.a libgtest_main.a libgmock.a libgmock_main.a) 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## C/C++项目实战大纲 2 | 1. 工具准备 3 | - Git 代码管理 4 | - CMake 依赖管理(#1) 5 | - GCC/G++/Clang/Llvm 编译器 6 | - Makefile 编译规则(#4) 7 | - Clion/VSCode/Atom/Sublime 编辑器(#1) 8 | - MySQL/PostgreSQL/Oracle/Redis/ElasticSearch 数据库(#2) 9 | - Docker/K8s 部署编排(#2) 10 | - Google Test 单元测试(#3) 11 | - Gdb/Valgrind/Cppcheck 调试和检查工具 12 | - Prometheus/Grafana 监控 13 | - Postman 模拟HTTP客户端 14 | 2. 常用知识 15 | - C/C++11/23 16 | - STL标准库 17 | - 操作系统 18 | - 进程管理 19 | - 多进程(#4) 20 | - 多线程(#5) 21 | - 内存管理 22 | - 文件系统 23 | - Linux内核与网络编程 24 | - Linux常用命令 25 | - IPC进程通信(#8/#9/#10) 26 | - 并发同步 27 | - 多路IO复用 28 | - 系统调用 29 | - 调度策略 30 | - 中断处理 31 | - 内核数据结构 32 | 3. C++Web服务器 33 | 1. socket(#6) 34 | 2. epoll(#6) 35 | 3. 线程池 36 | 4. 定时器(#6) 37 | 4. 开源项目 38 | - [TinyWebServer](https://github.com/qinguoyi/TinyWebServer)(C++校招项目Web服务器) 39 | - [RocksDB](https://github.com/facebook/rocksdb) Key-Value存储引擎 40 | - [Libhv](https://github.com/ithewei/libhv) (高性能Web服务器) 41 | - [TiDB](https://github.com/pingcap/tidb) 分布式HTAP型数据库 42 | ### Offer收割机必备 43 | 5. 推荐项目 44 | 1. [TinyKV](https://github.com/talent-plan/tinykv) KV存储引擎(PingCAP)(#7) 45 | 2. [TinySQL](https://github.com/talent-plan/tinysql) 分布式SQL(PingCAP) 46 | 6. 推荐课程 47 | 1. [《操作系统:设计与实现》南京大学,蒋炎岩,B站id:绿导师原谅你了](https://www.bilibili.com/video/BV1Cm4y1d7Ur?spm_id_from=333.999.0.0&vd_source=e9f1ced96b267a4bc02ec41ca31d850a) 48 | 2. [CMU15-445/645 数据库原理与设计 (#7)](https://15445.courses.cs.cmu.edu/fall2022/) 49 | 3. [MIT6.824 分布式设计](https://pdos.csail.mit.edu/6.824/) 50 | 4. [CMU15-721 高级数据库设计](https://15721.courses.cs.cmu.edu/spring2020/) 51 | 52 | 7. 面经整理 53 | 1. [姚军个人仓库](https://github.com/PeppaYao/work) 54 | 55 | -------------------------------------------------------------------------------- /class/lesson10/makefile: -------------------------------------------------------------------------------- 1 | mmap_test: mmap_test.cpp 2 | g++ mmap_test.cpp 3 | 4 | mmap2: mmap_test2.cpp 5 | g++ mmap_test2.cpp 6 | mmap3: mmap_test3.cpp 7 | g++ mmap_test3.cpp -------------------------------------------------------------------------------- /class/lesson10/mmap_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define GiB *(1024LL * 1024 * 1024) 6 | int main() { 7 | void *p = mmap(NULL, 3 GiB, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 8 | if(p == MAP_FAILED) { 9 | printf("mmap failed!\n"); 10 | }else{ 11 | printf("mmap success!\n"); 12 | } 13 | 14 | *(int *)((u_int8_t*)p + 1 GiB) = 114; 15 | *(int *)((u_int8_t*)p + 2 GiB) = 115; 16 | 17 | printf("read = %d\n", *(int *)((u_int8_t*)p + 2 GiB)); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /class/lesson10/mmap_test2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | int main(){ 9 | //把磁盘文件放入共享内存,这样可以使用指针访问磁盘文件 mytest.txt必须有内容。 10 | int fd = open("mytest.txt", O_RDWR | O_CREAT, 0644); 11 | if (fd < 0) 12 | { 13 | perror("open error!"); 14 | exit(1); 15 | } 16 | //申请共享映射 17 | void *p = mmap(NULL, 100, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 18 | if (p == MAP_FAILED) 19 | { 20 | perror("mmap error!"); 21 | exit(1); 22 | } 23 | strcpy((char *)p, "abc"); 24 | int ret = munmap(p, 100); //释放共享映射 25 | if (ret == -1) 26 | { 27 | perror("munmap error!"); 28 | exit(1); 29 | } 30 | close(fd); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /class/lesson10/mmap_test3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | int main(){ 9 | 10 | int fd = open("mytest.txt", O_RDWR | O_CREAT, 0644); 11 | if (fd < 0) 12 | { 13 | perror("open error!"); 14 | exit(1); 15 | } 16 | //申请共享映射 17 | void *p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 18 | if (p == MAP_FAILED) 19 | { 20 | perror("mmap error!"); 21 | exit(1); 22 | } 23 | strcpy((char *)p+4, "efg"); 24 | int ret = munmap(p, 8); //释放共享映射 25 | if (ret == -1) 26 | { 27 | perror("munmap error!"); 28 | exit(1); 29 | } 30 | close(fd); 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /class/lesson10/mytest.txt: -------------------------------------------------------------------------------- 1 | abcefgrld! -------------------------------------------------------------------------------- /class/lesson11/local_socket.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define UNIXSTR_PATH "/tmp/unix.str" 10 | #define LISTENQ 5 11 | #define BUFFER_SIZE 256 12 | 13 | int main(void) { 14 | int listenfd, connfd; 15 | socklen_t len; 16 | struct sockaddr_un servaddr, cliaddr; 17 | 18 | if(-1 == (listenfd = socket(AF_LOCAL, SOCK_STREAM, 0))) 19 | { 20 | perror("socket"); 21 | exit(EXIT_FAILURE); 22 | } 23 | 24 | unlink(UNIXSTR_PATH); 25 | 26 | bzero(&servaddr, sizeof(servaddr)); 27 | servaddr.sun_family = AF_LOCAL; 28 | strcpy(servaddr.sun_path, UNIXSTR_PATH); 29 | if(-1 == bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) 30 | { 31 | perror("bind"); 32 | exit(EXIT_FAILURE); 33 | } 34 | 35 | listen(listenfd, LISTENQ); 36 | 37 | len = sizeof(cliaddr); 38 | 39 | if(-1 == (connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len))) 40 | { 41 | perror("accept"); 42 | exit(EXIT_FAILURE); 43 | } 44 | 45 | char buf[BUFFER_SIZE]; 46 | 47 | while(1) 48 | { 49 | bzero(buf, sizeof(buf)); 50 | if(read(connfd, buf, BUFFER_SIZE) == 0) break; 51 | printf("Receive: %s", buf); 52 | } 53 | 54 | close(listenfd); 55 | close(connfd); 56 | unlink(UNIXSTR_PATH); 57 | 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /class/lesson11/local_socket_client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define UNIXSTR_PATH "/tmp/unix.str" 10 | #define LISTENQ 5 11 | #define BUFFER_SIZE 256 12 | 13 | int main(void) 14 | { 15 | int sockfd; 16 | struct sockaddr_un servaddr; 17 | 18 | sockfd = socket(AF_LOCAL, SOCK_STREAM, 0); 19 | 20 | bzero(&servaddr, sizeof(servaddr)); 21 | servaddr.sun_family = AF_LOCAL; 22 | strcpy(servaddr.sun_path, UNIXSTR_PATH); 23 | 24 | connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); 25 | 26 | char buf[BUFFER_SIZE]; 27 | 28 | while(1) 29 | { 30 | bzero(buf, sizeof(BUFFER_SIZE)); 31 | printf(">> "); 32 | if(fgets(buf, BUFFER_SIZE, stdin) == NULL) 33 | { 34 | break; 35 | } 36 | write(sockfd, buf, strlen(buf)); 37 | } 38 | 39 | close(sockfd); 40 | 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /class/lesson11/makefile: -------------------------------------------------------------------------------- 1 | local_socket_test: local_socket.cpp 2 | g++ local_socket.cpp -o local_socket_test 3 | local_socket_client_test: local_socket_client.cpp 4 | g++ local_socket_client.cpp -o local_socket_client_test 5 | udp_server_test: udp_server.cpp 6 | g++ udp_server.cpp -o udp_server_test 7 | udp_client_test: udp_client.cpp 8 | g++ udp_client.cpp -o udp_client_test -------------------------------------------------------------------------------- /class/lesson11/udp_client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define SERVER_PORT 8888 8 | #define BUFF_LEN 512 9 | #define SERVER_IP "172.0.5.182" 10 | 11 | 12 | void udp_msg_sender(int fd, struct sockaddr* dst) 13 | { 14 | 15 | socklen_t len; 16 | struct sockaddr_in src; 17 | while(1) 18 | { 19 | char buf[BUFF_LEN] = "TEST UDP MSG!\n"; 20 | len = sizeof(*dst); 21 | printf("client:%s\n",buf); //打印自己发送的信息 22 | sendto(fd, buf, BUFF_LEN, 0, dst, len); 23 | memset(buf, 0, BUFF_LEN); 24 | recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&src, &len); //接收来自server的信息 25 | printf("server:%s\n",buf); 26 | sleep(1); //一秒发送一次消息 27 | } 28 | } 29 | 30 | /* 31 | client: 32 | socket-->sendto-->revcfrom-->close 33 | */ 34 | 35 | int main(int argc, char* argv[]) 36 | { 37 | int client_fd; 38 | struct sockaddr_in ser_addr; 39 | 40 | client_fd = socket(AF_INET, SOCK_DGRAM, 0); 41 | if(client_fd < 0) 42 | { 43 | printf("create socket fail!\n"); 44 | return -1; 45 | } 46 | 47 | memset(&ser_addr, 0, sizeof(ser_addr)); 48 | ser_addr.sin_family = AF_INET; 49 | //ser_addr.sin_addr.s_addr = inet_addr(SERVER_IP); 50 | ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //注意网络序转换 51 | ser_addr.sin_port = htons(SERVER_PORT); //注意网络序转换 52 | 53 | udp_msg_sender(client_fd, (struct sockaddr*)&ser_addr); 54 | 55 | close(client_fd); 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /class/lesson11/udp_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define SERVER_PORT 8888 8 | #define BUFF_LEN 1024 9 | 10 | void handle_udp_msg(int fd) 11 | { 12 | char buf[BUFF_LEN]; //接收缓冲区,1024字节 13 | socklen_t len; 14 | int count; 15 | struct sockaddr_in clent_addr; //clent_addr用于记录发送方的地址信息 16 | while(1) 17 | { 18 | memset(buf, 0, BUFF_LEN); 19 | len = sizeof(clent_addr); 20 | count = recvfrom(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&clent_addr, &len); //recvfrom是拥塞函数,没有数据就一直拥塞 21 | if(count == -1) 22 | { 23 | printf("recieve data fail!\n"); 24 | return; 25 | } 26 | printf("client:%s\n",buf); //打印client发过来的信息 27 | memset(buf, 0, BUFF_LEN); 28 | sprintf(buf, "I have recieved %d bytes data!\n", count); //回复client 29 | printf("server:%s\n",buf); //打印自己发送的信息给 30 | sendto(fd, buf, BUFF_LEN, 0, (struct sockaddr*)&clent_addr, len); //发送信息给client,注意使用了clent_addr结构体指针 31 | 32 | } 33 | } 34 | 35 | 36 | /* 37 | server: 38 | socket-->bind-->recvfrom-->sendto-->close 39 | */ 40 | 41 | int main(int argc, char* argv[]) 42 | { 43 | int server_fd, ret; 44 | struct sockaddr_in ser_addr; 45 | 46 | server_fd = socket(AF_INET, SOCK_DGRAM, 0); //AF_INET:IPV4;SOCK_DGRAM:UDP 47 | if(server_fd < 0) 48 | { 49 | printf("create socket fail!\n"); 50 | return -1; 51 | } 52 | 53 | memset(&ser_addr, 0, sizeof(ser_addr)); 54 | ser_addr.sin_family = AF_INET; 55 | ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IP地址,需要进行网络序转换,INADDR_ANY:本地地址 56 | ser_addr.sin_port = htons(SERVER_PORT); //端口号,需要网络序转换 57 | 58 | ret = bind(server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)); 59 | if(ret < 0) 60 | { 61 | printf("socket bind fail!\n"); 62 | return -1; 63 | } 64 | 65 | handle_udp_msg(server_fd); //处理接收到的数据 66 | 67 | close(server_fd); 68 | return 0; 69 | } -------------------------------------------------------------------------------- /class/lesson12/test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/11/28. 3 | // 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | int main() { 10 | int num = 999; 11 | int *temp = # 12 | int **ptr = &temp; 13 | 14 | printf("ptr_value = %d\n", ptr); 15 | printf("=============\n"); 16 | printf("ptr_first_level = %d\n", *ptr); 17 | printf("temp_value = %d\n", temp); 18 | printf("num_addr = %d\n", &num); 19 | printf("=============\n"); 20 | printf("ptr_second_level = %d\n", **ptr); 21 | printf("temp_first_level = %d\n", *temp); 22 | printf("num_value = %d\n", num); 23 | 24 | return 0; 25 | } -------------------------------------------------------------------------------- /class/lesson4/chrono_test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/8/13. 3 | // 4 | 5 | #include 6 | #include 7 | typedef long long LL; 8 | int main(){ 9 | // 线性计算:1 到1e5 10 | auto start = std::chrono::steady_clock::now(); 11 | LL new_total = 0; 12 | for(int i = 0; i < 100000; i++) { 13 | new_total += i*(LL)i; 14 | } 15 | printf("linear scan result = %lld\n", new_total); 16 | auto end = std::chrono::steady_clock::now(); 17 | auto duration_ms = std::chrono::duration_cast(end - start).count(); 18 | printf( "线性扫描花费了%lld毫秒\n", duration_ms); 19 | return 0; 20 | } -------------------------------------------------------------------------------- /class/lesson4/compute.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/8/13. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static const int MAX = 1e8; 16 | using LL = long long; 17 | static LL sum = 0; 18 | void worker(int minV, int maxV){ 19 | for(int i = minV; i <= maxV; i++){ 20 | sum += i*(LL)i; 21 | } 22 | } 23 | void serial_task(){ 24 | // 单线程 计算1e8的平方根之和 25 | auto start_time = std::chrono::steady_clock::now(); 26 | sum = 0; 27 | worker(1, MAX); 28 | auto end_time = std::chrono::steady_clock::now(); 29 | auto ms = std::chrono::duration_cast(end_time - start_time).count(); 30 | std::cout<<"Serial task finish, "<< ms <<" ms consumed, Result: " << std::fixed << std::setprecision(3)< threads; 49 | minV = 0; 50 | sum = 0; 51 | for(int t = 0; t < concurrent_count; t++){ 52 | int range = maxV / concurrent_count *(t + 1); 53 | threads.push_back(std::thread(concurrent_worker, minV, range)); 54 | minV = range + 1; 55 | } 56 | for(auto &t: threads){ 57 | t.join(); 58 | } 59 | auto end_time = std::chrono::steady_clock::now(); 60 | auto ms = std::chrono::duration_cast(end_time - start_time).count(); 61 | std::cout<<"concurrency task finish, "<< ms <<" ms consumed, Result: " << std::fixed << std::setprecision(3)< 5 | #include 6 | #include 7 | 8 | int main(){ 9 | std::cout<<"主进程 pid = "< 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | typedef long long LL; 13 | LL get_interval_sum(int start) { 14 | start *= 20000; 15 | int stop = start + 20000; 16 | LL temp = 0; 17 | for(int i = start; i < stop; i++) { 18 | temp += i*(LL)i; 19 | } 20 | printf("I'm %dth, temp = %lld\n", start/20000, temp); 21 | return temp; 22 | } 23 | int main() { 24 | // 5个进程并行计算 25 | int THREAD_NUM = 5; 26 | LL total_sum = 0; 27 | auto start = std::chrono::steady_clock::now(); 28 | int i; 29 | for(i = 0; i < THREAD_NUM; i++) { 30 | pid_t pid = fork(); // n 2^n-1 n 31 | if(pid == 0){ 32 | // 进程之间变量不可见,怎么改呢? 33 | total_sum += get_interval_sum(i); 34 | break; 35 | } 36 | } 37 | if (i < THREAD_NUM){ // 子进程退出 38 | // printf("I'm %dth child, pid = %u, ppid = %u\n", i + 1, getpid(), getppid()); 39 | }else{ // 父进程退出 40 | // wait(NULL); //NULL不关心子进程退出的状态 41 | // waitpid回收指定进程 42 | // argv_1: pid指定子进程,-1任意子进程 43 | // argv_2: 子进程退出的状态,出参。 44 | // argv_3: WNOHANG不阻塞,通过轮询回收,回收成功返回子进程pid,回收失败返回0,出错返回-1 45 | int reclaim_num = 0; 46 | do{ 47 | auto wpid = waitpid(-1, NULL, WNOHANG); 48 | if (wpid > 0) { 49 | reclaim_num++; 50 | } 51 | }while(reclaim_num != THREAD_NUM); 52 | 53 | printf("I'm parent, pid = %u, ppid = %u\n", getpid(), getppid()); 54 | printf("multi-process result = %lld\n", total_sum); 55 | // 父进程等待子进程执行完毕再结束 56 | auto end = std::chrono::steady_clock::now(); 57 | auto duration_ms = std::chrono::duration_cast(end - start).count(); 58 | printf( "多进程花费了%lld毫秒\n", duration_ms); 59 | } 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /class/lesson4/multi-thread.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/8/13. 3 | // 4 | #include 5 | #include 6 | 7 | void hello(){ 8 | std::cout<<"hello world"< 2 | #include 3 | int main(){ 4 | alarm(3); //计时1s 到时后内核发送一个SIGALRM信号终止进程, 只能定时秒级 5 | long long i = 0; 6 | while(true) { 7 | i++; 8 | printf("processing...%lld\n", i); 9 | } 10 | return 0; 11 | } -------------------------------------------------------------------------------- /class/lesson6/client.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #define SERV_IP "127.0.0.1" 11 | #define SERV_PORT 6670 12 | /* 13 | 1.创建套接字 14 | 2.调用connect函数与服务器连接 15 | 3.从键盘write数据 16 | 4.从服务器read数据 17 | 5.close 18 | */ 19 | int main(void){ 20 | //1. 21 | int cfd; 22 | struct sockaddr_in serv_addr; 23 | socklen_t serv_addr_len; 24 | cfd = socket(AF_INET, SOCK_STREAM, 0); 25 | //2. 26 | memset(&serv_addr, 0, sizeof(serv_addr)); //初始化 27 | serv_addr.sin_family = AF_INET; //IPV4协议 28 | serv_addr.sin_port = htons(SERV_PORT); //服务器端口 29 | inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr); //点分十进制转网络字节序 30 | //3. 31 | connect(cfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); 32 | //4. 33 | char buf[BUFSIZ]; 34 | int n; 35 | while(1){ 36 | fgets(buf, sizeof(buf), stdin); //读一行 但是会自动加一个换行符 37 | write(cfd, buf, strlen(buf)); //写入到文件描述符 写缓冲区 38 | n = read(cfd, buf, sizeof(buf)); //返回从服务器读出的字节数 39 | write(STDOUT_FILENO, buf, n); //把读入的数据写到屏幕 40 | } 41 | //5. 42 | close(cfd); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /class/lesson6/makefile: -------------------------------------------------------------------------------- 1 | server: server.cpp 2 | g++ server.cpp -o server 3 | client: client.cpp 4 | g++ client.cpp -o client 5 | alarm: alarm_test.cpp 6 | g++ alarm_test.cpp -o alarm 7 | alarm_adv: setitimer_test.cpp 8 | g++ setitimer_test.cpp -o alarm_adv 9 | alarm_adv2: setitimer_test2.cpp 10 | g++ setitimer_test2.cpp -o alarm_adv2 -------------------------------------------------------------------------------- /class/lesson6/server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define SERV_IP "127.0.0.1" 9 | #define SERV_PORT 6670 10 | 11 | int main(void){ 12 | int lfd, cfd; 13 | char buf[BUFSIZ], client_IP[BUFSIZ]; //4k或者8k 14 | struct sockaddr_in serv_addr, clie_addr; 15 | // socket是一个input和output缓冲区 16 | // 文件描述符:37 17 | lfd = socket(AF_INET, SOCK_STREAM, 0); //创建套接字 18 | 19 | serv_addr.sin_family = AF_INET; 20 | serv_addr.sin_port = htons(SERV_PORT); 21 | inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr); //点分十进制转网络字节序 22 | 23 | // 绑定端口 类似于将上课的A5教室定下来,而客户端就是学生,学生需要知道教室A5 24 | // 绑定提供服务的接口 25 | bind(lfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr) ); 26 | // 监听端口 27 | listen(lfd, 128); //最大同时连接数 28 | socklen_t clie_addr_len; //套接字长度 29 | clie_addr_len = sizeof(clie_addr); 30 | // 接收请求 阻塞调用 等待 31 | cfd = accept(lfd, (struct sockaddr*)&clie_addr, &clie_addr_len ); 32 | printf("client IP: %s, client port: %d\n", 33 | inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, client_IP, sizeof(client_IP)), 34 | ntohs(clie_addr.sin_port)); 35 | int i, n; 36 | // 终端输入nc 127.0.0.1 6670 去发送数据 37 | // 服务端如何支持rest ful风格的请求get post put delete 38 | while(1){ //一直读 一直写 39 | n = read(cfd, buf, sizeof(buf)); 40 | for(i = 0; i < n; i++){ 41 | buf[i] = toupper(buf[i]); 42 | } 43 | buf[i++]='!'; 44 | write(cfd, buf, n+1); 45 | } 46 | close(lfd); 47 | close(cfd); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /class/lesson6/setitimer_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int my_alarm(int sec){ 6 | struct itimerval new_it, old_it; 7 | // new_id传入 8 | // old_it传出 9 | new_it.it_value.tv_sec = sec; //定时长度 10 | new_it.it_value.tv_usec = 0; //微秒 11 | 12 | new_it.it_interval.tv_sec = 0; //周期定时 13 | new_it.it_interval.tv_usec = 0; 14 | // argv_1:自然定时,也可以支持用户态时间或者用户态和内核态计时 15 | int ret = setitimer(ITIMER_REAL, &new_it, &old_it); 16 | if(ret == -1){ 17 | perror("setitimer error"); 18 | exit(1); 19 | } 20 | return old_it.it_value.tv_sec; 21 | } 22 | int main(){ 23 | my_alarm(1); //计时1s 到时后内核发送一个sigalrm信号终止 24 | for(int i = 0;;i++) printf("%d\n", i); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /class/lesson6/setitimer_test2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | void process_func(int x){ 7 | printf("I catch a signal. ha ha ha...\n"); 8 | } 9 | int main(){ 10 | // 信号注册 11 | signal(SIGALRM, process_func); 12 | struct itimerval new_it, old_it; 13 | // new_id传入 14 | // old_it传出 15 | // 定时为:5秒后开始,间隔3秒一次 16 | new_it.it_value.tv_sec = 1; //定时长度 17 | new_it.it_value.tv_usec = 0; //微秒 18 | 19 | new_it.it_interval.tv_sec = 3; //周期定时 20 | new_it.it_interval.tv_usec = 0; 21 | // argv_1:自然定时,也可以支持用户态时间或者用户态和内核态计时 22 | if(setitimer(ITIMER_REAL, &new_it, &old_it) == -1){ 23 | perror("setitimer error"); 24 | exit(1); 25 | } 26 | while (1); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /class/lesson6/time_heap.cpp: -------------------------------------------------------------------------------- 1 | #ifndef intIME_HEAP 2 | #define intIME_HEAP 3 | 4 | #include 5 | #include 6 | #include 7 | using std::exception; 8 | 9 | #define BUFFER_SIZE 64 10 | 11 | class heap_timer; 12 | struct client_data 13 | { 14 | sockaddr_in address; 15 | int sockfd; 16 | char buf[ BUFFER_SIZE ]; 17 | heap_timer* timer; 18 | }; 19 | 20 | class heap_timer 21 | { 22 | public: 23 | heap_timer( int delay ) 24 | { 25 | expire = time( NULL ) + delay; 26 | } 27 | 28 | public: 29 | time_t expire; 30 | void (*cb_func)( client_data* ); 31 | client_data* user_data; 32 | }; 33 | 34 | class time_heap 35 | { 36 | public: 37 | time_heap( int cap ) throw ( std::exception ) 38 | : capacity( cap ), cur_size( 0 ) 39 | { 40 | array = new heap_timer* [capacity]; 41 | if ( ! array ) 42 | { 43 | throw std::exception(); 44 | } 45 | for( int i = 0; i < capacity; ++i ) 46 | { 47 | array[i] = NULL; 48 | } 49 | } 50 | time_heap( heap_timer** init_array, int size, int capacity ) throw ( std::exception ) 51 | : cur_size( size ), capacity( capacity ) 52 | { 53 | if ( capacity < size ) 54 | { 55 | throw std::exception(); 56 | } 57 | array = new heap_timer* [capacity]; 58 | if ( ! array ) 59 | { 60 | throw std::exception(); 61 | } 62 | for( int i = 0; i < capacity; ++i ) 63 | { 64 | array[i] = NULL; 65 | } 66 | if ( size != 0 ) 67 | { 68 | for ( int i = 0; i < size; ++i ) 69 | { 70 | array[ i ] = init_array[ i ]; 71 | } 72 | for ( int i = (cur_size-1)/2; i >=0; --i ) 73 | { 74 | percolate_down( i ); 75 | } 76 | } 77 | } 78 | ~time_heap() 79 | { 80 | for ( int i = 0; i < cur_size; ++i ) 81 | { 82 | delete array[i]; 83 | } 84 | delete [] array; 85 | } 86 | 87 | public: 88 | void add_timer( heap_timer* timer ) throw ( std::exception ) 89 | { 90 | if( !timer ) 91 | { 92 | return; 93 | } 94 | if( cur_size >= capacity ) 95 | { 96 | resize(); 97 | } 98 | int hole = cur_size++; 99 | int parent = 0; 100 | for( ; hole > 0; hole=parent ) 101 | { 102 | parent = (hole-1)/2; 103 | if ( array[parent]->expire <= timer->expire ) 104 | { 105 | break; 106 | } 107 | array[hole] = array[parent]; 108 | } 109 | array[hole] = timer; 110 | } 111 | void del_timer( heap_timer* timer ) 112 | { 113 | if( !timer ) 114 | { 115 | return; 116 | } 117 | // lazy delelte 118 | timer->cb_func = NULL; 119 | } 120 | heap_timer* top() const 121 | { 122 | if ( empty() ) 123 | { 124 | return NULL; 125 | } 126 | return array[0]; 127 | } 128 | void pop_timer() 129 | { 130 | if( empty() ) 131 | { 132 | return; 133 | } 134 | if( array[0] ) 135 | { 136 | delete array[0]; 137 | array[0] = array[--cur_size]; 138 | percolate_down( 0 ); 139 | } 140 | } 141 | void tick() 142 | { 143 | heap_timer* tmp = array[0]; 144 | time_t cur = time( NULL ); 145 | while( !empty() ) 146 | { 147 | if( !tmp ) 148 | { 149 | break; 150 | } 151 | if( tmp->expire > cur ) 152 | { 153 | break; 154 | } 155 | if( array[0]->cb_func ) 156 | { 157 | array[0]->cb_func( array[0]->user_data ); 158 | } 159 | pop_timer(); 160 | tmp = array[0]; 161 | } 162 | } 163 | bool empty() const { return cur_size == 0; } 164 | 165 | private: 166 | void percolate_down( int hole ) 167 | { 168 | heap_timer* temp = array[hole]; 169 | int child = 0; 170 | for ( ; ((hole*2+1) <= (cur_size-1)); hole=child ) 171 | { 172 | child = hole*2+1; 173 | if ( (child < (cur_size-1)) && (array[child+1]->expire < array[child]->expire ) ) 174 | { 175 | ++child; 176 | } 177 | if ( array[child]->expire < temp->expire ) 178 | { 179 | array[hole] = array[child]; 180 | } 181 | else 182 | { 183 | break; 184 | } 185 | } 186 | array[hole] = temp; 187 | } 188 | void resize() throw ( std::exception ) 189 | { 190 | heap_timer** temp = new heap_timer* [2*capacity]; 191 | for( int i = 0; i < 2*capacity; ++i ) 192 | { 193 | temp[i] = NULL; 194 | } 195 | if ( ! temp ) 196 | { 197 | throw std::exception(); 198 | } 199 | capacity = 2*capacity; 200 | for ( int i = 0; i < cur_size; ++i ) 201 | { 202 | temp[i] = array[i]; 203 | } 204 | delete [] array; 205 | array = temp; 206 | } 207 | 208 | private: 209 | heap_timer** array; 210 | int capacity; 211 | int cur_size; 212 | }; 213 | 214 | #endif -------------------------------------------------------------------------------- /class/lesson6/time_wheel.cpp: -------------------------------------------------------------------------------- 1 | #ifndef TIME_WHEEL_TIMER 2 | #define TIME_WHEEL_TIMER 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define BUFFER_SIZE 64 9 | class tw_timer; 10 | struct client_data//绑定socket和定时器 11 | { 12 | sockaddr_in address; 13 | int sockfd; 14 | char buf[ BUFFER_SIZE ]; 15 | tw_timer* timer; 16 | }; 17 | 18 | class tw_timer//定时器类 19 | { 20 | public: 21 | tw_timer( int rot, int ts ) 22 | : next( NULL ), prev( NULL ), rotation( rot ), time_slot( ts ){} 23 | 24 | public: 25 | int rotation;//记录该定时器在时间轮转多少圈后生效 26 | int time_slot;//记录定时器属于那个槽 27 | void (*cb_func)( client_data* );//定时器回调函数 28 | client_data* user_data;//用户数据 29 | tw_timer* next;//指向上一个定时器 30 | tw_timer* prev;//指向下一个定时器 31 | }; 32 | 33 | class time_wheel//事件轮管理定时器 34 | { 35 | public: 36 | time_wheel() : cur_slot( 0 ) 37 | { 38 | for( int i = 0; i < N; ++i ) 39 | { 40 | slots[i] = NULL;//每个槽的头节点初始化为空 41 | } 42 | } 43 | ~time_wheel() 44 | { 45 | for( int i = 0; i < N; ++i ) 46 | { 47 | tw_timer* tmp = slots[i]; 48 | while( tmp ) 49 | { 50 | slots[i] = tmp->next; 51 | delete tmp;//遍历每个槽销毁new分配在堆中的定时器 52 | tmp = slots[i]; 53 | } 54 | } 55 | } 56 | tw_timer* add_timer( int timeout )//添加新的定时器,插入到合适的槽中 57 | { 58 | if( timeout < 0 )//时间错误 59 | { 60 | return NULL; 61 | } 62 | int ticks = 0; 63 | if( timeout < TI )//小于每个槽的interval,则为1 64 | { 65 | ticks = 1; 66 | } 67 | else 68 | { 69 | ticks = timeout / TI;//相对当前位置的槽数 70 | } 71 | int rotation = ticks / N;//记录多少圈后生效 72 | int ts = ( cur_slot + ( ticks % N ) ) % N;//确定插入槽的位置 73 | tw_timer* timer = new tw_timer( rotation, ts );//根据位置和圈数,插入对应的槽中 74 | if( !slots[ts] )//所在槽头节点为空,直接插入 75 | { 76 | printf( "add timer, rotation is %d, ts is %d, cur_slot is %d\n", rotation, ts, cur_slot ); 77 | slots[ts] = timer; 78 | } 79 | else 80 | { 81 | timer->next = slots[ts]; 82 | slots[ts]->prev = timer; 83 | slots[ts] = timer; 84 | } 85 | return timer;//返回含有时间信息和所在槽位置的定时器 86 | } 87 | void del_timer( tw_timer* timer )//从时间轮上删除定时器 88 | { 89 | if( !timer ) 90 | { 91 | return; 92 | } 93 | int ts = timer->time_slot;//找到所在槽 94 | if( timer == slots[ts] ) 95 | { 96 | slots[ts] = slots[ts]->next; 97 | if( slots[ts] ) 98 | { 99 | slots[ts]->prev = NULL; 100 | } 101 | delete timer; 102 | } 103 | else 104 | { 105 | timer->prev->next = timer->next; 106 | if( timer->next ) 107 | { 108 | timer->next->prev = timer->prev; 109 | } 110 | delete timer; 111 | } 112 | } 113 | void tick() 114 | { 115 | tw_timer* tmp = slots[cur_slot];//取出当前槽的头节点 116 | printf( "current slot is %d\n", cur_slot ); 117 | while( tmp )//遍历 118 | { 119 | printf( "tick the timer once\n" ); 120 | if( tmp->rotation > 0 ) 121 | { 122 | tmp->rotation--; 123 | tmp = tmp->next; 124 | } 125 | else 126 | { 127 | tmp->cb_func( tmp->user_data );//符合条件,调用回调函数 128 | if( tmp == slots[cur_slot] ) 129 | { 130 | printf( "delete header in cur_slot\n" ); 131 | slots[cur_slot] = tmp->next; 132 | delete tmp; 133 | if( slots[cur_slot] ) 134 | { 135 | slots[cur_slot]->prev = NULL; 136 | } 137 | tmp = slots[cur_slot]; 138 | } 139 | else 140 | { 141 | tmp->prev->next = tmp->next; 142 | if( tmp->next ) 143 | { 144 | tmp->next->prev = tmp->prev; 145 | } 146 | tw_timer* tmp2 = tmp->next; 147 | delete tmp; 148 | tmp = tmp2; 149 | } 150 | } 151 | } 152 | cur_slot = ++cur_slot % N; 153 | } 154 | 155 | private: 156 | static const int N = 60; 157 | static const int TI = 1; 158 | tw_timer* slots[N]; 159 | int cur_slot; 160 | }; 161 | #endif -------------------------------------------------------------------------------- /class/lesson8/basic_io.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(){ 9 | // open write read 10 | // 功能:从一个文件读内容,写到另一个文件 11 | int fd = open("hello.txt", O_RDONLY); 12 | if(fd == -1) { 13 | printf("open failed!\n"); 14 | return 0; 15 | } 16 | int fx = open("newhello.txt", O_CREAT | O_WRONLY, 0644); 17 | char buf[1024]; 18 | int n; 19 | while (n = read(fd, buf, sizeof(buf))){ 20 | int ret = write(fx, buf, n); 21 | if (ret == -1) { 22 | perror("write error"); 23 | exit(1); 24 | } 25 | printf("write bytes: %d\n", n); 26 | } 27 | 28 | close(fd); 29 | close(fx); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /class/lesson8/fifo_read.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #define P_FIFO "/tmp/p_fifo" 8 | int main(int argc, char** argv){ 9 | char cache[100]; 10 | int fd; 11 | memset(cache,0, sizeof(cache)); /*初始化内存*/ 12 | if(access(P_FIFO,F_OK)==0){ /*管道文件存在*/ 13 | execlp("rm","-f", P_FIFO, NULL); /*删掉*/ 14 | printf("access.\n"); 15 | } 16 | if(mkfifo(P_FIFO, 0777) < 0){ 17 | printf("createnamed pipe failed.\n"); 18 | } 19 | fd = open(P_FIFO, O_RDONLY|O_NONBLOCK); /*非阻塞方式打开,只读*/ 20 | while(1){ 21 | memset(cache,0, sizeof(cache)); 22 | if((read(fd,cache, 100)) == 0 ){ /*没有读到数据*/ 23 | printf("nodata:\n"); 24 | } 25 | else{ 26 | printf("getdata:%s\n", cache); /*读到数据,将其打印*/ 27 | } 28 | sleep(1);/*休眠1s*/ 29 | } 30 | close(fd); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /class/lesson8/fifo_write.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define P_FIFO "/tmp/p_fifo" 5 | int main(int argc, char **argv){ 6 | int fd; 7 | if(argc< 2){ 8 | printf("please input the write data.\n"); 9 | exit(1); 10 | } 11 | fd = open(P_FIFO, O_WRONLY|O_NONBLOCK); /*非阻塞方式*/ 12 | if(fd == -1) { 13 | printf("open failed!\n"); 14 | return 0; 15 | }else{ 16 | printf("open success!"); 17 | } 18 | write(fd, argv[1], 100); /*将argv[1]写道fd里面去*/ 19 | close(fd); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /class/lesson8/hello.txt: -------------------------------------------------------------------------------- 1 | Hello, my name is yaojun. 2 | You can call me James. -------------------------------------------------------------------------------- /class/lesson8/makefile: -------------------------------------------------------------------------------- 1 | mmap_test: mmap.cpp 2 | g++ mmap.cpp -o mmap_test 3 | pipe_test: pipe_test.cpp 4 | g++ pipe_test.cpp -o pipe_test 5 | basic_io_test: basic_io.cpp 6 | g++ basic_io.cpp -o basic_io_test 7 | fifo_r: fifo_read.cpp 8 | g++ fifo_read.cpp -o fifo_r 9 | fifo_w: fifo_write.cpp 10 | g++ fifo_write.cpp -o fifo_w -------------------------------------------------------------------------------- /class/lesson8/mmap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | int main() { 9 | char *p = NULL; 10 | int fd = open("mytest.txt", O_RDWR | O_CREAT, 0644); 11 | if (fd < 0) 12 | { 13 | perror("open error!"); 14 | exit(1); 15 | } 16 | //申请共享映射 17 | p = mmap(NULL, 6, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 18 | if (p == MAP_FAILED) 19 | { 20 | perror("mmap error!"); 21 | exit(1); 22 | } 23 | strcpy(p, "abc\n"); 24 | int ret = munmap(p, 8); //释放共享映射 25 | if (ret == -1) 26 | { 27 | perror("munmap error!"); 28 | exit(1); 29 | } 30 | close(fd); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /class/lesson8/non_blocking.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int setnonblocking(int fd) { 6 | int old_option = fcntl(fd, F_GETFL); 7 | int new_option = old_option | O_NONBLOCK; 8 | fcntl(fd, F_SETFL, new_option); 9 | return old_option; 10 | } 11 | int main() { 12 | int fd = open("jun.txt", O_CREAT | O_RDWR); 13 | if(fd < 0) { 14 | printf("error!"); 15 | _exit(0); 16 | } 17 | int old_ = setnonblocking(fd); 18 | int new_ = fcntl(fd, F_GETFL); 19 | printf("old = %d, new = %d\n", old_, new_); 20 | return 0; 21 | } -------------------------------------------------------------------------------- /class/lesson8/pipe_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | int main(){ 11 | // 父亲写 1 12 | // 孩子读 0 13 | int fd[2]; //0为读(子) 1为写(父) 14 | pid_t pid; 15 | int ret = pipe(fd); 16 | if (ret == -1){ 17 | perror("pipe error!"); 18 | exit(1); 19 | } 20 | pid = fork(); 21 | if (pid == -1){ 22 | perror("fork error!"); 23 | exit(1); 24 | }else if (pid == 0){ 25 | //子进程 读0 26 | close(fd[1]); 27 | char buf[1024]; 28 | printf("child = %d\n", getpid()); 29 | ret = read(fd[0], buf, sizeof(buf)); 30 | write(STDOUT_FILENO, buf, ret); 31 | }else if (pid > 0) { 32 | //父进程 写1 33 | sleep(1); 34 | close(fd[0]); 35 | printf("parent = %d\n", getpid()); 36 | write(fd[1], "hello pipe\n", 11); 37 | wait(NULL); // 回收子进程,避免成为僵尸进程 38 | } 39 | printf("finished! %d\n", getpid()); 40 | return 0; 41 | } -------------------------------------------------------------------------------- /class/rust_learn/cf1760A.rs: -------------------------------------------------------------------------------- 1 | /*** 2 | fn input()->i32{ 3 | let mut index = String::new(); 4 | use std::io; 5 | // 读一行 6 | io::stdin().read_line(&mut index).expect("not a num"); 7 | let mut res = 0; 8 | let trimmed = index.trim(); 9 | match trimmed.parse::() { 10 | Ok(num) => res = num, 11 | Err(..) => println!("this was not an integer: {}", trimmed), 12 | } 13 | res 14 | } 15 | fn main() { 16 | #[warn(unused_assignments)] 17 | let mut t: i32 = 0; 18 | t = input(); 19 | for j in 0..t { 20 | let mut array: [i32; 3]=[0,0,0]; 21 | for i in 0..3{ 22 | array[i] = input(); 23 | } 24 | array.sort(); 25 | println!("{}", array[1]); 26 | } 27 | } 28 | */ 29 | 30 | fn main() { 31 | let mut test_cases = String::new(); 32 | std::io::stdin().read_line(&mut test_cases).unwrap(); 33 | let t: i32 = test_cases.trim().parse().unwrap(); 34 | for _ in 0..t { 35 | let mut input_string = String::new(); 36 | std::io::stdin().read_line(&mut input_string).unwrap(); 37 | let mut numbers: Vec = input_string.split(" ").map(|x| x.trim().parse::().unwrap()).collect(); 38 | numbers.sort(); 39 | println!("{}", numbers[1]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /class/rust_learn/rust_study.md: -------------------------------------------------------------------------------- 1 | # Rust Study 2 | - Rust是一种类型安全的系统级编程语言 3 | - [参考博客](https://geektutu.com/post/quick-rust.html) 4 | ### 知识点 5 | 1. 变量 6 | 2. 函数 7 | 3. 结构体 8 | 4. string 9 | 5. hashmap 10 | 6. cargo 11 | 7. test 12 | ### 常用命令 13 | ```shell 14 | rustc --version 15 | cargo --version 16 | # 运行 17 | rustc hello_world.rs 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /class/rust_learn/test_1.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let a: i64 = 12; 3 | let b: bool = false; 4 | if a > 12 { 5 | print!("a = {}, b = {}", a, b); 6 | }else{ 7 | print!("go...\n"); 8 | } 9 | println!("Hello, world!"); 10 | } -------------------------------------------------------------------------------- /class/rust_learn/test_2.rs: -------------------------------------------------------------------------------- 1 | fn plus(x: i32, y: i32) -> i32 { 2 | x + y 3 | } 4 | 5 | fn main() { 6 | let x = 10; 7 | let y = 20; 8 | println!("{} + {} = {}", x, y, plus(x, y)) 9 | } 10 | 11 | #[test] 12 | fn it_works() { 13 | assert_eq!(4, plus(2, 2), ); 14 | } -------------------------------------------------------------------------------- /config/a.txt: -------------------------------------------------------------------------------- 1 | hellohello -------------------------------------------------------------------------------- /docs/Linux.md: -------------------------------------------------------------------------------- 1 | ## Linux开发指南 2 | - fork 3 | - pipe 4 | - mmap 5 | - mutex 6 | -------------------------------------------------------------------------------- /docs/Linux高性能服务器编程 (游双 著) (z-lib.org).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/docs/Linux高性能服务器编程 (游双 著) (z-lib.org).pdf -------------------------------------------------------------------------------- /docs/helper.md: -------------------------------------------------------------------------------- 1 | ## C++工程实践 2 | - 功能 3 | - 安全 4 | - 三高 5 | - 高并发 6 | - 高可用 7 | - 高性能 8 | ### 目录结构 9 | - build 10 | - include 11 | - src 12 | - docs 13 | - others 14 | ### CMakeLists.txt 15 | - 类似于maven,用来管理源文件和依赖。 16 | - xxx.so和xxx.a 17 | - 在链接的时候,把这些依赖的文件跟当前的文件,合并到一起。 18 | 19 | ### 编译 20 | - 针对Linux/MacOS 21 | ```shell 22 | cd build 23 | cmake .. 24 | ./server 25 | ``` 26 | ### 注意 27 | - 不要使用`using namespace std`,可能存在同名冲突。 28 | - 尽量使用列表初始化构造函数,性能更好,具体原因参考effective c++ 29 | 30 | ### 常用 31 | - 多态 32 | - 拷贝构造 33 | - 赋值构造 34 | - 传值 35 | - 传引用 36 | - 智能指针 37 | - 字符串 38 | - new 39 | - thread 40 | - vector 41 | - map/unordered_map/set 42 | - pair 43 | - bitset 44 | - 高精度时间chrono 45 | - sort 46 | - mutex 47 | - 模板 48 | - tuple 49 | ### 字节序 50 | - 主机字节序(现代PC)小端little endian 51 | - 网络字节序(JAVA虚拟机)大端big endian 52 | - 一个整数的高位字节23~31bit,存储在内存的低地址处 53 | - 低位字节0~7bit,存储在内存的高地址处。 54 | - 记法:小端字节序——低存低,高存高。12345678存储,12存在0x8f, 34存在0x6f, 56存在0x4f, 78存在0x2f。 55 | ### 高效IO读写函数(零拷贝技术) 56 | - sendfile 57 | - mmap 58 | - splice 59 | - tee 60 | ### 调测 61 | - tcpdump抓包 62 | - strace跟踪程序运行时执行的系统调用和接收到的信号 63 | - netstat网络接口统计 64 | - vmstat系统资源统计 65 | - top 66 | ### web服务器关键技术点 67 | > 参考书籍:《Linux高性能服务器编程》游双 68 | - 线程池 69 | - epoll使用 70 | - 定时器/任务调度策略/多核多备份的调度/分布式数据一致性 71 | ### 进阶问题 72 | - 你为什么要这样设计? 73 | - 他的优点和缺点分别是什么? 74 | - 你从项目中获得了哪些成长? 75 | ### 单例模式 76 | - 构造函数私有 77 | - 实例只有一份 78 | ### 工厂模式 79 | - 一个类别对应一个工厂 80 | - 不需要亲自创建对象,只需要从工厂中去取。 81 | 82 | -------------------------------------------------------------------------------- /file/minidb/minidb.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/file/minidb/minidb.data -------------------------------------------------------------------------------- /include/db.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | 5 | #ifndef SERVER_DB_H 6 | #define SERVER_DB_H 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "utils.h" 13 | #include "db_file.h" 14 | class miniDB{ 15 | public: 16 | // 内存中的索引 17 | std::unordered_map indexes; 18 | // 数据文件 19 | DBFile *dbFile; 20 | // 数据目录 21 | std::string dirPath; 22 | std::shared_mutex mutex_; 23 | 24 | std::pair get(std::string); 25 | STATUS put(std::string, std::string); 26 | ErrorInfo delete_(std::string); 27 | STATUS merge(); 28 | }; 29 | #endif //SERVER_DB_H 30 | -------------------------------------------------------------------------------- /include/db_file.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | 5 | #ifndef SERVER_DB_FILE_H 6 | #define SERVER_DB_FILE_H 7 | #include 8 | #include 9 | #include "entry.h" 10 | 11 | class DBFile{ 12 | public: 13 | int fd; 14 | int offset; 15 | void read(Entry); 16 | void write_(Entry); 17 | void loadIndex(); 18 | }; 19 | 20 | #endif //SERVER_DB_FILE_H 21 | -------------------------------------------------------------------------------- /include/entry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | 5 | #ifndef SERVER_ENTRY_H 6 | #define SERVER_ENTRY_H 7 | #include 8 | #include 9 | #include "utils.h" 10 | 11 | class Entry{ 12 | public: 13 | std::string key; 14 | std::string value; 15 | int keySize; 16 | int valueSize; 17 | MARK mark; 18 | Entry() = default; 19 | Entry(std::string&, std::string&, MARK); 20 | std::pair decode(std::string buf); 21 | std::pair encode(); 22 | int getSize(); 23 | }; 24 | #endif //SERVER_ENTRY_H 25 | -------------------------------------------------------------------------------- /include/gmock/gmock-cardinalities.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Google Mock - a framework for writing C++ mock classes. 31 | // 32 | // This file implements some commonly used cardinalities. More 33 | // cardinalities can be defined by the user implementing the 34 | // CardinalityInterface interface if necessary. 35 | 36 | // IWYU pragma: private, include "gmock/gmock.h" 37 | // IWYU pragma: friend gmock/.* 38 | 39 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 40 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 41 | 42 | #include 43 | 44 | #include 45 | #include // NOLINT 46 | 47 | #include "gmock/internal/gmock-port.h" 48 | #include "gtest/gtest.h" 49 | 50 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 51 | /* class A needs to have dll-interface to be used by clients of class B */) 52 | 53 | namespace testing { 54 | 55 | // To implement a cardinality Foo, define: 56 | // 1. a class FooCardinality that implements the 57 | // CardinalityInterface interface, and 58 | // 2. a factory function that creates a Cardinality object from a 59 | // const FooCardinality*. 60 | // 61 | // The two-level delegation design follows that of Matcher, providing 62 | // consistency for extension developers. It also eases ownership 63 | // management as Cardinality objects can now be copied like plain values. 64 | 65 | // The implementation of a cardinality. 66 | class CardinalityInterface { 67 | public: 68 | virtual ~CardinalityInterface() {} 69 | 70 | // Conservative estimate on the lower/upper bound of the number of 71 | // calls allowed. 72 | virtual int ConservativeLowerBound() const { return 0; } 73 | virtual int ConservativeUpperBound() const { return INT_MAX; } 74 | 75 | // Returns true if and only if call_count calls will satisfy this 76 | // cardinality. 77 | virtual bool IsSatisfiedByCallCount(int call_count) const = 0; 78 | 79 | // Returns true if and only if call_count calls will saturate this 80 | // cardinality. 81 | virtual bool IsSaturatedByCallCount(int call_count) const = 0; 82 | 83 | // Describes self to an ostream. 84 | virtual void DescribeTo(::std::ostream* os) const = 0; 85 | }; 86 | 87 | // A Cardinality is a copyable and IMMUTABLE (except by assignment) 88 | // object that specifies how many times a mock function is expected to 89 | // be called. The implementation of Cardinality is just a std::shared_ptr 90 | // to const CardinalityInterface. Don't inherit from Cardinality! 91 | class GTEST_API_ Cardinality { 92 | public: 93 | // Constructs a null cardinality. Needed for storing Cardinality 94 | // objects in STL containers. 95 | Cardinality() {} 96 | 97 | // Constructs a Cardinality from its implementation. 98 | explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} 99 | 100 | // Conservative estimate on the lower/upper bound of the number of 101 | // calls allowed. 102 | int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } 103 | int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } 104 | 105 | // Returns true if and only if call_count calls will satisfy this 106 | // cardinality. 107 | bool IsSatisfiedByCallCount(int call_count) const { 108 | return impl_->IsSatisfiedByCallCount(call_count); 109 | } 110 | 111 | // Returns true if and only if call_count calls will saturate this 112 | // cardinality. 113 | bool IsSaturatedByCallCount(int call_count) const { 114 | return impl_->IsSaturatedByCallCount(call_count); 115 | } 116 | 117 | // Returns true if and only if call_count calls will over-saturate this 118 | // cardinality, i.e. exceed the maximum number of allowed calls. 119 | bool IsOverSaturatedByCallCount(int call_count) const { 120 | return impl_->IsSaturatedByCallCount(call_count) && 121 | !impl_->IsSatisfiedByCallCount(call_count); 122 | } 123 | 124 | // Describes self to an ostream 125 | void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } 126 | 127 | // Describes the given actual call count to an ostream. 128 | static void DescribeActualCallCountTo(int actual_call_count, 129 | ::std::ostream* os); 130 | 131 | private: 132 | std::shared_ptr impl_; 133 | }; 134 | 135 | // Creates a cardinality that allows at least n calls. 136 | GTEST_API_ Cardinality AtLeast(int n); 137 | 138 | // Creates a cardinality that allows at most n calls. 139 | GTEST_API_ Cardinality AtMost(int n); 140 | 141 | // Creates a cardinality that allows any number of calls. 142 | GTEST_API_ Cardinality AnyNumber(); 143 | 144 | // Creates a cardinality that allows between min and max calls. 145 | GTEST_API_ Cardinality Between(int min, int max); 146 | 147 | // Creates a cardinality that allows exactly n calls. 148 | GTEST_API_ Cardinality Exactly(int n); 149 | 150 | // Creates a cardinality from its implementation. 151 | inline Cardinality MakeCardinality(const CardinalityInterface* c) { 152 | return Cardinality(c); 153 | } 154 | 155 | } // namespace testing 156 | 157 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 158 | 159 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ 160 | -------------------------------------------------------------------------------- /include/gmock/gmock-more-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Google Mock - a framework for writing C++ mock classes. 31 | // 32 | // This file implements some matchers that depend on gmock-matchers.h. 33 | // 34 | // Note that tests are implemented in gmock-matchers_test.cc rather than 35 | // gmock-more-matchers-test.cc. 36 | 37 | // IWYU pragma: private, include "gmock/gmock.h" 38 | // IWYU pragma: friend gmock/.* 39 | 40 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 41 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 42 | 43 | #include "gmock/gmock-matchers.h" 44 | 45 | namespace testing { 46 | 47 | // Silence C4100 (unreferenced formal 48 | // parameter) for MSVC 49 | #ifdef _MSC_VER 50 | #pragma warning(push) 51 | #pragma warning(disable : 4100) 52 | #if (_MSC_VER == 1900) 53 | // and silence C4800 (C4800: 'int *const ': forcing value 54 | // to bool 'true' or 'false') for MSVC 14 55 | #pragma warning(disable : 4800) 56 | #endif 57 | #endif 58 | 59 | // Defines a matcher that matches an empty container. The container must 60 | // support both size() and empty(), which all STL-like containers provide. 61 | MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { 62 | if (arg.empty()) { 63 | return true; 64 | } 65 | *result_listener << "whose size is " << arg.size(); 66 | return false; 67 | } 68 | 69 | // Define a matcher that matches a value that evaluates in boolean 70 | // context to true. Useful for types that define "explicit operator 71 | // bool" operators and so can't be compared for equality with true 72 | // and false. 73 | MATCHER(IsTrue, negation ? "is false" : "is true") { 74 | return static_cast(arg); 75 | } 76 | 77 | // Define a matcher that matches a value that evaluates in boolean 78 | // context to false. Useful for types that define "explicit operator 79 | // bool" operators and so can't be compared for equality with true 80 | // and false. 81 | MATCHER(IsFalse, negation ? "is true" : "is false") { 82 | return !static_cast(arg); 83 | } 84 | 85 | #ifdef _MSC_VER 86 | #pragma warning(pop) 87 | #endif 88 | 89 | } // namespace testing 90 | 91 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ 92 | -------------------------------------------------------------------------------- /include/gmock/gmock-nice-strict.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Implements class templates NiceMock, NaggyMock, and StrictMock. 31 | // 32 | // Given a mock class MockFoo that is created using Google Mock, 33 | // NiceMock is a subclass of MockFoo that allows 34 | // uninteresting calls (i.e. calls to mock methods that have no 35 | // EXPECT_CALL specs), NaggyMock is a subclass of MockFoo 36 | // that prints a warning when an uninteresting call occurs, and 37 | // StrictMock is a subclass of MockFoo that treats all 38 | // uninteresting calls as errors. 39 | // 40 | // Currently a mock is naggy by default, so MockFoo and 41 | // NaggyMock behave like the same. However, we will soon 42 | // switch the default behavior of mocks to be nice, as that in general 43 | // leads to more maintainable tests. When that happens, MockFoo will 44 | // stop behaving like NaggyMock and start behaving like 45 | // NiceMock. 46 | // 47 | // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of 48 | // their respective base class. Therefore you can write 49 | // NiceMock(5, "a") to construct a nice mock where MockFoo 50 | // has a constructor that accepts (int, const char*), for example. 51 | // 52 | // A known limitation is that NiceMock, NaggyMock, 53 | // and StrictMock only works for mock methods defined using 54 | // the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. 55 | // If a mock method is defined in a base class of MockFoo, the "nice" 56 | // or "strict" modifier may not affect it, depending on the compiler. 57 | // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT 58 | // supported. 59 | 60 | // IWYU pragma: private, include "gmock/gmock.h" 61 | // IWYU pragma: friend gmock/.* 62 | 63 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 64 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 65 | 66 | #include 67 | #include 68 | 69 | #include "gmock/gmock-spec-builders.h" 70 | #include "gmock/internal/gmock-port.h" 71 | 72 | namespace testing { 73 | template 74 | class NiceMock; 75 | template 76 | class NaggyMock; 77 | template 78 | class StrictMock; 79 | 80 | namespace internal { 81 | template 82 | std::true_type StrictnessModifierProbe(const NiceMock&); 83 | template 84 | std::true_type StrictnessModifierProbe(const NaggyMock&); 85 | template 86 | std::true_type StrictnessModifierProbe(const StrictMock&); 87 | std::false_type StrictnessModifierProbe(...); 88 | 89 | template 90 | constexpr bool HasStrictnessModifier() { 91 | return decltype(StrictnessModifierProbe(std::declval()))::value; 92 | } 93 | 94 | // Base classes that register and deregister with testing::Mock to alter the 95 | // default behavior around uninteresting calls. Inheriting from one of these 96 | // classes first and then MockClass ensures the MockClass constructor is run 97 | // after registration, and that the MockClass destructor runs before 98 | // deregistration. This guarantees that MockClass's constructor and destructor 99 | // run with the same level of strictness as its instance methods. 100 | 101 | #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \ 102 | (defined(_MSC_VER) || defined(__clang__)) 103 | // We need to mark these classes with this declspec to ensure that 104 | // the empty base class optimization is performed. 105 | #define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases) 106 | #else 107 | #define GTEST_INTERNAL_EMPTY_BASE_CLASS 108 | #endif 109 | 110 | template 111 | class NiceMockImpl { 112 | public: 113 | NiceMockImpl() { 114 | ::testing::Mock::AllowUninterestingCalls(reinterpret_cast(this)); 115 | } 116 | 117 | ~NiceMockImpl() { 118 | ::testing::Mock::UnregisterCallReaction(reinterpret_cast(this)); 119 | } 120 | }; 121 | 122 | template 123 | class NaggyMockImpl { 124 | public: 125 | NaggyMockImpl() { 126 | ::testing::Mock::WarnUninterestingCalls(reinterpret_cast(this)); 127 | } 128 | 129 | ~NaggyMockImpl() { 130 | ::testing::Mock::UnregisterCallReaction(reinterpret_cast(this)); 131 | } 132 | }; 133 | 134 | template 135 | class StrictMockImpl { 136 | public: 137 | StrictMockImpl() { 138 | ::testing::Mock::FailUninterestingCalls(reinterpret_cast(this)); 139 | } 140 | 141 | ~StrictMockImpl() { 142 | ::testing::Mock::UnregisterCallReaction(reinterpret_cast(this)); 143 | } 144 | }; 145 | 146 | } // namespace internal 147 | 148 | template 149 | class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock 150 | : private internal::NiceMockImpl, 151 | public MockClass { 152 | public: 153 | static_assert(!internal::HasStrictnessModifier(), 154 | "Can't apply NiceMock to a class hierarchy that already has a " 155 | "strictness modifier. See " 156 | "https://google.github.io/googletest/" 157 | "gmock_cook_book.html#NiceStrictNaggy"); 158 | NiceMock() : MockClass() { 159 | static_assert(sizeof(*this) == sizeof(MockClass), 160 | "The impl subclass shouldn't introduce any padding"); 161 | } 162 | 163 | // Ideally, we would inherit base class's constructors through a using 164 | // declaration, which would preserve their visibility. However, many existing 165 | // tests rely on the fact that current implementation reexports protected 166 | // constructors as public. These tests would need to be cleaned up first. 167 | 168 | // Single argument constructor is special-cased so that it can be 169 | // made explicit. 170 | template 171 | explicit NiceMock(A&& arg) : MockClass(std::forward(arg)) { 172 | static_assert(sizeof(*this) == sizeof(MockClass), 173 | "The impl subclass shouldn't introduce any padding"); 174 | } 175 | 176 | template 177 | NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 178 | : MockClass(std::forward(arg1), std::forward(arg2), 179 | std::forward(args)...) { 180 | static_assert(sizeof(*this) == sizeof(MockClass), 181 | "The impl subclass shouldn't introduce any padding"); 182 | } 183 | 184 | private: 185 | NiceMock(const NiceMock&) = delete; 186 | NiceMock& operator=(const NiceMock&) = delete; 187 | }; 188 | 189 | template 190 | class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock 191 | : private internal::NaggyMockImpl, 192 | public MockClass { 193 | static_assert(!internal::HasStrictnessModifier(), 194 | "Can't apply NaggyMock to a class hierarchy that already has a " 195 | "strictness modifier. See " 196 | "https://google.github.io/googletest/" 197 | "gmock_cook_book.html#NiceStrictNaggy"); 198 | 199 | public: 200 | NaggyMock() : MockClass() { 201 | static_assert(sizeof(*this) == sizeof(MockClass), 202 | "The impl subclass shouldn't introduce any padding"); 203 | } 204 | 205 | // Ideally, we would inherit base class's constructors through a using 206 | // declaration, which would preserve their visibility. However, many existing 207 | // tests rely on the fact that current implementation reexports protected 208 | // constructors as public. These tests would need to be cleaned up first. 209 | 210 | // Single argument constructor is special-cased so that it can be 211 | // made explicit. 212 | template 213 | explicit NaggyMock(A&& arg) : MockClass(std::forward(arg)) { 214 | static_assert(sizeof(*this) == sizeof(MockClass), 215 | "The impl subclass shouldn't introduce any padding"); 216 | } 217 | 218 | template 219 | NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 220 | : MockClass(std::forward(arg1), std::forward(arg2), 221 | std::forward(args)...) { 222 | static_assert(sizeof(*this) == sizeof(MockClass), 223 | "The impl subclass shouldn't introduce any padding"); 224 | } 225 | 226 | private: 227 | NaggyMock(const NaggyMock&) = delete; 228 | NaggyMock& operator=(const NaggyMock&) = delete; 229 | }; 230 | 231 | template 232 | class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock 233 | : private internal::StrictMockImpl, 234 | public MockClass { 235 | public: 236 | static_assert( 237 | !internal::HasStrictnessModifier(), 238 | "Can't apply StrictMock to a class hierarchy that already has a " 239 | "strictness modifier. See " 240 | "https://google.github.io/googletest/" 241 | "gmock_cook_book.html#NiceStrictNaggy"); 242 | StrictMock() : MockClass() { 243 | static_assert(sizeof(*this) == sizeof(MockClass), 244 | "The impl subclass shouldn't introduce any padding"); 245 | } 246 | 247 | // Ideally, we would inherit base class's constructors through a using 248 | // declaration, which would preserve their visibility. However, many existing 249 | // tests rely on the fact that current implementation reexports protected 250 | // constructors as public. These tests would need to be cleaned up first. 251 | 252 | // Single argument constructor is special-cased so that it can be 253 | // made explicit. 254 | template 255 | explicit StrictMock(A&& arg) : MockClass(std::forward(arg)) { 256 | static_assert(sizeof(*this) == sizeof(MockClass), 257 | "The impl subclass shouldn't introduce any padding"); 258 | } 259 | 260 | template 261 | StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 262 | : MockClass(std::forward(arg1), std::forward(arg2), 263 | std::forward(args)...) { 264 | static_assert(sizeof(*this) == sizeof(MockClass), 265 | "The impl subclass shouldn't introduce any padding"); 266 | } 267 | 268 | private: 269 | StrictMock(const StrictMock&) = delete; 270 | StrictMock& operator=(const StrictMock&) = delete; 271 | }; 272 | 273 | #undef GTEST_INTERNAL_EMPTY_BASE_CLASS 274 | 275 | } // namespace testing 276 | 277 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 278 | -------------------------------------------------------------------------------- /include/gmock/gmock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Google Mock - a framework for writing C++ mock classes. 31 | // 32 | // This is the main header file a user should include. 33 | 34 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 35 | #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 36 | 37 | // This file implements the following syntax: 38 | // 39 | // ON_CALL(mock_object, Method(...)) 40 | // .With(...) ? 41 | // .WillByDefault(...); 42 | // 43 | // where With() is optional and WillByDefault() must appear exactly 44 | // once. 45 | // 46 | // EXPECT_CALL(mock_object, Method(...)) 47 | // .With(...) ? 48 | // .Times(...) ? 49 | // .InSequence(...) * 50 | // .WillOnce(...) * 51 | // .WillRepeatedly(...) ? 52 | // .RetiresOnSaturation() ? ; 53 | // 54 | // where all clauses are optional and WillOnce() can be repeated. 55 | 56 | #include "gmock/gmock-actions.h" 57 | #include "gmock/gmock-cardinalities.h" 58 | #include "gmock/gmock-function-mocker.h" 59 | #include "gmock/gmock-matchers.h" 60 | #include "gmock/gmock-more-actions.h" 61 | #include "gmock/gmock-more-matchers.h" 62 | #include "gmock/gmock-nice-strict.h" 63 | #include "gmock/internal/gmock-internal-utils.h" 64 | #include "gmock/internal/gmock-port.h" 65 | 66 | // Declares Google Mock flags that we want a user to use programmatically. 67 | GMOCK_DECLARE_bool_(catch_leaked_mocks); 68 | GMOCK_DECLARE_string_(verbose); 69 | GMOCK_DECLARE_int32_(default_mock_behavior); 70 | 71 | namespace testing { 72 | 73 | // Initializes Google Mock. This must be called before running the 74 | // tests. In particular, it parses the command line for the flags 75 | // that Google Mock recognizes. Whenever a Google Mock flag is seen, 76 | // it is removed from argv, and *argc is decremented. 77 | // 78 | // No value is returned. Instead, the Google Mock flag variables are 79 | // updated. 80 | // 81 | // Since Google Test is needed for Google Mock to work, this function 82 | // also initializes Google Test and parses its flags, if that hasn't 83 | // been done. 84 | GTEST_API_ void InitGoogleMock(int* argc, char** argv); 85 | 86 | // This overloaded version can be used in Windows programs compiled in 87 | // UNICODE mode. 88 | GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); 89 | 90 | // This overloaded version can be used on Arduino/embedded platforms where 91 | // there is no argc/argv. 92 | GTEST_API_ void InitGoogleMock(); 93 | 94 | } // namespace testing 95 | 96 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ 97 | -------------------------------------------------------------------------------- /include/gmock/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gmock-port.h` 6 | 7 | The following macros can be defined: 8 | 9 | ### Flag related macros: 10 | 11 | * `GMOCK_DECLARE_bool_(name)` 12 | * `GMOCK_DECLARE_int32_(name)` 13 | * `GMOCK_DECLARE_string_(name)` 14 | * `GMOCK_DEFINE_bool_(name, default_val, doc)` 15 | * `GMOCK_DEFINE_int32_(name, default_val, doc)` 16 | * `GMOCK_DEFINE_string_(name, default_val, doc)` 17 | * `GMOCK_FLAG_GET(flag_name)` 18 | * `GMOCK_FLAG_SET(flag_name, value)` 19 | -------------------------------------------------------------------------------- /include/gmock/internal/custom/gmock-generated-actions.h: -------------------------------------------------------------------------------- 1 | // IWYU pragma: private, include "gmock/gmock.h" 2 | // IWYU pragma: friend gmock/.* 3 | 4 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 5 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 6 | 7 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ 8 | -------------------------------------------------------------------------------- /include/gmock/internal/custom/gmock-matchers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Injection point for custom user configurations. See README for details 31 | 32 | // IWYU pragma: private, include "gmock/gmock.h" 33 | // IWYU pragma: friend gmock/.* 34 | 35 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 36 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 37 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ 38 | -------------------------------------------------------------------------------- /include/gmock/internal/custom/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | // IWYU pragma: private, include "gmock/gmock.h" 35 | // IWYU pragma: friend gmock/.* 36 | 37 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 38 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 39 | 40 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ 41 | -------------------------------------------------------------------------------- /include/gmock/internal/gmock-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Low-level types and utilities for porting Google Mock to various 31 | // platforms. All macros ending with _ and symbols defined in an 32 | // internal namespace are subject to change without notice. Code 33 | // outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't 34 | // end with _ are part of Google Mock's public API and can be used by 35 | // code outside Google Mock. 36 | 37 | // IWYU pragma: private, include "gmock/gmock.h" 38 | // IWYU pragma: friend gmock/.* 39 | 40 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 41 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | // Most of the utilities needed for porting Google Mock are also 49 | // required for Google Test and are defined in gtest-port.h. 50 | // 51 | // Note to maintainers: to reduce code duplication, prefer adding 52 | // portability utilities to Google Test's gtest-port.h instead of 53 | // here, as Google Mock depends on Google Test. Only add a utility 54 | // here if it's truly specific to Google Mock. 55 | 56 | #include "gmock/internal/custom/gmock-port.h" 57 | #include "gtest/internal/gtest-port.h" 58 | 59 | #if GTEST_HAS_ABSL 60 | #include "absl/flags/declare.h" 61 | #include "absl/flags/flag.h" 62 | #endif 63 | 64 | // For MS Visual C++, check the compiler version. At least VS 2015 is 65 | // required to compile Google Mock. 66 | #if defined(_MSC_VER) && _MSC_VER < 1900 67 | #error "At least Visual C++ 2015 (14.0) is required to compile Google Mock." 68 | #endif 69 | 70 | // Macro for referencing flags. This is public as we want the user to 71 | // use this syntax to reference Google Mock flags. 72 | #define GMOCK_FLAG_NAME_(name) gmock_##name 73 | #define GMOCK_FLAG(name) FLAGS_gmock_##name 74 | 75 | // Pick a command line flags implementation. 76 | #if GTEST_HAS_ABSL 77 | 78 | // Macros for defining flags. 79 | #define GMOCK_DEFINE_bool_(name, default_val, doc) \ 80 | ABSL_FLAG(bool, GMOCK_FLAG_NAME_(name), default_val, doc) 81 | #define GMOCK_DEFINE_int32_(name, default_val, doc) \ 82 | ABSL_FLAG(int32_t, GMOCK_FLAG_NAME_(name), default_val, doc) 83 | #define GMOCK_DEFINE_string_(name, default_val, doc) \ 84 | ABSL_FLAG(std::string, GMOCK_FLAG_NAME_(name), default_val, doc) 85 | 86 | // Macros for declaring flags. 87 | #define GMOCK_DECLARE_bool_(name) \ 88 | ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name)) 89 | #define GMOCK_DECLARE_int32_(name) \ 90 | ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name)) 91 | #define GMOCK_DECLARE_string_(name) \ 92 | ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name)) 93 | 94 | #define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name)) 95 | #define GMOCK_FLAG_SET(name, value) \ 96 | (void)(::absl::SetFlag(&GMOCK_FLAG(name), value)) 97 | 98 | #else // GTEST_HAS_ABSL 99 | 100 | // Macros for defining flags. 101 | #define GMOCK_DEFINE_bool_(name, default_val, doc) \ 102 | namespace testing { \ 103 | GTEST_API_ bool GMOCK_FLAG(name) = (default_val); \ 104 | } \ 105 | static_assert(true, "no-op to require trailing semicolon") 106 | #define GMOCK_DEFINE_int32_(name, default_val, doc) \ 107 | namespace testing { \ 108 | GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val); \ 109 | } \ 110 | static_assert(true, "no-op to require trailing semicolon") 111 | #define GMOCK_DEFINE_string_(name, default_val, doc) \ 112 | namespace testing { \ 113 | GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val); \ 114 | } \ 115 | static_assert(true, "no-op to require trailing semicolon") 116 | 117 | // Macros for declaring flags. 118 | #define GMOCK_DECLARE_bool_(name) \ 119 | namespace testing { \ 120 | GTEST_API_ extern bool GMOCK_FLAG(name); \ 121 | } \ 122 | static_assert(true, "no-op to require trailing semicolon") 123 | #define GMOCK_DECLARE_int32_(name) \ 124 | namespace testing { \ 125 | GTEST_API_ extern int32_t GMOCK_FLAG(name); \ 126 | } \ 127 | static_assert(true, "no-op to require trailing semicolon") 128 | #define GMOCK_DECLARE_string_(name) \ 129 | namespace testing { \ 130 | GTEST_API_ extern ::std::string GMOCK_FLAG(name); \ 131 | } \ 132 | static_assert(true, "no-op to require trailing semicolon") 133 | 134 | #define GMOCK_FLAG_GET(name) ::testing::GMOCK_FLAG(name) 135 | #define GMOCK_FLAG_SET(name, value) (void)(::testing::GMOCK_FLAG(name) = value) 136 | 137 | #endif // GTEST_HAS_ABSL 138 | 139 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ 140 | -------------------------------------------------------------------------------- /include/gmock/internal/gmock-pp.h: -------------------------------------------------------------------------------- 1 | #ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ 2 | #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ 3 | 4 | // Expands and concatenates the arguments. Constructed macros reevaluate. 5 | #define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2) 6 | 7 | // Expands and stringifies the only argument. 8 | #define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__) 9 | 10 | // Returns empty. Given a variadic number of arguments. 11 | #define GMOCK_PP_EMPTY(...) 12 | 13 | // Returns a comma. Given a variadic number of arguments. 14 | #define GMOCK_PP_COMMA(...) , 15 | 16 | // Returns the only argument. 17 | #define GMOCK_PP_IDENTITY(_1) _1 18 | 19 | // Evaluates to the number of arguments after expansion. 20 | // 21 | // #define PAIR x, y 22 | // 23 | // GMOCK_PP_NARG() => 1 24 | // GMOCK_PP_NARG(x) => 1 25 | // GMOCK_PP_NARG(x, y) => 2 26 | // GMOCK_PP_NARG(PAIR) => 2 27 | // 28 | // Requires: the number of arguments after expansion is at most 15. 29 | #define GMOCK_PP_NARG(...) \ 30 | GMOCK_PP_INTERNAL_16TH( \ 31 | (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) 32 | 33 | // Returns 1 if the expansion of arguments has an unprotected comma. Otherwise 34 | // returns 0. Requires no more than 15 unprotected commas. 35 | #define GMOCK_PP_HAS_COMMA(...) \ 36 | GMOCK_PP_INTERNAL_16TH( \ 37 | (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0)) 38 | 39 | // Returns the first argument. 40 | #define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg)) 41 | 42 | // Returns the tail. A variadic list of all arguments minus the first. Requires 43 | // at least one argument. 44 | #define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__)) 45 | 46 | // Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__) 47 | #define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \ 48 | GMOCK_PP_IDENTITY( \ 49 | GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)) 50 | 51 | // If the arguments after expansion have no tokens, evaluates to `1`. Otherwise 52 | // evaluates to `0`. 53 | // 54 | // Requires: * the number of arguments after expansion is at most 15. 55 | // * If the argument is a macro, it must be able to be called with one 56 | // argument. 57 | // 58 | // Implementation details: 59 | // 60 | // There is one case when it generates a compile error: if the argument is macro 61 | // that cannot be called with one argument. 62 | // 63 | // #define M(a, b) // it doesn't matter what it expands to 64 | // 65 | // // Expected: expands to `0`. 66 | // // Actual: compile error. 67 | // GMOCK_PP_IS_EMPTY(M) 68 | // 69 | // There are 4 cases tested: 70 | // 71 | // * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0. 72 | // * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0. 73 | // * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma. 74 | // Expected 0 75 | // * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in 76 | // parenthesis, or is a macro that ()-evaluates to comma. Expected 1. 77 | // 78 | // We trigger detection on '0001', i.e. on empty. 79 | #define GMOCK_PP_IS_EMPTY(...) \ 80 | GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \ 81 | GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \ 82 | GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \ 83 | GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__())) 84 | 85 | // Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0. 86 | #define GMOCK_PP_IF(_Cond, _Then, _Else) \ 87 | GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else) 88 | 89 | // Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses. 90 | // 91 | // GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c 92 | // GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f 93 | // 94 | #define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \ 95 | GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else)) 96 | 97 | // Evaluates to the number of arguments after expansion. Identifies 'empty' as 98 | // 0. 99 | // 100 | // #define PAIR x, y 101 | // 102 | // GMOCK_PP_NARG0() => 0 103 | // GMOCK_PP_NARG0(x) => 1 104 | // GMOCK_PP_NARG0(x, y) => 2 105 | // GMOCK_PP_NARG0(PAIR) => 2 106 | // 107 | // Requires: * the number of arguments after expansion is at most 15. 108 | // * If the argument is a macro, it must be able to be called with one 109 | // argument. 110 | #define GMOCK_PP_NARG0(...) \ 111 | GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__)) 112 | 113 | // Expands to 1 if the first argument starts with something in parentheses, 114 | // otherwise to 0. 115 | #define GMOCK_PP_IS_BEGIN_PARENS(...) \ 116 | GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \ 117 | GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__)) 118 | 119 | // Expands to 1 is there is only one argument and it is enclosed in parentheses. 120 | #define GMOCK_PP_IS_ENCLOSED_PARENS(...) \ 121 | GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \ 122 | GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0) 123 | 124 | // Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1. 125 | #define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__ 126 | 127 | // Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data, 128 | // eK) as many of GMOCK_INTERNAL_NARG0 _Tuple. 129 | // Requires: * |_Macro| can be called with 3 arguments. 130 | // * |_Tuple| expansion has no more than 15 elements. 131 | #define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \ 132 | GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \ 133 | (0, _Macro, _Data, _Tuple) 134 | 135 | // Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, ) 136 | // Empty if _K = 0. 137 | // Requires: * |_Macro| can be called with 3 arguments. 138 | // * |_K| literal between 0 and 15 139 | #define GMOCK_PP_REPEAT(_Macro, _Data, _N) \ 140 | GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \ 141 | (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE) 142 | 143 | // Increments the argument, requires the argument to be between 0 and 15. 144 | #define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i) 145 | 146 | // Returns comma if _i != 0. Requires _i to be between 0 and 15. 147 | #define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i) 148 | 149 | // Internal details follow. Do not use any of these symbols outside of this 150 | // file or we will break your code. 151 | #define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , ) 152 | #define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2 153 | #define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__ 154 | #define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5 155 | #define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \ 156 | GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \ 157 | _1, _2, _3, _4)) 158 | #define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 , 159 | #define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then 160 | #define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else 161 | 162 | // Because of MSVC treating a token with a comma in it as a single token when 163 | // passed to another macro, we need to force it to evaluate it as multiple 164 | // tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We 165 | // define one per possible macro that relies on this behavior. Note "_Args" must 166 | // be parenthesized. 167 | #define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \ 168 | _10, _11, _12, _13, _14, _15, _16, \ 169 | ...) \ 170 | _16 171 | #define GMOCK_PP_INTERNAL_16TH(_Args) \ 172 | GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args) 173 | #define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1 174 | #define GMOCK_PP_INTERNAL_HEAD(_Args) \ 175 | GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args) 176 | #define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__ 177 | #define GMOCK_PP_INTERNAL_TAIL(_Args) \ 178 | GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args) 179 | 180 | #define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _ 181 | #define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1, 182 | #define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \ 183 | 0, 184 | #define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__ 185 | #define GMOCK_PP_INTERNAL_INC_0 1 186 | #define GMOCK_PP_INTERNAL_INC_1 2 187 | #define GMOCK_PP_INTERNAL_INC_2 3 188 | #define GMOCK_PP_INTERNAL_INC_3 4 189 | #define GMOCK_PP_INTERNAL_INC_4 5 190 | #define GMOCK_PP_INTERNAL_INC_5 6 191 | #define GMOCK_PP_INTERNAL_INC_6 7 192 | #define GMOCK_PP_INTERNAL_INC_7 8 193 | #define GMOCK_PP_INTERNAL_INC_8 9 194 | #define GMOCK_PP_INTERNAL_INC_9 10 195 | #define GMOCK_PP_INTERNAL_INC_10 11 196 | #define GMOCK_PP_INTERNAL_INC_11 12 197 | #define GMOCK_PP_INTERNAL_INC_12 13 198 | #define GMOCK_PP_INTERNAL_INC_13 14 199 | #define GMOCK_PP_INTERNAL_INC_14 15 200 | #define GMOCK_PP_INTERNAL_INC_15 16 201 | #define GMOCK_PP_INTERNAL_COMMA_IF_0 202 | #define GMOCK_PP_INTERNAL_COMMA_IF_1 , 203 | #define GMOCK_PP_INTERNAL_COMMA_IF_2 , 204 | #define GMOCK_PP_INTERNAL_COMMA_IF_3 , 205 | #define GMOCK_PP_INTERNAL_COMMA_IF_4 , 206 | #define GMOCK_PP_INTERNAL_COMMA_IF_5 , 207 | #define GMOCK_PP_INTERNAL_COMMA_IF_6 , 208 | #define GMOCK_PP_INTERNAL_COMMA_IF_7 , 209 | #define GMOCK_PP_INTERNAL_COMMA_IF_8 , 210 | #define GMOCK_PP_INTERNAL_COMMA_IF_9 , 211 | #define GMOCK_PP_INTERNAL_COMMA_IF_10 , 212 | #define GMOCK_PP_INTERNAL_COMMA_IF_11 , 213 | #define GMOCK_PP_INTERNAL_COMMA_IF_12 , 214 | #define GMOCK_PP_INTERNAL_COMMA_IF_13 , 215 | #define GMOCK_PP_INTERNAL_COMMA_IF_14 , 216 | #define GMOCK_PP_INTERNAL_COMMA_IF_15 , 217 | #define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \ 218 | _Macro(_i, _Data, _element) 219 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple) 220 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \ 221 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) 222 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \ 223 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 224 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \ 225 | (GMOCK_PP_TAIL _Tuple)) 226 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \ 227 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 228 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \ 229 | (GMOCK_PP_TAIL _Tuple)) 230 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \ 231 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 232 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \ 233 | (GMOCK_PP_TAIL _Tuple)) 234 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \ 235 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 236 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \ 237 | (GMOCK_PP_TAIL _Tuple)) 238 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \ 239 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 240 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \ 241 | (GMOCK_PP_TAIL _Tuple)) 242 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \ 243 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 244 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \ 245 | (GMOCK_PP_TAIL _Tuple)) 246 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \ 247 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 248 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \ 249 | (GMOCK_PP_TAIL _Tuple)) 250 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \ 251 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 252 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \ 253 | (GMOCK_PP_TAIL _Tuple)) 254 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \ 255 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 256 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \ 257 | (GMOCK_PP_TAIL _Tuple)) 258 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \ 259 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 260 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \ 261 | (GMOCK_PP_TAIL _Tuple)) 262 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \ 263 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 264 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \ 265 | (GMOCK_PP_TAIL _Tuple)) 266 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \ 267 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 268 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \ 269 | (GMOCK_PP_TAIL _Tuple)) 270 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \ 271 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 272 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \ 273 | (GMOCK_PP_TAIL _Tuple)) 274 | #define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \ 275 | GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ 276 | GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \ 277 | (GMOCK_PP_TAIL _Tuple)) 278 | 279 | #endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ 280 | -------------------------------------------------------------------------------- /include/gtest/gtest-assertion-result.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This file implements the AssertionResult type. 33 | 34 | // IWYU pragma: private, include "gtest/gtest.h" 35 | // IWYU pragma: friend gtest/.* 36 | // IWYU pragma: friend gmock/.* 37 | 38 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ 39 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "gtest/gtest-message.h" 47 | #include "gtest/internal/gtest-port.h" 48 | 49 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 50 | /* class A needs to have dll-interface to be used by clients of class B */) 51 | 52 | namespace testing { 53 | 54 | // A class for indicating whether an assertion was successful. When 55 | // the assertion wasn't successful, the AssertionResult object 56 | // remembers a non-empty message that describes how it failed. 57 | // 58 | // To create an instance of this class, use one of the factory functions 59 | // (AssertionSuccess() and AssertionFailure()). 60 | // 61 | // This class is useful for two purposes: 62 | // 1. Defining predicate functions to be used with Boolean test assertions 63 | // EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts 64 | // 2. Defining predicate-format functions to be 65 | // used with predicate assertions (ASSERT_PRED_FORMAT*, etc). 66 | // 67 | // For example, if you define IsEven predicate: 68 | // 69 | // testing::AssertionResult IsEven(int n) { 70 | // if ((n % 2) == 0) 71 | // return testing::AssertionSuccess(); 72 | // else 73 | // return testing::AssertionFailure() << n << " is odd"; 74 | // } 75 | // 76 | // Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) 77 | // will print the message 78 | // 79 | // Value of: IsEven(Fib(5)) 80 | // Actual: false (5 is odd) 81 | // Expected: true 82 | // 83 | // instead of a more opaque 84 | // 85 | // Value of: IsEven(Fib(5)) 86 | // Actual: false 87 | // Expected: true 88 | // 89 | // in case IsEven is a simple Boolean predicate. 90 | // 91 | // If you expect your predicate to be reused and want to support informative 92 | // messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up 93 | // about half as often as positive ones in our tests), supply messages for 94 | // both success and failure cases: 95 | // 96 | // testing::AssertionResult IsEven(int n) { 97 | // if ((n % 2) == 0) 98 | // return testing::AssertionSuccess() << n << " is even"; 99 | // else 100 | // return testing::AssertionFailure() << n << " is odd"; 101 | // } 102 | // 103 | // Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print 104 | // 105 | // Value of: IsEven(Fib(6)) 106 | // Actual: true (8 is even) 107 | // Expected: false 108 | // 109 | // NB: Predicates that support negative Boolean assertions have reduced 110 | // performance in positive ones so be careful not to use them in tests 111 | // that have lots (tens of thousands) of positive Boolean assertions. 112 | // 113 | // To use this class with EXPECT_PRED_FORMAT assertions such as: 114 | // 115 | // // Verifies that Foo() returns an even number. 116 | // EXPECT_PRED_FORMAT1(IsEven, Foo()); 117 | // 118 | // you need to define: 119 | // 120 | // testing::AssertionResult IsEven(const char* expr, int n) { 121 | // if ((n % 2) == 0) 122 | // return testing::AssertionSuccess(); 123 | // else 124 | // return testing::AssertionFailure() 125 | // << "Expected: " << expr << " is even\n Actual: it's " << n; 126 | // } 127 | // 128 | // If Foo() returns 5, you will see the following message: 129 | // 130 | // Expected: Foo() is even 131 | // Actual: it's 5 132 | // 133 | class GTEST_API_ AssertionResult { 134 | public: 135 | // Copy constructor. 136 | // Used in EXPECT_TRUE/FALSE(assertion_result). 137 | AssertionResult(const AssertionResult& other); 138 | 139 | // C4800 is a level 3 warning in Visual Studio 2015 and earlier. 140 | // This warning is not emitted in Visual Studio 2017. 141 | // This warning is off by default starting in Visual Studio 2019 but can be 142 | // enabled with command-line options. 143 | #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) 144 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) 145 | #endif 146 | 147 | // Used in the EXPECT_TRUE/FALSE(bool_expression). 148 | // 149 | // T must be contextually convertible to bool. 150 | // 151 | // The second parameter prevents this overload from being considered if 152 | // the argument is implicitly convertible to AssertionResult. In that case 153 | // we want AssertionResult's copy constructor to be used. 154 | template 155 | explicit AssertionResult( 156 | const T& success, 157 | typename std::enable_if< 158 | !std::is_convertible::value>::type* 159 | /*enabler*/ 160 | = nullptr) 161 | : success_(success) {} 162 | 163 | #if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920) 164 | GTEST_DISABLE_MSC_WARNINGS_POP_() 165 | #endif 166 | 167 | // Assignment operator. 168 | AssertionResult& operator=(AssertionResult other) { 169 | swap(other); 170 | return *this; 171 | } 172 | 173 | // Returns true if and only if the assertion succeeded. 174 | operator bool() const { return success_; } // NOLINT 175 | 176 | // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. 177 | AssertionResult operator!() const; 178 | 179 | // Returns the text streamed into this AssertionResult. Test assertions 180 | // use it when they fail (i.e., the predicate's outcome doesn't match the 181 | // assertion's expectation). When nothing has been streamed into the 182 | // object, returns an empty string. 183 | const char* message() const { 184 | return message_.get() != nullptr ? message_->c_str() : ""; 185 | } 186 | // Deprecated; please use message() instead. 187 | const char* failure_message() const { return message(); } 188 | 189 | // Streams a custom failure message into this object. 190 | template 191 | AssertionResult& operator<<(const T& value) { 192 | AppendMessage(Message() << value); 193 | return *this; 194 | } 195 | 196 | // Allows streaming basic output manipulators such as endl or flush into 197 | // this object. 198 | AssertionResult& operator<<( 199 | ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { 200 | AppendMessage(Message() << basic_manipulator); 201 | return *this; 202 | } 203 | 204 | private: 205 | // Appends the contents of message to message_. 206 | void AppendMessage(const Message& a_message) { 207 | if (message_.get() == nullptr) message_.reset(new ::std::string); 208 | message_->append(a_message.GetString().c_str()); 209 | } 210 | 211 | // Swap the contents of this AssertionResult with other. 212 | void swap(AssertionResult& other); 213 | 214 | // Stores result of the assertion predicate. 215 | bool success_; 216 | // Stores the message describing the condition in case the expectation 217 | // construct is not satisfied with the predicate's outcome. 218 | // Referenced via a pointer to avoid taking too much stack frame space 219 | // with test assertions. 220 | std::unique_ptr< ::std::string> message_; 221 | }; 222 | 223 | // Makes a successful assertion result. 224 | GTEST_API_ AssertionResult AssertionSuccess(); 225 | 226 | // Makes a failed assertion result. 227 | GTEST_API_ AssertionResult AssertionFailure(); 228 | 229 | // Makes a failed assertion result with the given failure message. 230 | // Deprecated; use AssertionFailure() << msg. 231 | GTEST_API_ AssertionResult AssertionFailure(const Message& msg); 232 | 233 | } // namespace testing 234 | 235 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 236 | 237 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_ 238 | -------------------------------------------------------------------------------- /include/gtest/gtest-message.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines the Message class. 33 | // 34 | // IMPORTANT NOTE: Due to limitation of the C++ language, we have to 35 | // leave some internal implementation details in this header file. 36 | // They are clearly marked by comments like this: 37 | // 38 | // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 39 | // 40 | // Such code is NOT meant to be used by a user directly, and is subject 41 | // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user 42 | // program! 43 | 44 | // IWYU pragma: private, include "gtest/gtest.h" 45 | // IWYU pragma: friend gtest/.* 46 | // IWYU pragma: friend gmock/.* 47 | 48 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 49 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 50 | 51 | #include 52 | #include 53 | #include 54 | 55 | #include "gtest/internal/gtest-port.h" 56 | 57 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 58 | /* class A needs to have dll-interface to be used by clients of class B */) 59 | 60 | // Ensures that there is at least one operator<< in the global namespace. 61 | // See Message& operator<<(...) below for why. 62 | void operator<<(const testing::internal::Secret&, int); 63 | 64 | namespace testing { 65 | 66 | // The Message class works like an ostream repeater. 67 | // 68 | // Typical usage: 69 | // 70 | // 1. You stream a bunch of values to a Message object. 71 | // It will remember the text in a stringstream. 72 | // 2. Then you stream the Message object to an ostream. 73 | // This causes the text in the Message to be streamed 74 | // to the ostream. 75 | // 76 | // For example; 77 | // 78 | // testing::Message foo; 79 | // foo << 1 << " != " << 2; 80 | // std::cout << foo; 81 | // 82 | // will print "1 != 2". 83 | // 84 | // Message is not intended to be inherited from. In particular, its 85 | // destructor is not virtual. 86 | // 87 | // Note that stringstream behaves differently in gcc and in MSVC. You 88 | // can stream a NULL char pointer to it in the former, but not in the 89 | // latter (it causes an access violation if you do). The Message 90 | // class hides this difference by treating a NULL char pointer as 91 | // "(null)". 92 | class GTEST_API_ Message { 93 | private: 94 | // The type of basic IO manipulators (endl, ends, and flush) for 95 | // narrow streams. 96 | typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); 97 | 98 | public: 99 | // Constructs an empty Message. 100 | Message(); 101 | 102 | // Copy constructor. 103 | Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT 104 | *ss_ << msg.GetString(); 105 | } 106 | 107 | // Constructs a Message from a C-string. 108 | explicit Message(const char* str) : ss_(new ::std::stringstream) { 109 | *ss_ << str; 110 | } 111 | 112 | // Streams a non-pointer value to this object. 113 | template 114 | inline Message& operator<<(const T& val) { 115 | // Some libraries overload << for STL containers. These 116 | // overloads are defined in the global namespace instead of ::std. 117 | // 118 | // C++'s symbol lookup rule (i.e. Koenig lookup) says that these 119 | // overloads are visible in either the std namespace or the global 120 | // namespace, but not other namespaces, including the testing 121 | // namespace which Google Test's Message class is in. 122 | // 123 | // To allow STL containers (and other types that has a << operator 124 | // defined in the global namespace) to be used in Google Test 125 | // assertions, testing::Message must access the custom << operator 126 | // from the global namespace. With this using declaration, 127 | // overloads of << defined in the global namespace and those 128 | // visible via Koenig lookup are both exposed in this function. 129 | using ::operator<<; 130 | *ss_ << val; 131 | return *this; 132 | } 133 | 134 | // Streams a pointer value to this object. 135 | // 136 | // This function is an overload of the previous one. When you 137 | // stream a pointer to a Message, this definition will be used as it 138 | // is more specialized. (The C++ Standard, section 139 | // [temp.func.order].) If you stream a non-pointer, then the 140 | // previous definition will be used. 141 | // 142 | // The reason for this overload is that streaming a NULL pointer to 143 | // ostream is undefined behavior. Depending on the compiler, you 144 | // may get "0", "(nil)", "(null)", or an access violation. To 145 | // ensure consistent result across compilers, we always treat NULL 146 | // as "(null)". 147 | template 148 | inline Message& operator<<(T* const& pointer) { // NOLINT 149 | if (pointer == nullptr) { 150 | *ss_ << "(null)"; 151 | } else { 152 | *ss_ << pointer; 153 | } 154 | return *this; 155 | } 156 | 157 | // Since the basic IO manipulators are overloaded for both narrow 158 | // and wide streams, we have to provide this specialized definition 159 | // of operator <<, even though its body is the same as the 160 | // templatized version above. Without this definition, streaming 161 | // endl or other basic IO manipulators to Message will confuse the 162 | // compiler. 163 | Message& operator<<(BasicNarrowIoManip val) { 164 | *ss_ << val; 165 | return *this; 166 | } 167 | 168 | // Instead of 1/0, we want to see true/false for bool values. 169 | Message& operator<<(bool b) { return *this << (b ? "true" : "false"); } 170 | 171 | // These two overloads allow streaming a wide C string to a Message 172 | // using the UTF-8 encoding. 173 | Message& operator<<(const wchar_t* wide_c_str); 174 | Message& operator<<(wchar_t* wide_c_str); 175 | 176 | #if GTEST_HAS_STD_WSTRING 177 | // Converts the given wide string to a narrow string using the UTF-8 178 | // encoding, and streams the result to this Message object. 179 | Message& operator<<(const ::std::wstring& wstr); 180 | #endif // GTEST_HAS_STD_WSTRING 181 | 182 | // Gets the text streamed to this object so far as an std::string. 183 | // Each '\0' character in the buffer is replaced with "\\0". 184 | // 185 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 186 | std::string GetString() const; 187 | 188 | private: 189 | // We'll hold the text streamed to this object here. 190 | const std::unique_ptr< ::std::stringstream> ss_; 191 | 192 | // We declare (but don't implement) this to prevent the compiler 193 | // from implementing the assignment operator. 194 | void operator=(const Message&); 195 | }; 196 | 197 | // Streams a Message to an ostream. 198 | inline std::ostream& operator<<(std::ostream& os, const Message& sb) { 199 | return os << sb.GetString(); 200 | } 201 | 202 | namespace internal { 203 | 204 | // Converts a streamable value to an std::string. A NULL pointer is 205 | // converted to "(null)". When the input value is a ::string, 206 | // ::std::string, ::wstring, or ::std::wstring object, each NUL 207 | // character in it is replaced with "\\0". 208 | template 209 | std::string StreamableToString(const T& streamable) { 210 | return (Message() << streamable).GetString(); 211 | } 212 | 213 | } // namespace internal 214 | } // namespace testing 215 | 216 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 217 | 218 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ 219 | -------------------------------------------------------------------------------- /include/gtest/gtest-spi.h: -------------------------------------------------------------------------------- 1 | // Copyright 2007, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Utilities for testing Google Test itself and code that uses Google Test 31 | // (e.g. frameworks built on top of Google Test). 32 | 33 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ 34 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ 35 | 36 | #include "gtest/gtest.h" 37 | 38 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 39 | /* class A needs to have dll-interface to be used by clients of class B */) 40 | 41 | namespace testing { 42 | 43 | // This helper class can be used to mock out Google Test failure reporting 44 | // so that we can test Google Test or code that builds on Google Test. 45 | // 46 | // An object of this class appends a TestPartResult object to the 47 | // TestPartResultArray object given in the constructor whenever a Google Test 48 | // failure is reported. It can either intercept only failures that are 49 | // generated in the same thread that created this object or it can intercept 50 | // all generated failures. The scope of this mock object can be controlled with 51 | // the second argument to the two arguments constructor. 52 | class GTEST_API_ ScopedFakeTestPartResultReporter 53 | : public TestPartResultReporterInterface { 54 | public: 55 | // The two possible mocking modes of this object. 56 | enum InterceptMode { 57 | INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. 58 | INTERCEPT_ALL_THREADS // Intercepts all failures. 59 | }; 60 | 61 | // The c'tor sets this object as the test part result reporter used 62 | // by Google Test. The 'result' parameter specifies where to report the 63 | // results. This reporter will only catch failures generated in the current 64 | // thread. DEPRECATED 65 | explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); 66 | 67 | // Same as above, but you can choose the interception scope of this object. 68 | ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, 69 | TestPartResultArray* result); 70 | 71 | // The d'tor restores the previous test part result reporter. 72 | ~ScopedFakeTestPartResultReporter() override; 73 | 74 | // Appends the TestPartResult object to the TestPartResultArray 75 | // received in the constructor. 76 | // 77 | // This method is from the TestPartResultReporterInterface 78 | // interface. 79 | void ReportTestPartResult(const TestPartResult& result) override; 80 | 81 | private: 82 | void Init(); 83 | 84 | const InterceptMode intercept_mode_; 85 | TestPartResultReporterInterface* old_reporter_; 86 | TestPartResultArray* const result_; 87 | 88 | ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) = 89 | delete; 90 | ScopedFakeTestPartResultReporter& operator=( 91 | const ScopedFakeTestPartResultReporter&) = delete; 92 | }; 93 | 94 | namespace internal { 95 | 96 | // A helper class for implementing EXPECT_FATAL_FAILURE() and 97 | // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given 98 | // TestPartResultArray contains exactly one failure that has the given 99 | // type and contains the given substring. If that's not the case, a 100 | // non-fatal failure will be generated. 101 | class GTEST_API_ SingleFailureChecker { 102 | public: 103 | // The constructor remembers the arguments. 104 | SingleFailureChecker(const TestPartResultArray* results, 105 | TestPartResult::Type type, const std::string& substr); 106 | ~SingleFailureChecker(); 107 | 108 | private: 109 | const TestPartResultArray* const results_; 110 | const TestPartResult::Type type_; 111 | const std::string substr_; 112 | 113 | SingleFailureChecker(const SingleFailureChecker&) = delete; 114 | SingleFailureChecker& operator=(const SingleFailureChecker&) = delete; 115 | }; 116 | 117 | } // namespace internal 118 | 119 | } // namespace testing 120 | 121 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 122 | 123 | // A set of macros for testing Google Test assertions or code that's expected 124 | // to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but 125 | // not a non-fatal failure, as from EXPECT_EQ). It verifies that the given 126 | // statement will cause exactly one fatal Google Test failure with 'substr' 127 | // being part of the failure message. 128 | // 129 | // There are two different versions of this macro. EXPECT_FATAL_FAILURE only 130 | // affects and considers failures generated in the current thread and 131 | // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. 132 | // 133 | // The verification of the assertion is done correctly even when the statement 134 | // throws an exception or aborts the current function. 135 | // 136 | // Known restrictions: 137 | // - 'statement' cannot reference local non-static variables or 138 | // non-static members of the current object. 139 | // - 'statement' cannot return a value. 140 | // - You cannot stream a failure message to this macro. 141 | // 142 | // Note that even though the implementations of the following two 143 | // macros are much alike, we cannot refactor them to use a common 144 | // helper macro, due to some peculiarity in how the preprocessor 145 | // works. The AcceptsMacroThatExpandsToUnprotectedComma test in 146 | // gtest_unittest.cc will fail to compile if we do that. 147 | #define EXPECT_FATAL_FAILURE(statement, substr) \ 148 | do { \ 149 | class GTestExpectFatalFailureHelper { \ 150 | public: \ 151 | static void Execute() { statement; } \ 152 | }; \ 153 | ::testing::TestPartResultArray gtest_failures; \ 154 | ::testing::internal::SingleFailureChecker gtest_checker( \ 155 | >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ 156 | { \ 157 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ 158 | ::testing::ScopedFakeTestPartResultReporter:: \ 159 | INTERCEPT_ONLY_CURRENT_THREAD, \ 160 | >est_failures); \ 161 | GTestExpectFatalFailureHelper::Execute(); \ 162 | } \ 163 | } while (::testing::internal::AlwaysFalse()) 164 | 165 | #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ 166 | do { \ 167 | class GTestExpectFatalFailureHelper { \ 168 | public: \ 169 | static void Execute() { statement; } \ 170 | }; \ 171 | ::testing::TestPartResultArray gtest_failures; \ 172 | ::testing::internal::SingleFailureChecker gtest_checker( \ 173 | >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ 174 | { \ 175 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ 176 | ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ 177 | >est_failures); \ 178 | GTestExpectFatalFailureHelper::Execute(); \ 179 | } \ 180 | } while (::testing::internal::AlwaysFalse()) 181 | 182 | // A macro for testing Google Test assertions or code that's expected to 183 | // generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ, 184 | // but not from an ASSERT_EQ). It asserts that the given statement will cause 185 | // exactly one non-fatal Google Test failure with 'substr' being part of the 186 | // failure message. 187 | // 188 | // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only 189 | // affects and considers failures generated in the current thread and 190 | // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. 191 | // 192 | // 'statement' is allowed to reference local variables and members of 193 | // the current object. 194 | // 195 | // The verification of the assertion is done correctly even when the statement 196 | // throws an exception or aborts the current function. 197 | // 198 | // Known restrictions: 199 | // - You cannot stream a failure message to this macro. 200 | // 201 | // Note that even though the implementations of the following two 202 | // macros are much alike, we cannot refactor them to use a common 203 | // helper macro, due to some peculiarity in how the preprocessor 204 | // works. If we do that, the code won't compile when the user gives 205 | // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that 206 | // expands to code containing an unprotected comma. The 207 | // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc 208 | // catches that. 209 | // 210 | // For the same reason, we have to write 211 | // if (::testing::internal::AlwaysTrue()) { statement; } 212 | // instead of 213 | // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) 214 | // to avoid an MSVC warning on unreachable code. 215 | #define EXPECT_NONFATAL_FAILURE(statement, substr) \ 216 | do { \ 217 | ::testing::TestPartResultArray gtest_failures; \ 218 | ::testing::internal::SingleFailureChecker gtest_checker( \ 219 | >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ 220 | (substr)); \ 221 | { \ 222 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ 223 | ::testing::ScopedFakeTestPartResultReporter:: \ 224 | INTERCEPT_ONLY_CURRENT_THREAD, \ 225 | >est_failures); \ 226 | if (::testing::internal::AlwaysTrue()) { \ 227 | statement; \ 228 | } \ 229 | } \ 230 | } while (::testing::internal::AlwaysFalse()) 231 | 232 | #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ 233 | do { \ 234 | ::testing::TestPartResultArray gtest_failures; \ 235 | ::testing::internal::SingleFailureChecker gtest_checker( \ 236 | >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ 237 | (substr)); \ 238 | { \ 239 | ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ 240 | ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ 241 | >est_failures); \ 242 | if (::testing::internal::AlwaysTrue()) { \ 243 | statement; \ 244 | } \ 245 | } \ 246 | } while (::testing::internal::AlwaysFalse()) 247 | 248 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ 249 | -------------------------------------------------------------------------------- /include/gtest/gtest-test-part.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // IWYU pragma: private, include "gtest/gtest.h" 31 | // IWYU pragma: friend gtest/.* 32 | // IWYU pragma: friend gmock/.* 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 36 | 37 | #include 38 | #include 39 | 40 | #include "gtest/internal/gtest-internal.h" 41 | #include "gtest/internal/gtest-string.h" 42 | 43 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 44 | /* class A needs to have dll-interface to be used by clients of class B */) 45 | 46 | namespace testing { 47 | 48 | // A copyable object representing the result of a test part (i.e. an 49 | // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). 50 | // 51 | // Don't inherit from TestPartResult as its destructor is not virtual. 52 | class GTEST_API_ TestPartResult { 53 | public: 54 | // The possible outcomes of a test part (i.e. an assertion or an 55 | // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). 56 | enum Type { 57 | kSuccess, // Succeeded. 58 | kNonFatalFailure, // Failed but the test can continue. 59 | kFatalFailure, // Failed and the test should be terminated. 60 | kSkip // Skipped. 61 | }; 62 | 63 | // C'tor. TestPartResult does NOT have a default constructor. 64 | // Always use this constructor (with parameters) to create a 65 | // TestPartResult object. 66 | TestPartResult(Type a_type, const char* a_file_name, int a_line_number, 67 | const char* a_message) 68 | : type_(a_type), 69 | file_name_(a_file_name == nullptr ? "" : a_file_name), 70 | line_number_(a_line_number), 71 | summary_(ExtractSummary(a_message)), 72 | message_(a_message) {} 73 | 74 | // Gets the outcome of the test part. 75 | Type type() const { return type_; } 76 | 77 | // Gets the name of the source file where the test part took place, or 78 | // NULL if it's unknown. 79 | const char* file_name() const { 80 | return file_name_.empty() ? nullptr : file_name_.c_str(); 81 | } 82 | 83 | // Gets the line in the source file where the test part took place, 84 | // or -1 if it's unknown. 85 | int line_number() const { return line_number_; } 86 | 87 | // Gets the summary of the failure message. 88 | const char* summary() const { return summary_.c_str(); } 89 | 90 | // Gets the message associated with the test part. 91 | const char* message() const { return message_.c_str(); } 92 | 93 | // Returns true if and only if the test part was skipped. 94 | bool skipped() const { return type_ == kSkip; } 95 | 96 | // Returns true if and only if the test part passed. 97 | bool passed() const { return type_ == kSuccess; } 98 | 99 | // Returns true if and only if the test part non-fatally failed. 100 | bool nonfatally_failed() const { return type_ == kNonFatalFailure; } 101 | 102 | // Returns true if and only if the test part fatally failed. 103 | bool fatally_failed() const { return type_ == kFatalFailure; } 104 | 105 | // Returns true if and only if the test part failed. 106 | bool failed() const { return fatally_failed() || nonfatally_failed(); } 107 | 108 | private: 109 | Type type_; 110 | 111 | // Gets the summary of the failure message by omitting the stack 112 | // trace in it. 113 | static std::string ExtractSummary(const char* message); 114 | 115 | // The name of the source file where the test part took place, or 116 | // "" if the source file is unknown. 117 | std::string file_name_; 118 | // The line in the source file where the test part took place, or -1 119 | // if the line number is unknown. 120 | int line_number_; 121 | std::string summary_; // The test failure summary. 122 | std::string message_; // The test failure message. 123 | }; 124 | 125 | // Prints a TestPartResult object. 126 | std::ostream& operator<<(std::ostream& os, const TestPartResult& result); 127 | 128 | // An array of TestPartResult objects. 129 | // 130 | // Don't inherit from TestPartResultArray as its destructor is not 131 | // virtual. 132 | class GTEST_API_ TestPartResultArray { 133 | public: 134 | TestPartResultArray() {} 135 | 136 | // Appends the given TestPartResult to the array. 137 | void Append(const TestPartResult& result); 138 | 139 | // Returns the TestPartResult at the given index (0-based). 140 | const TestPartResult& GetTestPartResult(int index) const; 141 | 142 | // Returns the number of TestPartResult objects in the array. 143 | int size() const; 144 | 145 | private: 146 | std::vector array_; 147 | 148 | TestPartResultArray(const TestPartResultArray&) = delete; 149 | TestPartResultArray& operator=(const TestPartResultArray&) = delete; 150 | }; 151 | 152 | // This interface knows how to report a test part result. 153 | class GTEST_API_ TestPartResultReporterInterface { 154 | public: 155 | virtual ~TestPartResultReporterInterface() {} 156 | 157 | virtual void ReportTestPartResult(const TestPartResult& result) = 0; 158 | }; 159 | 160 | namespace internal { 161 | 162 | // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a 163 | // statement generates new fatal failures. To do so it registers itself as the 164 | // current test part result reporter. Besides checking if fatal failures were 165 | // reported, it only delegates the reporting to the former result reporter. 166 | // The original result reporter is restored in the destructor. 167 | // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. 168 | class GTEST_API_ HasNewFatalFailureHelper 169 | : public TestPartResultReporterInterface { 170 | public: 171 | HasNewFatalFailureHelper(); 172 | ~HasNewFatalFailureHelper() override; 173 | void ReportTestPartResult(const TestPartResult& result) override; 174 | bool has_new_fatal_failure() const { return has_new_fatal_failure_; } 175 | 176 | private: 177 | bool has_new_fatal_failure_; 178 | TestPartResultReporterInterface* original_reporter_; 179 | 180 | HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete; 181 | HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete; 182 | }; 183 | 184 | } // namespace internal 185 | 186 | } // namespace testing 187 | 188 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 189 | 190 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ 191 | -------------------------------------------------------------------------------- /include/gtest/gtest_pred_impl.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Implements a family of generic predicate assertion macros. 31 | 32 | // IWYU pragma: private, include "gtest/gtest.h" 33 | // IWYU pragma: friend gtest/.* 34 | // IWYU pragma: friend gmock/.* 35 | 36 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ 37 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ 38 | 39 | #include "gtest/gtest-assertion-result.h" 40 | #include "gtest/internal/gtest-internal.h" 41 | #include "gtest/internal/gtest-port.h" 42 | 43 | namespace testing { 44 | 45 | // This header implements a family of generic predicate assertion 46 | // macros: 47 | // 48 | // ASSERT_PRED_FORMAT1(pred_format, v1) 49 | // ASSERT_PRED_FORMAT2(pred_format, v1, v2) 50 | // ... 51 | // 52 | // where pred_format is a function or functor that takes n (in the 53 | // case of ASSERT_PRED_FORMATn) values and their source expression 54 | // text, and returns a testing::AssertionResult. See the definition 55 | // of ASSERT_EQ in gtest.h for an example. 56 | // 57 | // If you don't care about formatting, you can use the more 58 | // restrictive version: 59 | // 60 | // ASSERT_PRED1(pred, v1) 61 | // ASSERT_PRED2(pred, v1, v2) 62 | // ... 63 | // 64 | // where pred is an n-ary function or functor that returns bool, 65 | // and the values v1, v2, ..., must support the << operator for 66 | // streaming to std::ostream. 67 | // 68 | // We also define the EXPECT_* variations. 69 | // 70 | // For now we only support predicates whose arity is at most 5. 71 | // Please email googletestframework@googlegroups.com if you need 72 | // support for higher arities. 73 | 74 | // GTEST_ASSERT_ is the basic statement to which all of the assertions 75 | // in this file reduce. Don't use this in your code. 76 | 77 | #define GTEST_ASSERT_(expression, on_failure) \ 78 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ 79 | if (const ::testing::AssertionResult gtest_ar = (expression)) \ 80 | ; \ 81 | else \ 82 | on_failure(gtest_ar.failure_message()) 83 | 84 | // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use 85 | // this in your code. 86 | template 87 | AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, 88 | Pred pred, const T1& v1) { 89 | if (pred(v1)) return AssertionSuccess(); 90 | 91 | return AssertionFailure() 92 | << pred_text << "(" << e1 << ") evaluates to false, where" 93 | << "\n" 94 | << e1 << " evaluates to " << ::testing::PrintToString(v1); 95 | } 96 | 97 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. 98 | // Don't use this in your code. 99 | #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \ 100 | GTEST_ASSERT_(pred_format(#v1, v1), on_failure) 101 | 102 | // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use 103 | // this in your code. 104 | #define GTEST_PRED1_(pred, v1, on_failure) \ 105 | GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure) 106 | 107 | // Unary predicate assertion macros. 108 | #define EXPECT_PRED_FORMAT1(pred_format, v1) \ 109 | GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) 110 | #define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) 111 | #define ASSERT_PRED_FORMAT1(pred_format, v1) \ 112 | GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) 113 | #define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) 114 | 115 | // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use 116 | // this in your code. 117 | template 118 | AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, 119 | const char* e2, Pred pred, const T1& v1, 120 | const T2& v2) { 121 | if (pred(v1, v2)) return AssertionSuccess(); 122 | 123 | return AssertionFailure() 124 | << pred_text << "(" << e1 << ", " << e2 125 | << ") evaluates to false, where" 126 | << "\n" 127 | << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" 128 | << e2 << " evaluates to " << ::testing::PrintToString(v2); 129 | } 130 | 131 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. 132 | // Don't use this in your code. 133 | #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \ 134 | GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure) 135 | 136 | // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use 137 | // this in your code. 138 | #define GTEST_PRED2_(pred, v1, v2, on_failure) \ 139 | GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \ 140 | on_failure) 141 | 142 | // Binary predicate assertion macros. 143 | #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ 144 | GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) 145 | #define EXPECT_PRED2(pred, v1, v2) \ 146 | GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) 147 | #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ 148 | GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) 149 | #define ASSERT_PRED2(pred, v1, v2) \ 150 | GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) 151 | 152 | // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use 153 | // this in your code. 154 | template 155 | AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, 156 | const char* e2, const char* e3, Pred pred, 157 | const T1& v1, const T2& v2, const T3& v3) { 158 | if (pred(v1, v2, v3)) return AssertionSuccess(); 159 | 160 | return AssertionFailure() 161 | << pred_text << "(" << e1 << ", " << e2 << ", " << e3 162 | << ") evaluates to false, where" 163 | << "\n" 164 | << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" 165 | << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" 166 | << e3 << " evaluates to " << ::testing::PrintToString(v3); 167 | } 168 | 169 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. 170 | // Don't use this in your code. 171 | #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \ 172 | GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure) 173 | 174 | // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use 175 | // this in your code. 176 | #define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \ 177 | GTEST_ASSERT_( \ 178 | ::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \ 179 | on_failure) 180 | 181 | // Ternary predicate assertion macros. 182 | #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ 183 | GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) 184 | #define EXPECT_PRED3(pred, v1, v2, v3) \ 185 | GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) 186 | #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ 187 | GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) 188 | #define ASSERT_PRED3(pred, v1, v2, v3) \ 189 | GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) 190 | 191 | // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use 192 | // this in your code. 193 | template 194 | AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, 195 | const char* e2, const char* e3, 196 | const char* e4, Pred pred, const T1& v1, 197 | const T2& v2, const T3& v3, const T4& v4) { 198 | if (pred(v1, v2, v3, v4)) return AssertionSuccess(); 199 | 200 | return AssertionFailure() 201 | << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 202 | << ") evaluates to false, where" 203 | << "\n" 204 | << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" 205 | << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" 206 | << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" 207 | << e4 << " evaluates to " << ::testing::PrintToString(v4); 208 | } 209 | 210 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. 211 | // Don't use this in your code. 212 | #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \ 213 | GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure) 214 | 215 | // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use 216 | // this in your code. 217 | #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \ 218 | GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \ 219 | v1, v2, v3, v4), \ 220 | on_failure) 221 | 222 | // 4-ary predicate assertion macros. 223 | #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ 224 | GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) 225 | #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ 226 | GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) 227 | #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ 228 | GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) 229 | #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ 230 | GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) 231 | 232 | // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use 233 | // this in your code. 234 | template 236 | AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, 237 | const char* e2, const char* e3, 238 | const char* e4, const char* e5, Pred pred, 239 | const T1& v1, const T2& v2, const T3& v3, 240 | const T4& v4, const T5& v5) { 241 | if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); 242 | 243 | return AssertionFailure() 244 | << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 245 | << ", " << e5 << ") evaluates to false, where" 246 | << "\n" 247 | << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n" 248 | << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n" 249 | << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n" 250 | << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n" 251 | << e5 << " evaluates to " << ::testing::PrintToString(v5); 252 | } 253 | 254 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. 255 | // Don't use this in your code. 256 | #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \ 257 | GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ 258 | on_failure) 259 | 260 | // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use 261 | // this in your code. 262 | #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \ 263 | GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \ 264 | pred, v1, v2, v3, v4, v5), \ 265 | on_failure) 266 | 267 | // 5-ary predicate assertion macros. 268 | #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ 269 | GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) 270 | #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ 271 | GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) 272 | #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ 273 | GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) 274 | #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ 275 | GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) 276 | 277 | } // namespace testing 278 | 279 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ 280 | -------------------------------------------------------------------------------- /include/gtest/gtest_prod.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Google C++ Testing and Mocking Framework definitions useful in production 31 | // code. 32 | 33 | #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 34 | #define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 35 | 36 | // When you need to test the private or protected members of a class, 37 | // use the FRIEND_TEST macro to declare your tests as friends of the 38 | // class. For example: 39 | // 40 | // class MyClass { 41 | // private: 42 | // void PrivateMethod(); 43 | // FRIEND_TEST(MyClassTest, PrivateMethodWorks); 44 | // }; 45 | // 46 | // class MyClassTest : public testing::Test { 47 | // // ... 48 | // }; 49 | // 50 | // TEST_F(MyClassTest, PrivateMethodWorks) { 51 | // // Can call MyClass::PrivateMethod() here. 52 | // } 53 | // 54 | // Note: The test class must be in the same namespace as the class being tested. 55 | // For example, putting MyClassTest in an anonymous namespace will not work. 56 | 57 | #define FRIEND_TEST(test_case_name, test_name) \ 58 | friend class test_case_name##_##test_name##_Test 59 | 60 | #endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_ 61 | -------------------------------------------------------------------------------- /include/gtest/internal/custom/README.md: -------------------------------------------------------------------------------- 1 | # Customization Points 2 | 3 | The custom directory is an injection point for custom user configurations. 4 | 5 | ## Header `gtest.h` 6 | 7 | ### The following macros can be defined: 8 | 9 | * `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of 10 | `OsStackTraceGetterInterface`. 11 | * `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See 12 | `testing::TempDir` for semantics and signature. 13 | 14 | ## Header `gtest-port.h` 15 | 16 | The following macros can be defined: 17 | 18 | ### Logging: 19 | 20 | * `GTEST_LOG_(severity)` 21 | * `GTEST_CHECK_(condition)` 22 | * Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too. 23 | 24 | ### Threading: 25 | 26 | * `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided. 27 | * `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal` 28 | are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)` 29 | and `GTEST_DEFINE_STATIC_MUTEX_(mutex)` 30 | * `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)` 31 | * `GTEST_LOCK_EXCLUDED_(locks)` 32 | 33 | ### Underlying library support features 34 | 35 | * `GTEST_HAS_CXXABI_H_` 36 | 37 | ### Exporting API symbols: 38 | 39 | * `GTEST_API_` - Specifier for exported symbols. 40 | 41 | ## Header `gtest-printers.h` 42 | 43 | * See documentation at `gtest/gtest-printers.h` for details on how to define a 44 | custom printer. 45 | -------------------------------------------------------------------------------- /include/gtest/internal/custom/gtest-port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 36 | 37 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ 38 | -------------------------------------------------------------------------------- /include/gtest/internal/custom/gtest-printers.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // This file provides an injection point for custom printers in a local 31 | // installation of gTest. 32 | // It will be included from gtest-printers.h and the overrides in this file 33 | // will be visible to everyone. 34 | // 35 | // Injection point for custom user configurations. See README for details 36 | // 37 | // ** Custom implementation starts here ** 38 | 39 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 40 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 41 | 42 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ 43 | -------------------------------------------------------------------------------- /include/gtest/internal/custom/gtest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | // 30 | // Injection point for custom user configurations. See README for details 31 | // 32 | // ** Custom implementation starts here ** 33 | 34 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 35 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 36 | 37 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ 38 | -------------------------------------------------------------------------------- /include/gtest/internal/gtest-death-test-internal.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines internal utilities needed for implementing 33 | // death tests. They are subject to change without notice. 34 | 35 | // IWYU pragma: private, include "gtest/gtest.h" 36 | // IWYU pragma: friend gtest/.* 37 | // IWYU pragma: friend gmock/.* 38 | 39 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 40 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 41 | 42 | #include 43 | 44 | #include 45 | 46 | #include "gtest/gtest-matchers.h" 47 | #include "gtest/internal/gtest-internal.h" 48 | 49 | GTEST_DECLARE_string_(internal_run_death_test); 50 | 51 | namespace testing { 52 | namespace internal { 53 | 54 | // Names of the flags (needed for parsing Google Test flags). 55 | const char kDeathTestStyleFlag[] = "death_test_style"; 56 | const char kDeathTestUseFork[] = "death_test_use_fork"; 57 | const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; 58 | 59 | #if GTEST_HAS_DEATH_TEST 60 | 61 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 62 | /* class A needs to have dll-interface to be used by clients of class B */) 63 | 64 | // DeathTest is a class that hides much of the complexity of the 65 | // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method 66 | // returns a concrete class that depends on the prevailing death test 67 | // style, as defined by the --gtest_death_test_style and/or 68 | // --gtest_internal_run_death_test flags. 69 | 70 | // In describing the results of death tests, these terms are used with 71 | // the corresponding definitions: 72 | // 73 | // exit status: The integer exit information in the format specified 74 | // by wait(2) 75 | // exit code: The integer code passed to exit(3), _exit(2), or 76 | // returned from main() 77 | class GTEST_API_ DeathTest { 78 | public: 79 | // Create returns false if there was an error determining the 80 | // appropriate action to take for the current death test; for example, 81 | // if the gtest_death_test_style flag is set to an invalid value. 82 | // The LastMessage method will return a more detailed message in that 83 | // case. Otherwise, the DeathTest pointer pointed to by the "test" 84 | // argument is set. If the death test should be skipped, the pointer 85 | // is set to NULL; otherwise, it is set to the address of a new concrete 86 | // DeathTest object that controls the execution of the current test. 87 | static bool Create(const char* statement, Matcher matcher, 88 | const char* file, int line, DeathTest** test); 89 | DeathTest(); 90 | virtual ~DeathTest() {} 91 | 92 | // A helper class that aborts a death test when it's deleted. 93 | class ReturnSentinel { 94 | public: 95 | explicit ReturnSentinel(DeathTest* test) : test_(test) {} 96 | ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } 97 | 98 | private: 99 | DeathTest* const test_; 100 | ReturnSentinel(const ReturnSentinel&) = delete; 101 | ReturnSentinel& operator=(const ReturnSentinel&) = delete; 102 | } GTEST_ATTRIBUTE_UNUSED_; 103 | 104 | // An enumeration of possible roles that may be taken when a death 105 | // test is encountered. EXECUTE means that the death test logic should 106 | // be executed immediately. OVERSEE means that the program should prepare 107 | // the appropriate environment for a child process to execute the death 108 | // test, then wait for it to complete. 109 | enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; 110 | 111 | // An enumeration of the three reasons that a test might be aborted. 112 | enum AbortReason { 113 | TEST_ENCOUNTERED_RETURN_STATEMENT, 114 | TEST_THREW_EXCEPTION, 115 | TEST_DID_NOT_DIE 116 | }; 117 | 118 | // Assumes one of the above roles. 119 | virtual TestRole AssumeRole() = 0; 120 | 121 | // Waits for the death test to finish and returns its status. 122 | virtual int Wait() = 0; 123 | 124 | // Returns true if the death test passed; that is, the test process 125 | // exited during the test, its exit status matches a user-supplied 126 | // predicate, and its stderr output matches a user-supplied regular 127 | // expression. 128 | // The user-supplied predicate may be a macro expression rather 129 | // than a function pointer or functor, or else Wait and Passed could 130 | // be combined. 131 | virtual bool Passed(bool exit_status_ok) = 0; 132 | 133 | // Signals that the death test did not die as expected. 134 | virtual void Abort(AbortReason reason) = 0; 135 | 136 | // Returns a human-readable outcome message regarding the outcome of 137 | // the last death test. 138 | static const char* LastMessage(); 139 | 140 | static void set_last_death_test_message(const std::string& message); 141 | 142 | private: 143 | // A string containing a description of the outcome of the last death test. 144 | static std::string last_death_test_message_; 145 | 146 | DeathTest(const DeathTest&) = delete; 147 | DeathTest& operator=(const DeathTest&) = delete; 148 | }; 149 | 150 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 151 | 152 | // Factory interface for death tests. May be mocked out for testing. 153 | class DeathTestFactory { 154 | public: 155 | virtual ~DeathTestFactory() {} 156 | virtual bool Create(const char* statement, 157 | Matcher matcher, const char* file, 158 | int line, DeathTest** test) = 0; 159 | }; 160 | 161 | // A concrete DeathTestFactory implementation for normal use. 162 | class DefaultDeathTestFactory : public DeathTestFactory { 163 | public: 164 | bool Create(const char* statement, Matcher matcher, 165 | const char* file, int line, DeathTest** test) override; 166 | }; 167 | 168 | // Returns true if exit_status describes a process that was terminated 169 | // by a signal, or exited normally with a nonzero exit code. 170 | GTEST_API_ bool ExitedUnsuccessfully(int exit_status); 171 | 172 | // A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads 173 | // and interpreted as a regex (rather than an Eq matcher) for legacy 174 | // compatibility. 175 | inline Matcher MakeDeathTestMatcher( 176 | ::testing::internal::RE regex) { 177 | return ContainsRegex(regex.pattern()); 178 | } 179 | inline Matcher MakeDeathTestMatcher(const char* regex) { 180 | return ContainsRegex(regex); 181 | } 182 | inline Matcher MakeDeathTestMatcher( 183 | const ::std::string& regex) { 184 | return ContainsRegex(regex); 185 | } 186 | 187 | // If a Matcher is passed to EXPECT_DEATH (etc.), it's 188 | // used directly. 189 | inline Matcher MakeDeathTestMatcher( 190 | Matcher matcher) { 191 | return matcher; 192 | } 193 | 194 | // Traps C++ exceptions escaping statement and reports them as test 195 | // failures. Note that trapping SEH exceptions is not implemented here. 196 | #if GTEST_HAS_EXCEPTIONS 197 | #define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ 198 | try { \ 199 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ 200 | } catch (const ::std::exception& gtest_exception) { \ 201 | fprintf( \ 202 | stderr, \ 203 | "\n%s: Caught std::exception-derived exception escaping the " \ 204 | "death test statement. Exception message: %s\n", \ 205 | ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ 206 | gtest_exception.what()); \ 207 | fflush(stderr); \ 208 | death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ 209 | } catch (...) { \ 210 | death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ 211 | } 212 | 213 | #else 214 | #define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ 215 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) 216 | 217 | #endif 218 | 219 | // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, 220 | // ASSERT_EXIT*, and EXPECT_EXIT*. 221 | #define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \ 222 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ 223 | if (::testing::internal::AlwaysTrue()) { \ 224 | ::testing::internal::DeathTest* gtest_dt; \ 225 | if (!::testing::internal::DeathTest::Create( \ 226 | #statement, \ 227 | ::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \ 228 | __FILE__, __LINE__, >est_dt)) { \ 229 | goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ 230 | } \ 231 | if (gtest_dt != nullptr) { \ 232 | std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \ 233 | switch (gtest_dt->AssumeRole()) { \ 234 | case ::testing::internal::DeathTest::OVERSEE_TEST: \ 235 | if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ 236 | goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ 237 | } \ 238 | break; \ 239 | case ::testing::internal::DeathTest::EXECUTE_TEST: { \ 240 | ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \ 241 | gtest_dt); \ 242 | GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ 243 | gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ 244 | break; \ 245 | } \ 246 | } \ 247 | } \ 248 | } else \ 249 | GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \ 250 | : fail(::testing::internal::DeathTest::LastMessage()) 251 | // The symbol "fail" here expands to something into which a message 252 | // can be streamed. 253 | 254 | // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in 255 | // NDEBUG mode. In this case we need the statements to be executed and the macro 256 | // must accept a streamed message even though the message is never printed. 257 | // The regex object is not evaluated, but it is used to prevent "unused" 258 | // warnings and to avoid an expression that doesn't compile in debug mode. 259 | #define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \ 260 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ 261 | if (::testing::internal::AlwaysTrue()) { \ 262 | GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ 263 | } else if (!::testing::internal::AlwaysTrue()) { \ 264 | ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \ 265 | } else \ 266 | ::testing::Message() 267 | 268 | // A class representing the parsed contents of the 269 | // --gtest_internal_run_death_test flag, as it existed when 270 | // RUN_ALL_TESTS was called. 271 | class InternalRunDeathTestFlag { 272 | public: 273 | InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, 274 | int a_write_fd) 275 | : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} 276 | 277 | ~InternalRunDeathTestFlag() { 278 | if (write_fd_ >= 0) posix::Close(write_fd_); 279 | } 280 | 281 | const std::string& file() const { return file_; } 282 | int line() const { return line_; } 283 | int index() const { return index_; } 284 | int write_fd() const { return write_fd_; } 285 | 286 | private: 287 | std::string file_; 288 | int line_; 289 | int index_; 290 | int write_fd_; 291 | 292 | InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete; 293 | InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete; 294 | }; 295 | 296 | // Returns a newly created InternalRunDeathTestFlag object with fields 297 | // initialized from the GTEST_FLAG(internal_run_death_test) flag if 298 | // the flag is specified; otherwise returns NULL. 299 | InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); 300 | 301 | #endif // GTEST_HAS_DEATH_TEST 302 | 303 | } // namespace internal 304 | } // namespace testing 305 | 306 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ 307 | -------------------------------------------------------------------------------- /include/gtest/internal/gtest-filepath.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Google Test filepath utilities 31 | // 32 | // This header file declares classes and functions used internally by 33 | // Google Test. They are subject to change without notice. 34 | // 35 | // This file is #included in gtest/internal/gtest-internal.h. 36 | // Do not include this header file separately! 37 | 38 | // IWYU pragma: private, include "gtest/gtest.h" 39 | // IWYU pragma: friend gtest/.* 40 | // IWYU pragma: friend gmock/.* 41 | 42 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 43 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 44 | 45 | #include "gtest/internal/gtest-string.h" 46 | 47 | GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ 48 | /* class A needs to have dll-interface to be used by clients of class B */) 49 | 50 | namespace testing { 51 | namespace internal { 52 | 53 | // FilePath - a class for file and directory pathname manipulation which 54 | // handles platform-specific conventions (like the pathname separator). 55 | // Used for helper functions for naming files in a directory for xml output. 56 | // Except for Set methods, all methods are const or static, which provides an 57 | // "immutable value object" -- useful for peace of mind. 58 | // A FilePath with a value ending in a path separator ("like/this/") represents 59 | // a directory, otherwise it is assumed to represent a file. In either case, 60 | // it may or may not represent an actual file or directory in the file system. 61 | // Names are NOT checked for syntax correctness -- no checking for illegal 62 | // characters, malformed paths, etc. 63 | 64 | class GTEST_API_ FilePath { 65 | public: 66 | FilePath() : pathname_("") {} 67 | FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} 68 | 69 | explicit FilePath(const std::string& pathname) : pathname_(pathname) { 70 | Normalize(); 71 | } 72 | 73 | FilePath& operator=(const FilePath& rhs) { 74 | Set(rhs); 75 | return *this; 76 | } 77 | 78 | void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } 79 | 80 | const std::string& string() const { return pathname_; } 81 | const char* c_str() const { return pathname_.c_str(); } 82 | 83 | // Returns the current working directory, or "" if unsuccessful. 84 | static FilePath GetCurrentDir(); 85 | 86 | // Given directory = "dir", base_name = "test", number = 0, 87 | // extension = "xml", returns "dir/test.xml". If number is greater 88 | // than zero (e.g., 12), returns "dir/test_12.xml". 89 | // On Windows platform, uses \ as the separator rather than /. 90 | static FilePath MakeFileName(const FilePath& directory, 91 | const FilePath& base_name, int number, 92 | const char* extension); 93 | 94 | // Given directory = "dir", relative_path = "test.xml", 95 | // returns "dir/test.xml". 96 | // On Windows, uses \ as the separator rather than /. 97 | static FilePath ConcatPaths(const FilePath& directory, 98 | const FilePath& relative_path); 99 | 100 | // Returns a pathname for a file that does not currently exist. The pathname 101 | // will be directory/base_name.extension or 102 | // directory/base_name_.extension if directory/base_name.extension 103 | // already exists. The number will be incremented until a pathname is found 104 | // that does not already exist. 105 | // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. 106 | // There could be a race condition if two or more processes are calling this 107 | // function at the same time -- they could both pick the same filename. 108 | static FilePath GenerateUniqueFileName(const FilePath& directory, 109 | const FilePath& base_name, 110 | const char* extension); 111 | 112 | // Returns true if and only if the path is "". 113 | bool IsEmpty() const { return pathname_.empty(); } 114 | 115 | // If input name has a trailing separator character, removes it and returns 116 | // the name, otherwise return the name string unmodified. 117 | // On Windows platform, uses \ as the separator, other platforms use /. 118 | FilePath RemoveTrailingPathSeparator() const; 119 | 120 | // Returns a copy of the FilePath with the directory part removed. 121 | // Example: FilePath("path/to/file").RemoveDirectoryName() returns 122 | // FilePath("file"). If there is no directory part ("just_a_file"), it returns 123 | // the FilePath unmodified. If there is no file part ("just_a_dir/") it 124 | // returns an empty FilePath (""). 125 | // On Windows platform, '\' is the path separator, otherwise it is '/'. 126 | FilePath RemoveDirectoryName() const; 127 | 128 | // RemoveFileName returns the directory path with the filename removed. 129 | // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". 130 | // If the FilePath is "a_file" or "/a_file", RemoveFileName returns 131 | // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does 132 | // not have a file, like "just/a/dir/", it returns the FilePath unmodified. 133 | // On Windows platform, '\' is the path separator, otherwise it is '/'. 134 | FilePath RemoveFileName() const; 135 | 136 | // Returns a copy of the FilePath with the case-insensitive extension removed. 137 | // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns 138 | // FilePath("dir/file"). If a case-insensitive extension is not 139 | // found, returns a copy of the original FilePath. 140 | FilePath RemoveExtension(const char* extension) const; 141 | 142 | // Creates directories so that path exists. Returns true if successful or if 143 | // the directories already exist; returns false if unable to create 144 | // directories for any reason. Will also return false if the FilePath does 145 | // not represent a directory (that is, it doesn't end with a path separator). 146 | bool CreateDirectoriesRecursively() const; 147 | 148 | // Create the directory so that path exists. Returns true if successful or 149 | // if the directory already exists; returns false if unable to create the 150 | // directory for any reason, including if the parent directory does not 151 | // exist. Not named "CreateDirectory" because that's a macro on Windows. 152 | bool CreateFolder() const; 153 | 154 | // Returns true if FilePath describes something in the file-system, 155 | // either a file, directory, or whatever, and that something exists. 156 | bool FileOrDirectoryExists() const; 157 | 158 | // Returns true if pathname describes a directory in the file-system 159 | // that exists. 160 | bool DirectoryExists() const; 161 | 162 | // Returns true if FilePath ends with a path separator, which indicates that 163 | // it is intended to represent a directory. Returns false otherwise. 164 | // This does NOT check that a directory (or file) actually exists. 165 | bool IsDirectory() const; 166 | 167 | // Returns true if pathname describes a root directory. (Windows has one 168 | // root directory per disk drive.) 169 | bool IsRootDirectory() const; 170 | 171 | // Returns true if pathname describes an absolute path. 172 | bool IsAbsolutePath() const; 173 | 174 | private: 175 | // Replaces multiple consecutive separators with a single separator. 176 | // For example, "bar///foo" becomes "bar/foo". Does not eliminate other 177 | // redundancies that might be in a pathname involving "." or "..". 178 | // 179 | // A pathname with multiple consecutive separators may occur either through 180 | // user error or as a result of some scripts or APIs that generate a pathname 181 | // with a trailing separator. On other platforms the same API or script 182 | // may NOT generate a pathname with a trailing "/". Then elsewhere that 183 | // pathname may have another "/" and pathname components added to it, 184 | // without checking for the separator already being there. 185 | // The script language and operating system may allow paths like "foo//bar" 186 | // but some of the functions in FilePath will not handle that correctly. In 187 | // particular, RemoveTrailingPathSeparator() only removes one separator, and 188 | // it is called in CreateDirectoriesRecursively() assuming that it will change 189 | // a pathname from directory syntax (trailing separator) to filename syntax. 190 | // 191 | // On Windows this method also replaces the alternate path separator '/' with 192 | // the primary path separator '\\', so that for example "bar\\/\\foo" becomes 193 | // "bar\\foo". 194 | 195 | void Normalize(); 196 | 197 | // Returns a pointer to the last occurrence of a valid path separator in 198 | // the FilePath. On Windows, for example, both '/' and '\' are valid path 199 | // separators. Returns NULL if no path separator was found. 200 | const char* FindLastPathSeparator() const; 201 | 202 | std::string pathname_; 203 | }; // class FilePath 204 | 205 | } // namespace internal 206 | } // namespace testing 207 | 208 | GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 209 | 210 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ 211 | -------------------------------------------------------------------------------- /include/gtest/internal/gtest-port-arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file defines the GTEST_OS_* macro. 33 | // It is separate from gtest-port.h so that custom/gtest-port.h can include it. 34 | 35 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 36 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 37 | 38 | // Determines the platform on which Google Test is compiled. 39 | #ifdef __CYGWIN__ 40 | #define GTEST_OS_CYGWIN 1 41 | #elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) 42 | #define GTEST_OS_WINDOWS_MINGW 1 43 | #define GTEST_OS_WINDOWS 1 44 | #elif defined _WIN32 45 | #define GTEST_OS_WINDOWS 1 46 | #ifdef _WIN32_WCE 47 | #define GTEST_OS_WINDOWS_MOBILE 1 48 | #elif defined(WINAPI_FAMILY) 49 | #include 50 | #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 51 | #define GTEST_OS_WINDOWS_DESKTOP 1 52 | #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) 53 | #define GTEST_OS_WINDOWS_PHONE 1 54 | #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) 55 | #define GTEST_OS_WINDOWS_RT 1 56 | #elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE) 57 | #define GTEST_OS_WINDOWS_PHONE 1 58 | #define GTEST_OS_WINDOWS_TV_TITLE 1 59 | #else 60 | // WINAPI_FAMILY defined but no known partition matched. 61 | // Default to desktop. 62 | #define GTEST_OS_WINDOWS_DESKTOP 1 63 | #endif 64 | #else 65 | #define GTEST_OS_WINDOWS_DESKTOP 1 66 | #endif // _WIN32_WCE 67 | #elif defined __OS2__ 68 | #define GTEST_OS_OS2 1 69 | #elif defined __APPLE__ 70 | #define GTEST_OS_MAC 1 71 | #include 72 | #if TARGET_OS_IPHONE 73 | #define GTEST_OS_IOS 1 74 | #endif 75 | #elif defined __DragonFly__ 76 | #define GTEST_OS_DRAGONFLY 1 77 | #elif defined __FreeBSD__ 78 | #define GTEST_OS_FREEBSD 1 79 | #elif defined __Fuchsia__ 80 | #define GTEST_OS_FUCHSIA 1 81 | #elif defined(__GNU__) 82 | #define GTEST_OS_GNU_HURD 1 83 | #elif defined(__GLIBC__) && defined(__FreeBSD_kernel__) 84 | #define GTEST_OS_GNU_KFREEBSD 1 85 | #elif defined __linux__ 86 | #define GTEST_OS_LINUX 1 87 | #if defined __ANDROID__ 88 | #define GTEST_OS_LINUX_ANDROID 1 89 | #endif 90 | #elif defined __MVS__ 91 | #define GTEST_OS_ZOS 1 92 | #elif defined(__sun) && defined(__SVR4) 93 | #define GTEST_OS_SOLARIS 1 94 | #elif defined(_AIX) 95 | #define GTEST_OS_AIX 1 96 | #elif defined(__hpux) 97 | #define GTEST_OS_HPUX 1 98 | #elif defined __native_client__ 99 | #define GTEST_OS_NACL 1 100 | #elif defined __NetBSD__ 101 | #define GTEST_OS_NETBSD 1 102 | #elif defined __OpenBSD__ 103 | #define GTEST_OS_OPENBSD 1 104 | #elif defined __QNX__ 105 | #define GTEST_OS_QNX 1 106 | #elif defined(__HAIKU__) 107 | #define GTEST_OS_HAIKU 1 108 | #elif defined ESP8266 109 | #define GTEST_OS_ESP8266 1 110 | #elif defined ESP32 111 | #define GTEST_OS_ESP32 1 112 | #elif defined(__XTENSA__) 113 | #define GTEST_OS_XTENSA 1 114 | #endif // __CYGWIN__ 115 | 116 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ 117 | -------------------------------------------------------------------------------- /include/gtest/internal/gtest-string.h: -------------------------------------------------------------------------------- 1 | // Copyright 2005, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // The Google C++ Testing and Mocking Framework (Google Test) 31 | // 32 | // This header file declares the String class and functions used internally by 33 | // Google Test. They are subject to change without notice. They should not used 34 | // by code external to Google Test. 35 | // 36 | // This header file is #included by gtest-internal.h. 37 | // It should not be #included by other files. 38 | 39 | // IWYU pragma: private, include "gtest/gtest.h" 40 | // IWYU pragma: friend gtest/.* 41 | // IWYU pragma: friend gmock/.* 42 | 43 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 44 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 45 | 46 | #ifdef __BORLANDC__ 47 | // string.h is not guaranteed to provide strcpy on C++ Builder. 48 | #include 49 | #endif 50 | 51 | #include 52 | 53 | #include 54 | #include 55 | 56 | #include "gtest/internal/gtest-port.h" 57 | 58 | namespace testing { 59 | namespace internal { 60 | 61 | // String - an abstract class holding static string utilities. 62 | class GTEST_API_ String { 63 | public: 64 | // Static utility methods 65 | 66 | // Clones a 0-terminated C string, allocating memory using new. The 67 | // caller is responsible for deleting the return value using 68 | // delete[]. Returns the cloned string, or NULL if the input is 69 | // NULL. 70 | // 71 | // This is different from strdup() in string.h, which allocates 72 | // memory using malloc(). 73 | static const char* CloneCString(const char* c_str); 74 | 75 | #if GTEST_OS_WINDOWS_MOBILE 76 | // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be 77 | // able to pass strings to Win32 APIs on CE we need to convert them 78 | // to 'Unicode', UTF-16. 79 | 80 | // Creates a UTF-16 wide string from the given ANSI string, allocating 81 | // memory using new. The caller is responsible for deleting the return 82 | // value using delete[]. Returns the wide string, or NULL if the 83 | // input is NULL. 84 | // 85 | // The wide string is created using the ANSI codepage (CP_ACP) to 86 | // match the behaviour of the ANSI versions of Win32 calls and the 87 | // C runtime. 88 | static LPCWSTR AnsiToUtf16(const char* c_str); 89 | 90 | // Creates an ANSI string from the given wide string, allocating 91 | // memory using new. The caller is responsible for deleting the return 92 | // value using delete[]. Returns the ANSI string, or NULL if the 93 | // input is NULL. 94 | // 95 | // The returned string is created using the ANSI codepage (CP_ACP) to 96 | // match the behaviour of the ANSI versions of Win32 calls and the 97 | // C runtime. 98 | static const char* Utf16ToAnsi(LPCWSTR utf16_str); 99 | #endif 100 | 101 | // Compares two C strings. Returns true if and only if they have the same 102 | // content. 103 | // 104 | // Unlike strcmp(), this function can handle NULL argument(s). A 105 | // NULL C string is considered different to any non-NULL C string, 106 | // including the empty string. 107 | static bool CStringEquals(const char* lhs, const char* rhs); 108 | 109 | // Converts a wide C string to a String using the UTF-8 encoding. 110 | // NULL will be converted to "(null)". If an error occurred during 111 | // the conversion, "(failed to convert from wide string)" is 112 | // returned. 113 | static std::string ShowWideCString(const wchar_t* wide_c_str); 114 | 115 | // Compares two wide C strings. Returns true if and only if they have the 116 | // same content. 117 | // 118 | // Unlike wcscmp(), this function can handle NULL argument(s). A 119 | // NULL C string is considered different to any non-NULL C string, 120 | // including the empty string. 121 | static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); 122 | 123 | // Compares two C strings, ignoring case. Returns true if and only if 124 | // they have the same content. 125 | // 126 | // Unlike strcasecmp(), this function can handle NULL argument(s). 127 | // A NULL C string is considered different to any non-NULL C string, 128 | // including the empty string. 129 | static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); 130 | 131 | // Compares two wide C strings, ignoring case. Returns true if and only if 132 | // they have the same content. 133 | // 134 | // Unlike wcscasecmp(), this function can handle NULL argument(s). 135 | // A NULL C string is considered different to any non-NULL wide C string, 136 | // including the empty string. 137 | // NB: The implementations on different platforms slightly differ. 138 | // On windows, this method uses _wcsicmp which compares according to LC_CTYPE 139 | // environment variable. On GNU platform this method uses wcscasecmp 140 | // which compares according to LC_CTYPE category of the current locale. 141 | // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the 142 | // current locale. 143 | static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, 144 | const wchar_t* rhs); 145 | 146 | // Returns true if and only if the given string ends with the given suffix, 147 | // ignoring case. Any string is considered to end with an empty suffix. 148 | static bool EndsWithCaseInsensitive(const std::string& str, 149 | const std::string& suffix); 150 | 151 | // Formats an int value as "%02d". 152 | static std::string FormatIntWidth2(int value); // "%02d" for width == 2 153 | 154 | // Formats an int value to given width with leading zeros. 155 | static std::string FormatIntWidthN(int value, int width); 156 | 157 | // Formats an int value as "%X". 158 | static std::string FormatHexInt(int value); 159 | 160 | // Formats an int value as "%X". 161 | static std::string FormatHexUInt32(uint32_t value); 162 | 163 | // Formats a byte as "%02X". 164 | static std::string FormatByte(unsigned char value); 165 | 166 | private: 167 | String(); // Not meant to be instantiated. 168 | }; // class String 169 | 170 | // Gets the content of the stringstream's buffer as an std::string. Each '\0' 171 | // character in the buffer is replaced with "\\0". 172 | GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); 173 | 174 | } // namespace internal 175 | } // namespace testing 176 | 177 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ 178 | -------------------------------------------------------------------------------- /include/gtest/internal/gtest-type-util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 Google Inc. 2 | // All Rights Reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Type utilities needed for implementing typed and type-parameterized 31 | // tests. 32 | 33 | // IWYU pragma: private, include "gtest/gtest.h" 34 | // IWYU pragma: friend gtest/.* 35 | // IWYU pragma: friend gmock/.* 36 | 37 | #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 38 | #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 39 | 40 | #include "gtest/internal/gtest-port.h" 41 | 42 | // #ifdef __GNUC__ is too general here. It is possible to use gcc without using 43 | // libstdc++ (which is where cxxabi.h comes from). 44 | #if GTEST_HAS_CXXABI_H_ 45 | #include 46 | #elif defined(__HP_aCC) 47 | #include 48 | #endif // GTEST_HASH_CXXABI_H_ 49 | 50 | namespace testing { 51 | namespace internal { 52 | 53 | // Canonicalizes a given name with respect to the Standard C++ Library. 54 | // This handles removing the inline namespace within `std` that is 55 | // used by various standard libraries (e.g., `std::__1`). Names outside 56 | // of namespace std are returned unmodified. 57 | inline std::string CanonicalizeForStdLibVersioning(std::string s) { 58 | static const char prefix[] = "std::__"; 59 | if (s.compare(0, strlen(prefix), prefix) == 0) { 60 | std::string::size_type end = s.find("::", strlen(prefix)); 61 | if (end != s.npos) { 62 | // Erase everything between the initial `std` and the second `::`. 63 | s.erase(strlen("std"), end - strlen("std")); 64 | } 65 | } 66 | return s; 67 | } 68 | 69 | #if GTEST_HAS_RTTI 70 | // GetTypeName(const std::type_info&) returns a human-readable name of type T. 71 | inline std::string GetTypeName(const std::type_info& type) { 72 | const char* const name = type.name(); 73 | #if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) 74 | int status = 0; 75 | // gcc's implementation of typeid(T).name() mangles the type name, 76 | // so we have to demangle it. 77 | #if GTEST_HAS_CXXABI_H_ 78 | using abi::__cxa_demangle; 79 | #endif // GTEST_HAS_CXXABI_H_ 80 | char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); 81 | const std::string name_str(status == 0 ? readable_name : name); 82 | free(readable_name); 83 | return CanonicalizeForStdLibVersioning(name_str); 84 | #else 85 | return name; 86 | #endif // GTEST_HAS_CXXABI_H_ || __HP_aCC 87 | } 88 | #endif // GTEST_HAS_RTTI 89 | 90 | // GetTypeName() returns a human-readable name of type T if and only if 91 | // RTTI is enabled, otherwise it returns a dummy type name. 92 | // NB: This function is also used in Google Mock, so don't move it inside of 93 | // the typed-test-only section below. 94 | template 95 | std::string GetTypeName() { 96 | #if GTEST_HAS_RTTI 97 | return GetTypeName(typeid(T)); 98 | #else 99 | return ""; 100 | #endif // GTEST_HAS_RTTI 101 | } 102 | 103 | // A unique type indicating an empty node 104 | struct None {}; 105 | 106 | #define GTEST_TEMPLATE_ \ 107 | template \ 108 | class 109 | 110 | // The template "selector" struct TemplateSel is used to 111 | // represent Tmpl, which must be a class template with one type 112 | // parameter, as a type. TemplateSel::Bind::type is defined 113 | // as the type Tmpl. This allows us to actually instantiate the 114 | // template "selected" by TemplateSel. 115 | // 116 | // This trick is necessary for simulating typedef for class templates, 117 | // which C++ doesn't support directly. 118 | template 119 | struct TemplateSel { 120 | template 121 | struct Bind { 122 | typedef Tmpl type; 123 | }; 124 | }; 125 | 126 | #define GTEST_BIND_(TmplSel, T) TmplSel::template Bind::type 127 | 128 | template 129 | struct Templates { 130 | using Head = TemplateSel; 131 | using Tail = Templates; 132 | }; 133 | 134 | template 135 | struct Templates { 136 | using Head = TemplateSel; 137 | using Tail = None; 138 | }; 139 | 140 | // Tuple-like type lists 141 | template 142 | struct Types { 143 | using Head = Head_; 144 | using Tail = Types; 145 | }; 146 | 147 | template 148 | struct Types { 149 | using Head = Head_; 150 | using Tail = None; 151 | }; 152 | 153 | // Helper metafunctions to tell apart a single type from types 154 | // generated by ::testing::Types 155 | template 156 | struct ProxyTypeList { 157 | using type = Types; 158 | }; 159 | 160 | template 161 | struct is_proxy_type_list : std::false_type {}; 162 | 163 | template 164 | struct is_proxy_type_list> : std::true_type {}; 165 | 166 | // Generator which conditionally creates type lists. 167 | // It recognizes if a requested type list should be created 168 | // and prevents creating a new type list nested within another one. 169 | template 170 | struct GenerateTypeList { 171 | private: 172 | using proxy = typename std::conditional::value, T, 173 | ProxyTypeList>::type; 174 | 175 | public: 176 | using type = typename proxy::type; 177 | }; 178 | 179 | } // namespace internal 180 | 181 | template 182 | using Types = internal::ProxyTypeList; 183 | 184 | } // namespace testing 185 | 186 | #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ 187 | -------------------------------------------------------------------------------- /include/index/skiplist.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | 5 | #ifndef SERVER_SKIPLIST_H 6 | #define SERVER_SKIPLIST_H 7 | class Skiplist { 8 | struct Node{ 9 | int val; 10 | Node* right, *down; 11 | Node(int v, Node* r, Node* d):val(v),right(r), down(d){} 12 | }; 13 | public: 14 | int level = 0; 15 | Node* head = nullptr; 16 | Skiplist() = default; 17 | bool get(int target); 18 | void put(int num); 19 | bool erase(int num); 20 | }; 21 | 22 | /** 23 | * Your Skiplist object will be instantiated and called as such: 24 | * Skiplist* obj = new Skiplist(); 25 | * bool param_1 = obj->search(target); 26 | * obj->add(num); 27 | * bool param_3 = obj->erase(num); 28 | */ 29 | 30 | #endif //SERVER_SKIPLIST_H 31 | -------------------------------------------------------------------------------- /include/utils.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | 5 | #ifndef SERVER_UTILS_H 6 | #define SERVER_UTILS_H 7 | #include 8 | const std::string relativeFilePath = "../file/minidb/minidb.data"; 9 | const std::string absFilePath = "/tmp/minidb/test.data"; 10 | const int HEADER_SIZE = 10; 11 | enum class MARK{ 12 | PUT = 1, 13 | DEL = 2 14 | }; 15 | enum class STATUS{ 16 | SUCCESS = 1, 17 | FAILED = 2, 18 | UNKNOWN = 3 19 | }; 20 | using ErrorInfo = std::string; 21 | #endif //SERVER_UTILS_H 22 | -------------------------------------------------------------------------------- /lib/libgmock.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/lib/libgmock.a -------------------------------------------------------------------------------- /lib/libgmock_main.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/lib/libgmock_main.a -------------------------------------------------------------------------------- /lib/libgtest.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/lib/libgtest.a -------------------------------------------------------------------------------- /lib/libgtest_main.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SYaoJun/cpp_in_action/3cfa3d66eab489767946540ae16d11ce15373a18/lib/libgtest_main.a -------------------------------------------------------------------------------- /src/db.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | #include "db.h" 5 | #include "entry.h" 6 | #include 7 | 8 | ErrorInfo miniDB::delete_(std::string) { 9 | return ErrorInfo(); 10 | } 11 | 12 | STATUS miniDB::put(std::string key, std::string value) { 13 | // 1. 打开文件 14 | int fd = open(absFilePath.c_str(), O_CREAT | O_WRONLY, 0644); 15 | if (fd == -1) { 16 | printf("open failed!"); 17 | return STATUS::FAILED; 18 | }else{ 19 | printf("open success!"); 20 | } 21 | this->dbFile->fd = fd; 22 | // 2. 写入磁盘 23 | this->mutex_.lock(); 24 | Entry entry(key, value, MARK::PUT); 25 | this->dbFile->write_(entry); 26 | // 3. 更新索引 27 | this->dbFile->loadIndex(); 28 | this->mutex_.unlock(); 29 | return STATUS::SUCCESS;; 30 | } 31 | 32 | std::pair miniDB::get(std::string) { 33 | 34 | return std::pair(); 35 | } 36 | 37 | STATUS miniDB::merge() { 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/db_file.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | #include "db_file.h" 5 | #include 6 | #include 7 | 8 | void DBFile::write_(Entry entry) { 9 | std::string tmp = entry.key + entry.value; 10 | int input_size = entry.getSize(); 11 | int write_size = pwrite(this->fd, tmp.c_str(), input_size, this->offset); 12 | if (write_size == -1){ 13 | perror("write error"); 14 | exit(1); 15 | } 16 | printf("write bytes: %d\n", write_size); 17 | this->offset += write_size; 18 | std::cout<<"offset = "<offset< 6 | 7 | Entry::Entry(std::string &key, std::string &value, MARK mark) { 8 | this->key = key; 9 | this->value = value; 10 | this->mark = mark; 11 | } 12 | 13 | std::pair Entry::encode() { 14 | return std::pair(); 15 | } 16 | 17 | std::pair Entry::decode(std::string buf) { 18 | Entry entry; 19 | return std::make_pair(entry, ErrorInfo()); 20 | } 21 | 22 | int Entry::getSize() { 23 | this->keySize = key.size(); 24 | this->valueSize = value.size(); 25 | return this->keySize + this->valueSize + HEADER_SIZE; 26 | } 27 | -------------------------------------------------------------------------------- /src/index/skiplist.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by 姚军 on 2022/9/5. 3 | // 4 | #include "skiplist.h" 5 | 6 | 7 | bool Skiplist::get(int target) { 8 | return false; 9 | } 10 | 11 | void Skiplist::put(int num) { 12 | 13 | } 14 | 15 | bool Skiplist::erase(int num) { 16 | return false; 17 | } 18 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "db.h" 13 | #include "utils.h" 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | int main(int argc,char **argv){ 19 | testing::InitGoogleTest(&argc,argv); 20 | return RUN_ALL_TESTS(); 21 | } 22 | /** 23 | * 测试相对路径打开文件 24 | */ 25 | TEST(TestOpenRelativePath, should_return_success_when_open_file){ 26 | // 注意:文件的位置是相对路径,相对于main函数的位置。 27 | int fd = open(relativeFilePath.c_str(), O_CREAT | O_WRONLY, 0644); 28 | if (fd == -1) { 29 | printf("open failed!"); 30 | }else{ 31 | printf("open success!"); 32 | } 33 | } 34 | /** 35 | * 测试绝对路径打开文件 36 | */ 37 | TEST(TestAbsoluteFilePath, should_return_success_when_open_file){ 38 | 39 | int fd = open(absFilePath.c_str(), O_CREAT | O_WRONLY, 0644); 40 | if (fd == -1) { 41 | printf("open failed!"); 42 | }else{ 43 | printf("open success!"); 44 | } 45 | } 46 | /** 47 | * 测试put方法 48 | * 根据key和value写入数据到磁盘 49 | */ 50 | TEST(TestMiniDBPut,TestMiniDBPut){ 51 | miniDB db; 52 | db.dbFile->offset = 0; 53 | std::string key = "test_key_"; 54 | std::string value = "test_val_"; 55 | for (int i = 0; i < 10; i ++) { 56 | unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 57 | mt19937 rand_num(seed); 58 | uniform_int_distribution dist(0, 5); 59 | int t = dist(rand_num); 60 | key += to_string(t); 61 | value += to_string(t); 62 | std::cout<<"key = "<offset = 0; 71 | std::string key = "test"; 72 | for(int i = 0; i < 5; i++) { 73 | auto val = db.get(key + to_string(i)); 74 | std::cout<<"value = "<< val.first << std::endl; 75 | } 76 | } 77 | TEST(TestMiniDB_Del, TestMiniDB_Del) { 78 | miniDB db; 79 | db.dbFile->offset = 0; 80 | std::string key = "test_key_78"; 81 | auto res = db.delete_(key); 82 | } 83 | TEST(TestMiniDB_Merge, TestMiniDB_Merge) { 84 | miniDB db; 85 | db.dbFile->offset = 0; 86 | auto res = db.merge(); 87 | } --------------------------------------------------------------------------------