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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
//! # dropcount
//! Count destructor calls.
//!
//! Rust is memory safe, but memory bugs may occur in unsafe blocks.
//! The unsafe programming is often required when implementing our own data structures like
//! containers or smart pointers.
//! This crate provides a way to test memory leaks or multiple destruction by counting destructor calls.
//!
//! If this crate is used only for tests, use 'dev-dependencies' section in Cargo.toml as follows;
//! ```toml
//! # Cargo.toml
//! [dev-dependencies]
//! dropcount = "0.1"
//! ```
//!
//! ## Usage
//! ```
//! // Create a pair of counter and viewer.
//! // They share an internal count value.
//! let (counter, viewer) = dropcount::new();
//!
//! // The viewer returns 0.
//! // The counter has not been destructed.
//! assert_eq!(viewer.get(), 0);
//!
//! // Destruct the counter.
//! drop(counter);
//!
//! // The viewer returns 1 after destructing the counter.
//! assert_eq!(viewer.get(), 1);
//! ```
//!
//! ## Example
//! ### Testing smart pointers
//! An example for testing a smart pointer destructs its value exactly once.
//! ```
//! use std::rc::Rc;
//!
//! fn test_rc() {
//! let (counter, viewer) = dropcount::new();
//!
//! // rc1 and rc2 shares the counter object.
//! let rc1 = Rc::new(counter);
//! let rc2 = rc1.clone();
//!
//! // The counter is not destructed.
//! assert_eq!(viewer.get(), 0);
//!
//! drop(rc1);
//!
//! // The counter is not destructed.
//! assert_eq!(viewer.get(), 0);
//!
//! drop(rc2);
//!
//! // The counter is destructed.
//! assert_eq!(viewer.get(), 1);
//! }
//!
//! # fn main() {
//! # test_rc();
//! # }
//! ```
//!
//! ### Testing collections
//! An example for testing a container destructs each value exactly once.
//! ```
//! use std::collections::HashMap;
//!
//! fn test_hashmap() {
//! let (counters, viewers) = dropcount::new_vec(5);
//!
//! let mut map: HashMap<usize, dropcount::Counter> =
//! counters.into_iter().enumerate().collect();
//!
//! assert_eq!(viewers[0].get(), 0);
//! assert_eq!(viewers[1].get(), 0);
//! assert_eq!(viewers[2].get(), 0);
//! assert_eq!(viewers[3].get(), 0);
//! assert_eq!(viewers[4].get(), 0);
//!
//! // Remove an element.
//! map.remove(&2);
//!
//! // The viewer paired with the removed element returns 1.
//! assert_eq!(viewers[0].get(), 0);
//! assert_eq!(viewers[1].get(), 0);
//! assert_eq!(viewers[2].get(), 1);
//! assert_eq!(viewers[3].get(), 0);
//! assert_eq!(viewers[4].get(), 0);
//!
//! // Drop the container.
//! drop(map);
//!
//! // All viewers returns 1 after the container is dropped.
//! assert_eq!(viewers[0].get(), 1);
//! assert_eq!(viewers[1].get(), 1);
//! assert_eq!(viewers[2].get(), 1);
//! assert_eq!(viewers[3].get(), 1);
//! assert_eq!(viewers[4].get(), 1);
//! }
//!
//! # fn main() {
//! # test_hashmap();
//! # }
//! ```
//!
//! ### Multi-threading support
//! This crate supports multi-threading.
//! Atomic integers are used as the internal coutner values.
//! Therefore, it is possible to capture the number of destructions with multi-threading.
//! ```
//! use std::thread;
//!
//! fn test_multi_thread() {
//! let (counter, viewer) = dropcount::new();
//!
//! let handle = thread::spawn(move || {
//! drop(counter);
//! });
//!
//! handle.join().expect("Error in thread.");
//!
//! assert_eq!(viewer.get(), 1);
//! }
//!
//! # fn main() {
//! # test_multi_thread();
//! # }
//! ```
pub use ;