Back to list
takeokunn

c-ecosystem

by takeokunn

takeokunn's nixos-configuration

59🍴 0📅 Jan 23, 2026

SKILL.md


name: C++ Ecosystem description: 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.

<cplusplus_language> <modern_features> <decision_tree name="when_to_use"> Are you working with modern C++ features like smart pointers, move semantics, or ranges? <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&lt;int&gt; v1 = {1, 2, 3};
    std::vector&lt;int&gt; 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&lt;MyClass&gt;(args);
    auto shared = std::make_shared&lt;MyClass&gt;(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&lt;int&gt;{};  // std::vector&lt;int&gt;
    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 = [&amp;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&lt;typename T&gt;
    concept Addable = requires(T a, T b) { a + b; };

    template&lt;Addable T&gt;
    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 &lt;coroutine&gt;

    generator&lt;int&gt; range(int start, int end) {
      for (int i = start; i &lt; end; ++i) {
        co_yield i;
      }
    }

    task&lt;int&gt; 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&lt;=&gt;(const Point&amp;) const = default;
    };

    // Automatically generates ==, !=, &lt;, &gt;, &lt;=, &gt;=
  </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&lt;int&gt; find_value(const std::vector&lt;int&gt;&amp; v, int target) {
      auto it = std::find(v.begin(), v.end(), target);
      if (it != v.end()) return *it;
      return std::nullopt;
    }

    std::variant&lt;int, std::string, double&gt; data = 42;
    std::visit([](auto&amp;&amp; val) { std::cout &lt;&lt; val; }, data);
  </example>
</concept>

</modern_features>

<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&lt;std::mutex&gt; lock(mtx);  // RAII lock

    std::shared_mutex rw_mtx;
    std::shared_lock&lt;std::shared_mutex&gt; read_lock(rw_mtx); // multiple readers
    std::unique_lock&lt;std::shared_mutex&gt; write_lock(rw_mtx); // exclusive writer
  </example>
</concept>

<concept name="atomics">
  <description>Lock-free atomic operations</description>
  <example>
    std::atomic&lt;int&gt; 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&lt;std::mutex&gt; lock(mtx);
    cv.wait(lock, []{ return ready; });

    // Notifying thread
    {
      std::lock_guard&lt;std::mutex&gt; 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>
<pattern name="rule_of_zero">
  <description>Prefer classes that do not define special member functions</description>
  <example>
    class Person {
      std::string name_;
      std::vector&lt;std::string&gt; 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&amp;);
      Resource(Resource&amp;&amp;) noexcept;
      Resource&amp; operator=(const Resource&amp;);
      Resource&amp; operator=(Resource&amp;&amp;) 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&lt;Impl&gt; 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&lt;typename Derived&gt;
    class Base {
    public:
      void interface() {
        static_cast&lt;Derived*&gt;(this)-&gt;implementation();
      }
    };

    class Derived : public Base&lt;Derived&gt; {
    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&lt;typename T&gt;
      struct Model : Concept {
        T obj_;
        void call() override { obj_(); }
      };
      std::unique_ptr&lt;Concept&gt; ptr_;
    public:
      template&lt;typename T&gt;
      AnyCallable(T obj) : ptr_(std::make_unique&lt;Model&lt;T&gt;&gt;(std::move(obj))) {}
    };
  </example>
  <use_case>std::function, std::any, runtime polymorphism without inheritance</use_case>
</pattern>

<anti_patterns> Using raw pointers for ownership Use std::unique_ptr or std::shared_ptr

<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>

<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> Target-based CMake (3.0+) 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
      $&lt;$&lt;CXX_COMPILER_ID:GNU,Clang&gt;:
        -Wall -Wextra -Wpedantic -Werror
        -Wshadow -Wnon-virtual-dtor -Wold-style-cast
        -Wcast-align -Wunused -Woverloaded-virtual
        -Wconversion -Wsign-conversion -Wnull-dereference
      &gt;
    )
  </example>
</pattern>

</cmake_patterns>

<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> Static analysis and linting tool clang-tidy src/*.cpp -- -std=c++20

<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> Code formatting tool clang-format -i src/.cpp include/.hpp

<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>

<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>
  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 &lt;gtest/gtest.h&gt;

  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>
  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 &lt;catch2/catch_test_macros.hpp&gt;

  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> Use Context7 MCP for up-to-date C++ documentation

<cplusplus_libraries> </cplusplus_libraries>

<usage_patterns> resolve-library-id libraryName="cppreference" get-library-docs context7CompatibleLibraryID="/websites/cppreference_com" topic="std::unique_ptr"

<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> Use smart pointers instead of raw pointers for ownership Enable -Wall -Wextra -Werror for all builds Run clang-tidy before committing Format with clang-format for consistent style Prefer const correctness throughout Use noexcept for move constructors and destructors Prefer constexpr for compile-time computation Use std::string_view for non-owning string references Prefer range-based for loops over index-based Use structured bindings for tuple/pair access Document public API with Doxygen comments Write unit tests alongside implementation </best_practices>

<error_escalation> Compiler warning about unused variable Fix warning, maintain clean build Compilation error Fix error, verify with full build Memory leak or undefined behavior detected Stop, require safe memory management Buffer overflow or security vulnerability Block operation, require immediate fix </error_escalation>

<related_skills> Symbol operations for C++ code navigation and refactoring C++ documentation via /websites/cppreference_com and CMake docs via /Kitware/CMake Debugging with sanitizers, valgrind, and gdb Creating library documentation with Doxygen </related_skills>

Score

Total Score

55/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon