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
// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
// SPDX-License-Identifier: Apache-2.0
#![allow(dead_code)]
//! Copy-on-write wrapper stub — shares the inner value between handles until
//! a mutable write is requested, at which point the data is cloned so that
//! other readers remain unaffected.
use std::sync::Arc;
/// A copy-on-write wrapper that shares data until mutation is requested.
pub struct CowHandle<T: Clone> {
inner: Arc<T>,
}
impl<T: Clone> CowHandle<T> {
/// Create a new handle owning `value`.
pub fn new(value: T) -> Self {
Self {
inner: Arc::new(value),
}
}
/// Borrow the inner value without cloning.
pub fn read(&self) -> &T {
&self.inner
}
/// Get a mutable reference, cloning the inner value if shared.
pub fn write(&mut self) -> &mut T {
Arc::make_mut(&mut self.inner)
}
/// Number of handles sharing this data.
pub fn ref_count(&self) -> usize {
Arc::strong_count(&self.inner)
}
/// Returns true if the inner data is exclusively owned (no sharing).
pub fn is_exclusive(&self) -> bool {
Arc::strong_count(&self.inner) == 1
}
/// Clone the handle without cloning the data (shared reference).
pub fn share(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
/// Create a new copy-on-write handle.
pub fn new_cow_handle<T: Clone>(value: T) -> CowHandle<T> {
CowHandle::new(value)
}
/// Share a handle without copying data.
pub fn cow_share<T: Clone>(h: &CowHandle<T>) -> CowHandle<T> {
h.share()
}
/// Read the current value.
pub fn cow_read<T: Clone>(h: &CowHandle<T>) -> &T {
h.read()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_read() {
let h = CowHandle::new(42);
assert_eq!(*h.read(), 42); /* value readable */
}
#[test]
fn test_write_exclusive() {
let mut h = CowHandle::new(1);
*h.write() = 99;
assert_eq!(*h.read(), 99); /* mutation applied */
}
#[test]
fn test_share_increases_ref_count() {
let h = CowHandle::new(0);
let h2 = h.share();
assert_eq!(h.ref_count(), 2); /* two handles share */
drop(h2);
}
#[test]
fn test_write_clones_shared() {
let h = CowHandle::new(vec![1, 2, 3]);
let h2 = h.share();
/* h and h2 share; writing h should clone */
let mut h_mut = h;
h_mut.write().push(4);
assert_eq!(h_mut.read().len(), 4); /* h_mut has the new element */
assert_eq!(h2.read().len(), 3); /* h2 unaffected */
}
#[test]
fn test_is_exclusive_initially() {
let h = CowHandle::new(5);
assert!(h.is_exclusive()); /* no sharing initially */
}
#[test]
fn test_is_exclusive_after_share() {
let h = CowHandle::new(5);
let h2 = h.share();
assert!(!h.is_exclusive()); /* shared */
drop(h2);
}
#[test]
fn test_is_exclusive_after_clone_drop() {
let h = CowHandle::new(5);
{
let _h2 = h.share();
}
assert!(h.is_exclusive()); /* exclusive after other handle dropped */
}
#[test]
fn test_new_helper() {
let h = new_cow_handle(100u32);
assert_eq!(*h.read(), 100); /* helper works */
}
#[test]
fn test_cow_share_helper() {
let h = new_cow_handle(7);
let h2 = cow_share(&h);
assert_eq!(*cow_read(&h2), 7); /* share and read helpers work */
}
#[test]
fn test_ref_count_starts_at_one() {
let h = CowHandle::new("hello");
assert_eq!(h.ref_count(), 1); /* single owner */
}
}