{{#title rust::Box — Rust ♡ C++}}
# rust::Box\

### Public API:

```cpp,hidelines
// rust/cxx.h
#
# #include 
#
# namespace rust {

template 
class Box final {
public:
  using element_type = T;
  using const_pointer =
      typename std::add_pointer::type>::type;
  using pointer = typename std::add_pointer::type;

  Box(Box &&) noexcept;
  ~Box() noexcept;

  explicit Box(const T &);
  explicit Box(T &&);

  Box &operator=(Box &&) noexcept;

  const T *operator->() const noexcept;
  const T &operator*() const noexcept;
  T *operator->() noexcept;
  T &operator*() noexcept;

  template 
  static Box in_place(Fields &&...);

  void swap(Box &) noexcept;

  // Important: requires that `raw` came from an into_raw call. Do not
  // pass a pointer from `new` or any other source.
  static Box from_raw(T *) noexcept;

  T *into_raw() noexcept;
};
#
# } // namespace rust
```

### Restrictions:

Box\ does not support T being an opaque C++ type. You should use
[UniquePtr\](uniqueptr.md) or [SharedPtr\](sharedptr.md) instead for
transferring ownership of opaque C++ types on the language boundary.

If T is an opaque Rust type, the Rust type is required to be [Sized] i.e. size
known at compile time. In the future we may introduce support for dynamically
sized opaque Rust types.

[Sized]: https://doc.rust-lang.org/std/marker/trait.Sized.html

## Example

This program uses a Box to pass ownership of some opaque piece of Rust state
over to C++ and then back to a Rust callback, which is a useful pattern for
implementing [async functions over FFI](../async.md).

```rust,noplayground
// src/main.rs

use std::io::Write;

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        type File;
    }

    unsafe extern "C++" {
        include!("example/include/example.h");

        fn f(
            callback: fn(Box, fst: &str, snd: &str),
            out: Box,
        );
    }
}

pub struct File(std::fs::File);

fn main() {
    let out = std::fs::File::create("example.log").unwrap();

    ffi::f(
        |mut out, fst, snd| { let _ = write!(out.0, "{}{}\n", fst, snd); },
        Box::new(File(out)),
    );
}
```

```cpp
// include/example.h

#pragma once
#include "example/src/main.rs.h"
#include "rust/cxx.h"

void f(rust::Fn, rust::Str, rust::Str)> callback,
       rust::Box out);
```

```cpp
// include/example.cc

#include "example/include/example.h"

void f(rust::Fn, rust::Str, rust::Str)> callback,
       rust::Box out) {
  callback(std::move(out), "fearless", "concurrency");
}
```