diff --git a/.agents/skills/d2mcpp-authoring/SKILL.md b/.agents/skills/d2mcpp-authoring/SKILL.md new file mode 100644 index 0000000..67abbfb --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/SKILL.md @@ -0,0 +1,182 @@ +--- +name: d2mcpp-authoring +description: >- + Authoring conventions, design principles, and file formats for the d2mcpp + (D2X) Modern C++ tutorial project. Use this whenever you add or edit a C++ + language-feature lesson — a book chapter, a dslings exercise, a reference + solution, or when registering them in SUMMARY/xmake/changelog. Trigger it for + any request like "add a chapter for X", "write a dslings exercise for fold + expressions", "add the constexpr lesson", "fill the cpp14 section", or + anything touching book/src, book/en/src, dslings/, or solutions/. Even small + edits should follow these conventions so the bilingual + book/code/checker + artifacts stay in sync. +--- + +# d2mcpp (D2X) Authoring Conventions + +d2mcpp teaches **Modern C++ core language features** through a tightly coupled +quartet: **Book (mdBook) + Code (dslings exercises) + Solution + Auto-checker +(`d2x checker`)**, all of it **bilingual (zh + en)**. A "lesson" is never one +file — it is a coordinated set across several directories. The cardinal sin here +is producing a half-set (a chapter with no exercise, a zh file with no en +counterpart, an exercise not registered in xmake). This skill exists so every +lesson lands complete and consistent. + +Read `references/anatomy.md` for the full directory map and the exact list of +files every lesson must touch. Use the ready-made scaffolds in `assets/` rather +than reconstructing format from memory. + +## The design principle (decide this BEFORE writing) + +The project is organized **by standard** (`cpp11/ cpp14/ cpp17/ cpp20/ cpp23/`). +Honor that axis: + +- **Teach each feature as the standard that introduced it actually delivered + it** — the historical state, compiled at its introduction standard. The + compiler-driven (dslings) format is at its best when the learner feels the + C++11-era restriction first (e.g. `constexpr` single-return, `std::is_pod`, + copy-elision behavior). Folding every later refinement back into the + introduction chapter erases that, and empties out the later-standard sections. +- **Independent later capabilities become their own chapter under the later + standard's section** — this is what fills `cpp14/17/20`. Examples: fold + expressions → cpp17, `using enum` → cpp20, designated initializers → cpp20, + `if constexpr` → cpp17, `decltype(auto)` → cpp14, `consteval`/`constinit` → cpp20. +- **Pure refinements / rule-tweaks / deprecations stay in the introduction + chapter as a short "特性演进 / Feature Evolution" note** with a cross-link + forward — they are not chapter-worthy on their own. Examples: `auto x{1}` + deduction change, `std::is_pod` deprecation pointer, guaranteed copy elision + remark, P0136 inheriting-constructor semantics fix. +- **Compile each chapter at its introduction standard.** Do not globally pin a + newer standard. If one exercise genuinely needs a later standard, make it an + **explicit, commented exception** in xmake — never a bare `-- TODO` hack. + +Background and the full per-feature evolution analysis live in +`.agents/docs/2026-06-08-cpp11-feature-evolution-and-cxx20-baseline.md`. Consult +it when deciding where a feature's later improvements should go. + +The decision rule, compactly: + +| Kind of later change | Where it goes | +|---|---| +| New independent syntax/ability | New chapter in the later standard's section | +| Relaxation/tweak/deprecation | "Feature Evolution" note in the intro chapter + forward link | + +## The unit of work: one lesson = these files, all bilingual + +When adding a feature numbered `NN` with slug `topic` (e.g. `06-scoped-enums`): + +1. `book/src//NN-topic.md` — zh chapter +2. `book/en/src//NN-topic.md` — en chapter (translate prose, keep code identical) +3. `dslings//NN-topic-K.cpp` — one or more exercises (`K` = 0,1,2…), zh comments +4. `dslings/en//NN-topic-K.cpp` — en exercises (translate comments only) +5. `solutions//NN-topic-K.cpp` — reference solution per exercise +6. Register each exercise target in `dslings//xmake.lua` +7. Register each solution target in `solutions/xmake.lua` +8. Add the chapter line to **both** `book/src/SUMMARY.md` and `book/en/src/SUMMARY.md` +9. Add a changelog entry to **both** `book/src/changelog.md` and `book/en/src/changelog.md` + +Missing any of these = an incomplete lesson. `references/anatomy.md` has the +exact registration snippets and SUMMARY/changelog line formats. + +## Naming and numbering + +- Chapter/exercise prefix is a **two-digit** sequence `NN` within the standard + section; slug is **kebab-case** and matches book + dslings + solutions. +- Exercises split into `-0`, `-1`, … by sub-topic; a single-exercise chapter has + no numeric suffix on the dslings target name but the file is still `NN-topic.cpp`. +- The **`d2x checker `** name is the slug (and `-1`, `-2` for + later exercises) — it omits the `NN-` prefix. Keep checker names, file names, + and book references mutually consistent. + +## Book chapter format + +Use `assets/chapter.zh.md` / `assets/chapter.en.md`. Required structure, in order: + +1. Language-switch header `
🌎 [中文] | [English]` + link defs. + - zh links: `[中文]: ./NN-topic.html` and `[English]: ../en//NN-topic.html` + - en links: `[中文]: ../..//NN-topic.html` and `[English]: ./NN-topic.html` +2. `# 标题 - english name` (zh) / `# English Title` (en), then a one-paragraph + intro that states the feature **was introduced in C++NN** and what problem it solves. +3. Resource table `| Book | Video | Code | X |` — cppreference link + markdown + permalink + video link + first practice-code permalink. +4. Bold motivation blocks: `**为什么引入?**`, `**和……的区别?**`. +5. Numbered Chinese-numeral sections, in order: `## 一、基础用法和场景`, + `## 二、真实案例 - STL 中的 `, `## 三、注意事项`, + `## 四、练习代码`, `## 五、其他`. +6. `## 二、真实案例` corroborates the feature with **real, verbatim STL code** + quoted from the in-repo `msvc-stl/` basis — see "The 真实案例 section" below. +7. `## 四、练习代码` lists **every** exercise topic of the chapter (`-0`, `-1`, …, + matching the dslings/xmake count) with dslings links as an index, but the checker + block shows only the **single entry** command `d2x checker ` — `d2x` auto- + advances through the remaining exercises, so do NOT list one command per exercise. + Then a `### 练习交流讨论` link to the chapter's forum thread. Each exercise's own + `d2x checker -K` name and a Tips line **specific to that exercise** belong in + that exercise file's header, not in the book. +8. `## 五、其他` is the fixed footer (forum / repo / video list / xlings links). +9. If the feature evolved later, add a **`## 特性演进 / Feature Evolution`** + block before `## 五、其他` — introduced standard + bullet list of later + refinements + forward links to the later-standard chapters. + +Keep prose tone consistent with existing chapters: explanatory, example-driven, +short code blocks with inline comments showing the failure and the fix. + +### The 真实案例 / Real-World Case section (msvc-stl basis) + +`## 二、真实案例` exists to prove the feature earns its place by showing **real +production code, quoted verbatim** — never invented, never paraphrased. The single +source of truth is the in-repo vendored MSVC STL basis at the top-level +**`msvc-stl/`** (the complete upstream `stl/` subtree; `msvc-stl/SOURCE.md` records +the pinned upstream commit and how to refresh it). Rules: + +- Quote from `msvc-stl/stl/inc/
` (or `src/`) **byte-for-byte**; mark any + elision with `(有删节)` / `(abridged)`. Do not reconstruct from memory. +- Keep internal macros (`_NODISCARD`, `_CONSTEXPR17`, `_STD`, …) as written and add + one line telling the reader they are library-internal and ignorable. +- Pick a usage that **echoes a syntax point from `## 一`** (e.g. `std::begin`'s + `auto … -> decltype(...)` for the auto/decltype chapter), so the section reads as + "you use it this way → the standard library does too". +- **Scope-lock to the chapter's standard**: a `cpp11` chapter quotes C++11-era + usage only; do not show later forms (e.g. `decltype(auto)`). +- Link to the **local `msvc-stl/` path**, not the upstream GitHub repo, so the + citation stays pinned to the vendored snapshot. +- Every chapter should carry this section. If a feature genuinely has no + representative usage in the STL implementation, omit it and state why in the PR. + +## dslings exercise format + +Use `assets/exercise.cpp`. Essentials: + +- Header comment block: `d2mcpp` URL, `license: Apache-2.0`, `file:` path, + `Exercise/练习:` line (` | NN - topic | 中文小标题`), `Tips/提示:`, + `Docs/文档:` (cppreference), and the `Auto-Checker/自动检测命令:` with + `d2x checker `. +- `#include ` then any std headers. +- `main()` seeded with **intentional errors** the learner fixes, each flagged by + a numbered inline comment (`// 1.…`, `// 2.…`) telling them what to do. +- Checkpoint macros from `d2x/cpp/common.hpp`: + - `d2x_assert(cond)` / `d2x_assert_eq(a, b)` — runtime checkpoints; learners + must make them pass by fixing code, **not** by deleting the checkpoint. + - `D2X_YOUR_ANSWER` — a fill-in placeholder the learner replaces. + - `D2X_WAIT` — separates exercises; learner deletes/comments it to advance. + Put exactly one at the end of each exercise's checkpoints. + - `D2X_DONT_DELETE_THIS` — guards lines that must not be removed. +- The **en exercise translates only the comment prose**; the code stays byte-for-byte + identical to the zh exercise so checker behavior matches. + +## Reference solution format + +Use `assets/solution.cpp`. It is the corrected exercise with: + +- A solution header: `reference solution for: `, plus the note + that it is **for CI/maintainers only, not a tutorial entry**, and a pointer + back to the exercise file. +- `D2X_WAIT` removed; all checkpoints passing; unused locals silenced with + `(void)var;` rather than left to warn. +- Same `#include`s and structure as the exercise. + +## Definition of done + +Before claiming a lesson complete, verify the whole set exists and is wired up, +and that the exercise/solution actually build & check. See +`references/anatomy.md` for the verification commands (`d2x checker ` and +the xmake build) — run them; do not assert success without the output. diff --git a/.agents/skills/d2mcpp-authoring/assets/chapter.en.md b/.agents/skills/d2mcpp-authoring/assets/chapter.en.md new file mode 100644 index 0000000..35ec161 --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/assets/chapter.en.md @@ -0,0 +1,129 @@ +
+ + 🌎 [中文] | [English] +
+ +[中文]: ../..//NN-topic.html +[English]: ./NN-topic.html + +# English Title + + + +| Book | Video | Code | X | +| --- | --- | --- | --- | +| [cppreference](https://en.cppreference.com/w/cpp/language/...) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/en/src//NN-topic.md) | [Video Explanation]() | [Practice Code](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-0.cpp) | | + + +**Why was it introduced?** + +- +- + +**How does it differ from …?** + +- +- + +## I. Basic Usage and Scenarios + +### + + + +```cpp +// example code +``` + + +## II. Real-World Case - in the STL + +> Corroborates how the feature is actually used in production-grade code. The snippet is taken from the in-repo MSVC STL reference basis [`msvc-stl/`](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) (source file [`stl/inc/
`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/
)); `_NODISCARD` / `_CONSTEXPR17` / `_STD` are internal library macros — ignore them when reading + +### + + + +```cpp +// MSVC STL · stl/inc/
(abridged) +// +``` + + + +## III. Notes and Caveats + +### + + + + +## IV. Practice Code + +### Practice Topics + +- 0 - [](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-0.cpp) +- 1 - [](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-1.cpp) + +### Auto-Checker Commands + + +
+Don't have d2x yet? Click to expand setup + +```bash +# 1. Install xlings (Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash +# Windows PowerShell: +# irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex + +# 2. Install d2x and fetch this tutorial +xlings install d2x -y +d2x install d2mcpp + +# 3. Enter the project directory & run the checker +cd d2mcpp +``` + +
+ +``` +d2x checker +``` + +### Exercise Discussion + +- [](https://forum.d2learn.org/post/NNN) + + +## Feature Evolution + +> **Introduced in**: C++NN +> **Later improvements**: +> - **C++14**: <...> +> - **C++17**: <...> (see [the dedicated chapter](..//MM-xxx.md)) +> - **C++20**: <...> +> +> **Teaching note**: + +## V. Additional Resources + +- [Discussion Forum](https://forum.d2learn.org/category/20) +- [d2mcpp Tutorial Repo](https://github.com/mcpp-community/d2mcpp) +- [mcpp-community Organization](https://github.com/mcpp-community) +- [Tutorial Video List](https://space.bilibili.com/65858958/lists/5208246) +- [Tutorial Tooling - xlings](https://github.com/openxlings/xlings) +- [Exercise Checker - d2x](https://github.com/d2learn/d2x) diff --git a/.agents/skills/d2mcpp-authoring/assets/chapter.zh.md b/.agents/skills/d2mcpp-authoring/assets/chapter.zh.md new file mode 100644 index 0000000..552e543 --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/assets/chapter.zh.md @@ -0,0 +1,124 @@ +
+ + 🌎 [中文] | [English] +
+ +[中文]: ./NN-topic.html +[English]: ../en//NN-topic.html + +# 标题 - english name + +<一段话简介:该特性由 C++NN 引入,用于解决……,让……> + +| Book | Video | Code | X | +| --- | --- | --- | --- | +| [cppreference](https://en.cppreference.com/w/cpp/language/...) / [markdown](https://github.com/mcpp-community/d2mcpp/blob/main/book/src//NN-topic.md) | [视频解读]() | [练习代码](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-0.cpp) | | + + +**为什么引入?** + +- <动机 1> +- <动机 2> + +**和……的区别?** + +- <对比点 1> +- <对比点 2> + +## 一、基础用法和场景 + +### <小节标题> + +<讲解 + 短代码块,代码内用注释标出"错误写法"与"正确写法"> + +```cpp +// 示例代码 +``` + + +## 二、真实案例 - STL 中的 <特性> + +> 印证该特性在生产级代码中的真实用法。代码取自仓库内置的 MSVC STL 引用基底 [`msvc-stl/`](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl)(源文件 [`stl/inc/
`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/
));`_NODISCARD` / `_CONSTEXPR17` / `_STD` 等为库内部宏,阅读时可忽略 + +### <真实用法小标题,呼应「一」中的某个语法点> + +<一句话:标准库为什么必须这样用该特性,人手写不出 / 写不优雅> + +```cpp +// MSVC STL · stl/inc/
(有删节) +// <逐字摘录真实代码;删减处保留 (有删节) 标注,切勿凭记忆改写> +``` + +<把它和「一」里的玩具示例对应起来:你这样用 → 标准库自己也这样写。这也是该特性被引入的核心动机之一> + +## 三、注意事项 + +### <易错点 / 迁移建议> + +<讲解> + + +## 四、练习代码 + +### 练习代码主题 + +- 0 - [<练习 0 主题>](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-0.cpp) +- 1 - [<练习 1 主题>](https://github.com/mcpp-community/d2mcpp/blob/main/dslings//NN-topic-1.cpp) + +### 练习代码自动检测命令 + + +
+还没有 d2x?点击展开获取方式 + +```bash +# 1. 安装 xlings(Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash +# Windows PowerShell: +# irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex + +# 2. 安装 d2x 并拉取本教程 +xlings install d2x -y +d2x install d2mcpp + +# 3. 进入项目目录 & 运行检查命令 +cd d2mcpp +``` + +
+ +``` +d2x checker +``` + +### 练习交流讨论 + +- [<本章练习讨论帖>](https://forum.d2learn.org/post/NNN) + + +## 特性演进 / Feature Evolution + +> **引入标准**:C++NN +> **后续优化**: +> - **C++14**:<...> +> - **C++17**:<...>(详见 [对应章节](..//MM-xxx.md)) +> - **C++20**:<...> +> +> **教学提示**:<跨标准行为差异 / 弃用 / 本练习为何用例外标准> + +## 五、其他 + +- [交流讨论](https://forum.d2learn.org/category/20) +- [d2mcpp教程仓库](https://github.com/mcpp-community/d2mcpp) +- [mcpp-community 社区](https://github.com/mcpp-community) +- [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) +- [教程支持工具-xlings](https://github.com/openxlings/xlings) +- [教程检测工具-d2x](https://github.com/d2learn/d2x) diff --git a/.agents/skills/d2mcpp-authoring/assets/exercise.cpp b/.agents/skills/d2mcpp-authoring/assets/exercise.cpp new file mode 100644 index 0000000..0ca3d10 --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/assets/exercise.cpp @@ -0,0 +1,36 @@ +// d2mcpp: https://github.com/mcpp-community/d2mcpp +// license: Apache-2.0 +// file: dslings//NN-topic-K.cpp +// +// Exercise/练习: | NN - topic | <中文小标题> +// +// Tips/提示: <针对【本练习子主题】的一句话提示,需与本文件内容对应,避免「修复代码中的错误」这类通用话术> +// +// Docs/文档: +// - https://en.cppreference.com/w/cpp/language/... +// +// Auto-Checker/自动检测命令: +// +// d2x checker +// + +#include + +#include + +int main() { + + // 1.<要修复的点>: <说明,例如:修复这个编译错误 / 改成正确类型> + int a = 1.1; // <提示> + + d2x_assert_eq(a, 1.1); // 运行时检查点:需修复代码使其通过(不要删除检查点) + + // 2.<填空点>: 用正确的代码替换 D2X_YOUR_ANSWER + D2X_YOUR_ANSWER b = a; // <提示:给 b 一个合适的类型> + + d2x_assert_eq(b, 1); + + D2X_WAIT // 删除或注释掉本宏进入下一个练习 + + return 0; +} diff --git a/.agents/skills/d2mcpp-authoring/assets/solution.cpp b/.agents/skills/d2mcpp-authoring/assets/solution.cpp new file mode 100644 index 0000000..65857f3 --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/assets/solution.cpp @@ -0,0 +1,29 @@ +// d2mcpp: https://github.com/mcpp-community/d2mcpp +// license: Apache-2.0 +// reference solution for: dslings//NN-topic-K.cpp +// +// 用途: 仅给 CI 与维护者参考使用,不是教程入口。 +// 教程练习入口: dslings//NN-topic-K.cpp +// + +#include + +#include + +int main() { + + // 1.<已修复>: 说明保持与练习一致,但代码为正确版本 + double a = 1.1; + + d2x_assert_eq(a, 1.1); + + // 2.<已填空> + double b = a; + (void)b; // 用 (void) 抑制未使用告警,不要留下会触发 warning 的代码 + + d2x_assert_eq(b, 1.1); + + // 注意: 参考答案中删除 D2X_WAIT,且所有检查点均通过 + + return 0; +} diff --git a/.agents/skills/d2mcpp-authoring/references/anatomy.md b/.agents/skills/d2mcpp-authoring/references/anatomy.md new file mode 100644 index 0000000..cdd4dee --- /dev/null +++ b/.agents/skills/d2mcpp-authoring/references/anatomy.md @@ -0,0 +1,126 @@ +# Lesson Anatomy & Registration + +The exact directory map, registration snippets, and verification commands for a +d2mcpp lesson. `` is the standard section (`cpp11`, `cpp14`, …); `NN` is the +two-digit chapter number; `topic` is the kebab-case slug; `K` is the +sub-exercise index (`0`, `1`, …); `` is the `d2x checker` name (the slug, +or `slug-1`, `slug-2` for later exercises). + +## Directory map + +``` +book/src//NN-topic.md # zh chapter +book/en/src//NN-topic.md # en chapter +book/src/SUMMARY.md # zh TOC (register here) +book/en/src/SUMMARY.md # en TOC (register here) +book/src/changelog.md # zh changelog (add entry) +book/en/src/changelog.md # en changelog (add entry) + +dslings//NN-topic-K.cpp # zh exercise(s) +dslings/en//NN-topic-K.cpp # en exercise(s) +dslings//xmake.lua # register exercise target(s) + +solutions//NN-topic-K.cpp # reference solution(s) +solutions/xmake.lua # register solution target(s) (includes ) +``` + +Repo-level shared basis (NOT per-lesson, created once, never edited by hand): + +``` +msvc-stl/ # vendored MSVC STL `stl/` subtree (read-only) +msvc-stl/stl/inc/
# what the chapter's `## 二、真实案例` quotes from +msvc-stl/SOURCE.md # pinned upstream commit + refresh steps +msvc-stl/LICENSE.txt, NOTICE.txt # upstream license, kept verbatim +``` + +The `## 二、真实案例` section of every chapter links into `msvc-stl/` for its +verbatim STL excerpt; you do not add files here per lesson — only refresh the +snapshot via `msvc-stl/SOURCE.md` when needed. + +A new `` section that does not exist yet also needs: an `includes("")` +line wired from `dslings/xmake.lua` and `solutions/xmake.lua`, a `dslings//` +and `dslings/en//` directory, a `solutions//` directory, and the +section heading in both `SUMMARY.md` files (e.g. `# C++14核心语言特性` / +`# C++14 Core Language Features`). + +## xmake registration — exercises (`dslings//xmake.lua`) + +Append one target per exercise file. Binary kind is the default; only set it +where existing siblings do. Example for a two-exercise chapter: + +```lua +-- target: -NN-topic + +target("-NN-topic-0") + add_files("NN-topic-0.cpp") + +target("-NN-topic-1") + add_files("NN-topic-1.cpp") +``` + +Per-target options seen in the repo, use only when the lesson needs them: + +```lua +target("cpp11-04-rvalue-references") + set_optimize("none") + add_cxxflags("-fno-elide-constructors") -- observe moves; note C++17 guaranteed elision can't be disabled + add_files("04-rvalue-references.cpp") +``` + +If an exercise needs a non-default standard, make it an **explicit, commented +exception** — never a bare TODO: + +```lua +target("cppNN-NN-topic-0") + set_languages("c++17") -- exception: + add_files("NN-topic-0.cpp") +``` + +The default standard is set at the top of `dslings//xmake.lua`. Per the +design principle, that should be the **introduction standard** of the section +(e.g. `set_languages("c++11")` for `cpp11`). Avoid per-host standard forks; if +one is unavoidable, comment why. + +## xmake registration — solutions (`solutions/xmake.lua` + `solutions//xmake.lua`) + +Mirror the exercise targets so CI builds the reference solutions too. Follow the +existing pattern in `solutions//xmake.lua`. + +## SUMMARY registration + +Add the chapter under the correct standard heading, keeping numeric order. + +zh — `book/src/SUMMARY.md`: +```markdown +- [标题 - english name](.//NN-topic.md) +``` + +en — `book/en/src/SUMMARY.md`: +```markdown +- [English Title](.//NN-topic.md) +``` + +## Changelog entry + +Add a dated entry to both `book/src/changelog.md` and `book/en/src/changelog.md` +under the current `## YYYY/MM` heading (create the month heading if missing). +Follow the existing entry shape — feature title, then `Book` / `Code` (and +`video` when available) links with per-artifact dates. Convert any relative date +to an absolute `YYYY/MM/DD`. + +## Verification (definition of done) + +Run from the project root; report real output, do not assert success blind: + +```bash +# build the exercise + solution targets (lang defaults come from xmake) +xmake f -c >/dev/null && xmake build cppNN-NN-topic-0 + +# drive the auto-checker against the exercise (expects the unsolved exercise to fail, +# the solution to pass) — name omits the NN- prefix +d2x checker +``` + +Bilingual sync check: every file in the zh column has its en counterpart, code +bodies are identical between zh/en exercises, and both SUMMARY + both changelog +files were updated. diff --git a/.gitignore b/.gitignore index caa2e79..683495e 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,9 @@ # Python __pycache__ +# temporary upstream STL clone (vendored subset lives in /msvc-stl) +/STL/ + # d2x project files .xlings .vscode diff --git a/book/en/src/cpp11/00-auto-and-decltype.md b/book/en/src/cpp11/00-auto-and-decltype.md index 6993249..eebb1f4 100644 --- a/book/en/src/cpp11/00-auto-and-decltype.md +++ b/book/en/src/cpp11/00-auto-and-decltype.md @@ -44,7 +44,7 @@ decltype(b) b3; // Can be used without initialization > Often used for complex expression type deduction to ensure calculation precision -```c++ +```cpp int a = 1; auto b1 = a + 2; @@ -58,7 +58,7 @@ decltype(2 + 'a') c2 = 2 + 'a'; **Iterator Type Deduction** -```c++ +```cpp std::vector v = {1, 2, 3}; auto it = v.begin(); // Automatically deduce iterator type @@ -72,7 +72,7 @@ for (; it != v.end(); ++it) { > For complex types like functions or lambda expressions, auto and decltype are commonly used. Generally, lambda definitions use auto, while template type parameters use decltype. -```c++ +```cpp int add_func(int a, int b) { return a + b; } @@ -135,7 +135,65 @@ int main() { } ``` -## II. Important Notes - The Impact of Parentheses +## II. Real-World Case - auto/decltype in the STL + +> The examples above illustrate syntax; the real value of auto/decltype shows up most directly in the standard library's own implementation. Below we use the in-repo [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) as the source ([`msvc-stl/stl/inc/xutility`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/xutility#L2200-L2235)); `_EXPORT_STD` / `_NODISCARD` / `_CONSTEXPR17` / `_STD` are internal library macros — ignore them when reading. + +### Trailing return type + decltype: std::begin / std::end + +`std::begin` / `std::end` (added in C++11) must adapt to any container; their return type depends entirely on `_Cont.begin()` and cannot be written ahead of time, so they "borrow" it via `auto ... -> decltype(...)` + +```cpp +// MSVC STL · msvc-stl/stl/inc/xutility (abridged) +_EXPORT_STD template +_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) -> decltype(_Cont.begin()) { + return _Cont.begin(); +} + +_EXPORT_STD template +_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) { + return _Cont.end(); +} +``` + +This is exactly the trailing-return form from the "Function Return Type Deduction" section, living inside the standard library itself: `auto` as the placeholder + `decltype(_Cont.begin())` precisely deducing the differing iterator types of `vector`, `list`, and so on. + +### Reusing another function's return type with decltype: std::cbegin / std::cend + +Going further, `std::cbegin` simply reuses `begin`'s return type via `decltype(_STD begin(_Cont))` — it doesn't care what that type is, only that it "matches what begin returns" + +```cpp +// MSVC STL · msvc-stl/stl/inc/xutility (abridged) +_EXPORT_STD template +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) + -> decltype(_STD begin(_Cont)) { + return _STD begin(_Cont); +} +``` + +> Takeaway: when a type "is decided by template parameters and simply cannot be written by hand", the standard library reaches for exactly the auto + decltype toolkit taught in this chapter — one of the core motivations for introducing them in C++11. + +## III. Important Notes + +### auto and const / reference stripping + +> auto deduction **strips top-level const and references**; to keep them you must write `const auto&` / `auto&` explicitly, whereas decltype preserves the declared type exactly + +```cpp +const int ci = 1; +int n = 2; +int& ri = n; + +auto a = ci; // int — top-level const stripped +auto b = ri; // int — reference stripped (b is an independent copy of n) + +const auto& r1 = ci; // const int& — preserved via const auto& +auto&& r2 = ci; // const int& — forwarding reference keeps it + +decltype(ci) d = ci; // const int — decltype preserves exactly +``` + +This is also why `auto a = obj.a;` in "Class/Struct Member Type Deduction" yields `int` rather than `const int` — auto stripped the top-level const. ### Difference between decltype(obj) and decltype( (obj) ) @@ -181,9 +239,51 @@ decltype(b) // Deduction result is declared type int && decltype( (b) ) // Deduction result is int & ``` -## III. Additional Resources +## IV. Practice Code + +### Practice Topics + +- 0 - [Declaration & Definition](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-0.cpp) +- 1 - [Expression Type Deduction](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-1.cpp) +- 2 - [Complex Type Deduction - Iterator / Function](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-2.cpp) +- 3 - [Function Return Type Deduction](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-3.cpp) +- 4 - [Class/Struct Member Type Deduction](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-4.cpp) +- 5 - [const & Reference Stripping and Preservation](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-5.cpp) + +### Auto-Checker Commands + +
+Don't have d2x yet? Click to expand setup + +```bash +# 1. Install xlings (Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash +# Windows PowerShell: +# irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex + +# 2. Install d2x and fetch this tutorial +xlings install d2x -y +d2x install d2mcpp + +# 3. Enter the project directory & run the checker +cd d2mcpp +``` + +
+ +``` +d2x checker auto-and-decltype +``` + +### Exercise Discussion + +- [auto/decltype exercise thread](https://forum.d2learn.org/post/357) + +## V. Additional Resources - [Discussion Forum](https://forum.d2learn.org/category/20) - [d2mcpp Tutorial Repository](https://github.com/mcpp-community/d2mcpp) +- [mcpp-community Organization](https://github.com/mcpp-community) - [Tutorial Video List](https://space.bilibili.com/65858958/lists/5208246) - [Tutorial Support Tool - xlings](https://github.com/openxlings/xlings) +- [Exercise Checker - d2x](https://github.com/d2learn/d2x) diff --git a/book/src/cpp11/00-auto-and-decltype.md b/book/src/cpp11/00-auto-and-decltype.md index 9162bea..7384c6f 100644 --- a/book/src/cpp11/00-auto-and-decltype.md +++ b/book/src/cpp11/00-auto-and-decltype.md @@ -8,7 +8,7 @@ # 类型自动推导 - auto和decltype -auto 和 decltype 是C++11引入的强有力的**类型自动推导**工具. 不仅让代码变的更加简洁, 还增强了模板和泛型的表达能力 +auto 和 decltype 是C++11引入的强有力的**类型自动推导**工具. 不仅让代码变得更加简洁, 还增强了模板和泛型的表达能力 | Book | Video | Code | X | | --- | --- | --- | --- | @@ -23,7 +23,7 @@ auto 和 decltype 是C++11引入的强有力的**类型自动推导**工具. 不 **auto和decltype有什么区别?** -- auto常常用于变量定义, 推导的类型可能丢失const或引用(可显示指定进行保留auto &) +- auto常常用于变量定义, 推导的类型可能丢失const或引用(可显式指定进行保留auto &) - decltype获取表达式的**精确类型** - auto通常无法作为模板类型参数使用 @@ -31,7 +31,7 @@ auto 和 decltype 是C++11引入的强有力的**类型自动推导**工具. 不 ### 声明定义 -> 充当类型站位符, 辅助变量的定义或声明。使用auto时变量必须要初始化, decltype可以不用初始化 +> 充当类型占位符, 辅助变量的定义或声明。使用auto时变量必须要初始化, decltype可以不用初始化 ```cpp int b = 2; @@ -44,7 +44,7 @@ decltype(b) b3; // 可以不用初始化 > 常常用于复杂表达式的类型推导, 确保计算精度 -```c++ +```cpp int a = 1; auto b1 = a + 2; @@ -58,7 +58,7 @@ decltype(2 + 'a') c2 = 2 + 'a'; **迭代器类型推导** -```c++ +```cpp std::vector v = {1, 2, 3}; auto it = v.begin(); // 自动推导it类型 @@ -72,7 +72,7 @@ for (; it != v.end(); ++it) { > 对于函数或lambda表达式这种复杂类型, 常常使用auto和decltype. 一般, lambda定义用auto, 模板类型参数用decltype -```c++ +```cpp int add_func(int a, int b) { return a + b; } @@ -135,11 +135,69 @@ int main() { } ``` -## 二、注意事项 - 括号带来的影响 +## 二、真实案例 - STL 中的 auto/decltype + +> 前面的例子是为了讲语法, 而 auto/decltype 真正的价值, 在标准库自己的实现里体现得最直接。下面以仓库内置的 [MSVC STL](https://github.com/mcpp-community/d2mcpp/tree/main/msvc-stl) 为例 (源码: [`msvc-stl/stl/inc/xutility`](https://github.com/mcpp-community/d2mcpp/blob/main/msvc-stl/stl/inc/xutility#L2200-L2235)); `_EXPORT_STD` / `_NODISCARD` / `_CONSTEXPR17` / `_STD` 是库内部宏, 阅读时可忽略 + +### 后置返回类型 + decltype:std::begin / std::end + +`std::begin` / `std::end` (C++11 新增) 要适配任意容器, 返回类型完全取决于 `_Cont.begin()`, 没法提前写死, 于是直接用 `auto ... -> decltype(...)` 把返回类型"借"过来 + +```cpp +// MSVC STL · msvc-stl/stl/inc/xutility (有删节) +_EXPORT_STD template +_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) -> decltype(_Cont.begin()) { + return _Cont.begin(); +} + +_EXPORT_STD template +_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) { + return _Cont.end(); +} +``` + +这正是本章「函数返回值类型推导」一节讲的后置返回写法在标准库里的真身: `auto` 占位 + `decltype(_Cont.begin())` 精确推导出 `vector::iterator`、`list::iterator` 等各不相同的迭代器类型 + +### 用 decltype 复用另一个函数的返回类型:std::cbegin / std::cend + +更进一步, `std::cbegin` 干脆用 `decltype(_STD begin(_Cont))` 直接复用了 `begin` 的返回类型 —— 不必关心它到底是什么, 只要"和 begin 返回的一样"就行 + +```cpp +// MSVC STL · msvc-stl/stl/inc/xutility (有删节) +_EXPORT_STD template +_NODISCARD constexpr auto cbegin(const _Container& _Cont) noexcept(noexcept(_STD begin(_Cont))) + -> decltype(_STD begin(_Cont)) { + return _STD begin(_Cont); +} +``` + +> 小结: 面对"类型由模板参数决定、人手根本写不出来"的场景, 标准库用的正是本章这套 auto + decltype 工具。这也是 C++11 当初引入它们的核心动机之一 + +## 三、注意事项 + +### auto 的 const / 引用剥离 + +> auto 推导会**剥离顶层 const 和引用**, 想保留得显式写 `const auto&` / `auto&`; decltype 则精确保留声明类型 + +```cpp +const int ci = 1; +int n = 2; +int& ri = n; + +auto a = ci; // int —— 顶层 const 被剥离 +auto b = ri; // int —— 引用被剥离, b 是 n 的独立副本 + +const auto& r1 = ci; // const int& —— 用 const auto& 保留 +auto&& r2 = ci; // const int& —— 万能引用按需保留 + +decltype(ci) d = ci; // const int —— decltype 精确保留 +``` + +这也解释了前面「类/结构体成员类型推导」里 `auto a = obj.a;` 为什么得到的是 `int` 而非 `const int` —— 顶层 const 被 auto 剥离了 ### decltype(obj) 和 decltype( (obj) )的区别 -- 一般`decltype(obj)`获取的时其声明类型 +- 一般`decltype(obj)`获取的是其声明类型 - 而`decltype( (obj) )` 获取的是 `(obj)` 这个表达式的类型(左值表达式) ```cpp @@ -181,9 +239,51 @@ decltype(b) // 推导结果是声明类型 int && decltype( (b) ) // 推导结果是 int & ``` -## 三、其他 +## 四、练习代码 + +### 练习代码主题 + +- 0 - [声明定义](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-0.cpp) +- 1 - [表达式类型推导](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-1.cpp) +- 2 - [复杂类型推导 - 迭代器 / 函数](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-2.cpp) +- 3 - [函数返回值类型推导](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-3.cpp) +- 4 - [类/结构体成员类型推导](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-4.cpp) +- 5 - [const 与引用的剥离和保留](https://github.com/mcpp-community/d2mcpp/blob/main/dslings/cpp11/00-auto-and-decltype-5.cpp) + +### 练习代码自动检测命令 + +
+还没有 d2x?点击展开获取方式 + +```bash +# 1. 安装 xlings(Linux / macOS) +curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash +# Windows PowerShell: +# irm https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.ps1 | iex + +# 2. 安装 d2x 并拉取本教程 +xlings install d2x -y +d2x install d2mcpp + +# 3. 进入项目目录 & 运行检查命令 +cd d2mcpp +``` + +
+ +``` +d2x checker auto-and-decltype +``` + +### 练习交流讨论 + +- [auto/decltype 练习讨论帖](https://forum.d2learn.org/post/357) + +## 五、其他 - [交流讨论](https://forum.d2learn.org/category/20) - [d2mcpp教程仓库](https://github.com/mcpp-community/d2mcpp) +- [mcpp-community 社区](https://github.com/mcpp-community) - [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) -- [教程支持工具-xlings](https://github.com/openxlings/xlings) \ No newline at end of file +- [教程支持工具-xlings](https://github.com/openxlings/xlings) +- [教程检测工具-d2x](https://github.com/d2learn/d2x) \ No newline at end of file diff --git a/dslings/cpp11/00-auto-and-decltype-0.cpp b/dslings/cpp11/00-auto-and-decltype-0.cpp index 8172b9c..3e8e3a4 100644 --- a/dslings/cpp11/00-auto-and-decltype-0.cpp +++ b/dslings/cpp11/00-auto-and-decltype-0.cpp @@ -4,7 +4,7 @@ // // Exercise/练习: cpp11 | 00 - auto and decltype | 自动类型推导 // -// Tips/提示: 使用 auto 和 decltype 修复代码中的错误 +// Tips/提示: 用 auto 从初始值推导类型, 用 decltype 取已声明变量的类型 // // Docs/文档: // - https://en.cppreference.com/w/cpp/language/auto @@ -39,6 +39,8 @@ int main() { d2x_assert_eq(a1, a2); d2x_assert_eq(b, b1); d2x_assert_eq(b1, b2); + d2x_assert_eq(c, c1); + d2x_assert_eq(c1, c2); D2X_WAIT diff --git a/dslings/cpp11/00-auto-and-decltype-1.cpp b/dslings/cpp11/00-auto-and-decltype-1.cpp index e78a921..29d76f9 100644 --- a/dslings/cpp11/00-auto-and-decltype-1.cpp +++ b/dslings/cpp11/00-auto-and-decltype-1.cpp @@ -4,7 +4,7 @@ // // Exercise/练习: cpp11 | 00 - auto and decltype | 表达式类型推导 // -// Tips/提示: 使用 auto 和 decltype 修复代码中的错误 +// Tips/提示: 含浮点的表达式要推导成 double, 别用 int 截断了精度 // // Docs/文档: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/cpp11/00-auto-and-decltype-2.cpp b/dslings/cpp11/00-auto-and-decltype-2.cpp index ef51d99..8b3fa4c 100644 --- a/dslings/cpp11/00-auto-and-decltype-2.cpp +++ b/dslings/cpp11/00-auto-and-decltype-2.cpp @@ -4,7 +4,7 @@ // // Exercise/练习: cpp11 | 00 - auto and decltype | 复杂类型推导 // -// Tips/提示: 使用 auto 和 decltype 修复代码中的错误 +// Tips/提示: 迭代器用 auto, std::function 的模板参数用 decltype(函数名), 替代手写长类型 // // Docs/文档: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/cpp11/00-auto-and-decltype-3.cpp b/dslings/cpp11/00-auto-and-decltype-3.cpp index 1fa8d48..a75fc96 100644 --- a/dslings/cpp11/00-auto-and-decltype-3.cpp +++ b/dslings/cpp11/00-auto-and-decltype-3.cpp @@ -4,7 +4,7 @@ // // Exercise/练习: cpp11 | 00 - auto and decltype | 函数返回值类型推导 // -// Tips/提示: 使用 auto 和 decltype 修复代码中的错误 +// Tips/提示: 用后置返回 auto ... -> decltype(a - b) 让模板函数自动推导返回类型 // // Docs/文档: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/cpp11/00-auto-and-decltype-4.cpp b/dslings/cpp11/00-auto-and-decltype-4.cpp index 262588d..aadb47f 100644 --- a/dslings/cpp11/00-auto-and-decltype-4.cpp +++ b/dslings/cpp11/00-auto-and-decltype-4.cpp @@ -4,7 +4,7 @@ // // Exercise/练习: cpp11 | 00 - auto and decltype | 类/结构体成员类型推导 // -// Tips/提示: 在D2X_YOUR_ANSWER处填写正确的推导类型 +// Tips/提示: 区分 decltype(obj) 与 decltype((obj)), 带括号是表达式会推导出引用类型 // // Docs/文档: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/cpp11/00-auto-and-decltype-5.cpp b/dslings/cpp11/00-auto-and-decltype-5.cpp new file mode 100644 index 0000000..0cd35bd --- /dev/null +++ b/dslings/cpp11/00-auto-and-decltype-5.cpp @@ -0,0 +1,58 @@ +// d2mcpp: https://github.com/mcpp-community/d2mcpp +// license: Apache-2.0 +// file: dslings/cpp11/00-auto-and-decltype-5.cpp +// +// Exercise/练习: cpp11 | 00 - auto and decltype | const 与引用的剥离和保留 +// +// Tips/提示: auto 会剥离顶层 const 和引用, 用 const auto& / auto& 保留, decltype 精确保留 +// +// Docs/文档: +// - https://en.cppreference.com/w/cpp/language/auto +// - https://en.cppreference.com/w/cpp/language/decltype +// - https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp11/00-auto-and-decltype.md +// +// 练习交流讨论: http://forum.d2learn.org/post/357 +// +// Auto-Checker/自动检测命令: +// +// d2x checker auto-and-decltype-5 +// + +#include + +#include + + +// 5. const 与引用的剥离和保留 + +int main() { + const int ci = 1; + int n = 2; + int& ri = n; + + bool type_check = false; + + // auto 剥离顶层 const: a 推导成什么? + auto a = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // auto 剥离引用: b 推导成什么?(b 是 n 的独立副本) + auto b = ri; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // 想保留 const 引用 const int&: cr 该怎么声明? + D2X_YOUR_ANSWER cr = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // 想精确保留声明类型 const int: d 该怎么声明? + D2X_YOUR_ANSWER d = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + D2X_WAIT + + return 0; +} diff --git a/dslings/cpp11/xmake.lua b/dslings/cpp11/xmake.lua index 3f60434..3f7d247 100644 --- a/dslings/cpp11/xmake.lua +++ b/dslings/cpp11/xmake.lua @@ -21,6 +21,9 @@ target("cpp11-00-auto-and-decltype-3") target("cpp11-00-auto-and-decltype-4") set_kind("binary") add_files("00-auto-and-decltype-4.cpp") +target("cpp11-00-auto-and-decltype-5") + set_kind("binary") + add_files("00-auto-and-decltype-5.cpp") -- target: cpp11-01-default-and-delete diff --git a/dslings/en/cpp11/00-auto-and-decltype-0.cpp b/dslings/en/cpp11/00-auto-and-decltype-0.cpp index bac48ac..8f2896d 100644 --- a/dslings/en/cpp11/00-auto-and-decltype-0.cpp +++ b/dslings/en/cpp11/00-auto-and-decltype-0.cpp @@ -4,7 +4,7 @@ // // Exercise: cpp11 | 00 - auto and decltype | Automatic Type Deduction // -// Tips: Use auto and decltype to fix errors in the code +// Tips: Use auto to deduce from the initializer, and decltype to take an already-declared variable's type // // Docs: // - https://en.cppreference.com/w/cpp/language/auto @@ -39,6 +39,8 @@ int main() { d2x_assert_eq(a1, a2); d2x_assert_eq(b, b1); d2x_assert_eq(b1, b2); + d2x_assert_eq(c, c1); + d2x_assert_eq(c1, c2); D2X_WAIT diff --git a/dslings/en/cpp11/00-auto-and-decltype-1.cpp b/dslings/en/cpp11/00-auto-and-decltype-1.cpp index 59b1fb9..a3b9a01 100644 --- a/dslings/en/cpp11/00-auto-and-decltype-1.cpp +++ b/dslings/en/cpp11/00-auto-and-decltype-1.cpp @@ -4,7 +4,7 @@ // // Exercise: cpp11 | 00 - auto and decltype | Expression Type Deduction // -// Tips: Use auto and decltype to fix errors in the code +// Tips: A float-containing expression should deduce to double — don't let int truncate the precision // // Docs: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/en/cpp11/00-auto-and-decltype-2.cpp b/dslings/en/cpp11/00-auto-and-decltype-2.cpp index ea0fb48..fb1cffd 100644 --- a/dslings/en/cpp11/00-auto-and-decltype-2.cpp +++ b/dslings/en/cpp11/00-auto-and-decltype-2.cpp @@ -4,7 +4,7 @@ // // Exercise: cpp11 | 00 - auto and decltype | Complex Type Deduction // -// Tips: Use auto and decltype to fix errors in the code +// Tips: Use auto for the iterator and decltype(func) for the std::function template argument, instead of spelling the long type // // Docs: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/en/cpp11/00-auto-and-decltype-3.cpp b/dslings/en/cpp11/00-auto-and-decltype-3.cpp index d0a7a97..fb7d426 100644 --- a/dslings/en/cpp11/00-auto-and-decltype-3.cpp +++ b/dslings/en/cpp11/00-auto-and-decltype-3.cpp @@ -4,7 +4,7 @@ // // Exercise: cpp11 | 00 - auto and decltype | Function Return Type Deduction // -// Tips: Use auto and decltype to fix errors in the code +// Tips: Use a trailing return auto ... -> decltype(a - b) so the template function deduces its return type // // Docs: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/en/cpp11/00-auto-and-decltype-4.cpp b/dslings/en/cpp11/00-auto-and-decltype-4.cpp index 1f68531..f56a15e 100644 --- a/dslings/en/cpp11/00-auto-and-decltype-4.cpp +++ b/dslings/en/cpp11/00-auto-and-decltype-4.cpp @@ -4,7 +4,7 @@ // // Exercise: cpp11 | 00 - auto and decltype | Class/Struct Member Type Deduction // -// Tips: Fill in the correct deduced type at D2X_YOUR_ANSWER +// Tips: Distinguish decltype(obj) from decltype((obj)) — the parenthesized form is an expression and deduces a reference type // // Docs: // - https://en.cppreference.com/w/cpp/language/auto diff --git a/dslings/en/cpp11/00-auto-and-decltype-5.cpp b/dslings/en/cpp11/00-auto-and-decltype-5.cpp new file mode 100644 index 0000000..90d1664 --- /dev/null +++ b/dslings/en/cpp11/00-auto-and-decltype-5.cpp @@ -0,0 +1,58 @@ +// d2mcpp: https://github.com/mcpp-community/d2mcpp +// license: Apache-2.0 +// file: dslings/cpp11/00-auto-and-decltype-5.cpp +// +// Exercise: cpp11 | 00 - auto and decltype | const & reference stripping and preservation +// +// Tips: auto strips top-level const and references; use const auto& / auto& to keep them, decltype preserves exactly +// +// Docs: +// - https://en.cppreference.com/w/cpp/language/auto +// - https://en.cppreference.com/w/cpp/language/decltype +// - https://github.com/mcpp-community/d2mcpp/blob/main/book/src/cpp11/00-auto-and-decltype.md +// +// Forum: https://forum.d2learn.org/category/20 +// +// Auto-Checker command: +// +// d2x checker auto-and-decltype-5 +// + +#include + +#include + + +// 5. const & reference stripping and preservation + +int main() { + const int ci = 1; + int n = 2; + int& ri = n; + + bool type_check = false; + + // auto strips top-level const: what does a deduce to? + auto a = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // auto strips the reference: what does b deduce to? (b is an independent copy of n) + auto b = ri; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // To keep a const reference const int&: how should cr be declared? + D2X_YOUR_ANSWER cr = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + // To preserve the declared type const int exactly: how should d be declared? + D2X_YOUR_ANSWER d = ci; + type_check = std::is_same::value; + d2x_assert(type_check); type_check = false; // dont change this line + + D2X_WAIT + + return 0; +} diff --git a/msvc-stl/LICENSE.txt b/msvc-stl/LICENSE.txt new file mode 100644 index 0000000..487531f --- /dev/null +++ b/msvc-stl/LICENSE.txt @@ -0,0 +1,219 @@ +The Microsoft C++ Standard Library is under the Apache License v2.0 with LLVM Exception: + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. diff --git a/msvc-stl/NOTICE.txt b/msvc-stl/NOTICE.txt new file mode 100644 index 0000000..8c846a8 --- /dev/null +++ b/msvc-stl/NOTICE.txt @@ -0,0 +1,218 @@ +Microsoft C++ Standard Library + +Copyright (c) Microsoft Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +---------------------------------------------------- + +In addition, certain files include the notices provided below. + + + +// Copyright 2018 Ulf Adams +// Copyright (c) Microsoft Corporation. All rights reserved. + +// Boost Software License - Version 1.0 - August 17th, 2003 + +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: + +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +---------------------- + +/* +* This file is derived from software bearing the following +* restrictions: +* +* (c) Copyright William E. Kempf 2001 +* +* Permission to use, copy, modify, distribute and sell this +* software and its documentation for any purpose is hereby +* granted without fee, provided that the above copyright +* notice appear in all copies and that both that copyright +* notice and this permission notice appear in supporting +* documentation. William E. Kempf makes no representations +* about the suitability of this software for any purpose. +* It is provided "as is" without express or implied warranty. +*/ + +---------------------- + +// NOTE: +// The conversion data in this header has been derived by Dinkumware +// from a Unicode, Inc. file with the preamble reproduced below, under +// the grant of right described in that preamble. This header contains +// no other material from that file. +// +// Copyright (c) 1994-2011 Unicode, Inc. All Rights reserved. +// +// This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +// No claims are made as to fitness for any particular purpose. No +// warranties of any kind are expressed or implied. The recipient +// agrees to determine applicability of information provided. If this +// file has been provided on magnetic media by Unicode, Inc., the sole +// remedy for any claim will be exchange of defective media within 90 +// days of receipt. +// +// Unicode, Inc. hereby grants the right to freely use the information +// supplied in this file in the creation of products supporting the +// Unicode Standard, and to make copies of this file in any form for +// internal or external distribution as long as this notice remains +// attached. + +---------------------- + +/// NOTE: +// The conversion data in this header has been derived by Dinkumware +// from a Unicode, Inc. file with the preamble reproduced below, under +// the grant of right described in that preamble. This header contains +// no other material from that file. +// +// Copyright (c) 1991-1994 Unicode, Inc. All Rights reserved. +// +// This file is provided as-is by Unicode, Inc. (The Unicode Consortium). +// No claims are made as to fitness for any particular purpose. No +// warranties of any kind are expressed or implied. The recipient +// agrees to determine applicability of information provided. If this +// file has been provided on magnetic media by Unicode, Inc., the sole +// remedy for any claim will be exchange of defective media within 90 +// days of receipt. +// +// Recipient is granted the right to make copies in any form for +// internal distribution and to freely use the information supplied +// in the creation of products supporting Unicode. + +---------------------- + +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +---------------------- + +// Copyright (c) 2012 - present, Victor Zverovich +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// --- Optional exception to the license --- +// +// As an exception, if, as a result of your compiling your source code, portions +// of this Software are embedded into a machine-executable object form of such +// source code, you may redistribute such embedded portions in such object form +// without including the above copyright and permission notices. + +---------------------- + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. diff --git a/msvc-stl/SOURCE.md b/msvc-stl/SOURCE.md new file mode 100644 index 0000000..da037a4 --- /dev/null +++ b/msvc-stl/SOURCE.md @@ -0,0 +1,76 @@ +# msvc-stl + +> 🌎 [English](#english) | [中文](#中文) + +--- + +## English + +A **read-only reference copy** of Microsoft's open-source STL implementation. It backs the *"Real-world Case"* sections across the d2mcpp chapters, used to corroborate how language features are actually used in production-grade code. **This is NOT this repository's own code — do not modify it.** + +### Upstream + +- Repository: +- License: Apache-2.0 WITH LLVM-exception (see `LICENSE.txt` / `NOTICE.txt`, kept verbatim) +- Snapshot commit: `926d9b2b1f75c6b0cdc7fe2d65630f9a81825c05` +- Commit date: 2026-05-28 + +### Scope + +Only the complete library subtree `stl/` is kept (`inc/` + `src/` + `modules/` + its own build files). Excluded: + +- `tests/`, `benchmarks/`, `tools/` — tests / benchmarks / tooling, not the library implementation +- `.git/` — upstream history +- `llvm-project`, `boost-math`, `benchmarks/google-benchmark` — submodules that only serve testing + +### Refresh + +```sh +# 1. Clone upstream (shallow is fine) +git clone --depth 1 https://github.com/microsoft/STL.git /tmp/STL + +# 2. Replace the stl/ subtree and sync the licenses +rm -rf msvc-stl/stl +cp -r /tmp/STL/stl msvc-stl/stl +cp /tmp/STL/LICENSE.txt msvc-stl/LICENSE.txt +cp /tmp/STL/NOTICE.txt msvc-stl/NOTICE.txt + +# 3. Update the commit / date in this file, and re-check that line +# numbers referenced by each chapter still match +``` + +--- + +## 中文 + +微软开源 STL 实现的**只读引用基底**,供 d2mcpp 各章「真实案例」节链接、印证语言特性在生产级代码中的真实用法。**非本仓库自有代码,请勿修改。** + +### 上游来源 + +- 仓库: +- 许可:Apache-2.0 WITH LLVM-exception(见 `LICENSE.txt` / `NOTICE.txt`,原样保留) +- 快照 commit:`926d9b2b1f75c6b0cdc7fe2d65630f9a81825c05` +- commit 日期:2026-05-28 + +### 包含范围 + +仅保留完整的库子树 `stl/`(`inc/` + `src/` + `modules/` + 其自带构建文件),已排除: + +- `tests/`、`benchmarks/`、`tools/`(测试 / 基准 / 工具,非库实现) +- `.git/`(上游历史) +- `llvm-project`、`boost-math`、`benchmarks/google-benchmark`(仅服务测试的子模块) + +### 刷新方式 + +```sh +# 1. 克隆上游(浅克隆即可) +git clone --depth 1 https://github.com/microsoft/STL.git /tmp/STL + +# 2. 用新的 stl/ 子树覆盖,并同步 license +rm -rf msvc-stl/stl +cp -r /tmp/STL/stl msvc-stl/stl +cp /tmp/STL/LICENSE.txt msvc-stl/LICENSE.txt +cp /tmp/STL/NOTICE.txt msvc-stl/NOTICE.txt + +# 3. 更新本文件的 commit / 日期,并核对各章引用的行号是否仍对应 +``` diff --git a/msvc-stl/stl/CMakeLists.txt b/msvc-stl/stl/CMakeLists.txt new file mode 100644 index 0000000..a8dbd70 --- /dev/null +++ b/msvc-stl/stl/CMakeLists.txt @@ -0,0 +1,591 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +################################################## +# Lists of files. (We can also copy files here.) # +################################################## + +set(HEADERS + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_all_public_headers.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_bit_utils.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_chrono.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_cxx_stdatomic.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_doom_core.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_filebuf.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_format_ucd_tables.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_formatter.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_heap_algorithms.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_int128.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_iter_core.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_minmax.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_ostream.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_print.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_ranges_to.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_ranges_tuple_formatter.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_sanitizer_annotate_container.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_string_view.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_system_error_abi.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_threads_core.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_tzdb.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/__msvc_xlocinfo_types.hpp + ${CMAKE_CURRENT_LIST_DIR}/inc/algorithm + ${CMAKE_CURRENT_LIST_DIR}/inc/any + ${CMAKE_CURRENT_LIST_DIR}/inc/array + ${CMAKE_CURRENT_LIST_DIR}/inc/atomic + ${CMAKE_CURRENT_LIST_DIR}/inc/barrier + ${CMAKE_CURRENT_LIST_DIR}/inc/bit + ${CMAKE_CURRENT_LIST_DIR}/inc/bitset + ${CMAKE_CURRENT_LIST_DIR}/inc/cassert + ${CMAKE_CURRENT_LIST_DIR}/inc/ccomplex + ${CMAKE_CURRENT_LIST_DIR}/inc/cctype + ${CMAKE_CURRENT_LIST_DIR}/inc/cerrno + ${CMAKE_CURRENT_LIST_DIR}/inc/cfenv + ${CMAKE_CURRENT_LIST_DIR}/inc/cfloat + ${CMAKE_CURRENT_LIST_DIR}/inc/charconv + ${CMAKE_CURRENT_LIST_DIR}/inc/chrono + ${CMAKE_CURRENT_LIST_DIR}/inc/cinttypes + ${CMAKE_CURRENT_LIST_DIR}/inc/ciso646 + ${CMAKE_CURRENT_LIST_DIR}/inc/climits + ${CMAKE_CURRENT_LIST_DIR}/inc/clocale + ${CMAKE_CURRENT_LIST_DIR}/inc/cmath + ${CMAKE_CURRENT_LIST_DIR}/inc/codecvt + ${CMAKE_CURRENT_LIST_DIR}/inc/compare + ${CMAKE_CURRENT_LIST_DIR}/inc/complex + ${CMAKE_CURRENT_LIST_DIR}/inc/concepts + ${CMAKE_CURRENT_LIST_DIR}/inc/condition_variable + ${CMAKE_CURRENT_LIST_DIR}/inc/coroutine + ${CMAKE_CURRENT_LIST_DIR}/inc/csetjmp + ${CMAKE_CURRENT_LIST_DIR}/inc/csignal + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdalign + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdarg + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdbool + ${CMAKE_CURRENT_LIST_DIR}/inc/cstddef + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdint + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdio + ${CMAKE_CURRENT_LIST_DIR}/inc/cstdlib + ${CMAKE_CURRENT_LIST_DIR}/inc/cstring + ${CMAKE_CURRENT_LIST_DIR}/inc/ctgmath + ${CMAKE_CURRENT_LIST_DIR}/inc/ctime + ${CMAKE_CURRENT_LIST_DIR}/inc/cuchar + ${CMAKE_CURRENT_LIST_DIR}/inc/cwchar + ${CMAKE_CURRENT_LIST_DIR}/inc/cwctype + ${CMAKE_CURRENT_LIST_DIR}/inc/deque + ${CMAKE_CURRENT_LIST_DIR}/inc/exception + ${CMAKE_CURRENT_LIST_DIR}/inc/execution + ${CMAKE_CURRENT_LIST_DIR}/inc/expected + ${CMAKE_CURRENT_LIST_DIR}/inc/experimental/coroutine + ${CMAKE_CURRENT_LIST_DIR}/inc/experimental/generator + ${CMAKE_CURRENT_LIST_DIR}/inc/experimental/resumable + ${CMAKE_CURRENT_LIST_DIR}/inc/filesystem + ${CMAKE_CURRENT_LIST_DIR}/inc/flat_map + ${CMAKE_CURRENT_LIST_DIR}/inc/flat_set + ${CMAKE_CURRENT_LIST_DIR}/inc/format + ${CMAKE_CURRENT_LIST_DIR}/inc/forward_list + ${CMAKE_CURRENT_LIST_DIR}/inc/fstream + ${CMAKE_CURRENT_LIST_DIR}/inc/functional + ${CMAKE_CURRENT_LIST_DIR}/inc/future + ${CMAKE_CURRENT_LIST_DIR}/inc/generator + ${CMAKE_CURRENT_LIST_DIR}/inc/header-units.json + ${CMAKE_CURRENT_LIST_DIR}/inc/initializer_list + ${CMAKE_CURRENT_LIST_DIR}/inc/iomanip + ${CMAKE_CURRENT_LIST_DIR}/inc/ios + ${CMAKE_CURRENT_LIST_DIR}/inc/iosfwd + ${CMAKE_CURRENT_LIST_DIR}/inc/iostream + ${CMAKE_CURRENT_LIST_DIR}/inc/iso646.h + ${CMAKE_CURRENT_LIST_DIR}/inc/istream + ${CMAKE_CURRENT_LIST_DIR}/inc/iterator + ${CMAKE_CURRENT_LIST_DIR}/inc/latch + ${CMAKE_CURRENT_LIST_DIR}/inc/limits + ${CMAKE_CURRENT_LIST_DIR}/inc/list + ${CMAKE_CURRENT_LIST_DIR}/inc/locale + ${CMAKE_CURRENT_LIST_DIR}/inc/map + ${CMAKE_CURRENT_LIST_DIR}/inc/mdspan + ${CMAKE_CURRENT_LIST_DIR}/inc/memory + ${CMAKE_CURRENT_LIST_DIR}/inc/memory_resource + ${CMAKE_CURRENT_LIST_DIR}/inc/mutex + ${CMAKE_CURRENT_LIST_DIR}/inc/new + ${CMAKE_CURRENT_LIST_DIR}/inc/numbers + ${CMAKE_CURRENT_LIST_DIR}/inc/numeric + ${CMAKE_CURRENT_LIST_DIR}/inc/optional + ${CMAKE_CURRENT_LIST_DIR}/inc/ostream + ${CMAKE_CURRENT_LIST_DIR}/inc/print + ${CMAKE_CURRENT_LIST_DIR}/inc/queue + ${CMAKE_CURRENT_LIST_DIR}/inc/random + ${CMAKE_CURRENT_LIST_DIR}/inc/ranges + ${CMAKE_CURRENT_LIST_DIR}/inc/ratio + ${CMAKE_CURRENT_LIST_DIR}/inc/regex + ${CMAKE_CURRENT_LIST_DIR}/inc/scoped_allocator + ${CMAKE_CURRENT_LIST_DIR}/inc/semaphore + ${CMAKE_CURRENT_LIST_DIR}/inc/set + ${CMAKE_CURRENT_LIST_DIR}/inc/shared_mutex + ${CMAKE_CURRENT_LIST_DIR}/inc/source_location + ${CMAKE_CURRENT_LIST_DIR}/inc/span + ${CMAKE_CURRENT_LIST_DIR}/inc/spanstream + ${CMAKE_CURRENT_LIST_DIR}/inc/sstream + ${CMAKE_CURRENT_LIST_DIR}/inc/stack + ${CMAKE_CURRENT_LIST_DIR}/inc/stacktrace + ${CMAKE_CURRENT_LIST_DIR}/inc/stdexcept + ${CMAKE_CURRENT_LIST_DIR}/inc/stdfloat + ${CMAKE_CURRENT_LIST_DIR}/inc/stop_token + ${CMAKE_CURRENT_LIST_DIR}/inc/streambuf + ${CMAKE_CURRENT_LIST_DIR}/inc/string + ${CMAKE_CURRENT_LIST_DIR}/inc/string_view + ${CMAKE_CURRENT_LIST_DIR}/inc/strstream + ${CMAKE_CURRENT_LIST_DIR}/inc/syncstream + ${CMAKE_CURRENT_LIST_DIR}/inc/system_error + ${CMAKE_CURRENT_LIST_DIR}/inc/thread + ${CMAKE_CURRENT_LIST_DIR}/inc/tuple + ${CMAKE_CURRENT_LIST_DIR}/inc/type_traits + ${CMAKE_CURRENT_LIST_DIR}/inc/typeindex + ${CMAKE_CURRENT_LIST_DIR}/inc/typeinfo + ${CMAKE_CURRENT_LIST_DIR}/inc/unordered_map + ${CMAKE_CURRENT_LIST_DIR}/inc/unordered_set + ${CMAKE_CURRENT_LIST_DIR}/inc/use_ansi.h + ${CMAKE_CURRENT_LIST_DIR}/inc/utility + ${CMAKE_CURRENT_LIST_DIR}/inc/valarray + ${CMAKE_CURRENT_LIST_DIR}/inc/variant + ${CMAKE_CURRENT_LIST_DIR}/inc/vector + ${CMAKE_CURRENT_LIST_DIR}/inc/version + ${CMAKE_CURRENT_LIST_DIR}/inc/xatomic.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xatomic_wait.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xbit_ops.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xcall_once.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xcharconv.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xcharconv_ryu.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xcharconv_ryu_tables.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xcharconv_tables.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xerrc.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xfacet + ${CMAKE_CURRENT_LIST_DIR}/inc/xfilesystem_abi.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xhash + ${CMAKE_CURRENT_LIST_DIR}/inc/xiosbase + ${CMAKE_CURRENT_LIST_DIR}/inc/xkeycheck.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocale + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocbuf + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocinfo + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocmes + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocmon + ${CMAKE_CURRENT_LIST_DIR}/inc/xlocnum + ${CMAKE_CURRENT_LIST_DIR}/inc/xloctime + ${CMAKE_CURRENT_LIST_DIR}/inc/xmemory + ${CMAKE_CURRENT_LIST_DIR}/inc/xnode_handle.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xpolymorphic_allocator.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xsmf_control.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xstring + ${CMAKE_CURRENT_LIST_DIR}/inc/xthreads.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xtimec.h + ${CMAKE_CURRENT_LIST_DIR}/inc/xtr1common + ${CMAKE_CURRENT_LIST_DIR}/inc/xtree + ${CMAKE_CURRENT_LIST_DIR}/inc/xutility + ${CMAKE_CURRENT_LIST_DIR}/inc/ymath.h + ${CMAKE_CURRENT_LIST_DIR}/inc/yvals.h + ${CMAKE_CURRENT_LIST_DIR}/inc/yvals_core.h +) + +foreach(header ${HEADERS}) + file(RELATIVE_PATH _header_path "${CMAKE_CURRENT_LIST_DIR}/inc" "${header}") + configure_file("${header}" "${PROJECT_BINARY_DIR}/out/inc/${_header_path}" COPYONLY) +endforeach() + +set(MODULE_FILES + ${CMAKE_CURRENT_LIST_DIR}/modules/modules.json + ${CMAKE_CURRENT_LIST_DIR}/modules/std.ixx + ${CMAKE_CURRENT_LIST_DIR}/modules/std.compat.ixx +) + +foreach(module_file ${MODULE_FILES}) + file(RELATIVE_PATH _module_file_path "${CMAKE_CURRENT_LIST_DIR}/modules" "${module_file}") + configure_file("${module_file}" "${PROJECT_BINARY_DIR}/out/modules/${_module_file_path}" COPYONLY) +endforeach() + +# Objs that implement aliases; these are completely independent of the configuration +set(ALIAS_SOURCES_X86_X64 + ${CMAKE_CURRENT_LIST_DIR}/src/alias_init_once_begin_initialize.asm + ${CMAKE_CURRENT_LIST_DIR}/src/alias_init_once_complete.asm +) + +# Objs that exist in both libcpmt[d][01].lib and msvcprt[d].lib. +set(IMPLIB_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/asan_noop.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/charconv.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/filesystem.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/format.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/locale0_implib.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/nothrow.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/print.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/regex.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/sharedmutex.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/stacktrace.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/syserror_import_lib.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/vector_algorithms.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xcharconv_ryu_tables.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xcharconv_tables_double.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xcharconv_tables_float.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xonce2.cpp +) + +# The following files are linked in msvcp140[d][_clr].dll. +set(DLL_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/dllmain.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/instances.cpp +) + +# Sources that must not be compiled with /GL, since they contain CRT initializers. +set(INITIALIZER_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/winapisupp.cpp +) + +set(SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/StlCompareStringA.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/StlCompareStringW.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/StlLCMapStringA.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/StlLCMapStringW.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/_tolower.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/_toupper.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/atomic.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cerr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cin.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/clog.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cond.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cout.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/cthread.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/filesys.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/fiopen.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/future.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/iomanip.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ios.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/iosptrs.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/iostream.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/locale.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/locale0.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/multprec.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/mutex.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/pplerror.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ppltasks.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/raisehan.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/stdhndlr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/stdthrow.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/syserror.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/taskscheduler.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/thread0.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/uncaught_exception.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/uncaught_exceptions.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ushcerr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ushcin.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ushclog.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ushcout.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ushiostr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wcerr.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wcin.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wclog.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wcout.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/winapinls.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wiostrea.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/wlocale.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xalloc.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xcosh.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xdateord.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xdtest.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xexp.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xgetwctype.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xlgamma.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xlocale.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xlock.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xmbtowc.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xmtx.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xnotify.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xonce.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xrngabort.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xrngdev.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xsinh.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstod.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstof.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstol.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstoll.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstoul.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstoull.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstrcoll.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xstrxfrm.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xthrow.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xtime.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xtowlower.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xtowupper.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xvalues.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xwcscoll.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xwcsxfrm.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xwctomb.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xwstod.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/xwstof.cpp +) + +set(ASAN_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/asan.cpp +) + +set(EHA_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/excptptr.cpp +) + +set(SOURCES_SATELLITE_1 + ${CMAKE_CURRENT_LIST_DIR}/src/memory_resource.cpp +) + +set(SOURCES_SATELLITE_2 + ${CMAKE_CURRENT_LIST_DIR}/src/special_math.cpp +) + +set(SOURCES_SATELLITE_ATOMIC_WAIT + ${CMAKE_CURRENT_LIST_DIR}/src/atomic_wait.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/parallel_algorithms.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/syncstream.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/tzdb.cpp +) + +set(SOURCES_SATELLITE_CODECVT_IDS + ${CMAKE_CURRENT_LIST_DIR}/src/ulocale.cpp +) + +# Objs that exist only in libcpmt[d][01].lib. +set(STATIC_SOURCES + ${SOURCES_SATELLITE_1} + ${SOURCES_SATELLITE_2} + ${SOURCES_SATELLITE_ATOMIC_WAIT} + ${SOURCES_SATELLITE_CODECVT_IDS} +) + +# Objs that exist in all satellite DLLs +set(SATELLITE_DLL_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/src/dllmain_satellite.cpp +) + +#################### +# Toolset options. # +#################### + +set(CMAKE_CXX_FLAGS "") +set(CMAKE_CXX_FLAGS_DEBUG "") +set(CMAKE_CXX_FLAGS_RELEASE "") +set(CMAKE_MSVC_RUNTIME_CHECKS "") +set(CMAKE_CXX_STANDARD_LIBRARIES "kernel32.lib") +set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "kernel32.lib") +set(CMAKE_MSVC_RUNTIME_LIBRARY "") + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${STL_ARCHIVE_OUTPUT_DIRECTORY}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${STL_LIBRARY_OUTPUT_DIRECTORY}") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${STL_RUNTIME_OUTPUT_DIRECTORY}") + +set(CMAKE_STATIC_LINKER_FLAGS "/WX") +set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "") +set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "") +set(CMAKE_SHARED_LINKER_FLAGS "/DEBUG:FULL /WX /RELEASE /SUBSYSTEM:Console /NODEFAULTLIB /INCREMENTAL:NO /MANIFEST:NO /DLL /profile /guard:cf /DEBUGTYPE:cv,fixup /LARGEADDRESSAWARE") +if(VCLIBS_TARGET_ARCHITECTURE STREQUAL "x64") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /CETCOMPAT") +endif() +if(VCLIBS_TARGET_ARCHITECTURE MATCHES "^(x64|arm64|arm64ec)$") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:ehcont") +endif() +if(VCLIBS_TARGET_ARCHITECTURE MATCHES "^(arm64|arm64ec)$") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:delayloadsignret") +endif() +set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "") +set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "") + +# Toolset options must appear before add_library() for the options to take effect. +add_compile_definitions(_CRTBLD _HAS_OLD_IOSTREAMS_MEMBERS=1) + +# /Z7 for MSVC, /Zi for MASM +set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "Embedded") + +add_compile_options(/nologo /WX /Gy + "$<$:/diagnostics:caret;/W4;/w14265;/w15038;/fastfail;/guard:cf;/Zp8;/std:c++latest;/permissive-;/Zc:preprocessor;/Zc:threadSafeInit-;/Zl>" + "$<$,$>:/guard:ehcont>" + "$<$,$>:/guard:signret>" + "$<$:/W3;/quiet>" +) + +include_directories(BEFORE + "${CMAKE_CURRENT_LIST_DIR}/inc" + "${TOOLSET_ROOT_DIR}/crt/src/vcruntime" +) + +########################### +# End of toolset options. # +########################### + +if(VCLIBS_TARGET_ARCHITECTURE MATCHES "^(x86|x64)$") + add_library(stl_alias_objects OBJECT ${ALIAS_SOURCES_X86_X64}) +else() + add_library(stl_alias_objects INTERFACE) +endif() + +if(STL_ASAN_BUILD) + set(DLL_ASAN_SOURCES ${ASAN_SOURCES}) +else() + set(DLL_ASAN_SOURCES "") +endif() + +function(target_stl_compile_options tgt rel_or_dbg) + if(rel_or_dbg STREQUAL "Release") + target_compile_options(${tgt} PRIVATE ${VCLIBS_RELEASE_OPTIONS}) + elseif(rel_or_dbg STREQUAL "Debug") + target_compile_options(${tgt} PRIVATE ${VCLIBS_DEBUG_OPTIONS}) + target_compile_definitions(${tgt} PRIVATE "_DEBUG") + else() + message(FATAL_ERROR "INTERNAL ERROR: unexpected value for rel_or_dbg: '${rel_or_dbg}'") + endif() +endfunction() + +function(generate_satellite_def SATELLITE_NAME D_SUFFIX) + set(full_satellite_name "msvcp140${D_SUFFIX}_${SATELLITE_NAME}${VCLIBS_SUFFIX}") + string(TOUPPER "${full_satellite_name}" upper_full_satellite_name) + set(satellite_input_src_file_path "${CMAKE_CURRENT_LIST_DIR}/src/msvcp_${SATELLITE_NAME}.src") + set(satellite_output_def_file_path "${CMAKE_BINARY_DIR}/msvcp_${SATELLITE_NAME}${D_SUFFIX}.def") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${satellite_input_src_file_path}") + + # We use the placeholder name "LIBRARYNAME" in the corresponding .src file of a satellite DLL + # (i.e., we write "LIBRARY LIBRARYNAME" as the first non-commented line in the file). + # + # Here, we dynamically replace this placeholder name with the name of the satellite DLL for + # the current build configuration. Then, we write out the new .def file to the binary output + # directory. + file(READ "${satellite_input_src_file_path}" satellite_def_file_contents) + string(REPLACE "LIBRARYNAME" "${upper_full_satellite_name}" satellite_def_file_contents "${satellite_def_file_contents}") + file(GENERATE OUTPUT "${satellite_output_def_file_path}" CONTENT "${satellite_def_file_contents}") +endfunction() + +function(add_stl_dlls D_SUFFIX REL_OR_DBG) + set(link_options_Release "/LTCG;/opt:ref,icf;${VCLIBS_EXPLICIT_MACHINE}") + set(link_options_Debug "/opt:ref,noicf;${VCLIBS_EXPLICIT_MACHINE}") + + set(gl_flag_Release "/GL") + set(gl_flag_Debug "") + + # msvcp140.dll + add_library(msvcp${D_SUFFIX}_objects OBJECT ${DLL_SOURCES} ${SOURCES} ${DLL_ASAN_SOURCES}) + target_compile_definitions(msvcp${D_SUFFIX}_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_objects ${REL_OR_DBG}) + + add_library(msvcp${D_SUFFIX}_init_objects OBJECT ${INITIALIZER_SOURCES}) + target_compile_definitions(msvcp${D_SUFFIX}_init_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_init_objects PRIVATE /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_init_objects ${REL_OR_DBG}) + + add_library(msvcp${D_SUFFIX}_eha_objects OBJECT ${EHA_SOURCES}) + target_compile_definitions(msvcp${D_SUFFIX}_eha_objects PRIVATE CRTDLL2 _DLL) + target_compile_options(msvcp${D_SUFFIX}_eha_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHa) + target_stl_compile_options(msvcp${D_SUFFIX}_eha_objects ${REL_OR_DBG}) + + add_library(msvcp${D_SUFFIX} SHARED) + target_link_libraries(msvcp${D_SUFFIX} PRIVATE msvcp${D_SUFFIX}_eha_objects msvcp${D_SUFFIX}_objects msvcp${D_SUFFIX}_init_objects "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") + if(VCLIBS_TARGET_ARCHITECTURE MATCHES "^(arm64|arm64ec)$") + target_link_libraries(msvcp${D_SUFFIX} PRIVATE "softintrin.lib") + endif() + set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_base${D_SUFFIX}${VCLIBS_SUFFIX}") + set_target_properties(msvcp${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + set_target_properties(msvcp${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}${VCLIBS_SUFFIX}") + target_link_options(msvcp${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) + + # import library 'statics' + add_library(msvcp${D_SUFFIX}_implib_objects OBJECT ${IMPLIB_SOURCES}) + target_compile_definitions(msvcp${D_SUFFIX}_implib_objects PRIVATE _DLL _ENFORCE_ONLY_CORE_HEADERS) + target_compile_options(msvcp${D_SUFFIX}_implib_objects PRIVATE /EHsc) # No /GL! + target_stl_compile_options(msvcp${D_SUFFIX}_implib_objects ${REL_OR_DBG}) + + add_library(msvcp${D_SUFFIX}_satellite_objects OBJECT ${SATELLITE_DLL_SOURCES}) + target_compile_definitions(msvcp${D_SUFFIX}_satellite_objects PRIVATE _DLL) + target_compile_options(msvcp${D_SUFFIX}_satellite_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_satellite_objects ${REL_OR_DBG}) + + # msvcp140_1.dll (the memory_resource satellite) + add_library(msvcp_1${D_SUFFIX}_objects OBJECT ${SOURCES_SATELLITE_1}) + target_compile_definitions(msvcp_1${D_SUFFIX}_objects PRIVATE _BUILDING_SATELLITE_1 _DLL) + target_compile_options(msvcp_1${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp_1${D_SUFFIX}_objects ${REL_OR_DBG}) + + add_library(msvcp_1${D_SUFFIX} SHARED) + target_link_libraries(msvcp_1${D_SUFFIX} PRIVATE msvcp_1${D_SUFFIX}_objects msvcp${D_SUFFIX}_satellite_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") + set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_1${D_SUFFIX}${VCLIBS_SUFFIX}") + set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + set_target_properties(msvcp_1${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140_1${D_SUFFIX}${VCLIBS_SUFFIX}") + target_link_options(msvcp_1${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) + + # msvcp140_2.dll (the special math satellite) + add_library(msvcp_2${D_SUFFIX}_objects OBJECT ${SOURCES_SATELLITE_2}) + target_compile_definitions(msvcp_2${D_SUFFIX}_objects PRIVATE _BUILDING_SATELLITE_2 _DLL) + target_compile_options(msvcp_2${D_SUFFIX}_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_link_libraries(msvcp_2${D_SUFFIX}_objects PRIVATE Boost::math) + target_stl_compile_options(msvcp_2${D_SUFFIX}_objects ${REL_OR_DBG}) + + add_library(msvcp_2${D_SUFFIX} SHARED) + target_link_libraries(msvcp_2${D_SUFFIX} PRIVATE msvcp_2${D_SUFFIX}_objects msvcp${D_SUFFIX}_satellite_objects msvcp${D_SUFFIX}_implib_objects msvcp${D_SUFFIX} "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") + set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_2${D_SUFFIX}${VCLIBS_SUFFIX}") + set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + set_target_properties(msvcp_2${D_SUFFIX} PROPERTIES OUTPUT_NAME "msvcp140_2${D_SUFFIX}${VCLIBS_SUFFIX}") + target_link_options(msvcp_2${D_SUFFIX} PRIVATE ${link_options_${REL_OR_DBG}}) + + # msvcp140_atomic_wait.dll (the atomic wait satellite) + add_library(msvcp${D_SUFFIX}_atomic_wait_objects OBJECT ${SOURCES_SATELLITE_ATOMIC_WAIT}) + target_compile_definitions(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE _BUILDING_SATELLITE_ATOMIC_WAIT _DLL) + target_compile_options(msvcp${D_SUFFIX}_atomic_wait_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_atomic_wait_objects ${REL_OR_DBG}) + + # generate the .def for msvcp140_atomic_wait.dll + generate_satellite_def("atomic_wait" "${D_SUFFIX}") + + add_library(msvcp${D_SUFFIX}_atomic_wait SHARED "${CMAKE_BINARY_DIR}/msvcp_atomic_wait${D_SUFFIX}.def") + target_link_libraries(msvcp${D_SUFFIX}_atomic_wait PRIVATE msvcp${D_SUFFIX}_atomic_wait_objects msvcp${D_SUFFIX}_satellite_objects msvcp${D_SUFFIX}_implib_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib" "advapi32.lib" "synchronization.lib") + set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_atomic_wait${D_SUFFIX}${VCLIBS_SUFFIX}") + set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + set_target_properties(msvcp${D_SUFFIX}_atomic_wait PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}_atomic_wait${VCLIBS_SUFFIX}") + target_link_options(msvcp${D_SUFFIX}_atomic_wait PRIVATE ${link_options_${REL_OR_DBG}}) + + # msvcp140_codecvt_ids.dll + add_library(msvcp${D_SUFFIX}_codecvt_ids_objects OBJECT ${SOURCES_SATELLITE_CODECVT_IDS}) + target_compile_definitions(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE _BUILDING_SATELLITE_CODECVT_IDS _DLL) + target_compile_options(msvcp${D_SUFFIX}_codecvt_ids_objects PRIVATE ${gl_flag_${REL_OR_DBG}} /EHsc) + target_stl_compile_options(msvcp${D_SUFFIX}_codecvt_ids_objects ${REL_OR_DBG}) + + add_library(msvcp${D_SUFFIX}_codecvt_ids SHARED) + target_link_libraries(msvcp${D_SUFFIX}_codecvt_ids PRIVATE msvcp${D_SUFFIX}_codecvt_ids_objects msvcp${D_SUFFIX}_satellite_objects "msvcp${D_SUFFIX}" "${TOOLSET_LIB}/vcruntime${D_SUFFIX}.lib" "${TOOLSET_LIB}/msvcrt${D_SUFFIX}.lib" "ucrt${D_SUFFIX}.lib") + set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES ARCHIVE_OUTPUT_NAME "msvcp140_codecvt_ids${D_SUFFIX}${VCLIBS_SUFFIX}") + set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + set_target_properties(msvcp${D_SUFFIX}_codecvt_ids PROPERTIES OUTPUT_NAME "msvcp140${D_SUFFIX}_codecvt_ids${VCLIBS_SUFFIX}") + target_link_options(msvcp${D_SUFFIX}_codecvt_ids PRIVATE ${link_options_${REL_OR_DBG}}) + + # import library + add_library(msvcp${D_SUFFIX}_implib STATIC ${HEADERS}) + target_link_libraries(msvcp${D_SUFFIX}_implib stl_alias_objects msvcp${D_SUFFIX}_implib_objects) + add_dependencies(msvcp${D_SUFFIX}_implib msvcp${D_SUFFIX} msvcp_1${D_SUFFIX} msvcp_2${D_SUFFIX} msvcp${D_SUFFIX}_atomic_wait msvcp${D_SUFFIX}_codecvt_ids) + set_target_properties(msvcp${D_SUFFIX}_implib PROPERTIES STATIC_LIBRARY_OPTIONS "/NOLOGO;/NODEFAULTLIB;/IGNORE:4006;$;$;$;$;$;${VCLIBS_EXPLICIT_MACHINE}") + set_target_properties(msvcp${D_SUFFIX}_implib PROPERTIES ARCHIVE_OUTPUT_NAME "msvcprt${D_SUFFIX}") +endfunction() + +add_stl_dlls("" Release) +add_stl_dlls("d" Debug) + +function(add_stl_statics FLAVOR_SUFFIX REL_OR_DBG IDL_VALUE) + add_library(libcpmt${FLAVOR_SUFFIX}_eha OBJECT ${EHA_SOURCES}) + target_compile_definitions(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE _ANNOTATE_STL "_ITERATOR_DEBUG_LEVEL=${IDL_VALUE}") + target_compile_options(libcpmt${FLAVOR_SUFFIX}_eha PRIVATE /EHa) + target_stl_compile_options(libcpmt${FLAVOR_SUFFIX}_eha ${REL_OR_DBG}) + + add_library(libcpmt${FLAVOR_SUFFIX} STATIC ${HEADERS} ${IMPLIB_SOURCES} ${SOURCES} ${INITIALIZER_SOURCES} ${STATIC_SOURCES}) + target_compile_definitions(libcpmt${FLAVOR_SUFFIX} PRIVATE _ANNOTATE_STL "_ITERATOR_DEBUG_LEVEL=${IDL_VALUE}") + target_compile_options(libcpmt${FLAVOR_SUFFIX} PRIVATE "$<$:/EHsc>") + target_link_libraries(libcpmt${FLAVOR_SUFFIX} PRIVATE Boost::math stl_alias_objects libcpmt${FLAVOR_SUFFIX}_eha) + target_stl_compile_options(libcpmt${FLAVOR_SUFFIX} ${REL_OR_DBG}) + set_target_properties(libcpmt${FLAVOR_SUFFIX} PROPERTIES STATIC_LIBRARY_OPTIONS "${VCLIBS_EXPLICIT_MACHINE}") +endfunction() + +add_stl_statics("" Release 0) +add_stl_statics("1" Release 1) +add_stl_statics("d" Debug 2) +add_stl_statics("d1" Debug 1) +add_stl_statics("d0" Debug 0) + +add_library(stl_asan STATIC ${ASAN_SOURCES}) +set_target_properties(stl_asan PROPERTIES STATIC_LIBRARY_OPTIONS "${VCLIBS_EXPLICIT_MACHINE}") + +configure_file(set_environment.bat.in "${PROJECT_BINARY_DIR}/set_environment.bat" @ONLY) +configure_file(set_environment.ps1.in "${PROJECT_BINARY_DIR}/set_environment.ps1" @ONLY) diff --git a/msvc-stl/stl/debugger/STL.natvis b/msvc-stl/stl/debugger/STL.natvis new file mode 100644 index 0000000..6c83247 --- /dev/null +++ b/msvc-stl/stl/debugger/STL.natvis @@ -0,0 +1,2357 @@ + + + + + + + {*($T1 *)this} + + *($T1 *)this + + + + + + {_Myval1} + + _Myval1 + + + + + + [{name(),sb}] + + + Enable "Allow Function Calls In Value Formatting" if you see "???" here + + + + + + {{ value={_Myval}, category={*_Mycat} }} + + + Enable "Allow Function Calls In Value Formatting" if you see "???" here + + _Myval + _Mycat + + + + + + null + + + + + + {{ size={_Last - _First} }} + + + _Last - _First + _First + + + + + + + {first}, {second} + ({first}, {second}) + + first + second + + + + + + ({*this,view(noparens)}) + + + + + + + + {_Myfirst._Val}, {*((_Mybase *) this),view(noparens)} + + {_Myfirst._Val} + ({*this,view(noparens)}) + + _Myfirst._Val + ((_Mybase *) this)->_Myfirst._Val + ((_Mybase::_Mybase *) this)->_Myfirst._Val + ((_Mybase::_Mybase::_Mybase *) this)->_Myfirst._Val + ((_Mybase::_Mybase::_Mybase::_Mybase *) this)->_Myfirst._Val + + Next five elements: + + *((_Mybase::_Mybase::_Mybase::_Mybase::_Mybase *) this) + + + + + + {_Myfirst._Val}, {*((_Mybase *) this),view(noparensasptr)} + + {&_Myfirst._Val} + ({*this,view(noparensasptr)}) + + &_Myfirst._Val + &((_Mybase *) this)->_Myfirst._Val + &((_Mybase::_Mybase *) this)->_Myfirst._Val + &((_Mybase::_Mybase::_Mybase *) this)->_Myfirst._Val + &((_Mybase::_Mybase::_Mybase::_Mybase *) this)->_Myfirst._Val + + Next five elements: + + *((_Mybase::_Mybase::_Mybase::_Mybase::_Mybase *) this),view(asptr) + + + + + nullopt + + + + nullopt + {_Value} + + _Value + + + + + + {_Elem} + + + + + [valueless_by_exception] + {{ index=0, value={_Head} }} + {{ index=1, value={_Tail._Head} }} + {{ index=2, value={_Tail._Tail._Head} }} + {{ index=3, value={_Tail._Tail._Tail._Head} }} + {{ index=4, value={_Tail._Tail._Tail._Tail._Head} }} + {{ index=5, value={_Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=6, value={_Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=7, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=8, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=9, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=10, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=11, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=12, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=13, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=14, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=15, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=16, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=17, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=18, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=19, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=20, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=21, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=22, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=23, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=24, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=25, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=26, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=27, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=28, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=29, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=30, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + {{ index=31, value={_Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head} }} + + index() + _Head + _Tail._Head + _Tail._Tail._Head + _Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + _Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Tail._Head + + + + + monostate + + + + + {unex()} + + unex() + + + + + + {unex()} + + unex() + + + + + + + + {value()} + {unex()} + + value() + unex() + + + + + + + void + {unex()} + + unex() + + + + + + {{ size={$T1} }} + + + $T1 + (_Array[$i / _Bitsperword] >> ($i % _Bitsperword)) & 1,d + + + + + + {(_Pbitset->_Array[_Mypos / _Pbitset->_Bitsperword] >> (_Mypos % _Pbitset->_Bitsperword)) & 1,d} + + _Pbitset + _Mypos + + + + + + allocator + + + + + + default_delete + + + + + + _Mypair._Myval2 + empty + unique_ptr void + + _Mypair._Myval2 + _Mypair + + + + + _Mypair._Myval2 + empty + unique_ptr {*_Mypair._Myval2} + + _Mypair._Myval2 + _Mypair + + + + + + + + + + + + + + {{empty}} + {_Mypair._Myval2} + _Mypair._Myval2 + + _Mypair + _Mypair._Myval2,hv + + + + + default + + _Ptr + + + + + + custom deleter + + _Mypair._Myval2 + _Mypair + + + + + + custom deleter, custom allocator + + _Mypair._Myval2._Myval2 + _Mypair + _Mypair._Myval2 + + + + + make_shared + + ($T1 *) &_Storage + + + + + + make_shared + + ($T1 *) &_Storage + + + + + + make_shared<T[N]> + + _Storage._Value + + + + + + + + make_shared<T[]> + + + size() + data() + + + + + + + make_shared<T[]> + + _Storage._Value + + + + + + allocate_shared + + ($T1 *) &_Mypair._Myval2 + _Mypair + + + + + + + + + + + + allocate_shared + + ($T1 *) &_Storage + allocator() + + + + + + + + + + allocate_shared<T[N]> + + _Storage._Value + allocator() + + + + + + + + + + + + allocate_shared<T[]> + + allocator() + + size() + data() + + + + + + + + + + + allocate_shared_for_overwrite + + ($T1 *) &_Storage + allocator() + + + + + + + + + + allocate_shared_for_overwrite<T[N]> + + _Storage._Value + allocator() + + + + + + + + + + + + allocate_shared_for_overwrite<T[]> + + allocator() + + size() + data() + + + + + + + custom deleter + + _Mypair._Myval2 + _Mypair + + + + + + custom deleter, custom allocator + + _Mypair._Myval2._Myval2 + _Mypair + _Mypair._Myval2 + + + + + + _Ptr + empty + nullptr + void + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + + _Ptr + *_Rep + + + + + _Ptr + empty + nullptr + {*_Ptr} + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + shared_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + + _Ptr + *_Rep + + + + + + empty + nullptr + void + expired [{_Rep->_Weaks} weak ref] [{*_Rep}] + expired [{_Rep->_Weaks} weak refs] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + + _Ptr + *_Rep + + + + + empty + nullptr + {*_Ptr} + expired [{_Rep->_Weaks} weak ref] [{*_Rep}] + expired [{_Rep->_Weaks} weak refs] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong ref, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak ref] [{*_Rep}] + weak_ptr {*this,view(ptr)} [{_Rep->_Uses} strong refs, {_Rep->_Weaks - 1} weak refs] [{*_Rep}] + + _Ptr + *_Rep + + + + + + + {*_Ptr} + + _Ptr + + + + + ranges::equal_to + ranges::not_equal_to + ranges::greater + ranges::less + ranges::greater_equal + ranges::less_equal + compare_three_way + + + plus<> + minus<> + multiplies<> + divides<> + modulus<> + negate<> + equal_to<> + not_equal_to<> + greater<> + less<> + greater_equal<> + less_equal<> + logical_and<> + logical_or<> + logical_not<> + bit_and<> + bit_or<> + bit_xor<> + bit_not<> + + + plus + minus + multiplies + divides + modulus + negate + equal_to + not_equal_to + greater + less + greater_equal + less_equal + logical_and + logical_or + logical_not + bit_and + bit_or + bit_xor + bit_not + + + + not1({_Functor}) + + _Functor + + + + + not2({_Functor}) + + _Functor + + + + + + _{$T1,d} + + + + + + bind({_Mypair}, {_Mypair._Myval2,view(noparens)}) + + _Mypair + _Mypair._Myval2 + + + + + bind_front({_Mypair}, {_Mypair._Myval2,view(noparens)}) + + _Mypair + _Mypair._Myval2 + + + + + bind_back({_Mypair}, {_Mypair._Myval2,view(noparens)}) + + _Mypair + _Mypair._Myval2 + + + + + + + mem_fn({_Pm}) + + + + + + + {_Mypair._Myval2} + + _Mypair._Myval2 + _Mypair + + + + + {_Callee} + + _Callee + + + + + + empty + {*_Mystorage._Ptrs[_EEN_IMPL]} + + *_Mystorage._Ptrs[_EEN_IMPL] + + + + + + hash + + + + + + {_MyRep} nanosecond + {_MyRep} nanoseconds + + + + + {_MyRep} microsecond + {_MyRep} microseconds + + + + + {_MyRep} millisecond + {_MyRep} milliseconds + + + + + {_MyRep} second + {_MyRep} seconds + + + + + {_MyRep} minute + {_MyRep} minutes + + + + + {_MyRep} hour + {_MyRep} hours + + + + + {_MyRep} day + {_MyRep} days + + + + + {_MyRep} week + {_MyRep} weeks + + + + + {_MyRep} month + {_MyRep} months + + + + + {_MyRep} year + {_MyRep} years + + + + + {(int)_Day}st + {(int)_Day}nd + {(int)_Day}rd + {(int)_Day}th + + + + + January + February + March + April + May + June + July + August + September + October + November + December + {_Month} + + + + + {_Year} + + + + + Sunday + Monday + Tuesday + Wednesday + Thursday + Friday + Saturday + {_Weekday} + + + + + {(int)_Index}st {_Weekday} + {(int)_Index}nd {_Weekday} + {(int)_Index}rd {_Weekday} + {(int)_Index}th {_Weekday} + {(int)_Index}, {_Weekday} + + _Weekday + (int)_Index + + + + + Last {_Weekday} + + _Weekday + + + + + {_Month} {_Day} + + _Month + _Day + + + + + Last day of {_Month} + + _Month + + + + + {_Weekday_index} of {_Month} + + _Month + _Weekday_index + + + + + Last {_Weekday_last._Weekday} of {_Month} + + _Month + _Weekday_last._Weekday + + + + + {_Year} {_Month} + + _Year + _Month + + + + + {_Year} {_Month} {_Day} + + _Year + _Month + _Day + + + + + {_Month_day_last}, {_Year} + + _Year + _Month_day_last._Month + + + + + {_Weekday_index} of {_Month}, {_Year} + + _Year + _Month + _Weekday_index + + + + + {_Weekday_last} of {_Month}, {_Year} + + _Year + _Month + _Weekday_last._Weekday + + + + + -{_Hours._MyRep}h {_Mins._MyRep}m {_Secs._MyRep}s {_Sub_secs._MyRep}ss + {_Hours._MyRep}h {_Mins._MyRep}m {_Secs._MyRep}s {_Sub_secs._MyRep}ss + + _Is_neg + _Hours + _Mins + _Secs + _Sub_secs + + + + + + + + + + + + + {_Mypair._Myval2._Bx._Buf,na} + {_Mypair._Myval2._Bx._Ptr,na} + _Mypair._Myval2._Bx._Buf,na + _Mypair._Myval2._Bx._Ptr,na + + size() + capacity() + _Mypair + + _Mypair._Myval2._Mysize + _Mypair._Myval2._Bx._Buf + _Mypair._Myval2._Bx._Ptr + + + + + + + _Ptr,na + + _Ptr + + + + + + + {_Mydata,[_Mysize]na} + _Mydata,[_Mysize]na + + size() + + size() + data() + + + + + + + _Myptr,na + + _Myptr + + + + + + {_Mydata + _Myoff,[_Mysize - _Myoff]na} + _Mydata + _Myoff,[_Mysize - _Myoff]na + + _Mydata + _Myoff + _Myoff + _Mydata,[_Mysize]na + + + + + + {{ size={$T2} }} + + + $T2 + _Elems + + + + + + + + _Ptr,na + {*_Ptr} + + _Ptr + + + + + + + _Ptr + _Idx + {_Ptr[_Idx]} + end + + _Ptr + _Idx + + + + + + {{ size={size()} }} + + _Mypair + + size() + _Mypair._Myval2._Map[(($i + _Mypair._Myval2._Myoff) / _EEN_DS) % _Mypair._Myval2._Mapsize][($i + _Mypair._Myval2._Myoff) % _EEN_DS] + + + + + + + {((_Mydeque_t *)_Myproxy->_Mycont)->_Map[(_Myoff / _EEN_DS) % ((_Mydeque_t *)_Myproxy->_Mycont)->_Mapsize][_Myoff % _EEN_DS]} + end + + _Myoff - ((_Mydeque_t *)_Myproxy->_Mycont)->_Myoff + &((_Mydeque_t *)_Myproxy->_Mycont)->_Map[(_Myoff / _EEN_DS) % ((_Mydeque_t *)_Myproxy->_Mycont)->_Mapsize][_Myoff % _EEN_DS] + + + + + + + empty + non-empty + + _Mypair + + _Mypair._Myval2._Myhead + _Next + _Myval + + + + + + + &_Ptr->_Myval,na + end + {**this} + + + + + {{ size={_Mypair._Myval2._Mysize} }} + + _Mypair + + _Mypair._Myval2._Mysize + _Mypair._Myval2._Myhead->_Next + _Next + _Myval + + + + + + + &_Ptr->_Myval,na + + + + + + + + {{ size={size()} }} + + capacity() + _Myvec._Mypair + + _Mysize + (bool)((_Myvec._Mypair._Myval2._Myfirst[$i / _EEN_VBITS] >> ($i % _EEN_VBITS)) & 1) + + + + + + + + {(bool)((*_Myptr >> _Myoff) & 1)} + + _Myptr + _Myoff + + + + + + + + + {{ size={size()} }} + + capacity() + _Mypair + + size() + _Mypair._Myval2._Myfirst + + + + + + + + + + + + + data() + {data(),[size()]na} + {{empty}} + + size() + capacity() + _Mypair + + size() + data() + + + + + + + + _Ptr,na + {*_Ptr} + + _Ptr + + + + + + + + _Ptr,na + end + {*_Ptr} + + _Ptr + + + + + + + + + {{ size={_Mypair._Myval2._Myval2._Mysize} }} + + _Mypair + _Mypair._Myval2 + + _Mypair._Myval2._Myval2._Mysize + _Mypair._Myval2._Myval2._Myhead->_Parent + _Left + _Right + _Myval + + + + + + + + {{ size={_Mypair._Myval2._Myval2._Mysize} }} + + _Mypair + _Mypair._Myval2 + + _Mypair._Myval2._Myval2._Mysize + _Mypair._Myval2._Myval2._Myhead->_Parent + _Left + _Right + _Myval,view(MapHelper) + + + + + + {second} + + + + + _Ptr->_Isnil ? nullptr : &_Ptr->_Myval + {_Ptr->_Myval} + end + + &_Ptr->_Myval + + + + + + + + + + {_List} + + _Maxidx + ((float)_List._Mypair._Myval2._Mysize) / ((float)_Maxidx) + _Traitsobj._Max_buckets + _List._Mypair + _List,view(simple) + + + + + + + + + {_List} + + _Maxidx + ((float)_List._Mypair._Myval2._Mysize) / ((float)_Maxidx) + _Traitsobj._Mypair._Myval2._Myval2 + _Traitsobj._Mypair + _Traitsobj._Mypair._Myval2 + _List._Mypair + _List,view(simple) + + + + + + {_List} + + _Maxidx + ((float)_List._Mypair._Myval2._Mysize) / ((float)_Maxidx) + _Traitsobj._Mypair._Myval2._Myval2 + _Traitsobj._Mypair + _Traitsobj._Mypair._Myval2 + _List._Mypair + _List,view(MapHelper) + + + + + + Test + + + _Mypair._Myval2._Mysize + _Mypair._Myval2._Myhead->_Next + _Next + _Myval + + + + + + + + {c} + + c + + + + + + {c} + + c + comp + + + + + + + + current._Ptr - 1,na + reverse_iterator {current._Ptr[-1]} + + current._Ptr - 1 + + + + + + + current._Ptr + current._Idx - 1,na + reverse_iterator {current._Ptr[current._Idx - 1]} + reverse_iterator rend + + current._Ptr + current._Idx - 1 + + + + + + &current._Ptr->_Prev->_Myval,na + reverse_iterator {**this} + + + + + current._Ptr - 1,na + reverse_iterator {**this} + + current._Ptr - 1 + + + + + reverse_iterator base() {current} + + NOTE: *ri is equivalent to *prev(ri.base()) + current + + + + + + current - 1 + reverse_iterator {current[-1]} + + current - 1 + + + + + + back_insert_iterator into {container} + + container + + + + + + front_insert_iterator into {container} + + container + + + + + + insert_iterator into {container} at {iter} + + container + iter + + + + + + move_iterator {_Current} + + _Current + + + + + + basic_const_iterator {_Current} + + _Current + + + + + + -i*{-_Val[1]} + {_Val[0]}-i*{-_Val[1]} + {_Val[0]} + i*{_Val[1]} + {_Val[0]}+i*{_Val[1]} + + _Val[0] + _Val[1] + + + + + + {{ size={_Mysize} }} + + + _Mysize + _Myptr + + + + + + + + + {data(),[size()]} + + + + + {_Stringbuffer} + + _Stringbuffer + + + + + {_Stringbuffer} + + _Stringbuffer + + + + + {_Stringbuffer} + + _Stringbuffer + + + + + + empty + {_Visualization} + _Visualization + + + + + + {first,[second - first]na} + false + + matched + first + second + + + + + + {first._Ptr,[second._Ptr - first._Ptr]na} + false + + matched + first + second + + + + + + not ready + {_Matches} + + _Matches,view(simple) + _Prefix + _Suffix + + + + + + &_MyVal + end + {_MyVal} + + _Begin + _End + _MyRe + _Flags + _MyVal + + + + + + _Res + end + {*_Res} + + _Pos + _Res + _Suffix + _Cur + _Subs + + + + + + + + + + {value()} + + value() + + + + + + + + + + {value()} + + + + + + unlocked + locked + + _Mtx_storage._Thread_id + _Mtx_storage._Count + + + + + + unlocked + locked + + _My_owner + _My_locked + + + + + {&_MyMutex} + + &_MyMutex + + + + + empty + {*_Pmtx} - unowned + {*_Pmtx} - owned + + _Pmtx + _Owns + + + + + () + + + + ({&_MyMutex}) + + &_MyMutex + + + + + {_MyMutexes,view(asptr)} + + _MyMutexes,view(asptr) + + + + + std::defer_lock + + + + std::try_to_lock + + + + std::adopt_lock + + + + incomplete + complete + + + + + + _Retrieved + _Result + _Exception + + + + + + + empty + pending + has_result + + *_MyPromise._State._Assoc_state + _MyPromise._Future_retrieved + + + + + + + empty + pending + has_result + + *_Assoc_state + + + + + + + ptr_fun({_Pfun}) + + + + + + + + mem_fun({_Pmemfun}) + + + + + + + + mem_fun_ref({_Pmemfun}) + + + + + bind1st({op}, {value}) + + op + value + + + + + bind2nd({op}, {value}) + + op + value + + + + + empty + auto_ptr {*_Myptr} + + _Myptr + + + + + + + {_Ptr->_Fn,na}, #initial suspend + {_Ptr->_Fn,na}, #final suspend + {_Ptr->_Fn,na}, suspend point #{(_Ptr->_Index)/2 - 1} + {_Ptr->_Fn,na} + + "initial suspend" + "final suspend" + (_Ptr->_Index)/2 - 1 + this,view(ViewPromise) + + + + + + + + + + + + *reinterpret_cast<$T1 *>(reinterpret_cast<char*>(_Ptr) - _ALIGNED_SIZE) + + + + + + + *reinterpret_cast<$T1 *>(reinterpret_cast<char*>(_Ptr) + 2*sizeof(void*)) + + + + + + + + + + + + + + empty + {primary_function(_Ptr),na} #final suspend + {primary_function(_Ptr),na} #initial suspend + {primary_function(_Ptr),na} #suspend point {suspend_point(_Ptr)} + {primary_function(_Ptr),na} #suspend point {suspend_point(_Ptr)}, line {suspend_point_line(_Ptr)} + + this,view(ViewPromise) + + + + + + + + + + + + + {{ size={size()} }} + + + size() + data() + + + + + + + _Myptr,na + {*_Myptr} + + _Myptr + + + + + + _Myptr,na + end + {*_Myptr} + + _Myptr + + + + + default sentinel + + + + unreachable + + + + {{}} + + + + [{ _Val._Val }] + + + 1 + &_Val._Val + + + + + + + [{_Value}; {_Bound}) + + size() + + + + size() + + + val + ++val + + + + + + + [{_Value}; +∞) + + _Value + + + + + [{_Value._Val} x {_Bound}] + + _Bound + + + + + + _Value._Val + ++idx + + + + + + + [{_Value._Val} x +∞] + + _Value._Val + + + + + {*_Value} + + _Value + _Current + + + + + {*_Value} + + _Value + + + + + dangling + + + + {_Base} + + + + {_Stream} + + _Val + + + + + &_Current,na + + _Current + + + + + {&_Last,na} + + _Last + + + + + + + + + + + + + + + + + + + {_Range} + + _Pred + _Next + _Count + _Fun + _Pattern + _Stride + + + + + {{ id={_Thr._Id} }} + + + + {_Id} + + + + {_Impl} + + + + {_Text} + + + + {_Function,sb}: ({_Line}, {_Column}) + + _Line + _Column + _File,s + _Function,s + + + + + less + equal + greater + + + + + less + equivalent + greater + + + + + less + equivalent + greater + unordered + + + + + {_Format_string} + + _Num_args + _Next_arg_id + + + + + + + + + {{ size={_Num_args} }} + + + _Num_args + "None" + + + *(int*)(&storage()[_Index_array[$i]._Index]) + + + + *(unsigned int*)(&storage()[_Index_array[$i]._Index]) + + + + *(long long*)(&storage()[_Index_array[$i]._Index]) + + + + *(unsigned long long*)(&storage()[_Index_array[$i]._Index]) + + + + *(bool*)(&storage()[_Index_array[$i]._Index]) + + + + *(char*)(&storage()[_Index_array[$i]._Index]) + + + + *(float*)(&storage()[_Index_array[$i]._Index]) + + + + *(double*)(&storage()[_Index_array[$i]._Index]) + + + + *(long double*)(&storage()[_Index_array[$i]._Index]) + + + + *(void**)(&storage()[_Index_array[$i]._Index]) + + + + *(char**)(&storage()[_Index_array[$i]._Index]) + + + + *(std::string_view*)(&storage()[_Index_array[$i]._Index]) + + + + *(void**)(&storage()[_Index_array[$i]._Index]) + + + + + + + + + + + {{ size={_Num_args} }} + + + _Num_args + + + *(int*)(&storage()[_Index_array[$i]._Index]) + + + + *(unsigned int*)(&storage()[_Index_array[$i]._Index]) + + + + *(long long*)(&storage()[_Index_array[$i]._Index]) + + + + *(unsigned long long*)(&storage()[_Index_array[$i]._Index]) + + + + *(bool*)(&storage()[_Index_array[$i]._Index]) + + + + *(wchar_t*)(&storage()[_Index_array[$i]._Index]) + + + + *(float*)(&storage()[_Index_array[$i]._Index]) + + + + *(double*)(&storage()[_Index_array[$i]._Index]) + + + + *(long double*)(&storage()[_Index_array[$i]._Index]) + + + + *(void**)(&storage()[_Index_array[$i]._Index]) + + + + *(wchar_t**)(&storage()[_Index_array[$i]._Index]) + + + + *(std::wstring_view*)(&storage()[_Index_array[$i]._Index]) + + + + *(void**)(&storage()[_Index_array[$i]._Index]) + + + + + + + No state: {_No_state} + Int state: {_Int_state} + UInt state: {_UInt_state} + Long long state: {_Long_long_state} + ULong long state: {_ULong_long_state} + Bool state: {_Bool_state} + Char state: {_Char_state} + Float state: {_Float_state} + Double state: {_Double_state} + Long double state: {_Long_double_state} + Pointer state: {_Pointer_state} + CString state: {_CString_state} + String state: {_String_state} + Custom state: {_Custom_state} + Invalid state: {_Active_state} + + + + {_Args} + + _OutputIt + _Loc + + + + + {what()} + + + + + + {_Data} + + + + + + + + + + [empty] + [not empty (trivial)] + [not empty (small)] + [not empty (large)] + + (void*)(&_Storage._TrivialData) + (void*)(&_Storage._SmallStorage._Data) + _Storage._BigStorage._Ptr + + {has_value()} + + + {type()} + + + (Small and Trivial Object) + + + (Small Object) + + + (Dynamic Allocation) + + + + + + + + + + + + + + + + + + + + + {year(),d}-{month()/10,d}{month()%10,d}-{day()/10,d}{day()%10,d} { + (_MyDur._MyRep % (24 * 60 * 60 * 10000000ull))/(10 * 60 * 60 * 10000000ull),d + }{ + ((_MyDur._MyRep % (24 * 60 * 60 * 10000000ull))/(60 * 60 * 10000000ull)) % 10,d + }:{ + (_MyDur._MyRep % (60 * 60 * 10000000ull))/(10 * 60 * 10000000ull),d + }{ + (_MyDur._MyRep % (10 * 60 * 10000000ull)) / (60 * 10000000ull),d + }:{ + (_MyDur._MyRep % (60 * 10000000ull)) / (10 * 10000000ull),d + }{ + (_MyDur._MyRep % (10 * 10000000ull)) / 10000000ull,d + }.{ + (_MyDur._MyRep % 10000000) / 1000000,d + }{ + (_MyDur._MyRep % 1000000) / 100000,d + }{ + (_MyDur._MyRep % 100000) / 10000,d + }{ + (_MyDur._MyRep % 10000) / 1000,d + }{ + (_MyDur._MyRep % 1000) / 100,d + }{ + (_MyDur._MyRep % 100) / 10,d + }{ + _MyDur._MyRep % 10,d + } + + + _MyDur._MyRep + _MyDur._MyRep/10 + _MyDur._MyRep/(10 * 1000) + _MyDur._MyRep/(10 * 1000 * 1000) + UTC + + + + + {{ rank={_Rank}, rank_dynamic={_Rank_dynamic} }} + + + + + + + + + + *dynptr + ++dynptr + + ($T1) *statptr + ++idx, ++statptr + + + + + + + + + + *dynptr + ++idx, ++dynptr + + + + + + + + + + ($T1) *statptr + ++idx, ++statptr + + + + + + + + + + + + + + + + {{ size={size()} }} + + + size() + _Key_compare + + + size() + + *value_at(i) + ++i + + + + + + + + + + {{ size={size()} }} + + _Key_compare + _Data.keys + _Data.values + + + + + ({_Key_it}, {_Mapped_it}) + + _Key_it + _Mapped_it + + + + + + {_Data} + + _Key_compare + _Data + + + + diff --git a/msvc-stl/stl/inc/__msvc_all_public_headers.hpp b/msvc-stl/stl/inc/__msvc_all_public_headers.hpp new file mode 100644 index 0000000..da0e110 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_all_public_headers.hpp @@ -0,0 +1,225 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// This file is intended as a test resource for tools that want to verify that they can parse all MSVC standard +// library headers without warnings. This file disables deprecations, so it should not be included in programs directly. +// +// This file may be changed, renamed, or removed at any time. + +#ifndef __MSVC_ALL_PUBLIC_HEADERS_HPP +#define __MSVC_ALL_PUBLIC_HEADERS_HPP + +#pragma warning(push) +#pragma warning(1 : 4668) // 'MEOW' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + +// All STL headers should protect themselves from macroized new. +#if !(defined(__CUDACC__) && defined(__clang__)) +#pragma push_macro("new") +#undef new +#define new WILL NOT COMPILE +#endif // !(defined(__CUDACC__) && defined(__clang__)) + +// VSO-768746: mbctype.h macroizes _MS, _MP, _M1, and _M2. Include it first for test coverage. +#ifndef _MSVC_TESTING_NVCC +#include +#endif // !defined(_MSVC_TESTING_NVCC) + +#ifndef _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING +#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING +#endif // !defined(_SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING) + +#define _SILENCE_CXX20_CISO646_REMOVED_WARNING + +// Core STL Headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Core C Wrapper Headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _CORE_HEADERS_ONLY + +// Non-Core STL Headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _M_CEE_PURE +#include <__msvc_cxx_stdatomic.hpp> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // !defined(_M_CEE_PURE) + +// Non-Core C Wrapper Headers +#include +#include +#include +#include +#include +#include + +#endif // !defined(_CORE_HEADERS_ONLY) + +#ifndef _MSVC_TESTING_NVCC +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _CORE_HEADERS_ONLY +#include +#include +#endif // !defined(_CORE_HEADERS_ONLY) + +#ifndef _M_CEE_PURE +#include +#endif // !defined(_M_CEE_PURE) +#endif // !defined(_MSVC_TESTING_NVCC) + +#if !(defined(__CUDACC__) && defined(__clang__)) +#pragma pop_macro("new") +#endif // !(defined(__CUDACC__) && defined(__clang__)) + +#pragma warning(pop) + +#endif // __MSVC_ALL_PUBLIC_HEADERS_HPP diff --git a/msvc-stl/stl/inc/__msvc_bit_utils.hpp b/msvc-stl/stl/inc/__msvc_bit_utils.hpp new file mode 100644 index 0000000..5b4ae34 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_bit_utils.hpp @@ -0,0 +1,406 @@ +// __msvc_bit_utils.hpp internal header (core) + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_BIT_UTILS_HPP +#define __MSVC_BIT_UTILS_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#include +#include + +#include _STL_INTRIN_HEADER + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +_STD_BEGIN +extern "C" { +extern int __isa_available; +} + +_INLINE_VAR constexpr int _Stl_isa_available_sse42 = 2; // equal to __ISA_AVAILABLE_SSE42 +_INLINE_VAR constexpr int _Stl_isa_available_avx2 = 5; // equal to __ISA_AVAILABLE_AVX2 + +template +constexpr int _Unsigned_integer_digits = sizeof(_UInt) * CHAR_BIT; + +// Implementation of countl_zero without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +// see "Hacker's Delight" section 5-3 +template +_NODISCARD constexpr int _Countl_zero_fallback(_Ty _Val) noexcept { + _Ty _Yx = 0; + + unsigned int _Nx = _Unsigned_integer_digits<_Ty>; + unsigned int _Cx = _Unsigned_integer_digits<_Ty> / 2; + do { + _Yx = static_cast<_Ty>(_Val >> _Cx); + if (_Yx != 0) { + _Nx -= _Cx; + _Val = _Yx; + } + _Cx >>= 1; + } while (_Cx != 0); + return static_cast(_Nx) - static_cast(_Val); +} + +#if !defined(_M_CEE_PURE) +#define _HAS_COUNTL_ZERO_INTRINSICS 1 +#else // ^^^ intrinsics available / intrinsics unavailable vvv +#define _HAS_COUNTL_ZERO_INTRINSICS 0 +#endif // ^^^ intrinsics unavailable ^^^ + +#if _HAS_COUNTL_ZERO_INTRINSICS +#if (defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC)) +template +_NODISCARD int _Countl_zero_lzcnt(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + + if constexpr (_Digits <= 16) { + return static_cast(__lzcnt16(_Val) - (16 - _Digits)); + } else if constexpr (_Digits == 32) { + return static_cast(__lzcnt(_Val)); + } else { +#ifdef _WIN64 + return static_cast(__lzcnt64(_Val)); +#else // ^^^ 64-bit / 32-bit vvv + const unsigned int _High = _Val >> 32; + const auto _Low = static_cast(_Val); + if (_High == 0) { + return 32 + _Countl_zero_lzcnt(_Low); + } else { + return _Countl_zero_lzcnt(_High); + } +#endif // ^^^ 32-bit ^^^ + } +} + +template +_NODISCARD int _Countl_zero_bsr(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + + unsigned long _Result; + if constexpr (_Digits <= 32) { + if (!_BitScanReverse(&_Result, _Val)) { + return _Digits; + } + } else { +#ifdef _WIN64 + if (!_BitScanReverse64(&_Result, _Val)) { + return _Digits; + } +#else // ^^^ 64-bit / 32-bit vvv + const unsigned int _High = _Val >> 32; + if (_BitScanReverse(&_Result, _High)) { + return static_cast(31 - _Result); + } + + const auto _Low = static_cast(_Val); + if (!_BitScanReverse(&_Result, _Low)) { + return _Digits; + } +#endif // ^^^ 32-bit ^^^ + } + return static_cast(_Digits - 1 - _Result); +} + +template +_NODISCARD int _Checked_x86_x64_countl_zero(const _Ty _Val) noexcept { +#ifndef __AVX2__ + const bool _Definitely_have_lzcnt = __isa_available >= _Stl_isa_available_avx2; + if (!_Definitely_have_lzcnt) { + return _Countl_zero_bsr(_Val); + } +#endif // ^^^ !defined(__AVX2__) ^^^ + return _Countl_zero_lzcnt(_Val); +} +#endif // (defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC)) + +#if defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) +template +_NODISCARD int _Checked_arm64_countl_zero(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + if (_Val == 0) { + return _Digits; + } + + if constexpr (_Digits <= 32) { + return static_cast(_CountLeadingZeros(_Val)) - (_Unsigned_integer_digits - _Digits); + } else { + return static_cast(_CountLeadingZeros64(_Val)); + } +} +#endif // defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) +#endif // _HAS_COUNTL_ZERO_INTRINSICS + +// Implementation of countr_zero without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +// see "Hacker's Delight" section 5-4 +template +_NODISCARD constexpr int _Countr_zero_fallback(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + return _Digits - _Countl_zero_fallback(static_cast<_Ty>(static_cast<_Ty>(~_Val) & static_cast<_Ty>(_Val - 1))); +} + +// Implementation of popcount without using specialized CPU instructions. +// Used at compile time and when said instructions are not supported. +template +_NODISCARD constexpr int _Popcount_fallback(_Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; +#if defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64) + if constexpr (_Digits == 64) { + // 64-bit bit operations on architectures without 64-bit registers are less efficient, + // hence we split the value so that it fits in 32-bit registers + return _Popcount_fallback(static_cast(_Val)) + + _Popcount_fallback(static_cast(_Val >> 32)); + } else +#endif // defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64) + { + // we static_cast these bit patterns in order to truncate them to the correct size + _Val = static_cast<_Ty>(_Val - ((_Val >> 1) & static_cast<_Ty>(0x5555'5555'5555'5555ull))); + _Val = static_cast<_Ty>((_Val & static_cast<_Ty>(0x3333'3333'3333'3333ull)) + + ((_Val >> 2) & static_cast<_Ty>(0x3333'3333'3333'3333ull))); + _Val = static_cast<_Ty>((_Val + (_Val >> 4)) & static_cast<_Ty>(0x0F0F'0F0F'0F0F'0F0Full)); + // Multiply by one in each byte, so that it will have the sum of all source bytes in the highest byte + _Val = static_cast<_Ty>(_Val * static_cast<_Ty>(0x0101'0101'0101'0101ull)); + // Extract highest byte + return static_cast(_Val >> (_Digits - 8)); + } +} + +#if ((defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC))) \ + && !defined(_M_CEE_PURE) +#define _HAS_TZCNT_BSF_INTRINSICS 1 +#else // ^^^ intrinsics available / intrinsics unavailable vvv +#define _HAS_TZCNT_BSF_INTRINSICS 0 +#endif // ^^^ intrinsics unavailable ^^^ + +#if _HAS_TZCNT_BSF_INTRINSICS +#ifdef __clang__ +#define _TZCNT_U32 __builtin_ia32_tzcnt_u32 +#define _TZCNT_U64 __builtin_ia32_tzcnt_u64 +#else // ^^^ __clang__ / !__clang__ vvv +#define _TZCNT_U32 _tzcnt_u32 +#define _TZCNT_U64 _tzcnt_u64 +#endif // __clang__ + +template +_NODISCARD int _Countr_zero_tzcnt(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + constexpr _Ty _Max = static_cast<_Ty>(-1); // equal to (numeric_limits<_Ty>::max)() + + if constexpr (_Digits <= 32) { + // Intended widening to int. This operation means that a narrow 0 will widen + // to 0xFFFF....FFFF0... instead of 0. We need this to avoid counting all the zeros + // of the wider type. + return static_cast(_TZCNT_U32(static_cast(~_Max | _Val))); + } else { +#ifdef _WIN64 + return static_cast(_TZCNT_U64(_Val)); +#else // ^^^ 64-bit / 32-bit vvv + const auto _Low = static_cast(_Val); + if (_Low == 0) { + const unsigned int _High = _Val >> 32; + return static_cast(32 + _TZCNT_U32(_High)); + } else { + return static_cast(_TZCNT_U32(_Low)); + } +#endif // ^^^ 32-bit ^^^ + } +} + +#undef _TZCNT_U32 +#undef _TZCNT_U64 + +template +_NODISCARD int _Countr_zero_bsf(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + constexpr _Ty _Max = static_cast<_Ty>(-1); // equal to (numeric_limits<_Ty>::max)() + + unsigned long _Result; + if constexpr (_Digits <= 32) { + // Intended widening to int. This operation means that a narrow 0 will widen + // to 0xFFFF....FFFF0... instead of 0. We need this to avoid counting all the zeros + // of the wider type. + if (!_BitScanForward(&_Result, static_cast(~_Max | _Val))) { + return _Digits; + } + } else { +#ifdef _WIN64 + if (!_BitScanForward64(&_Result, _Val)) { + return _Digits; + } +#else // ^^^ 64-bit / 32-bit vvv + const auto _Low = static_cast(_Val); + if (_BitScanForward(&_Result, _Low)) { + return static_cast(_Result); + } + + const unsigned int _High = _Val >> 32; + if (!_BitScanForward(&_Result, _High)) { + return _Digits; + } else { + return static_cast(_Result + 32); + } +#endif // ^^^ 32-bit ^^^ + } + return static_cast(_Result); +} + +template +_NODISCARD int _Checked_x86_x64_countr_zero(const _Ty _Val) noexcept { +#ifndef __AVX2__ + const bool _Definitely_have_tzcnt = __isa_available >= _Stl_isa_available_avx2; + if (!_Definitely_have_tzcnt) { + return _Countr_zero_bsf(_Val); + } +#endif // ^^^ !defined(__AVX2__) ^^^ + return _Countr_zero_tzcnt(_Val); +} + +#endif // _HAS_TZCNT_BSF_INTRINSICS + +#if !defined(_M_CEE_PURE) +#define _HAS_POPCNT_INTRINSICS 1 +#if defined(__AVX__) || defined(_M_ARM64) || defined(_M_ARM64EC) +#define _POPCNT_INTRINSICS_ALWAYS_AVAILABLE 1 +#else // ^^^ intrinsics always available / intrinsics not always available vvv +#define _POPCNT_INTRINSICS_ALWAYS_AVAILABLE 0 +#endif // ^^^ intrinsics not always available ^^^ +#else // ^^^ intrinsics available / intrinsics unavailable vvv +#define _HAS_POPCNT_INTRINSICS 0 +#define _POPCNT_INTRINSICS_ALWAYS_AVAILABLE 0 +#endif // ^^^ intrinsics unavailable ^^^ + +#if _HAS_POPCNT_INTRINSICS +template +_NODISCARD int _Unchecked_popcount(const _Ty _Val) noexcept { + constexpr int _Digits = _Unsigned_integer_digits<_Ty>; + if constexpr (_Digits <= 16) { + return static_cast(__popcnt16(_Val)); + } else if constexpr (_Digits == 32) { + return static_cast(__popcnt(_Val)); + } else { +#ifdef _WIN64 + return static_cast(__popcnt64(_Val)); +#else // ^^^ 64-bit / 32-bit vvv + return static_cast(__popcnt(_Val >> 32) + __popcnt(static_cast(_Val))); +#endif // ^^^ 32-bit ^^^ + } +} + +template +_NODISCARD int _Checked_popcount(const _Ty _Val) noexcept { +#if !_POPCNT_INTRINSICS_ALWAYS_AVAILABLE + const bool _Definitely_have_popcnt = __isa_available >= _Stl_isa_available_sse42; + if (!_Definitely_have_popcnt) { + return _Popcount_fallback(_Val); + } +#endif // ^^^ !_POPCNT_INTRINSICS_ALWAYS_AVAILABLE ^^^ + return _Unchecked_popcount(_Val); +} +#endif // ^^^ _HAS_POPCNT_INTRINSICS ^^^ + +template +constexpr bool _Is_standard_unsigned_integer = + _Is_any_of_v<_Ty, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>; + +template , int> = 0> +_NODISCARD _CONSTEXPR20 int _Countr_zero(const _Ty _Val) noexcept { +#if _HAS_TZCNT_BSF_INTRINSICS +#if _HAS_CXX20 + if (!_STD is_constant_evaluated()) +#endif // _HAS_CXX20 + { + return _Checked_x86_x64_countr_zero(_Val); + } +#endif // _HAS_TZCNT_BSF_INTRINSICS + return _Countr_zero_fallback(_Val); +} + +template +constexpr decltype(auto) _Select_countr_zero_impl(_Fn _Callback) { + // TRANSITION, DevCom-1527995: Lambdas in this function ensure inlining +#if _HAS_TZCNT_BSF_INTRINSICS && _HAS_CXX20 + if (!_STD is_constant_evaluated()) { +#ifndef __AVX2__ + const bool _Definitely_have_tzcnt = __isa_available >= _Stl_isa_available_avx2; + if (!_Definitely_have_tzcnt) { + return _Callback([](_Ty _Val) static { return _Countr_zero_bsf(_Val); }); + } +#endif // ^^^ !defined(__AVX2__) ^^^ + return _Callback([](_Ty _Val) static { return _Countr_zero_tzcnt(_Val); }); + } +#endif // ^^^ _HAS_TZCNT_BSF_INTRINSICS && _HAS_CXX20 ^^^ + // C++17 constexpr gcd() calls this function, so it should be constexpr unless we detect runtime evaluation. + return _Callback([](_Ty _Val) static { return _Countr_zero_fallback(_Val); }); +} + +template +_NODISCARD constexpr int _Countl_zero(const _Ty _Val) noexcept { + _STL_INTERNAL_STATIC_ASSERT(_Is_standard_unsigned_integer<_Ty>); +#if _HAS_COUNTL_ZERO_INTRINSICS +#if (defined(_M_IX86) && !defined(_M_HYBRID_X86_ARM64)) || (defined(_M_X64) && !defined(_M_ARM64EC)) + if (!_Is_constant_evaluated()) { + return _Checked_x86_x64_countl_zero(_Val); + } +#elif defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) + if (!_Is_constant_evaluated()) { + return _Checked_arm64_countl_zero(_Val); + } +#endif // defined(_M_ARM64) || defined(_M_ARM64EC) || defined(_M_HYBRID_X86_ARM64) +#endif // _HAS_COUNTL_ZERO_INTRINSICS + + return _Countl_zero_fallback(_Val); +} + +template , int> = 0> +_NODISCARD _CONSTEXPR20 int _Popcount(const _Ty _Val) noexcept { +#if _HAS_POPCNT_INTRINSICS +#if _HAS_CXX20 + if (!_STD is_constant_evaluated()) +#endif // _HAS_CXX20 + { + return _Checked_popcount(_Val); + } +#endif // ^^^ _HAS_POPCNT_INTRINSICS ^^^ + return _Popcount_fallback(_Val); +} + +template +_CONSTEXPR20 decltype(auto) _Select_popcount_impl(_Fn _Callback) { + // TRANSITION, DevCom-1527995: Lambdas in this function ensure inlining +#if _HAS_POPCNT_INTRINSICS +#if _HAS_CXX20 + if (!_STD is_constant_evaluated()) +#endif // _HAS_CXX20 + { +#if !_POPCNT_INTRINSICS_ALWAYS_AVAILABLE + const bool _Definitely_have_popcnt = __isa_available >= _Stl_isa_available_sse42; + if (!_Definitely_have_popcnt) { + return _Callback([](_Ty _Val) static { return _Popcount_fallback(_Val); }); + } +#endif // ^^^ !_POPCNT_INTRINSICS_ALWAYS_AVAILABLE ^^^ + return _Callback([](_Ty _Val) static { return _Unchecked_popcount(_Val); }); + } +#endif // ^^^ _HAS_POPCNT_INTRINSICS ^^^ + return _Callback([](_Ty _Val) static { return _Popcount_fallback(_Val); }); +} + +#undef _HAS_TZCNT_BSF_INTRINSICS + +_STD_END + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_BIT_UTILS_HPP diff --git a/msvc-stl/stl/inc/__msvc_chrono.hpp b/msvc-stl/stl/inc/__msvc_chrono.hpp new file mode 100644 index 0000000..0dbf810 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_chrono.hpp @@ -0,0 +1,731 @@ +// __msvc_chrono.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_CHRONO_HPP +#define __MSVC_CHRONO_HPP +#include +#if _STL_COMPILER_PREPROCESSOR +#include +#include +#include +#include +#include +#include + +#if _HAS_CXX20 +#include +#endif + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +// TRANSITION, non-_Ugly attribute tokens +#pragma push_macro("msvc") +#pragma push_macro("no_specializations") +#undef msvc +#undef no_specializations + +_STD_BEGIN +namespace chrono { + _EXPORT_STD template + struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type + + _EXPORT_STD template + _NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool treat_as_floating_point_v = + treat_as_floating_point<_Rep>::value; + + _EXPORT_STD template + struct duration_values { // gets arithmetic properties of a type + _NODISCARD static constexpr _Rep zero() noexcept { + // get zero value + return _Rep(0); + } + + _NODISCARD static constexpr _Rep(min)() noexcept { + // get smallest value + return numeric_limits<_Rep>::lowest(); + } + + _NODISCARD static constexpr _Rep(max)() noexcept { + // get largest value + return (numeric_limits<_Rep>::max)(); + } + }; + + _EXPORT_STD template > + class duration; + + _EXPORT_STD template + class time_point; + +#if _HAS_CXX20 + _EXPORT_STD template + _NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool is_clock_v = requires { + // Basic checks from N5014 [time.traits.is.clock]/1 + typename _Clock::rep; + typename _Clock::period; + typename _Clock::duration; + typename _Clock::time_point; + _Clock::is_steady; + _Clock::now(); + + // Additional stricter checks from N5014 [time.clock.req]/2 + // "An arithmetic type or a class emulating an arithmetic type" is not checked + requires _Is_ratio_v; + requires same_as>; + requires same_as> + || same_as>; + { _Clock::is_steady } -> std::same_as; + { _Clock::now() } -> std::same_as; + }; + _EXPORT_STD template + struct _NO_SPECIALIZATIONS_CITING("N5014 [time.traits.is.clock]/2") is_clock : bool_constant> {}; + + template + constexpr bool _Is_clock_v = is_clock_v<_Clock>; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + template + constexpr bool _Is_clock_v = false; + + template + constexpr bool + _Is_clock_v<_Clock, void_t> = + true; +#endif // ^^^ !_HAS_CXX20 ^^^ + + template + constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>; + + _EXPORT_STD template , int> = 0> + constexpr _To duration_cast(const duration<_Rep, _Period>&) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v); // strengthened + + _EXPORT_STD template + class duration { // represents a time duration + public: + using rep = _Rep; + using period = typename _Period::type; + + static_assert(!is_const_v<_Rep>, "rep type of duration must not be a const type"); + static_assert(!is_volatile_v<_Rep>, "rep type of duration must not be a volatile type"); + static_assert(!_Is_duration_v<_Rep>, "duration can't have duration as first template argument"); + static_assert(_Is_ratio_v<_Period>, "period not an instance of std::ratio"); + static_assert(0 < _Period::num, "period negative or zero"); + + constexpr duration() = default; + + template + && (treat_as_floating_point_v<_Rep> || !treat_as_floating_point_v<_Rep2>), + int> = 0> + constexpr explicit duration(const _Rep2& _Val) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened + : _MyRep(static_cast<_Rep>(_Val)) {} + + template + && (treat_as_floating_point_v<_Rep> + || (_Ratio_divide_sfinae<_Period2, _Period>::den == 1 + && !treat_as_floating_point_v<_Rep2>) ), + int> = 0> + constexpr duration(const duration<_Rep2, _Period2>& _Dur) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v<_Rep2>) // strengthened + : _MyRep(_CHRONO duration_cast(_Dur).count()) {} + + _NODISCARD constexpr _Rep count() const noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + return _MyRep; + } + + _NODISCARD constexpr common_type_t operator+() const + noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + return common_type_t(*this); + } + + _NODISCARD constexpr common_type_t operator-() const + noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + return common_type_t(-_MyRep); + } + + _CONSTEXPR17 duration& operator++() noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + ++_MyRep; + return *this; + } + + _CONSTEXPR17 duration operator++(int) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + return duration(_MyRep++); + } + + _CONSTEXPR17 duration& operator--() noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + --_MyRep; + return *this; + } + + _CONSTEXPR17 duration operator--(int) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + return duration(_MyRep--); + } + + _CONSTEXPR17 duration& operator+=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep += _Right._MyRep; + return *this; + } + + _CONSTEXPR17 duration& operator-=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep -= _Right._MyRep; + return *this; + } + + _CONSTEXPR17 duration& operator*=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep *= _Right; + return *this; + } + + _CONSTEXPR17 duration& operator/=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep /= _Right; + return *this; + } + + _CONSTEXPR17 duration& operator%=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep %= _Right; + return *this; + } + + _CONSTEXPR17 duration& operator%=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + _MyRep %= _Right.count(); + return *this; + } + + _NODISCARD static constexpr duration zero() noexcept { + // get zero value + return duration(duration_values<_Rep>::zero()); + } + + _NODISCARD static constexpr duration(min)() noexcept { + // get minimum value + return duration((duration_values<_Rep>::min)()); + } + + _NODISCARD static constexpr duration(max)() noexcept { + // get maximum value + return duration((duration_values<_Rep>::max)()); + } + + private: + _Rep _MyRep; // the stored rep + }; + + _EXPORT_STD template + class time_point { // represents a point in time + public: + using clock = _Clock; + using duration = _Duration; + using rep = typename _Duration::rep; + using period = typename _Duration::period; + + static_assert(_Is_duration_v<_Duration>, + "N4950 [time.point.general]/1 mandates Duration to be a specialization of chrono::duration."); + + constexpr time_point() = default; + + constexpr explicit time_point(const _Duration& _Other) noexcept(is_arithmetic_v) // strengthened + : _MyDur(_Other) {} + + template , int> = 0> + constexpr time_point(const time_point<_Clock, _Duration2>& _Tp) + noexcept(is_arithmetic_v && is_arithmetic_v) // strengthened + : _MyDur(_Tp.time_since_epoch()) {} + + _NODISCARD constexpr _Duration time_since_epoch() const noexcept(is_arithmetic_v) /* strengthened */ { + return _MyDur; + } + +#if _HAS_CXX20 + constexpr time_point& operator++() noexcept(is_arithmetic_v) /* strengthened */ { + ++_MyDur; + return *this; + } + constexpr time_point operator++(int) noexcept(is_arithmetic_v) /* strengthened */ { + return time_point{_MyDur++}; + } + constexpr time_point& operator--() noexcept(is_arithmetic_v) /* strengthened */ { + --_MyDur; + return *this; + } + constexpr time_point operator--(int) noexcept(is_arithmetic_v) /* strengthened */ { + return time_point{_MyDur--}; + } +#endif // _HAS_CXX20 + + _CONSTEXPR17 time_point& operator+=(const _Duration& _Dur) noexcept(is_arithmetic_v) /* strengthened */ { + _MyDur += _Dur; + return *this; + } + + _CONSTEXPR17 time_point& operator-=(const _Duration& _Dur) noexcept(is_arithmetic_v) /* strengthened */ { + _MyDur -= _Dur; + return *this; + } + + _NODISCARD static constexpr time_point(min)() noexcept { + return time_point((_Duration::min) ()); + } + + _NODISCARD static constexpr time_point(max)() noexcept { + return time_point((_Duration::max) ()); + } + + private: + _Duration _MyDur{duration::zero()}; // duration since the epoch + }; +} // namespace chrono + +template +constexpr bool _Is_trivially_swappable_v> = _Is_trivially_swappable_v<_Rep>; + +template +constexpr bool _Is_trivially_swappable_v> = _Is_trivially_swappable_v<_Duration>; + +_NODISCARD constexpr intmax_t _Lcm(const intmax_t _Ax, const intmax_t _Bx) noexcept { + return (_Ax / _Gcd(_Ax, _Bx)) * _Bx; +} + +template +struct common_type<_CHRONO duration<_Rep1, _Period1>, _CHRONO duration<_Rep2, _Period2>> { + using type = _CHRONO duration, + ratio<_Gcd(_Period1::num, _Period2::num), _Lcm(_Period1::den, _Period2::den)>>; +}; + +template +struct common_type<_CHRONO time_point<_Clock, _Duration1>, + _CHRONO time_point<_Clock, _Duration2>> { // common type of two time points + using type = _CHRONO time_point<_Clock, common_type_t<_Duration1, _Duration2>>; +}; + +namespace chrono { + _EXPORT_STD template + _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator+( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CD = common_type_t, duration<_Rep2, _Period2>>; + return _CD(_CD(_Left).count() + _CD(_Right).count()); + } + + _EXPORT_STD template + _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator-( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CD = common_type_t, duration<_Rep2, _Period2>>; + return _CD(_CD(_Left).count() - _CD(_Right).count()); + } + + _EXPORT_STD template >, int> = 0> + _NODISCARD constexpr duration, _Period1> operator*( + const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CR = common_type_t<_Rep1, _Rep2>; + using _CD = duration<_CR, _Period1>; + return _CD(_CD(_Left).count() * _Right); + } + + _EXPORT_STD template >, int> = 0> + _NODISCARD constexpr duration, _Period2> operator*( + const _Rep1& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + return _Right * _Left; + } + + template > + struct _Duration_div_mod1 { // return type for duration / rep and duration % rep + using type = duration<_CR, _Period1>; + }; + + template + struct _Duration_div_mod1<_CR, _Period1, _Rep2, false> {}; // no return type + + template > + struct _Duration_div_mod {}; // no return type + + template + struct _Duration_div_mod<_CR, _Period1, _Rep2, false> : _Duration_div_mod1<_CR, _Period1, _Rep2> { + // return type for duration / rep and duration % rep + }; + + _EXPORT_STD template + _NODISCARD constexpr typename _Duration_div_mod, _Period1, _Rep2>::type operator/( + const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CR = common_type_t<_Rep1, _Rep2>; + using _CD = duration<_CR, _Period1>; + return _CD(_CD(_Left).count() / _Right); + } + + _EXPORT_STD template + _NODISCARD constexpr common_type_t<_Rep1, _Rep2> operator/( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CD = common_type_t, duration<_Rep2, _Period2>>; + return _CD(_Left).count() / _CD(_Right).count(); + } + + _EXPORT_STD template + _NODISCARD constexpr typename _Duration_div_mod, _Period1, _Rep2>::type operator%( + const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CR = common_type_t<_Rep1, _Rep2>; + using _CD = duration<_CR, _Period1>; + return _CD(_CD(_Left).count() % _Right); + } + + _EXPORT_STD template + _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator%( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CD = common_type_t, duration<_Rep2, _Period2>>; + return _CD(_CD(_Left).count() % _CD(_Right).count()); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator==( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CT = common_type_t, duration<_Rep2, _Period2>>; + return _CT(_Left).count() == _CT(_Right).count(); + } + +#if !_HAS_CXX20 + template + _NODISCARD constexpr bool operator!=( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + return !(_Left == _Right); + } +#endif // !_HAS_CXX20 + + _EXPORT_STD template + _NODISCARD constexpr bool operator<(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CT = common_type_t, duration<_Rep2, _Period2>>; + return _CT(_Left).count() < _CT(_Right).count(); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator<=( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + return !(_Right < _Left); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator>(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + return _Right < _Left; + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator>=( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + return !(_Left < _Right); + } + +#if _HAS_CXX20 + _EXPORT_STD template + requires three_way_comparable, duration<_Rep2, _Period2>>::rep> + _NODISCARD constexpr auto operator<=>( + const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) + noexcept(is_arithmetic_v<_Rep1> && is_arithmetic_v<_Rep2>) /* strengthened */ { + using _CT = common_type_t, duration<_Rep2, _Period2>>; + return _CT(_Left).count() <=> _CT(_Right).count(); + } +#endif // _HAS_CXX20 + + _EXPORT_STD template , int> /* = 0 */> + _NODISCARD constexpr _To duration_cast(const duration<_Rep, _Period>& _Dur) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v) /* strengthened */ { + // convert duration to another duration; truncate + using _CF = ratio_divide<_Period, typename _To::period>; + + using _ToRep = typename _To::rep; + using _CR = common_type_t<_ToRep, _Rep, intmax_t>; + + constexpr bool _Num_is_one = _CF::num == 1; + constexpr bool _Den_is_one = _CF::den == 1; + + if constexpr (_Den_is_one) { + if constexpr (_Num_is_one) { + return static_cast<_To>(static_cast<_ToRep>(_Dur.count())); + } else { + return static_cast<_To>( + static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num))); + } + } else { + if constexpr (_Num_is_one) { + return static_cast<_To>( + static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) / static_cast<_CR>(_CF::den))); + } else { + return static_cast<_To>(static_cast<_ToRep>( + static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); + } + } + } + + _EXPORT_STD template , int> = 0> + _NODISCARD constexpr _To floor(const duration<_Rep, _Period>& _Dur) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v) /* strengthened */ { + // convert duration to another duration; round towards negative infinity + // i.e. the greatest integral result such that the result <= _Dur + const _To _Casted{_CHRONO duration_cast<_To>(_Dur)}; + if (_Casted > _Dur) { + return _To{_Casted.count() - static_cast(1)}; + } + + return _Casted; + } + + _EXPORT_STD template , int> = 0> + _NODISCARD constexpr _To ceil(const duration<_Rep, _Period>& _Dur) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v) /* strengthened */ { + // convert duration to another duration; round towards positive infinity + // i.e. the least integral result such that _Dur <= the result + const _To _Casted{_CHRONO duration_cast<_To>(_Dur)}; + if (_Casted < _Dur) { + return _To{_Casted.count() + static_cast(1)}; + } + + return _Casted; + } + + template + constexpr bool _Is_even(_Rep _Val) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + // Tests whether _Val is even + return _Val % 2 == 0; + } + + _EXPORT_STD template && !treat_as_floating_point_v, int> = 0> + _NODISCARD constexpr _To round(const duration<_Rep, _Period>& _Dur) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v) /* strengthened */ { + // convert duration to another duration, round to nearest, ties to even + const _To _Floored{_CHRONO floor<_To>(_Dur)}; + const _To _Ceiled{_Floored + _To{1}}; + const auto _Floor_adjustment = _Dur - _Floored; + const auto _Ceil_adjustment = _Ceiled - _Dur; + if (_Floor_adjustment < _Ceil_adjustment + || (_Floor_adjustment == _Ceil_adjustment && _Is_even(_Floored.count()))) { + return _Floored; + } + + return _Ceiled; + } + + _EXPORT_STD template ::is_signed, int> = 0> + _NODISCARD constexpr duration<_Rep, _Period> abs(const duration<_Rep, _Period> _Dur) + noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { + // create a duration whose count() is the absolute value of _Dur.count() + if (_Dur < duration<_Rep, _Period>::zero()) { + return -_Dur; + } else { + return _Dur; + } + } + + _EXPORT_STD using nanoseconds = duration; + _EXPORT_STD using microseconds = duration; + _EXPORT_STD using milliseconds = duration; + _EXPORT_STD using seconds = duration; + _EXPORT_STD using minutes = duration>; + _EXPORT_STD using hours = duration>; +#if _HAS_CXX20 + _EXPORT_STD using days = duration, hours::period>>; + _EXPORT_STD using weeks = duration, days::period>>; + _EXPORT_STD using years = duration, days::period>>; + _EXPORT_STD using months = duration>>; +#endif // _HAS_CXX20 + + _EXPORT_STD template + _NODISCARD constexpr time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>> operator+( + const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right) + noexcept(is_arithmetic_v && is_arithmetic_v<_Rep>) /* strengthened */ { + using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>; + return _RT(_Left.time_since_epoch() + _Right); + } + + _EXPORT_STD template + _NODISCARD constexpr time_point<_Clock, common_type_t, _Duration>> operator+( + const duration<_Rep, _Period>& _Left, const time_point<_Clock, _Duration>& _Right) + noexcept(is_arithmetic_v<_Rep> && is_arithmetic_v) /* strengthened */ { + return _Right + _Left; + } + + _EXPORT_STD template + _NODISCARD constexpr time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>> operator-( + const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right) + noexcept(is_arithmetic_v && is_arithmetic_v<_Rep>) /* strengthened */ { + using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>; + return _RT(_Left.time_since_epoch() - _Right); + } + + _EXPORT_STD template + _NODISCARD constexpr common_type_t<_Duration1, _Duration2> operator-( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return _Left.time_since_epoch() - _Right.time_since_epoch(); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator==( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return _Left.time_since_epoch() == _Right.time_since_epoch(); + } + +#if !_HAS_CXX20 + template + _NODISCARD constexpr bool operator!=( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return !(_Left == _Right); + } +#endif // !_HAS_CXX20 + + _EXPORT_STD template + _NODISCARD constexpr bool operator<( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return _Left.time_since_epoch() < _Right.time_since_epoch(); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator<=( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return !(_Right < _Left); + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator>( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return _Right < _Left; + } + + _EXPORT_STD template + _NODISCARD constexpr bool operator>=( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return !(_Left < _Right); + } + +#if _HAS_CXX20 + _EXPORT_STD template _Duration2> + _NODISCARD constexpr auto operator<=>( + const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) + noexcept( + is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + return _Left.time_since_epoch() <=> _Right.time_since_epoch(); + } +#endif // _HAS_CXX20 + + _EXPORT_STD template , int> = 0> + _NODISCARD constexpr time_point<_Clock, _To> time_point_cast(const time_point<_Clock, _Duration>& _Time) + noexcept(is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + // change the duration type of a time_point; truncate + return time_point<_Clock, _To>(_CHRONO duration_cast<_To>(_Time.time_since_epoch())); + } + + _EXPORT_STD template , int> = 0> + _NODISCARD constexpr time_point<_Clock, _To> floor(const time_point<_Clock, _Duration>& _Time) + noexcept(is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + // change the duration type of a time_point; round towards negative infinity + return time_point<_Clock, _To>(_CHRONO floor<_To>(_Time.time_since_epoch())); + } + + _EXPORT_STD template , int> = 0> + _NODISCARD constexpr time_point<_Clock, _To> ceil(const time_point<_Clock, _Duration>& _Time) + noexcept(is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + // change the duration type of a time_point; round towards positive infinity + return time_point<_Clock, _To>(_CHRONO ceil<_To>(_Time.time_since_epoch())); + } + + _EXPORT_STD template && !treat_as_floating_point_v, int> = 0> + _NODISCARD constexpr time_point<_Clock, _To> round(const time_point<_Clock, _Duration>& _Time) + noexcept(is_arithmetic_v && is_arithmetic_v) /* strengthened */ { + // change the duration type of a time_point; round to nearest, ties to even + return time_point<_Clock, _To>(_CHRONO round<_To>(_Time.time_since_epoch())); + } + + _EXPORT_STD struct steady_clock { // wraps QueryPerformanceCounter + using rep = long long; + using period = nano; + using duration = nanoseconds; + using time_point = _CHRONO time_point; + static constexpr bool is_steady = true; + + _NODISCARD static time_point now() noexcept { // get current time + const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot + const long long _Ctr = _Query_perf_counter(); + _STL_INTERNAL_STATIC_ASSERT(period::num == 1); + // The compiler recognizes the constants for frequency and time period and uses shifts and + // multiplies instead of divides to calculate the nanosecond value. + constexpr long long _TenMHz = 10'000'000; + constexpr long long _TwentyFourMHz = 24'000'000; + if (_Freq == _TenMHz) { + // 10 MHz is a very common QPC frequency on modern x86/x64 PCs. Optimizing for + // this specific frequency can double the performance of this function by + // avoiding the expensive frequency conversion path. + _STL_INTERNAL_STATIC_ASSERT(period::den % _TenMHz == 0); + constexpr long long _Multiplier = period::den / _TenMHz; + return time_point(duration(_Ctr * _Multiplier)); + } else if (_Freq == _TwentyFourMHz) { + // 24 MHz is a common frequency on ARM64, including cases where it emulates x86/x64. + constexpr long long _Multiplier_whole = period::den / _TwentyFourMHz; + using _Multiplier_part = ratio; + constexpr long long _Multiplier_num = _Multiplier_part::num; + constexpr long long _Multiplier_den = _Multiplier_part::den; + // This assumes that _Ctr * _Multiplier_num doesn't overflow. + _STL_INTERNAL_STATIC_ASSERT(_Multiplier_num <= _Multiplier_whole); + const long long _Whole = _Ctr * _Multiplier_whole; + const long long _Part = _Ctr * _Multiplier_num / _Multiplier_den; + return time_point(duration(_Whole + _Part)); + } else { + // Instead of just having "(_Ctr * period::den) / _Freq", + // the algorithm below prevents overflow when _Ctr is sufficiently large. + // It assumes that _Freq * period::den does not overflow, which is currently true for nano period. + // It is not realistic for _Ctr to accumulate to large values from zero with this assumption, + // but the initial value of _Ctr could be large. + const long long _Whole = (_Ctr / _Freq) * period::den; + const long long _Part = (_Ctr % _Freq) * period::den / _Freq; + return time_point(duration(_Whole + _Part)); + } + } + }; +} // namespace chrono +_STD_END + +// TRANSITION, non-_Ugly attribute tokens +#pragma pop_macro("no_specializations") +#pragma pop_macro("msvc") + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_CHRONO_HPP diff --git a/msvc-stl/stl/inc/__msvc_cxx_stdatomic.hpp b/msvc-stl/stl/inc/__msvc_cxx_stdatomic.hpp new file mode 100644 index 0000000..f6874f7 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_cxx_stdatomic.hpp @@ -0,0 +1,138 @@ +// __msvc_cxx_stdatomic.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_CXX_STDATOMIC_HPP +#define __MSVC_CXX_STDATOMIC_HPP + +// see _STL_COMPILER_PREPROCESSOR in yvals_core.h +#if !defined(RC_INVOKED) && !defined(Q_MOC_RUN) && !defined(__midl) + +// provide a specific error message for C compilers, before the general error message in yvals_core.h +#ifndef __cplusplus +#error <__msvc_cxx_stdatomic.hpp> is an internal header. It is incompatible with C and should not be directly included. +#endif // !defined(__cplusplus) + +#include + +#ifdef _M_CEE_PURE +#error is not supported when compiling with /clr:pure. +#endif // defined(_M_CEE_PURE) + +#if !_HAS_CXX23 +_EMIT_STL_WARNING(STL4038, "The contents of are available only with C++23 or later."); +#else // ^^^ !_HAS_CXX23 / _HAS_CXX23 vvv + +#include + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +template +using _Std_atomic = _STD atomic<_Ty>; + +#define _Atomic(T) _Std_atomic + +using _STD memory_order; +using _STD memory_order_relaxed; +using _STD memory_order_consume; +using _STD memory_order_acquire; +using _STD memory_order_release; +using _STD memory_order_acq_rel; +using _STD memory_order_seq_cst; + +using _STD atomic_flag; + +using _STD atomic_bool; +using _STD atomic_char; +using _STD atomic_schar; +using _STD atomic_uchar; +using _STD atomic_short; +using _STD atomic_ushort; +using _STD atomic_int; +using _STD atomic_uint; +using _STD atomic_long; +using _STD atomic_ulong; +using _STD atomic_llong; +using _STD atomic_ullong; + +#ifdef __cpp_lib_char8_t +using _STD atomic_char8_t; +#endif // defined(__cpp_lib_char8_t) + +using _STD atomic_char16_t; +using _STD atomic_char32_t; +using _STD atomic_wchar_t; +using _STD atomic_int8_t; +using _STD atomic_uint8_t; +using _STD atomic_int16_t; +using _STD atomic_uint16_t; +using _STD atomic_int32_t; +using _STD atomic_uint32_t; +using _STD atomic_int64_t; +using _STD atomic_uint64_t; +using _STD atomic_int_least8_t; +using _STD atomic_uint_least8_t; +using _STD atomic_int_least16_t; +using _STD atomic_uint_least16_t; +using _STD atomic_int_least32_t; +using _STD atomic_uint_least32_t; +using _STD atomic_int_least64_t; +using _STD atomic_uint_least64_t; +using _STD atomic_int_fast8_t; +using _STD atomic_uint_fast8_t; +using _STD atomic_int_fast16_t; +using _STD atomic_uint_fast16_t; +using _STD atomic_int_fast32_t; +using _STD atomic_uint_fast32_t; +using _STD atomic_int_fast64_t; +using _STD atomic_uint_fast64_t; +using _STD atomic_intptr_t; +using _STD atomic_uintptr_t; +using _STD atomic_size_t; +using _STD atomic_ptrdiff_t; +using _STD atomic_intmax_t; +using _STD atomic_uintmax_t; + +using _STD atomic_is_lock_free; +using _STD atomic_load; +using _STD atomic_load_explicit; +using _STD atomic_store; +using _STD atomic_store_explicit; +using _STD atomic_exchange; +using _STD atomic_exchange_explicit; +using _STD atomic_compare_exchange_strong; +using _STD atomic_compare_exchange_strong_explicit; +using _STD atomic_compare_exchange_weak; +using _STD atomic_compare_exchange_weak_explicit; +using _STD atomic_fetch_add; +using _STD atomic_fetch_add_explicit; +using _STD atomic_fetch_sub; +using _STD atomic_fetch_sub_explicit; +using _STD atomic_fetch_or; +using _STD atomic_fetch_or_explicit; +using _STD atomic_fetch_xor; +using _STD atomic_fetch_xor_explicit; +using _STD atomic_fetch_and; +using _STD atomic_fetch_and_explicit; +using _STD atomic_flag_test_and_set; +using _STD atomic_flag_test_and_set_explicit; +using _STD atomic_flag_clear; +using _STD atomic_flag_clear_explicit; + +using _STD atomic_thread_fence; +using _STD atomic_signal_fence; + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // ^^^ _HAS_CXX23 ^^^ + +#endif // !defined(RC_INVOKED) && !defined(Q_MOC_RUN) && !defined(__midl) +#endif // __MSVC_CXX_STDATOMIC_HPP diff --git a/msvc-stl/stl/inc/__msvc_doom_core.hpp b/msvc-stl/stl/inc/__msvc_doom_core.hpp new file mode 100644 index 0000000..1300f80 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_doom_core.hpp @@ -0,0 +1,54 @@ +// __msvc_doom_core.hpp internal header (core) + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_DOOM_CORE_HPP +#define __MSVC_DOOM_CORE_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION +#include +#elif defined(_M_CEE) +#include +#endif // ^^^ defined(_M_CEE) ^^^ + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +// The STL's "doom function" can be replaced. Notes: +// * It must not throw. (Attempting to throw would slam into noexcept.) +// * Common case: If it doesn't return, it should be marked as `[[noreturn]]`. +// * Uncommon case: If it returns, the STL will attempt to "continue on error", behaving as if no checking was done. +// + For example, a legacy codebase with a long startup time might want to log errors for investigation later. +// + WARNING: If you replace the STL's "doom function" to "continue on error", you do so at your own risk! +// After the STL has detected a precondition violation, undefined behavior is imminent. The STL will support +// "continue on error" by proceeding to do what it would have done anyways (instead of falling off the end of +// a non-void function, etc.), but it will not attempt to replace undefined behavior with implementation-defined +// behavior. (For example, we will not transform `pop_back()` of an empty `vector` to be a no-op.) +#ifndef _MSVC_STL_DOOM_FUNCTION +#ifdef _MSVC_STL_USE_ABORT_AS_DOOM_FUNCTION // The user wants to use abort(): +#define _MSVC_STL_DOOM_FUNCTION(mesg) _CSTD abort() +#elif defined(__clang__) // Use the Clang intrinsic: +#define _MSVC_STL_DOOM_FUNCTION(mesg) __builtin_verbose_trap("MSVC STL error", mesg) +#elif defined(_M_CEE) // TRANSITION, VSO-2457624 (/clr silent bad codegen for __fastfail); /clr:pure lacks __fastfail +#define _MSVC_STL_DOOM_FUNCTION(mesg) ::_invoke_watson(nullptr, nullptr, nullptr, 0, 0) +#else // Use the MSVC __fastfail intrinsic: +extern "C" __declspec(noreturn) void __fastfail(unsigned int); // declared by +#define _MSVC_STL_DOOM_FUNCTION(mesg) \ + __fastfail(5); /* __fastfail(FAST_FAIL_INVALID_ARG), value defined by */ \ + _STL_UNREACHABLE /* TRANSITION, DevCom-10914110 */ +#endif // choose "doom function" +#endif // ^^^ !defined(_MSVC_STL_DOOM_FUNCTION) ^^^ + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_DOOM_CORE_HPP diff --git a/msvc-stl/stl/inc/__msvc_filebuf.hpp b/msvc-stl/stl/inc/__msvc_filebuf.hpp new file mode 100644 index 0000000..fd6069d --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_filebuf.hpp @@ -0,0 +1,751 @@ +// __msvc_filebuf.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_FILEBUF_HPP +#define __MSVC_FILEBUF_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#include +#include + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +// TRANSITION, ABI: The _Path_ish functions accepting filesystem::path are templates +// which always use the same types as a workaround for user code deriving from iostreams types and +// __declspec(dllexport)ing the derived types. Adding member functions to iostreams broke the ABI of such DLLs. +// Deriving and __declspec(dllexport)ing standard library types is not supported, but in this particular case +// the workaround was inexpensive. The workaround will be removed in the next ABI breaking release of the +// Visual C++ Libraries. +_STD_BEGIN +#if _HAS_CXX17 +namespace filesystem { + _EXPORT_STD class path; +} +#endif // _HAS_CXX17 + +extern "C++" _CRTIMP2_PURE FILE* __CLRCALL_PURE_OR_CDECL _Fiopen(const char*, ios_base::openmode, int); +extern "C++" _CRTIMP2_PURE FILE* __CLRCALL_PURE_OR_CDECL _Fiopen(const wchar_t*, ios_base::openmode, int); + +template +bool _Fgetc(_Elem& _Ch, FILE* _File) { // get an element from a C stream + return _CSTD fread(&_Ch, sizeof(_Elem), 1, _File) == 1; +} + +template <> +inline bool _Fgetc(char& _Byte, FILE* _File) { // get a char element from a C stream + int _Meta; + if ((_Meta = _CSTD fgetc(_File)) == EOF) { + return false; + } else { // got one, convert to char + _Byte = static_cast(_Meta); + return true; + } +} + +template <> +inline bool _Fgetc(wchar_t& _Wchar, FILE* _File) { // get a wchar_t element from a C stream + wint_t _Meta; + if ((_Meta = _CSTD fgetwc(_File)) == WEOF) { + return false; + } else { // got one, convert to wchar_t + _Wchar = static_cast(_Meta); + return true; + } +} + +#ifdef _CRTBLD +template <> +inline bool _Fgetc(unsigned short& _Wchar, FILE* _File) { // get an unsigned short element from a C stream + wint_t _Meta; + if ((_Meta = _CSTD fgetwc(_File)) == WEOF) { + return false; + } else { // got one, convert to unsigned short + _Wchar = static_cast(_Meta); + return true; + } +} +#endif // defined(_CRTBLD) + +template +bool _Fputc(_Elem _Ch, FILE* _File) { // put an element to a C stream + return _CSTD fwrite(&_Ch, 1, sizeof(_Elem), _File) == sizeof(_Elem); +} + +template <> +inline bool _Fputc(char _Byte, FILE* _File) { // put a char element to a C stream + return _CSTD fputc(_Byte, _File) != EOF; +} + +template <> +inline bool _Fputc(wchar_t _Wchar, FILE* _File) { // put a wchar_t element to a C stream + return _CSTD fputwc(_Wchar, _File) != WEOF; +} + +#ifdef _CRTBLD +template <> +inline bool _Fputc(unsigned short _Wchar, FILE* _File) { // put an unsigned short element to a C stream + return _CSTD fputwc(_Wchar, _File) != WEOF; +} +#endif // defined(_CRTBLD) + +template +bool _Ungetc(const _Elem&, FILE*) { // put back an arbitrary element to a C stream (always fail) + return false; +} + +template <> +inline bool _Ungetc(const char& _Byte, FILE* _File) { // put back a char element to a C stream + return _CSTD ungetc(static_cast(_Byte), _File) != EOF; +} + +template <> +inline bool _Ungetc(const signed char& _Byte, FILE* _File) { // put back a signed char element to a C stream + return _CSTD ungetc(static_cast(_Byte), _File) != EOF; +} + +template <> +inline bool _Ungetc(const unsigned char& _Byte, FILE* _File) { // put back an unsigned char element to a C stream + return _CSTD ungetc(_Byte, _File) != EOF; +} + +template <> +inline bool _Ungetc(const wchar_t& _Wchar, FILE* _File) { // put back a wchar_t element to a C stream + return _CSTD ungetwc(_Wchar, _File) != WEOF; +} + +#ifdef _CRTBLD +template <> +inline bool _Ungetc(const unsigned short& _Wchar, FILE* _File) { // put back an unsigned short element to a C stream + return _CSTD ungetwc(_Wchar, _File) != WEOF; +} +#endif // defined(_CRTBLD) + +_EXPORT_STD template +class basic_filebuf : public basic_streambuf<_Elem, _Traits> { // stream buffer associated with a C stream +public: + using _Mysb = basic_streambuf<_Elem, _Traits>; + using _Cvt = codecvt<_Elem, char, typename _Traits::state_type>; + + basic_filebuf() : _Mysb() { + _Init(nullptr, _Newfl); + } + + explicit basic_filebuf(FILE* const _File) : _Mysb() { // extension, no ownership taking + _Init(_File, _Newfl); + } + + __CLR_OR_THIS_CALL ~basic_filebuf() noexcept override { + if (_Myfile) { + _Reset_back(); // revert from _Mychar buffer + } + + if (_Closef) { + close(); + } + } + + using int_type = typename _Traits::int_type; + using pos_type = typename _Traits::pos_type; + using off_type = typename _Traits::off_type; + + basic_filebuf(_Uninitialized) noexcept : _Mysb(_Noinit) {} + + basic_filebuf(basic_filebuf&& _Right) { + _Init(_Right._Myfile, _Newfl); // match buffering styles + _Init(static_cast(nullptr), _Closefl); // then make *this look closed + _Assign_rv(_STD move(_Right)); + } + + basic_filebuf& operator=(basic_filebuf&& _Right) { + _Assign_rv(_STD move(_Right)); + return *this; + } + + void _Assign_rv(basic_filebuf&& _Right) { + if (this != _STD addressof(_Right)) { + close(); + this->swap(_Right); + } + } + + void swap(basic_filebuf& _Right) noexcept /* strengthened */ { + if (this != _STD addressof(_Right)) { + FILE* _Myfile_sav = _Myfile; + const _Cvt* _Pcvt_sav = _Pcvt; + typename _Traits::state_type _State_sav = _State; + bool _Wrotesome_sav = _Wrotesome; + bool _Closef_sav = _Closef; + bool _Set_eback_sav = _Mysb::eback() == &_Mychar; + bool _Set_eback_live = _Mysb::gptr() == &_Mychar; + + _Elem* _Pfirst0 = _Mysb::pbase(); + _Elem* _Pnext0 = _Mysb::pptr(); + _Elem* _Pend = _Mysb::epptr(); + _Elem* _Gfirst0 = _Mysb::eback(); + _Elem* _Gnext0 = _Mysb::gptr(); + _Elem* _Gend = _Mysb::egptr(); + + // reinitialize *this + _Init(_Right._Myfile, _Right._Myfile ? _Openfl : _Newfl); + _Mysb::setp(_Right.pbase(), _Right.pptr(), _Right.epptr()); + if (_Right.eback() != &_Right._Mychar) { + _Mysb::setg(_Right.eback(), _Right.gptr(), _Right.egptr()); + } else if (_Right.gptr() != &_Right._Mychar) { + _Mysb::setg(&_Mychar, &_Mychar + 1, &_Mychar + 1); + } else { + _Mysb::setg(&_Mychar, &_Mychar, &_Mychar + 1); + } + + _Pcvt = _Right._Pcvt; + _State = _Right._State; + _Wrotesome = _Right._Wrotesome; + _Closef = _Right._Closef; + + // reinitialize _Right + _Right._Init(_Myfile_sav, _Myfile_sav ? _Openfl : _Newfl); + _Right.setp(_Pfirst0, _Pnext0, _Pend); + if (!_Set_eback_sav) { + _Right.setg(_Gfirst0, _Gnext0, _Gend); + } else if (!_Set_eback_live) { + _Right.setg(&_Right._Mychar, &_Right._Mychar + 1, &_Right._Mychar + 1); + } else { + _Right.setg(&_Right._Mychar, &_Right._Mychar, &_Right._Mychar + 1); + } + + _Right._Pcvt = _Pcvt_sav; + _Right._State = _State_sav; + _Right._Wrotesome = _Wrotesome_sav; + _Right._Closef = _Closef_sav; + + // swap ancillary data + _STD swap(_Set_eback, _Right._Set_eback); + _STD swap(_Set_egptr, _Right._Set_egptr); + + _STD swap(_Mychar, _Right._Mychar); + _STD swap(_Mysb::_Plocale, _Right._Plocale); + } + } + + basic_filebuf(const basic_filebuf&) = delete; + basic_filebuf& operator=(const basic_filebuf&) = delete; + + enum _Initfl { // reasons for a call to _Init + _Newfl, + _Openfl, + _Closefl + }; + + _NODISCARD bool is_open() const noexcept /* strengthened */ { + return static_cast(_Myfile); + } + + basic_filebuf* open(const char* _Filename, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { + // _Prot is an extension + if (_Myfile) { + return nullptr; + } + + const auto _File = _Fiopen(_Filename, _Mode, _Prot); + if (!_File) { + return nullptr; // open failed + } + + _Init(_File, _Openfl); + _Initcvt(_STD use_facet<_Cvt>(_Mysb::getloc())); + return this; // open succeeded + } + + basic_filebuf* open(const string& _Str, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { + // _Prot is an extension + return open(_Str.c_str(), _Mode, _Prot); + } + +#if _HAS_OLD_IOSTREAMS_MEMBERS + basic_filebuf* open(const char* _Filename, ios_base::open_mode _Mode) { + return open(_Filename, static_cast(_Mode)); + } +#endif // _HAS_OLD_IOSTREAMS_MEMBERS + + basic_filebuf* open(const wchar_t* _Filename, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { + // in standard as const std::filesystem::path::value_type *; _Prot is an extension + if (_Myfile) { + return nullptr; + } + + const auto _File = _Fiopen(_Filename, _Mode, _Prot); + if (!_File) { + return nullptr; // open failed + } + + _Init(_File, _Openfl); + _Initcvt(_STD use_facet<_Cvt>(_Mysb::getloc())); + return this; // open succeeded + } + + basic_filebuf* open(const wstring& _Str, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { + // extension + return open(_Str.c_str(), _Mode, _Prot); + } + +#if _HAS_CXX17 + template + basic_filebuf* open( + const _Identity_t<_Path_ish>& _Path, ios_base::openmode _Mode, int _Prot = ios_base::_Default_open_prot) { + // _Prot is an extension + return open(_Path.c_str(), _Mode, _Prot); + } +#endif // _HAS_CXX17 + +#if _HAS_OLD_IOSTREAMS_MEMBERS + basic_filebuf* open(const wchar_t* _Filename, ios_base::open_mode _Mode) { + // in standard as const std::filesystem::path::value_type * + return open(_Filename, static_cast(_Mode)); + } +#endif // _HAS_OLD_IOSTREAMS_MEMBERS + + basic_filebuf* close() { + basic_filebuf* _Ans; + if (_Myfile) { // put any homing sequence and close file + _Reset_back(); // revert from _Mychar buffer + + _Ans = this; + if (!_Endwrite()) { + _Ans = nullptr; + } + + if (_CSTD fclose(_Myfile) != 0) { + _Ans = nullptr; + } + } else { + _Ans = nullptr; + } + + _Init(nullptr, _Closefl); + return _Ans; + } + + void __CLR_OR_THIS_CALL _Lock() override { // lock file instead of stream buffer + if (_Myfile) { + _CSTD _lock_file(_Myfile); + } + } + + void __CLR_OR_THIS_CALL _Unlock() override { // unlock file instead of stream buffer + if (_Myfile) { + _CSTD _unlock_file(_Myfile); + } + } + +#if _HAS_CXX23 && defined(_CPPRTTI) + template + friend ios_base::iostate _Do_on_maybe_unicode_console(ostream&, _UnicodeConsoleFn, _FallbackFn); +#endif // ^^^ _HAS_CXX23 && defined(_CPPRTTI) ^^^ + +protected: + int_type __CLR_OR_THIS_CALL overflow(int_type _Meta = _Traits::eof()) override { // put an element to stream + if (_Traits::eq_int_type(_Traits::eof(), _Meta)) { + return _Traits::not_eof(_Meta); // EOF, return success code + } + + if (_Mysb::pptr() && _Mysb::pptr() < _Mysb::epptr()) { // room in buffer, store it + *_Mysb::_Pninc() = _Traits::to_char_type(_Meta); + return _Meta; + } + + if (!_Myfile) { + return _Traits::eof(); // no open C stream, fail + } + + _Reset_back(); // revert from _Mychar buffer + if (!_Pcvt) { // no codecvt facet, put as is + return _Fputc(_Traits::to_char_type(_Meta), _Myfile) ? _Meta : _Traits::eof(); + } + + // put using codecvt facet + constexpr size_t _Codecvt_temp_buf = 32; + char _Str[_Codecvt_temp_buf]; + const _Elem _Ch = _Traits::to_char_type(_Meta); + const _Elem* _Src; + char* _Dest; + + // test result of converting one element + switch (_Pcvt->out(_State, &_Ch, &_Ch + 1, _Src, _Str, _Str + _Codecvt_temp_buf, _Dest)) { + case codecvt_base::partial: + case codecvt_base::ok: + { // converted something, try to put it out + const auto _Count = static_cast(_Dest - _Str); + if (0 < _Count && _Count != static_cast(_CSTD fwrite(_Str, 1, _Count, _Myfile))) { + return _Traits::eof(); // write failed + } + + _Wrotesome = true; // write succeeded + if (_Src != &_Ch) { + return _Meta; // converted whole element + } + + return _Traits::eof(); // conversion failed + } + + case codecvt_base::noconv: + // no conversion, put as is + return _Fputc(_Ch, _Myfile) ? _Meta : _Traits::eof(); + + default: + return _Traits::eof(); // conversion failed + } + } + + int_type __CLR_OR_THIS_CALL pbackfail(int_type _Meta = _Traits::eof()) override { + // put an element back to stream + if (_Mysb::gptr() && _Mysb::eback() < _Mysb::gptr() + && (_Traits::eq_int_type(_Traits::eof(), _Meta) + || _Traits::eq_int_type(_Traits::to_int_type(_Mysb::gptr()[-1]), + _Meta))) { // just back up position + _Mysb::_Gndec(); + return _Traits::not_eof(_Meta); + } else if (!_Myfile || _Traits::eq_int_type(_Traits::eof(), _Meta)) { + return _Traits::eof(); // no open C stream or EOF, fail + } else if (!_Pcvt && _Ungetc(_Traits::to_char_type(_Meta), _Myfile)) { + return _Meta; // no facet and unget succeeded, return + } else if (_Mysb::gptr() != &_Mychar) { // putback to _Mychar + _Mychar = _Traits::to_char_type(_Meta); + _Set_back(); // switch to _Mychar buffer + return _Meta; + } else { + return _Traits::eof(); // nowhere to put back + } + } + + int_type __CLR_OR_THIS_CALL underflow() override { // get an element from stream, but don't point past it + int_type _Meta; + if (_Mysb::gptr() && _Mysb::gptr() < _Mysb::egptr()) { + return _Traits::to_int_type(*_Mysb::gptr()); // return buffered + } else if (_Traits::eq_int_type(_Traits::eof(), _Meta = uflow())) { + return _Meta; // uflow failed, return EOF + } else { // get a char, don't point past it + pbackfail(_Meta); + return _Meta; + } + } + + int_type __CLR_OR_THIS_CALL uflow() override { // get an element from stream, point past it + if (_Mysb::gptr() && _Mysb::gptr() < _Mysb::egptr()) { + return _Traits::to_int_type(*_Mysb::_Gninc()); // return buffered + } + + if (!_Myfile) { + return _Traits::eof(); // no open C stream, fail + } + + _Reset_back(); // revert from _Mychar buffer + if (!_Pcvt) { // no codecvt facet, just get it + _Elem _Ch; + return _Fgetc(_Ch, _Myfile) ? _Traits::to_int_type(_Ch) : _Traits::eof(); + } + + // build string until codecvt succeeds + string _Str; + + for (;;) { // get using codecvt facet + const char* _Src; + int _Meta = _CSTD fgetc(_Myfile); + + if (_Meta == EOF) { + return _Traits::eof(); // partial char? + } + + _Str.push_back(static_cast(_Meta)); // append byte and convert + + _Elem _Ch; + _Elem* _Dest; + + // test result of converting one element + switch (_Pcvt->in(_State, _Str.data(), _Str.data() + _Str.size(), _Src, &_Ch, &_Ch + 1, _Dest)) { + case codecvt_base::partial: + case codecvt_base::ok: + if (_Dest != &_Ch) { // got an element, put back excess and deliver it + auto _Nleft = _Str.data() + _Str.size() - _Src; + while (0 < _Nleft) { + _CSTD ungetc(_Src[--_Nleft], _Myfile); + } + + return _Traits::to_int_type(_Ch); + } + + _Str.erase(0, static_cast(_Src - _Str.data())); // partial, discard used input + break; + + case codecvt_base::noconv: + // noconv is only possible if _Elem is char, so we can use it directly + return static_cast(_Str.front()); + + default: + return _Traits::eof(); // conversion failed + } + } + } + + streamsize __CLR_OR_THIS_CALL xsgetn(_Elem* _Ptr, streamsize _Count) override { + // get _Count characters from stream + if constexpr (sizeof(_Elem) == 1) { + if (_Count <= 0) { + return 0; + } + + if (_Pcvt) { // if we need a nontrivial codecvt transform, do the default expensive thing + return _Mysb::xsgetn(_Ptr, _Count); + } + + // assuming this is OK because _Ptr + _Count must be valid + auto _Count_s = static_cast(_Count); + const auto _Start_count = _Count; + const auto _Available = static_cast(_Mysb::_Gnavail()); + if (0 < _Available) { // copy from get area + const auto _Read_size = (_STD min) (_Count_s, _Available); + _Traits::copy(_Ptr, _Mysb::gptr(), _Read_size); + _Ptr += _Read_size; + _Count_s -= _Read_size; + _Mysb::gbump(static_cast(_Read_size)); + } + + if (_Myfile) { // open C stream, attempt read + _Reset_back(); // revert from _Mychar buffer + // process in 4k - 1 chunks to avoid tripping over fread's clobber-the-end behavior when + // doing \r\n -> \n translation + constexpr size_t _Read_size = 4095; // _INTERNAL_BUFSIZ - 1 + while (_Read_size < _Count_s) { + const auto _Actual_read = _CSTD fread(_Ptr, sizeof(_Elem), _Read_size, _Myfile); + _Ptr += _Actual_read; + _Count_s -= _Actual_read; + if (_Actual_read != _Read_size) { + return static_cast(_Start_count - _Count_s); + } + } + + if (0 < _Count_s) { + _Count_s -= _CSTD fread(_Ptr, sizeof(_Elem), _Count_s, _Myfile); + } + } + + return static_cast(_Start_count - _Count_s); + } else { // non-chars always get element-by-element processing + return _Mysb::xsgetn(_Ptr, _Count); + } + } + + streamsize __CLR_OR_THIS_CALL xsputn(const _Elem* _Ptr, streamsize _Count) override { + // put _Count characters to stream + if constexpr (sizeof(_Elem) == 1) { + if (_Pcvt) { // if we need a nontrivial codecvt transform, do the default expensive thing + return _Mysb::xsputn(_Ptr, _Count); + } + + const streamsize _Start_count = _Count; + streamsize _Size = _Mysb::_Pnavail(); + if (0 < _Count && 0 < _Size) { // copy to write buffer + if (_Count < _Size) { + _Size = _Count; + } + + _Traits::copy(_Mysb::pptr(), _Ptr, static_cast(_Size)); + _Ptr += _Size; + _Count -= _Size; + _Mysb::pbump(static_cast(_Size)); + } + + if (0 < _Count && _Myfile) { // open C stream, attempt write + _Count -= _CSTD fwrite(_Ptr, sizeof(_Elem), static_cast(_Count), _Myfile); + } + + return _Start_count - _Count; + } else { // non-chars always get element-by-element processing + return _Mysb::xsputn(_Ptr, _Count); + } + } + + pos_type __CLR_OR_THIS_CALL seekoff(off_type _Off, ios_base::seekdir _Way, + ios_base::openmode = ios_base::in | ios_base::out) override { // change position by _Off + fpos_t _Fileposition; + + if (_Mysb::gptr() == &_Mychar // something putback + && _Way == ios_base::cur // a relative seek + && !_Pcvt) { // not converting + _Off -= static_cast(sizeof(_Elem)); // back up over _Elem bytes + } + + if (!_Myfile || !_Endwrite() + || ((_Off != 0 || _Way != ios_base::cur) && _CSTD _fseeki64(_Myfile, _Off, _Way) != 0) + || _CSTD fgetpos(_Myfile, &_Fileposition) != 0) { + return pos_type{off_type{-1}}; // report failure + } + + _Reset_back(); // revert from _Mychar buffer, discarding any putback + return pos_type{_State, _Fileposition}; // return new position + } + + pos_type __CLR_OR_THIS_CALL seekpos(pos_type _Pos, ios_base::openmode = ios_base::in | ios_base::out) override { + // change position to _Pos + off_type _Off = static_cast(_Pos); + + if (!_Myfile || !_Endwrite() || _CSTD fsetpos(_Myfile, &_Off) != 0) { + return pos_type{off_type{-1}}; // report failure + } + + _State = _Pos.state(); + _Reset_back(); // revert from _Mychar buffer, discarding any putback + return pos_type{_State, _Off}; // return new position + } + + _Mysb* __CLR_OR_THIS_CALL setbuf(_Elem* _Buffer, streamsize _Count) override { // offer _Buffer to C stream + int _Mode; + if (!_Buffer && _Count == 0) { + _Mode = _IONBF; + } else { + _Mode = _IOFBF; + } + + const size_t _Size = static_cast(_Count) * sizeof(_Elem); + + if (!_Myfile || _CSTD setvbuf(_Myfile, reinterpret_cast(_Buffer), _Mode, _Size) != 0) { + return nullptr; // failed + } + + // new buffer, reinitialize pointers + _Init(_Myfile, _Openfl); + return this; + } + + int __CLR_OR_THIS_CALL sync() override { // synchronize C stream with external file + if (!_Myfile || _Traits::eq_int_type(_Traits::eof(), overflow()) || 0 <= _CSTD fflush(_Myfile)) { + return 0; + } + + return -1; + } + + void __CLR_OR_THIS_CALL imbue(const locale& _Loc) override { + // set locale to argument (capture nontrivial codecvt facet) + _Initcvt(_STD use_facet<_Cvt>(_Loc)); + } + + void _Init(FILE* _File, _Initfl _Which) noexcept { // initialize to C stream _File after {new, open, close} + using _State_type = typename _Traits::state_type; + + __PURE_APPDOMAIN_GLOBAL static _State_type _Stinit; // initial state + + _Closef = _Which == _Openfl; + _Wrotesome = false; + + _Mysb::_Init(); // initialize stream buffer base object + + if (_File && sizeof(_Elem) == 1) { // point inside C stream with [first, first + count) buffer + _Elem** _Pb = nullptr; + _Elem** _Pn = nullptr; + int* _Nr = nullptr; + + ::_get_stream_buffer_pointers( + _File, reinterpret_cast(&_Pb), reinterpret_cast(&_Pn), &_Nr); + int* _Nw = _Nr; + + _Mysb::_Init(_Pb, _Pn, _Nr, _Pb, _Pn, _Nw); + } + + _Myfile = _File; + _State = _Stinit; + _Pcvt = nullptr; // pointer to codecvt facet + } + + bool _Endwrite() { // put shift to initial conversion state, as needed + if (!_Pcvt || !_Wrotesome) { + return true; + } + + // may have to put + if (_Traits::eq_int_type(_Traits::eof(), overflow())) { + return false; + } + + constexpr size_t _Codecvt_temp_buf = 32; + char _Str[_Codecvt_temp_buf]; + char* _Dest; + switch (_Pcvt->unshift(_State, _Str, _Str + _Codecvt_temp_buf, _Dest)) { // test result of homing conversion + case codecvt_base::ok: + _Wrotesome = false; // homed successfully + _FALLTHROUGH; + + case codecvt_base::partial: + { // put any generated bytes + const auto _Count = static_cast(_Dest - _Str); + if (0 < _Count && _Count != static_cast(_CSTD fwrite(_Str, 1, _Count, _Myfile))) { + return false; // write failed + } + + return !_Wrotesome; + } + + case codecvt_base::noconv: + _Wrotesome = false; // homed successfully + return true; // nothing else to do + + default: + return false; // conversion failed + } + } + + void _Initcvt(const _Cvt& _Newcvt) noexcept { // initialize codecvt pointer + if (_Newcvt.always_noconv()) { + _Pcvt = nullptr; // nothing to do + } else { // set up for nontrivial codecvt facet + _Pcvt = _STD addressof(_Newcvt); + _Mysb::_Init(); // reset any buffering + } + } + +private: + const _Cvt* _Pcvt; // pointer to codecvt facet (may be null) + _Elem _Mychar; // putback character, when _Ungetc fails + bool _Wrotesome; // true if homing sequence may be needed + typename _Traits::state_type _State; // current conversion state + bool _Closef; // true if C stream must be closed + FILE* _Myfile; // pointer to C stream + + void _Reset_back() noexcept { // restore buffer after putback + if (_Mysb::eback() == &_Mychar) { + _Mysb::setg(_Set_eback, _Set_eback, _Set_egptr); + } + } + + void _Set_back() noexcept { // set up putback area + if (_Mysb::eback() != &_Mychar) { // save current get buffer + _Set_eback = _Mysb::eback(); + _Set_egptr = _Mysb::egptr(); + } + _Mysb::setg(&_Mychar, &_Mychar, &_Mychar + 1); + } + + _Elem* _Set_eback; // saves eback() during one-element putback + _Elem* _Set_egptr; // saves egptr() +}; + +_EXPORT_STD template +void swap(basic_filebuf<_Elem, _Traits>& _Left, basic_filebuf<_Elem, _Traits>& _Right) noexcept /* strengthened */ { + _Left.swap(_Right); +} + +_STD_END + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) + +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_FILEBUF_HPP diff --git a/msvc-stl/stl/inc/__msvc_format_ucd_tables.hpp b/msvc-stl/stl/inc/__msvc_format_ucd_tables.hpp new file mode 100644 index 0000000..a4ebf52 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_format_ucd_tables.hpp @@ -0,0 +1,659 @@ +// __msvc_format_ucd_tables.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// WARNING, this entire header is generated by +// tools/unicode_properties_parse/unicode_properties_data_gen.py +// DO NOT MODIFY! + +// UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE +// +// See Terms of Use +// for definitions of Unicode Inc.'s Data Files and Software. +// +// NOTICE TO USER: Carefully read the following legal agreement. +// BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +// DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +// YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +// TERMS AND CONDITIONS OF THIS AGREEMENT. +// IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +// THE DATA FILES OR SOFTWARE. +// +// COPYRIGHT AND PERMISSION NOTICE +// +// Copyright (c) 1991-2022 Unicode, Inc. All rights reserved. +// Distributed under the Terms of Use in https://www.unicode.org/copyright.html. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of the Unicode data files and any associated documentation +// (the "Data Files") or Unicode software and any associated documentation +// (the "Software") to deal in the Data Files or Software +// without restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, and/or sell copies of +// the Data Files or Software, and to permit persons to whom the Data Files +// or Software are furnished to do so, provided that either +// (a) this copyright and permission notice appear with all copies +// of the Data Files or Software, or +// (b) this copyright and permission notice appear in associated +// Documentation. +// +// THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT OF THIRD PARTY RIGHTS. +// IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +// NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +// DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +// PERFORMANCE OF THE DATA FILES OR SOFTWARE. +// +// Except as contained in this notice, the name of a copyright holder +// shall not be used in advertising or otherwise to promote the sale, +// use or other dealings in these Data Files or Software without prior +// written authorization of the copyright holder. + +#ifndef __MSVC_FORMAT_UCD_TABLES_HPP +#define __MSVC_FORMAT_UCD_TABLES_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#include +#include + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +_STD_BEGIN + +template +struct _Unicode_property_data { + uint32_t _Lower_bounds[_NumRanges]; + uint16_t _Props_and_size[_NumRanges]; + _NODISCARD constexpr _ValueEnum _Get_property_for_codepoint(const uint32_t _Code_point) const noexcept { + ptrdiff_t _Upper_idx = _STD upper_bound(_Lower_bounds, _STD end(_Lower_bounds), _Code_point) - _Lower_bounds; + constexpr auto _No_value_constant = static_cast<_ValueEnum>(UINT8_MAX); + if (_Upper_idx == 0) { + return _No_value_constant; + } + --_Upper_idx; + const uint32_t _Lower_bound = _Lower_bounds[_Upper_idx]; + const uint16_t _Data = _Props_and_size[_Upper_idx]; + _STL_INTERNAL_CHECK(_Code_point >= _Lower_bound); + if constexpr (_Is_binary_property) { + if (_Code_point < _Lower_bound + _Data) { + return static_cast<_ValueEnum>(0); + } + } else { + const uint16_t _Size = static_cast(_Data & 0x0FFF); + const _ValueEnum _Prop = static_cast<_ValueEnum>((_Data & 0xF000) >> 12); + if (_Code_point < _Lower_bound + _Size) { + return _Prop; + } + } + return _No_value_constant; + } +}; + +// The following static data tables are generated from the Unicode character database. +// _Grapheme_Break_property_data comes from ucd/auxiliary/GraphemeBreakProperty.txt. +// +// _Indic_Conjunct_Break_property_data comes from ucd/DerivedCoreProperties.txt. +// +// _Extended_Pictographic_property_data comes from ucd/emoji/emoji-data.txt. +// +// __printable_property_data comes from ucd/extracted/DerivedGeneralCategory.txt. +// +// _Grapheme_Extend_property_data comes from ucd/DerivedCoreProperties.txt. +// +// The enums containing the values for the properties are also generated, in order to ensure they match +// up correctly with how we're parsing them. +// +// All sets of data tables are generated by tools/unicode_properties_parse/unicode_properties_data_gen.py in the +// https://github.com/microsoft/stl repository. +// +// The data format is a set of arrays for each character property. The first is an array of uint32_t encoding +// the lower bound of each range of codepoints that has the given property. +// The second is an array of uint16_t. +// - For enumerated properties, this array encodes both the range size and property value as follows: +// 16 12 0 +// +-----------------------------------------------------+ +// | property_value | range_size | +// +-----------------------------------------------------+ +// that is: the size is stored in the least significant 12 bits +// (leading to a max size of 4095), and the property value is stored in the most significant 4 bits, +// leading to a maximum of 16 property values. +// - For binary properties, this array simply stores the range size. +// +// Codepoint ranges may not overlap, and, within one property, a codepoint may only appear once. Furthermore the +// codepoint lower bounds appear in sorted (ascending) order. + +// GraphemeBreakProperty-17.0.0.txt +// Date: 2025-06-30, 06:20:23 GMT +enum class _Grapheme_Break_property_values : uint8_t { + _CR_value, + _Control_value, + _Extend_value, + _L_value, + _LF_value, + _LV_value, + _LVT_value, + _Prepend_value, + _Regional_Indicator_value, + _SpacingMark_value, + _T_value, + _V_value, + _ZWJ_value, + _No_value = 255 +}; + +// GraphemeBreakProperty-17.0.0.txt +// Date: 2025-06-30, 06:20:23 GMT +inline constexpr _Unicode_property_data<_Grapheme_Break_property_values, 1386, false> _Grapheme_Break_property_data{ + {0x0, 0xa, 0xb, 0xd, 0xe, 0x7f, 0xad, 0x300, 0x483, 0x591, 0x5bf, 0x5c1, 0x5c4, 0x5c7, 0x600, 0x610, 0x61c, 0x64b, + 0x670, 0x6d6, 0x6dd, 0x6df, 0x6e7, 0x6ea, 0x70f, 0x711, 0x730, 0x7a6, 0x7eb, 0x7fd, 0x816, 0x81b, 0x825, 0x829, + 0x859, 0x890, 0x897, 0x8ca, 0x8e2, 0x8e3, 0x903, 0x93a, 0x93b, 0x93c, 0x93e, 0x941, 0x949, 0x94d, 0x94e, 0x951, + 0x962, 0x981, 0x982, 0x9bc, 0x9be, 0x9bf, 0x9c1, 0x9c7, 0x9cb, 0x9cd, 0x9d7, 0x9e2, 0x9fe, 0xa01, 0xa03, 0xa3c, + 0xa3e, 0xa41, 0xa47, 0xa4b, 0xa51, 0xa70, 0xa75, 0xa81, 0xa83, 0xabc, 0xabe, 0xac1, 0xac7, 0xac9, 0xacb, 0xacd, + 0xae2, 0xafa, 0xb01, 0xb02, 0xb3c, 0xb3e, 0xb40, 0xb41, 0xb47, 0xb4b, 0xb4d, 0xb55, 0xb62, 0xb82, 0xbbe, 0xbbf, + 0xbc0, 0xbc1, 0xbc6, 0xbca, 0xbcd, 0xbd7, 0xc00, 0xc01, 0xc04, 0xc3c, 0xc3e, 0xc41, 0xc46, 0xc4a, 0xc55, 0xc62, + 0xc81, 0xc82, 0xcbc, 0xcbe, 0xcbf, 0xcc1, 0xcc2, 0xcc3, 0xcc6, 0xcca, 0xcd5, 0xce2, 0xcf3, 0xd00, 0xd02, 0xd3b, + 0xd3e, 0xd3f, 0xd41, 0xd46, 0xd4a, 0xd4d, 0xd4e, 0xd57, 0xd62, 0xd81, 0xd82, 0xdca, 0xdcf, 0xdd0, 0xdd2, 0xdd6, + 0xdd8, 0xddf, 0xdf2, 0xe31, 0xe33, 0xe34, 0xe47, 0xeb1, 0xeb3, 0xeb4, 0xec8, 0xf18, 0xf35, 0xf37, 0xf39, 0xf3e, + 0xf71, 0xf7f, 0xf80, 0xf86, 0xf8d, 0xf99, 0xfc6, 0x102d, 0x1031, 0x1032, 0x1039, 0x103b, 0x103d, 0x1056, 0x1058, + 0x105e, 0x1071, 0x1082, 0x1084, 0x1085, 0x108d, 0x109d, 0x1100, 0x1160, 0x11a8, 0x135d, 0x1712, 0x1732, 0x1752, + 0x1772, 0x17b4, 0x17b6, 0x17b7, 0x17be, 0x17c6, 0x17c7, 0x17c9, 0x17dd, 0x180b, 0x180e, 0x180f, 0x1885, 0x18a9, + 0x1920, 0x1923, 0x1927, 0x1929, 0x1930, 0x1932, 0x1933, 0x1939, 0x1a17, 0x1a19, 0x1a1b, 0x1a55, 0x1a56, 0x1a57, + 0x1a58, 0x1a60, 0x1a62, 0x1a65, 0x1a6d, 0x1a73, 0x1a7f, 0x1ab0, 0x1ae0, 0x1b00, 0x1b04, 0x1b34, 0x1b3e, 0x1b42, + 0x1b6b, 0x1b80, 0x1b82, 0x1ba1, 0x1ba2, 0x1ba6, 0x1ba8, 0x1be6, 0x1be7, 0x1be8, 0x1bea, 0x1bed, 0x1bee, 0x1bef, + 0x1c24, 0x1c2c, 0x1c34, 0x1c36, 0x1cd0, 0x1cd4, 0x1ce1, 0x1ce2, 0x1ced, 0x1cf4, 0x1cf7, 0x1cf8, 0x1dc0, 0x200b, + 0x200c, 0x200d, 0x200e, 0x2028, 0x2060, 0x20d0, 0x2cef, 0x2d7f, 0x2de0, 0x302a, 0x3099, 0xa66f, 0xa674, 0xa69e, + 0xa6f0, 0xa802, 0xa806, 0xa80b, 0xa823, 0xa825, 0xa827, 0xa82c, 0xa880, 0xa8b4, 0xa8c4, 0xa8e0, 0xa8ff, 0xa926, + 0xa947, 0xa952, 0xa953, 0xa960, 0xa980, 0xa983, 0xa9b3, 0xa9b4, 0xa9b6, 0xa9ba, 0xa9bc, 0xa9be, 0xa9c0, 0xa9e5, + 0xaa29, 0xaa2f, 0xaa31, 0xaa33, 0xaa35, 0xaa43, 0xaa4c, 0xaa4d, 0xaa7c, 0xaab0, 0xaab2, 0xaab7, 0xaabe, 0xaac1, + 0xaaeb, 0xaaec, 0xaaee, 0xaaf5, 0xaaf6, 0xabe3, 0xabe5, 0xabe6, 0xabe8, 0xabe9, 0xabec, 0xabed, 0xac00, 0xac01, + 0xac1c, 0xac1d, 0xac38, 0xac39, 0xac54, 0xac55, 0xac70, 0xac71, 0xac8c, 0xac8d, 0xaca8, 0xaca9, 0xacc4, 0xacc5, + 0xace0, 0xace1, 0xacfc, 0xacfd, 0xad18, 0xad19, 0xad34, 0xad35, 0xad50, 0xad51, 0xad6c, 0xad6d, 0xad88, 0xad89, + 0xada4, 0xada5, 0xadc0, 0xadc1, 0xaddc, 0xaddd, 0xadf8, 0xadf9, 0xae14, 0xae15, 0xae30, 0xae31, 0xae4c, 0xae4d, + 0xae68, 0xae69, 0xae84, 0xae85, 0xaea0, 0xaea1, 0xaebc, 0xaebd, 0xaed8, 0xaed9, 0xaef4, 0xaef5, 0xaf10, 0xaf11, + 0xaf2c, 0xaf2d, 0xaf48, 0xaf49, 0xaf64, 0xaf65, 0xaf80, 0xaf81, 0xaf9c, 0xaf9d, 0xafb8, 0xafb9, 0xafd4, 0xafd5, + 0xaff0, 0xaff1, 0xb00c, 0xb00d, 0xb028, 0xb029, 0xb044, 0xb045, 0xb060, 0xb061, 0xb07c, 0xb07d, 0xb098, 0xb099, + 0xb0b4, 0xb0b5, 0xb0d0, 0xb0d1, 0xb0ec, 0xb0ed, 0xb108, 0xb109, 0xb124, 0xb125, 0xb140, 0xb141, 0xb15c, 0xb15d, + 0xb178, 0xb179, 0xb194, 0xb195, 0xb1b0, 0xb1b1, 0xb1cc, 0xb1cd, 0xb1e8, 0xb1e9, 0xb204, 0xb205, 0xb220, 0xb221, + 0xb23c, 0xb23d, 0xb258, 0xb259, 0xb274, 0xb275, 0xb290, 0xb291, 0xb2ac, 0xb2ad, 0xb2c8, 0xb2c9, 0xb2e4, 0xb2e5, + 0xb300, 0xb301, 0xb31c, 0xb31d, 0xb338, 0xb339, 0xb354, 0xb355, 0xb370, 0xb371, 0xb38c, 0xb38d, 0xb3a8, 0xb3a9, + 0xb3c4, 0xb3c5, 0xb3e0, 0xb3e1, 0xb3fc, 0xb3fd, 0xb418, 0xb419, 0xb434, 0xb435, 0xb450, 0xb451, 0xb46c, 0xb46d, + 0xb488, 0xb489, 0xb4a4, 0xb4a5, 0xb4c0, 0xb4c1, 0xb4dc, 0xb4dd, 0xb4f8, 0xb4f9, 0xb514, 0xb515, 0xb530, 0xb531, + 0xb54c, 0xb54d, 0xb568, 0xb569, 0xb584, 0xb585, 0xb5a0, 0xb5a1, 0xb5bc, 0xb5bd, 0xb5d8, 0xb5d9, 0xb5f4, 0xb5f5, + 0xb610, 0xb611, 0xb62c, 0xb62d, 0xb648, 0xb649, 0xb664, 0xb665, 0xb680, 0xb681, 0xb69c, 0xb69d, 0xb6b8, 0xb6b9, + 0xb6d4, 0xb6d5, 0xb6f0, 0xb6f1, 0xb70c, 0xb70d, 0xb728, 0xb729, 0xb744, 0xb745, 0xb760, 0xb761, 0xb77c, 0xb77d, + 0xb798, 0xb799, 0xb7b4, 0xb7b5, 0xb7d0, 0xb7d1, 0xb7ec, 0xb7ed, 0xb808, 0xb809, 0xb824, 0xb825, 0xb840, 0xb841, + 0xb85c, 0xb85d, 0xb878, 0xb879, 0xb894, 0xb895, 0xb8b0, 0xb8b1, 0xb8cc, 0xb8cd, 0xb8e8, 0xb8e9, 0xb904, 0xb905, + 0xb920, 0xb921, 0xb93c, 0xb93d, 0xb958, 0xb959, 0xb974, 0xb975, 0xb990, 0xb991, 0xb9ac, 0xb9ad, 0xb9c8, 0xb9c9, + 0xb9e4, 0xb9e5, 0xba00, 0xba01, 0xba1c, 0xba1d, 0xba38, 0xba39, 0xba54, 0xba55, 0xba70, 0xba71, 0xba8c, 0xba8d, + 0xbaa8, 0xbaa9, 0xbac4, 0xbac5, 0xbae0, 0xbae1, 0xbafc, 0xbafd, 0xbb18, 0xbb19, 0xbb34, 0xbb35, 0xbb50, 0xbb51, + 0xbb6c, 0xbb6d, 0xbb88, 0xbb89, 0xbba4, 0xbba5, 0xbbc0, 0xbbc1, 0xbbdc, 0xbbdd, 0xbbf8, 0xbbf9, 0xbc14, 0xbc15, + 0xbc30, 0xbc31, 0xbc4c, 0xbc4d, 0xbc68, 0xbc69, 0xbc84, 0xbc85, 0xbca0, 0xbca1, 0xbcbc, 0xbcbd, 0xbcd8, 0xbcd9, + 0xbcf4, 0xbcf5, 0xbd10, 0xbd11, 0xbd2c, 0xbd2d, 0xbd48, 0xbd49, 0xbd64, 0xbd65, 0xbd80, 0xbd81, 0xbd9c, 0xbd9d, + 0xbdb8, 0xbdb9, 0xbdd4, 0xbdd5, 0xbdf0, 0xbdf1, 0xbe0c, 0xbe0d, 0xbe28, 0xbe29, 0xbe44, 0xbe45, 0xbe60, 0xbe61, + 0xbe7c, 0xbe7d, 0xbe98, 0xbe99, 0xbeb4, 0xbeb5, 0xbed0, 0xbed1, 0xbeec, 0xbeed, 0xbf08, 0xbf09, 0xbf24, 0xbf25, + 0xbf40, 0xbf41, 0xbf5c, 0xbf5d, 0xbf78, 0xbf79, 0xbf94, 0xbf95, 0xbfb0, 0xbfb1, 0xbfcc, 0xbfcd, 0xbfe8, 0xbfe9, + 0xc004, 0xc005, 0xc020, 0xc021, 0xc03c, 0xc03d, 0xc058, 0xc059, 0xc074, 0xc075, 0xc090, 0xc091, 0xc0ac, 0xc0ad, + 0xc0c8, 0xc0c9, 0xc0e4, 0xc0e5, 0xc100, 0xc101, 0xc11c, 0xc11d, 0xc138, 0xc139, 0xc154, 0xc155, 0xc170, 0xc171, + 0xc18c, 0xc18d, 0xc1a8, 0xc1a9, 0xc1c4, 0xc1c5, 0xc1e0, 0xc1e1, 0xc1fc, 0xc1fd, 0xc218, 0xc219, 0xc234, 0xc235, + 0xc250, 0xc251, 0xc26c, 0xc26d, 0xc288, 0xc289, 0xc2a4, 0xc2a5, 0xc2c0, 0xc2c1, 0xc2dc, 0xc2dd, 0xc2f8, 0xc2f9, + 0xc314, 0xc315, 0xc330, 0xc331, 0xc34c, 0xc34d, 0xc368, 0xc369, 0xc384, 0xc385, 0xc3a0, 0xc3a1, 0xc3bc, 0xc3bd, + 0xc3d8, 0xc3d9, 0xc3f4, 0xc3f5, 0xc410, 0xc411, 0xc42c, 0xc42d, 0xc448, 0xc449, 0xc464, 0xc465, 0xc480, 0xc481, + 0xc49c, 0xc49d, 0xc4b8, 0xc4b9, 0xc4d4, 0xc4d5, 0xc4f0, 0xc4f1, 0xc50c, 0xc50d, 0xc528, 0xc529, 0xc544, 0xc545, + 0xc560, 0xc561, 0xc57c, 0xc57d, 0xc598, 0xc599, 0xc5b4, 0xc5b5, 0xc5d0, 0xc5d1, 0xc5ec, 0xc5ed, 0xc608, 0xc609, + 0xc624, 0xc625, 0xc640, 0xc641, 0xc65c, 0xc65d, 0xc678, 0xc679, 0xc694, 0xc695, 0xc6b0, 0xc6b1, 0xc6cc, 0xc6cd, + 0xc6e8, 0xc6e9, 0xc704, 0xc705, 0xc720, 0xc721, 0xc73c, 0xc73d, 0xc758, 0xc759, 0xc774, 0xc775, 0xc790, 0xc791, + 0xc7ac, 0xc7ad, 0xc7c8, 0xc7c9, 0xc7e4, 0xc7e5, 0xc800, 0xc801, 0xc81c, 0xc81d, 0xc838, 0xc839, 0xc854, 0xc855, + 0xc870, 0xc871, 0xc88c, 0xc88d, 0xc8a8, 0xc8a9, 0xc8c4, 0xc8c5, 0xc8e0, 0xc8e1, 0xc8fc, 0xc8fd, 0xc918, 0xc919, + 0xc934, 0xc935, 0xc950, 0xc951, 0xc96c, 0xc96d, 0xc988, 0xc989, 0xc9a4, 0xc9a5, 0xc9c0, 0xc9c1, 0xc9dc, 0xc9dd, + 0xc9f8, 0xc9f9, 0xca14, 0xca15, 0xca30, 0xca31, 0xca4c, 0xca4d, 0xca68, 0xca69, 0xca84, 0xca85, 0xcaa0, 0xcaa1, + 0xcabc, 0xcabd, 0xcad8, 0xcad9, 0xcaf4, 0xcaf5, 0xcb10, 0xcb11, 0xcb2c, 0xcb2d, 0xcb48, 0xcb49, 0xcb64, 0xcb65, + 0xcb80, 0xcb81, 0xcb9c, 0xcb9d, 0xcbb8, 0xcbb9, 0xcbd4, 0xcbd5, 0xcbf0, 0xcbf1, 0xcc0c, 0xcc0d, 0xcc28, 0xcc29, + 0xcc44, 0xcc45, 0xcc60, 0xcc61, 0xcc7c, 0xcc7d, 0xcc98, 0xcc99, 0xccb4, 0xccb5, 0xccd0, 0xccd1, 0xccec, 0xcced, + 0xcd08, 0xcd09, 0xcd24, 0xcd25, 0xcd40, 0xcd41, 0xcd5c, 0xcd5d, 0xcd78, 0xcd79, 0xcd94, 0xcd95, 0xcdb0, 0xcdb1, + 0xcdcc, 0xcdcd, 0xcde8, 0xcde9, 0xce04, 0xce05, 0xce20, 0xce21, 0xce3c, 0xce3d, 0xce58, 0xce59, 0xce74, 0xce75, + 0xce90, 0xce91, 0xceac, 0xcead, 0xcec8, 0xcec9, 0xcee4, 0xcee5, 0xcf00, 0xcf01, 0xcf1c, 0xcf1d, 0xcf38, 0xcf39, + 0xcf54, 0xcf55, 0xcf70, 0xcf71, 0xcf8c, 0xcf8d, 0xcfa8, 0xcfa9, 0xcfc4, 0xcfc5, 0xcfe0, 0xcfe1, 0xcffc, 0xcffd, + 0xd018, 0xd019, 0xd034, 0xd035, 0xd050, 0xd051, 0xd06c, 0xd06d, 0xd088, 0xd089, 0xd0a4, 0xd0a5, 0xd0c0, 0xd0c1, + 0xd0dc, 0xd0dd, 0xd0f8, 0xd0f9, 0xd114, 0xd115, 0xd130, 0xd131, 0xd14c, 0xd14d, 0xd168, 0xd169, 0xd184, 0xd185, + 0xd1a0, 0xd1a1, 0xd1bc, 0xd1bd, 0xd1d8, 0xd1d9, 0xd1f4, 0xd1f5, 0xd210, 0xd211, 0xd22c, 0xd22d, 0xd248, 0xd249, + 0xd264, 0xd265, 0xd280, 0xd281, 0xd29c, 0xd29d, 0xd2b8, 0xd2b9, 0xd2d4, 0xd2d5, 0xd2f0, 0xd2f1, 0xd30c, 0xd30d, + 0xd328, 0xd329, 0xd344, 0xd345, 0xd360, 0xd361, 0xd37c, 0xd37d, 0xd398, 0xd399, 0xd3b4, 0xd3b5, 0xd3d0, 0xd3d1, + 0xd3ec, 0xd3ed, 0xd408, 0xd409, 0xd424, 0xd425, 0xd440, 0xd441, 0xd45c, 0xd45d, 0xd478, 0xd479, 0xd494, 0xd495, + 0xd4b0, 0xd4b1, 0xd4cc, 0xd4cd, 0xd4e8, 0xd4e9, 0xd504, 0xd505, 0xd520, 0xd521, 0xd53c, 0xd53d, 0xd558, 0xd559, + 0xd574, 0xd575, 0xd590, 0xd591, 0xd5ac, 0xd5ad, 0xd5c8, 0xd5c9, 0xd5e4, 0xd5e5, 0xd600, 0xd601, 0xd61c, 0xd61d, + 0xd638, 0xd639, 0xd654, 0xd655, 0xd670, 0xd671, 0xd68c, 0xd68d, 0xd6a8, 0xd6a9, 0xd6c4, 0xd6c5, 0xd6e0, 0xd6e1, + 0xd6fc, 0xd6fd, 0xd718, 0xd719, 0xd734, 0xd735, 0xd750, 0xd751, 0xd76c, 0xd76d, 0xd788, 0xd789, 0xd7b0, 0xd7cb, + 0xfb1e, 0xfe00, 0xfe20, 0xfeff, 0xff9e, 0xfff0, 0x101fd, 0x102e0, 0x10376, 0x10a01, 0x10a05, 0x10a0c, 0x10a38, + 0x10a3f, 0x10ae5, 0x10d24, 0x10d69, 0x10eab, 0x10efa, 0x10f46, 0x10f82, 0x11000, 0x11001, 0x11002, 0x11038, + 0x11070, 0x11073, 0x1107f, 0x11082, 0x110b0, 0x110b3, 0x110b7, 0x110b9, 0x110bd, 0x110c2, 0x110cd, 0x11100, + 0x11127, 0x1112c, 0x1112d, 0x11145, 0x11173, 0x11180, 0x11182, 0x111b3, 0x111b6, 0x111bf, 0x111c0, 0x111c2, + 0x111c9, 0x111ce, 0x111cf, 0x1122c, 0x1122f, 0x11232, 0x11234, 0x1123e, 0x11241, 0x112df, 0x112e0, 0x112e3, + 0x11300, 0x11302, 0x1133b, 0x1133e, 0x1133f, 0x11340, 0x11341, 0x11347, 0x1134b, 0x1134d, 0x11357, 0x11362, + 0x11366, 0x11370, 0x113b8, 0x113b9, 0x113bb, 0x113c2, 0x113c5, 0x113c7, 0x113ca, 0x113cc, 0x113ce, 0x113d1, + 0x113d2, 0x113e1, 0x11435, 0x11438, 0x11440, 0x11442, 0x11445, 0x11446, 0x1145e, 0x114b0, 0x114b1, 0x114b3, + 0x114b9, 0x114ba, 0x114bb, 0x114bd, 0x114be, 0x114bf, 0x114c1, 0x114c2, 0x115af, 0x115b0, 0x115b2, 0x115b8, + 0x115bc, 0x115be, 0x115bf, 0x115dc, 0x11630, 0x11633, 0x1163b, 0x1163d, 0x1163e, 0x1163f, 0x116ab, 0x116ac, + 0x116ad, 0x116ae, 0x116b0, 0x1171d, 0x1171e, 0x1171f, 0x11722, 0x11726, 0x11727, 0x1182c, 0x1182f, 0x11838, + 0x11839, 0x11930, 0x11931, 0x11937, 0x1193b, 0x1193f, 0x11940, 0x11941, 0x11942, 0x11943, 0x119d1, 0x119d4, + 0x119da, 0x119dc, 0x119e0, 0x119e4, 0x11a01, 0x11a33, 0x11a39, 0x11a3b, 0x11a47, 0x11a51, 0x11a57, 0x11a59, + 0x11a84, 0x11a8a, 0x11a97, 0x11a98, 0x11b60, 0x11b61, 0x11b62, 0x11b65, 0x11b66, 0x11b67, 0x11c2f, 0x11c30, + 0x11c38, 0x11c3e, 0x11c3f, 0x11c92, 0x11ca9, 0x11caa, 0x11cb1, 0x11cb2, 0x11cb4, 0x11cb5, 0x11d31, 0x11d3a, + 0x11d3c, 0x11d3f, 0x11d46, 0x11d47, 0x11d8a, 0x11d90, 0x11d93, 0x11d95, 0x11d96, 0x11d97, 0x11ef3, 0x11ef5, + 0x11f00, 0x11f02, 0x11f03, 0x11f34, 0x11f36, 0x11f3e, 0x11f40, 0x11f5a, 0x13430, 0x13440, 0x13447, 0x1611e, + 0x1612a, 0x1612d, 0x16af0, 0x16b30, 0x16d63, 0x16d67, 0x16f4f, 0x16f51, 0x16f8f, 0x16fe4, 0x16ff0, 0x1bc9d, + 0x1bca0, 0x1cf00, 0x1cf30, 0x1d165, 0x1d16d, 0x1d173, 0x1d17b, 0x1d185, 0x1d1aa, 0x1d242, 0x1da00, 0x1da3b, + 0x1da75, 0x1da84, 0x1da9b, 0x1daa1, 0x1e000, 0x1e008, 0x1e01b, 0x1e023, 0x1e026, 0x1e08f, 0x1e130, 0x1e2ae, + 0x1e2ec, 0x1e4ec, 0x1e5ee, 0x1e6e3, 0x1e6e6, 0x1e6ee, 0x1e6f5, 0x1e8d0, 0x1e944, 0x1f1e6, 0x1f3fb, 0xe0000, + 0xe0020, 0xe0080, 0xe0100, 0xe01f0}, + {0x100a, 0x4001, 0x1002, 0x1, 0x1012, 0x1021, 0x1001, 0x2070, 0x2007, 0x202d, 0x2001, 0x2002, 0x2002, 0x2001, + 0x7006, 0x200b, 0x1001, 0x2015, 0x2001, 0x2007, 0x7001, 0x2006, 0x2002, 0x2004, 0x7001, 0x2001, 0x201b, 0x200b, + 0x2009, 0x2001, 0x2004, 0x2009, 0x2003, 0x2005, 0x2003, 0x7002, 0x2009, 0x2018, 0x7001, 0x2020, 0x9001, 0x2001, + 0x9001, 0x2001, 0x9003, 0x2008, 0x9004, 0x2001, 0x9002, 0x2007, 0x2002, 0x2001, 0x9002, 0x2001, 0x2001, 0x9002, + 0x2004, 0x9002, 0x9002, 0x2001, 0x2001, 0x2002, 0x2001, 0x2002, 0x9001, 0x2001, 0x9003, 0x2002, 0x2002, 0x2003, + 0x2001, 0x2002, 0x2001, 0x2002, 0x9001, 0x2001, 0x9003, 0x2005, 0x2002, 0x9001, 0x9002, 0x2001, 0x2002, 0x2006, + 0x2001, 0x9002, 0x2001, 0x2002, 0x9001, 0x2004, 0x9002, 0x9002, 0x2001, 0x2003, 0x2002, 0x2001, 0x2001, 0x9001, + 0x2001, 0x9002, 0x9003, 0x9003, 0x2001, 0x2001, 0x2001, 0x9003, 0x2001, 0x2001, 0x2003, 0x9004, 0x2003, 0x2004, + 0x2002, 0x2002, 0x2001, 0x9002, 0x2001, 0x9001, 0x2002, 0x9001, 0x2001, 0x9002, 0x2003, 0x2004, 0x2002, 0x2002, + 0x9001, 0x2002, 0x9002, 0x2002, 0x2001, 0x9002, 0x2004, 0x9003, 0x9003, 0x2001, 0x7001, 0x2001, 0x2002, 0x2001, + 0x9002, 0x2001, 0x2001, 0x9002, 0x2003, 0x2001, 0x9007, 0x2001, 0x9002, 0x2001, 0x9001, 0x2007, 0x2008, 0x2001, + 0x9001, 0x2009, 0x2007, 0x2002, 0x2001, 0x2001, 0x2001, 0x9002, 0x200e, 0x9001, 0x2005, 0x2002, 0x200b, 0x2024, + 0x2001, 0x2004, 0x9001, 0x2006, 0x2002, 0x9002, 0x2002, 0x9002, 0x2002, 0x2003, 0x2004, 0x2001, 0x9001, 0x2002, + 0x2001, 0x2001, 0x3060, 0xb048, 0xa058, 0x2003, 0x2004, 0x2003, 0x2002, 0x2002, 0x2002, 0x9001, 0x2007, 0x9008, + 0x2001, 0x9002, 0x200b, 0x2001, 0x2003, 0x1001, 0x2001, 0x2002, 0x2001, 0x2003, 0x9004, 0x2002, 0x9003, 0x9002, + 0x2001, 0x9006, 0x2003, 0x2002, 0x9002, 0x2001, 0x9001, 0x2001, 0x9001, 0x2007, 0x2001, 0x2001, 0x2008, 0x9006, + 0x200a, 0x2001, 0x202e, 0x200c, 0x2004, 0x9001, 0x200a, 0x9004, 0x2003, 0x2009, 0x2002, 0x9001, 0x9001, 0x2004, + 0x9002, 0x2006, 0x2001, 0x9001, 0x2002, 0x9003, 0x2001, 0x9001, 0x2005, 0x9008, 0x2008, 0x9002, 0x2002, 0x2003, + 0x200d, 0x9001, 0x2007, 0x2001, 0x2001, 0x9001, 0x2002, 0x2040, 0x1001, 0x2001, 0xc001, 0x1002, 0x1007, 0x1010, + 0x2021, 0x2003, 0x2001, 0x2020, 0x2006, 0x2002, 0x2004, 0x200a, 0x2002, 0x2002, 0x2001, 0x2001, 0x2001, 0x9002, + 0x2002, 0x9001, 0x2001, 0x9002, 0x9010, 0x2002, 0x2012, 0x2001, 0x2008, 0x200b, 0x9001, 0x2001, 0x301d, 0x2003, + 0x9001, 0x2001, 0x9002, 0x2004, 0x9002, 0x2002, 0x9002, 0x2001, 0x2001, 0x2006, 0x9002, 0x2002, 0x9002, 0x2002, + 0x2001, 0x2001, 0x9001, 0x2001, 0x2001, 0x2003, 0x2002, 0x2002, 0x2001, 0x9001, 0x2002, 0x9002, 0x9001, 0x2001, + 0x9002, 0x2001, 0x9002, 0x2001, 0x9002, 0x9001, 0x2001, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, + 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0x5001, 0x601b, 0xb017, 0xa031, 0x2001, 0x2010, 0x2010, 0x1001, 0x2002, + 0x100c, 0x2001, 0x2001, 0x2005, 0x2003, 0x2002, 0x2004, 0x2003, 0x2001, 0x2002, 0x2004, 0x2005, 0x2002, 0x2006, + 0x200b, 0x2004, 0x9001, 0x2001, 0x9001, 0x200f, 0x2001, 0x2002, 0x2003, 0x9001, 0x9003, 0x2004, 0x9002, 0x2002, + 0x7001, 0x2001, 0x7001, 0x2003, 0x2005, 0x9001, 0x2008, 0x9002, 0x2001, 0x2002, 0x9001, 0x9003, 0x2009, 0x9001, + 0x2001, 0x7002, 0x2004, 0x9001, 0x2001, 0x9003, 0x2003, 0x9002, 0x2004, 0x2001, 0x2001, 0x2001, 0x9003, 0x2008, + 0x2002, 0x9002, 0x2002, 0x2001, 0x9001, 0x2001, 0x9004, 0x9002, 0x9002, 0x2001, 0x2001, 0x9002, 0x2007, 0x2005, + 0x2001, 0x9002, 0x2006, 0x2001, 0x2001, 0x2003, 0x9001, 0x9002, 0x2003, 0x7001, 0x2001, 0x2002, 0x9003, 0x2008, + 0x9002, 0x2003, 0x9001, 0x2001, 0x2001, 0x2001, 0x9002, 0x2006, 0x9001, 0x2001, 0x9002, 0x2001, 0x9001, 0x2002, + 0x9001, 0x2002, 0x2001, 0x9002, 0x2004, 0x9004, 0x2002, 0x9001, 0x2002, 0x2002, 0x9003, 0x2008, 0x9002, 0x2001, + 0x9001, 0x2002, 0x2001, 0x9001, 0x2001, 0x9002, 0x2008, 0x2001, 0x9001, 0x2001, 0x2004, 0x9001, 0x2005, 0x9003, + 0x2009, 0x9001, 0x2002, 0x2001, 0x9005, 0x9002, 0x2004, 0x7001, 0x9001, 0x7001, 0x9001, 0x2001, 0x9003, 0x2004, + 0x2002, 0x9004, 0x2001, 0x9001, 0x200a, 0x2006, 0x9001, 0x2004, 0x2001, 0x2006, 0x9002, 0x2003, 0x7006, 0x200d, + 0x9001, 0x2002, 0x2001, 0x9001, 0x2003, 0x9001, 0x2001, 0x9001, 0x9001, 0x2007, 0x2006, 0x9001, 0x2001, 0x2016, + 0x9001, 0x2007, 0x9001, 0x2002, 0x9001, 0x2002, 0x2006, 0x2001, 0x2002, 0x2007, 0x7001, 0x2001, 0x9005, 0x2002, + 0x9002, 0x2001, 0x9001, 0x2001, 0x2002, 0x9002, 0x2002, 0x7001, 0x9001, 0x9002, 0x2005, 0x9002, 0x2003, 0x2001, + 0x1010, 0x2001, 0x200f, 0x200c, 0x9003, 0x2003, 0x2005, 0x2007, 0xb001, 0xb004, 0x2001, 0x9037, 0x2004, 0x2001, + 0x2002, 0x2002, 0x1004, 0x202e, 0x2017, 0x2005, 0x2006, 0x1008, 0x2008, 0x2007, 0x2004, 0x2003, 0x2037, 0x2032, + 0x2001, 0x2001, 0x2005, 0x200f, 0x2007, 0x2011, 0x2007, 0x2002, 0x2005, 0x2001, 0x2007, 0x2001, 0x2004, 0x2004, + 0x2002, 0x2001, 0x2001, 0x2002, 0x2001, 0x2007, 0x2007, 0x801a, 0x2005, 0x1020, 0x2060, 0x1080, 0x20f0, + 0x1e10}}; + +// DerivedCoreProperties-17.0.0.txt +// Date: 2025-07-30, 23:55:08 GMT +enum class _Indic_Conjunct_Break_property_values : uint8_t { + _Consonant_value, + _Extend_value, + _Linker_value, + _No_value = 255 +}; + +// DerivedCoreProperties-17.0.0.txt +// Date: 2025-07-30, 23:55:08 GMT +inline constexpr _Unicode_property_data<_Indic_Conjunct_Break_property_values, 473, false> + _Indic_Conjunct_Break_property_data{ + {0x300, 0x483, 0x591, 0x5bf, 0x5c1, 0x5c4, 0x5c7, 0x610, 0x64b, 0x670, 0x6d6, 0x6df, 0x6e7, 0x6ea, 0x711, 0x730, + 0x7a6, 0x7eb, 0x7fd, 0x816, 0x81b, 0x825, 0x829, 0x859, 0x897, 0x8ca, 0x8e3, 0x915, 0x93a, 0x93c, 0x941, + 0x94d, 0x951, 0x958, 0x962, 0x978, 0x981, 0x995, 0x9aa, 0x9b2, 0x9b6, 0x9bc, 0x9be, 0x9c1, 0x9cd, 0x9d7, + 0x9dc, 0x9df, 0x9e2, 0x9f0, 0x9fe, 0xa01, 0xa3c, 0xa41, 0xa47, 0xa4b, 0xa51, 0xa70, 0xa75, 0xa81, 0xa95, + 0xaaa, 0xab2, 0xab5, 0xabc, 0xac1, 0xac7, 0xacd, 0xae2, 0xaf9, 0xafa, 0xb01, 0xb15, 0xb2a, 0xb32, 0xb35, + 0xb3c, 0xb3e, 0xb41, 0xb4d, 0xb55, 0xb5c, 0xb5f, 0xb62, 0xb71, 0xb82, 0xbbe, 0xbc0, 0xbcd, 0xbd7, 0xc00, + 0xc04, 0xc15, 0xc2a, 0xc3c, 0xc3e, 0xc46, 0xc4a, 0xc4d, 0xc55, 0xc58, 0xc62, 0xc81, 0xcbc, 0xcbf, 0xcc2, + 0xcc6, 0xcca, 0xcd5, 0xce2, 0xd00, 0xd15, 0xd3b, 0xd3e, 0xd41, 0xd4d, 0xd57, 0xd62, 0xd81, 0xdca, 0xdcf, + 0xdd2, 0xdd6, 0xddf, 0xe31, 0xe34, 0xe47, 0xeb1, 0xeb4, 0xec8, 0xf18, 0xf35, 0xf37, 0xf39, 0xf71, 0xf80, + 0xf86, 0xf8d, 0xf99, 0xfc6, 0x1000, 0x102d, 0x1032, 0x1039, 0x103a, 0x103d, 0x103f, 0x1050, 0x1058, 0x105a, + 0x105e, 0x1061, 0x1065, 0x106e, 0x1071, 0x1075, 0x1082, 0x1085, 0x108d, 0x108e, 0x109d, 0x135d, 0x1712, + 0x1732, 0x1752, 0x1772, 0x1780, 0x17b4, 0x17b7, 0x17c6, 0x17c9, 0x17d2, 0x17d3, 0x17dd, 0x180b, 0x180f, + 0x1885, 0x18a9, 0x1920, 0x1927, 0x1932, 0x1939, 0x1a17, 0x1a1b, 0x1a20, 0x1a56, 0x1a58, 0x1a60, 0x1a62, + 0x1a65, 0x1a73, 0x1a7f, 0x1ab0, 0x1ae0, 0x1b00, 0x1b0b, 0x1b13, 0x1b34, 0x1b42, 0x1b44, 0x1b45, 0x1b6b, + 0x1b80, 0x1b83, 0x1ba2, 0x1ba8, 0x1bab, 0x1bac, 0x1bae, 0x1bbb, 0x1be6, 0x1be8, 0x1bed, 0x1bef, 0x1c2c, + 0x1c36, 0x1cd0, 0x1cd4, 0x1ce2, 0x1ced, 0x1cf4, 0x1cf8, 0x1dc0, 0x200d, 0x20d0, 0x2cef, 0x2d7f, 0x2de0, + 0x302a, 0x3099, 0xa66f, 0xa674, 0xa69e, 0xa6f0, 0xa802, 0xa806, 0xa80b, 0xa825, 0xa82c, 0xa8c4, 0xa8e0, + 0xa8ff, 0xa926, 0xa947, 0xa953, 0xa980, 0xa989, 0xa98f, 0xa9b3, 0xa9b6, 0xa9bc, 0xa9c0, 0xa9e0, 0xa9e5, + 0xa9e7, 0xa9fa, 0xaa29, 0xaa31, 0xaa35, 0xaa43, 0xaa4c, 0xaa60, 0xaa71, 0xaa7a, 0xaa7c, 0xaa7e, 0xaab0, + 0xaab2, 0xaab7, 0xaabe, 0xaac1, 0xaae0, 0xaaec, 0xaaf6, 0xabc0, 0xabe5, 0xabe8, 0xabed, 0xfb1e, 0xfe00, + 0xfe20, 0xff9e, 0x101fd, 0x102e0, 0x10376, 0x10a00, 0x10a01, 0x10a05, 0x10a0c, 0x10a10, 0x10a15, 0x10a19, + 0x10a38, 0x10a3f, 0x10ae5, 0x10d24, 0x10d69, 0x10eab, 0x10efa, 0x10f46, 0x10f82, 0x11001, 0x11038, 0x11070, + 0x11073, 0x1107f, 0x110b3, 0x110b9, 0x110c2, 0x11100, 0x11103, 0x11127, 0x1112d, 0x11133, 0x11134, 0x11144, + 0x11147, 0x11173, 0x11180, 0x111b6, 0x111c0, 0x111c9, 0x111cf, 0x1122f, 0x11234, 0x1123e, 0x11241, 0x112df, + 0x112e3, 0x11300, 0x1133b, 0x1133e, 0x11340, 0x1134d, 0x11357, 0x11366, 0x11370, 0x11380, 0x1138b, 0x1138e, + 0x11390, 0x113b8, 0x113bb, 0x113c2, 0x113c5, 0x113c7, 0x113ce, 0x113d0, 0x113d2, 0x113e1, 0x11438, 0x11442, + 0x11446, 0x1145e, 0x114b0, 0x114b3, 0x114ba, 0x114bd, 0x114bf, 0x114c2, 0x115af, 0x115b2, 0x115bc, 0x115bf, + 0x115dc, 0x11633, 0x1163d, 0x1163f, 0x116ab, 0x116ad, 0x116b0, 0x1171d, 0x1171f, 0x11722, 0x11727, 0x1182f, + 0x11839, 0x11900, 0x11909, 0x1190c, 0x11915, 0x11918, 0x11930, 0x1193b, 0x1193e, 0x11943, 0x119d4, 0x119da, + 0x119e0, 0x11a00, 0x11a01, 0x11a0b, 0x11a33, 0x11a3b, 0x11a47, 0x11a50, 0x11a51, 0x11a59, 0x11a5c, 0x11a8a, + 0x11a98, 0x11a99, 0x11b60, 0x11b62, 0x11b66, 0x11c30, 0x11c38, 0x11c3f, 0x11c92, 0x11caa, 0x11cb2, 0x11cb5, + 0x11d31, 0x11d3a, 0x11d3c, 0x11d3f, 0x11d47, 0x11d90, 0x11d95, 0x11d97, 0x11ef3, 0x11f00, 0x11f04, 0x11f12, + 0x11f36, 0x11f40, 0x11f42, 0x11f5a, 0x13440, 0x13447, 0x1611e, 0x1612d, 0x16af0, 0x16b30, 0x16f4f, 0x16f8f, + 0x16fe4, 0x16ff0, 0x1bc9d, 0x1cf00, 0x1cf30, 0x1d165, 0x1d16d, 0x1d17b, 0x1d185, 0x1d1aa, 0x1d242, 0x1da00, + 0x1da3b, 0x1da75, 0x1da84, 0x1da9b, 0x1daa1, 0x1e000, 0x1e008, 0x1e01b, 0x1e023, 0x1e026, 0x1e08f, 0x1e130, + 0x1e2ae, 0x1e2ec, 0x1e4ec, 0x1e5ee, 0x1e6e3, 0x1e6e6, 0x1e6ee, 0x1e6f5, 0x1e8d0, 0x1e944, 0x1f3fb, 0xe0020, + 0xe0100}, + {0x1070, 0x1007, 0x102d, 0x1001, 0x1002, 0x1002, 0x1001, 0x100b, 0x1015, 0x1001, 0x1007, 0x1006, 0x1002, 0x1004, + 0x1001, 0x101b, 0x100b, 0x1009, 0x1001, 0x1004, 0x1009, 0x1003, 0x1005, 0x1003, 0x1009, 0x1018, 0x1020, + 0x25, 0x1001, 0x1001, 0x1008, 0x2001, 0x1007, 0x8, 0x1002, 0x8, 0x1001, 0x14, 0x7, 0x1, 0x4, 0x1001, 0x1001, + 0x1004, 0x2001, 0x1001, 0x2, 0x1, 0x1002, 0x2, 0x1001, 0x1002, 0x1001, 0x1002, 0x1002, 0x1003, 0x1001, + 0x1002, 0x1001, 0x1002, 0x14, 0x7, 0x2, 0x5, 0x1001, 0x1005, 0x1002, 0x2001, 0x1002, 0x1, 0x1006, 0x1001, + 0x14, 0x7, 0x2, 0x5, 0x1001, 0x1002, 0x1004, 0x2001, 0x1003, 0x2, 0x1, 0x1002, 0x1, 0x1001, 0x1001, 0x1001, + 0x1001, 0x1001, 0x1001, 0x1001, 0x14, 0x10, 0x1001, 0x1003, 0x1003, 0x1003, 0x2001, 0x1002, 0x3, 0x1002, + 0x1001, 0x1001, 0x1002, 0x1001, 0x1003, 0x1004, 0x1002, 0x1002, 0x1002, 0x26, 0x1002, 0x1001, 0x1004, + 0x2001, 0x1001, 0x1002, 0x1001, 0x1001, 0x1001, 0x1003, 0x1001, 0x1001, 0x1001, 0x1007, 0x1008, 0x1001, + 0x1009, 0x1007, 0x1002, 0x1001, 0x1001, 0x1001, 0x100e, 0x1005, 0x1002, 0x100b, 0x1024, 0x1001, 0x2b, + 0x1004, 0x1006, 0x2001, 0x1001, 0x1002, 0x1, 0x6, 0x1002, 0x4, 0x1003, 0x1, 0x2, 0x3, 0x1004, 0xd, 0x1001, + 0x1002, 0x1001, 0x1, 0x1001, 0x1003, 0x1004, 0x1003, 0x1002, 0x1002, 0x34, 0x1002, 0x1007, 0x1001, 0x1009, + 0x2001, 0x1001, 0x1001, 0x1003, 0x1001, 0x1002, 0x1001, 0x1003, 0x1002, 0x1001, 0x1003, 0x1002, 0x1001, + 0x35, 0x1001, 0x1007, 0x2001, 0x1001, 0x1008, 0x100a, 0x1001, 0x102e, 0x100c, 0x1004, 0x2, 0x21, 0x100a, + 0x1002, 0x2001, 0x8, 0x1009, 0x1002, 0x1e, 0x1004, 0x1003, 0x2001, 0x1002, 0x2, 0x3, 0x1001, 0x1002, 0x1001, + 0x1005, 0x1008, 0x1002, 0x1003, 0x100d, 0x1007, 0x1001, 0x1001, 0x1002, 0x1040, 0x1001, 0x1021, 0x1003, + 0x1001, 0x1020, 0x1006, 0x1002, 0x1004, 0x100a, 0x1002, 0x1002, 0x1001, 0x1001, 0x1001, 0x1002, 0x1001, + 0x1002, 0x1012, 0x1001, 0x1008, 0x100b, 0x1001, 0x1003, 0x3, 0x24, 0x1001, 0x1004, 0x1002, 0x2001, 0x5, + 0x1001, 0x9, 0x5, 0x1006, 0x1002, 0x1002, 0x1001, 0x1001, 0x10, 0x3, 0x1, 0x1001, 0x2, 0x1001, 0x1003, + 0x1002, 0x1002, 0x1001, 0xb, 0x1002, 0x2001, 0x1b, 0x1001, 0x1001, 0x1001, 0x1001, 0x1010, 0x1010, 0x1002, + 0x1001, 0x1001, 0x1005, 0x1, 0x1003, 0x1002, 0x1004, 0x4, 0x3, 0x1d, 0x1003, 0x2001, 0x1002, 0x1004, 0x1005, + 0x1002, 0x1006, 0x100b, 0x1004, 0x1001, 0x100f, 0x1001, 0x1002, 0x1003, 0x1004, 0x1002, 0x1001, 0x1003, + 0x24, 0x1005, 0x1006, 0x2001, 0x1001, 0x1, 0x1, 0x1001, 0x1002, 0x1009, 0x1001, 0x1004, 0x1001, 0x1003, + 0x1004, 0x1001, 0x1001, 0x1001, 0x1008, 0x1002, 0x1002, 0x1001, 0x1001, 0x1001, 0x1001, 0x1007, 0x1005, 0xa, + 0x1, 0x1, 0x26, 0x1001, 0x1006, 0x1001, 0x1001, 0x1003, 0x1002, 0x2001, 0x1001, 0x1002, 0x1008, 0x1003, + 0x1001, 0x1001, 0x1001, 0x1006, 0x1001, 0x1001, 0x1002, 0x1002, 0x1001, 0x1004, 0x1002, 0x1002, 0x1002, + 0x1008, 0x1001, 0x1002, 0x1001, 0x1001, 0x1008, 0x1001, 0x1001, 0x1004, 0x1005, 0x1009, 0x1002, 0x7, 0x1, + 0x8, 0x2, 0x18, 0x1001, 0x1003, 0x2001, 0x1001, 0x1004, 0x1002, 0x1001, 0x1, 0x100a, 0x28, 0x1006, 0x1004, + 0x2001, 0x1, 0x1006, 0x1003, 0x28, 0x100d, 0x1001, 0x2001, 0x1001, 0x1003, 0x1001, 0x1007, 0x1006, 0x1001, + 0x1016, 0x1007, 0x1002, 0x1002, 0x1006, 0x1001, 0x1002, 0x1007, 0x1001, 0x1002, 0x1001, 0x1001, 0x1002, + 0x1002, 0xd, 0x22, 0x1005, 0x1002, 0x2001, 0x1001, 0x1001, 0x100f, 0x100c, 0x1003, 0x1005, 0x1007, 0x1001, + 0x1004, 0x1001, 0x1002, 0x1002, 0x102e, 0x1017, 0x1005, 0x1006, 0x1008, 0x1007, 0x1004, 0x1003, 0x1037, + 0x1032, 0x1001, 0x1001, 0x1005, 0x100f, 0x1007, 0x1011, 0x1007, 0x1002, 0x1005, 0x1001, 0x1007, 0x1001, + 0x1004, 0x1004, 0x1002, 0x1001, 0x1001, 0x1002, 0x1001, 0x1007, 0x1007, 0x1005, 0x1060, 0x10f0}}; + +// emoji-data.txt +// Date: 2025-07-25, 17:54:31 GMT +enum class _Extended_Pictographic_property_values : uint8_t { _Extended_Pictographic_value, _No_value = 255 }; + +// emoji-data.txt +// Date: 2025-07-25, 17:54:31 GMT +inline constexpr _Unicode_property_data<_Extended_Pictographic_property_values, 156, true> + _Extended_Pictographic_property_data{ + {0xa9, 0xae, 0x203c, 0x2049, 0x2122, 0x2139, 0x2194, 0x21a9, 0x231a, 0x2328, 0x23cf, 0x23e9, 0x23f8, 0x24c2, + 0x25aa, 0x25b6, 0x25c0, 0x25fb, 0x2600, 0x260e, 0x2611, 0x2614, 0x2618, 0x261d, 0x2620, 0x2622, 0x2626, + 0x262a, 0x262e, 0x2638, 0x2640, 0x2642, 0x2648, 0x265f, 0x2663, 0x2665, 0x2668, 0x267b, 0x267e, 0x2692, + 0x2699, 0x269b, 0x26a0, 0x26a7, 0x26aa, 0x26b0, 0x26bd, 0x26c4, 0x26c8, 0x26ce, 0x26d1, 0x26d3, 0x26e9, + 0x26f0, 0x26f7, 0x26fd, 0x2702, 0x2705, 0x2708, 0x270f, 0x2712, 0x2714, 0x2716, 0x271d, 0x2721, 0x2728, + 0x2733, 0x2744, 0x2747, 0x274c, 0x274e, 0x2753, 0x2757, 0x2763, 0x2795, 0x27a1, 0x27b0, 0x27bf, 0x2934, + 0x2b05, 0x2b1b, 0x2b50, 0x2b55, 0x3030, 0x303d, 0x3297, 0x3299, 0x1f004, 0x1f02c, 0x1f094, 0x1f0af, 0x1f0c0, + 0x1f0cf, 0x1f0f6, 0x1f170, 0x1f17e, 0x1f18e, 0x1f191, 0x1f1ae, 0x1f201, 0x1f21a, 0x1f22f, 0x1f232, 0x1f23c, + 0x1f249, 0x1f266, 0x1f324, 0x1f396, 0x1f399, 0x1f39e, 0x1f3f3, 0x1f3f7, 0x1f400, 0x1f4ff, 0x1f549, 0x1f550, + 0x1f56f, 0x1f573, 0x1f587, 0x1f58a, 0x1f590, 0x1f595, 0x1f5a4, 0x1f5a8, 0x1f5b1, 0x1f5bc, 0x1f5c2, 0x1f5d1, + 0x1f5dc, 0x1f5e1, 0x1f5e3, 0x1f5e8, 0x1f5ef, 0x1f5f3, 0x1f5fa, 0x1f680, 0x1f6cb, 0x1f6d5, 0x1f6e9, 0x1f6eb, + 0x1f6f3, 0x1f7da, 0x1f80c, 0x1f848, 0x1f85a, 0x1f888, 0x1f8ae, 0x1f8bc, 0x1f8c2, 0x1f8d9, 0x1f90c, 0x1f93c, + 0x1f947, 0x1fa58, 0x1fa6e, 0x1fc00}, + {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x2, 0x2, 0x1, 0x1, 0xb, 0x3, 0x1, 0x2, 0x1, 0x1, 0x4, 0x5, 0x1, 0x1, 0x2, + 0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x2, 0x3, 0x1, 0x1, 0xc, 0x2, 0x1, 0x2, 0x1, 0x1, 0x2, 0x6, 0x1, 0x2, 0x2, + 0x1, 0x2, 0x2, 0x2, 0x2, 0x1, 0x2, 0x1, 0x2, 0x2, 0x6, 0x4, 0x1, 0x1, 0x1, 0x6, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x3, 0x1, 0x2, 0x3, 0x1, 0x1, 0x1, 0x2, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x4, 0xc, 0x2, 0x1, 0x2, 0xa, 0x2, 0x2, 0x1, 0xa, 0x38, 0xf, 0x1, 0x1, 0x9, 0x4, 0x17, 0xbc, + 0x70, 0x2, 0x3, 0x53, 0x3, 0x4, 0xfe, 0x3f, 0x6, 0x18, 0x2, 0x8, 0x1, 0x4, 0x1, 0x2, 0x2, 0x1, 0x2, 0x1, + 0x3, 0x3, 0x3, 0x1, 0x1, 0x1, 0x1, 0x1, 0x56, 0x46, 0x8, 0x11, 0x1, 0x6, 0xd, 0x26, 0x4, 0x8, 0x6, 0x8, 0x2, + 0x4, 0xe, 0x27, 0x2f, 0xa, 0xb9, 0x8, 0x92, 0x3fe}}; + +// DerivedGeneralCategory-17.0.0.txt +// Date: 2025-07-24, 00:12:50 GMT +enum class __printable_property_values : uint8_t { _Yes_value, _No_value = 255 }; + +// DerivedGeneralCategory-17.0.0.txt +// Date: 2025-07-24, 00:12:50 GMT +inline constexpr _Unicode_property_data<__printable_property_values, 741, true> __printable_property_data{ + {0x20, 0xa1, 0xae, 0x37a, 0x384, 0x38c, 0x38e, 0x3a3, 0x531, 0x559, 0x58d, 0x591, 0x5d0, 0x5ef, 0x606, 0x61d, 0x6de, + 0x710, 0x74d, 0x7c0, 0x7fd, 0x830, 0x840, 0x85e, 0x860, 0x870, 0x897, 0x8e3, 0x985, 0x98f, 0x993, 0x9aa, 0x9b2, + 0x9b6, 0x9bc, 0x9c7, 0x9cb, 0x9d7, 0x9dc, 0x9df, 0x9e6, 0xa01, 0xa05, 0xa0f, 0xa13, 0xa2a, 0xa32, 0xa35, 0xa38, + 0xa3c, 0xa3e, 0xa47, 0xa4b, 0xa51, 0xa59, 0xa5e, 0xa66, 0xa81, 0xa85, 0xa8f, 0xa93, 0xaaa, 0xab2, 0xab5, 0xabc, + 0xac7, 0xacb, 0xad0, 0xae0, 0xae6, 0xaf9, 0xb01, 0xb05, 0xb0f, 0xb13, 0xb2a, 0xb32, 0xb35, 0xb3c, 0xb47, 0xb4b, + 0xb55, 0xb5c, 0xb5f, 0xb66, 0xb82, 0xb85, 0xb8e, 0xb92, 0xb99, 0xb9c, 0xb9e, 0xba3, 0xba8, 0xbae, 0xbbe, 0xbc6, + 0xbca, 0xbd0, 0xbd7, 0xbe6, 0xc00, 0xc0e, 0xc12, 0xc2a, 0xc3c, 0xc46, 0xc4a, 0xc55, 0xc58, 0xc5c, 0xc60, 0xc66, + 0xc77, 0xc8e, 0xc92, 0xcaa, 0xcb5, 0xcbc, 0xcc6, 0xcca, 0xcd5, 0xcdc, 0xce0, 0xce6, 0xcf1, 0xd00, 0xd0e, 0xd12, + 0xd46, 0xd4a, 0xd54, 0xd66, 0xd81, 0xd85, 0xd9a, 0xdb3, 0xdbd, 0xdc0, 0xdca, 0xdcf, 0xdd6, 0xdd8, 0xde6, 0xdf2, + 0xe01, 0xe3f, 0xe81, 0xe84, 0xe86, 0xe8c, 0xea5, 0xea7, 0xec0, 0xec6, 0xec8, 0xed0, 0xedc, 0xf00, 0xf49, 0xf71, + 0xf99, 0xfbe, 0xfce, 0x1000, 0x10c7, 0x10cd, 0x10d0, 0x124a, 0x1250, 0x1258, 0x125a, 0x1260, 0x128a, 0x1290, + 0x12b2, 0x12b8, 0x12c0, 0x12c2, 0x12c8, 0x12d8, 0x1312, 0x1318, 0x135d, 0x1380, 0x13a0, 0x13f8, 0x1400, 0x1681, + 0x16a0, 0x1700, 0x171f, 0x1740, 0x1760, 0x176e, 0x1772, 0x1780, 0x17e0, 0x17f0, 0x1800, 0x180f, 0x1820, 0x1880, + 0x18b0, 0x1900, 0x1920, 0x1930, 0x1940, 0x1944, 0x1970, 0x1980, 0x19b0, 0x19d0, 0x19de, 0x1a1e, 0x1a60, 0x1a7f, + 0x1a90, 0x1aa0, 0x1ab0, 0x1ae0, 0x1b00, 0x1b4e, 0x1bfc, 0x1c3b, 0x1c4d, 0x1c90, 0x1cbd, 0x1cd0, 0x1d00, 0x1f18, + 0x1f20, 0x1f48, 0x1f50, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x1f80, 0x1fb6, 0x1fc6, 0x1fd6, 0x1fdd, 0x1ff2, 0x1ff6, + 0x2010, 0x2030, 0x2070, 0x2074, 0x2090, 0x20a0, 0x20d0, 0x2100, 0x2190, 0x2440, 0x2460, 0x2b76, 0x2cf9, 0x2d27, + 0x2d2d, 0x2d30, 0x2d6f, 0x2d7f, 0x2da0, 0x2da8, 0x2db0, 0x2db8, 0x2dc0, 0x2dc8, 0x2dd0, 0x2dd8, 0x2de0, 0x2e80, + 0x2e9b, 0x2f00, 0x2ff0, 0x3001, 0x3041, 0x3099, 0x3105, 0x3131, 0x3190, 0x31ef, 0x3220, 0xa490, 0xa4d0, 0xa640, + 0xa700, 0xa7f1, 0xa830, 0xa840, 0xa880, 0xa8ce, 0xa8e0, 0xa95f, 0xa980, 0xa9cf, 0xa9de, 0xaa00, 0xaa40, 0xaa50, + 0xaa5c, 0xaadb, 0xab01, 0xab09, 0xab11, 0xab20, 0xab28, 0xab30, 0xab70, 0xabf0, 0xac00, 0xd7b0, 0xd7cb, 0xf900, + 0xfa70, 0xfb00, 0xfb13, 0xfb1d, 0xfb38, 0xfb3e, 0xfb40, 0xfb43, 0xfb46, 0xfdf0, 0xfe20, 0xfe54, 0xfe68, 0xfe70, + 0xfe76, 0xff01, 0xffc2, 0xffca, 0xffd2, 0xffda, 0xffe0, 0xffe8, 0xfffc, 0x10000, 0x1000d, 0x10028, 0x1003c, + 0x1003f, 0x10050, 0x10080, 0x10100, 0x10107, 0x10137, 0x10190, 0x101a0, 0x101d0, 0x10280, 0x102a0, 0x102e0, + 0x10300, 0x1032d, 0x10350, 0x10380, 0x1039f, 0x103c8, 0x10400, 0x104a0, 0x104b0, 0x104d8, 0x10500, 0x10530, + 0x1056f, 0x1057c, 0x1058c, 0x10594, 0x10597, 0x105a3, 0x105b3, 0x105bb, 0x105c0, 0x10600, 0x10740, 0x10760, + 0x10780, 0x10787, 0x107b2, 0x10800, 0x10808, 0x1080a, 0x10837, 0x1083c, 0x1083f, 0x10857, 0x108a7, 0x108e0, + 0x108f4, 0x108fb, 0x1091f, 0x1093f, 0x10980, 0x109bc, 0x109d2, 0x10a05, 0x10a0c, 0x10a15, 0x10a19, 0x10a38, + 0x10a3f, 0x10a50, 0x10a60, 0x10ac0, 0x10aeb, 0x10b00, 0x10b39, 0x10b58, 0x10b78, 0x10b99, 0x10ba9, 0x10c00, + 0x10c80, 0x10cc0, 0x10cfa, 0x10d30, 0x10d40, 0x10d69, 0x10d8e, 0x10e60, 0x10e80, 0x10eab, 0x10eb0, 0x10ec2, + 0x10ed0, 0x10efa, 0x10f30, 0x10f70, 0x10fb0, 0x10fe0, 0x11000, 0x11052, 0x1107f, 0x110be, 0x110d0, 0x110f0, + 0x11100, 0x11136, 0x11150, 0x11180, 0x111e1, 0x11200, 0x11213, 0x11280, 0x11288, 0x1128a, 0x1128f, 0x1129f, + 0x112b0, 0x112f0, 0x11300, 0x11305, 0x1130f, 0x11313, 0x1132a, 0x11332, 0x11335, 0x1133b, 0x11347, 0x1134b, + 0x11350, 0x11357, 0x1135d, 0x11366, 0x11370, 0x11380, 0x1138b, 0x1138e, 0x11390, 0x113b7, 0x113c2, 0x113c5, + 0x113c7, 0x113cc, 0x113d7, 0x113e1, 0x11400, 0x1145d, 0x11480, 0x114d0, 0x11580, 0x115b8, 0x11600, 0x11650, + 0x11660, 0x11680, 0x116c0, 0x116d0, 0x11700, 0x1171d, 0x11730, 0x11800, 0x118a0, 0x118ff, 0x11909, 0x1190c, + 0x11915, 0x11918, 0x11937, 0x1193b, 0x11950, 0x119a0, 0x119aa, 0x119da, 0x11a00, 0x11a50, 0x11ab0, 0x11b00, + 0x11b60, 0x11bc0, 0x11bf0, 0x11c00, 0x11c0a, 0x11c38, 0x11c50, 0x11c70, 0x11c92, 0x11ca9, 0x11d00, 0x11d08, + 0x11d0b, 0x11d3a, 0x11d3c, 0x11d3f, 0x11d50, 0x11d60, 0x11d67, 0x11d6a, 0x11d90, 0x11d93, 0x11da0, 0x11db0, + 0x11de0, 0x11ee0, 0x11f00, 0x11f12, 0x11f3e, 0x11fb0, 0x11fc0, 0x11fff, 0x12400, 0x12470, 0x12480, 0x12f90, + 0x13000, 0x13440, 0x13460, 0x14400, 0x16100, 0x16800, 0x16a40, 0x16a60, 0x16a6e, 0x16ac0, 0x16ad0, 0x16af0, + 0x16b00, 0x16b50, 0x16b5b, 0x16b63, 0x16b7d, 0x16d40, 0x16e40, 0x16ea0, 0x16ebb, 0x16f00, 0x16f4f, 0x16f8f, + 0x16fe0, 0x16ff0, 0x17000, 0x18cff, 0x18d80, 0x1aff0, 0x1aff5, 0x1affd, 0x1b000, 0x1b132, 0x1b150, 0x1b155, + 0x1b164, 0x1b170, 0x1bc00, 0x1bc70, 0x1bc80, 0x1bc90, 0x1bc9c, 0x1cc00, 0x1cd00, 0x1ceba, 0x1cee0, 0x1cf00, + 0x1cf30, 0x1cf50, 0x1d000, 0x1d100, 0x1d129, 0x1d17b, 0x1d200, 0x1d2c0, 0x1d2e0, 0x1d300, 0x1d360, 0x1d400, + 0x1d456, 0x1d49e, 0x1d4a2, 0x1d4a5, 0x1d4a9, 0x1d4ae, 0x1d4bb, 0x1d4bd, 0x1d4c5, 0x1d507, 0x1d50d, 0x1d516, + 0x1d51e, 0x1d53b, 0x1d540, 0x1d546, 0x1d54a, 0x1d552, 0x1d6a8, 0x1d7ce, 0x1da9b, 0x1daa1, 0x1df00, 0x1df25, + 0x1e000, 0x1e008, 0x1e01b, 0x1e023, 0x1e026, 0x1e030, 0x1e08f, 0x1e100, 0x1e130, 0x1e140, 0x1e14e, 0x1e290, + 0x1e2c0, 0x1e2ff, 0x1e4d0, 0x1e5d0, 0x1e5ff, 0x1e6c0, 0x1e6e0, 0x1e6fe, 0x1e7e0, 0x1e7e8, 0x1e7ed, 0x1e7f0, + 0x1e800, 0x1e8c7, 0x1e900, 0x1e950, 0x1e95e, 0x1ec71, 0x1ed01, 0x1ee00, 0x1ee05, 0x1ee21, 0x1ee24, 0x1ee27, + 0x1ee29, 0x1ee34, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee4d, 0x1ee51, 0x1ee54, 0x1ee57, + 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee64, 0x1ee67, 0x1ee6c, 0x1ee74, 0x1ee79, 0x1ee7e, 0x1ee80, + 0x1ee8b, 0x1eea1, 0x1eea5, 0x1eeab, 0x1eef0, 0x1f000, 0x1f030, 0x1f0a0, 0x1f0b1, 0x1f0c1, 0x1f0d1, 0x1f100, + 0x1f1e6, 0x1f210, 0x1f240, 0x1f250, 0x1f260, 0x1f300, 0x1f6dc, 0x1f6f0, 0x1f700, 0x1f7e0, 0x1f7f0, 0x1f800, + 0x1f810, 0x1f850, 0x1f860, 0x1f890, 0x1f8b0, 0x1f8c0, 0x1f8d0, 0x1f900, 0x1fa60, 0x1fa70, 0x1fa80, 0x1fa8e, + 0x1fac8, 0x1facd, 0x1fadf, 0x1faef, 0x1fb00, 0x1fb94, 0x20000, 0x2a700, 0x2b820, 0x2ceb0, 0x2ebf0, 0x2f800, + 0x30000, 0x31350, 0xe0100}, + {0x5f, 0xc, 0x2ca, 0x6, 0x7, 0x1, 0x14, 0x18d, 0x26, 0x32, 0x3, 0x37, 0x1b, 0x6, 0x16, 0xc0, 0x30, 0x3b, 0x65, 0x3b, + 0x31, 0xf, 0x1c, 0x1, 0xb, 0x20, 0x4b, 0xa1, 0x8, 0x2, 0x16, 0x7, 0x1, 0x4, 0x9, 0x2, 0x4, 0x1, 0x2, 0x5, 0x19, + 0x3, 0x6, 0x2, 0x16, 0x7, 0x2, 0x2, 0x2, 0x1, 0x5, 0x2, 0x3, 0x1, 0x4, 0x1, 0x11, 0x3, 0x9, 0x3, 0x16, 0x7, 0x2, + 0x5, 0xa, 0x3, 0x3, 0x1, 0x4, 0xc, 0x7, 0x3, 0x8, 0x2, 0x16, 0x7, 0x2, 0x5, 0x9, 0x2, 0x3, 0x3, 0x2, 0x5, 0x12, + 0x2, 0x6, 0x3, 0x4, 0x2, 0x1, 0x2, 0x2, 0x3, 0xc, 0x5, 0x3, 0x4, 0x1, 0x1, 0x15, 0xd, 0x3, 0x17, 0x10, 0x9, 0x3, + 0x4, 0x2, 0x3, 0x2, 0x4, 0xa, 0x16, 0x3, 0x17, 0xa, 0x5, 0x9, 0x3, 0x4, 0x2, 0x3, 0x4, 0xa, 0x3, 0xd, 0x3, 0x33, + 0x3, 0x6, 0x10, 0x1a, 0x3, 0x12, 0x18, 0x9, 0x1, 0x7, 0x1, 0x6, 0x1, 0x8, 0xa, 0x3, 0x3a, 0x1d, 0x2, 0x1, 0x5, + 0x18, 0x1, 0x17, 0x5, 0x1, 0x7, 0xa, 0x4, 0x48, 0x24, 0x27, 0x24, 0xf, 0xd, 0xc6, 0x1, 0x1, 0x179, 0x4, 0x7, + 0x1, 0x4, 0x29, 0x4, 0x21, 0x4, 0x7, 0x1, 0x4, 0xf, 0x39, 0x4, 0x43, 0x20, 0x1a, 0x56, 0x6, 0x280, 0x1c, 0x59, + 0x16, 0x18, 0x14, 0xd, 0x3, 0x2, 0x5e, 0xa, 0xa, 0xe, 0xb, 0x59, 0x2b, 0x46, 0x1f, 0xc, 0xc, 0x1, 0x2a, 0x5, + 0x2c, 0x1a, 0xb, 0x3e, 0x41, 0x1d, 0xb, 0xa, 0xe, 0x2e, 0xc, 0x4d, 0xa6, 0x3c, 0xf, 0x3e, 0x2b, 0xb, 0x2b, + 0x216, 0x6, 0x26, 0x6, 0x8, 0x1, 0x1, 0x1, 0x1f, 0x35, 0xf, 0xe, 0x6, 0x13, 0x3, 0x9, 0x18, 0x2f, 0x2, 0x1b, + 0xd, 0x22, 0x21, 0x8c, 0x29a, 0xb, 0x714, 0x17e, 0x2d, 0x1, 0x1, 0x38, 0x2, 0x18, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, + 0x7, 0x7, 0x7e, 0x1a, 0x59, 0xd6, 0x10, 0x3f, 0x56, 0x67, 0x2b, 0x5e, 0x56, 0x30, 0x726d, 0x37, 0x15c, 0xb8, + 0xdd, 0x3c, 0xa, 0x38, 0x46, 0xc, 0x74, 0x1e, 0x4e, 0xb, 0x21, 0x37, 0xe, 0xa, 0x67, 0x1c, 0x6, 0x6, 0x6, 0x7, + 0x7, 0x3c, 0x7e, 0xa, 0x2ba4, 0x17, 0x31, 0x16e, 0x6a, 0x7, 0x5, 0x1a, 0x5, 0x1, 0x2, 0x2, 0x28a, 0x2a, 0x33, + 0x13, 0x4, 0x5, 0x87, 0xbe, 0x6, 0x6, 0x6, 0x3, 0x7, 0x7, 0x2, 0xc, 0x1a, 0x13, 0x2, 0xf, 0xe, 0x7b, 0x3, 0x2d, + 0x58, 0xd, 0x1, 0x2e, 0x1d, 0x31, 0x1c, 0x24, 0x1e, 0x2b, 0x1e, 0x25, 0xe, 0x9e, 0xa, 0x24, 0x24, 0x28, 0x34, + 0xc, 0xf, 0x7, 0x2, 0xb, 0xf, 0x7, 0x2, 0x34, 0x137, 0x16, 0x8, 0x6, 0x2a, 0x9, 0x6, 0x1, 0x2c, 0x2, 0x1, 0x17, + 0x48, 0x9, 0x13, 0x2, 0x21, 0x1b, 0x1b, 0x38, 0x14, 0x32, 0x2, 0x8, 0x3, 0x1d, 0x3, 0xa, 0x9, 0x40, 0x27, 0xc, + 0x36, 0x1d, 0x1b, 0x1a, 0x4, 0x7, 0x49, 0x33, 0x33, 0x2e, 0xa, 0x26, 0x1d, 0x2, 0x1f, 0x2a, 0x3, 0x2, 0x6, 0x9, + 0x2e, 0x2a, 0x1a, 0x1c, 0x17, 0x4e, 0x24, 0x3e, 0x5, 0x19, 0xa, 0x35, 0x12, 0x27, 0x60, 0x14, 0x12, 0x2f, 0x7, + 0x1, 0x4, 0xf, 0xb, 0x3b, 0xa, 0x4, 0x8, 0x2, 0x16, 0x7, 0x2, 0x5, 0xa, 0x2, 0x3, 0x1, 0x1, 0x7, 0x7, 0x5, 0xa, + 0x1, 0x1, 0x26, 0xa, 0x1, 0x1, 0x4, 0xa, 0x2, 0x2, 0x5c, 0x5, 0x48, 0xa, 0x36, 0x26, 0x45, 0xa, 0xd, 0x3a, 0xa, + 0x14, 0x1b, 0xf, 0x17, 0x3c, 0x53, 0x8, 0x1, 0x8, 0x2, 0x1e, 0x2, 0xc, 0xa, 0x8, 0x2e, 0xb, 0x48, 0x53, 0x49, + 0xa, 0x8, 0x22, 0xa, 0x9, 0x2d, 0xe, 0x1d, 0x20, 0x16, 0xe, 0x7, 0x2, 0x2c, 0x1, 0x2, 0x9, 0xa, 0x6, 0x2, 0x25, + 0x2, 0x6, 0xa, 0x2c, 0xa, 0x19, 0x11, 0x29, 0x1d, 0x1, 0x32, 0x39b, 0x6f, 0x5, 0xc4, 0x63, 0x430, 0x16, 0xf9b, + 0x247, 0x3a, 0x239, 0x1f, 0xa, 0x51, 0xa, 0x1e, 0x6, 0x46, 0xa, 0x7, 0x15, 0x13, 0x3a, 0x5b, 0x19, 0x19, 0x4b, + 0x39, 0x11, 0x5, 0x7, 0x1cd6, 0x20, 0x73, 0x4, 0x7, 0x2, 0x123, 0x1, 0x3, 0x1, 0x4, 0x18c, 0x6b, 0xd, 0x9, 0xa, + 0x4, 0xfd, 0x1b4, 0x17, 0x11, 0x2e, 0x17, 0x74, 0xf6, 0x27, 0x4a, 0x70, 0x46, 0x14, 0x14, 0x57, 0x19, 0x55, + 0x47, 0x2, 0x1, 0x2, 0x4, 0xc, 0x1, 0x7, 0x41, 0x4, 0x8, 0x7, 0x1c, 0x4, 0x5, 0x1, 0x7, 0x154, 0x124, 0x2be, + 0x5, 0xf, 0x1f, 0x6, 0x7, 0x11, 0x7, 0x2, 0x5, 0x3e, 0x1, 0x2d, 0xe, 0xa, 0x2, 0x1f, 0x3a, 0x1, 0x2a, 0x2b, 0x1, + 0x1f, 0x16, 0x2, 0x7, 0x4, 0x2, 0xf, 0xc5, 0x10, 0x4c, 0xa, 0x2, 0x44, 0x3d, 0x4, 0x1b, 0x2, 0x1, 0x1, 0xa, 0x4, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x4, 0x7, 0x4, 0x4, 0x1, 0xa, + 0x11, 0x3, 0x5, 0x11, 0x2, 0x2c, 0x64, 0xf, 0xf, 0xf, 0x25, 0xae, 0x1d, 0x2c, 0x9, 0x2, 0x6, 0x3d9, 0x11, 0xd, + 0xda, 0xc, 0x1, 0xc, 0x38, 0xa, 0x28, 0x1e, 0xc, 0x2, 0x9, 0x158, 0xe, 0xd, 0xb, 0x39, 0x1, 0x10, 0xc, 0xa, + 0x93, 0x67, 0xa6e0, 0x111e, 0x168e, 0x1d31, 0x26e, 0x21e, 0x134b, 0x212a, 0xf0}}; + +// DerivedCoreProperties-17.0.0.txt +// Date: 2025-07-30, 23:55:08 GMT +enum class _Grapheme_Extend_property_values : uint8_t { _Grapheme_Extend_value, _No_value = 255 }; + +// DerivedCoreProperties-17.0.0.txt +// Date: 2025-07-30, 23:55:08 GMT +inline constexpr _Unicode_property_data<_Grapheme_Extend_property_values, 383, true> _Grapheme_Extend_property_data{ + {0x300, 0x483, 0x591, 0x5bf, 0x5c1, 0x5c4, 0x5c7, 0x610, 0x64b, 0x670, 0x6d6, 0x6df, 0x6e7, 0x6ea, 0x711, 0x730, + 0x7a6, 0x7eb, 0x7fd, 0x816, 0x81b, 0x825, 0x829, 0x859, 0x897, 0x8ca, 0x8e3, 0x93a, 0x93c, 0x941, 0x94d, 0x951, + 0x962, 0x981, 0x9bc, 0x9be, 0x9c1, 0x9cd, 0x9d7, 0x9e2, 0x9fe, 0xa01, 0xa3c, 0xa41, 0xa47, 0xa4b, 0xa51, 0xa70, + 0xa75, 0xa81, 0xabc, 0xac1, 0xac7, 0xacd, 0xae2, 0xafa, 0xb01, 0xb3c, 0xb3e, 0xb41, 0xb4d, 0xb55, 0xb62, 0xb82, + 0xbbe, 0xbc0, 0xbcd, 0xbd7, 0xc00, 0xc04, 0xc3c, 0xc3e, 0xc46, 0xc4a, 0xc55, 0xc62, 0xc81, 0xcbc, 0xcbf, 0xcc2, + 0xcc6, 0xcca, 0xcd5, 0xce2, 0xd00, 0xd3b, 0xd3e, 0xd41, 0xd4d, 0xd57, 0xd62, 0xd81, 0xdca, 0xdcf, 0xdd2, 0xdd6, + 0xddf, 0xe31, 0xe34, 0xe47, 0xeb1, 0xeb4, 0xec8, 0xf18, 0xf35, 0xf37, 0xf39, 0xf71, 0xf80, 0xf86, 0xf8d, 0xf99, + 0xfc6, 0x102d, 0x1032, 0x1039, 0x103d, 0x1058, 0x105e, 0x1071, 0x1082, 0x1085, 0x108d, 0x109d, 0x135d, 0x1712, + 0x1732, 0x1752, 0x1772, 0x17b4, 0x17b7, 0x17c6, 0x17c9, 0x17dd, 0x180b, 0x180f, 0x1885, 0x18a9, 0x1920, 0x1927, + 0x1932, 0x1939, 0x1a17, 0x1a1b, 0x1a56, 0x1a58, 0x1a60, 0x1a62, 0x1a65, 0x1a73, 0x1a7f, 0x1ab0, 0x1ae0, 0x1b00, + 0x1b34, 0x1b42, 0x1b6b, 0x1b80, 0x1ba2, 0x1ba8, 0x1be6, 0x1be8, 0x1bed, 0x1bef, 0x1c2c, 0x1c36, 0x1cd0, 0x1cd4, + 0x1ce2, 0x1ced, 0x1cf4, 0x1cf8, 0x1dc0, 0x200c, 0x20d0, 0x2cef, 0x2d7f, 0x2de0, 0x302a, 0x3099, 0xa66f, 0xa674, + 0xa69e, 0xa6f0, 0xa802, 0xa806, 0xa80b, 0xa825, 0xa82c, 0xa8c4, 0xa8e0, 0xa8ff, 0xa926, 0xa947, 0xa953, 0xa980, + 0xa9b3, 0xa9b6, 0xa9bc, 0xa9c0, 0xa9e5, 0xaa29, 0xaa31, 0xaa35, 0xaa43, 0xaa4c, 0xaa7c, 0xaab0, 0xaab2, 0xaab7, + 0xaabe, 0xaac1, 0xaaec, 0xaaf6, 0xabe5, 0xabe8, 0xabed, 0xfb1e, 0xfe00, 0xfe20, 0xff9e, 0x101fd, 0x102e0, + 0x10376, 0x10a01, 0x10a05, 0x10a0c, 0x10a38, 0x10a3f, 0x10ae5, 0x10d24, 0x10d69, 0x10eab, 0x10efa, 0x10f46, + 0x10f82, 0x11001, 0x11038, 0x11070, 0x11073, 0x1107f, 0x110b3, 0x110b9, 0x110c2, 0x11100, 0x11127, 0x1112d, + 0x11173, 0x11180, 0x111b6, 0x111c0, 0x111c9, 0x111cf, 0x1122f, 0x11234, 0x1123e, 0x11241, 0x112df, 0x112e3, + 0x11300, 0x1133b, 0x1133e, 0x11340, 0x1134d, 0x11357, 0x11366, 0x11370, 0x113b8, 0x113bb, 0x113c2, 0x113c5, + 0x113c7, 0x113ce, 0x113d2, 0x113e1, 0x11438, 0x11442, 0x11446, 0x1145e, 0x114b0, 0x114b3, 0x114ba, 0x114bd, + 0x114bf, 0x114c2, 0x115af, 0x115b2, 0x115bc, 0x115bf, 0x115dc, 0x11633, 0x1163d, 0x1163f, 0x116ab, 0x116ad, + 0x116b0, 0x1171d, 0x1171f, 0x11722, 0x11727, 0x1182f, 0x11839, 0x11930, 0x1193b, 0x11943, 0x119d4, 0x119da, + 0x119e0, 0x11a01, 0x11a33, 0x11a3b, 0x11a47, 0x11a51, 0x11a59, 0x11a8a, 0x11a98, 0x11b60, 0x11b62, 0x11b66, + 0x11c30, 0x11c38, 0x11c3f, 0x11c92, 0x11caa, 0x11cb2, 0x11cb5, 0x11d31, 0x11d3a, 0x11d3c, 0x11d3f, 0x11d47, + 0x11d90, 0x11d95, 0x11d97, 0x11ef3, 0x11f00, 0x11f36, 0x11f40, 0x11f5a, 0x13440, 0x13447, 0x1611e, 0x1612d, + 0x16af0, 0x16b30, 0x16f4f, 0x16f8f, 0x16fe4, 0x16ff0, 0x1bc9d, 0x1cf00, 0x1cf30, 0x1d165, 0x1d16d, 0x1d17b, + 0x1d185, 0x1d1aa, 0x1d242, 0x1da00, 0x1da3b, 0x1da75, 0x1da84, 0x1da9b, 0x1daa1, 0x1e000, 0x1e008, 0x1e01b, + 0x1e023, 0x1e026, 0x1e08f, 0x1e130, 0x1e2ae, 0x1e2ec, 0x1e4ec, 0x1e5ee, 0x1e6e3, 0x1e6e6, 0x1e6ee, 0x1e6f5, + 0x1e8d0, 0x1e944, 0xe0020, 0xe0100}, + {0x70, 0x7, 0x2d, 0x1, 0x2, 0x2, 0x1, 0xb, 0x15, 0x1, 0x7, 0x6, 0x2, 0x4, 0x1, 0x1b, 0xb, 0x9, 0x1, 0x4, 0x9, 0x3, + 0x5, 0x3, 0x9, 0x18, 0x20, 0x1, 0x1, 0x8, 0x1, 0x7, 0x2, 0x1, 0x1, 0x1, 0x4, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, + 0x2, 0x3, 0x1, 0x2, 0x1, 0x2, 0x1, 0x5, 0x2, 0x1, 0x2, 0x6, 0x1, 0x1, 0x2, 0x4, 0x1, 0x3, 0x2, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0x1, 0x1, 0x3, 0x3, 0x4, 0x2, 0x2, 0x1, 0x1, 0x2, 0x1, 0x3, 0x4, 0x2, 0x2, 0x2, 0x2, 0x1, 0x4, + 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x3, 0x1, 0x1, 0x1, 0x7, 0x8, 0x1, 0x9, 0x7, 0x2, 0x1, 0x1, 0x1, 0xe, 0x5, 0x2, + 0xb, 0x24, 0x1, 0x4, 0x6, 0x2, 0x2, 0x2, 0x3, 0x4, 0x1, 0x2, 0x1, 0x1, 0x3, 0x4, 0x3, 0x2, 0x2, 0x2, 0x7, 0x1, + 0xb, 0x1, 0x3, 0x1, 0x2, 0x1, 0x3, 0x2, 0x1, 0x3, 0x2, 0x1, 0x1, 0x7, 0x1, 0x1, 0x8, 0xa, 0x1, 0x2e, 0xc, 0x4, + 0xa, 0x3, 0x9, 0x2, 0x4, 0x6, 0x1, 0x2, 0x1, 0x5, 0x8, 0x2, 0x3, 0xd, 0x7, 0x1, 0x1, 0x2, 0x40, 0x1, 0x21, 0x3, + 0x1, 0x20, 0x6, 0x2, 0x4, 0xa, 0x2, 0x2, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x12, 0x1, 0x8, 0xb, 0x1, 0x3, 0x1, 0x4, + 0x2, 0x1, 0x1, 0x6, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x3, 0x2, 0x2, 0x1, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x10, 0x10, + 0x2, 0x1, 0x1, 0x5, 0x3, 0x2, 0x4, 0x3, 0x1, 0x2, 0x4, 0x5, 0x2, 0x6, 0xb, 0x4, 0x1, 0xf, 0x1, 0x2, 0x3, 0x4, + 0x2, 0x1, 0x3, 0x5, 0x8, 0x1, 0x2, 0x9, 0x1, 0x4, 0x1, 0x3, 0x4, 0x1, 0x1, 0x1, 0x8, 0x2, 0x2, 0x1, 0x1, 0x1, + 0x1, 0x7, 0x5, 0x1, 0x6, 0x1, 0x1, 0x3, 0x3, 0x1, 0x2, 0x8, 0x3, 0x1, 0x1, 0x1, 0x6, 0x1, 0x1, 0x2, 0x2, 0x1, + 0x4, 0x2, 0x2, 0x2, 0x8, 0x1, 0x2, 0x1, 0x1, 0x8, 0x1, 0x1, 0x4, 0x5, 0x9, 0x2, 0x1, 0x4, 0x1, 0x4, 0x2, 0x1, + 0xa, 0x6, 0x4, 0x1, 0x6, 0x3, 0xd, 0x2, 0x1, 0x3, 0x1, 0x7, 0x6, 0x1, 0x16, 0x7, 0x2, 0x2, 0x6, 0x1, 0x2, 0x7, + 0x1, 0x2, 0x1, 0x1, 0x2, 0x2, 0x5, 0x3, 0x1, 0x1, 0xf, 0xc, 0x3, 0x5, 0x7, 0x1, 0x4, 0x1, 0x2, 0x2, 0x2e, 0x17, + 0x5, 0x6, 0x8, 0x7, 0x4, 0x3, 0x37, 0x32, 0x1, 0x1, 0x5, 0xf, 0x7, 0x11, 0x7, 0x2, 0x5, 0x1, 0x7, 0x1, 0x4, 0x4, + 0x2, 0x1, 0x1, 0x2, 0x1, 0x7, 0x7, 0x60, 0xf0}}; + +// EastAsianWidth-17.0.0.txt +// Date: 2025-07-24, 00:12:54 GMT +inline constexpr char32_t _Width_estimate_intervals_v2[] = {0x1100, 0x1160, 0x231a, 0x231c, 0x2329, 0x232b, 0x23e9, + 0x23ed, 0x23f0, 0x23f1, 0x23f3, 0x23f4, 0x25fd, 0x25ff, 0x2614, 0x2616, 0x2630, 0x2638, 0x2648, 0x2654, 0x267f, + 0x2680, 0x268a, 0x2690, 0x2693, 0x2694, 0x26a1, 0x26a2, 0x26aa, 0x26ac, 0x26bd, 0x26bf, 0x26c4, 0x26c6, 0x26ce, + 0x26cf, 0x26d4, 0x26d5, 0x26ea, 0x26eb, 0x26f2, 0x26f4, 0x26f5, 0x26f6, 0x26fa, 0x26fb, 0x26fd, 0x26fe, 0x2705, + 0x2706, 0x270a, 0x270c, 0x2728, 0x2729, 0x274c, 0x274d, 0x274e, 0x274f, 0x2753, 0x2756, 0x2757, 0x2758, 0x2795, + 0x2798, 0x27b0, 0x27b1, 0x27bf, 0x27c0, 0x2b1b, 0x2b1d, 0x2b50, 0x2b51, 0x2b55, 0x2b56, 0x2e80, 0x2e9a, 0x2e9b, + 0x2ef4, 0x2f00, 0x2fd6, 0x2ff0, 0x303f, 0x3041, 0x3097, 0x3099, 0x3100, 0x3105, 0x3130, 0x3131, 0x318f, 0x3190, + 0x31e6, 0x31ef, 0x321f, 0x3220, 0x3248, 0x3250, 0xa48d, 0xa490, 0xa4c7, 0xa960, 0xa97d, 0xac00, 0xd7a4, 0xf900, + 0xfb00, 0xfe10, 0xfe1a, 0xfe30, 0xfe53, 0xfe54, 0xfe67, 0xfe68, 0xfe6c, 0xff01, 0xff61, 0xffe0, 0xffe7, 0x16fe0, + 0x16fe5, 0x16ff0, 0x16ff7, 0x17000, 0x18cd6, 0x18cff, 0x18d1f, 0x18d80, 0x18df3, 0x1aff0, 0x1aff4, 0x1aff5, 0x1affc, + 0x1affd, 0x1afff, 0x1b000, 0x1b123, 0x1b132, 0x1b133, 0x1b150, 0x1b153, 0x1b155, 0x1b156, 0x1b164, 0x1b168, 0x1b170, + 0x1b2fc, 0x1d300, 0x1d357, 0x1d360, 0x1d377, 0x1f004, 0x1f005, 0x1f0cf, 0x1f0d0, 0x1f18e, 0x1f18f, 0x1f191, 0x1f19b, + 0x1f200, 0x1f203, 0x1f210, 0x1f23c, 0x1f240, 0x1f249, 0x1f250, 0x1f252, 0x1f260, 0x1f266, 0x1f300, 0x1f650, 0x1f680, + 0x1f6c6, 0x1f6cc, 0x1f6cd, 0x1f6d0, 0x1f6d3, 0x1f6d5, 0x1f6d9, 0x1f6dc, 0x1f6e0, 0x1f6eb, 0x1f6ed, 0x1f6f4, 0x1f6fd, + 0x1f7e0, 0x1f7ec, 0x1f7f0, 0x1f7f1, 0x1f900, 0x1fa00, 0x1fa70, 0x1fa7d, 0x1fa80, 0x1fa8b, 0x1fa8e, 0x1fac7, 0x1fac8, + 0x1fac9, 0x1facd, 0x1fadd, 0x1fadf, 0x1faeb, 0x1faef, 0x1faf9, 0x20000, 0x2fffe, 0x30000, 0x3fffe}; + +_STD_END + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) + +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_FORMAT_UCD_TABLES_HPP diff --git a/msvc-stl/stl/inc/__msvc_formatter.hpp b/msvc-stl/stl/inc/__msvc_formatter.hpp new file mode 100644 index 0000000..e61fb08 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_formatter.hpp @@ -0,0 +1,438 @@ +// __msvc_formatter.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// NOTE: +// The contents of this header are derived in part from libfmt under the following license: + +// Copyright (c) 2012 - present, Victor Zverovich +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +// --- Optional exception to the license --- +// +// As an exception, if, as a result of your compiling your source code, portions +// of this Software are embedded into a machine-executable object form of such +// source code, you may redistribute such embedded portions in such object form +// without including the above copyright and permission notices. + +#ifndef __MSVC_FORMATTER_HPP +#define __MSVC_FORMATTER_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#if !_HAS_CXX20 +#error The contents of are only available with C++20. (Also, you should not include this internal header.) +#endif // !_HAS_CXX20 + +#include +#include +#include +#include + +#if _HAS_CXX23 +#include +#endif // _HAS_CXX23 + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +// TRANSITION, non-_Ugly attribute tokens +#pragma push_macro("msvc") +#pragma push_macro("no_specializations") +#undef msvc +#undef no_specializations + +_STD_BEGIN +#if _HAS_CXX23 +#define _FMT_P2286_BEGIN inline namespace __p2286 { +#define _FMT_P2286_END } +#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv +#define _FMT_P2286_BEGIN +#define _FMT_P2286_END +#endif // ^^^ !_HAS_CXX23 ^^^ + +enum class _Fmt_align : uint8_t { _None, _Left, _Right, _Center }; + +enum class _Fmt_sign : uint8_t { _None, _Plus, _Minus, _Space }; + +enum class _Basic_format_arg_type : uint8_t { + _None, + _Int_type, + _UInt_type, + _Long_long_type, + _ULong_long_type, + _Bool_type, + _Char_type, + _Float_type, + _Double_type, + _Long_double_type, + _Pointer_type, + _CString_type, + _String_type, + _Custom_type, +}; +static_assert(static_cast(_Basic_format_arg_type::_Custom_type) < 16, "must fit in 4-bit bitfield"); + +#if _HAS_CXX23 +_EXPORT_STD template // specializations allowed by N5014 [format.formatter.locking]/1 +constexpr bool enable_nonlocking_formatter_optimization = false; + +_NODISCARD consteval bool _Is_debug_enabled_fmt_type(_Basic_format_arg_type _Ty) { + return _Ty == _Basic_format_arg_type::_Char_type || _Ty == _Basic_format_arg_type::_CString_type + || _Ty == _Basic_format_arg_type::_String_type; +} +#endif // _HAS_CXX23 + +template +struct _Basic_format_specs { + int _Width = 0; + int _Precision = -1; + char _Type = '\0'; + _Fmt_align _Alignment = _Fmt_align::_None; + _Fmt_sign _Sgn = _Fmt_sign::_None; + bool _Alt = false; + bool _Localized = false; + bool _Leading_zero = false; + uint8_t _Fill_length = 1; + // At most one codepoint (so one char32_t or four utf-8 char8_t). + _CharT _Fill[4 / sizeof(_CharT)] = {_CharT{' '}}; +}; + +// Adds width and precision references to _Basic_format_specs. +// This is required for std::formatter implementations because we must +// parse the format specs without having access to the format args (via a format context). +template +struct _Dynamic_format_specs : _Basic_format_specs<_CharT> { + int _Dynamic_width_index = -1; + int _Dynamic_precision_index = -1; +}; + +[[noreturn]] inline void _Throw_format_error(const char* _Message); + +_EXPORT_STD template +class _NO_SPECIALIZATIONS_CITING("N5014 [format.parse.ctx]/2") basic_format_parse_context; + +template +concept _Format_supported_charT = _Is_any_of_v<_CharT, char, wchar_t>; + +_EXPORT_STD template +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +_FMT_P2286_BEGIN +template +struct _Formatter_base { +public: +#if _HAS_CXX23 + constexpr void _Set_debug_format() noexcept + requires (_Is_debug_enabled_fmt_type(_ArgType)) + { + _Specs._Type = '?'; + } +#endif // _HAS_CXX23 + + template > + constexpr _ParseContext::iterator parse(type_identity_t<_ParseContext&> _Parse_ctx); // defined in + + template + _FormatContext::iterator format(const _Ty& _Val, _FormatContext& _Format_ctx) const; // defined in + +private: + _Dynamic_format_specs<_CharT> _Specs; +}; +_FMT_P2286_END + +#if _HAS_CXX23 +#define _FORMAT_SPECIALIZE_NONLOCKING_FOR(_Type) \ + template <> \ + inline constexpr bool enable_nonlocking_formatter_optimization<_Type> = true; +#else // ^^^ _HAS_CXX23 / !_HAS_CXX23 vvv +#define _FORMAT_SPECIALIZE_NONLOCKING_FOR(_Type) +#endif // ^^^ !_HAS_CXX23 ^^^ + +#define _FORMAT_SPECIALIZE_FOR(_Type, _ArgType) \ + _FORMAT_SPECIALIZE_NONLOCKING_FOR(_Type) \ + template <_Format_supported_charT _CharT> \ + struct formatter<_Type, _CharT> : _Formatter_base<_Type, _CharT, _ArgType> {} + +_FORMAT_SPECIALIZE_FOR(int, _Basic_format_arg_type::_Int_type); +_FORMAT_SPECIALIZE_FOR(unsigned int, _Basic_format_arg_type::_UInt_type); +_FORMAT_SPECIALIZE_FOR(long long, _Basic_format_arg_type::_Long_long_type); +_FORMAT_SPECIALIZE_FOR(unsigned long long, _Basic_format_arg_type::_ULong_long_type); +_FORMAT_SPECIALIZE_FOR(bool, _Basic_format_arg_type::_Bool_type); +_FORMAT_SPECIALIZE_FOR(float, _Basic_format_arg_type::_Float_type); +_FORMAT_SPECIALIZE_FOR(double, _Basic_format_arg_type::_Double_type); +_FORMAT_SPECIALIZE_FOR(long double, _Basic_format_arg_type::_Long_double_type); +_FORMAT_SPECIALIZE_FOR(nullptr_t, _Basic_format_arg_type::_Pointer_type); +_FORMAT_SPECIALIZE_FOR(void*, _Basic_format_arg_type::_Pointer_type); +_FORMAT_SPECIALIZE_FOR(const void*, _Basic_format_arg_type::_Pointer_type); +_FORMAT_SPECIALIZE_FOR(short, _Basic_format_arg_type::_Int_type); +_FORMAT_SPECIALIZE_FOR(unsigned short, _Basic_format_arg_type::_UInt_type); +_FORMAT_SPECIALIZE_FOR(long, _Basic_format_arg_type::_Int_type); +_FORMAT_SPECIALIZE_FOR(unsigned long, _Basic_format_arg_type::_UInt_type); +_FORMAT_SPECIALIZE_FOR(signed char, _Basic_format_arg_type::_Int_type); +_FORMAT_SPECIALIZE_FOR(unsigned char, _Basic_format_arg_type::_UInt_type); + +#undef _FORMAT_SPECIALIZE_FOR +#undef _FORMAT_SPECIALIZE_NONLOCKING_FOR + +// not using the macro because we'd like to add 'set_debug_format' member function in C++23 mode +template <_Format_supported_charT _CharT> +struct formatter : _Formatter_base { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +// not using the macro because we'd like to avoid the formatter specialization +template <> +struct formatter : _Formatter_base { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + _Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +// We could use the macro for these specializations, but it's confusing to refer to symbols that are defined +// inside the macro in the macro's "call". +template <_Format_supported_charT _CharT> +struct formatter<_CharT*, _CharT> : _Formatter_base<_CharT*, _CharT, _Basic_format_arg_type::_CString_type> { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +template <_Format_supported_charT _CharT> +struct formatter + : _Formatter_base { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +template <_Format_supported_charT _CharT, size_t _Nx> +struct formatter<_CharT[_Nx], _CharT> : _Formatter_base<_CharT[_Nx], _CharT, _Basic_format_arg_type::_CString_type> { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +_EXPORT_STD template +class basic_string; + +_EXPORT_STD template +class basic_string_view; + +template <_Format_supported_charT _CharT, class _Traits, class _Allocator> +struct formatter, _CharT> + : _Formatter_base, _CharT, _Basic_format_arg_type::_String_type> { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +template <_Format_supported_charT _CharT, class _Traits> +struct formatter, _CharT> + : _Formatter_base, _CharT, _Basic_format_arg_type::_String_type> { +#if _HAS_CXX23 + constexpr void set_debug_format() noexcept { + this->_Set_debug_format(); + } +#endif // _HAS_CXX23 +}; + +#if _HAS_CXX23 +template <> +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template <> +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter, wchar_t> { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +template +struct formatter, wchar_t> { + formatter() = delete; + formatter(const formatter&) = delete; + formatter& operator=(const formatter&) = delete; +}; + +_EXPORT_STD enum class range_format { disabled, map, set, sequence, string, debug_string }; + +template +struct _Invalid_format_kind { + static_assert(false, "A program that instantiates the primary template of format_kind is ill-formed. " + "(N4981 [format.range.fmtkind]/1)"); +}; + +_EXPORT_STD template +constexpr _Invalid_format_kind<_Ty> format_kind; // specializations allowed by N5014 [format.range.fmtkind]/3 + +template +constexpr bool _Is_two_tuple = false; + +template +constexpr bool _Is_two_tuple> = true; + +template +constexpr bool _Is_two_tuple> = true; + +template <_RANGES input_range _Rng> + requires same_as<_Rng, remove_cvref_t<_Rng>> +constexpr range_format format_kind<_Rng> = []() consteval { + using _Ref_value_t = remove_cvref_t<_RANGES range_reference_t<_Rng>>; + if constexpr (same_as<_Ref_value_t, _Rng>) { + return range_format::disabled; + } else if constexpr (requires { typename _Rng::key_type; }) { + if constexpr (requires { typename _Rng::mapped_type; } && _Is_two_tuple<_Ref_value_t>) { + return range_format::map; + } else { + return range_format::set; + } + } else { + return range_format::sequence; + } +}(); + +// Specializations for pairs, tuples, and ranges are forward-declared to avoid any risk of using the disabled primary +// template. + +// Per LWG-3997, `_CharT` in library-provided `formatter` specializations is +// constrained to character types supported by `format`. + +template +concept _Formatting_enabled_range = format_kind<_Rng> != range_format::disabled; + +template <_RANGES input_range _Rng, _Format_supported_charT _CharT> + requires _Formatting_enabled_range<_Rng> +struct formatter<_Rng, _CharT>; + +template <_Format_supported_charT _CharT, class _Ty1, class _Ty2> +struct formatter, _CharT>; + +template <_Format_supported_charT _CharT, class... _Types> +struct formatter, _CharT>; + +template <_Format_supported_charT _CharT> +constexpr bool enable_nonlocking_formatter_optimization<_CharT> = true; + +template <_Format_supported_charT _CharT> +constexpr bool enable_nonlocking_formatter_optimization<_CharT*> = true; + +template <_Format_supported_charT _CharT> +constexpr bool enable_nonlocking_formatter_optimization = true; + +template <_Format_supported_charT _CharT, size_t _Nx> +constexpr bool enable_nonlocking_formatter_optimization<_CharT[_Nx]> = true; + +template <_Format_supported_charT _CharT, class _Traits, class _Allocator> +constexpr bool enable_nonlocking_formatter_optimization> = true; + +template <_Format_supported_charT _CharT, class _Traits> +constexpr bool enable_nonlocking_formatter_optimization> = true; + +template +constexpr bool enable_nonlocking_formatter_optimization> = + enable_nonlocking_formatter_optimization> + && enable_nonlocking_formatter_optimization>; + +template +constexpr bool enable_nonlocking_formatter_optimization> = + (enable_nonlocking_formatter_optimization> && ...); + +template +struct _Fill_align_and_width_specs { + int _Width = -1; + int _Dynamic_width_index = -1; + _Fmt_align _Alignment = _Fmt_align::_None; + uint8_t _Fill_length = 1; + // At most one codepoint (so one char32_t or four utf-8 char8_t). + _CharT _Fill[4 / sizeof(_CharT)]{' '}; +}; + +template +struct _Fill_align_and_width_formatter { +public: + template > // improves throughput, see GH-5003 + _NODISCARD constexpr _ParseContext::iterator _Parse( + type_identity_t<_ParseContext&> _Parse_ctx); // defined in + + template + _NODISCARD _FormatContext::iterator _Format(_FormatContext& _Format_ctx, const int _Width, + _Fmt_align _Default_align, + _Func&& _Fn) const; // defined in + +private: + _Fill_align_and_width_specs<_CharT> _Specs; +}; +#endif // _HAS_CXX23 +_STD_END + +// TRANSITION, non-_Ugly attribute tokens +#pragma pop_macro("no_specializations") +#pragma pop_macro("msvc") + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) + +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_FORMATTER_HPP diff --git a/msvc-stl/stl/inc/__msvc_heap_algorithms.hpp b/msvc-stl/stl/inc/__msvc_heap_algorithms.hpp new file mode 100644 index 0000000..f368fc7 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_heap_algorithms.hpp @@ -0,0 +1,150 @@ +// __msvc_heap_algorithms.hpp internal header + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_HEAP_ALGORITHMS_HPP +#define __MSVC_HEAP_ALGORITHMS_HPP +#include +#if _STL_COMPILER_PREPROCESSOR + +#include + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +_STD_BEGIN +template +_CONSTEXPR20 void _Push_heap_by_index( + _RanIt _First, _Iter_diff_t<_RanIt> _Hole, _Iter_diff_t<_RanIt> _Top, _Ty&& _Val, _Pr _Pred) { + // percolate _Hole to _Top or where _Val belongs + using _Diff = _Iter_diff_t<_RanIt>; + for (_Diff _Idx = (_Hole - 1) >> 1; // shift for codegen + _Top < _Hole && _DEBUG_LT_PRED(_Pred, *(_First + _Idx), _Val); _Idx = (_Hole - 1) >> 1) { // shift for codegen + // move _Hole up to parent + *(_First + _Hole) = _STD move(*(_First + _Idx)); + _Hole = _Idx; + } + + *(_First + _Hole) = _STD forward<_Ty>(_Val); // drop _Val into final hole +} + +_EXPORT_STD template +_CONSTEXPR20 void push_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { + // push *(_Last - 1) onto heap at [_First, _Last - 1) + _STD _Adl_verify_range(_First, _Last); + const auto _UFirst = _STD _Get_unwrapped(_First); + auto _ULast = _STD _Get_unwrapped(_Last); + using _Diff = _Iter_diff_t<_RanIt>; + _Diff _Count = _ULast - _UFirst; + if (2 <= _Count) { + _Iter_value_t<_RanIt> _Val(_STD move(*--_ULast)); + _STD _Push_heap_by_index(_UFirst, --_Count, _Diff(0), _STD move(_Val), _STD _Pass_fn(_Pred)); + } +} + +_EXPORT_STD template +_CONSTEXPR20 void push_heap(_RanIt _First, _RanIt _Last) { + // push *(_Last - 1) onto heap at [_First, _Last - 1) + _STD push_heap(_First, _Last, less<>{}); +} + +template +_CONSTEXPR20 void _Pop_heap_hole_by_index( + _RanIt _First, _Iter_diff_t<_RanIt> _Hole, _Iter_diff_t<_RanIt> _Bottom, _Ty&& _Val, _Pr _Pred) { + // percolate _Hole to _Bottom, then push _Val + _STL_INTERNAL_CHECK(_Bottom > 0); + + using _Diff = _Iter_diff_t<_RanIt>; + const _Diff _Top = _Hole; + _Diff _Idx = _Hole; + + // Check whether _Idx can have a child before calculating that child's index, since + // calculating the child's index can trigger integer overflows + const _Diff _Max_sequence_non_leaf = (_Bottom - 1) >> 1; // shift for codegen + while (_Idx < _Max_sequence_non_leaf) { // move _Hole down to larger child + _Idx = 2 * _Idx + 2; + if (_DEBUG_LT_PRED(_Pred, *(_First + _Idx), *(_First + (_Idx - 1)))) { + --_Idx; + } + *(_First + _Hole) = _STD move(*(_First + _Idx)); + _Hole = _Idx; + } + + if (_Idx == _Max_sequence_non_leaf && _Bottom % 2 == 0) { // only child at bottom, move _Hole down to it + *(_First + _Hole) = _STD move(*(_First + (_Bottom - 1))); + _Hole = _Bottom - 1; + } + + _STD _Push_heap_by_index(_First, _Hole, _Top, _STD forward<_Ty>(_Val), _Pred); +} + +template +_CONSTEXPR20 void _Pop_heap_hole_unchecked(_RanIt _First, _RanIt _Last, _RanIt _Dest, _Ty&& _Val, _Pr _Pred) { + // pop *_First to *_Dest and reheap + // precondition: _First != _Last + // precondition: _First != _Dest + *_Dest = _STD move(*_First); + using _Diff = _Iter_diff_t<_RanIt>; + _STD _Pop_heap_hole_by_index( + _First, static_cast<_Diff>(0), static_cast<_Diff>(_Last - _First), _STD forward<_Ty>(_Val), _Pred); +} + +template +_CONSTEXPR20 void _Pop_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { + // pop *_First to *(_Last - 1) and reheap + if (2 <= _Last - _First) { + --_Last; + _Iter_value_t<_RanIt> _Val(_STD move(*_Last)); + _STD _Pop_heap_hole_unchecked(_First, _Last, _Last, _STD move(_Val), _Pred); + } +} + +_EXPORT_STD template +_CONSTEXPR20 void pop_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { + // pop *_First to *(_Last - 1) and reheap + _STD _Adl_verify_range(_First, _Last); + _STD _Pop_heap_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred)); +} + +_EXPORT_STD template +_CONSTEXPR20 void pop_heap(_RanIt _First, _RanIt _Last) { + // pop *_First to *(_Last - 1) and reheap + _STD pop_heap(_First, _Last, less<>{}); +} + +template +_CONSTEXPR20 void _Make_heap_unchecked(_RanIt _First, _RanIt _Last, _Pr _Pred) { + // make [_First, _Last) into a heap + using _Diff = _Iter_diff_t<_RanIt>; + _Diff _Bottom = _Last - _First; + for (_Diff _Hole = _Bottom >> 1; _Hole > 0;) { // shift for codegen + // reheap top half, bottom to top + --_Hole; + _Iter_value_t<_RanIt> _Val(_STD move(*(_First + _Hole))); + _STD _Pop_heap_hole_by_index(_First, _Hole, _Bottom, _STD move(_Val), _Pred); + } +} + +_EXPORT_STD template +_CONSTEXPR20 void make_heap(_RanIt _First, _RanIt _Last, _Pr _Pred) { // make [_First, _Last) into a heap + _STD _Adl_verify_range(_First, _Last); + _STD _Make_heap_unchecked(_STD _Get_unwrapped(_First), _STD _Get_unwrapped(_Last), _STD _Pass_fn(_Pred)); +} + +_EXPORT_STD template +_CONSTEXPR20 void make_heap(_RanIt _First, _RanIt _Last) { // make [_First, _Last) into a heap + _STD make_heap(_First, _Last, less<>{}); +} +_STD_END + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_HEAP_ALGORITHMS_HPP diff --git a/msvc-stl/stl/inc/__msvc_int128.hpp b/msvc-stl/stl/inc/__msvc_int128.hpp new file mode 100644 index 0000000..e7d9650 --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_int128.hpp @@ -0,0 +1,1605 @@ +// __msvc_int128.hpp internal header (core) + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_INT128_HPP +#define __MSVC_INT128_HPP + +#include +#if _STL_COMPILER_PREPROCESSOR +#include <__msvc_bit_utils.hpp> +#include +#include +#include + +#include _STL_INTRIN_HEADER + +#if _HAS_CXX20 +#include +#include +#define _TEMPLATE_CLASS_INTEGRAL(type) template +#define _ZERO_OR_NO_INIT +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define _TEMPLATE_CLASS_INTEGRAL(type) template , int> = 0> +#define _ZERO_OR_NO_INIT \ + { \ + } // Trivial default initialization is not allowed in constexpr functions before C++20. +#endif // ^^^ !_HAS_CXX20 ^^^ + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +_STD_BEGIN + +#if defined(_M_X64) && !defined(_M_ARM64EC) && !defined(_M_CEE_PURE) +#define _STL_128_INTRINSICS 1 +#ifdef __clang__ // clang doesn't have _udiv128 / _div128 +#define _STL_128_DIV_INTRINSICS 0 +#else // ^^^ Clang / other vvv +#define _STL_128_DIV_INTRINSICS 1 +#endif // ^^^ detect _udiv128 / _div128 ^^^ +#else // ^^^ intrinsics available / intrinsics unavailable vvv +#define _STL_128_INTRINSICS 0 +#define _STL_128_DIV_INTRINSICS 0 +#endif // ^^^ intrinsics unavailable ^^^ + +struct alignas(16) _Base128 { + uint64_t _Word[2]; + + constexpr void _Left_shift(const unsigned char _Count) noexcept { + // _STL_INTERNAL_CHECK(_Count < 128); + if (_Count == 0) { + return; + } + + if (_Count >= 64) { + _Word[1] = _Word[0] << (_Count % 64); + _Word[0] = 0; + return; + } + +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + _Word[1] = __shiftleft128(_Word[0], _Word[1], _Count); + } else +#endif // _STL_128_INTRINSICS + { + _Word[1] = (_Word[1] << _Count) | (_Word[0] >> (64 - _Count)); + } + + _Word[0] <<= _Count; + } + + constexpr void _Unsigned_right_shift(const unsigned char _Count) noexcept { + // _STL_INTERNAL_CHECK(_Count < 128); + if (_Count == 0) { + return; + } + + if (_Count >= 64) { + _Word[0] = _Word[1] >> (_Count % 64); + _Word[1] = 0; + return; + } + +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + _Word[0] = __shiftright128(_Word[0], _Word[1], _Count); + } else +#endif // _STL_128_INTRINSICS + { + _Word[0] = (_Word[0] >> _Count) | (_Word[1] << (64 - _Count)); + } + + _Word[1] >>= _Count; + } + + static constexpr unsigned char _AddCarry64( + unsigned char _Carry, uint64_t _Left, uint64_t _Right, uint64_t& _Result) noexcept { + // _STL_INTERNAL_CHECK(_Carry < 2); +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + return _addcarry_u64(_Carry, _Left, _Right, &_Result); + } +#endif // _STL_128_INTRINSICS + + const uint64_t _Sum = _Left + _Right + _Carry; + _Result = _Sum; + return _Carry ? _Sum <= _Left : _Sum < _Left; + } + + static constexpr unsigned char _SubBorrow64( + unsigned char _Carry, uint64_t _Left, uint64_t _Right, uint64_t& _Result) noexcept { + // _STL_INTERNAL_CHECK(_Carry < 2); +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + return _subborrow_u64(_Carry, _Left, _Right, &_Result); + } +#endif // _STL_128_INTRINSICS + + const auto _Difference = _Left - _Right - _Carry; + _Result = _Difference; + return _Carry ? _Difference >= _Left : _Difference > _Left; + } + + template + static constexpr void _Knuth_4_3_1_M( + const uint32_t (&__u)[__m], const uint32_t (&__v)[__n], uint32_t (&__w)[__n + __m]) noexcept { +#ifdef _ENABLE_STL_INTERNAL_CHECK + constexpr auto _Int_max = static_cast(INT_MAX); + _STL_INTERNAL_STATIC_ASSERT(__m <= _Int_max); + _STL_INTERNAL_STATIC_ASSERT(__n <= _Int_max); +#endif // defined(_ENABLE_STL_INTERNAL_CHECK) + + for (auto& _Elem : __w) { + _Elem = 0; + } + + for (int __j = 0; __j < static_cast(__n); ++__j) { + // stash Knuth's `k` in the lower 32 bits of __t + uint64_t __t = 0; + for (int __i = 0; __i < static_cast(__m); ++__i) { + __t += static_cast(__u[__i]) * __v[__j] + __w[__i + __j]; + __w[__i + __j] = static_cast(__t); + __t >>= 32; + } + __w[__j + __m] = static_cast(__t); + } + } + + _NODISCARD static constexpr uint64_t _UMul128( + const uint64_t _Left, const uint64_t _Right, uint64_t& _High_result) noexcept { +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + return _umul128(_Left, _Right, &_High_result); + } +#endif // _STL_128_INTRINSICS + + const uint32_t __u[2] = { + static_cast(_Left), + static_cast(_Left >> 32), + }; + const uint32_t __v[2] = { + static_cast(_Right), + static_cast(_Right >> 32), + }; + uint32_t __w[4] _ZERO_OR_NO_INIT; + + // multiply 2-digit numbers with 4-digit result in base 2^32 + _Knuth_4_3_1_M(__u, __v, __w); + + _High_result = (static_cast(__w[3]) << 32) | __w[2]; + return (static_cast(__w[1]) << 32) | __w[0]; + } + + static constexpr void _Knuth_4_3_1_D(uint32_t* const __u, const size_t __u_size, const uint32_t* const __v, + const size_t __v_size, uint32_t* const __q) noexcept { + // Pre: __u + [0, __u_size), __v + [0, __v_size), and __q + [0, __u_size - __v_size) are all valid ranges + // constexpr auto _Int_max = static_cast(INT_MAX); + // _STL_INTERNAL_CHECK(__v_size <= _Int_max); + const int __n = static_cast(__v_size); + // _STL_INTERNAL_CHECK(__u_size > __v_size); + // _STL_INTERNAL_CHECK(__u_size <= _Int_max); + const int __m = static_cast(__u_size - __v_size - 1); + // _STL_INTERNAL_CHECK(__v[__n - 1] >> 31 != 0); // Arguments are already normalized + + for (int __j = __m; __j >= 0; --__j) { + const auto _Two_digits = (static_cast(__u[__j + __n]) << 32) | __u[__j + __n - 1]; + auto __qhat = _Two_digits / __v[__n - 1]; + auto __rhat = _Two_digits % __v[__n - 1]; + + while ((__qhat >> 32) != 0 + || static_cast(__qhat) * static_cast(__v[__n - 2]) + > ((__rhat << 32) | __u[__j + __n - 2])) { + --__qhat; + __rhat += __v[__n - 1]; + if ((__rhat >> 32) != 0) { + break; + } + } + + int64_t __k = 0; + int64_t __t _ZERO_OR_NO_INIT; + for (int __i = 0; __i < __n; ++__i) { + const auto _Prod = static_cast(__qhat) * static_cast(__v[__i]); + __t = __u[__i + __j] - __k - static_cast(_Prod); + __u[__i + __j] = static_cast(__t); + __k = static_cast(_Prod >> 32) - (__t >> 32); + } + __t = __u[__j + __n] - __k; + __u[__j + __n] = static_cast(__t); + + __q[__j] = static_cast(__qhat); + if (__t < 0) { + --__q[__j]; + __k = 0; + for (int __i = 0; __i < __n; ++__i) { + __t = __u[__i + __j] + __k + __v[__i]; + __u[__i + __j] = static_cast(__t); + __k = __t >> 32; + } + __u[__j + __n] += static_cast(__k); + } + } + + // quotient is in __q, normalized remainder is in __u + } + + _NODISCARD static constexpr uint64_t _UDiv128( + uint64_t _High, uint64_t _Low, uint64_t _Div, uint64_t& _Remainder) noexcept { + // _STL_INTERNAL_CHECK(_High < _Div); + +#if _STL_128_DIV_INTRINSICS + if (!_Is_constant_evaluated()) { + return _udiv128(_High, _Low, _Div, &_Remainder); + } +#endif // _STL_128_DIV_INTRINSICS + + const auto __d = _Countl_zero(static_cast(_Div >> 32)); + if (__d >= 32) { // _Div < 2^32 + auto _Rem = (_High << 32) | (_Low >> 32); + auto _Result = _Rem / static_cast(_Div); + _Rem = ((_Rem % static_cast(_Div)) << 32) | static_cast(_Low); + _Result = (_Result << 32) | (_Rem / static_cast(_Div)); + _Remainder = _Rem % static_cast(_Div); + return _Result; + } + + uint32_t __u[5] = { + static_cast(_Low << __d), + static_cast(_Low >> (32 - __d)), + static_cast(_High << __d), + static_cast(_High >> (32 - __d)), + 0, + }; + if (__d != 0) { + __u[2] |= static_cast(_Low >> (64 - __d)); + __u[4] |= static_cast(_High >> (64 - __d)); + } + + uint32_t __v[2] = { + static_cast(_Div << __d), + static_cast(_Div >> (32 - __d)), + }; + uint32_t __q[3] _ZERO_OR_NO_INIT; + + _Knuth_4_3_1_D(__u, 5, __v, 2, __q); + // _STL_INTERNAL_CHECK(__u[4] == 0); + // _STL_INTERNAL_CHECK(__u[3] == 0); + // _STL_INTERNAL_CHECK(__u[2] == 0); + _Remainder = (static_cast(__u[1]) << (32 - __d)) | (__u[0] >> __d); + + // _STL_INTERNAL_CHECK(__q[2] == 0); + return (static_cast(__q[1]) << 32) | __q[0]; + } + + constexpr _Base128() noexcept : _Word{} {} + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Base128(const _Ty _Val) noexcept : _Word{static_cast(_Val)} { +#if _HAS_CXX20 + if constexpr (signed_integral<_Ty>) +#else + if constexpr (is_signed_v<_Ty>) +#endif + { + if (_Val < 0) { + _Word[1] = ~0ull; + } + } + } + + constexpr explicit _Base128(const uint64_t _Low, const uint64_t _High) noexcept : _Word{_Low, _High} {} + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD constexpr explicit operator _Ty() const noexcept { + return static_cast<_Ty>(_Word[0]); + } + + _NODISCARD constexpr explicit operator bool() const noexcept { + return (_Word[0] | _Word[1]) != 0; + } + +#if _HAS_CXX20 + _NODISCARD friend constexpr bool operator==(const _Base128&, const _Base128&) noexcept = default; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + _NODISCARD friend constexpr bool operator==(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Left._Word[0] == _Right._Word[0] && _Left._Word[1] == _Right._Word[1]; + } + + _NODISCARD friend constexpr bool operator!=(const _Base128& _Left, const _Base128& _Right) noexcept { + return !(_Left == _Right); + } +#endif // ^^^ !_HAS_CXX20 ^^^ + + _NODISCARD friend constexpr bool operator<(const _Base128& _Left, const _Base128& _Right) noexcept { + if (_Left._Word[1] < _Right._Word[1]) { + return true; + } + + if (_Left._Word[1] > _Right._Word[1]) { + return false; + } + return _Left._Word[0] < _Right._Word[0]; + } + _NODISCARD friend constexpr bool operator>(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Right < _Left; + } + _NODISCARD friend constexpr bool operator<=(const _Base128& _Left, const _Base128& _Right) noexcept { + return !(_Right < _Left); + } + _NODISCARD friend constexpr bool operator>=(const _Base128& _Left, const _Base128& _Right) noexcept { + return !(_Left < _Right); + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Ty operator<<(const _Ty _Left, const _Base128& _Right) noexcept { + return _Left << _Right._Word[0]; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Ty operator>>(const _Ty _Left, const _Base128& _Right) noexcept { + return _Left >> _Right._Word[0]; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Base128& operator<<=(const _Ty _Count) noexcept { + _Left_shift(static_cast(_Count)); + return *this; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator<<=(_Ty& _Left, const _Base128& _Right) noexcept { + _Left <<= _Right._Word[0]; + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Base128& operator>>=(const _Ty _Count) noexcept { + _Unsigned_right_shift(static_cast(_Count)); + return *this; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator>>=(_Ty& _Left, const _Base128& _Right) noexcept { + _Left >>= _Right._Word[0]; + return _Left; + } + + constexpr _Base128& operator++() noexcept { + if (++_Word[0] == 0) { + ++_Word[1]; + } + return *this; + } + constexpr _Base128 operator++(int) noexcept { + auto _Tmp = *this; + ++*this; + return _Tmp; + } + + constexpr _Base128& operator--() noexcept { + if (_Word[0]-- == 0) { + --_Word[1]; + } + return *this; + } + constexpr _Base128 operator--(int) noexcept { + auto _Tmp = *this; + --*this; + return _Tmp; + } + + _NODISCARD static constexpr _Base128 _Multiply(const _Base128& _Left, const _Base128& _Right) noexcept { + _Base128 _Result; + _Result._Word[0] = _UMul128(_Left._Word[0], _Right._Word[0], _Result._Word[1]); + _Result._Word[1] += _Left._Word[0] * _Right._Word[1]; + _Result._Word[1] += _Left._Word[1] * _Right._Word[0]; + return _Result; + } + +#if !_STL_128_DIV_INTRINSICS + _NODISCARD static constexpr _Base128 _Divide(const _Base128& _Num, const uint32_t _Den) noexcept { + _Base128 _Result; + _Result._Word[1] = _Num._Word[1] / _Den; + uint64_t _Rem = ((_Num._Word[1] % _Den) << 32) | (_Num._Word[0] >> 32); + _Result._Word[0] = (_Rem / _Den) << 32; + _Rem = ((_Rem % _Den) << 32) | static_cast(_Num._Word[0]); + _Result._Word[0] |= static_cast(_Rem / _Den); + return _Result; + } +#endif // !_STL_128_DIV_INTRINSICS + _NODISCARD static constexpr _Base128 _Divide(const _Base128& _Num, const uint64_t _Den) noexcept { + _Base128 _Result; + _Result._Word[1] = _Num._Word[1] / _Den; + uint64_t _Rem _ZERO_OR_NO_INIT; + _Result._Word[0] = _UDiv128(_Num._Word[1] % _Den, _Num._Word[0], _Den, _Rem); + return _Result; + } + _NODISCARD static constexpr _Base128 _Divide(_Base128 _Num, _Base128 _Den) noexcept { + // establish _Den < _Num and _Num._Word[1] > 0 + if (_Den._Word[1] >= _Num._Word[1]) { + if (_Den._Word[1] > _Num._Word[1]) { + return 0; + } + + return _Num._Word[1] == 0 ? _Num._Word[0] / _Den._Word[0] : _Num._Word[0] >= _Den._Word[0]; + } + + // establish _Den has more than 1 non-zero "digit" + if (_Den._Word[1] == 0) { +#if !_STL_128_DIV_INTRINSICS + if (_Den._Word[0] < (1ull << 32)) { + return _Divide(_Num, static_cast(_Den._Word[0])); + } else +#endif // !_STL_128_DIV_INTRINSICS + { + return _Divide(_Num, _Den._Word[0]); + } + } + +#if _STL_128_INTRINSICS + // Knuth 4.3.1D, 2-digit by 2-digit divide in base 2^64 + // _STL_INTERNAL_CHECK(_Den._Word[1] != 0); + // _STL_INTERNAL_CHECK(_Num._Word[1] > _Den._Word[1]); + // Normalize by shifting both left until _Den's high bit is set (So _Den's high digit is >= b / 2) + const auto __d = _Countl_zero(_Den._Word[1]); + _Den <<= __d; + auto _High_digit = __d == 0 ? 0 : _Num._Word[1] >> (64 - __d); // This creates a third digit for _Num + _Num <<= __d; + + _Base128 __qhat; + __qhat._Word[1] = _High_digit >= _Den._Word[1]; + uint64_t __rhat _ZERO_OR_NO_INIT; + __qhat._Word[0] = _UDiv128(_High_digit >= _Den._Word[1] ? _High_digit - _Den._Word[1] : _High_digit, + _Num._Word[1], _Den._Word[1], __rhat); + + for (;;) { + if (__qhat._Word[1] > 0) { + --__qhat; + } else { + _Base128 _Prod; + _Prod._Word[0] = _UMul128(__qhat._Word[0], _Den._Word[0], _Prod._Word[1]); + if (_Prod <= _Base128{_Num._Word[0], __rhat}) { + break; + } + --__qhat._Word[0]; + } + + const auto _Sum = __rhat + _Den._Word[1]; + if (__rhat > _Sum) { + break; + } + __rhat = _Sum; + } + // _STL_INTERNAL_CHECK(__qhat._Word[1] == 0); + + // [_High_digit | _Num] -= __qhat * _Den [Since __qhat < b, this is 3-digit - 1-digit * 2-digit] + uint64_t _Prod0_hi _ZERO_OR_NO_INIT; + uint64_t _Prod_lo = _UMul128(__qhat._Word[0], _Den._Word[0], _Prod0_hi); + auto _Borrow = _SubBorrow64(0, _Num._Word[0], _Prod_lo, _Num._Word[0]); + uint64_t _Prod1_hi _ZERO_OR_NO_INIT; + _Prod_lo = _UMul128(__qhat._Word[0], _Den._Word[1], _Prod1_hi); + _Prod1_hi += _AddCarry64(0, _Prod_lo, _Prod0_hi, _Prod_lo); + _Borrow = _SubBorrow64(_Borrow, _Num._Word[1], _Prod_lo, _Num._Word[1]); + _Borrow = _SubBorrow64(_Borrow, _High_digit, _Prod1_hi, _High_digit); + if (_Borrow) { + --__qhat._Word[0]; + } + return __qhat; +#else // ^^^ 128-bit intrinsics / no such intrinsics vvv + auto __d = _Countl_zero(_Den._Word[1]); + const bool _Three_word_den = __d >= 32; + __d &= 31; + uint32_t __u[5]{ + static_cast(_Num._Word[0] << __d), + static_cast(_Num._Word[0] >> (32 - __d)), + static_cast(_Num._Word[1] << __d), + static_cast(_Num._Word[1] >> (32 - __d)), + 0, + }; + uint32_t __v[4] = { + static_cast(_Den._Word[0] << __d), + static_cast(_Den._Word[0] >> (32 - __d)), + static_cast(_Den._Word[1] << __d), + static_cast(_Den._Word[1] >> (32 - __d)), + }; + if (__d != 0) { + __u[2] |= _Num._Word[0] >> (64 - __d); + __u[4] |= _Num._Word[1] >> (64 - __d); + __v[2] |= _Den._Word[0] >> (64 - __d); + } + + uint32_t __q[2] _ZERO_OR_NO_INIT; + if (_Three_word_den) { + // 4-digit by 3-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 3, __q); + } else { + // 4-digit by 4-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 4, __q); + __q[1] = 0; + } + + return (static_cast(__q[1]) << 32) | __q[0]; +#endif // _STL_128_INTRINSICS + } + +#if !_STL_128_DIV_INTRINSICS + _NODISCARD static constexpr _Base128 _Modulo(const _Base128& _Num, const uint32_t _Den) noexcept { + uint64_t _Rem = _Num._Word[1]; + _Rem = ((_Rem % _Den) << 32) | (_Num._Word[0] >> 32); + _Rem = ((_Rem % _Den) << 32) | static_cast(_Num._Word[0]); + return _Rem % _Den; + } +#endif // !_STL_128_DIV_INTRINSICS + _NODISCARD static constexpr _Base128 _Modulo(const _Base128& _Num, const uint64_t _Den) noexcept { + uint64_t _Rem _ZERO_OR_NO_INIT; + (void) _UDiv128(_Num._Word[1] % _Den, _Num._Word[0], _Den, _Rem); + return _Rem; + } + _NODISCARD static constexpr _Base128 _Modulo(_Base128 _Num, _Base128 _Den) noexcept { + // establish _Den < _Num and _Num._Word[1] > 0 + if (_Den._Word[1] >= _Num._Word[1]) { + if (_Den._Word[1] > _Num._Word[1]) { + return _Num; + } + + if (_Den._Word[0] <= _Num._Word[0]) { + return _Num._Word[1] == 0 ? _Num._Word[0] % _Den._Word[0] : _Num._Word[0] - _Den._Word[0]; + } + + return _Num; + } + + // establish _Den has more than 1 non-zero "digit" + if (_Den._Word[1] == 0) { +#if !_STL_128_DIV_INTRINSICS + if (_Den._Word[0] < (1ull << 32)) { + return _Modulo(_Num, static_cast(_Den._Word[0])); + } else +#endif // !_STL_128_DIV_INTRINSICS + { + return _Modulo(_Num, _Den._Word[0]); + } + } + +#if _STL_128_INTRINSICS + // Knuth 4.3.1D, 2-digit by 2-digit divide in base 2^64 + // _STL_INTERNAL_CHECK(_Den._Word[1] != 0); + // _STL_INTERNAL_CHECK(_Num._Word[1] > _Den._Word[1]); + // Normalize by shifting both left until _Den's high bit is set (So _Den's high digit is >= b / 2) + const auto __d = _Countl_zero(_Den._Word[1]); + _Den <<= __d; + auto _High_digit = __d == 0 ? 0 : _Num._Word[1] >> (64 - __d); // This creates a third digit for _Num + _Num <<= __d; + + uint64_t __qhat_high = _High_digit >= _Den._Word[1]; + uint64_t __rhat _ZERO_OR_NO_INIT; + uint64_t __qhat = _UDiv128(_High_digit >= _Den._Word[1] ? _High_digit - _Den._Word[1] : _High_digit, + _Num._Word[1], _Den._Word[1], __rhat); + + for (;;) { + if (__qhat_high > 0) { + if (__qhat-- == 0) { + --__qhat_high; + } + } else { + _Base128 _Prod; + _Prod._Word[0] = _UMul128(__qhat, _Den._Word[0], _Prod._Word[1]); + if (_Prod <= _Base128{_Num._Word[0], __rhat}) { + break; + } + --__qhat; + } + + const auto _Sum = __rhat + _Den._Word[1]; + if (__rhat > _Sum) { + break; + } + __rhat = _Sum; + // The addition didn't overflow, so `__rhat < b` holds + } + // _STL_INTERNAL_CHECK(__qhat_high == 0); + + // [_High_digit | _Num] -= __qhat * _Den [3-digit - 1-digit * 2-digit] + uint64_t _Prod0_hi _ZERO_OR_NO_INIT; + uint64_t _Prod_lo = _UMul128(__qhat, _Den._Word[0], _Prod0_hi); + auto _Borrow = _SubBorrow64(0, _Num._Word[0], _Prod_lo, _Num._Word[0]); + uint64_t _Prod1_hi _ZERO_OR_NO_INIT; + _Prod_lo = _UMul128(__qhat, _Den._Word[1], _Prod1_hi); + _Prod1_hi += _AddCarry64(0, _Prod_lo, _Prod0_hi, _Prod_lo); + _Borrow = _SubBorrow64(_Borrow, _Num._Word[1], _Prod_lo, _Num._Word[1]); + _Borrow = _SubBorrow64(_Borrow, _High_digit, _Prod1_hi, _High_digit); + if (_Borrow) { + auto _Carry = _AddCarry64(0, _Num._Word[0], _Den._Word[0], _Num._Word[0]); + (void) _AddCarry64(_Carry, _Num._Word[1], _Den._Word[1], _Num._Word[1]); + } +#else // ^^^ 128-bit intrinsics / no such intrinsics vvv + auto __d = _Countl_zero(_Den._Word[1]); + const bool _Three_word_den = __d >= 32; + __d &= 31; + uint32_t __u[5]{ + static_cast(_Num._Word[0] << __d), + static_cast(_Num._Word[0] >> (32 - __d)), + static_cast(_Num._Word[1] << __d), + static_cast(_Num._Word[1] >> (32 - __d)), + 0, + }; + uint32_t __v[4] = { + static_cast(_Den._Word[0] << __d), + static_cast(_Den._Word[0] >> (32 - __d)), + static_cast(_Den._Word[1] << __d), + static_cast(_Den._Word[1] >> (32 - __d)), + }; + if (__d != 0) { + __u[2] |= _Num._Word[0] >> (64 - __d); + __u[4] |= _Num._Word[1] >> (64 - __d); + __v[2] |= _Den._Word[0] >> (64 - __d); + } + + uint32_t __q[2] _ZERO_OR_NO_INIT; + if (_Three_word_den) { + // 4-digit by 3-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 3, __q); + // _STL_INTERNAL_CHECK(__u[3] == 0); + } else { + // 4-digit by 4-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 4, __q); + } + // _STL_INTERNAL_CHECK(__u[4] == 0); + + _Num._Word[0] = (static_cast(__u[1]) << 32) | __u[0]; + _Num._Word[1] = (static_cast(__u[3]) << 32) | __u[2]; +#endif // _STL_128_INTRINSICS + _Num >>= __d; + return _Num; + } + +#if _HAS_CXX23 +#if !_STL_128_DIV_INTRINSICS + _NODISCARD static constexpr _Base128 _Div_ceil(const _Base128& _Num, const uint32_t _Den) noexcept { + _Base128 _Result; + _Result._Word[1] = _Num._Word[1] / _Den; + uint64_t _Rem = ((_Num._Word[1] % _Den) << 32) | (_Num._Word[0] >> 32); + _Result._Word[0] = (_Rem / _Den) << 32; + _Rem = ((_Rem % _Den) << 32) | static_cast(_Num._Word[0]); + _Result._Word[0] |= static_cast(_Rem / _Den); + if (_Rem % _Den != 0) { + ++_Result; + } + + return _Result; + } +#endif // !_STL_128_DIV_INTRINSICS + + _NODISCARD static constexpr _Base128 _Div_ceil(const _Base128& _Num, const uint64_t _Den) noexcept { + _Base128 _Result; + _Result._Word[1] = _Num._Word[1] / _Den; + uint64_t _Rem; + _Result._Word[0] = _UDiv128(_Num._Word[1] % _Den, _Num._Word[0], _Den, _Rem); + if (_Rem != 0) { + ++_Result; + } + + return _Result; + } + + _NODISCARD static constexpr _Base128 _Div_ceil(_Base128 _Num, _Base128 _Den) noexcept { + // establish _Den < _Num and _Num._Word[1] > 0 + if (_Den._Word[1] >= _Num._Word[1]) { + if (_Den._Word[1] > _Num._Word[1]) { + return static_cast<_Base128>(_Num != 0); + } + + if (_Num._Word[1] == 0) { + uint64_t _Result = _Num._Word[0] / _Den._Word[0]; // with 64-bit inputs, the ceiling is also 64-bit + if (_Num._Word[0] % _Den._Word[0] != 0) { + ++_Result; + } + + return _Result; + } + + if (_Num._Word[0] > _Den._Word[0]) { + return 2u; + } + + return 1u; + } + + // establish _Den has more than 1 non-zero "digit" + if (_Den._Word[1] == 0) { +#if !_STL_128_DIV_INTRINSICS + if (_Den._Word[0] < (1ull << 32)) { + return _Div_ceil(_Num, static_cast(_Den._Word[0])); + } else +#endif // !_STL_128_DIV_INTRINSICS + { + return _Div_ceil(_Num, _Den._Word[0]); + } + } + + _Base128 _Result; +#if _STL_128_INTRINSICS + // Knuth 4.3.1D, 2-digit by 2-digit divide in base 2^64 + // _STL_INTERNAL_CHECK(_Den._Word[1] != 0); + // _STL_INTERNAL_CHECK(_Num._Word[1] > _Den._Word[1]); + // Normalize by shifting both left until _Den's high bit is set (So _Den's high digit is >= b / 2) + const auto __d = _STD _Countl_zero(_Den._Word[1]); + _Den <<= __d; + auto _High_digit = __d == 0 ? 0 : _Num._Word[1] >> (64 - __d); // This creates a third digit for _Num + _Num <<= __d; + + _Base128 __qhat; + __qhat._Word[1] = _High_digit >= _Den._Word[1]; + uint64_t __rhat; + __qhat._Word[0] = _UDiv128(_High_digit >= _Den._Word[1] ? _High_digit - _Den._Word[1] : _High_digit, + _Num._Word[1], _Den._Word[1], __rhat); + + for (;;) { + if (__qhat._Word[1] > 0) { + --__qhat; + } else { + _Base128 _Prod; + _Prod._Word[0] = _UMul128(__qhat._Word[0], _Den._Word[0], _Prod._Word[1]); + if (_Prod <= _Base128{_Num._Word[0], __rhat}) { + break; + } + --__qhat._Word[0]; + } + + const auto _Sum = __rhat + _Den._Word[1]; + if (__rhat > _Sum) { + break; + } + __rhat = _Sum; + } + // _STL_INTERNAL_CHECK(__qhat._Word[1] == 0); + + // [_High_digit | _Num] -= __qhat * _Den [Since __qhat < b, this is 3-digit - 1-digit * 2-digit] + uint64_t _Prod0_hi; + uint64_t _Prod_lo = _UMul128(__qhat._Word[0], _Den._Word[0], _Prod0_hi); + auto _Borrow = _SubBorrow64(0, _Num._Word[0], _Prod_lo, _Num._Word[0]); + uint64_t _Prod1_hi; + _Prod_lo = _UMul128(__qhat._Word[0], _Den._Word[1], _Prod1_hi); + _Prod1_hi += _AddCarry64(0, _Prod_lo, _Prod0_hi, _Prod_lo); + _Borrow = _SubBorrow64(_Borrow, _Num._Word[1], _Prod_lo, _Num._Word[1]); + _Borrow = _SubBorrow64(_Borrow, _High_digit, _Prod1_hi, _High_digit); + if (_Borrow) { + --__qhat._Word[0]; + auto _Carry = _AddCarry64(0, _Num._Word[0], _Den._Word[0], _Num._Word[0]); + (void) _AddCarry64(_Carry, _Num._Word[1], _Den._Word[1], _Num._Word[1]); + } + _Result = __qhat; +#else // ^^^ 128-bit intrinsics / no such intrinsics vvv + auto __d = _Countl_zero(_Den._Word[1]); + const bool _Three_word_den = __d >= 32; + __d &= 31; + uint32_t __u[5]{ + static_cast(_Num._Word[0] << __d), + static_cast(_Num._Word[0] >> (32 - __d)), + static_cast(_Num._Word[1] << __d), + static_cast(_Num._Word[1] >> (32 - __d)), + 0, + }; + uint32_t __v[4] = { + static_cast(_Den._Word[0] << __d), + static_cast(_Den._Word[0] >> (32 - __d)), + static_cast(_Den._Word[1] << __d), + static_cast(_Den._Word[1] >> (32 - __d)), + }; + if (__d != 0) { + __u[2] |= _Num._Word[0] >> (64 - __d); + __u[4] |= _Num._Word[1] >> (64 - __d); + __v[2] |= _Den._Word[0] >> (64 - __d); + } + + uint32_t __q[2] = {}; + if (_Three_word_den) { + // 4-digit by 3-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 3, __q); + // _STL_INTERNAL_CHECK(__u[3] == 0); + } else { + // 4-digit by 4-digit base 2^32 division + _Knuth_4_3_1_D(__u, 5, __v, 4, __q); + } + + _Result = (static_cast(__q[1]) << 32) | __q[0]; + _Num._Word[0] = (static_cast(__u[1]) << 32) | __u[0]; + _Num._Word[1] = (static_cast(__u[3]) << 32) | __u[2]; +#endif // _STL_128_INTRINSICS + + if (_Num != 0) { + ++_Result; + } + + return _Result; + } +#endif // _HAS_CXX23 + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator&=(_Ty& _Left, const _Base128& _Right) noexcept { + _Left &= _Right._Word[0]; + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator^=(_Ty& _Left, const _Base128& _Right) noexcept { + _Left ^= _Right._Word[0]; + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator|=(_Ty& _Left, const _Base128& _Right) noexcept { + _Left |= _Right._Word[0]; + return _Left; + } +}; + +struct _Signed128; + +struct _Unsigned128 : _Base128 { + using _Signed_type = _Signed128; + using _Unsigned_type = _Unsigned128; + +#if !_HAS_CXX17 + constexpr _Unsigned128() noexcept : _Base128{} {} +#endif // !_HAS_CXX17 + + using _Base128::_Base128; + constexpr explicit _Unsigned128(const _Base128& _That) noexcept : _Base128{_That} {} + + constexpr _Unsigned128& operator=(const _Base128& _That) noexcept { + _Base128::operator=(_That); + return *this; + } + +#if _HAS_CXX20 + _NODISCARD friend constexpr strong_ordering operator<=>( + const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + strong_ordering _Ord = _Left._Word[1] <=> _Right._Word[1]; + if (_Ord == strong_ordering::equal) { + _Ord = _Left._Word[0] <=> _Right._Word[0]; + } + return _Ord; + } +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + _NODISCARD friend constexpr bool operator<(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + if (_Left._Word[1] < _Right._Word[1]) { + return true; + } + + if (_Right._Word[1] < _Left._Word[1]) { + return false; + } + + return _Left._Word[0] < _Right._Word[0]; + } + + _NODISCARD friend constexpr bool operator>(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + return _Right < _Left; + } + + _NODISCARD friend constexpr bool operator<=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + return !(_Right < _Left); + } + + _NODISCARD friend constexpr bool operator>=(const _Unsigned128& _Left, const _Unsigned128& _Right) noexcept { + return !(_Left < _Right); + } +#endif // ^^^ !_HAS_CXX20 ^^^ + + _NODISCARD friend constexpr _Unsigned128 operator<<(const _Unsigned128& _Left, const _Base128& _Right) noexcept { + auto _Tmp{_Left}; + _Tmp._Left_shift(static_cast(_Right._Word[0])); + return _Tmp; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Unsigned128& operator<<=(const _Ty _Count) noexcept { + _Left_shift(static_cast(_Count)); + return *this; + } + constexpr _Unsigned128& operator<<=(const _Base128& _Count) noexcept { + _Left_shift(static_cast(_Count._Word[0])); + return *this; + } + + _NODISCARD friend constexpr _Unsigned128 operator>>(const _Unsigned128& _Left, const _Base128& _Right) noexcept { + auto _Tmp{_Left}; + _Tmp._Unsigned_right_shift(static_cast(_Right._Word[0])); + return _Tmp; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Unsigned128& operator>>=(const _Ty _Count) noexcept { + _Unsigned_right_shift(static_cast(_Count)); + return *this; + } + constexpr _Unsigned128& operator>>=(const _Base128& _Count) noexcept { + _Unsigned_right_shift(static_cast(_Count._Word[0])); + return *this; + } + + constexpr _Unsigned128& operator++() noexcept { + if (++_Word[0] == 0) { + ++_Word[1]; + } + return *this; + } + constexpr _Unsigned128 operator++(int) noexcept { + auto _Tmp = *this; + ++*this; + return _Tmp; + } + + constexpr _Unsigned128& operator--() noexcept { + if (_Word[0]-- == 0) { + --_Word[1]; + } + return *this; + } + constexpr _Unsigned128 operator--(int) noexcept { + auto _Tmp = *this; + --*this; + return _Tmp; + } + + _NODISCARD constexpr _Unsigned128 operator+() const noexcept { + return *this; + } + + _NODISCARD constexpr _Unsigned128 operator-() const noexcept { + return _Unsigned128{} - *this; + } + + _NODISCARD constexpr _Unsigned128 operator~() const noexcept { + return _Unsigned128{~_Word[0], ~_Word[1]}; + } + + _NODISCARD friend constexpr _Unsigned128 operator+(const _Base128& _Left, const _Base128& _Right) noexcept { + _Unsigned128 _Result; + const auto _Carry = _AddCarry64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); + _AddCarry64(_Carry, _Left._Word[1], _Right._Word[1], _Result._Word[1]); + return _Result; + } + + constexpr _Unsigned128& operator+=(const _Base128& _That) noexcept { + const auto _Carry = _AddCarry64(0, _Word[0], _That._Word[0], _Word[0]); + _AddCarry64(_Carry, _Word[1], _That._Word[1], _Word[1]); + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator+=(_Ty& _Left, const _Unsigned128& _Right) noexcept { + _Left += _Right._Word[0]; + return _Left; + } + + _NODISCARD friend constexpr _Unsigned128 operator-(const _Base128& _Left, const _Base128& _Right) noexcept { + _Unsigned128 _Result; + const auto _Borrow = _SubBorrow64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); + _SubBorrow64(_Borrow, _Left._Word[1], _Right._Word[1], _Result._Word[1]); + return _Result; + } + + constexpr _Unsigned128& operator-=(const _Base128& _That) noexcept { + const auto _Borrow = _SubBorrow64(0, _Word[0], _That._Word[0], _Word[0]); + _SubBorrow64(_Borrow, _Word[1], _That._Word[1], _Word[1]); + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator-=(_Ty& _Left, const _Unsigned128& _Right) noexcept { + _Left -= _Right._Word[0]; + return _Left; + } + + _NODISCARD friend constexpr _Unsigned128 operator*(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Unsigned128{_Base128::_Multiply(_Left, _Right)}; + } + + constexpr _Unsigned128& operator*=(const _Base128& _That) noexcept { + *this = *this * _That; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator*=(_Ty& _Left, const _Unsigned128& _Right) noexcept { + _Left *= _Right._Word[0]; + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Unsigned128 operator/(const _Unsigned128& _Num, const _Ty _Den) noexcept { +#if !_STL_128_DIV_INTRINSICS + if constexpr (sizeof(_Ty) <= 4) { + return _Unsigned128{_Base128::_Divide(_Num, static_cast(_Den))}; + } else +#endif // !_STL_128_DIV_INTRINSICS + { + return _Unsigned128{_Base128::_Divide(_Num, static_cast(_Den))}; + } + } + _NODISCARD friend constexpr _Unsigned128 operator/(const _Base128& _Num, const _Base128& _Den) noexcept { + return _Unsigned128{_Base128::_Divide(_Num, _Den)}; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Unsigned128& operator/=(const _Ty _That) noexcept { +#if !_STL_128_DIV_INTRINSICS + if constexpr (sizeof(_Ty) <= 4) { + *this = _Unsigned128{_Base128::_Divide(*this, static_cast(_That))}; + } else +#endif // !_STL_128_DIV_INTRINSICS + { + *this = _Unsigned128{_Base128::_Divide(*this, static_cast(_That))}; + } + return *this; + } + constexpr _Unsigned128& operator/=(const _Base128& _That) noexcept { + *this = _Unsigned128{_Base128::_Divide(*this, _That)}; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator/=(_Ty& _Left, const _Unsigned128& _Right) noexcept { + if (_Right._Word[1] != 0) { + _Left = 0; + } else { + _Left /= _Right._Word[0]; + } + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Unsigned128 operator%(const _Base128& _Num, const _Ty _Den) noexcept { +#if !_STL_128_DIV_INTRINSICS + if constexpr (sizeof(_Ty) <= 4) { + return _Unsigned128{_Base128::_Modulo(_Num, static_cast(_Den))}; + } else +#endif // !_STL_128_DIV_INTRINSICS + { + return _Unsigned128{_Base128::_Modulo(_Num, static_cast(_Den))}; + } + } + _NODISCARD friend constexpr _Unsigned128 operator%(const _Base128& _Num, const _Base128& _Den) noexcept { + return _Unsigned128{_Base128::_Modulo(_Num, _Den)}; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Unsigned128& operator%=(const _Ty _Den) noexcept { + *this = *this % _Den; + return *this; + } + constexpr _Unsigned128& operator%=(const _Base128& _Den) noexcept { + *this = *this % _Den; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator%=(_Ty& _Left, const _Unsigned128& _Right) noexcept { + if (_Right._Word[1] == 0) { + _Left %= _Right._Word[0]; + } + return _Left; + } + + _NODISCARD friend constexpr _Unsigned128 operator&(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Unsigned128{_Left._Word[0] & _Right._Word[0], _Left._Word[1] & _Right._Word[1]}; + } + + constexpr _Unsigned128& operator&=(const _Base128& _That) noexcept { + _Word[0] &= _That._Word[0]; + _Word[1] &= _That._Word[1]; + return *this; + } + + _NODISCARD friend constexpr _Unsigned128 operator^(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Unsigned128{_Left._Word[0] ^ _Right._Word[0], _Left._Word[1] ^ _Right._Word[1]}; + } + + constexpr _Unsigned128& operator^=(const _Base128& _That) noexcept { + _Word[0] ^= _That._Word[0]; + _Word[1] ^= _That._Word[1]; + return *this; + } + + _NODISCARD friend constexpr _Unsigned128 operator|(const _Base128& _Left, const _Base128& _Right) noexcept { + return _Unsigned128{_Left._Word[0] | _Right._Word[0], _Left._Word[1] | _Right._Word[1]}; + } + + constexpr _Unsigned128& operator|=(const _Base128& _That) noexcept { + _Word[0] |= _That._Word[0]; + _Word[1] |= _That._Word[1]; + return *this; + } +}; + +template <> +class numeric_limits<_Unsigned128> : public _Num_int_base { +public: + _NODISCARD static constexpr _Unsigned128(min)() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128(max)() noexcept { + return _Unsigned128{~0ull, ~0ull}; + } + + _NODISCARD static constexpr _Unsigned128 lowest() noexcept { + return (min) (); + } + + _NODISCARD static constexpr _Unsigned128 epsilon() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128 round_error() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128 denorm_min() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128 infinity() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128 quiet_NaN() noexcept { + return 0; + } + + _NODISCARD static constexpr _Unsigned128 signaling_NaN() noexcept { + return 0; + } + + static constexpr bool is_modulo = true; + static constexpr int digits = 128; + static constexpr int digits10 = 38; +}; + +struct _Signed128 : _Base128 { + using _Signed_type = _Signed128; + using _Unsigned_type = _Unsigned128; + +#if !_HAS_CXX17 + constexpr _Signed128() noexcept : _Base128{} {} +#endif // !_HAS_CXX17 + + using _Base128::_Base128; + constexpr explicit _Signed128(const _Base128& _That) noexcept : _Base128{_That} {} + + constexpr _Signed128& operator=(const _Base128& _That) noexcept { + _Base128::operator=(_That); + return *this; + } + +#if _HAS_CXX20 + _NODISCARD friend constexpr strong_ordering operator<=>( + const _Signed128& _Left, const _Signed128& _Right) noexcept { + strong_ordering _Ord = static_cast(_Left._Word[1]) <=> static_cast(_Right._Word[1]); + if (_Ord == strong_ordering::equal) { + _Ord = _Left._Word[0] <=> _Right._Word[0]; + } + return _Ord; + } +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv + _NODISCARD friend constexpr bool operator<(const _Signed128& _Left, const _Signed128& _Right) noexcept { + if (static_cast(_Left._Word[1]) < static_cast(_Right._Word[1])) { + return true; + } + + if (static_cast(_Right._Word[1]) < static_cast(_Left._Word[1])) { + return false; + } + + return _Left._Word[0] < _Right._Word[0]; + } + + _NODISCARD friend constexpr bool operator>(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return _Right < _Left; + } + + _NODISCARD friend constexpr bool operator<=(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return !(_Right < _Left); + } + + _NODISCARD friend constexpr bool operator>=(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return !(_Left < _Right); + } +#endif // ^^^ !_HAS_CXX20 ^^^ + + _NODISCARD friend constexpr _Signed128 operator<<(const _Signed128& _Left, const _Base128& _Right) noexcept { + auto _Tmp{_Left}; + _Tmp._Left_shift(static_cast(_Right._Word[0])); + return _Tmp; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Signed128& operator<<=(const _Ty _Count) noexcept { + _Left_shift(static_cast(_Count)); + return *this; + } + constexpr _Signed128& operator<<=(const _Base128& _Count) noexcept { + _Left_shift(static_cast(_Count._Word[0])); + return *this; + } + + constexpr void _Signed_right_shift(const unsigned char _Count) noexcept { + if (_Count == 0) { + return; + } + + if (_Count >= 64) { + _Word[0] = static_cast(static_cast(_Word[1]) >> (_Count % 64)); + _Word[1] = (_Word[1] & (1ull << 63)) == 0 ? 0 : ~0ull; + return; + } + +#if _STL_128_INTRINSICS + if (!_Is_constant_evaluated()) { + _Word[0] = __shiftright128(_Word[0], _Word[1], _Count); + } else +#endif // _STL_128_INTRINSICS + { + _Word[0] = (_Word[0] >> _Count) | (_Word[1] << (64 - _Count)); + } + + _Word[1] = static_cast(static_cast(_Word[1]) >> _Count); + } + + _NODISCARD friend constexpr _Signed128 operator>>(const _Signed128& _Left, const _Base128& _Right) noexcept { + auto _Tmp{_Left}; + _Tmp._Signed_right_shift(static_cast(_Right._Word[0])); + return _Tmp; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Signed128& operator>>=(const _Ty _Count) noexcept { + _Signed_right_shift(static_cast(_Count)); + return *this; + } + constexpr _Signed128& operator>>=(const _Base128& _Count) noexcept { + _Signed_right_shift(static_cast(_Count._Word[0])); + return *this; + } + + constexpr _Signed128& operator++() noexcept { + if (++_Word[0] == 0) { + ++_Word[1]; + } + return *this; + } + constexpr _Signed128 operator++(int) noexcept { + auto _Tmp = *this; + ++*this; + return _Tmp; + } + + constexpr _Signed128& operator--() noexcept { + if (_Word[0]-- == 0) { + --_Word[1]; + } + return *this; + } + constexpr _Signed128 operator--(int) noexcept { + auto _Tmp = *this; + --*this; + return _Tmp; + } + + _NODISCARD constexpr _Signed128 operator+() const noexcept { + return *this; + } + + _NODISCARD constexpr _Signed128 operator-() const noexcept { + return _Signed128{} - *this; + } + + _NODISCARD constexpr _Signed128 operator~() const noexcept { + return _Signed128{~_Word[0], ~_Word[1]}; + } + + _NODISCARD friend constexpr _Signed128 operator+(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _Signed128 _Result; + const auto _Carry = _AddCarry64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); + _AddCarry64(_Carry, _Left._Word[1], _Right._Word[1], _Result._Word[1]); + return _Result; + } + + constexpr _Signed128& operator+=(const _Base128& _That) noexcept { + const auto _Carry = _AddCarry64(0, _Word[0], _That._Word[0], _Word[0]); + _AddCarry64(_Carry, _Word[1], _That._Word[1], _Word[1]); + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator+=(_Ty& _Left, const _Signed128& _Right) noexcept { + _Left = static_cast<_Ty>(_Signed128{_Left} + _Right); + return _Left; + } + + _NODISCARD friend constexpr _Signed128 operator-(const _Signed128& _Left, const _Signed128& _Right) noexcept { + _Signed128 _Result; + const auto _Borrow = _SubBorrow64(0, _Left._Word[0], _Right._Word[0], _Result._Word[0]); + _SubBorrow64(_Borrow, _Left._Word[1], _Right._Word[1], _Result._Word[1]); + return _Result; + } + + constexpr _Signed128& operator-=(const _Base128& _That) noexcept { + const auto _Borrow = _SubBorrow64(0, _Word[0], _That._Word[0], _Word[0]); + _SubBorrow64(_Borrow, _Word[1], _That._Word[1], _Word[1]); + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator-=(_Ty& _Left, const _Signed128& _Right) noexcept { + _Left = static_cast<_Ty>(_Signed128{_Left} - _Right); + return _Left; + } + + constexpr void _Strip_negative(bool& _Flip) noexcept { + if ((_Word[1] & (1ull << 63)) != 0) { + *this = -*this; + _Flip = !_Flip; + } + } + + _NODISCARD friend constexpr _Signed128 operator*(_Signed128 _Left, _Signed128 _Right) noexcept { + bool _Negative = false; + _Left._Strip_negative(_Negative); + _Right._Strip_negative(_Negative); + _Signed128 _Result{_Base128::_Multiply(_Left, _Right)}; + if (_Negative) { + _Result = -_Result; + } + return _Result; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Signed128& operator*=(const _Ty _That) noexcept { + *this = *this * _That; + return *this; + } + constexpr _Signed128& operator*=(const _Signed128& _That) noexcept { + *this = *this * _That; + return *this; + } + constexpr _Signed128& operator*=(const _Unsigned128& _That) noexcept { + *this = _Signed128{static_cast(*this) * _That}; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator*=(_Ty& _Left, const _Signed128& _Right) noexcept { + _Left = static_cast<_Ty>(_Signed128{_Left} * _Right); + return _Left; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Signed128 operator/(_Signed128 _Num, _Ty _Den) noexcept { + bool _Negative = false; + _Num._Strip_negative(_Negative); + if constexpr (is_signed_v<_Ty>) { + if (_Den < 0) { + _Den = -_Den; + _Negative = !_Negative; + } + } + + _Signed128 _Result; +#if !_STL_128_DIV_INTRINSICS + if constexpr (sizeof(_Ty) <= 4) { + _Result = _Signed128{_Base128::_Divide(_Num, static_cast(_Den))}; + } else +#endif // !_STL_128_DIV_INTRINSICS + { + _Result = _Signed128{_Base128::_Divide(_Num, static_cast(_Den))}; + } + + if (_Negative) { + _Result = -_Result; + } + return _Result; + } + _NODISCARD friend constexpr _Signed128 operator/(_Signed128 _Num, _Signed128 _Den) noexcept { + bool _Negative = false; + _Num._Strip_negative(_Negative); + _Den._Strip_negative(_Negative); + _Signed128 _Result{_Base128::_Divide(_Num, _Den)}; + if (_Negative) { + _Result = -_Result; + } + return _Result; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Signed128& operator/=(const _Ty _That) noexcept { + *this = *this / _That; + return *this; + } + constexpr _Signed128& operator/=(const _Signed128& _That) noexcept { + *this = *this / _That; + return *this; + } + constexpr _Signed128& operator/=(const _Unsigned128& _That) noexcept { + *this = _Signed128{static_cast<_Base128&>(*this) / _That}; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator/=(_Ty& _Left, const _Signed128& _Right) noexcept { + _Left = static_cast<_Ty>(_Signed128{_Left} / _Right); + return _Left; + } + + _NODISCARD friend constexpr _Signed128 operator%(_Signed128 _Left, _Signed128 _Right) noexcept { + bool _Negative = false; + _Left._Strip_negative(_Negative); + + if ((_Right._Word[1] & (1ull << 63)) != 0) { + _Right = -_Right; + // intentionally not flipping _Negative + } + + _Unsigned128 _Result{_Base128::_Modulo(_Left, _Right)}; + if (_Negative) { + _Result = -_Result; + } + return _Signed128{_Result}; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + _NODISCARD friend constexpr _Signed128 operator%(_Signed128 _Left, const _Ty _Right) noexcept { + return _Left % _Signed128{_Right}; + } + + _TEMPLATE_CLASS_INTEGRAL(_Ty) + constexpr _Signed128& operator%=(const _Ty _That) noexcept { + *this = *this % _That; + return *this; + } + constexpr _Signed128& operator%=(const _Signed128& _That) noexcept { + *this = *this % _That; + return *this; + } + constexpr _Signed128& operator%=(const _Unsigned128& _That) noexcept { + *this = static_cast(*this) % _That; + return *this; + } + _TEMPLATE_CLASS_INTEGRAL(_Ty) + friend constexpr _Ty& operator%=(_Ty& _Left, const _Signed128& _Right) noexcept { + _Left = static_cast<_Ty>(_Signed128{_Left} % _Right); + return _Left; + } + +#if _HAS_CXX23 + _NODISCARD static constexpr _Signed128 _Div_ceil(_Signed128 _Num, _Signed128 _Den) noexcept { + // _STL_INTERNAL_CHECK(_Num >= 0); + // _STL_INTERNAL_CHECK(_Den > 0); + return _Signed128{_Base128::_Div_ceil(_Num, _Den)}; + } +#endif // _HAS_CXX23 + + _NODISCARD friend constexpr _Signed128 operator&(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return _Signed128{_Left._Word[0] & _Right._Word[0], _Left._Word[1] & _Right._Word[1]}; + } + + constexpr _Signed128& operator&=(const _Base128& _That) noexcept { + _Word[0] &= _That._Word[0]; + _Word[1] &= _That._Word[1]; + return *this; + } + + _NODISCARD friend constexpr _Signed128 operator^(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return _Signed128{_Left._Word[0] ^ _Right._Word[0], _Left._Word[1] ^ _Right._Word[1]}; + } + + constexpr _Signed128& operator^=(const _Base128& _That) noexcept { + _Word[0] ^= _That._Word[0]; + _Word[1] ^= _That._Word[1]; + return *this; + } + + _NODISCARD friend constexpr _Signed128 operator|(const _Signed128& _Left, const _Signed128& _Right) noexcept { + return _Signed128{_Left._Word[0] | _Right._Word[0], _Left._Word[1] | _Right._Word[1]}; + } + + constexpr _Signed128& operator|=(const _Base128& _That) noexcept { + _Word[0] |= _That._Word[0]; + _Word[1] |= _That._Word[1]; + return *this; + } +}; + +template <> +class numeric_limits<_Signed128> : public _Num_int_base { +public: + _NODISCARD static constexpr _Signed128(min)() noexcept { + return _Signed128{0ull, 1ull << 63}; + } + + _NODISCARD static constexpr _Signed128(max)() noexcept { + return _Signed128{~0ull, ~0ull >> 1}; + } + + _NODISCARD static constexpr _Signed128 lowest() noexcept { + return (min) (); + } + + _NODISCARD static constexpr _Signed128 epsilon() noexcept { + return 0; + } + + _NODISCARD static constexpr _Signed128 round_error() noexcept { + return 0; + } + + _NODISCARD static constexpr _Signed128 denorm_min() noexcept { + return 0; + } + + _NODISCARD static constexpr _Signed128 infinity() noexcept { + return 0; + } + + _NODISCARD static constexpr _Signed128 quiet_NaN() noexcept { + return 0; + } + + _NODISCARD static constexpr _Signed128 signaling_NaN() noexcept { + return 0; + } + + static constexpr int digits = 127; + static constexpr int digits10 = 38; + static constexpr bool is_signed = true; +}; + +template <> +struct common_type<_Signed128, _Unsigned128> { + using type = _Unsigned128; +}; +template <> +struct common_type<_Unsigned128, _Signed128> { + using type = _Unsigned128; +}; + +template +_NODISCARD constexpr _Ty _Min_limit() noexcept; + +template <> +_NODISCARD constexpr _Unsigned128 _Min_limit<_Unsigned128>() noexcept { + return 0; +} + +template <> +_NODISCARD constexpr _Signed128 _Min_limit<_Signed128>() noexcept { + return _Signed128{0ull, 1ull << 63}; +} + +template +_NODISCARD constexpr _Ty _Max_limit() noexcept; + +template <> +_NODISCARD constexpr _Unsigned128 _Max_limit<_Unsigned128>() noexcept { + return _Unsigned128{~0ull, ~0ull}; +} + +template <> +_NODISCARD constexpr _Signed128 _Max_limit<_Signed128>() noexcept { + return _Signed128{~0ull, ~0ull >> 1}; +} + +#undef _STL_128_INTRINSICS +#undef _STL_128_DIV_INTRINSICS + +_STD_END + +#undef _TEMPLATE_CLASS_INTEGRAL +#undef _ZERO_OR_NO_INIT + +#pragma pop_macro("new") +_STL_RESTORE_CLANG_WARNINGS +#pragma warning(pop) +#pragma pack(pop) +#endif // _STL_COMPILER_PREPROCESSOR +#endif // __MSVC_INT128_HPP diff --git a/msvc-stl/stl/inc/__msvc_iter_core.hpp b/msvc-stl/stl/inc/__msvc_iter_core.hpp new file mode 100644 index 0000000..439e8bf --- /dev/null +++ b/msvc-stl/stl/inc/__msvc_iter_core.hpp @@ -0,0 +1,560 @@ +// __msvc_iter_core.hpp internal header (core) + +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef __MSVC_ITER_CORE_HPP +#define __MSVC_ITER_CORE_HPP +#include +#if _STL_COMPILER_PREPROCESSOR +#include + +#pragma pack(push, _CRT_PACKING) +#pragma warning(push, _STL_WARNING_LEVEL) +#pragma warning(disable : _STL_DISABLED_WARNINGS) +_STL_DISABLE_CLANG_WARNINGS +#pragma push_macro("new") +#undef new + +// TRANSITION, non-_Ugly attribute tokens +#pragma push_macro("msvc") +#pragma push_macro("no_specializations") +#undef msvc +#undef no_specializations + +_STD_BEGIN +template +struct _Has_allocator_type : false_type {}; // tests for suitable _Ty::allocator_type + +template +struct _Has_allocator_type<_Ty, _Alloc, void_t> + : is_convertible<_Alloc, typename _Ty::allocator_type>::type {}; + +_EXPORT_STD struct allocator_arg_t { // tag type for added allocator argument + explicit allocator_arg_t() = default; +}; + +_EXPORT_STD _INLINE_VAR constexpr allocator_arg_t allocator_arg{}; + +_EXPORT_STD template +struct uses_allocator : _Has_allocator_type<_Ty, _Alloc>::type {}; + +_EXPORT_STD template +_NO_SPECIALIZATIONS_OF_VARIABLE_TEMPLATES constexpr bool uses_allocator_v = uses_allocator<_Ty, _Alloc>::value; + +// from +_EXPORT_STD struct input_iterator_tag {}; + +_EXPORT_STD struct output_iterator_tag {}; + +_EXPORT_STD struct forward_iterator_tag : input_iterator_tag {}; + +_EXPORT_STD struct bidirectional_iterator_tag : forward_iterator_tag {}; + +_EXPORT_STD struct random_access_iterator_tag : bidirectional_iterator_tag {}; + +#if _HAS_CXX20 +_EXPORT_STD struct contiguous_iterator_tag : random_access_iterator_tag {}; + +template +using _With_reference = _Ty&; + +template +concept _Can_reference = requires { typename _With_reference<_Ty>; }; + +template +concept _Dereferenceable = requires(_Ty& __t) { + { *__t } -> _Can_reference; +}; + +template +concept _Has_member_iterator_concept = requires { typename _Ty::iterator_concept; }; + +template +concept _Has_member_iterator_category = requires { typename _Ty::iterator_category; }; + +template +concept _Has_member_value_type = requires { typename _Ty::value_type; }; + +template +concept _Has_member_element_type = requires { typename _Ty::element_type; }; + +template +concept _Has_member_difference_type = requires { typename _Ty::difference_type; }; + +template +concept _Has_member_pointer = requires { typename _Ty::pointer; }; + +template +concept _Has_member_reference = requires { typename _Ty::reference; }; + +_EXPORT_STD template +struct incrementable_traits {}; + +template + requires is_object_v<_Ty> +struct incrementable_traits<_Ty*> { + using difference_type = ptrdiff_t; +}; + +template +struct incrementable_traits : incrementable_traits<_Ty> {}; + +template <_Has_member_difference_type _Ty> +struct incrementable_traits<_Ty> { + using difference_type = _Ty::difference_type; +}; + +template +concept _Can_difference = requires(const _Ty& __a, const _Ty& __b) { + { __a - __b } -> integral; +}; + +template + requires (!_Has_member_difference_type<_Ty> && _Can_difference<_Ty>) +struct incrementable_traits<_Ty> { + using difference_type = make_signed_t() - _STD declval<_Ty>())>; +}; + +template +concept _Is_from_primary = _Same_impl; + +_EXPORT_STD template +struct iterator_traits; + +_EXPORT_STD template +using iter_difference_t = conditional_t<_Is_from_primary>>, + incrementable_traits>, iterator_traits>>::difference_type; + +template +struct _Cond_value_type {}; + +template + requires is_object_v<_Ty> +struct _Cond_value_type<_Ty> { + using value_type = remove_cv_t<_Ty>; +}; + +_EXPORT_STD template +struct indirectly_readable_traits {}; + +template +struct indirectly_readable_traits<_Ty*> : _Cond_value_type<_Ty> {}; + +template + requires is_array_v<_Ty> +struct indirectly_readable_traits<_Ty> { + using value_type = remove_cv_t>; +}; + +template +struct indirectly_readable_traits : indirectly_readable_traits<_Ty> {}; + +template <_Has_member_value_type _Ty> +struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; + +template <_Has_member_element_type _Ty> +struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; + +template <_Has_member_value_type _Ty> + requires _Has_member_element_type<_Ty> +struct indirectly_readable_traits<_Ty> {}; + +template <_Has_member_value_type _Ty> + requires _Has_member_element_type<_Ty> + && same_as, remove_cv_t> +struct indirectly_readable_traits<_Ty> : _Cond_value_type {}; + +_EXPORT_STD template +using iter_value_t = conditional_t<_Is_from_primary>>, + indirectly_readable_traits>, iterator_traits>>::value_type; + +_EXPORT_STD template <_Dereferenceable _Ty> +using iter_reference_t = decltype(*_STD declval<_Ty&>()); + +template +struct _Iterator_traits_base {}; + +template +concept _Has_iter_types = _Has_member_difference_type<_It> && _Has_member_value_type<_It> && _Has_member_reference<_It> + && _Has_member_iterator_category<_It>; + +template +struct _Old_iter_traits_pointer { + template + using _Apply = _It::pointer; +}; + +template <> +struct _Old_iter_traits_pointer { + template + using _Apply = void; +}; + +template <_Has_iter_types _It> +struct _Iterator_traits_base<_It> { + using iterator_category = _It::iterator_category; + using value_type = _It::value_type; + using difference_type = _It::difference_type; + using pointer = _Old_iter_traits_pointer<_Has_member_pointer<_It>>::template _Apply<_It>; + using reference = _It::reference; +}; + +template +struct _Iter_traits_difference { + template + using _Apply = incrementable_traits<_It>::difference_type; +}; + +template <> +struct _Iter_traits_difference { + template + using _Apply = void; +}; + +template +concept _Cpp17_iterator = requires(_It __i) { + { *__i } -> _Can_reference; + { ++__i } -> same_as<_It&>; + { *__i++ } -> _Can_reference; +} && copyable<_It>; + +template +concept _Cpp17_input_iterator = + _Cpp17_iterator<_It> && equality_comparable<_It> && _Has_member_difference_type> + && _Has_member_value_type> && requires(_It __i) { + typename common_reference_t&&, typename indirectly_readable_traits<_It>::value_type&>; + typename common_reference_t::value_type&>; + requires signed_integral::difference_type>; + }; + +template + requires (!_Has_iter_types<_It> && _Cpp17_iterator<_It> && !_Cpp17_input_iterator<_It>) +struct _Iterator_traits_base<_It> { + using iterator_category = output_iterator_tag; + using value_type = void; + using difference_type = + _Iter_traits_difference<_Has_member_difference_type>>::template _Apply<_It>; + using pointer = void; + using reference = void; +}; + +enum class _Itraits_pointer_strategy { _Use_void, _Use_member, _Use_decltype }; + +template <_Itraits_pointer_strategy> +struct _Iter_traits_pointer; + +template <> +struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_void> { + template + using _Apply = void; +}; + +template <> +struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_member> { + template + using _Apply = _It::pointer; +}; + +template <> +struct _Iter_traits_pointer<_Itraits_pointer_strategy::_Use_decltype> { + template + using _Apply = decltype(_STD declval<_It&>().operator->()); +}; + +template +concept _Has_member_arrow = requires(_Ty&& __t) { static_cast<_Ty&&>(__t).operator->(); }; + +template +struct _Iter_traits_reference { + template + using _Apply = _It::reference; +}; + +template <> +struct _Iter_traits_reference { + template + using _Apply = iter_reference_t<_It>; +}; + +template +struct _Iter_traits_category4 { + using type = random_access_iterator_tag; +}; + +template <> +struct _Iter_traits_category4 { + using type = bidirectional_iterator_tag; +}; + +template +concept _Cpp17_random_delta = + totally_ordered<_It> && requires(_It __i, incrementable_traits<_It>::difference_type __n) { + { __i += __n } -> same_as<_It&>; + { __i -= __n } -> same_as<_It&>; + { __i + __n } -> same_as<_It>; + { __n + __i } -> same_as<_It>; + { __i - __n } -> same_as<_It>; + { __i - __i } -> same_as; + { __i[__n] } -> convertible_to>; + }; + +template +struct _Iter_traits_category3 { + template + using _Apply = _Iter_traits_category4<_Cpp17_random_delta<_It>>::type; +}; + +template <> +struct _Iter_traits_category3 { + template + using _Apply = forward_iterator_tag; +}; + +template +concept _Cpp17_bidi_delta = requires(_It __i) { + { --__i } -> same_as<_It&>; + { __i-- } -> convertible_to; + requires same_as>; +}; + +template +struct _Iter_traits_category2 { + template + using _Apply = _Iter_traits_category3<_Cpp17_bidi_delta<_It>>::template _Apply<_It>; +}; + +template <> +struct _Iter_traits_category2 { + template + using _Apply = input_iterator_tag; +}; + +template +concept _Cpp17_forward_delta = + constructible_from<_It> && is_reference_v> + && same_as>, typename indirectly_readable_traits<_It>::value_type> + && requires(_It __i) { + { __i++ } -> convertible_to; + requires same_as>; + }; + +template +struct _Iter_traits_category { + template + using _Apply = _It::iterator_category; +}; + +template <> +struct _Iter_traits_category { + template + using _Apply = _Iter_traits_category2<_Cpp17_forward_delta<_It>>::template _Apply<_It>; +}; + +template + requires (!_Has_iter_types<_It> && _Cpp17_input_iterator<_It>) +struct _Iterator_traits_base<_It> { + using iterator_category = _Iter_traits_category<_Has_member_iterator_category<_It>>::template _Apply<_It>; + using value_type = indirectly_readable_traits<_It>::value_type; + using difference_type = incrementable_traits<_It>::difference_type; + using pointer = + _Iter_traits_pointer<(_Has_member_pointer<_It> ? _Itraits_pointer_strategy::_Use_member + : _Has_member_arrow<_It&> ? _Itraits_pointer_strategy::_Use_decltype + : _Itraits_pointer_strategy::_Use_void)>::template _Apply<_It>; + using reference = _Iter_traits_reference<_Has_member_reference<_It>>::template _Apply<_It>; +}; + +_EXPORT_STD template +struct iterator_traits : _Iterator_traits_base<_Ty> { + using _From_primary = iterator_traits; +}; + +template + requires is_object_v<_Ty> +struct iterator_traits<_Ty*> { + using iterator_concept = contiguous_iterator_tag; + using iterator_category = random_access_iterator_tag; + using value_type = remove_cv_t<_Ty>; + using difference_type = ptrdiff_t; + using pointer = _Ty*; + using reference = _Ty&; +}; + +template +constexpr bool _Integer_class = requires { + typename _Ty::_Signed_type; + typename _Ty::_Unsigned_type; +}; + +template +concept _Integer_like = _Is_nonbool_integral<_Ty> || _Integer_class<_Ty>; + +template +concept _Signed_integer_like = _Integer_like<_Ty> && static_cast<_Ty>(-1) < static_cast<_Ty>(0); + +_EXPORT_STD template +concept weakly_incrementable = movable<_Ty> && requires(_Ty __i) { + typename iter_difference_t<_Ty>; + requires _Signed_integer_like>; + { ++__i } -> same_as<_Ty&>; + __i++; +}; + +_EXPORT_STD template +concept input_or_output_iterator = requires(_It __i) { + { *__i } -> _Can_reference; +} && weakly_incrementable<_It>; + +_EXPORT_STD template +concept sentinel_for = semiregular<_Se> && !_Integer_like<_Se> && input_or_output_iterator<_It> + && _Weakly_equality_comparable_with<_Se, _It>; + +_EXPORT_STD template // specializations allowed by N5014 [iterator.concept.sizedsentinel]/3 +constexpr bool disable_sized_sentinel_for = false; + +_EXPORT_STD template +concept sized_sentinel_for = sentinel_for<_Se, _It> && !disable_sized_sentinel_for, remove_cv_t<_It>> + && requires(const _It& __i, const _Se& __s) { + { __s - __i } -> same_as>; + { __i - __s } -> same_as>; + }; + +_EXPORT_STD struct default_sentinel_t {}; + +_EXPORT_STD inline constexpr default_sentinel_t default_sentinel{}; + +namespace ranges { + _EXPORT_STD enum class subrange_kind : bool { unsized, sized }; + + _EXPORT_STD template _Se = _It, + subrange_kind _Ki = sized_sentinel_for<_Se, _It> ? subrange_kind::sized : subrange_kind::unsized> + requires (_Ki == subrange_kind::sized || !sized_sentinel_for<_Se, _It>) + class subrange; + + _EXPORT_STD template + requires ((_Idx == 0 && copyable<_It>) || _Idx == 1) + _NODISCARD constexpr auto get(const subrange<_It, _Se, _Ki>& _Val); + + _EXPORT_STD template + requires (_Idx < 2) + _NODISCARD constexpr auto get(subrange<_It, _Se, _Ki>&& _Val); +} // namespace ranges + +_EXPORT_STD using ranges::get; + +template +constexpr bool _Is_subrange_v> = true; + +template +struct tuple_size> : integral_constant {}; + +template +struct tuple_element<0, ranges::subrange<_It, _Se, _Ki>> { + using type = _It; +}; + +template +struct tuple_element<1, ranges::subrange<_It, _Se, _Ki>> { + using type = _Se; +}; + +template +struct tuple_element<0, const ranges::subrange<_It, _Se, _Ki>> { + using type = _It; +}; + +template +struct tuple_element<1, const ranges::subrange<_It, _Se, _Ki>> { + using type = _Se; +}; +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +template +struct _Iterator_traits_base {}; // empty for non-iterators + +template +struct _Iterator_traits_base<_Iter, + void_t> { + // defined if _Iter::* types exist + using iterator_category = typename _Iter::iterator_category; + using value_type = typename _Iter::value_type; + using difference_type = typename _Iter::difference_type; + using pointer = typename _Iter::pointer; + using reference = typename _Iter::reference; +}; + +template > +struct _Iterator_traits_pointer_base { // iterator properties for pointers to object + using iterator_category = random_access_iterator_tag; + using value_type = remove_cv_t<_Ty>; + using difference_type = ptrdiff_t; + using pointer = _Ty*; + using reference = _Ty&; +}; + +template +struct _Iterator_traits_pointer_base<_Ty, false> {}; // iterator non-properties for pointers to non-object + +template +struct iterator_traits : _Iterator_traits_base<_Iter> {}; // get traits from iterator _Iter, if possible + +template +struct iterator_traits<_Ty*> : _Iterator_traits_pointer_base<_Ty> {}; // get traits from pointer, if possible + +template +constexpr bool _Integer_like = _Is_nonbool_integral<_Ty>; + +template +constexpr bool _Signed_integer_like = _Integer_like<_Ty> && is_signed_v<_Ty>; +#endif // ^^^ !_HAS_CXX20 ^^^ + +_INLINE_VAR constexpr auto _Meta_npos = ~size_t{0}; + +constexpr size_t _Meta_find_index_i_(const bool* const _Ptr, const size_t _Count, size_t _Idx = 0) { + // return the index of the first true in the _Count bools at _Ptr, or _Meta_npos if all are false + for (; _Idx < _Count; ++_Idx) { + if (_Ptr[_Idx]) { + return _Idx; + } + } + + return _Meta_npos; +} + +template +struct _Meta_find_unique_index_ { + using type = integral_constant; +}; +template +using _Meta_find_unique_index = + // The index of _Ty in _List if it occurs exactly once, otherwise _Meta_npos + typename _Meta_find_unique_index_<_List, _Ty>::type; + +constexpr size_t _Meta_find_unique_index_i_2(const bool* const _Ptr, const size_t _Count, const size_t _First) { + // return _First if there is no _First < j < _Count such that _Ptr[j] is true, otherwise _Meta_npos + return _First != _Meta_npos && _STD _Meta_find_index_i_(_Ptr, _Count, _First + 1) == _Meta_npos ? _First + : _Meta_npos; +} + +constexpr size_t _Meta_find_unique_index_i_(const bool* const _Ptr, const size_t _Count) { + // Pass the smallest i such that _Ptr[i] is true to _Meta_find_unique_index_i_2 + return _STD _Meta_find_unique_index_i_2(_Ptr, _Count, _STD _Meta_find_index_i_(_Ptr, _Count)); +} + +template