简介
Modern STL (简称: MSTL) 是我们基于concept等 C++20 的新特性构建的 C++ 模板库, 致力于以更现代化的方法实现STL提供的功能.
MSTL 提供函数式风格的迭代器,
与STL相似的模板容器(Array, Vector, LinkedList等),
表示可能为空的值的Option,
用于取代异常机制的 Result,
以及含编码的字符和字符串 (AsciiChar, AsciiString, UTF8Char, UTF8String) 等功能.
MSTL的主旨在于现代化与零成本抽象, 致力于以零成本, 现代化的方式完成STL能完成的工作.
项目地址: https://github.com/a1393323447/modern_stl
项目目前在github上以GPLv3开源, 欢迎感兴趣的朋友关注, 使用, 学习, 交流以及参与改进.
示例
迭代器的使用
MSTL实现了函数式风格的迭代器, 在进一步简化代码的同时实现了零成本抽象.
#include <mstl/mstl.h>
#include <cassert>
using namespace mstl;
using mstl::collection::Array;
using mstl::collection::Vector;
using namespace mstl::iter;
template<typename T>
struct Pow {
    T pow;
    bool operator==(const Pow &rhs) const {
        return pow == rhs.pow;
    }
};
int main() {
    Array<i32, 10> arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 管道风格
    auto pow_arr1 =
            arr.iter()                           // 获取arr的迭代器
            | map([](const auto& ele) {            // 把迭代器中的元素转化为它的平方
                return ele * ele;
            })
            | map([](const auto& ele) {            // 把迭代器中的元素转化为Pow<usize>对象
                return Pow<usize>{
                        static_cast<usize>(ele * ele)
                };
            })
            | filter([](const auto& ele) {         // 滤去pow成员为奇数的元素
                return ele.pow % 2 == 0;
            })
            | collect<Vector<Pow<usize>>>();   // 把元素收集到Vector<Pow<usize>>中
// 链式风格
    auto pow_arr2 = combine(arr.iter(),             // 获取arr的迭代器
                            Map{}, [](auto ele) {                       // 把迭代器中的元素转化为它的平方
                return ele * ele;
            },
                            Map{}, [](auto ele) {                       // 把迭代器中的元素转化为Pow<usize>对象
                return Pow<usize>{ static_cast<usize>(ele * ele) };
            },
                            Filter{}, [](auto& ele) {                   // 滤去pow成员为奇数的元素
                return ele.pow % 2 == 0;
            },
                            CollectAs<Vector<Pow<usize>>>{}          // 把元素收集到Vector<Pow<usize>>中
    );
    auto pow_arr3 = Vector<Pow<usize>>{
            Pow<usize>{16},
            Pow<usize>{256},
            Pow<usize>{1296},
            Pow<usize>{4096},
            Pow<usize>{10000},
    };
    assert(pow_arr1 == pow_arr2);
    assert(pow_arr2 == pow_arr3);
}
编译时类型运算
MSTL实现了用于编译时类型运算的TypeList类, 可以对类型进行提取, 应用, 过滤, 转化等操作.
#include <mstl/mstl.h>
using namespace mstl::utility;
int main() {
    constexpr auto tuple = make_tuple(1, 2.0, 3l);
    constexpr auto ls1 = extract_from(tuple);                    // 从类模板中提取模板参数
    static_assert(ls1 == TypeList<int, double, long>);
    constexpr auto ls2 = TypeList<int, double>;
    constexpr auto t1 = ls2 | apply_to<Tuple>();                 // 把类型列表应用到类模板中
    static_assert(t1 == TypeConstInstance<Tuple<int, double>>);
    constexpr auto ls3 = ls2 | append<char, float>();            // 在类型列表后添加元素
    static_assert(ls3 == TypeList<int, double, char, float>);
    constexpr auto ls4 = ls3 | prepend<double*, const char*>();  // 在类型列表前添加元素
    static_assert(ls4 == TypeList<double*, const char*, int, double, char, float>);
    static_assert(ls4.at<1>() == TypeConstInstance<const char*>); // 按索引取出元素
    constexpr auto ls5 = ls4
                       | filter([]<typename T>(TypeConst<T>) {    // 过滤类型元素, 如同普通元素那样
                           return_v<(sizeof(T) < 8)>;             // 使用return_v返回一个编译期常量值. 此处返回bool类型, 滤去size小于8的类型
                       })  
                       | map([]<typename T>(TypeConst<T>) {       // 转换类型元素, 如同普通元素那样.
                           return_t<T*>;                          // 使用return_t返回一个类型. 此处使列表中的每个元素T转换成T*.
                       });
    static_assert(ls5 == TypeList<int*, char*, float*>);
}
按值匹配 (match)
MSTL实现了按值匹配功能, 不妨看作可以返回值且能匹配数值范围的switch-case语句.
#include <mstl/mstl.h>
using namespace mstl;
using namespace mstl::utility;
int main() {
    constexpr i32 i = 10;
    // 支持链式调用风格
    constexpr auto x = match(i)
                      .when(10, []{return 10;})  // 匹配成功, 表达式返回10
                      .rest([]{return 20;})
                      .finale();                // 获取返回值
    static_assert(x == 10);
    constexpr auto y = match(i)
                     .when(1, [](){return 5;})                  // 失配
                     .when(ops::Range(2, 10), [](){return 10;}) // 失配
                     .rest([](){return 20;})                    // 匹配剩余值, 匹配成功, 表达式返回20
                     .finale();
    static_assert(y == 20);
    // 也支持管道风格
    constexpr auto z = match(i)
                     | when(1, [](){return 5;})                  // 失配
                     | when(ops::Range(2, 11), [](){return 10;}) // 匹配成功, 表达式返回10
                     | rest([](){return 20;})
                     | finale();
    static_assert(z == 10);
}
使用字符串
MSTL 实现了含编码的字符串, 且对字符串字面量支持编译期无效字符检查.

更多示例参见此处的单元测试.
开始使用
MSTL是纯头文件库, 使用CMake进行管理进行构建.
因此, 我们建议您在使用本库时, 也尝试使用CMake构建您的项目.
需求
| 包 | 版本 | 备注 | 
| CMake | >=3.14 | 若您使用CMake构建本项目和您的其他项目 | 
| GCC | >= 12.2.0 | 暂不支持 MSVC | 
| Boost (可选) | >= 1.77.0 | 用于构建单元测试 | 
| Google Benchmark (可选) | >= 1.7.0 | 用于构建Benchmarks | 
准备工作
Clone仓库, 并Checkout main 分支.
git clone https://github.com/a1393323447/modern_stl.git 
cd modern_stl
git checkout main
构建与使用(通过CMake)
进入项目目录, 使用CMake构建并安装项目
# 假设您处于modern_stl目录下
md build
cd build
cmake ..  # 若您使用Windows操作系统, 还应该添加 -G "Unix Makefiles". MSTL还不支持MSVC
          # 若您需要指定安装路径, 还应该添加 -DCMAKE_INSTALL_PREFIX:PATH=...
cmake --build . --config Release --target install
然后您便可以在新的项目中使用mstl. 您需要在CMakeLists.txt文件中引入mstl.
set(CMAKE_CXX_STANDARD 20)
# 若您安装的路径不在PATH环境变量内, 您可能还需要使用如下语句设置搜索路径
# list(APPEND CMAKE_PREFIX_PATH "...")  # 把 ... 替换为mstl的安装路径
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")  # 开启调试模式下的部分运行时检查功能
find_package(mstl REQUIRED)
add_executable(mstl_test src/main.cpp)
target_link_libraries(mstl_test mstl::mstl)
接着, 在您的项目文件中包含mstl/mstl.h
#include <mstl/mstl.h>
构建与使用(不通过CMake)
您可以直接把include/mstl目录复制到任意地方.
在您的项目文件中包含mstl/mstl.h
#include <mstl/mstl.h>
并在编译时指定mstl目录所在的目录.
g++ main.cpp -o main -I/path/to/the/directory
您也可以使用任何支持指定包含目录的构建工具.
贡献者
 @Shiroan 
 @a1393323447
 
加入我们
我们欢迎您的积极参与, 您可以借由以下方法参与到本项目的开发之中:
- 就您认为可改进的地方, 希望实现的功能等提出issue, 我们随时欢迎您的指教.
 
- fork我们的仓库, 帮助我们完善文档和代码, 实现新功能.
 
作为一个全新的项目, MSTL还有很多不足.
我们期待您的加入, 让我们一起打造更强大的MSTL!