1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#![feature(unique, unsize, fnbox, fn_traits, unboxed_closures, alloc, heap_api, allocator_api)]
/*!
Provides thin pointer types to dynamically sized types that implement the `DynSized` trait. By "thin", that means they store the metadata (i.e. slice length or vtable pointer) together with the data, instead of in the pointer itself. Currently provides `ThinBox`, a thin version of `Box`.

Example: storing a closure in a `ThinBox`;

```
extern crate thin;
#[macro_use] extern crate dyn_sized;
use thin::{ThinBox, FnMove};

// Define our own subtrait to get around the orphan rule for trait impls
// Have to use `FnMove` instead of `FnOnce` or `FnBox`
trait Closure: FnMove(&str) -> String {}
derive_DynSized!(Closure<Output=String>);

fn main() {
  let s1 = String::from("Hello");

  let closure: ThinBox<FnMove(&'static str) -> String> = ThinBox::new(move |s2|{
      s1 + " " + s2 + "!"
  });

  assert_eq!("Hello World!", closure("World"));
}
```

There's a couple things to notice here: one is that we needed to derive `DynSized` for our closure trait object type in order to store it in a `ThinBox`. And because of the orphan rule for trait impls, we needed to define our own trait `Closure` to do that. And the other thing to notice, is that our `Closure` trait has `FnMove` as a supertrait instead of `FnBox` or `FnOnce`, in order to be callable from inside a `ThinBox`. That's alright, though, since ThinBox<F: FnMove> implemnts FnOnce, and we're able to call the `ThinBox<Closure>` directly.
*/

#[allow(unused)]
#[macro_use]
pub extern crate dyn_sized;
extern crate fn_move;
extern crate alloc;

pub use dyn_sized::DynSized;
pub use fn_move::FnMove;

mod backend;
pub use backend::ThinBackend;

mod boxed;
pub use boxed::ThinBox;