import set import map __if_comp__ __C__ simple_passthrough """ #include """ /* we have a template versions so we don't have to cast (because we don't have that yet) */ fun null(): *T { __if_comp__ __C__ { simple_passthrough(::) """ return (void*)0; """ } } fun malloc(size: int): *T { var memPtr: *T; __if_comp__ __C__ { simple_passthrough( size = size, memPtr = memPtr : memPtr = memPtr :) """ memPtr = malloc(size); """ } return memPtr; } fun free(memPtr: *T): void { __if_comp__ __C__ { simple_passthrough(memPtr = memPtr ::) """ free(memPtr); """ } } fun sizeof(): int { var testObj: *T; var result: int; __if_comp__ __C__ { simple_passthrough(testObj = testObj : result = result:) """ int result = sizeof(*testObj); """ } return result; } fun new(count: int): *T { return malloc( sizeof() * count ); } fun new(): *T { return new(1); } /* We specilize on the trait Object to decide on whether or not the destructor should be called */ fun delete(toDelete: *T, itemCount: int): void { delete(toDelete); } /* Calling this with itemCount = 0 allows you to delete destructable objects without calling their destructors. */ fun delete(toDelete: *T, itemCount: int): void { // start at one because the actual delete will call the destructor of the first one as it // finishes the pointer for (var i: int = 0; i < itemCount; i++;) toDelete[i].destruct(); free(toDelete); //delete(toDelete); } /* We specilize on the trait Object to decide on whether or not the destructor should be called */ fun delete(toDelete: *T): void { free(toDelete); } fun delete(toDelete: *T): void { toDelete->destruct(); free(toDelete); } // a wrapper for construct if it has the Object trait fun maybe_construct(it:*T):*T { return it } fun maybe_construct(it:*T):*T { return it->construct() } // a wrapper for copy constructing if it has the Object trait fun maybe_copy_construct(to:*T, from:*T):void { *to = *from } fun maybe_copy_construct(to:*T, from:*T):void { to->copy_construct(from) } // a wrapper for destruct if it has the Object trait fun maybe_destruct(it:*T):void {} fun maybe_destruct(it:*T):void { it->destruct() } // a function that allows the safe deletion of recursive and complicated data structures fun safe_recursive_delete(first: *T, addingFunc: fun(*T): set::set<*T>) { var toDelete = set::set<*T>() var next = set::set(first) while (toDelete != next) { toDelete = next toDelete.for_each( fun(it: *T) next.add(addingFunc(it)); ) } toDelete.for_each( fun(it: *T) delete(it); ) } // a function that allows the safe cloning of recursive and complicated data structures // cloneing func is the func that does the cloning, it takes in a recursive clone function and // a register clone function fun safe_recursive_clone(first: *T, cloningFunc: fun(*T, fun(*T):*T, fun(*T):void): void): *T { var rec_map = map::map<*T,*T>() // can't do type infrence if you need the type inside the expression... var rec_it: fun(*T):*T = fun(it: *T): *T { if (!rec_map.contains_key(it)) cloningFunc(it, rec_it, fun(cloned: *T) { rec_map[it] = cloned; }) return rec_map[it] } return rec_it(first) } obj shared_ptr (Object){ var data: *T; var refCount: int; fun construct(): *shared_ptr { data = 0; refCount = 1; return this; } fun construct(newPtr: *T): *shared_ptr { data = newPtr; refCount = 1; return this; } fun construct(newPtr: ref shared_ptr): *shared_ptr { data = newPtr.data; refCount = newPtr.refCount; refCount++; return this; } fun destruct(): void { if(refCount == 1){ delete(data,1); refCount--; } } fun operator*(): ref T { return *data; } fun operator->(): *T { return data; } fun operator=(newPtr: ref shared_ptr): ref shared_ptr { if(this != &newPtr){ if(refCount == 1){ delete(data,1); refCount--; } //use copy constructor here??? data = newPtr.data; refCount = newPtr.refCount; refCount++; }//end self-assignment check return *this; } fun operator=(newPtr: ref *T): ref shared_ptr { data = newPtr; refCount = 1; delete(newPtr,1); return *this; } }; //end shared_ptr class