﻿/*
	Copyright by FrankHB 2009 - 2013.

	This file is part of the YSLib project, and may only be used,
	modified, and distributed under the terms of the YSLib project
	license, LICENSE.TXT.  By continuing to use, modify, or distribute
	this file you indicate that you have read the license and
	understand and accept it fully.
*/

/*!	\file Designation.txt
\ingroup Documentation
\brief 设计规则指定和说明。
\version r7624
\author FrankHB <frankhb1989@gmail.com>
\since 早于 build 132
\par 创建时间:
	2009-12-02 05:14:30 +0800
\par 修改时间:
	2013-04-24 15:02 +0800
\par 文本编码:
	UTF-8
\par 模块名称:
	Documentation::Designation
*/


/*

@0 体例和适用范围：
引用标记参见 [Documentation::CommonRules @@0.1] 。
 YSLib 项目(the YSLib project) 包括 YFramework 和 YBase 。
本文档适用于 YFramework 的开发。除非有特别说明，编码细节和其它规范也适用于 YBase(@5.2.1) 。

@1 设计：

@1.1 设计的基本原理和表达形式：
设计的出发点：构建一个可复用的组件组成的库框架。
代码不保证语义角度（例如实现需求）内容的连贯性。
原始目的：在以标准 C++ 环境（宿主实现或独立实现）为基础的嵌入式设备等平台上，建立常规应用程序框架。
扩展目的：渐进地向独立的计算机软件系统演进，探究具有高度互操作性的系统的一般实现方法。

@1.1.1 设计原则：

@1.1.1.1 规约视角：
仅向内廪语义耦合：使用列举外延定义概念前必须提取清晰的内涵，同时避免和其它概念的耦合。
避免重复冗余：语义允许忽略差异的应保持同一性(identity) 的概念和实体不应存在别名以外的副本。

@1.1.1.2 组件视角：
层次封装：组件可分为若干层次，在任意层次上都需要保持对满足一定接口约束的同类组件的可替换性（如果可能，也适用于库的外部依赖项）。
任务关联：允许对完成一种任务提供多种接口，但应尽量能在足够明确的限制条件下找到单一最佳实践。

@1.1.1.3 用户视角：
给用户提供选择的自由。
信任用户，给用户提供服务而不是检查用户的行为。（类似 C 和 C++ 的设计哲学。注意这点同时也允许未定义行为。）

@1.2 理论背景、工具和依据：
基本内容参见 [Documentation::CommonRules @@2.1] 。
表现以下设计意义：
环境隔离：对特定领域相关的上层源代码提供一致的接口。
抽象和封装：提供控制流实体语义的抽象；提供用于封装上层平台相关的模块的支持。

@1.2.1 组织概念模型：

@1.2.1.1 平台无关的组织分类：
框架核心称为 Core ；
其它必须直接基于 Core 之上一些外围功能实现程序是 Shell ；
和框架核心之间没有整体依赖性（依赖在逻辑上可被其它组件替代）的部分称为 Service 。
 Shell 和 Core 应保持相对独立，以方便移植。

@1.2.1.1.1 相对性：
Shell 和 Core 的关系是相对的，例如：
操作系统上层（最终）用户界面和服务相对于操作系统内核(kernel) ；
基于操作系统 Shell 的应用程序相对于操作系统 Shell 。
这样， Shell 和 Core 之间的相对关系可以级联。对组织虚拟化程序架构等有一定意义。

@1.2.1.2 环境(environment) ：
程序中的某一部分的外界称为环境。
根据限定程序的范围，可以有更确切的概念定义，如实现环境（对于一类语言实现而言）、运行时环境（对于共享实现环境的一类程序而言）。
一般地，实现环境可以分为独立环境(freestanding environment) 和宿主环境(hosted environment) ，区分依据为是否依赖于宿主（对于部署在单一计算机上的实现，一般指操作系统）的支持。
因此，环境有时指操作系统及其提供的外部服务的集合。
一些语言，如 ISO C 和 ISO C++ ，可以同时支持宿主环境和独立环境的实现，对应地独立实现(freestanding impementation) 和宿主实现(hosted impementation) 。

@1.3 构建原则：
基本内容参见 [Documentation::CommonRules @@2.2] 。

@1.3.1 可移植性相关：
基本内容参见 [Documentation::CommonRules @@2.2.2] 。
语言使用规则参见 [Documentation::CommonRules @@5] 。

@1.3.2 环境依赖性：
关于环境，参见 @1.2.1.2 。
关于库配置，参见 @5 。
本节适用于 YSLib 库，用户程序不受此限制。
 YSLib 程序默认基于 ISO C++03 环境和基本的系统调用（由 YCLib 支持）。
依赖 ISO C++ 独立实现或宿主实现，附加以下例外：
需要 @1.3.2.1 列出的扩展支持；
库要求等同于 ISO C++11 定义的宿主实现；
需要定宽整数 std::intN_t 和 std::uintN_t （其中 N 为 8 、 16 、 32 或 64 ）支持（ ISO C++11 中为可选支持）。

@1.3.2.1 需要使用的非 ISO C++03 扩展：
定义于 ISO C99（ISO/IEC 9899:1999）和 ISO C++11（ISO/IEC 14882:2011）中，且有一个以上完整的语言实现。
 C99 preprocessor(N1653) ；
 Static assertions(N1720) ；
 Right angle brackets(N1757) ；
 long long(N1811) ；
 Built-in type traits(N1836) ；
 auto-typed variables(N1984) ；
 Delegating constructors(N1986) ；
 Extern templates(N1987) ；
 Generalized constant expressions(N2235) ；
 Variadic templates v0.9(N2242) ；
 New character types(N2249) ；
 Declared type of an expression v1.0(N2343) ；
 Defaulted and deleted functions(N2346) ；
 Strongly-typed enums(N2347) ；
 nullptr(N2431) ；
 Explicit conversion operators(N2437) ；
 Unicode string literals(N2442) ；
 New function declaration syntax for deduced return types(N2541) ；
 Initializer lists (N2672) ；
 Rvalue references v3.0(N3053) ；
 Lambda expressions and closures v1.1(N2927) ；
 Range-based for(N2930) ；
 Converting Lambdas to Function Pointers(N3052) ；
 Explicit virtual overrides v1.0(N3272) 。
接口和实现仅使用 ISO C++11 中头文件 <array> 、 <atomic> 、 <chrono> 、 <condition_variable> 、 <forward_list> 、 <mutex> 、 <thread> 、 <type_traits> 、 <tuple> 、 <unordered_map> 、<unordered_set> 和 <utility> 的特性。

@1.3.2.2
 YSLib 的源代码的本体(@2.9) 是平台中立([Documentation::CommonRules @@2.2.2.1]) 的。其中的一部分在冯·诺依曼体系结构的现代数字式电子计算机的范畴内是平台无关的。

@1.3.2.3
格式化输出及结构对齐时注意平台字长差异。

@1.3.3 可维护性和架构设计：
基本内容参见 [Documentation::CommonRules @@2.2.3] 。
语义相关的架构参见 [Documentation::CommonRules @@2.3.2] 。

@1.3.4 实现功能特征概述：
便于扩展。
尽可能地平台无关，且注重效率。
能够保持必要的运行时安全性。
实现一部分的通用较高级功能，例如消息机制(@1.4.1.3) 。

@1.4 通用语义：
基本内容参见 [Documentation::CommonRules @@2.3] 。

@1.4.1 运行时程序模型：
除以下部分外由具体项目定义。

@1.4.1.1 运行时程序结构和部署模型：
 YSLib 中讨论可部署的程序的基本单位是 Shell(@1.4.4.2) 。
 YSLib 基于单一进程和单一线程的运行时程序结构，类似于单内核操作系统；但内部实现是微内核至无内核的，除了主循环，任意一个 Shell 都可以独立部署。
在适当的平台上通过扩充能实现多个独立的二进制实体并行运行的多进程程序。

@1.4.1.2 并发模型：
基于可移植性和易用性的考虑， YSLib 并发语义的表达不包括作为机器模型的语言和库特性提供的线程模型的直接使用，而以角色模型进行并发抽象的问题模型。
对于 Shell 内部的操作，不存在共享状态的竞争条件，无需进行加锁操作，避免死锁、活锁和优先级反转等问题。即 Shell 本身使用单线程。
由于语言的限制，无法直接表达任意的并行语义，从而无法有效实现真并发行为。真并发行为可能由平台相关的扩展 API 实现。
 YSLib 仅提供有限的调度设施保证，通过加入线程模型相关的设计和实现，进程内的控制流实体保持是可扩充的和自洽的。

@1.4.1.3 消息机制：
基本内容参见 [Documentation::CommonRules @@2.5.3] 。
 YSLib 支持消息队列。
 YSLib 的消息被用于在 Shell 之间传递状态，称为 Shell 消息。
默认 Shell 消息列表参见 [Documentation::YSLib @@1] 。
消息、消息队列、消息分派和消息循环的实现参见 @2.5.10 。

@1.4.1.4 可重入性和线程安全性：
除本条外， YSLib 及其部分依赖项的可重入性和线程安全性参见 @2.6 、 @2.6.2 、@2.9 、 @5.2 、 @5.5 和 [Documentation::CHRLib] 。

@1.4.1.4.1 一般准则：
中断服务例程应保证可重入性。
可重入和线程安全无必然联系。
对于单线程实现环境，不对线程安全性另行说明。

@1.4.1.4.2 例程和包含的可调用对象(callable object) 的调用：
仅包含可调用对象的调用时，此例程的可重入性和线程安全性等价于包含的所有调用：
包含可调用对象的调用时，此例程可重入，仅当包含的所有调用可重入。
包含可调用对象的调用时，此例程线程安全，仅当包含的所有调用线程安全。

@1.4.1.5 全局初始化：
除另有说明，仅保证可重入的调用可用于全局初始化。

@1.4.2 资源分类：
基本内容参见 [Documentation::CommonRules @@2.3.2.2] 。
 YSLib 对于资源的直接使用仅限软件资源（硬件资源通过语言抽象和 YCLib 等平台兼容层包装后间接使用）。

@1.4.3 资源管理：
基本内容参见 [Documentation::CommonRules @@2.3.2.3] 。
 RAII 在异常安全和可维护性等方面具有其它方法不可替代的优势，因此是 YSLib 中最主要使用的资源管理惯用法。

@1.4.4 Shell ：
在 YFramework/YSLib 中， Shell 有多种含义。
如无特殊说明一般指 @1.5.1.1 。

@1.4.4.1 组织分类：
参见 @1.2.1.1 。

@1.4.4.2 程序实体：
 Shell 实体（简称 Shell ）是一种包含状态的有限片段控制流抽象，是动态映像(@1.5.1.1) 或静态映像(@1.5.1.2) 之一。

@1.4.3 会话(session) ：
会话是连接对象([Documentation::CommonRules @@2.5.4]) 或其它会话具有直接所有权的实体集合，通常用于在一段时间间隔内跟踪连接的客户端的操作。

@1.4.3.1 网络通信会话：
网络通信会话是半持久化的数据交换的抽象。
会话的连接用于网络通信。
它可能被基于特定的协议上实现。

@1.4.3.2 用户登录会话：
保存特定用户使用计算机的状态的抽象。

@1.4.3.3 用户界面会话：
用户界面会话是对用户在特定界面操作状态集合的抽象。
会话的连接用于在界面逻辑状态和输入/输出缓冲区之间通信。

@1.4.3.4 会话的实例：
桌面会话是典型的用户界面会话。
浏览器会话包含客户端的网络通信会话和用户界面会话。

@1.4.3.5 会话管理：
会话管理是人机交互中对抽象为若干会话的用户活动的追踪。它能重置或还原特定用户行为和操作下的状态。

@1.5 YSLib 模型抽象：
本节讨论具体的基本特性相关的模型抽象。

@1.5.1 框架抽象：
本节描述框架组成成分的抽象。

@1.5.1.1 Shell 动态映像：
 Shell 作为被执行的程序称为 Shell 的动态映像。一个 Shell 动态映像的实例称为 Shell 对象，是运行时控制流映像，用于表示一段时间间隔（称为生存期）内计算机系统当前处理的任务。
 Shell 对象是程序的基本调度单位之一。不同于进程/线程等具体的任务实体，它仅是表示可执行的程序的高层抽象，并不限定环境(@1.2.1.2) 对共享资源的分配方式。
实现形式上 Shell 对象，可以是进程/线程等和体系结构关联更彻底的方式，但这并非其内涵。

@1.5.1.2 Shell 静态映像：
储存 Shell 动态映像中执行的代码的非运行时映像实体称为 Shell 静态映像。
实现形式上， Shell 静态映像可以是可执行文件中的代码片段或内存中的流，但这并非其内涵。
它可以作为构建程序时复用的单位。因此可以用于组织分类(@1.4.4.1) 。
注意 YSLib 中的实现 Shell 实体的基类 Shell 属于组织意义上的 Core 而非 Shell ，位于 "/Core" 。

@1.5.1.3 Shell 对象的执行状态：
一个 Shell 对象被调度的时间间隔不一定等于它的生存期，可能是其中的一部分。
因此， Shell 对象不仅表示活动的（当前正在运行的）运行时状态，还可以储存非活动的运行时状态。
在某个确定的时刻，一个 Shell 对象具有以下执行状态之一：不处于可被有效调度时的非活动态和处于可被有效调度时的活动态。
新建的 Shell 对象默认具有非活动态。
对于单线程的实现，同一时刻有且仅有一个 Shell 对象处于活动态。

@1.5.1.4 Shell 状态切换：
 Shell 对象由非活动态至活动态的转换过程称为激活(activation) ；活动态至非活动态的转换过程称为停用(deactivation) 。激活和停用合称为 Shell 状态的切换(switching) ，简称 Shell 切换。
 Shell 切换要求 Shell 具有完整的存储和正常的生存期。

@1.5.1.5 Shell 通信：
 Shell 的必要的基本通信机制是消息机制(@1.4.1.3) 。
使用消息机制， Shell 切换是用户程序可知的(@2.5.11) 。
用户可以自定义具体 Shell 的特定机制。
 Shell 可能是连接对象([Documentation::CommonRules @@2.5.4]) 。

@1.5.1.6 Shell 类和 Shell 对象生存期导致的限制：
 Shell 被设计为一个 C++ 多态类。
默认不在 Shell 内部保存激活或停用状态，而由外部控制。
在 C++ 中应注意以下几点：
一个类类型对象的生存期起始于构造调用结束后，构造函数中的操作是受限的（例如无法正确地调用虚函数）；
构造函数允许抛出异常。
因此：
 Shell 切换(@1.5.1.2) 时无法新建 Shell 对象且是无异常抛出保证([Documentation::CommonRules @@5.20.5.4]) 的；
激活和停用有必要明确地区分于构造和析构。
特定的 Shell 可作为 ISO C++11 30.2.5.1/1 定义的执行代理(execution agent) 。

@1.5.1.7 Shell 的应用场景：
 Shell 表示一类任务，可作为程序中的可重用组件存在。
 Shell 可在一段时间间隔内作为保存程序执行中公共状态的实体，类似于 Microsoft Windows 的会话(session) 或窗口站(window station) 。
 Shell 可以是会话(@1.5.1.8) 。

@1.5.2 显示模型：
本节描述显示特性相关的抽象。

@1.5.2.1 二维输出设备参照坐标系：
表示输出平面，使用二维欧几里得空间的视图坐标系。
逻辑上，坐标值是纯量，是实数或其子集的元素。对于实现而言也可能包括非数学量（如浮点数的无穷值）。
若无额外说明，同一个坐标系内的两个坐标值的取值范围相等。
若无额外说明，以输出设备相对于用户的最左上角为原点(0, 0) ，横坐标正方向向右，纵坐标正方向向下。
最基本的实例是屏幕坐标系。

@1.5.2.2 部件坐标系：
相对于输出所在屏幕的屏幕坐标系直接平移变换得到的坐标系。
注意原点相对于屏幕坐标系的坐标分量可以有负值。

@1.5.2.3 标准矩形(canonical rectangle) ：
边和二维输出设备坐标系共线的矩形。
一般地，可以使用四个纯量表示，如表示左上角的点坐标和长、宽，或表示对角线端点的两个点坐标。

@1.6 组件和界面设计概述：

@1.6.1 UI（User Interface ，用户界面）设计：
为了适应不确定数量的输出设备，特定的 Shell(@1.2.1.1) 可以用于实现程序中处理 UI（User Interface ，用户界面）行为，称为 UI Shell 。
输出特性依赖于部件坐标系(@1.5.2.2) 。
用于实现 UI 的 Shell 一般也包括实现相关消息处理。
和 Shell 相对的 Core 不直接参与实现 UI 。

@1.6.2 GUI（Graphical UI ，图形用户界面）设计概述：
界面实现使用称为 Shell-Widget 的模式，是精简的主动模型-视图-控制器模式的变体，参照窗体-控件模式。但架构模式无本质变化。
界面实现解决的三个问题：安排状态(state) 、逻辑(logic) 和同步(synchronization) ，都可以在运行期配置。
为了方便复用，这些属性有如下分类：
根据是否依赖于具体的 Widget 实例分为实例的和公共的；
根据是否能被所有 Widget 类共用分为公用的和专用的。
这些属性也适用于用于实现的构件。
强化了编译期可配置性。
基于性能考虑，仅在少数必要处实现观察者模式。
默认公共 UI 状态通过 YGUI 单元的 GUIState 类实现。

@1.6.2.1 模型(model) ：
模型表示数据模型(data model) ，保证和领域逻辑(domain logic)/业务逻辑(business logic) 具有合理的关联。
模型和其它部分是适当分离的，模型不被依赖，或仅被专用视图或控制器依赖。

@1.6.2.2 视图(view) ：
视图用于向用户呈现数据，保持用户界面状态。
视图在 GUI 响应（如具体实现 @2.8.3 和 @2.8.5 ）中不会修改模型，但可以向控制器提交状态。
部件类实现了基本的视图。通过派生或修饰这些类可以得到扩展的视图。
通常约定视图在显示设备上呈现矩形区域。

@1.6.2.2.1 视图组织：
构件对象的视图之间的联系组成的抽象整体（是一个图）称为视图组织。
为了便于实现中以遍历为基础的算法能可靠结束，视图组织一般应是受限的、可以使用带层次的树型结构表示的有向无环图，它的表示称为视图树。
一旦存在环路，对视图的某些操作可能导致未定义行为。
视图树的节点之间表示的显示范围存在约束。子节点可表示的区域是父节点的子集。

@1.6.2.3 控制器(controller) ：
控制器完成界面状态和模型状态的同步，保持根据用户在视图中的行为更新模型的逻辑。
若有必要，控制器可以保持状态。模型和视图不能直接修改控制器的状态，但可以提交状态等待控制器自行更新。

@1.6.2.3.1 公用控制器：
公用控制器用于实现公用输入逻辑，并储存了相关状态，是 UI Shell(@1.6.1) 的重要组成部分。
用户输入由公用控制器而不是视图进行直接处理。公用控制器转发处理的结果到专用控制器(@1.6.2.3.2) 中以便被进一步处理。
公用控制器是公共的，不依赖于实例。
专用控制器依赖于公用控制器的行为，但不依赖其实现。

@1.6.2.3.2 专用控制器：
专用控制器用于实现特定 Widget 的较高层 UI 行为。

@1.6.2.3.2.1 专用公共控制器：
专用公共控制器用于实现 Widget 类特定的较高层 UI 行为。

@1.6.2.3.2.2 专用实例控制器：
专用实例控制器用于实现 Widget 实例特定的较高层 UI 行为。一般位于部件(@1.6.2.5) 中。

@1.6.2.4 Shell-Widget 模式：

@1.6.2.4.1 Shell 状态和控制器：
 Shell 负责保存所有 GUI 之间的公用状态（如拖曳位置），并集成保存公用逻辑的公用控制器。它们都是公共的，不依赖于 Widget 实例。

@1.6.2.4.2 Widget 状态、控制器和视图：
 Widget 负责保存单一的 GUI 非公用状态、视图的直接实现，并集成保存专用逻辑的专用控制器用于在一定范围内动态配置 UI 的行为。
专用公共逻辑可能是多个 Widget 中相同的。
专用公共状态可能是多个 Widget 之间共享的([Documentation::CommonRules @@2.3.3.2]) 。
视图总是实例的，它自身有且仅有两种状态：已经被同步或未被同步。

@1.6.2.4.3 数据流和响应流程：
输入数据流首先被 Shell 的公用控制器响应；若有必要，更新公用状态。然后，转发至 Widget 。
 Widget 的专用控制器对输入进行响应；若有必要，更新非公用状态。（通常是公共的）专用控制器可能更新公用状态。根据此状态同步视图，并决定对输入数据的修饰以及是否转发至下一层次的 Widget 。
因为 Widget 之间的视图组织是有限的，所以当不存在环路时，以上流程应在有限时间内完成。
 Shell 的其它部分实现使视图更新至显示设备的输出调用。

@1.6.2.5 构件实体(part entities) ：
实现中 Shell-Widget 模式中作为 Widget 的角色。相较于典型的窗体-控件模式， GUI 控件(controls) 退化为部件(widgets) ，部件退化为组件(components) ，进而分离可视属性，抽象出独立于这些构件的部件特征，细分功能以实现高度可配置性。
一般的组件、部件和控件等实体在此统称为构件(parts) 。
 YSLib 本身不提供大量成熟的控件，而是着重提供可供组装为控件的基本 GUI 类（部件模块类）、部件类、在部件基础上衍生的构件以及部件简单组合的组件。这些用户界面元素(UI elements) 不一定具有消息处理或事件响应的功能，因此可以不是控件；参见 @1.6.2.6 。
控件主要由用户通过组装以上的构件定制。

@1.6.2.5.1 组合构件(compound parts) ：
可以自定义任意的模型类来组装部件、控件或其它用户界面元素。
但是，并非每一个成分都是必须的。某些成分可能在具体的类的外部实现。
若组合的结果能处理消息或响应事件，同时能够呈现界面数据，那么就是控件。

@1.6.2.5.2 构件容器(containers) ：
构件容器是能以引用等方式在逻辑上包含构件的构件实体。被包含的构件称为包含构件的子构件。
组件容器是组件。部件容器是部件。控件容器是控件。

@1.6.2.6 构件组织(parts construct) ：
和视图组织(@1.6.2.2.1) 类似，部件之间存在的联系组成的抽象整体（是一个图）称为构件组织。类似地，存在构件树。
部件的构件组织用于作为视图组织的实现。其它非部件的构件组织同样具有树形结构，但（默认）不具有直接的实现。

@1.6.2.7 场景(scenes) ：
构件组织中任意两个节点具有至少一个直接依赖的子集称为场景。

@1.6.2.8 焦点(focuses) 概述：
焦点在部件容器（称为焦点上下文）中对 GUI 对象的标识。
控制器根据焦点选择当前操作（通常是输入）作用的对象。
由于在一个焦点上下文中可能包含多个子上下文（参见 @1.6.2.6 ），因此可能有多个焦点。
对于视图树而言，通过迭代访问焦点对象可以得到唯一的路径，称为焦点活动路径；其中的焦点称为活动路径焦点。末端的活动路径焦点称为活动焦点，在确定状态下若存在，则是唯一的。

@1.6.3 目标风格与最佳实践：
本节概述基于 @1.1 和 @1.3 的约束下，组件和 UI 库接口设计的总体风格和对用户代码的影响。

@1.6.3.1 引用参照：
 Ultimate++ ： http://www.ultimatepp.org/www$uppweb$overview$en-us.html 。

@1.6.3.2 库依赖性：
除非必要，尽量使用标准库。例外情况下应该提供充足理由，并对用户自行替换底层接口和实现提供一定的便利性。

@1.6.3.3 资源管理：
基于对象所有权，方法参见 @2.2.2 。
基于和 Ultimate++ 相同的理由，接口不使用智能指针，且用户代码而不是被依赖的组件决定部件对象的所有权从属。
但总体风格上没有限定作用域和所有权的严格对应关系，也因此能够自然地使用部件指针的标准库容器。这点同时简化基于迭代器模式的实现。
此外， YSLib 不排斥在部件实现(@2.8) 中提供（有限的）复制和转移支持以保证值语义。

@1.6.3.4 泛型值类型：
适当使用 YBase(@5.2.1) 提供的基于类型擦除的泛型值语义对象 ystdex::any 等类型实现。允许空值。

@2 框架实现概览：
本章描述 YSLib 项目中的 YFramework/YSLib 库（位于 "/YFramework/YSLib/" 目录下；本章内以下路径表示以此作为根目录）。支持库参见 @5 。
模块化设计原则参见 [Documentation::CommonRules @@3.7.1] 。
一个模块目录([Documentation::ProjectRules @@3.2]) 中的模块组成一个系统。
关于一些文件的文件名的额外约定参见 @2.9.1 。

@2.1 名称和命名空间规则：
名称使用前提约束：参见 [Documentation::CommonRules @@5.2] 。

@2.1.1 文件名和目录名：
本节适用于代码和相关目录，不适用于文档和相关目录。

@2.1.1.1 长度和可包含的字符：
除 @2.1.1.2 列出的例外，同 Boost 限制，参见 http://www.boost.org/development/requirements.html#Directory_structure 。
 build 275 前在此之上有更强的保证：支持 8.3 文件名兼容性，文件名不使用大写字母，目录名不超过 8 个字符）。
考虑可移植性，在每一个目录下，保证其中所有文件名和目录名中的所有字符使用 std::tolower 转换后得到的文件名不重复。

@2.1.1.2 可包含字符例外：
除了 YBase(@5.2.1) ，在文件名（但对于存在扩展名的文件名，不包含扩展名部分）和目录名中允许使用大写字母。

@2.1.1.3 头文件扩展名：
一般使用 h ，但设计时即确定不需要作为独立翻译单元的实现文件（如仅包含模板的实现或元编程设施）的头文件使用 hpp 。

@2.1.2 源代码一般规则：
使用嵌套命名空间，避免过长的标识符命名。
一个单元可能有多个命名空间。
一个命名空间可能在多个单元中。

@2.1.3 头文件附加准则：
禁止在头文件中使用未命名命名空间(unnamed namespace) ，除非其中仅含 inline 函数和模板或需要和每一个翻译单元独立地相关的对象。
禁止在头文件中使用全局 using 指示，除非是有意的（例如减少别名个数；需在文档中说明）。

@2.1.4 全局名称：
 YSLib 库的根命名空间为 YSLib ，应置于全局命名空间中，即为 ::YSLib 。
根据平台特性增设全局对象的定义位于 YSLib 外部 Helper 库的 YGlobal(@5.5) 中。

@2.1.5 特定引用规则：
 YSLib 默认显式依赖于库 YCLib ，可声明 YCLib 中的名称。具体由适配器系统(@2.6) 决定。

@2.1.6 命名空间分配：
 YSLib::Devices ：设备抽象。
 YSLib::Drawing ：图形处理。
 YSLib::Messaging ：消息机制。
 YSLib::Host ：宿主环境支持，仅在宿主实现的 Helper 库(@5.5) 使用 。
 YSLib::IO ：输入/输出管理。
 YSLib::Shells ：Shell 抽象层。
 YSLib::Text ：文本相关的服务。
 YSLib::Timers ：计时器服务。
 YSLib::UI ：用户界面。
 YSLib::UI::Styles ：用户界面样式定制。

@2.1.7 名称引用限制：
除 Adaptor 外， YSLib 命名空间下不直接使用 YSLib 、 std 和 ystdex 以外的根命名空间以及其中的名称；不直接使用 std::tr1 及其中的名称。
不使用除了 operator new 、 operator new[] 、 operator delete 、 operator delete[] 和 main 以外的全局命名空间中的名称。

@2.1.8 附加名称限制：
不在 Adaptor 和 Helper 等确定可以使用平台相关的代码以外区域使用环境、编译器和版本判断宏。

@2.2 实体实现规则：

@2.2.1 对象准则：
局部对象在声明时同时初始化。
函数内变量尽可能置于最小作用域内——除非效率原因，尽可能使用语句块级对象代替函数级局部对象。
避免在嵌套类中定义被嵌套类的定义，除非能够确保此定义的实现无关性。
有依赖关系的全局对象应置于同一编译单元内。
禁止使用函数返回值初始化全局对象。
除非程序明确为单线程的，禁止使用非 POD(plain-old data) 类型的全局对象。若非必要，用内建 (built-in) 类型代替 POD 结构体全局对象。
多线程程序中，禁止使用非 const 全局对象。

@2.2.2 对象引用和所有权管理：
基本概念参见 [Documentation::CommonRules @@2.3.3] 。
注意基于非透明引用计数实现的非侵入式智能指针（如 boost::shared_ptr/std::tr1::shared_ptr 以及 C++11 的 std::shared_ptr ）具有以下固有的缺点：
无法修改引用计数并直接转移所有权，资源实例的生存期依赖于至少一个具体智能指针对象的生存期；
资源实例对智能指针对象的上述依赖性导致智能指针类型入侵用户程序接口；
并非完全的非侵入式实现（例如可能依赖于 enable_shared_from_this 等），可能入侵客户资源实现，导致耦合扩散；
用户程序无法显式指定引用计数操作而造成不必要的性能负担（特别是异步流程中，无法进行基于调用栈的引用计数优化）。
为了克服前三个缺点，可以使用侵入式方案代替，但可能会引起额外的编码复杂度。最后一个缺点所在的场景一般不适合使用引用计数策略（尽管改用侵入式引用计数方案可能减小开销）。
因此 YSLib 仅在必要时使用基于此类智能指针实现的句柄，如跨 Shell 资源传递（包括 Shell 类实例本身）。
注意此时尽管和非句柄意义下的智能指针类型相同，但意义不同，除特殊情况外（如和内建指针直接比较；需在对应实现处注释）应避免通过 get 成员或 ystdex::raw 等直接使用对应的内建指针值。
对于需要保持所有权但又要避免重复引用计数的开销的情况，使用 std::unique_ptr 。
其它情况下，使用不含所有权的内建指针，以保持用户程序对资源管理的选择自由和灵活性。若没有在注释或文档注明所有权关系，均应视为由用户程序对象具有指针参数指向对象的所有权。

@2.2.2.1 所有权标签：
以下独占所有权关系中，被托管对象类不是直接的成员或明确具有所有权语义的指针指向的对象。使用 OwnershipTag 模版标识这些类型。
所有者（基类）中 private 继承了 OwnershipTag<_type> 。被托管对象的实际类型可能是 _type 的派生类。实例包括：
 Drawing::FontCache 具有 Drawing::Typeface 和 Drawing::FontFamily 的所有权；
 UI::MenuHost 具有 UI::Menu 的所有权；
 Text::TextMap 及其派生类 Text::TextFileBuffer 具有 Text::TextBlock 的所有权。
可以使用 HasOwnership<_tOwner, _type> 判断 _tOwner 是否具有 _type 成员的所有权。

@2.3 语言特性扩展支持：
位于 YBase(@5.2.1) 或 YFrameowrk::YSLib::Core(@2.5) 中。

@2.3.1 接口

@2.3.2 断言

@2.3.3 成员函数简写（代码生成器）

@2.4 类型构建：

@2.4.1 基本约束：
命名必须和标识符命名规约(@4) 兼容。

@2.4.2 类型特性：
除了 I 和 A 前缀的类，都不含有纯虚函数。
命名中按以下列出的顺序确定分类。

@2.4.3 I 前缀类名的类：
接口类型([Documentation::CommonRules @@2.4.1]) 或纯虚类。

@2.4.4 A 前缀类名的类：
抽象类。
成员函数中至少存在一个纯虚函数；不能被实例化。

@2.4.5 S 前缀类名的类：
静态类。
除了类型定义外，应仅包含静态成员。但编译时不作检查。
可参与多重继承，例如作为特征类(traits class) 。

@2.4.6 M 前缀类名的类：
模块类。
具有 public 或 protected 的无参数（或所有参数都有默认参数）的构造函数。不一定能够被复制构造（可能显式地被禁止）。
用于提供实现而非规范接口，可定义人本接口成员。
作为混入(mixin) 类的实现：强调可以参与多重继承组合为其它模块类和一般构件类，也包括被参数化（作为模板类型参数）以构建这些类。
当作为非多态类时析构函数应为 protected （除非它的所有派生类都没有在它的基础上扩展域，或都满足析构函数为 protected ），且不可作为类的成员或被实例化。
其它情况下可实例化，但通常仅用于作为类实例的子对象（混入实例）。此时应尽可能减少虚表体积，并降低额外的运行时效率开销（例如，不使用引用类型的成员）。

@2.4.7 H 前缀类名的类型：
从属于相近但不同的两类：
句柄(handles) ：具有间接访问语义的类型（例如指针、引用或迭代器）。
处理器(handlers) ：具有回调功能的类型（例如事件处理器或 std::function 的实例）。

@2.4.8 无前缀类名的类型：
一般类型。
其它类型。无其它限制和特性保证。

@2.4.9 异常类总览：
专用于被 C++ 异常机制捕获的类称为异常类。
异常类不在特定的命名空间中定义。
标准库异常类以外， YSLib 仅使用派生自 YSLib::Exceptions::Exception 异常类。
以下是 YSLib 命名空间中一般的异常类列表：
 YException 单元中：
 Exception ：YSLib 异常基类。
 GeneralEvent ：一般异常事件类。
 LoggedEvent ：记录异常事件类。

@2.5 核心构件系统：
通称 Core ，位于 "/Core" 。
除了核心定义 YSDefinition 以外，主要包含以下几大部分：
不依赖于其它任何头文件的通用基础设施 YBaseMacro ：定义了各种基础平台无关的宏，用于简化代码等；
核心实用模块 YCoreUtilities ；
平台无关的基础对象 YObject ；
对象计数器 YCounter；
函数对象封装 YFunc ；
异常处理模块 YException ；
基础字符串管理 YString ；
平台无关的基础图形学对象 YGDIBase ；
平台无关的设备抽象层 YDevice ；
事件回调 YEvent ；
消息处理 YMessage ；
标准 Shell 消息列表 YMessageDefinition ；
全局静态类型存储管理 YStatic ；
平台无关的文件处理系统 YFileSystem ；
 Shell 定义 YShell ；
系统资源和应用程序实例抽象 YApplication 等。

@2.5.1 核心实用模块 YCoreUtilities

@2.5.2 平台无关的基础对象 YObject

@2.5.3 对象计数器 YCounter

@2.5.4 函数对象封装 YFunc

@2.5.5 异常处理模块 YException ：
参见 @2.4.10 。

@2.5.6 基础字符串管理 YString
通用字符串抽象以及相关 API 。

@2.5.7 平台无关的基础图形学对象 YGDIBase ：

@2.5.7.1 基本屏幕对象：
用于实现二维输出设备参照坐标系(@1.5.2.1) 。
 YSLib 默认使用整数分量坐标，类型为 SPos （平台相关的有符号整数类型），绝对值类型为 SDst （宽度与 SPos 相同的无符号整数类型）。
以此为基础进一步定义了 Point 、 Vec 、 Size 和 Rect 等基本屏幕对象类。
 Point 和 Vec 为 SPos 二元组，具有不同的相关运算集。
 Size 为 SDst 二元组。
 Rect 为标准矩形(@1.5.2.3) ，即边和屏幕坐标系共线的矩形；使用 Point 表示左上角， Size 表示长和宽。

@2.5.7.2 二维图形接口上下文：
表示图形缓冲区及其大小的类。
图形缓冲区指针以 YCLib 定义类型 BitmapPtr 表示。
不对缓冲区具有所有权。

@2.5.7.3 绘制上下文：
用于保存绘制信息的结构体，包含渲染目标、参考位置和剪切区域。
渲染目标是被渲染对象的光栅化直接关联的图形接口上下文。
参考位置指定渲染目标关联的参考点的位置的偏移坐标。如无额外说明，选取渲染目标左上角为原点的屏幕坐标系。
剪切区域是相对于图形接口上下文的标准矩形，指定需要保证被刷新的边界区域。如无额外说明，剪切区域的位置坐标选取渲染目标左上角为原点的屏幕坐标系。

@2.5.8 平台无关的设备抽象层 YDevice ：
位于命名空间 Devices 中。

@2.5.8.1 设备基类：
 GraphicDevice 是输出设备基类。

@2.5.8.2 物理设备：
 Screen 由 GraphicDevice 派生，是二维屏幕的抽象。

@2.5.8.3 虚拟设备：

@2.5.8.3.1 桌面：
桌面是大小和对应输出屏幕相等的窗口（参见 @2.8.1.2.4 ），默认实现为 UI::Desktop 类，除了 YShellDefinition 的前向声明，并非位于 Core 。

@2.5.9 事件回调 YEvent ：
实现事件。
用户界面事件参数基类 UIEventArgs ，可从这个类派生自定义参数类。
除此之外，默认提供以下参数类：
 ScreenPositionEventArgs ，屏幕事件参数类。
 InputEventArgs ，输入事件参数模块类。
 TouchEventArgs ，指针设备输入事件参数类。
 KeyEventArgs ，键盘输入事件参数类。
以下用模板定义用于事件处理机制的接口和实现类：
事件处理器接口模板 GIHEvent ，提供两个参数的 operator() 抽象方法。
事件处理器模板 GHEvent ，标准版 HEvent ；基于 Function 和 list 实现。
事件模板 GEvent 为多播版本。（单播版本已被移除。）
事件依赖项模板 GDependencyEvent ；基于 YObject 单元中的类模板 GDependency 实现共享事件以节约空间。
事件包装类 GEventWrapper ；实现基于复杂性考虑，直接使用 GEvent 而不是 GDependencyEvent 的实例。
事件映射表模板 GEventMap ，映射特定的枚举 ID 到 GEventWrapper 模板实例。

@2.5.9.1 YSLib 标准事件处理实现概述：
仅实现同步事件。
相关概念说明参见 [Documentation::CommonRules @@2.5.1.1] 。

@2.5.9.1.1 单播版本（自 build 204 起被移除）：
添加事件订阅和移除事件订阅的时间复杂度为 O(1) ，同普通的函数指针赋值。调用事件处理器的时间复杂度为 O(1) ，同普通的函数指针调用。

@2.5.9.1.2 多播版本：
使用 std::list 实现的函数对象队列。
调用链维持稳定的顺序（和订阅顺序相同）。
对于重复的事件订阅，允许存在多个实例；也可以在添加时指定仅保留一个实例（移至调用链末尾）。
事件处理器调用顺序由调用链决定。
对于调用链长 n ，添加事件订阅、移除事件订阅、调用事件处理器复杂度相对每个事件处理器调用为 O(n) 。
每个事件处理器调用复杂度同单播版本。

@2.5.10 消息处理 YMessage ：

@2.5.10.1 消息：
在命名空间 YSLib::Messaging 中。
消息类型是 Message 类；
决定消息种类的消息主标识是唯一的，简称为消息标识，它的类型为 ID（本质上是无符号整数）；
库中的 "/Core/ymsgdef.h" 文件预定义了一些消息标识。覆盖这些标识的最小连续区间称为系统消息标识区间。
用户可自定义新的标识（用户自定义消息标识），但不应和原有定义冲突。由于为宏定义实现，可以使多个标识名对应一个实际的标识，但反之无法实现。
应尽可能保持所有用户自定义消息标识在系统消息标识区间之外。
消息的处理的具体实现取决于用户。

@2.5.10.2 消息队列：
消息队列类型是 MessageQueue 类，在逻辑上是一个优先队列。
使用多重集作为消息队列的内部容器实现。
第一优先级为 unsigned char 型变量。

@2.5.10.2.1 自 build 216 起过时的特性：
为了适应不支持 std::clock() 的平台，用消息实例构造时的计数标识代替产生时间作为第二优先级。

@2.5.10.3 消息分派：
 Shell 消息分派实质上是双分派。
由于需要实现运行时可切换的 Shell 来处理不同的消息，以及消息携带语义但并不决定处理逻辑，分派由 Shell 的实现决定。
因此 Shell 类需要是多态类；而消息类不需要是多态类，需要消息标识，且和其它大多数框架不同，默认必须指定的标识数较少。

@2.5.10.4 消息循环：
重复获取、分派并处理消息的程序逻辑称为消息循环。
消息循环总体通常使用默认的消息队列，但由于逻辑上并不总是需要异步操作，也可以使用立即处理非队列消息来提高运行时性能。

@2.5.11 标准 Shell 消息列表 YMessageDefinition
 SM_SET 消息指示 Shell 切换。通过重写 SM_SET 消息处理函数可以控制 Shell 切换前和切换后的行为。

@2.5.12 全局静态类型存储管理 YStatic

@2.5.13 平台无关的文件处理系统 YFileSystem

@2.5.14 Shell 定义 YShell

@2.5.15 系统资源和应用程序实例抽象 YApplication

@2.6 适配器(Adaptor) 系统：
位于 "/Adaptor" 。
负责衔接和封装外部库，便于移植。
除了 C++ 标准库以外，其它外部库的名称需要在此声明。
直接使用除 C++ 标准库、 POSIX / GNU C 兼容函数库、 YCLib 库之外的外部库原代码片段所在文件都从属于 Adaptor 。
除非另有说明，仅保证必要文件(@2.9.1) 提供接口中的可重入性和线程安全性同本体(@2.9) 。

@2.6.1 外部库关联 YAdaptor ：
默认行为如下：
包含 "ynew.h" ，引入平台设置和存储调试设施(@2.6.2) 。
包含 YBase 依赖项(@5) <ystdex/functional.hpp> 和 <ystdex/utility.hpp> 。
包含 <YCLib/ycommon.h> 、 <YCLib/FileSystem.h> 和 <YCLib/Video.h> 。
包含 CHRLib (@5.4.1) （<CHRLib/chrlib.h>）。
在 YSLib 命名空间 using 引用必要的名称。

@2.6.2 内存调试设施 YNew ：
默认包含编译配置、平台支持文件 <Platform.h>(@5.2.2.3.1) 和通用基础设施(@2.6.2) 。
定义宏 YSL_USE_MEMORY_DEBUG 后（默认 debug 配置在 "config.h" 有此定义）可以使用 "ynew.h" 声明的宏和类进行内存调试。
重载全局 operator new 和 operator delete 可以用于用户程序调试（ YSLib 中默认并不使用）。
 MemoryList 用于跟踪记录已分配的内存块。 debug 配置下默认定义了一个函数内静态对象，用函数 GetDebugMemoryList 取此对象引用获得默认调试内存信息。
可以用宏 ynew 代替 new/new[] ， ydelete 代替 delete ， ydelete_array 代替 delete[] ，配合 GetDebugMemoryList 检测内存泄露以及重复释放错误；但不适于智能指针，因为未使用 ydelete 和 ydelete_array 。
 YNew 的接口不保证可重入性，暂时不支持线程安全性。

@2.6.3 引用对象 YReference ：
在 "yref.hpp" 中声明智能指针等引用对象类型。
可以包装 Loki 或 std::tr1 指针智能等实现。
 YSLib 早期包装 Loki 指针实现句柄；
 build 208 起包装 ISO C++11 标准库智能指针实现；
 build 210 开始直接使用 ISO C++11 标准库智能指针作为句柄。

@2.6.4 平台无关的字体缓存库 Font ：
基本接口平台无关，但可能提供平台相关的扩展接口，实现也是平台相关的，因此在 Adaptor 中。

@2.7 服务系统：
位于 "/Service" 。
对以上组成部分提供内部和外部的常用功能的实现与封装。
提供辅助性接口供用户程序使用。

@2.7.1 计时器服务 YTimer

@2.7.2 图形库

@2.7.2.1 平台无关的图形设备接口 YGDI

@2.7.2.2 平台无关的二维图形光栅化 YDraw

@2.7.2.3 平台无关的图像块操作 YBlit

@2.7.3 基础文本显示：
通用的字符/字符串光栅化处理。字符串本身的逻辑处理在 Core::YString 中，而不在此处。

@2.7.3.1 文本基础抽象 TextBase ：
包含笔样式 PenStyle 、文本状态 TextState 等。

@2.7.3.2 字符渲染 CharRenderer ：
单一字符渲染的例程。

@2.7.3.3 文本渲染 TextRenderer ：
文本渲染器和批量文本（字符串、行等）渲染。

@2.7.3.4 文本布局 TextLayout ：
提供文本相关位置和大小等布局计算。

@2.7.4 应用程序资源管理模块 YResource

@2.7.5 文件抽象

@2.7.5.1 平台无关的文件抽象 YFile

@2.7.5.2 平台无关的文本文件抽象 YFile_(Text)

@2.7.6 扩展服务

@2.7.6.1 文本管理类 TextManager

@2.8 组件和界面系统：
位于 "/UI" 。
包含基本的部件/控件抽象、图形界面中较常用绘图例程以及样式管理。
更基本的图形抽象、绘图/图像处理例程和图像资源管理则来自于 Core::YGDIBase 、 Service::YGDI 和 Service::YResource 。
组件 (Component) 是具有一定相互联系的功能集合单元。
组件类是非抽象类，默认基类为 YComponent ，继承自 YCountableObject，可以引用方式作为参数传递。
组件对 GUI 对象进行直接支持。包含部件和控件类：
具有基本屏幕输出效果，实现了部件接口 IWidget 的类，称为部件(Widget) 类；
具有基本屏幕输出效果和公共事件响应能力的部件类，称为控件(Control) 类。
部件仅仅负责 Shell 直接和 UI 相关的部分，默认不包含任何消息处理。
消息应被其从属的 Shell 消息处理过程截获并进行处理。
特定的控件行为由专用公共控制器(@2.8.1.2.3.2) 控制。
其它组件行为原则上直接由 Shell 消息处理过程控制，以避免消息转发带来的开销。

@2.8.1 用于 GUI 的对象特性：

@2.8.1.1 视图组织：
默认为视图树，其中的节点实现了 IWidget 接口(@2.8.1.2.1) 。
 IWidget 支持向上（父节点指针）和向下（子节点迭代器范围）访问视图树中与之直接关联的节点。
 Desktop 作为默认视图树的默认根节点类型。

@2.8.1.2 类组织：

@2.8.1.2.1 部件接口 UI::IWidget ：
 IWidget 除了支持访问视图树关联节点(@2.8.1.1) 外，还包括对部件内部的架构实现代理(@2.8.1.2.1) 的相关操作。所有虚方法可以在容器中重载实现。
功能说明和其它描述参见 @2.8 、 @2.8.1.2.4 。

@2.8.1.2.2 继承：
 GUI 构件相关参见 @2.8.1.2.4 。
视图类、渲染器、控制器分别进行继承。
为了避免虚继承无法静态转换类型以及带来的运行时开销，所有继承除混入(@2.4.6) （一般使用 protected 继承）外都是 public 单继承。

@2.8.1.2.3 部件架构实现代理：
包括视图、控制器、渲染器等，包含在 IWidget 的实现类中，需要实现运行时的代理对象访问以及渲染器的设置。

@2.8.1.2.3.1 视图：
默认视图类 UI::View ，由基类 UI::Visual 提供基本的视图属性，并包含了焦点。

@2.8.1.2.3.2 专用公共控制器：
默认实现的专用公共控制器基类是 AController 。
 AController 使用事件机制(@2.8.2) 提供控制（在运行期加载供回调的函数）。

@2.8.1.2.3.3 渲染器：
参见 @2.8.5.2.1 。

@2.8.1.2.4 主要 GUI 元素的具体类：
部件是实现了 IWidget 接口的类，是基本的 GUI 对象类。
部件容器是包含子部件的部件，是一般化的组件容器，它能以可视化方式处理其包含的部件（例如顺序显示）。部件树的非叶节点是部件容器。
和部件树的抽象结构不同，部件类保存指向容器的指针，而容器是否保存的子部件指针由具体容器（部件派生类）的实现决定。
应重写成员方法 GetChildren 以便保证部件树节点遍历的正确行为。
控件是使用非空控制器的具有事件响应特性的部件，默认继承 YControl 单元中提供的 Control 类实现。
窗口是继承 Window 类的类，是一种具有背景显示功能的部件容器。
窗体（基类为 Form ）是增加了客户区布局管理的标准窗口。
默认组件中，除继承自窗口的组件（基类为 Frame ，缓冲区继承自类 BitmapBuffer ）外，所有部件默认不带显示缓冲区。实际使用时可以用其它类型成员（如 TextRegion ）提供显示缓冲区。

@2.8.1.2.5 辅助类：
默认提供基本事件回调模板类，以方便用户实现消息映射和其它间接传递消息的功能。
此外，还提供对默认 GUI 输入事件的参数类。

@2.8.2 GUI 事件：

@2.8.2.1 默认 GUI 事件：
即 YWidgetEvent 单元中定义的标准部件事件，发送对象类型为 IWidget 。
参数类型总是 UIEventArgs 及其派生类，包含发送对象类型，通过 UIEventArgs::GetSender 取得发送对象的引用。
事件依赖项仅对非映射事件使用。相关类参见 @2.5.9 。
默认 GUI 事件使用 Core::YEvent 等单元实现，和 YWidget 、 YControl 和 YGUI 单元相关。
在 YWidgetEvent 单元中的枚举类型 typedef 名称 VisualEvent 定义了标准控件事件空间，其中定义了标准控件事件，包含视图变更事件、 GUI 输入/输出事件和焦点事件。
 GUI 输入事件包含基本 GUI 输入事件和扩展 GUI 输入事件，参见 @2.8.2.1.2 。
事件参数类型由 RoutedEventArgs 派生的称为路由事件。
路由事件的路由策略分为三类： Tunnel 、 Direct 和 Bubble 。
 Tunnel 事件在处理事件的根部件进入子部件时依序触发， Direct 事件在定位至部件时触发， Bubble 事件在之后子部件退出至根部件时依序触发。
当 Tunnel 事件非可视(visible) 或非启用(enabled) 时事件路由终止。
当参数中的处理标记（数据成员 Handled ）被设置为 true 时，事件路由终止。
基本 GUI 输入事件是路由事件，参见 @2.8.2.1.2 。

@2.8.2.1.1 视图变更事件：
包括 Move 、 Resize 事件等。
事件参数类型 UIEventArgs ，事件类型为 HUIEvent 。
在试图变更视图时触发。
需要注意，不包括必然的视图改变后置条件。即使设置控件视图操作的结果与未设置时相同，仍触发事件。

@2.8.2.1.1.1 Move 事件：
设置控件位置后触发。
默认通过调用 UI::SetLocationOf 触发，此时发送对象和订阅者相同。

@2.8.2.1.1.2 Resize 事件：
设置控件大小后触发。
默认通过调用 UI::SetSizeOf 触发，此时事件发送者和订阅者相同。

@2.8.2.1.2 GUI 输入事件：
基本用户界面输入事件是 GUI 输入直接引起的事件，分为基本按键输入事件和基本指针设备（屏幕光标定位设备）输入事件。
默认通过 GUIState 实现的事件参数中，除了 TouchHeld 外，事件发送者和订阅者相同。

@2.8.2.1.2.1 基本按键输入事件：
基本按键输入事件包含 KeyUp 、 KeyDown 和 KeyHeld 。

@2.8.2.1.2.2 基本指针设备输入（触摸屏输入）事件：
基本指针设备输入事件包含 TouchUp 、 TouchDown 和 TouchHeld 。
默认通过 GUIState 实现的 TouchHeld 事件当且仅当触摸移动的部件和开始接触时不同时，事件发送者和订阅者不同。订阅者总是开始接触时的部件。

@2.8.2.1.2.3 扩展 GUI 输入事件：
扩展 GUI 输入事件有以下几类：复合事件（包括 KeyPress 、 Click 、TouchMove ）、边界事件（包括 Enter 和 Leave ，参见 @2.8.2.1.5 ）等。

@2.8.2.1.2.4 输入事件路由：
事件路由通过 YGUI 单元中的 GUIState 类实现。包括按键输入事件 KeyUp 、 KeyDown 、 KeyHeld 和 KeyPress；指针设备（屏幕光标定位设备）接触事件 TouchUp 、TouchDown 、 TouchHeld 、 TouchMove 和 Click 。
触发过程：由 Helper 中的单元完成平台相关的用户输入信号捕获并向 YGUI 单元的 GUIState 类的全局实例传递，后者处理后生成对应输入事件。
当用户按键时，触发 KeyDown 事件；持续时触发 KeyHeld 事件；结束时依次触发 KeyUp 和 KeyPress 事件。
当用户使用指针设备（包括触摸屏）输入时，依此触发 Enter(@2.8.2.1.5) 和 TouchDown 事件；持续时触发 TouchHeld 事件；持续且移动时可触发 TouchMove 事件；结束时依次触发 TouchUp 、Leave(@2.8.2.1.5) 和 Click 事件。
注意非直接事件路由中 TouchHeld 不被触发。当 TouchHeld 被触发时，即使路由策略是 Direct ，也有可能因为其它部件移动而导致状态不一致。因此在 TouchHeld 的事件处理器中需要注意校验发送者是否符合预期。

@2.8.2.1.2.5 指针设备坐标状态：
指针设备相关事件中，参数包含了相对于部件的坐标。
最近操作的坐标保存于全局变量 ControlLocation 中。
拖放操作依赖的最近坐标保存于全局变量 LastControlLocation 中。

@2.8.2.1.2.6 默认输入事件处理器：
在 YControl 单元中定义了主要的事件处理器。
 Control 类处理 TouchDown 事件，调用函数 RequestFocus 向容器请求焦点。若请求成功，则默认当前控件以外的控件失去焦点（触发 LostFocus 事件），之后当前控件获得焦点（触发 GotFocus 事件）。

@2.8.2.1.3 GUI 输出事件：
 Paint 事件在绘制界面时触发，表示事件订阅者应对发送者进行渲染等操作以便完成绘制。
 Paint 事件的参数中包含上下文信息 PaintContext ，表示绘制必要的信息，如重绘区域 ClipArea 。
默认通过 YRenderer 单元实现。事件发送者为被绘制的部件，订阅者为实际提供绘制方法的部件。

@2.8.2.1.4 焦点事件：
包括 GotFocus 和 LostFocus 事件。
默认通过 YFocus 单元实现。事件发送者为引起焦点变化的部件，订阅者为实际发生焦点改变的部件。
触发条件参见 @2.8.4 。
功能概述参见 @1.6.2.7 。

@2.8.2.1.5 边界事件：
包括 Enter 和 Leave 事件。
默认通过 GUIState 实现，事件发送者和订阅者相同。
指针设备作用于部件，触发 TouchDown 事件之前判断输入焦点时触发 Enter 事件；触发 TouchHeld 同时移动指针设备出入控件边界可触发 Leave 和 Enter 事件； TouchUp 事件触发后触发 Leave 事件。
边界事件的事件源是被作用的边界对应的部件，且参数坐标相对于此部件。

@2.8.2.2 公用和扩展事件处理程序：
 YControl 单元中定义了部分非成员函数公用事件处理器。
 OnKeyHeld 使用 RepeatHeld 产生有延迟的连续按键输入。
 OnTouchHeld 是 Control 默认加载的 TouchHeld 事件处理器，在其中实现记录坐标偏移（用于拖放）或触发 TouchMove 事件。
 OnTouchMove 可结合 OnTouchHeld 用于处理 TouchMove 事件实现重复触发 TouchDown 事件。
 OnTouchMove_Dragging 可结合 OnTouchHeld 实现控件拖曳。

@2.8.2.3 默认实现细节：
默认的事件处理器不适用虚函数，以免在基类添加事件后，在派生类重复添加事件响应。
默认的事件处理器可以是 lambda 表达式。
在派生类定义的和基类同名的事件响应函数（函数名以 On 起始）会被隐藏而不是覆盖基类的事件响应函数，是非 public 方法。一般应避免在类实现外部调用响应函数。
 Control 类在构造函数中添加了 GotFocus 、 LostFocus 、 TouchDown 、 TouchHeld 的事件处理器，且除了 TouchHeld 外，都是 Control 的成员函数。

@2.8.2.2 自定义 GUI 事件：
和 YGUI 等单元相关的自定义事件，一般使用 YEvent 等单元实现。可以使用 GDependencyEvent 节约存储。

@2.8.2.3 GUI 事件组映射：
事件组映射通过 std::function 等返回被映射事件的参数，并传递给特定的用于映射的事件处理器。
 Control 类使用 BoundControlPtr 取按键-指针设备输入事件映射的控件，默认实现使用 GetBoundControlPtr 。

@2.8.3 GUI 输入控制器：
由于设备的特点， GUI 输入相对于输出而言是容易规格化的。因此在 YControl 单元中定义了一些默认 GUI 输入事件（参见 @2.8.2.1 ），且在 YGUI 单元中定义了若干函数/类用于处理默认 GUI 输入事件。
默认实现输入输出消息及输入状态寄存的控制器类是 GUIState ，同时是输入事件的触发器。
在默认的控件实现中，使用上述的默认 GUI 输入处理程序作为调度控件行为的控制器。在自定义控件实现中，可以另行定义控制器。

@2.8.4 用于 GUI 的焦点特性：
概述：参见 @1.6.2.7 。

@2.8.4.1 焦点污染：
焦点默认和请求/响应双方相关，而和其它对象无关。即 RequestFocus 函数应只改变主调对象及其响应对象中描述焦点的状态域，而不产生副作用。
可以在 GotFocus 和 LostFocus 的响应函数中添加相关代码改变这一特性，但会使主调对象和其它对象产生额外的关联。这种关联不符合焦点本身的语义，且难以调试，如非必要，应避免。

@2.8.4.2 焦点请求链：
在排除 @2.8.4.1 中叙述的副作用的情况下，可以认为不同对象的 RequestFocus 的调用是顺序无关的，可以任意调度。
使用 YGUI 单元声明的函数 void RequestFocusCascade(UI::IWidget&) 可以实现由 IWidget 对象自下向上的嵌套容器焦点申请。注意，会以相同的顺序触发 GotFocus 事件。

@2.8.4.3 默认实现综述：
具有焦点响应能力（即储存了关于集中焦点于特定的子对象的状态）的类称为焦点响应类。
默认通过组合 WidgetView 保存的部件焦点指针实现焦点响应类。
部件容器需要实现明确的响应焦点的请求和释放操作。
在 GUI Shell 实现中独立保存额外的控件独立焦点指针，捕获自由状态的控件指针并判断是否能够据此调用 KeyPress 或 Click 事件。
为了支持拖放操作，索引控件时，按位置判断作用的控件并根据上述 Shell 中的独立焦点指针和状态变量判断附加操作，而不通过上述的通用焦点。

@2.8.4.3.1 实例：
 Desktop 和 Form 是 IWidget 的焦点响应类。

@2.8.5 默认 GUI 响应流程：

@2.8.5.1 概述：
用户进行 GUI 输入；
控制器捕获 GUI 输入产生 GUI 输入事件；
视图或控制器处理 GUI 输入事件，必要时呈递至模型，并向视图同步模型数据；
视图向用户呈现 GUI 数据。
以上流程在组合构件中可以有相应细节上的变化，但步骤之间的顺序不变。

@2.8.5.2 默认 GUI 渲染逻辑：
使用视图信息（渲染状态等）和指定的部件对部件指定的缓冲区进行渲染。具体内容由视图的实现定义。
重绘信息(@2.8.2.1.3) 是由外部直接或间接的参数。

@2.8.5.2.1 渲染器(renderer) ：
用于存储渲染状态的类，基类为 Componenets::Renderer 。
此外，提供带有缓冲区和验证(@2.8.5.2.4) 效果的默认缓冲渲染器类 Componenets::BufferedRenderer ，默认仅窗口使用。
渲染器可在运行时向指定部件设置。

@2.8.5.2.2 渲染器绘制(painting) ：
渲染器的使用部件和渲染状态绘制的过程。
 UI::Renderer 的 Paint 方法调用部件的 Paint 事件(@2.8.2.1.3) 。
 UI::BufferedRenderer 的 Paint 方法验证(@2.8.5.2.4) 后更新(@2.8.5.2.5) 。

@2.8.5.2.3 无效化(invalidation) ：
渲染器向上层缓冲区容器请求需要重绘的区域的过程。
请求得到的需要保证之后被重绘的区域在被绘制前表示无效状态。
默认缓冲渲染器通过 Rect 类型的重绘区域保持，称为无效区域。
无效区域长或宽为零时表示重绘已经结束且无新的绘制请求，无需再次重绘。

@2.8.5.2.4 验证(validation) ：
绘制部件并消除自身无效区域的过程。
因为并非所有部件都保存自身无效区域，它们不一定提供验证接口。
部件被验证时，保证缓冲区中若存在无效区域则进行绘制，并消除无效区域。
 UI::BufferedRenderer::Validate(IWidget&, IWidget&, const PaintContext&) 是默认缓冲渲染器提供的接口。

@2.8.5.2.5 更新(updating) ：
缓冲区内的图形信息复制到其它缓冲区的过程。
带缓冲区的部件（包括窗口和桌面）实例存储无效区域状态。
 UI::Update 基于渲染器实现一般的缓冲区复制。
成员方法 Update() 查询区域重绘状态，若区域需要重绘则忽略，否则当上层缓冲区存在时更新至上层缓冲区（对于桌面而言是屏幕）。
在 Shell 处理函数中可以在输入分支后添加对桌面对象的渲染操作以按需要更新最近经过重绘但未经过更新的 GUI 对象：
绘制(@2.8.5.2.2) ；
无效化(@2.8.5.2.3) ，延时绘制；
批量验证(@2.8.5.2.4) 后再更新，避免多个对象直接绘制之间的明显间断。

@2.8.5.3 默认 GUI 绘制(@2.8.5.3.5) 逻辑：

@2.8.5.3.1 渲染状态同步：
部件通过与渲染器的交互保证渲染状态。
部件的无效化是部件通过渲染器向上层缓冲区容器请求需要重绘的区域的过程。
 UI::InvalidateCascade(IWidget&, const Rect&) 通过调用 Validate() 向本层和上层缓冲区（若存在）传递相对于部件的标准矩形区域无效状态，以便被重绘。
 UI::Invalidate(IWidget&) 是使用部件自身区域为参数调用 InvalidateCascade 的人本接口。

@2.8.5.3.2 刷新(refreshing) ：
具体部件按传入的参数（图形接口上下文、起始偏移坐标和边界）直接进行绘制的过程。不被渲染器策略直接影响。
边界基于部件坐标系，用于优化暗示，可以被忽略，但是刷新过程需要保证边界内的区域无需被重绘。
带缓冲区的部件（包括窗口和桌面）实例存储刷新状态。
通常应实现为 Paint 事件的处理器。
 Widget 的虚成员方法 void Refresh(PaintEventArgs&&) 是状态无关的默认刷新接口，即直接绘制部件界面。
 Widget 初始化 Paint 事件时加载背景和 Refresh 作为事件处理器。

@2.8.5.3.3 部件绘制(painting) ：
对部件进行导致部件的 Paint 事件被调用一次的操作，称为一次绘制，包括直接调用部件的 Paint 事件和通过其它函数进行间接调用。
一般可以通过 YWidget 单元的 PaintChild 等函数调用，它包含了重绘区域(@2.8.2.1.3) 预验证：当重绘区域和无效区域(@2.8.5.2.3) 不相交时，不进行绘制。

@2.8.5.3.4 描画(drawing) ：
绘制过程中的某一相关组成部分，但不直接导致 Paint 事件被调用。

@2.8.5.3.5 绘制：
含义清楚，不至于造成歧义时，描画可和上述部件渲染器绘制、部件绘制称为绘制。

@2.8.5.3.6 全局层次绘制逻辑：
一般通过 Shell 对 SM_PAINT 消息的处理，以桌面对象的全局绘制操作起始，递归至各个子部件。
典型的全局绘制操作可以是刷新。
当多个桌面的显示需要保持同步时，一般不直接调用刷新，而是显式地验证和更新，即分别调用需要同步显示的桌面的 Desktop::Validate 和 Desktop::Update 。

@2.8.6 GUI 特性抽象

@2.8.6.1 GUI 样式 YStyle

@2.8.6.2 GUI 焦点特性 YFocus

@2.8.6.3 平台无关的 GUI YGUI

@2.8.7 组件

@2.8.7.1 平台无关的 Shell 组件 YComponent

@2.8.7.2 控制台

@2.8.8 默认部件

@2.8.8.1 样式无关的 GUI 部件 YWidget ：
主要类型：
 Renderer 类；
 BufferedRenderer 类；
 IWidget 接口；
 Visual 类；
 Widget 类。
渲染器 BufferedRenderer 可以设置是否忽略背景（注意忽略背景可能影响子部件的渲染行为）。

@2.8.8.2 样式无关的 GUI 容器 YUIContainer ：
主要类型：
 MUIContainer 类。

@2.8.9 默认控件

@2.8.9.1 样式无关的控件 YControl ：
主要类型：
 Control 类。

@2.8.9.2 样式无关的 GUI 面板 Panel ：
主要类型：
 Panel 类。

@2.8.9.3 样式无关的 GUI 窗口 YWindow ：
主要类型：
 Window 类。

@2.8.9.4 桌面 YDesktop ：
命名空间 UI 中的 Desktop 类是桌面的抽象，自带显示缓冲区，和 Screen 关联，负责把窗体和其它桌面对象输出至屏幕。

@2.8.10 扩展部件

@2.8.10.1 样式无关的用户界面标签 Label ：
主要类型：
 Label 类。

@2.8.11 扩展控件

@2.9 本体和文件依赖性：
本体是以上 YSLib 构成单元中，除了 Adaptor 以外的部分的总称，是平台中立的。
非本体是本体在 YSLib 中的补集，即 Adaptor ，接口是平台中立的。
 Adaptor 的改变很可能导致整个本体中的很一大部分翻译单元的重新编译。
因此除非是用来实现基本功能的外部的库，新增的平台相关的部分应尽量放在外部的 Helper 库(@5.5) 而不是 Adaptor 中。
除非另有说明，仅保证非成员函数（排除声明紧随于某个类之后，首个参数为该类类型引用的人本接口）和静态成员函数的可重入性和线程安全性。
以下节指定 YFramework 中明确或明确禁止依赖的文件。关于 YBase 的文件依赖性参见 @5.2.1.2 。

@2.9.1 基本代码依赖性（适用于 YFramework 内部）：
 YSLib 文件中，文件名以 y 或 Y 起始且非限定模块名以 Y 起始的文件为必要文件，其它为非必要文件。
关于 ISO C++ 2011 直接指定的依赖项，参考 [Documentation::CommonRules @@5.25.2] 。
以下为基本代码依赖性规则（以优先级顺序排列，即后者不满足前者的部分以前者为准）：
除非另有说明，禁止依赖于（包括包含）非头文件。
除非另有说明，禁止重复包含同一文件，避免造成循环依赖。
 YSLib/Adaptor 中的 config.h 不依赖 YCLib/Platform.h 以外的其它文件，仅可被 YSLib/Adaptor 中的头文件直接包含。
任意 YFramework 文件可依赖 @2.9 余下部分指定的标准库头文件以及 YBase 头文件。
必要文件不依赖非必要文件。
 YCLib 中除 YCLib/Platform.h 外的文件仅可被 YCLib 、 YSLib 和 Helper 依赖。
除 YSLib/Adaptor/yadaptor.h 外， YSLib/Adaptor 头文件不依赖 YCLib/ycommon.h 以外的 YCLib 文件。
 YSLib/Adaptor 头文件可依赖 YFramework 文件或标准库实现的非标准头文件。
本体头文件不依赖 YSLib 以外的文件。
 Helper 文件和本体的非必要源文件可依赖除 YSLib 和 Helper 外的 YFramework 其它文件（包括 YCLib 文件）。
 YCLib 和 Helper 文件可依赖具体平台相关的文件。

@2.9.1.1 引入自 C 标准库的 C++ 标准库头文件依赖项：
不在本体的必要文件中显式包含，除了以下例外：
 "ydaptor.h" 需要保证 <cstddef> 、 <cstdint> 、 <climits> 和 <cmath> 被包含；

@2.9.1.2 不在本体中显式包含，需要在 "ycont.h" 包含或提供替代品的 C++ 标准库依赖项：
 <array> 、 <deque> 、 <forward_list> 、 <list> 、 <map> 、 <queue> 、 <set> 、 <stack> 、 <string> 、 <unordered_map> 、 <unordered_set> 、 <utility> 和  <vector>。
例外：同时需要使用容器和限定标准库类型时：
 "yexcept.h" 包含 <string> （鉴于复用标准库异常需要的参数类型 std::string 不一定是 "ycont.h" 配置的类型）。

@2.9.1.3 不在本体的头文件中显式包含，需要在除了 "ycont.h" 的 Adaptor 的必要头文件直接或间接包含的 C++ 标准库依赖项：
 <algorithm> 、 <memory> 、 <new> 、 <type_traits> 。
 "yadaptor.h" 需要保证 <bitset> 和 <initializer_list> 被包含。

@2.9.1.4 不在本体或 Adaptor 的头文件中显式包含的 C++ 标准库依赖项：
基于性能、兼容性或其它因素考虑，Adaptor 和本体不直接使用以下头文件及唯一在其中声明的接口（但 Adaptor 可能会间接依赖）：
 <fstream> 、 <iomanip> 、 <iostream> 、 <istream> 、 <locale>、 <ostream> 、 <sstream> 、 <streambuf> 和 <strstream> 。
其它要点参见 [Documentation::CommonRules @@5.22] 。

@2.9.1.5 本体的头文件中显式包含的 C++ 标准库依赖项：
 "Core/yexcept.h" 包含 <exception> 和 <stdexcept> ；
 "Core/yfunc.hpp" 包含 <functional> 和 <typeinfo> ；
 "Service/ytimer.h" 包含 <chrono> 。
其它： <iterator> 。

@2.9.1.6 本体的头文件中未限定（可能会在将来版本显式包含）的 C++ 标准库依赖项：
 <bitset> 、 <codecvt> 、 <complex> 、 <condition_variable> 、 <future> 、 <limits> 、 <mutex> 、 <numeric> 、 <random> 、 <ratio> 、 <system_error> 、 <thread> 、 <typeindex> 和 <valarray> 。

@2.9.2 本体头文件对 YBase 依赖性：
 "yblit.h" 依赖于 <ystdex/algorithm.hpp> 和 <ystdex/iterator.hpp> 。

@2.9.3 本体内部头文件依赖性：
 Core 的头文件仅包含 Adaptor 或 Core 的头文件。
 Adaptor 的头文件依赖于 Core 的 "ybasemac.h" 。
实现源文件依赖于同名头文件，应保证包含此头文件，但不重复包含此头文件已经包含的其它头文件。
在 Core 中，以下依赖关系对于头文件包含是确定的：
 "ybasemac.h" 不依赖于任何其它文件；
 "ysdef.h" 依赖于 Adaptor 的 "yadaptor.h" 和 "yref.hpp" ；
除了 "ybasemac.h" 和 "ysdef.h" 外都直接或间接依赖于 "ysdef.h"；
 "yobject.h" 依赖于 "ycutil.h" 和 "yexcept.h" ；
 "ystring.h" 、 "ymsg.h" 依赖于 "yobject.h" ；
 "ystring.h" 依赖于 Adaptor 的 "YTextBase.h" ；
 "yevt.hpp" 依赖于 "yobject.h" 和 "yfunc.hpp" ；
 "ymsgdef.h" 依赖于 "ymsg.h" ；
 "yshell.h" 依赖于 "ymsgdef.h" ；
 "yfilesys.h" 依赖于 "ystring.h"；
 "yapp.h" 依赖于 "yfilesys.h" 和 "yshell.h" 。
在 Service 中，以下依赖关系对于头文件包含是确定的：
 "ytimer.h" 依赖于 Core 的 "yobject.h" 和 "ycounter.hpp" ；
 "yblit.h" 、 "ydraw.h" 和 "ygdi.h" 依赖于 Core 的 "ygdibase.h" ；
 "yblit.h" 依赖于 Core 的 "ycutil.h" ；
在 UI 中，以下依赖关系对于头文件包含是确定的：
 "ycomp.h" 依赖于 Core 的 "ygdibase.h" 、 "yfunc.hpp" 和 "ysmsgdef.h" 以及 Adaptor 的 "ycont.h" ；
 "yfocus.hpp" 依赖于 "ycomp.h" ；
 "yrender.h" 依赖于 "ycomp.h" 和 Service 的 "ygdi.h" ；
 "ystyle.h" 依赖于 "ycomp.h" 和 Service 的 "ydraw.h" ；
 "ywgtview.h" 依赖于 "ycomp.h" ；
 "ywgtevt.h" 依赖于 "ycomp.h" 和 Core 的 "yevt.hpp" ；
 "YBrush.h" 依赖于 "ywgtview.h" 和 Service 的 "yres.h" ；
 "ywidget.h" 依赖于 "yfocus.hpp" 和 "ywgtview.h" ；
 "ygui.h" 依赖于 "ywgtevt.h" 、 "ystyle.h" 和 Service 的 "ytimer.h" ；
 "yuicont.h" 依赖于 "ywidget.h" ；
 "ycontrol.h" 依赖于 "ywidget.h" 和 "ywgtevt.h" ；
 "ypanel.h" 依赖于 "ycontrol.h" 和 "yuicont.h" ；
 "ywindow.h" 依赖于 "ypanel.h" 和 Service 的 "yres.h" ；
 "ydesktop.h" 依赖于 "ywindow.h" 、 "yrender.h" 和 Core 的 "ydevice.h" 。
在整个 YSLib 头文件中根据以上确定的依赖关系，包含尽可能少（数量相同时从上至下应用依赖关系）的头文件。

@3 API 设计和风格概述：
基本规则参见 [Documentation::CommonRules @@3] 。

@3.1 类 C 标准库接口：

@3.1.1 内存管理行为：
接口不符合无隐式 malloc 规则 [Documentation::CommonRules @@5.25.3.1] 时必须向用户明确存储所有权。

@3.2 C++ 函数和函数模板：

@3.2.1 成员最小接口：
为了利用以类为单位的封装性（包括访问权限控制），一般类内的成员函数以最小接口为主，而人本接口在类外紧接类定义声明为第一个参数为类的引用类型的非成员函数。
可以适当使用友元简化接口和实现。

@3.2.2 函数参数：
尽量避免使用输出参数，特别是在最小接口中。
合理使用默认函数参数减少需要的函数重载版本。

@3.2.3 模板参数：
合理使用 ISO C++11 支持的函数模板的模板默认参数简化实现，减少需要的函数重载版本。

@3.2.4 SFINAE(substition failure is not an error) 技巧：
使用 SFINAE 进行类型检查，实现复杂的重载匹配。避免暴露过于复杂的接口。
在模板参数或函数参数中使用 ISO C++11 的 std::enable_if 实现 SFINAE 。需要考虑函数签名时，只能使用前者；需要考虑模板和非模板的匹配顺序时，一般使用后者。

@4 标识符命名规约(naming convention) ：
以下是 YSLib 风格标识符的命名规则和约定。

@4.1
参见 [Documentation::CommonRules @@4.1] 。

@4.1.6
基本内容参见 [Documentation::CommonRules @@4.1.6] 。

@4.1.6.1
以 "_y" 起始的标识符保留给 YSLib 库内部实现使用。

@4.1.6.2
以 "INCLUDED_" 起始的标识符专用于头文件包含标识。

@4.1.6.3 模版形式参数前缀：
以下前缀保留给的标识符保留作为模板形式参数的名称：
 "_b" ：布尔类型参数；
 "_f" ：函数/可调用对象(callable object) 类型参数；
 "_i" ：接口（纯虚类）类型参数；
 "_p" ：内建指针类型参数；
 "_r" ：引用类型参数；
 "_t" ：不保证以上类型的其它类型参数；
 "_g" ：泛型类型（模板）参数；
 "_gi" ：泛型接口（纯虚类模板）参数；
 "_gf" ：泛型函数/仿函数模板参数；
 "_v" ：其它非类型参数（值参数）。

@4.1.7 惯用函数命名：
基本内容参见 [Documentation::CommonRules @@4.1.7] 。

@4.1.7.3 YFramework 约定：

@4.1.7.3.1 模式 Fetch* ：
除了 YSLib 中非本体部分，命名空间作用域函数名 Fetch* ：语义近似于 Get*Of ，但遵循以下附加规则：
函数名符合模式 Fetch*Ref 的，返回类型为目标类型的引用或 const 引用类型；
函数名符合模式 Fetch*Ptr 的，返回类型为目标类型的指针、 const 指针或对应的智能指针类型；
目标类型为 POD 类型的，返回类型为目标类型；
其它情况返回类型为目标类型的引用或 const 引用类型。

@4.1.7.3.2 模式 Make* ：
类似 ISO C++ 标准库中的 make_* 。

@4.2 宏名：
基本内容参见 [Documentation::CommonRules @@4.2] 。

代码生成器：用宏展开为一段声明或定义的代码。

@4.2.3 全局保留宏名：
使用 YSLib 前需要保证未定义，且之后无法使用，除非使用 #undef 取消定义。
 YSLib 保留宏名以 "YSL" 起始，其基础库使用保留宏名以 "YCL" 起始。

@4.2.3.1 局部保留宏名：
使用 YSLib 前需要保证未定义，但库实现使用 #undef 限制作用域，因此之后可以使用。
 "This" 和 "CThis" 。

@4.3 类型名：
参见 [Documentation::CommonRules @@4.3] 。

@4.4 标号：
参见 [Documentation::CommonRules @@4.4] 。

@4.5 函数名：
参见 [Documentation::CommonRules @@4.5] 。

@4.6 具名对象：
参见 [Documentation::CommonRules @@4.6] 。

@5 程序部署和用户配置：
依赖项相关定义参见 [Documentation::ProjectRules @@1] 。
项目管理相关定义参见 [Documentation::ProjectRules @@2] 。
本章描述 YSLib 项目中除了 YFramework/YSLib 以外的库。
 YFramework 内包含少量外部依赖性如 FreeType2(@5.4.2) 。
以下如无特别说明，非外部依赖项的根路径取 YFramework 包含目录或源代码目录。

@5.1 平台配置：
平台配置 YCLib 平台定义文件(@5.2.2.3.1) 中定义的可支持平台对应。
当前正式支持的平台：
非宿主实现平台 DS （ Nintendo/iQue DS/DS Lite/DSi/DSi LL 以及 PC 端模拟器 DeSmuMe 等）；
宿主实现平台 MinGW32 （对应三元组 i686-pc-mingw32 及其向前兼容的 i686-w64-mingw32 等）。
目前除了 MinGW32 外，仅使用静态链接库链接至静态或动态目标。

@5.1.1 配置管理：
基本配置管理参见 [Documentation::ProjectRules @@2.1]。
 MinGW32 为 DLL 目标追加对应 debug 和 release 的配置 debug_DLL 和 release_DLL 。

@5.2 基础库：
除了 ISO C++ 标准库外的非外部依赖项：
基于标准库的基础库 YBase ，包含基于标准库的平台中立的扩展 YStandardEx ，独立于 YFramework 。
基于 YBase 的平台隔离用库 YCLib ，包含于 YFramework 中。

@5.2.1 YBase ：
 YBase 除了公用头文件 YDefinition(ydef.h) 外，由 YStandardEx 、 LibDefect 和 YTest 子库组成。
 LibDefect 不保证可重入性，线程安全性由 ISO C++11 规范。
 YBase 和其它模块之间传递的对象类型满足 trivially copyable ，以保证动态库存储安全（参见 [Documentation::CommonRules @@3.7.2] ）。

@5.2.1.1 LibDefect 以外的设计和实现原则：
除了去除后不影响语义正确性的扩展，遵守 ISO C++ ，不使用不兼容于 ISO C++11 的特性或依赖于特定平台实现的接口。但注意 YDefinition 实现及判断语言特性的接口可能依赖于具体语言实现的特性限制。
关于当前允许使用的非 ISO C++03 扩展参见 @1.3.2.1 。
尽量严格遵守 ISO C++11 ，涉及未确定行为和实现定义的行为时应附文档说明。
除非另有说明， YBase 中 LibDefect 以外的接口仅保证非成员或静态成员函数的可重入性和线程安全性。
除非有显著性能问题，否则非成员或静态成员接口应保证线程安全性。
不降低性能时尽量保证可重入性。

@5.2.1.2 文件依赖性：
以下为基本代码依赖性规则按（以优先级顺序排列，即后者不满足前者的部分以前者为准）：
 ydef.h(@5.2.1.3) 仅依赖标准库头文件。
 LibDefect 不包含头文件或仅包含标准库头文件。
 YBase 依赖且仅依赖 YBase 文件和标准库头文件。

@5.2.1.3 YDefinition ：
模块 YBase::YDefinition ，文件名 ydef.h ，是其它 YBase 头文件的公共依赖项。
若其它文件不依赖此文件，则也不依赖其它 YBase 文件。
文件內容为系统环境和公用类型和宏的基础定义，包括对实现环境的检测、实现特性的封装、部分未被实现关键字替代以及一些语言层次上的公共基础设施。

@5.2.1.3.1 宏 yoffsetof ：
同标准库宏 offsetof ，但额外提供了对于可能导致未定义行为的检查。
某些实现（如 GNU C++ ）可能已经自行提供了内建检查，所以此宏并非必要。但为了一致性在库的代码使用此宏。

@5.2.1.3.2 宏 yunseq ：
用于标记无序列依赖表达式组，以支持非序列优化。
参见 [Documentation::CommonRules @@6.4.3.3] 。

@5.2.1.4 YStandardEx ：
 YStandardEx 直接扩充标准库，包含仅依赖于标准库而非标准库的接口。
实现的内容限制为以下两个部分：
适用范围最广的基础设施（比标准库更严格），如序列/非序列调用、通用类型转换、元类型、函数对象、迭代器；
直接基于标准库接口的抽象和封装，如输入/输出抽象。
所有更具体应用问题领域相关的或特定于运行时表达形式相关的操作，如形式语言处理等，都不由 YStandardEx 直接提供接口。

@5.2.1.5 LibDefect ：
用于修正依赖的标准库实现因不完善或配置问题等与标准规定的接口的偏差。

@5.2.1.6 YTest ：
提供软件测试需要的一些功能的辅助库。

@5.2.2 YCLib ：
 YCLib 包含平台相关的 API 包装和若干接口平台中立的独立子库（按头文件路径划分，参见 @5.4.1 ）。
 YCLib 允许接口平台中立的接口具有实现定义的行为差异。
除非另有说明， YCLib 仅保证非成员或静态成员函数的线程安全性。
平台定义文件 Platform.h 不包含其它文件。

@5.2.2.1 环境资源占用：

@5.2.2.1.1 DS 计时器：
 build 291 前占用计时器 0 和计时器 1 。
 build 291 起占用计时器 2 。
占用计时器用于实现计时接口。若用户占用计时器或修改计数，则计时相关接口结果未定义。

@5.2.2.2 实现定义行为：

@5.2.2.2.1 对于未说明字符串参数编码的文件操作接口：
必要时的编码转换使用 CHRLib(@5.4.1) 。
 DS 直接使用 UTF-8 路径，或 UCS-2LE 转换得到的 UTF-8 路径，使用标准库函数或 POSIX 文件操作。
 MinGW32 直接使用 UCS2-LE 作为 UTF-16LE 路径，或 UTF-8 转换得到的 UCL2-LE 路径，使用 _w 起始的 MSVCRT 文件函数。

@5.2.2.3 平台 API 使用策略：

@5.2.2.3.1 Win32 API ：
需要 #undef 消除引起冲突的宏名，尽可能显式使用带后缀的函数（若存在）。
当存在后缀时，一般尽可能使用 W ，因为大部分情况下 W 后缀为原始版本， A 后缀需要转换间接调用 W 后缀版本。
但也存在例外， 如使用 ::OutputDebugStringA 。此时注意应该使相关字符串保持和 ANSI 及相关代码页的编码兼容，一般应仅使用 ASCII 。
不使用被标记为过时的 API 如 IsBadReadPtr 。

@5.2.2.3 平台文件：
引入平台相关特性。

@5.2.2.3.1 <Platform.h> ：
定义了必要的平台支持。
对正式支持的平台定义 YCL_ 起始的宏，保证替换得到的值非零。使用 #if （而不需要 #ifdef ）直接检测这些宏以确定是否支持。

@5.2.2.3.2 <NativeAPI.h> ：
定义了扩展的平台 API 。

@5.2.3 DS 平台库和标准库实现：
目标平台 DS ，实现环境参见 @5.1 。
使用 devkitPro（参见 http://devkitpro.org ） 中的 devkitARM 工具链及库文件的非 debug 版本。
依赖 devkitARM / libnds / default arm7 / libfat 版本：
 build 131 前：
未指定。可使用 devkitARM release 26 - 29 。
 2009-09-20 起：
 libnds 1.3.7 / default arm7 0.5.6 。
 2009-09-22 起：
 devkitARM release 26 / libnds 1.3.8 / libfat 1.0.4 。
 2009-12-12 起：
 devkitARM release 27 / libnds 1.4.0 / default arm7 0.5.8 / libfat 1.0.6 。
 2010-03-25 起：
 devkitARM release 29 / libnds 1.4.3 / default arm7 0.5.12 / libfat 1.0.7 。
 2010-04-06(build 131) 起：
 devkitARM release 30 。
 2010-08-08(build 139) 起：
 devkitARM release 31 / libnds 1.4.5 / default arm7 0.5.14 。
 2010-09-19(build 244) 起：
 default arm7 0.5.15 。
 2010-11-18(build 171) 起：
 devkitARM release 32 / libnds 1.4.8 / default arm7 0.5.17 。
 2011-01-06(build 180) 起：
 libnds 1.4.9 / default arm7 0.5.18 。
 2011-02-16(build 192) 起：
 libnds 1.5.0 / default arm7 0.5.20 / libfat 1.0.9 。
 2011-06-24(build 221) 起：
 devkitARM release 33 / libnds 1.5.0 / default arm7 0.5.20 。
注：文件系统目录访问接口变化，需要使用 devkitARM release 33 或自行配置所需的 POSIX API 。 
 2011-07-03(build 223) 起：
 libnds 1.5.1 / default arm7 0.5.21 。
 2011-07-05(build 223) 起：
 devkitARM release 34 。
 2011-08-27(build 236) 起：
 libnds 1.5.4 / default arm7 0.5.23 。
 2011-10-13(build 252) 起：
 devkitARM release 35 / libfat 1.0.10 。
 2012-03-06(build 291) 起：
 devkitARM release 37 。
 2012-04-12(build 300) 起：
 devkitARM release 38 / libnds 1.5.5 / default arm7 0.5.24 。
 2012-05-03(build 306) 起：
 devkitARM release 39 / libnds 1.5.7 。
 2012-05-14(build 308) 起：
 devkitARM release 40 / libfat 1.0.11 。
 2012-06-29(build 321) 起：
 devkitARM release 41 。

@5.2.4 MinGW32 平台库和标准库实现：
目标三元组(target triplet) i686-w64-mingw32 ，操作系统 Windows XP 及以上。
 build 299 前：
无（不支持的平台）。
 2012-04-09(build 299) 起：
使用 http://code.google.com/p/mingw-builds 的 i686-mingw32-gcc-4.7.0-release-c,c++,fortran-sjlj 。
 2012-06-21(build 319) 起：
使用 http://sourceforge.net/projects/mingwbuilds/files/windows-host/4.7.1/release/i686-mingw-w64-gcc-4.7.1-release-c,c++,fortran-sjlj.7z 。
此版本于 2012-10-06 确认已被移除。
 2012-10-06(build 346) 起：
使用 http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.7.2/32-bit/threads-posix/sjlj/x32-4.7.2-release-posix-sjlj-rev0.7z 。
此版本于 2013-01-20 确认已被重命名为 x32-4.7.2-release-posix-sjlj-rev0.7z 。
 2013-03-23(build 392) 起：
使用 http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.8.0/32-bit/threads-posix/sjlj/x32-4.8.0-release-posix-sjlj-rev0.7z 。

@5.3 通用库：

@5.3.1
 build 207 前使用 Loki 库的智能指针实现句柄。

@5.4 专用库：
包含于 YFramework 中的子库。

@5.4.1 字符表示结构支持库 CHRLib ：
位于 "/CHRLib" 。非外部依赖项。
支持字符相关构造（编码和字符集等）的抽象。
支持特定编码字符串的转换。
参见 [Documentation::CHRLib] 。

@5.4.2
字体输出使用 FreeType2（参见 http://www.freetype.org ） 实现向量字体光栅化支持。

@5.4.2.1 使用版本：
 build 185 前：
头文件版本： 2.3.12 。
库文件版本：在 VNDS 源代码中提取的 2.3.6 。
 build 185 起：
头文件版本： 2.4.4 。
库文件版本：使用当时 devkitPro(@5.2.3) 编译的对应版本，使用 makefile 宏 CFLAGS ?= -c -g -O3 -Wall 。
库配置： modules.cfg 配置包含以下有效行：
FONT_MODULES += truetype
FONT_MODULES += sfnt
HINTING_MODULES += autofit
HINTING_MODULES += pshinter
RASTER_MODULES += smooth
AUX_MODULES += cache
AUX_MODULES += gzip
AUX_MODULES += psnames
BASE_EXTENSIONS += ftbitmap.c
BASE_EXTENSIONS += ftglyph.c
使用 makefile 宏 CFLAGS ?= -c -g -O3 -Wall 。
 build 223 rev 31 起：
头文件版本： 2.4.5 。
库配置：  modules.cfg 配置追加以下有效行：
BASE_EXTENSIONS += ftbbox.c
BASE_EXTENSIONS += ftstroke.c
BASE_EXTENSIONS += ftsynth.c
其它配置不变。
 build 224 rev 34 起：
使用 2.4.4 的 /src/cache 源文件代替 2.4.5 对应部分并重新编译库文件（以修正不明原因的 FontCache::GetAscender 的结果错误）。
其它配置不变。
 build 266 起：
头文件版本： 2.4.8 。
库文件版本：使用 2.4.4 的 /src/cache 源文件代替 2.4.8 对应部分，用当时 devkitPro(@5.2.3) 编译的对应版本。
其它配置不变。
 build 292 起：
头文件版本： 2.4.9 。
库文件版本： 2.4.9 用 devkitPro(@5.2.3) 编译的对应版本。
 build 299 起：
增加 MinGW32 库文件版本： 2.4.9 用当时 MinGW32(@5.2.4) 编译的对应版本，使用 mingw32-make 直接构建默认提供的 makefile 。
 modules.cfg 配置不变。
 build 318 起：
头文件版本： 2.4.10 。
 DS 库文件版本： 2.4.10 使用 devkitPro 编译的对应版本。
 MinGW32 库文件版本： 2.4.10 用当时 MinGW32(@5.2.4) 编译的对应版本。
其它配置不变。
 2012-12-21(build 366) 起：
头文件版本： 2.4.11 。
 DS 库文件版本： 2.4.11 使用 devkitPro(@5.2.3) 编译的对应版本。
 MinGW32 库文件版本： 2.4.11 用当时 MinGW32(@5.2.4) 编译的对应版本。
其它配置不变。

@5.4.3
图形库：修正的 Anti-Grain Geometry 库 V2.4 。
已移除。

@5.5 助手(Helper) 库：
位于 "/Helper" 。非外部依赖项。
可能平台相关的外部库，可以提供宿主实现、加入插件等，一般由库用户自行配置。
除非另有说明，仅保证必要文件(@2.9.1) 提供接口中的可重入性和线程安全性同本体(@2.9) 。其它文件应明确非成员函数和静态成员函数的可重入性和线程安全性。
 YGlobal 是不可缺少的，它封装了必要的全局对象。
 main 函数由 Helper 的其它源文件封装，或由用户提供。
 Helper 定义的类型若适用于不同平台，不保证二进制兼容性，除非另有说明。

@5.5.1 YGlobal 单元：
平台相关的全局对象和函数定义。
除了以下接口，其它都是不确定的：
const SDst MainScreenWidth, MainScreenHeight;

unspecified_class_type&
FetchGlobalInstance() ynothrow;

bool
InitConsole(Devices::Screen&, Drawing::PixelType, Drawing::PixelType);

这里 FetchGlobalInstance 返回类型为平台相关的应用程序类的引用。
 YSLib 不依赖这些接口以外的特性。

@5.5.2 Application 派生类：
适应于具体平台的应用程序实例抽象。
包含默认消息循环等。

@5.5.3 初始化 Initialization ：
参见 [Documentation::YSLib @@3] 。

@5.6 NPL 库：
实现基于 S 表达式的名称协议语言，当前仅用于用户配置设置。

@5.7 库基础结构：
平台设置在 <Platform.h>(@5.2.2.3.1) 中。
任何 YSLib 头文件，除了 "/Adaptor/" 路径下的文件以及仅包含宏定义的文件外，都直接或间接地包含 "/Core/ysdef.h" 文件。
所有外部链接库为静态库。除了 YCLib 外，对外部库未经过封装的使用仅在 Adaptor 中。这样有利于以子库为单位的移植。

@5.8 全局命名空间：
除了使用标准库命名空间 std 外如下所列。

@5.8.1 标准库实现提供的附加命名空间：
 __gnu_cxx ： libstdc++ 扩展，可被 YBase::LibDefect 和 YFramework::YSLib::Adaptor 使用。

@5.8.2 YBase 引入的命名空间：
 YBase 使用的命名空间。
 ystdex ：从 std 扩充的平台无关的实用程序 YStandard 。 YSLib 本体直接依赖于此命名空间。
 ytest ：测试框架设施 YTest 。

@5.8.3 YFramework 引入的命名空间：
 platform ：平台中立：接口平台无关但实现平台相关的实用程序。 YSLib 本体间接依赖于此命名空间。
 platform_ex ：接口和实现都平台相关的实用程序。 YSLib 本体不依赖于此命名空间。
 CHRLib ：子库 CHRLib 的命名空间。 YSLib 本体直接依赖于此命名空间。
 NPL ：子库 NPL(@5.6) 的命名空间。
 YSLib ： YSLib 库命名空间。

@6 编码风格导引：
仅叙述之前章节未涉及的内容。
基本内容参见 [Documentation::CommonRules @@6] 。

@6.1 类成员和类定义内声明规则：
以下为一般建议性规则。
除非另有说明，关于声明顺序排列的规则的优先级以从高到低排列。

@6.1.1 基本原则：
一致性原则：声明和实现（定义）若分离，顺序应保持一致，以便查找。
类定义内声明顺序规则：分为区段规则和非区段规则，参见 @6.1.2 。
仅在必要时使用类名声明。

@6.1.2 声明区段(section) ：
为明确顺序，划分类定义内的声明的组合为若干区段。
同一区段的声明之间连续（即不穿插其它区段的声明），不同区段之间具有明确的顺序。
区段按声明的语法形式归类划分。区段内可以划分子区段（如按限定符）。
根据区段明确的声明顺序规则称为区段顺序规则。非区段顺序规则优先于区段顺序规则。

@6.1.3 非区段顺序规则：
若应用区段顺序规则后导致使用未声明的名称，且可以通过调整声明顺序解决，则允许调整声明顺序。
非替代 typedef 的 using 和 static_assert 声明不受区段顺序规则限制。
除了数据成员布局需要，无视访问权限。

@6.1.4 区段顺序一般规则：
同一区段内，非静态成员先于静态成员。

@6.1.5 声明区段划分和特定区段顺序规则：
总体区段以类型/模板类型、数据成员、其它成员或非成员（包括类定义内的友元声明等）顺序排列。

@6.1.5.1 类型/模板类型声明：
一般应该保证非模板优先。

@6.1.5.2 数据成员：
分为两个区段，以静态数据成员、非静态数据成员的顺序排列。

@6.1.5.2.1 静态数据成员
按 cv-qualifier 分为以下区段，以 constexpr 、 const 、无限定、 volatile 的顺序排列。

@6.1.5.3 其它成员或非成员：

@6.1.5.3.1 名称区段：
操作符（以 operator 起始）名称在同一区段其它名称之前；
其它成员或非成员声明按各区段之间的名称的字典序排列。

@6.1.5.3.2 非成员区段与成员区段：
名称相同的非成员函数与非成员函数模板先于对应类型的成员函数与成员函数模板。

@6.1.5.3.3 重载区段：
构成重载的所有成员声明之间不插入其它成员声明。
对于同一个名称的成员，成员重载先于非成员重载。
涉及特殊成员函数的重载以默认构造函数、其它构造函数/构造模板、复制构造函数、转移构造函数、析构函数、其它赋值操作符函数/模板、复制赋值操作符函数、转移复制操作符函数的顺序声明，优先于以下子区段规则。
仅限定符不同或仅修饰相同位置参数中的限定符构成重载的区段：首先按 cv-qualifier 以无限定、const 、volatile 、const volatile 排列，其次按 ref-qualifier 以无限定、 & 、 && 排列；但命名空间作用域中若在接口语义或实现中存在声明（调用）依赖则允许使用其它顺序（但应尽少改变）。
类型和所有的限定符一致的成员函数先于成员函数模板。

@6.1.6 建议的具体声明顺序：
以下同一区段内，按约定顺序排列；约定同类顺序的， @6.1.5.3.1 的规则排列。
友元类和友元模板；
嵌套类、嵌套类模板；
 typedef 或代替 typedef 的 using 声明；
静态 constexpr 数据成员；
静态 const 数据成员；
静态无限定数据成员；
静态 volatile 数据成员；
非静态数据成员；
默认构造函数；
以基类引用参数作为唯一参数的构造函数；
以基类引用参数作为唯一参数的构造模板；
其它（排除以下提及同类的，下同）构造函数或构造模板；
复制构造函数；
转移构造函数；
析构函数；
以基类引用参数作为唯一参数的赋值操作符函数；
以基类引用参数作为唯一参数的赋值操作符模板；
其它赋值操作符函数或模板；
复制赋值操作符；
转移赋值操作符；
组合赋值操作符（以 += 、 -= 、 *= 、 /= 、 %= 、 <<= 、 >>= 、 &= 、 |= 的顺序）；
一元操作符（以 ! 、 ~ 、 + 、 - 、 & 、 * 的顺序)；
重载 operator-> ；
重载 operator->* ；
自增/自减（以前缀自增、后缀自增、前缀自减、后缀自减的顺序）；
重载 operator[] ；
关系操作符（以 == 、 != 、 < 、 <= 、 > 、 >= 的顺序）；
算术操作符（以 + 、 - 、 * 、 / 、 % ）的顺序；
二元位操作符（以 << 、 >> 、 & 、 | 、 ^ 的顺序）；
逻辑操作符（以 && 、 || ）的顺序；
分配/去配操作符（以 new 、new[] 、 delete 、 delete[] 的顺序）；
转换操作符（以整数类型、枚举类型、其它基本类型、类类型顺序；整数类型之间以转换阶(conversion rank) 从小到大的顺序排列）；
访问器([Documentation::CommonRules @@3.11.3]) （以谓词([Documentation::CommonRules @@3.11.2]) 、其它获取器([Documentation::CommonRules @@3.11.4]) 、设置器([Documentation::CommonRules @@3.11.4]) 排列）；
其它函数或函数模板。

@6.2 源代码嵌入文档：
使用 Doxygen 。
编码适应大多数源文件，默认为 UTF-8 。
默认语言为简体中文。

@6.2.1 注释风格：
使用简化的（去除可以省略的星号后的） Qt 风格的注释。
分行例外（默认参见 [Documentation::CommonRules @@6.4.1] ）： URL 链接等超出默认行宽时可在同一行（无法生成正确的代码）。

@6.2.2 指令同义词：
当多种指令等价时使用 Doxygen 手册中直接说明（而非指示同义词即 "Equivalent to" ）的一项。
例外：
对外部参考使用 \see 而不是 \sa ；
 \throw 指显式抛出异常， \exception 指内部调用间接抛出的异常。

@6.2.3 指令行风格：
除了组(group) 相关指令、实体标识指令（ \def 、 \fn 等）以及 \author 、\par 、 \sa 、 \since 、 \version 外，其它指令后的内容以句为单位（不成句的不视为完整的注释）。
实体注释中详细注释放在最后。组相关指令在最前（且在注释首行使用水平制表符缩进），然后是实体标识指令（，除了 \def 外一般省略），之后是其它指令。

@6.2.4 指令顺序：
指定顺序的实体注释指令： \brief 、 \tparam 、 \param 、 \pre 、 \post 、 \return 、 \throw 、 \exception 、 \note 、 \warning 、 \bug 、 \deprecated 、 \relates 、 \sa 、 \see 、 \since  、 \todo 。
其它参见 http://drupal.org/node/1354#links 。

@7 一般实现导引：
自定义应用程序 Shell 类，继承默认 Shells::Shell 类或其派生类并产生实例。
完成自定义 Shell 类的消息处理过程。一般把多个处理过程的响应封装为单一函数。
对于支持实现对应 Shell 的窗口封装为窗体（Form）类（一般继承自 Window 类），在此自定义类中添加所需的 GUI 部件的定义，并实现界面效果。
在响应 SM_ACTIVATED 的处理过程中添加需要初始化的资源或子 Shell ，在 SM_DEACTIVATED 的处理过程中添加退出程序或转移线程控制权的指令。
在响应输入等事件消息的处理过程中添加对应的代码。

@7.1 初始化：
需要保证主 Shell 句柄在应用程序实例初始化之后初始化，基类 Shell 的构造函数调用了 Application 的非静态成员函数。

*/
////

