> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Coroutine Handle

`std::coroutine_handle` is a non-owning, trivially copyable handle to a compiler-generated coroutine state (the coroutine frame). It provides the low-level interface required to resume execution of a suspended coroutine, query its execution status, access its associated promise object, or explicitly destroy its state.

Defined in the `<coroutine>` header, the handle acts essentially as a type-safe wrapper around a `void*` pointer pointing to the coroutine frame. While conceptually dynamically allocated, C++20 explicitly supports Heap Allocation Elision (HALO). This means the compiler is permitted to optimize the coroutine state to be allocated on the stack or inlined into the caller's frame, rather than strictly relying on heap allocation.

## Template Structure and Specializations

The handle is implemented as a class template with `void` as the default template argument (`template <typename Promise = void>`), alongside an explicit specialization for `void` (`coroutine_handle<void>`). There is no inheritance relationship between the primary template and the explicit specialization.

```cpp theme={"dark"}
namespace std {
    // Explicit specialization for the type-erased handle
    template <>
    struct coroutine_handle<void> {
        constexpr coroutine_handle() noexcept;
        constexpr coroutine_handle(nullptr_t) noexcept;
        coroutine_handle& operator=(nullptr_t) noexcept;
        
        // State observation
        constexpr explicit operator bool() const noexcept;
        bool done() const;
        
        // Execution control
        void operator()() const;
        void resume() const;
        
        // Lifecycle
        void destroy() const;
        
        // Interoperability
        constexpr void* address() const noexcept;
        static constexpr coroutine_handle from_address(void* addr);
    };

    // Primary template for the strongly-typed handle
    template <typename Promise>
    struct coroutine_handle {
        constexpr coroutine_handle() noexcept;
        constexpr coroutine_handle(nullptr_t) noexcept;
        coroutine_handle& operator=(nullptr_t) noexcept;

        // Implicit conversion to type-erased handle
        constexpr operator coroutine_handle<void>() const noexcept;
        
        // State observation
        constexpr explicit operator bool() const noexcept;
        bool done() const;
        
        // Execution control
        void operator()() const;
        void resume() const;
        
        // Lifecycle
        void destroy() const;
        
        // Interoperability
        constexpr void* address() const noexcept;
        static constexpr coroutine_handle from_address(void* addr);

        // Promise interaction
        Promise& promise() const;
        static coroutine_handle from_promise(Promise& p);
    };

    // Comparison operators
    constexpr bool operator==(coroutine_handle<void> x, coroutine_handle<void> y) noexcept;
    constexpr strong_ordering operator<=>(coroutine_handle<void> x, coroutine_handle<void> y) noexcept;

    // Hash support
    template <class P> struct hash<coroutine_handle<P>>;
}
```

### 1. `std::coroutine_handle<void>` (Type-Erased Handle)

Often written as `std::coroutine_handle<>`, this explicit specialization knows nothing about the coroutine's return type or promise object. It is used when the caller only needs to control the execution flow (resume or destroy) without interacting with the data yielded or returned by the coroutine.

### 2. `std::coroutine_handle<Promise>` (Strongly-Typed Handle)

The primary template is bound to a specific `Promise` type, allowing bidirectional data transfer between the caller and the coroutine frame via the promise object. It independently declares all the execution control and state observation methods found in the `void` specialization, alongside promise-specific methods and a conversion operator.

## Core Mechanics and Member Functions

### Execution Control

* **`resume()` / `operator()()`**: Resumes the execution of a suspended coroutine. The call blocks until the coroutine suspends again or runs to completion. Invoking `resume()` on a coroutine that is already executing, or one that has completed (`done() == true`), results in undefined behavior.

### State Observation

* **`done()`**: Returns `true` if the coroutine is suspended at its final suspension point, and `false` if suspended at any other point. **Crucially**, calling `done()` on a coroutine that is currently executing is **Undefined Behavior**. This method can only be safely invoked when the coroutine is known to be in a suspended state.
* **`operator bool()`**: Returns `true` if the handle points to a valid coroutine frame (i.e., the internal pointer is not `nullptr`). It does *not* indicate whether the coroutine has finished executing.

### Promise Interaction (Typed Handle Only)

* **`promise()`**: Returns a reference to the promise object stored inside the coroutine frame.
* **`from_promise(Promise& p)`**: A static factory function that reconstructs the `coroutine_handle` from a reference to the promise object. This relies on the compiler's deterministic memory layout of the coroutine frame.

### Memory and Lifecycle Management

* **`destroy()`**: Explicitly destroys the coroutine frame, invoking the destructors of all in-scope local variables and the promise object, and deallocates the memory. Like `done()`, calling `destroy()` on a currently executing coroutine is undefined behavior.

**Crucial Lifecycle Semantics:** `std::coroutine_handle` does **not** implement RAII. It is a raw handle. If a handle goes out of scope, the underlying coroutine frame is not automatically destroyed, leading to a memory leak. Conversely, if a coroutine reaches the end of its execution and its promise type's `final_suspend` returns `std::suspend_never`, the frame destroys itself automatically, leaving any existing `coroutine_handle` instances dangling.

### Interoperability

* **`address()`**: Extracts the underlying `void*` pointer. Useful for passing the coroutine through C-style APIs or storing it in type-erased contexts.
* **`from_address(void* addr)`**: Reconstructs a `coroutine_handle` from a raw pointer previously obtained via `address()`. This function is intentionally *not* `noexcept` because it possesses a narrow contract: passing an invalid or unaligned address results in undefined behavior.

### Identity and Comparison

The `<coroutine>` header defines namespace-scope comparison operators (`operator==` and `operator<=>`) and specializes `std::hash` for the handle. These operate directly on the underlying memory addresses, allowing handles to be checked for identity or used as keys in associative containers (e.g., `std::unordered_map` or `std::set`). Because strongly-typed handles implicitly convert to `coroutine_handle<void>`, these operators seamlessly support all handle types.

## Type Conversion

Because the primary template provides an implicit conversion operator (`operator coroutine_handle<void>()`), implicit type conversion is supported. You can pass a strongly-typed handle to any function expecting a type-erased handle.

Converting back from a type-erased handle to a strongly-typed handle requires explicit reconstruction using the underlying memory address.

```cpp theme={"dark"}
std::coroutine_handle<MyPromise> typed_handle = /* ... */;

// Implicit type conversion to type-erased handle
std::coroutine_handle<> erased_handle = typed_handle; 

// Explicit reconstruction requires using the raw address
std::coroutine_handle<MyPromise> restored_handle = 
    std::coroutine_handle<MyPromise>::from_address(erased_handle.address());
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C++ Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
