Files
qt-migration-legatus/scripts/migration-cpp23.prompt
T
2026-08-13 16:59:32 +00:00

120 lines
6.5 KiB
Plaintext

# GitHub Copilot Repository Instructions: C++ Modernization
## Project Context
- **Language:** C++
- **Target Standard:** C++23 (Strict enforcement)
- **Migration Goal:** Systematically upgrade legacy C++11/C++14/C++17 code to modern C++23 paradigms.
## Core Objective
Modernize the codebase incrementally and safely. Preserve existing behavior unless the task explicitly requests functional changes. Prefer small, reviewable refactors that improve correctness, safety, readability, and maintainability.
## Global Migration Principles
- Preserve semantics first; modernize second.
- Prefer standard C++23 library facilities over custom utilities where equivalent.
- Favor compile-time validation, explicit ownership, and strong type safety.
- Reduce boilerplate only when readability improves.
- Avoid unnecessary churn in code that is already modern and clear.
- Keep ABI-sensitive or externally exposed interfaces stable unless breaking changes are explicitly allowed.
- For larger migrations, refactor file-by-file or subsystem-by-subsystem.
## Migration Rules
### 1. Type Inference & Variables
- Replace explicit types with `auto` where the type is obvious from the initializer.
- Do not use `auto` when it obscures important type information or changes value/reference semantics unintentionally.
- Prefer `const auto` and `const auto&` where appropriate.
- Use structured bindings (`auto [x, y] = ...`) instead of `std::tie`, `.first/.second`, or tuple indexing where it improves clarity.
- Prefer uniform initialization where appropriate.
### 2. Memory & Resource Management
- Replace raw owning pointers and manual `delete` with `std::unique_ptr` or `std::shared_ptr`.
- Prefer `std::unique_ptr` by default; use `std::shared_ptr` only for true shared ownership.
- Use `std::make_unique` and `std::make_shared`.
- Enforce RAII for all resource management.
- Replace manual lifetime management with scoped objects where possible.
- Distinguish clearly between owning and non-owning access; prefer references, `std::span`, or observer-style usage for non-owning views.
### 3. Containers, Views & Strings
- Use `std::string_view` for read-only string parameters where lifetime safety is guaranteed.
- Never introduce dangling `std::string_view`.
- Replace `if (items.find(key) != items.end())` with `if (items.contains(key))` where supported.
- Prefer `.starts_with()`, `.ends_with()`, and `.contains()` when they improve readability.
- Prefer `std::span` for non-owning contiguous views.
- Use `std::mdspan` for multidimensional indexing only where it meaningfully improves safety or clarity.
- Prefer standard algorithms and ranges over manual loops when they improve readability and maintainability.
- Avoid unnecessary copies; prefer move semantics, `emplace`, and views where safe.
### 4. Control Flow & Error Handling
- Prefer early returns over deep nesting.
- Use `[[nodiscard]]` for functions whose return values should not be ignored.
- Modernize `std::optional` usage with `.and_then()`, `.transform()`, and `.or_else()` where this makes the logic clearer.
- Replace sentinel values with `std::optional`, strong types, or `std::expected` if supported by the project/toolchain.
- Preserve existing exception guarantees and error behavior unless changes are explicitly requested.
### 5. Formatting & Output
- Replace `printf` and legacy `<iostream>` console output with `<print>` where toolchain support exists.
- Use `std::print` and `std::println` for standard console output.
- If `<print>` is unavailable in the project toolchain, note the limitation and prefer the most modern supported alternative.
- Do not mix output styles in the same updated code path without a strong reason.
### 6. Compile-Time Optimization & Templates
- Maximize appropriate use of `constexpr`.
- Use `consteval` and `constinit` where semantically beneficial.
- Replace legacy SFINAE / `std::enable_if` with Concepts and `requires` clauses.
- Use `if constexpr` to simplify compile-time branching.
- Prefer readable template constraints and diagnostics over complex metaprogramming.
### 7. API & Interface Modernization
- Add `noexcept` where correct and useful.
- Use `override` consistently for overridden virtual functions.
- Use `final` where appropriate.
- Prefer `= default` and `= delete` for special member functions.
- Prefer `enum class` over unscoped enums where practical.
- Replace output parameters with return values or small result structs where this improves clarity and does not break required interfaces.
### 8. Concurrency & Time
- Prefer modern standard library concurrency primitives.
- Use `std::jthread` instead of `std::thread` where automatic joining and cancellation semantics are beneficial.
- Prefer typed `std::chrono` durations and literals over raw integer time values.
## Code Style Enforcement
- Avoid C-style macros where `constexpr`, `const`, enums, or inline functions are better.
- Never introduce deprecated or removed standard library facilities.
- Prefer expressive, self-documenting code over mechanical modernization.
- Keep includes minimal and correct.
- Avoid hidden lifetime bugs, dangling references, dangling views, and ownership ambiguity.
- Preserve repository formatting and local style conventions unless explicitly changing them.
## Safety Constraints
- Do not change business logic unless explicitly requested.
- Do not silently alter ownership semantics without calling it out.
- Do not replace code with newer constructs if the result is harder to read.
- Do not introduce C++23 features that are unsupported by the project compiler/toolchain.
- Highlight any modernization that may affect ABI, performance, exception behavior, or object lifetime.
## Review Checklist
For each proposed migration, verify:
- Behavior is preserved.
- Ownership and lifetime are clearer and safer.
- Readability is improved.
- Interface compatibility is maintained unless breaking changes are allowed.
- C++23 features are applied only where beneficial.
- Toolchain compatibility is respected.
- Tests and warnings should still pass after the change.
## Expected Copilot Behavior
When modernizing code:
1. Start from the existing implementation and refactor incrementally.
2. Prefer minimal, reviewable patches over broad rewrites.
3. Briefly explain non-trivial modernizations.
4. Call out risky or behavior-adjacent changes explicitly.
5. Provide optional follow-up refactors separately when they are useful but non-essential.
6. Avoid touching unrelated code.
## Preferred Output Format
For each migration task, provide:
- the modernized code,
- a short rationale,
- any compatibility/toolchain caveats,
- and optional next-step improvements.tes