tock_cells/
numeric_cell_ext.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! `NumericCellExt` extension trait for `Cell`s.
6//!
7//! Adds a suite of convenience functions to `Cell`s that contain numeric
8//! types. Cells that contains types that can meaningfully execute arithmetic
9//! operations can use mechanisms such as `cell.add(val)` rather than
10//! `cell.set(cell.get() + val)`.
11//!
12//! To use these traits, simply pull them into scope:
13//!
14//! ```rust
15//! extern crate tock_cells;
16//! use tock_cells::numeric_cell_ext::NumericCellExt;
17//! ```
18
19use core::cell::Cell;
20use core::ops::{Add, Sub};
21
22pub trait NumericCellExt<T>
23where
24    T: Copy + Add + Sub,
25{
26    /// Add the passed in `val` to the stored value.
27    fn add(&self, val: T);
28
29    /// Subtract the passed in `val` from the stored value.
30    fn subtract(&self, val: T);
31
32    /// Add 1 to the stored value.
33    fn increment(&self);
34
35    /// Subtract 1 from the stored value.
36    fn decrement(&self);
37
38    /// Return the current value and then add 1 to the stored value.
39    fn get_and_increment(&self) -> T;
40
41    /// Return the current value and then subtract 1 from the stored value.
42    fn get_and_decrement(&self) -> T;
43}
44
45impl<T> NumericCellExt<T> for Cell<T>
46where
47    T: Add<Output = T> + Sub<Output = T> + Copy + From<usize>,
48{
49    fn add(&self, val: T) {
50        self.set(self.get() + val);
51    }
52
53    fn subtract(&self, val: T) {
54        self.set(self.get() - val);
55    }
56
57    fn increment(&self) {
58        self.set(self.get() + T::from(1_usize));
59    }
60
61    fn decrement(&self) {
62        self.set(self.get() - T::from(1_usize));
63    }
64
65    fn get_and_increment(&self) -> T {
66        let ret = self.get();
67        self.set(ret + T::from(1_usize));
68        ret
69    }
70
71    fn get_and_decrement(&self) -> T {
72        let ret = self.get();
73        self.set(ret - T::from(1_usize));
74        ret
75    }
76}