1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! An owned, task-local, reference counted type
15 //! XXX There is currently no type-system mechanism for enforcing that
16 //! reference counted types are both allocated on the exchange heap
17 //! and also non-sendable
19 //! This doesn't prevent borrowing multiple aliasable mutable pointers
27 p: *c_void // ~(uint, T)
31 pub fn new(val: T) -> RC<T> {
34 let p: *c_void = cast::transmute(v);
39 fn get_mut_state(&mut self) -> *mut (uint, T) {
41 let p: &mut ~(uint, T) = cast::transmute(&mut self.p);
42 let p: *mut (uint, T) = &mut **p;
47 fn get_state(&self) -> *(uint, T) {
49 let p: &~(uint, T) = cast::transmute(&self.p);
50 let p: *(uint, T) = &**p;
55 pub fn unsafe_borrow_mut(&mut self) -> *mut T {
57 match *self.get_mut_state() {
66 pub fn refcount(&self) -> uint {
68 match *self.get_state() {
76 impl<T> Drop for RC<T> {
78 assert!(self.refcount() > 0);
81 // FIXME(#4330) Need self by value to get mutability.
82 let this: &mut RC<T> = cast::transmute_mut(self);
84 match *this.get_mut_state() {
85 (ref mut count, _) => {
90 if this.refcount() == 0 {
91 let _: ~(uint, T) = cast::transmute(this.p);
97 impl<T> Clone for RC<T> {
98 fn clone(&self) -> RC<T> {
100 // XXX: Mutable clone
101 let this: &mut RC<T> = cast::transmute_mut(self);
103 match *this.get_mut_state() {
104 (ref mut count, _) => {
121 let mut v1 = RC::new(100);
122 assert!(*v1.unsafe_borrow_mut() == 100);
123 assert!(v1.refcount() == 1);
125 let mut v2 = v1.clone();
126 assert!(*v2.unsafe_borrow_mut() == 100);
127 assert!(v2.refcount() == 2);
129 *v2.unsafe_borrow_mut() = 200;
130 assert!(*v2.unsafe_borrow_mut() == 200);
131 assert!(*v1.unsafe_borrow_mut() == 200);
134 assert!(v3.refcount() == 3);
139 assert!(v3.refcount() == 1);