mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 11:52:22 -07:00
Fix copy
This commit is contained in:
+2
-196
@@ -1,199 +1,5 @@
|
||||
import (
|
||||
"fmt.odin";
|
||||
"atomics.odin";
|
||||
"bits.odin";
|
||||
"hash.odin";
|
||||
"math.odin";
|
||||
"mem.odin";
|
||||
"opengl.odin";
|
||||
"os.odin";
|
||||
"pool.odin";
|
||||
"raw.odin";
|
||||
"sort.odin";
|
||||
"strconv.odin";
|
||||
"strings.odin";
|
||||
"sync.odin";
|
||||
"types.odin";
|
||||
"utf8.odin";
|
||||
"utf16.odin";
|
||||
)
|
||||
|
||||
Table :: struct(Key, Value: type) {
|
||||
Slot :: struct {
|
||||
occupied: bool;
|
||||
hash: u32;
|
||||
key: Key;
|
||||
value: Value;
|
||||
}
|
||||
SIZE_MIN :: 32;
|
||||
|
||||
count: int;
|
||||
allocator: Allocator;
|
||||
slots: []Slot;
|
||||
}
|
||||
|
||||
allocate :: proc(table: ^$T/Table, capacity: int) {
|
||||
c := context;
|
||||
if table.allocator.procedure != nil do c.allocator = table.allocator;
|
||||
|
||||
push_context c {
|
||||
table.slots = make([]T.Slot, max(capacity, T.SIZE_MIN));
|
||||
}
|
||||
}
|
||||
|
||||
expand :: proc(table: ^$T/Table) {
|
||||
c := context;
|
||||
if table.allocator.procedure != nil do c.allocator = table.allocator;
|
||||
|
||||
push_context c {
|
||||
old_slots := table.slots;
|
||||
|
||||
cap := max(2*cap(table.slots), T.SIZE_MIN);
|
||||
allocate(table, cap);
|
||||
|
||||
for s in old_slots do if s.occupied {
|
||||
put(table, s.key, s.value);
|
||||
}
|
||||
|
||||
free(old_slots);
|
||||
}
|
||||
}
|
||||
|
||||
// put :: proc(table: ^$T/Table, key: T.Key, value: T.Value) {
|
||||
put :: proc(table: ^Table($Key, $Value), key: Key, value: Value) {
|
||||
hash := get_hash(key); // Ad-hoc method which would fail in differentcope
|
||||
index := find_index(table, key, hash);
|
||||
if index < 0 {
|
||||
if f64(table.count) >= 0.75*cast(f64)cap(table.slots) {
|
||||
expand(table);
|
||||
}
|
||||
assert(table.count <= cap(table.slots));
|
||||
|
||||
hash := get_hash(key);
|
||||
index = cast(int)(hash % cast(u32)cap(table.slots));
|
||||
|
||||
for table.slots[index].occupied {
|
||||
index += 1;
|
||||
if index >= cap(table.slots) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
table.count += 1;
|
||||
}
|
||||
|
||||
slot := &table.slots[index];
|
||||
slot.occupied = true;
|
||||
slot.hash = hash;
|
||||
slot.key = key;
|
||||
slot.value = value;
|
||||
}
|
||||
|
||||
|
||||
// find :: proc(table: ^$T/Table, key: T.Key) -> (T.Value, bool) {
|
||||
find :: proc(table: ^Table($Key, $Value), key: Key) -> (Value, bool) {
|
||||
hash := get_hash(key);
|
||||
index := find_index(table, key, hash);
|
||||
if index < 0 {
|
||||
return Value{}, false;
|
||||
}
|
||||
return table.slots[index].value, true;
|
||||
}
|
||||
|
||||
find_index :: proc(table: ^Table($Key, $Value), key: Key, hash: u32) -> int {
|
||||
if cap(table.slots) <= 0 do return -1;
|
||||
|
||||
slot := int(hash % cast(u32)cap(table.slots));
|
||||
|
||||
index := slot;
|
||||
for table.slots[index].occupied {
|
||||
if table.slots[index].hash == hash {
|
||||
if table.slots[index].key == key {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
if index += 1; index >= cap(table.slots) {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
get_hash :: proc(s: string) -> u32 {
|
||||
// djb2
|
||||
hash: u32 = 5381;
|
||||
for i in 0..len(s) do hash = (hash<<5) + hash + u32(s[i]);
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vector :: struct(N: int, T: type) #raw_union {
|
||||
using e: [N]T;
|
||||
when 0 < N && N <= 4 {
|
||||
using v: struct {
|
||||
when N >= 1 do x: T;
|
||||
when N >= 2 do y: T;
|
||||
when N >= 3 do z: T;
|
||||
when N >= 4 do w: T;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 :: Vector(3, f32);
|
||||
|
||||
add :: proc(a, b: $T/Vector) -> T {
|
||||
c := a;
|
||||
for i in 0..3 {
|
||||
c[i] += b[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
foo1 :: proc(a: type/Vector) { fmt.println("foo1", a{}); }
|
||||
// foo2 :: proc(a: type/Vector(3, f32)) {}
|
||||
foo3 :: proc(a: type/Vector(3, $T)) { fmt.println("foo3", a{}); }
|
||||
// foo4 :: proc(a: type/Vector3) {}
|
||||
|
||||
import "fmt.odin";
|
||||
|
||||
main :: proc() {
|
||||
// Foo :: struct {
|
||||
// a := 123;
|
||||
// b := true;
|
||||
// }
|
||||
// v1 := Foo{};
|
||||
// fmt.println(v1);
|
||||
|
||||
// foo1(Vector(3, f32));
|
||||
// foo1(Vector3);
|
||||
// foo3(Vector(3, f32));
|
||||
// foo3(Vector3);
|
||||
|
||||
|
||||
a, b: Vector3;
|
||||
a[0] = 1;
|
||||
a[1] = 4;
|
||||
a[2] = 9;
|
||||
|
||||
b.x = 3;
|
||||
b.y = 4;
|
||||
b.z = 5;
|
||||
|
||||
v := add(a, b);
|
||||
fmt.println(size_of(Vector3));
|
||||
fmt.println(v.e, v.v);
|
||||
|
||||
// table: Table(string, int);
|
||||
|
||||
// for i in 0..36 do put(&table, "Hellope", i);
|
||||
// for i in 0..42 do put(&table, "World!", i);
|
||||
|
||||
|
||||
// found, _ := find(&table, "Hellope");
|
||||
// fmt.printf("found is %v\n", found);
|
||||
|
||||
// found, _ = find(&table, "World!");
|
||||
// fmt.printf("found is %v\n", found);
|
||||
fmt.println("Hellope, World!");
|
||||
}
|
||||
|
||||
+4
-1
@@ -305,7 +305,7 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL
|
||||
|
||||
copy :: proc(dst, src: $T/[]$E) -> int #cc_contextless {
|
||||
n := max(0, min(len(dst), len(src)));
|
||||
if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(T));
|
||||
if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(E));
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -670,6 +670,7 @@ __string_decode_rune :: proc(s: string) -> (rune, int) #cc_contextless #inline {
|
||||
|
||||
|
||||
__mem_set :: proc(data: rawptr, value: i32, len: int) -> rawptr #cc_contextless {
|
||||
if data == nil do return nil;
|
||||
when size_of(rawptr) == 8 {
|
||||
foreign __llvm_core llvm_memset :: proc(dst: rawptr, val: u8, len: int, align: i32, is_volatile: bool) #link_name "llvm.memset.p0i8.i64" ---;
|
||||
} else {
|
||||
@@ -682,6 +683,7 @@ __mem_zero :: proc(data: rawptr, len: int) -> rawptr #cc_contextless {
|
||||
return __mem_set(data, 0, len);
|
||||
}
|
||||
__mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless {
|
||||
if src == nil do return dst;
|
||||
// NOTE(bill): This _must_ be implemented like C's memmove
|
||||
when size_of(rawptr) == 8 {
|
||||
foreign __llvm_core llvm_memmove :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memmove.p0i8.p0i8.i64" ---;
|
||||
@@ -692,6 +694,7 @@ __mem_copy :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless {
|
||||
return dst;
|
||||
}
|
||||
__mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_contextless {
|
||||
if src == nil do return dst;
|
||||
// NOTE(bill): This _must_ be implemented like C's memcpy
|
||||
when size_of(rawptr) == 8 {
|
||||
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---;
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
||||
return write(fd, cast([]u8)str);
|
||||
}
|
||||
|
||||
read_entire_file :: proc(name: string) -> ([]u8, bool) {
|
||||
read_entire_file :: proc(name: string) -> (data: []u8, success: bool) {
|
||||
fd, err := open(name, O_RDONLY, 0);
|
||||
if err != 0 {
|
||||
return nil, false;
|
||||
@@ -37,7 +37,7 @@ read_entire_file :: proc(name: string) -> ([]u8, bool) {
|
||||
return data[0..bytes_read], true;
|
||||
}
|
||||
|
||||
write_entire_file :: proc(name: string, data: []u8) -> bool {
|
||||
write_entire_file :: proc(name: string, data: []u8) -> (sucess: bool) {
|
||||
fd, err := open(name, O_WRONLY, 0);
|
||||
if err != 0 {
|
||||
return false;
|
||||
|
||||
@@ -15,6 +15,7 @@ new_c_string :: proc(s: string) -> ^u8 {
|
||||
}
|
||||
|
||||
to_odin_string :: proc(c: ^u8) -> string {
|
||||
if c == nil do return "";
|
||||
len := 0;
|
||||
for (c+len)^ != 0 do len+=1;
|
||||
return string(mem.slice_ptr(c, len));
|
||||
|
||||
Reference in New Issue
Block a user