| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
f35aa134dc | move semantics | 5 years ago |
| @@ -1,25 +1,64 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <utility> | |||||
| #include <initializer_list> | |||||
| #include "types.hpp" | #include "types.hpp" | ||||
| // template<class E> class my_initializer_list { | |||||
| // public: | |||||
| // using value_type = E; | |||||
| // using reference = const E&; | |||||
| // using const_reference = const E&; | |||||
| // using size_type = size_t; | |||||
| // using iterator = const E*; | |||||
| // using const_iterator = const E*; | |||||
| // constexpr my_initializer_list() noexcept; | |||||
| // constexpr size_t size() const noexcept; // number of elements | |||||
| // constexpr const E* begin() const noexcept; // first element | |||||
| // constexpr const E* end() const noexcept; // one past the last element | |||||
| // }; | |||||
| // // initializer list range access | |||||
| // template<class E> constexpr const E* begin(my_initializer_list<E> il) noexcept; | |||||
| // template<class E> constexpr const E* end(my_initializer_list<E> il) noexcept; | |||||
| template <typename type> | template <typename type> | ||||
| struct Array_List { | struct Array_List { | ||||
| type* data; | type* data; | ||||
| u32 length; | u32 length; | ||||
| u32 next_index; | u32 next_index; | ||||
| void alloc(u32 initial_capacity = 16) { | |||||
| Array_List(u32 initial_capacity = 16) { | |||||
| data = (type*)malloc(initial_capacity * sizeof(type)); | data = (type*)malloc(initial_capacity * sizeof(type)); | ||||
| next_index = 0; | next_index = 0; | ||||
| length = initial_capacity; | length = initial_capacity; | ||||
| } | } | ||||
| void dealloc() { | |||||
| Array_List(std::initializer_list<type> list) | |||||
| : Array_List(list.size()) | |||||
| { | |||||
| for (type e : list) { | |||||
| append(e); | |||||
| } | |||||
| } | |||||
| Array_List(Array_List<type>&& other) { | |||||
| data = other.data; | |||||
| length = other.length; | |||||
| next_index = other.next_index; | |||||
| other.data = nullptr; | |||||
| } | |||||
| ~Array_List() { | |||||
| free(data); | free(data); | ||||
| data = nullptr; | data = nullptr; | ||||
| } | } | ||||
| void clear() { | void clear() { | ||||
| next_index = 0; | next_index = 0; | ||||
| } | } | ||||
| @@ -53,7 +92,7 @@ struct Array_List { | |||||
| length *= 2; | length *= 2; | ||||
| data = (type*)realloc(data, length * sizeof(type)); | data = (type*)realloc(data, length * sizeof(type)); | ||||
| } | } | ||||
| data[next_index] = element; | |||||
| data[next_index] = std::move(element); | |||||
| next_index++; | next_index++; | ||||
| } | } | ||||
| @@ -13,12 +13,12 @@ set BINDIR_LINUX=./%BINDIR_RAW% | |||||
| echo. | echo. | ||||
| echo clang: | echo clang: | ||||
| clang -std=c++17 %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN% | |||||
| clang++ -std=c++17 %SRC% -o %BINDIR_WIN%\clang_%EXE_WIN% | |||||
| %BINDIR_WIN%\clang_%EXE_WIN% | %BINDIR_WIN%\clang_%EXE_WIN% | ||||
| echo. | echo. | ||||
| echo g++: | echo g++: | ||||
| g++ -std=c++17 %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN% | |||||
| g++ -O3 -std=c++17 %SRC% -o %BINDIR_WIN%\g++_%EXE_WIN% | |||||
| %BINDIR_WIN%\g++_%EXE_WIN% | %BINDIR_WIN%\g++_%EXE_WIN% | ||||
| echo. | echo. | ||||
| @@ -28,8 +28,10 @@ cl %SRC% /nologo /Zi /Fd: %BINDIR_WIN%\cl_%EXE_WIN%.pdb /Fo: %BINDIR_WIN%\ /Fe: | |||||
| echo. | echo. | ||||
| echo bash_clang: | echo bash_clang: | ||||
| bash -c "clang -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_clang_%EXE_LINUX% && %BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| wsl bash -c "clang++ -g -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| :: wsl bash -c "valgrind --leak-check=full --show-leak-kinds=all %BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| wsl bash -c "%BINDIR_LINUX%/bash_clang_%EXE_LINUX%" | |||||
| echo. | |||||
| :: echo. | |||||
| echo bash_g++: | echo bash_g++: | ||||
| bash -c "g++ -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_g++_%EXE_LINUX% && %BINDIR_LINUX%/bash_g++_%EXE_LINUX%" | bash -c "g++ -std=c++17 %SRC% -o %BINDIR_LINUX%/bash_g++_%EXE_LINUX% && %BINDIR_LINUX%/bash_g++_%EXE_LINUX%" | ||||
| @@ -21,8 +21,8 @@ auto delete_error() -> void { | |||||
| auto create_error(const char* c_func_name, const char* c_file_name, | auto create_error(const char* c_func_name, const char* c_file_name, | ||||
| u32 c_file_line, String type, const char* format, ...) -> void { | u32 c_file_line, String type, const char* format, ...) -> void { | ||||
| error = new Error; | |||||
| error->type = type; | |||||
| error = (Error*)malloc(sizeof(Error)); | |||||
| error->type = std::move(type); | |||||
| va_list args; | va_list args; | ||||
| va_start(args, format); | va_start(args, format); | ||||
| @@ -44,7 +44,7 @@ auto create_error(const char* c_func_name, const char* c_file_name, | |||||
| #define __create_error(keyword, ...) \ | #define __create_error(keyword, ...) \ | ||||
| create_error( \ | create_error( \ | ||||
| __FUNCTION__, __FILE__, __LINE__, \ | __FUNCTION__, __FILE__, __LINE__, \ | ||||
| make_heap_string(keyword), \ | |||||
| String(keyword), \ | |||||
| __VA_ARGS__) | __VA_ARGS__) | ||||
| #define create_assertion_error(...) \ | #define create_assertion_error(...) \ | ||||
| @@ -48,16 +48,27 @@ struct Hash_Map { | |||||
| value_type object; | value_type object; | ||||
| }* data; | }* data; | ||||
| void alloc(u32 initial_capacity = 8) { | |||||
| Hash_Map(u32 initial_capacity = 8) { | |||||
| current_capacity = initial_capacity; | current_capacity = initial_capacity; | ||||
| cell_count = 0; | cell_count = 0; | ||||
| data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | data = (HM_Cell*)calloc(initial_capacity, sizeof(HM_Cell)); | ||||
| } | } | ||||
| void dealloc() { | |||||
| free(data); | |||||
| data = nullptr; | |||||
| } | |||||
| ~Hash_Map() { | |||||
| free(data); | |||||
| data = nullptr; | |||||
| } | |||||
| Hash_Map(Hash_Map<key_type, value_type>& other) = delete; | |||||
| Hash_Map(const Hash_Map<key_type, value_type>& other) = delete; | |||||
| Hash_Map(Hash_Map<key_type, value_type>&& other) { | |||||
| data = other.data; | |||||
| cell_count = other.cell_count; | |||||
| current_capacity = other.current_capacity; | |||||
| other.data = nullptr; | |||||
| } | |||||
| s32 get_index_of_living_cell_if_it_exists(key_type key, u64 hash_val) { | s32 get_index_of_living_cell_if_it_exists(key_type key, u64 hash_val) { | ||||
| // s32 index = hash_val & (current_capacity - 1); | // s32 index = hash_val & (current_capacity - 1); | ||||
| @@ -51,12 +51,6 @@ struct Lambda<R(Args...)> | |||||
| struct Hook : Array_List<Lambda<void()>> { | struct Hook : Array_List<Lambda<void()>> { | ||||
| Hook() { | |||||
| alloc(); | |||||
| } | |||||
| ~Hook () { | |||||
| dealloc(); | |||||
| } | |||||
| void operator<<(Lambda<void()> f) { | void operator<<(Lambda<void()> f) { | ||||
| // FIXME(Felix): Why can I not call Array_List::append here??? Hallo? | // FIXME(Felix): Why can I not call Array_List::append here??? Hallo? | ||||
| if (next_index == length) { | if (next_index == length) { | ||||
| @@ -79,6 +73,5 @@ struct __System_Shutdown_Hook : Hook { | |||||
| void operator()() = delete; | void operator()() = delete; | ||||
| ~__System_Shutdown_Hook() { | ~__System_Shutdown_Hook() { | ||||
| Hook::operator()(); | Hook::operator()(); | ||||
| dealloc(); | |||||
| } | } | ||||
| } system_shutdown_hook; | } system_shutdown_hook; | ||||
| @@ -35,9 +35,9 @@ enum struct Printer_Function_Type { | |||||
| _void | _void | ||||
| }; | }; | ||||
| Array_List<char*> color_stack = {0}; | |||||
| Hash_Map<char*, printer_function_ptr> printer_map = {0}; | |||||
| Hash_Map<char*, int> type_map = {0}; | |||||
| Array_List<char*> color_stack; | |||||
| Hash_Map<char*, printer_function_ptr> printer_map; | |||||
| Hash_Map<char*, int> type_map; | |||||
| #define register_printer(spec, fun, type) \ | #define register_printer(spec, fun, type) \ | ||||
| register_printer_ptr(spec, (printer_function_ptr)fun, type) | register_printer_ptr(spec, (printer_function_ptr)fun, type) | ||||
| @@ -183,6 +183,7 @@ int maybe_special_print(FILE* file, static_string format, int* pos, va_list* arg | |||||
| *pos = end_pos; | *pos = end_pos; | ||||
| return written_length; | return written_length; | ||||
| } else { | } else { | ||||
| // printf("%p \n", printer.printer_ptr); | |||||
| *pos = end_pos; | *pos = end_pos; | ||||
| if (type == Printer_Function_Type::_32b) return printer.printer_32b(file, va_arg(*arg_list, u32)); | if (type == Printer_Function_Type::_32b) return printer.printer_32b(file, va_arg(*arg_list, u32)); | ||||
| else if (type == Printer_Function_Type::_64b) return printer.printer_64b(file, va_arg(*arg_list, u64)); | else if (type == Printer_Function_Type::_64b) return printer.printer_64b(file, va_arg(*arg_list, u64)); | ||||
| @@ -267,12 +268,16 @@ int maybe_fprintf(FILE* file, static_string format, int* pos, va_list* arg_list) | |||||
| strncpy(temp+1, format+*pos, writen_len); | strncpy(temp+1, format+*pos, writen_len); | ||||
| temp[writen_len] = 0; | temp[writen_len] = 0; | ||||
| // printf("\ntest:: len(%s) = %d\n", temp, writen_len+1); | |||||
| writen_len = vfprintf(file, temp, *arg_list); | |||||
| // NOTE(Felix): Somehow we have to pass a copy of the list to vfprintf | |||||
| // because otherwise it destroys it on some platforms :( | |||||
| va_list arg_list_copy; | |||||
| va_copy(arg_list_copy, *arg_list); | |||||
| writen_len = vfprintf(file, temp, arg_list_copy); | |||||
| va_end(arg_list_copy); | |||||
| // NOTE(Felix): For WSL Linux we have to manually overstep the | |||||
| // used args | |||||
| for (int i = 0; i < used_arg_values; ++i) { | for (int i = 0; i < used_arg_values; ++i) { | ||||
| va_arg(*arg_list, void*); | va_arg(*arg_list, void*); | ||||
| } | } | ||||
| @@ -444,28 +449,22 @@ auto print_str_line(FILE* f, char* str) -> s32 { | |||||
| return print_to_file(f, "%.*s", length, str); | return print_to_file(f, "%.*s", length, str); | ||||
| } | } | ||||
| void init_printer() { | |||||
| color_stack.alloc(); | |||||
| printer_map.alloc(); | |||||
| type_map.alloc(); | |||||
| system_shutdown_hook << [](){ | |||||
| color_stack.dealloc(); | |||||
| printer_map.dealloc(); | |||||
| type_map.dealloc(); | |||||
| }; | |||||
| register_printer("u32", print_u32, Printer_Function_Type::_32b); | |||||
| register_printer("u64", print_u64, Printer_Function_Type::_64b); | |||||
| register_printer("bool", print_bool, Printer_Function_Type::_32b); | |||||
| register_printer("s64", print_s64, Printer_Function_Type::_64b); | |||||
| register_printer("s32", print_s32, Printer_Function_Type::_32b); | |||||
| register_printer("f32", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("f64", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("->char", print_str, Printer_Function_Type::_ptr); | |||||
| register_printer("->", print_ptr, Printer_Function_Type::_ptr); | |||||
| register_printer("color<", print_color_start, Printer_Function_Type::_ptr); | |||||
| register_printer(">color", print_color_end, Printer_Function_Type::_void); | |||||
| register_printer("->Str", print_Str, Printer_Function_Type::_ptr); | |||||
| register_printer("->char_line", print_str_line, Printer_Function_Type::_ptr); | |||||
| namespace { | |||||
| struct Printer_Initter { | |||||
| Printer_Initter() { | |||||
| register_printer("u32", print_u32, Printer_Function_Type::_32b); | |||||
| register_printer("u64", print_u64, Printer_Function_Type::_64b); | |||||
| register_printer("bool", print_bool, Printer_Function_Type::_32b); | |||||
| register_printer("s64", print_s64, Printer_Function_Type::_64b); | |||||
| register_printer("s32", print_s32, Printer_Function_Type::_32b); | |||||
| register_printer("f32", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("f64", print_flt, Printer_Function_Type::_flt); | |||||
| register_printer("->char", print_str, Printer_Function_Type::_ptr); | |||||
| register_printer("->", print_ptr, Printer_Function_Type::_ptr); | |||||
| register_printer("color<", print_color_start, Printer_Function_Type::_ptr); | |||||
| register_printer(">color", print_color_end, Printer_Function_Type::_void); | |||||
| register_printer("->Str", print_Str, Printer_Function_Type::_ptr); | |||||
| register_printer("->char_line", print_str_line, Printer_Function_Type::_ptr); | |||||
| } | |||||
| } printer_initter; | |||||
| } | } | ||||
| @@ -1,6 +1,7 @@ | |||||
| #define _CRT_SECURE_NO_WARNINGS | #define _CRT_SECURE_NO_WARNINGS | ||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include <stdlib.h> | |||||
| #include "./types.hpp" | #include "./types.hpp" | ||||
| #include "./hooks.hpp" | #include "./hooks.hpp" | ||||
| @@ -48,7 +49,7 @@ s32 main(s32 argc, char* argv[]) { | |||||
| // test_printer(); | // test_printer(); | ||||
| init_printer(); | |||||
| // init_printer(); | |||||
| // create_generic_error("nothing to lex was found:\n" | // create_generic_error("nothing to lex was found:\n" | ||||
| // " in %{color<}%{->char}%{>color}\n" | // " in %{color<}%{->char}%{>color}\n" | ||||
| // " at %{color<}%{->char}%{>color}\n" | // " at %{color<}%{->char}%{>color}\n" | ||||
| @@ -59,7 +60,7 @@ s32 main(s32 argc, char* argv[]) { | |||||
| // "yesssssss"); | // "yesssssss"); | ||||
| create_error(__FUNCTION__, __FILE__, __LINE__, | create_error(__FUNCTION__, __FILE__, __LINE__, | ||||
| make_heap_string("generic"), | |||||
| String("generic"), | |||||
| "nothing to lex was found:\n" | "nothing to lex was found:\n" | ||||
| " in %{color<}%{->char}%{>color}\n" | " in %{color<}%{->char}%{>color}\n" | ||||
| " at %{color<}%{->char}%{>color}\n" | " at %{color<}%{->char}%{>color}\n" | ||||
| @@ -2,7 +2,7 @@ | |||||
| typedef s32 testresult; | typedef s32 testresult; | ||||
| #define epsilon 2.2204460492503131E-16 | |||||
| static const double epsilon = 2.2204460492503131E-16; | |||||
| #define pass 1 | #define pass 1 | ||||
| #define fail 0 | #define fail 0 | ||||
| @@ -2,6 +2,7 @@ | |||||
| #include "platform.hpp" | #include "platform.hpp" | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <stdlib.h> | |||||
| #include <string.h> | #include <string.h> | ||||
| typedef int8_t s8; | typedef int8_t s8; | ||||
| @@ -23,17 +24,6 @@ typedef wchar_t path_char; | |||||
| typedef char path_char; | typedef char path_char; | ||||
| #endif | #endif | ||||
| struct StringSlice { | |||||
| const char* data; | |||||
| u64 length; | |||||
| }; | |||||
| struct String { | |||||
| char* data; | |||||
| u64 length; | |||||
| }; | |||||
| inline auto heap_copy_c_string(const char* str) -> char* { | inline auto heap_copy_c_string(const char* str) -> char* { | ||||
| #ifdef FTB_WINDOWS | #ifdef FTB_WINDOWS | ||||
| return _strdup(str); | return _strdup(str); | ||||
| @@ -42,17 +32,55 @@ inline auto heap_copy_c_string(const char* str) -> char* { | |||||
| #endif | #endif | ||||
| } | } | ||||
| inline auto make_heap_string(const char* str) -> String { | |||||
| String ret; | |||||
| ret.length = strlen(str); | |||||
| ret.data = heap_copy_c_string(str); | |||||
| return ret; | |||||
| } | |||||
| struct String_Slice { | |||||
| String_Slice() = default; | |||||
| String_Slice (const char* str) | |||||
| : length(strlen(str)), | |||||
| data(str) | |||||
| {} | |||||
| const char* data; | |||||
| u64 length; | |||||
| }; | |||||
| struct String { | |||||
| String () = default; | |||||
| String (const char* str) { | |||||
| length = strlen(str); | |||||
| data = heap_copy_c_string(str); | |||||
| } | |||||
| ~String () { | |||||
| free(data); | |||||
| data = nullptr; | |||||
| } | |||||
| String (const String&) = delete; | |||||
| String (String&& other) { | |||||
| length = other.length; | |||||
| data = other.data; | |||||
| other.data = nullptr; | |||||
| } | |||||
| String& operator= (String&& other) { | |||||
| length = other.length; | |||||
| data = other.data; | |||||
| other.data = nullptr; | |||||
| return *this; | |||||
| } | |||||
| char* data; | |||||
| u64 length; | |||||
| }; | |||||
| inline auto make_static_string(const char* str) -> const StringSlice { | |||||
| StringSlice ret; | |||||
| ret.length = strlen(str); | |||||
| ret.data = str; | |||||
| inline auto make_static_string(const char* str) -> const String_Slice { | |||||
| String_Slice ret(str); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -60,19 +88,19 @@ auto inline string_equal(const char* input, const char* check) -> bool { | |||||
| return strcmp(input, check) == 0; | return strcmp(input, check) == 0; | ||||
| } | } | ||||
| auto inline string_equal(StringSlice str, const char* check) -> bool { | |||||
| auto inline string_equal(String_Slice str, const char* check) -> bool { | |||||
| if (str.length != strlen(check)) | if (str.length != strlen(check)) | ||||
| return false; | return false; | ||||
| return strncmp(str.data, check, str.length) == 0; | return strncmp(str.data, check, str.length) == 0; | ||||
| } | } | ||||
| auto inline string_equal(const char* check, StringSlice str) -> bool { | |||||
| auto inline string_equal(const char* check, String_Slice str) -> bool { | |||||
| if (str.length != strlen(check)) | if (str.length != strlen(check)) | ||||
| return false; | return false; | ||||
| return strncmp(str.data, check, str.length) == 0; | return strncmp(str.data, check, str.length) == 0; | ||||
| } | } | ||||
| auto inline string_equal(StringSlice str1, StringSlice str2) -> bool { | |||||
| auto inline string_equal(String_Slice str1, String_Slice str2) -> bool { | |||||
| if (str1.length != str2.length) | if (str1.length != str2.length) | ||||
| return false; | return false; | ||||