Claude-skill-registry C++ Ecosystem
This skill should be used when working with C++ projects, CMakeLists.txt, Ninja, clang-tidy, clang-format, GoogleTest, Catch2, or Modern C++ (C++11-23) language patterns. Provides comprehensive C++ ecosystem patterns and best practices.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cplusplus-ecosystem" ~/.claude/skills/majiayu000-claude-skill-registry-c-ecosystem-0afb2c && rm -rf "$T"
skills/data/cplusplus-ecosystem/SKILL.md<cplusplus_language> <modern_features> <decision_tree name="when_to_use"> <question>Are you working with modern C++ features like smart pointers, move semantics, or ranges?</question> <if_yes>Apply modern C++ patterns for safer, more efficient code</if_yes> <if_no>Consider refactoring legacy code to modern C++ standards</if_no> </decision_tree>
<concept name="move_semantics"> <description>Transfer ownership of resources without copying. Introduced in C++11.</description> <example> std::vector<int> v1 = {1, 2, 3}; std::vector<int> v2 = std::move(v1); // v1 is now empty </example> <use>Use std::move for expensive-to-copy objects when ownership transfer is intended</use> </concept> <concept name="smart_pointers"> <description>RAII-based automatic memory management</description> <types> <type name="unique_ptr">Exclusive ownership, zero overhead</type> <type name="shared_ptr">Shared ownership with reference counting</type> <type name="weak_ptr">Non-owning observer of shared_ptr</type> </types> <example> auto ptr = std::make_unique<MyClass>(args); auto shared = std::make_shared<MyClass>(args); </example> </concept> <concept name="constexpr"> <description>Compile-time computation</description> <evolution> <version name="C++11">Simple expressions only</version> <version name="C++14">Loops and local variables allowed</version> <version name="C++17">if constexpr for compile-time branching</version> <version name="C++20">constexpr std::vector, std::string</version> </evolution> </concept> <concept name="auto_type_deduction"> <description>Compiler deduces type from initializer</description> <example> auto x = 42; // int auto vec = std::vector<int>{}; // std::vector<int> auto [key, value] = pair; // structured bindings (C++17) </example> </concept> <concept name="lambdas"> <description>Anonymous function objects</description> <example> auto add = [](int a, int b) { return a + b; }; auto capture_by_ref = [&x]() { x++; }; auto capture_by_val = [=]() { return x; }; auto generic = [](auto a, auto b) { return a + b; }; // C++14 </example> </concept> <concept name="concepts"> <description>Constraints on template parameters (C++20)</description> <example> template<typename T> concept Addable = requires(T a, T b) { a + b; }; template<Addable T> T add(T a, T b) { return a + b; } </example> </concept> <concept name="ranges"> <description>Composable range operations (C++20)</description> <example> auto result = numbers | std::views::filter([](int n) { return n % 2 == 0; }) | std::views::transform([](int n) { return n * 2; }); </example> </concept> <concept name="modules"> <description>C++20 modules for faster compilation and better encapsulation</description> <example> // math.cppm (module interface) export module math; export int add(int a, int b) { return a + b; } // main.cpp import math; int main() { return add(1, 2); } </example> <note>Requires CMake 3.28+ with CMAKE_CXX_SCAN_FOR_MODULES</note> </concept> <concept name="coroutines"> <description>C++20 coroutines for async and generator patterns</description> <example> #include <coroutine> generator<int> range(int start, int end) { for (int i = start; i < end; ++i) { co_yield i; } } task<int> async_compute() { co_return co_await some_async_operation(); } </example> <note>Requires coroutine library (cppcoro, libcoro, or custom promise types)</note> </concept> <concept name="three_way_comparison"> <description>C++20 spaceship operator for simplified comparisons</description> <example> struct Point { int x, y; auto operator<=>(const Point&) const = default; }; // Automatically generates ==, !=, <, >, <=, >= </example> </concept> <concept name="vocabulary_types"> <description>C++17 vocabulary types for safer value handling</description> <types> <type name="std::optional">Maybe-value container, replaces nullable pointers</type> <type name="std::variant">Type-safe union, replaces raw unions</type> <type name="std::any">Type-erased container for any single value</type> </types> <example> std::optional<int> find_value(const std::vector<int>& v, int target) { auto it = std::find(v.begin(), v.end(), target); if (it != v.end()) return *it; return std::nullopt; } std::variant<int, std::string, double> data = 42; std::visit([](auto&& val) { std::cout << val; }, data); </example> </concept>
</modern_features>
<concurrency> <decision_tree name="when_to_use"> <question>Do you need concurrent or parallel execution?</question> <if_yes>Use std::thread for explicit control, std::async for task-based parallelism, or atomics for lock-free synchronization</if_yes> <if_no>Use single-threaded sequential execution for simplicity</if_no> </decision_tree></concurrency> <patterns> <pattern name="raii"> <description>Resource Acquisition Is Initialization - bind resource lifetime to object lifetime</description> <example> class FileHandle { FILE* file_; public: explicit FileHandle(const char* path) : file_(fopen(path, "r")) {} ~FileHandle() { if (file_) fclose(file_); } FileHandle(const FileHandle&) = delete; FileHandle& operator=(const FileHandle&) = delete; }; </example> <use_case>Managing resources: files, sockets, locks, memory</use_case> </pattern><concept name="threads"> <description>Thread creation and management</description> <example> std::thread t([]{ /* work */ }); t.join(); // or t.detach() auto future = std::async(std::launch::async, []{ return 42; }); int result = future.get(); </example> </concept> <concept name="mutexes"> <description>Mutual exclusion for shared data</description> <example> std::mutex mtx; std::lock_guard<std::mutex> lock(mtx); // RAII lock std::shared_mutex rw_mtx; std::shared_lock<std::shared_mutex> read_lock(rw_mtx); // multiple readers std::unique_lock<std::shared_mutex> write_lock(rw_mtx); // exclusive writer </example> </concept> <concept name="atomics"> <description>Lock-free atomic operations</description> <example> std::atomic<int> counter{0}; counter.fetch_add(1, std::memory_order_relaxed); counter.store(10, std::memory_order_release); int val = counter.load(std::memory_order_acquire); </example> </concept> <concept name="condition_variables"> <description>Thread synchronization primitives</description> <example> std::condition_variable cv; std::mutex mtx; bool ready = false; // Waiting thread std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{ return ready; }); // Notifying thread { std::lock_guard<std::mutex> lock(mtx); ready = true; } cv.notify_one(); </example> </concept> <anti_patterns> <avoid name="data_races"> <description>Accessing shared data without synchronization</description> <instead>Use mutex, atomic, or immutable data</instead> </avoid> <avoid name="deadlocks"> <description>Circular lock dependencies</description> <instead>Use std::scoped_lock for multiple mutexes, consistent lock ordering</instead> </avoid> </anti_patterns>
</patterns><pattern name="rule_of_zero"> <description>Prefer classes that do not define special member functions</description> <example> class Person { std::string name_; std::vector<std::string> addresses_; // No destructor, copy/move constructors, or assignment operators needed }; </example> <use_case>Use smart pointers and standard containers; let compiler generate defaults</use_case> </pattern> <pattern name="rule_of_five"> <description>If you define one of destructor, copy/move constructor, or copy/move assignment, define all five</description> <example> class Resource { int* data_; public: Resource(); ~Resource(); Resource(const Resource&); Resource(Resource&&) noexcept; Resource& operator=(const Resource&); Resource& operator=(Resource&&) noexcept; }; </example> <use_case>Classes managing raw resources directly</use_case> </pattern> <pattern name="pimpl"> <description>Pointer to Implementation - hide implementation details and reduce compilation dependencies</description> <example> // header class Widget { class Impl; std::unique_ptr<Impl> pimpl_; public: Widget(); ~Widget(); void doSomething(); }; // source class Widget::Impl { // implementation details }; </example> <use_case>Reducing compile times, ABI stability, hiding implementation</use_case> </pattern> <pattern name="crtp"> <description>Curiously Recurring Template Pattern - static polymorphism</description> <example> template<typename Derived> class Base { public: void interface() { static_cast<Derived*>(this)->implementation(); } }; class Derived : public Base<Derived> { public: void implementation() { /_ ... _/ } }; </example> <use_case>Static polymorphism, mixin classes, compile-time polymorphism</use_case> </pattern> <pattern name="type_erasure"> <description>Hide concrete types behind a uniform interface</description> <example> class AnyCallable { struct Concept { virtual ~Concept() = default; virtual void call() = 0; }; template<typename T> struct Model : Concept { T obj_; void call() override { obj_(); } }; std::unique_ptr<Concept> ptr_; public: template<typename T> AnyCallable(T obj) : ptr_(std::make_unique<Model<T>>(std::move(obj))) {} }; </example> <use_case>std::function, std::any, runtime polymorphism without inheritance</use_case> </pattern>
<anti_patterns> <avoid name="raw_pointer_ownership"> <description>Using raw pointers for ownership</description> <instead>Use std::unique_ptr or std::shared_ptr</instead> </avoid>
<avoid name="manual_memory_management"> <description>Using new/delete directly</description> <instead>Use std::make_unique/std::make_shared</instead> </avoid> <avoid name="c_style_casts"> <description>Using (Type)value casts</description> <instead>Use static_cast, dynamic_cast, const_cast, or reinterpret_cast</instead> </avoid> <avoid name="using_namespace_in_headers"> <description>Using using namespace std; in headers</description> <instead>Use fully qualified names or limited using declarations in source files</instead> </avoid> <avoid name="throwing_in_destructors"> <description>Throwing exceptions in destructors</description> <instead>Mark destructors noexcept, handle errors internally</instead> </avoid> <avoid name="const_cast_abuse"> <description>Using const_cast to remove const from data you do not own</description> <instead>Fix the design to avoid needing const_cast</instead> </avoid>
</anti_patterns> </cplusplus_language>
<cmake> <decision_tree name="when_to_use"> <question>Are you building a C++ project with dependencies and multiple targets?</question> <if_yes>Use CMake for cross-platform, modern build configuration</if_yes> <if_no>Use simple Makefile for single-file projects or prototypes</if_no> </decision_tree><project_structure> <standard_layout> . ├── CMakeLists.txt ├── cmake/ │ └── modules/ ├── src/ │ ├── CMakeLists.txt │ ├── main.cpp │ └── lib/ ├── include/ │ └── project/ ├── tests/ │ ├── CMakeLists.txt │ └── test_*.cpp └── build/ </standard_layout> </project_structure>
<cmake_patterns> <pattern name="modern_cmake"> <description>Target-based CMake (3.0+)</description> <example> cmake_minimum_required(VERSION 3.20) project(MyProject VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) add_library(mylib STATIC src/mylib.cpp) target_include_directories(mylib PUBLIC include) target_compile_features(mylib PUBLIC cxx_std_20) add_executable(myapp src/main.cpp) target_link_libraries(myapp PRIVATE mylib) </example> </pattern> <pattern name="find_package"> <description>Finding and using external dependencies</description> <example> find_package(Threads REQUIRED) find_package(GTest REQUIRED) target_link_libraries(myapp PRIVATE Threads::Threads) target_link_libraries(mytests PRIVATE GTest::gtest GTest::gtest_main) </example> </pattern> <pattern name="compiler_options"> <description>Setting compiler warnings and options</description> <example> add_library(project_warnings INTERFACE) target_compile_options(project_warnings INTERFACE $<$<CXX_COMPILER_ID:GNU,Clang>: -Wall -Wextra -Wpedantic -Werror -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual -Wconversion -Wsign-conversion -Wnull-dereference > ) </example> </pattern>
</cmake_patterns>
<commands> <command name="cmake -B build -G Ninja">Configure with Ninja generator</command> <command name="cmake --build build">Build the project</command> <command name="cmake --build build --target test">Run tests</command> <command name="cmake --build build --config Release">Build in Release mode</command> <command name="cmake --install build --prefix /usr/local">Install the project</command> </commands> </cmake> <toolchain> <compilers> <compiler name="clang"> <description>LLVM C++ compiler</description> <flags> <flag name="-std=c++20">Enable C++20 standard</flag> <flag name="-stdlib=libc++">Use LLVM libc++ standard library</flag> <flag name="-Wall -Wextra -Wpedantic">Enable comprehensive warnings</flag> <flag name="-Werror">Treat warnings as errors</flag> <flag name="-fsanitize=address,undefined">Enable sanitizers</flag> </flags> </compiler></compilers><compiler name="gcc"> <description>GNU C++ compiler</description> <flags> <flag name="-std=c++20">Enable C++20 standard</flag> <flag name="-Wall -Wextra -Wpedantic">Enable comprehensive warnings</flag> <flag name="-Werror">Treat warnings as errors</flag> <flag name="-fsanitize=address,undefined">Enable sanitizers</flag> <flag name="-fanalyzer">Enable static analysis (GCC 10+)</flag> </flags> </compiler>
<clang_tidy> <description>Static analysis and linting tool</description> <usage>clang-tidy src/*.cpp -- -std=c++20</usage>
<configuration> <file_reference>.clang-tidy</file_reference> Checks: > -*, bugprone-*, clang-analyzer-*, cppcoreguidelines-*, modernize-*, performance-*, readability-*, -modernize-use-trailing-return-type WarningsAsErrors: '_' HeaderFilterRegex: '._' CheckOptions: - key: readability-identifier-naming.ClassCase value: CamelCase - key: readability-identifier-naming.FunctionCase value: camelBack - key: readability-identifier-naming.VariableCase value: lower_case </configuration> <common_checks> <check name="modernize-use-nullptr">Replace NULL with nullptr</check> <check name="modernize-use-auto">Use auto where appropriate</check> <check name="modernize-use-override">Use override keyword</check> <check name="modernize-loop-convert">Convert C-style loops to range-based</check> <check name="cppcoreguidelines-owning-memory">Check ownership semantics</check> <check name="bugprone-use-after-move">Detect use-after-move bugs</check> <check name="performance-unnecessary-copy-initialization">Detect unnecessary copies</check> </common_checks>
</clang_tidy>
<clang_format> <description>Code formatting tool</description> <usage>clang-format -i src/.cpp include/.hpp</usage>
<configuration> <file_reference>.clang-format</file_reference> BasedOnStyle: LLVM IndentWidth: 4 ColumnLimit: 100 Language: Cpp Standard: c++20 AccessModifierOffset: -4 AlignAfterOpenBracket: Align AllowShortFunctionsOnASingleLine: Inline BreakBeforeBraces: Attach IncludeBlocks: Regroup IncludeCategories: - Regex: '^<.*>' Priority: 1 - Regex: '^".*"' Priority: 2 PointerAlignment: Left SortIncludes: CaseSensitive </configuration>
</clang_format>
<sanitizers> <description>Runtime error detection tools</description></sanitizers> </toolchain> <testing> <decision_tree name="when_to_use"> <question>Do you need unit testing for C++ code?</question> <if_yes>Use GoogleTest for comprehensive testing features or Catch2 for header-only simplicity</if_yes> <if_no>Consider adding tests to improve code quality and maintainability</if_no> </decision_tree> <googletest> <description>Google Test framework</description> <cmake_integration> enable_testing() find_package(GTest REQUIRED)<sanitizer name="AddressSanitizer"> <description>Detects memory errors (buffer overflow, use-after-free)</description> <flags>-fsanitize=address -fno-omit-frame-pointer</flags> <cmake> target_compile_options(myapp PRIVATE -fsanitize=address -fno-omit-frame-pointer) target_link_options(myapp PRIVATE -fsanitize=address) </cmake> </sanitizer> <sanitizer name="UndefinedBehaviorSanitizer"> <description>Detects undefined behavior (signed overflow, null dereference)</description> <flags>-fsanitize=undefined</flags> <cmake> target_compile_options(myapp PRIVATE -fsanitize=undefined) target_link_options(myapp PRIVATE -fsanitize=undefined) </cmake> </sanitizer> <sanitizer name="ThreadSanitizer"> <description>Detects data races and deadlocks</description> <flags>-fsanitize=thread</flags> <note>Cannot be combined with AddressSanitizer</note> </sanitizer> <sanitizer name="MemorySanitizer"> <description>Detects uninitialized memory reads (Clang only)</description> <flags>-fsanitize=memory</flags> <note>Requires all code and libraries to be instrumented</note> </sanitizer> <cmake_preset> # CMakePresets.json sanitizer configuration { "configurePresets": [{ "name": "sanitize", "cacheVariables": { "CMAKE_CXX_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer" } }] } </cmake_preset>
</googletest> <catch2> <description>Catch2 test framework</description> <cmake_integration> find_package(Catch2 3 REQUIRED)add_executable(tests tests/test_main.cpp) target_link_libraries(tests PRIVATE GTest::gtest GTest::gtest_main) include(GoogleTest) gtest_discover_tests(tests) </cmake_integration> <example> #include <gtest/gtest.h> TEST(MyTest, BasicAssertion) { EXPECT_EQ(1 + 1, 2); } TEST(MyTest, StringComparison) { std::string s = "hello"; EXPECT_STREQ(s.c_str(), "hello"); } class MyFixture : public ::testing::Test { protected: void SetUp() override { /_ setup _/ } void TearDown() override { /_ cleanup _/ } }; TEST_F(MyFixture, FixtureTest) { EXPECT_TRUE(true); } </example>
</catch2> </testing>add_executable(tests tests/test_main.cpp) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain) include(CTest) include(Catch) catch_discover_tests(tests) </cmake_integration> <example> #include <catch2/catch_test_macros.hpp> TEST_CASE("Basic arithmetic", "[math]") { REQUIRE(1 + 1 == 2); CHECK(2 * 2 == 4); } TEST_CASE("String operations", "[string]") { std::string s = "hello"; SECTION("length") { REQUIRE(s.length() == 5); } SECTION("comparison") { REQUIRE(s == "hello"); } } </example>
<context7_integration> <description>Use Context7 MCP for up-to-date C++ documentation</description>
<cplusplus_libraries> <library name="cppreference" id="/websites/cppreference_com" /> <library name="CMake" id="/Kitware/CMake" /> <library name="GoogleTest" id="/google/googletest" /> <library name="Catch2" id="/catchorg/Catch2" /> </cplusplus_libraries>
<usage_patterns> <pattern name="language_reference"> <step>resolve-library-id libraryName="cppreference"</step> <step>get-library-docs context7CompatibleLibraryID="/websites/cppreference_com" topic="std::unique_ptr"</step> </pattern>
<pattern name="cmake_reference"> <step>get-library-docs context7CompatibleLibraryID="/Kitware/CMake" topic="target_link_libraries"</step> </pattern> <pattern name="testing_reference"> <step>get-library-docs context7CompatibleLibraryID="/google/googletest" topic="assertions"</step> </pattern>
</usage_patterns> </context7_integration>
<best_practices> <practice priority="critical">Use smart pointers instead of raw pointers for ownership</practice> <practice priority="critical">Enable -Wall -Wextra -Werror for all builds</practice> <practice priority="critical">Run clang-tidy before committing</practice> <practice priority="critical">Format with clang-format for consistent style</practice> <practice priority="standard">Prefer const correctness throughout</practice> <practice priority="standard">Use noexcept for move constructors and destructors</practice> <practice priority="standard">Prefer constexpr for compile-time computation</practice> <practice priority="standard">Use std::string_view for non-owning string references</practice> <practice priority="standard">Prefer range-based for loops over index-based</practice> <practice priority="standard">Use structured bindings for tuple/pair access</practice> <practice priority="standard">Document public API with Doxygen comments</practice> <practice priority="standard">Write unit tests alongside implementation</practice> </best_practices>
<workflow> <phase name="analyze"> <objective>Understand C++ code requirements</objective> <step>1. Check CMakeLists.txt for build configuration</step> <step>2. Review existing code patterns and standards</step> <step>3. Identify memory management requirements</step> </phase> <phase name="implement"> <objective>Write modern, safe C++ code</objective> <step>1. Use RAII and smart pointers</step> <step>2. Follow C++ Core Guidelines</step> <step>3. Prefer standard library over raw implementations</step> </phase> <phase name="validate"> <objective>Verify C++ code correctness</objective> <step>1. Build with warnings enabled</step> <step>2. Run static analysis tools</step> <step>3. Execute tests with sanitizers</step> </phase> </workflow><error_escalation> <level severity="low"> <example>Compiler warning about unused variable</example> <action>Fix warning, maintain clean build</action> </level> <level severity="medium"> <example>Compilation error</example> <action>Fix error, verify with full build</action> </level> <level severity="high"> <example>Memory leak or undefined behavior detected</example> <action>Stop, require safe memory management</action> </level> <level severity="critical"> <example>Buffer overflow or security vulnerability</example> <action>Block operation, require immediate fix</action> </level> </error_escalation>
<constraints> <must>Use smart pointers for memory management</must> <must>Enable compiler warnings (-Wall -Wextra)</must> <must>Follow C++ Core Guidelines</must> <avoid>Raw pointers for ownership</avoid> <avoid>Manual memory management when smart pointers suffice</avoid> <avoid>Undefined behavior</avoid> </constraints><related_agents> <agent name="design">Architecture design for C++ class hierarchies and template metaprogramming</agent> <agent name="docs">Doxygen documentation and API reference generation</agent> <agent name="execute">CMake configuration and C++ implementation tasks</agent> <agent name="bug">Debugging memory leaks, segfaults, and undefined behavior</agent> </related_agents>
<related_skills> <skill name="serena-usage">Symbol operations for C++ code navigation and refactoring</skill> <skill name="context7-usage">C++ documentation via /websites/cppreference_com and CMake docs via /Kitware/CMake</skill> <skill name="investigation-patterns">Debugging with sanitizers, valgrind, and gdb</skill> <skill name="technical-documentation">Creating library documentation with Doxygen</skill> </related_skills>