PSuM 代码风格规范¶
概述¶
本文档描述了 PSuM 项目核心部分的代码风格。建议开发中维持此风格。
1. 文件结构与命名空间¶
1.1 文件路径与命名空间映射¶
规则:文件路径(src 目录下)与命名空间结构对应,命名空间和文件名均使用蛇形命名法(小写字母和下划线)。
示例:
src/tag/foundation.hpp -> namespace psum { namespace tag { namespace foundation { ... } } }
src/field/device_field.hpp -> namespace psum { namespace field { ... } }
src/particle_container/device_vector.hpp -> namespace psum { namespace particle_container { ... } }
src/serialization/object_manager.hpp -> namespace psum { namespace serialization { ... } }
说明:
- 如果文件创建了一组类型、模板或函数,则这些内容组织为命名空间,命名空间名称与文件名相同。
- 如果文件主要用于创建单个类型或函数,则文件名与类型名相同,没有命名空间。
- 简而言之:文件夹总对应命名空间;文件对应命名空间,或重要的类型/函数。
1.2 头文件保护¶
规则:全大写,用下划线连接路径和文件名
src/tag/foundation.hpp -> #ifndef PSUM_TAG_FOUNDATION_HPP
src/field/device_field.hpp -> #ifndef PSUM_FIELD_DEVICE_FIELD_HPP
src/particle_container/device_vector.hpp -> #ifndef PSUM_PARTICLE_CONTAINER_DEVICE_VECTOR_HPP
1.3 头文件内容布局¶
规则:头文件内容按顺序排列,依次为:
#ifndef HEADER_GUARD
#define HEADER_GUARD
// introduce library dependencies first
#include <library>
// then project headers
...
#include "file/in/project.hpp"
...
// remeber write content in 'psum'
namespace psum {
// and right module namespace
namespace _module_you_are_writing {
// namespace/class/template declarations
// whatever you want to declare in this module
...
}
}
#endif
2. 命名规范¶
2.1 基本原则¶
规则:大部分时候使用蛇形命名法(小写字母和下划线)。
示例:
- 文件名:
foundation.hpp,device_field.hpp,particle_group.hpp - 类/结构体:
device_field,particle_container,tagged_struct - 函数:
get_access(),to_host(),for_each() - 命名空间:
psum,tag,field,serialization
2.2 惩罚性命名¶
规则:成员变量和私有方法使用下划线后缀,表示不应从外部访问。
说明:这是一种"惩罚性命名"机制,下划线后缀作为一种视觉提示,提醒使用者这些成员不应从外部直接访问。
class device_vector {
private:
mutable sycl::queue q_; // 成员变量带下划线后缀
T* data_;
size_t* size_;
bool* overflow_;
size_t capacity_;
void set_size_(size_t new_size) const; // 私有方法带下划线后缀
size_t get_size_() const;
public:
// 公共接口不使用下划线后缀
size_t size() const;
T* data() const;
};
例外:类内部的类型别名(using / typedef)不遵守此规则,因为那些类型别名通常被外部使用。即使私有类型别名也不使用下划线后缀。
class device_vector {
public:
using value_type = T; // 类型别名不使用下划线后缀
using acc_type = device_vector_acc<T>;
private:
T* data_; // 成员变量使用下划线后缀
};
2.3 枚举值¶
规则:枚举值使用驼峰命名法(PascalCase)。
示例:
2.4 模板参数¶
规则:模板参数通常使用首字母大写的名称。
说明:
- 使用描述性名称:
T,Func,Data,Item,Tag,Type,Scalar,Dimension。 - 对于那些有物理意义的模板参数,不建议使用
T这类单字母名称。 - 如果模板参数与类型内部的类型别名相同,使用前置下划线。
示例:模板参数名与类成员名不会产生冲突时,不使用下划线前缀。
// 大多数模块
template <typename T>
class device_vector { ... };
template <typename Func, typename Data>
concept handler_to_device_func = ...;
template <typename Item, typename First, typename... Rest>
struct index_in_tuple { ... };
template <typename Type>
concept has_tag_name = ...;
示例:如果模板参数与类型内部的类型别名相同,使用前置下划线。这见于模板参数精确对应内部的类型别名的情况。
// field 模块示例
template <int _Dimension, var_loc _location, typename _Scalar, int _QuantitySize = 1>
class device_field {
public:
// 模板参数:_Dimension, _location, _Scalar, _QuantitySize (带下划线前缀)
// 因为类内部有对应的类型别名,所以模板参数使用下划线前缀
static constexpr int Dimension = _Dimension; // 类内类型别名(大写开头)
static constexpr var_loc Location = _location;
static constexpr int QuantitySize = _QuantitySize;
using Scalar = _Scalar; // 类内类型别名(大写开头)
using Value = ...;
using Position = ...;
using Grid = simple_grid<Dimension>;
};
示例:如果模板参数与类型内部的类型别名不同,则互不影响。
// particle_container 模块 - 不使用下划线前缀
template <typename T>
class device_vector {
using value_type = T; // 直接使用,不使用下划线前缀
using acc_type = device_vector_acc<T>;
};
2.5 宏定义¶
规则:宏定义使用全大写,单词间用下划线连接。
#define PSUM_UNIQUE_PTR_TYPE(x) std::unique_ptr<x[]>
#define PSUM_MATCH_TYPE_MEMSET(x) {std::string(#x), [](size_t size){return vPtr( std::make_unique<x[]>(size) );}}
#define DEFAULT_SEED 1
3. 代码组织¶
3.1 模块¶
规则:src目录下的每个子目录对应一个模块。
示例:
说明:
- 同一目录下的文件属于同一模块,共享相同的命名空间并形成完整的功能。
- 模块之间尽量不要有依赖关系;有依赖关系的情况,对应的文件放在依赖方而不是被依赖方的目录下。
3.2 模块入口文件¶
规则:每个模块都有一个入口文件,以简化外部引入。
示例:
src/tag.hpp // tag模块入口
src/particle_container.hpp // particle_container模块入口
src/field.hpp // field模块入口
src/serialization.hpp // serialization模块入口
附录:命名速查表¶
| 类型 | 命名规则 | 示例 |
|---|---|---|
| 文件名 | 小写+下划线 | foundation.hpp, device_field.hpp |
| 类/结构体 | 小写+下划线 | device_field, tagged_struct |
| 公共函数 | 小写+下划线 | get_access(), for_each() |
| 成员变量 | 小写+下划线 + 下划线后缀 | data_, size_, capacity_ |
| 私有方法 | 小写+下划线 + 下划线后缀 | set_size_(), get_size_() |
| 命名空间 | 小写 | psum, tag, field |
| 枚举值 | 驼峰 | cellCentered, faceCentered |
| 类型别名 | 小写 | value_type, acc_type |
| 模板参数(默认) | 首字母大写 | T, Func, Type |
| 模板参数(与类型别名冲突) | 下划线前缀 | _Dimension, _Scalar |
| 宏定义 | 全大写+下划线 | PSUM_UNIQUE_PTR_TYPE, DEFAULT_SEED |