alloc_counter 0.0.1

Count allocations, reallocations, deallocations. Allow, deny, or forbid allocations on an expression or function basis.
Documentation
# alloc_counter

## Alloc counters

A redesign of the [Quick and Dirty Allocation Profiling
Tool](https://github.com/bspeice/qadapt).


### Features

* Count allocations, reallocations and deallocations individually with `count_alloc`.

* Allow, deny, and forbid use of the global allocator with `allow_alloc`, `deny_alloc` and
`forbid_alloc`.

* `#[no_alloc]` function attribute to deny and `#[no_alloc(forbid)]` to forbid use of the
global allocator.


### Limitations and known issues

* Methods must either take a reference to `self` or `Self` must be a `Copy` type.


### Usage

An `AllocCounter<A>` wraps an allocator `A` to individually count the number of calls to
`alloc`, `realloc`, and `dealloc`.

```rust
use alloc_counter::AllocCounter;

#[global_allocator]
static A: AllocCounter<MyAllocator> = AllocCounter(MyAllocator);
```

Std-users may prefer to inherit their system's allocator.

```rust
use alloc_counter::AllocCounterSystem;

#[global_allocator]
static A: AllocCounterSystem = AllocCounterSystem;
```

To count the allocations of an expression, use `count_alloc`.

```rust
assert_eq!(
    count_alloc(|| {
        // no alloc
        let mut v = Vec::new();
        // alloc
        v.push(0);
        // realloc
        v.push(1);
        // dealloc
    })
    .0,
    (1, 1, 1)
);
```

To deny allocations for an expression use `deny_alloc`.

```rust
fn foo(b: Box<i32>) {
    // dropping causes a panic
    deny_alloc(|| drop(b))
}
foo(Box::new(0));
```

Similar to Rust's lints, you can still allow allocation inside a deny block.

```rust
fn foo(b: Box<i32>) {
    deny_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));
```

Forbidding allocations forces a panic even when `allow_alloc` is used.

```rust
fn foo(b: Box<i32>) {
    // panics because of outer `forbid`, even though drop happens in an allow block
    forbid_alloc(|| allow_alloc(|| drop(b)))
}
foo(Box::new(0));
```

For added sugar you may use the `#[no_alloc]` attribute on functions, including methods with
self-binds. `#[no_alloc]` expands to calling `deny_alloc` and forcefully moves the parameters
into the checked block. `#[no_alloc(forbid)]` calls `forbid_alloc`.

```rust
#[no_alloc(forbid)]
fn foo(b: Box<i32>) {
    allow_alloc(|| drop(b))
}
foo(Box::new(0));
```

License: MIT OR Apache-2.0