Delete DqnInspect, it's too broken. Replace with new one
This commit is contained in:
		
							parent
							
								
									c36ea18a64
								
							
						
					
					
						commit
						96b7c05daf
					
				
							
								
								
									
										867
									
								
								Code/Dqn.h
									
									
									
									
									
								
							
							
						
						
									
										867
									
								
								Code/Dqn.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										190
									
								
								Code/DqnHeader.h
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								Code/DqnHeader.h
									
									
									
									
									
								
							@ -1,8 +1,51 @@
 | 
			
		||||
#ifndef DQN_HEADER_H
 | 
			
		||||
#define DQN_HEADER_H
 | 
			
		||||
 | 
			
		||||
// NOTE: Copy the function prototype, all functions will be whitespaced aligned to the longest return type of the file
 | 
			
		||||
// NOTE: If you function contains a comma NOT in the argument list (i.e. multiple template parameters), this macro does NOT work.
 | 
			
		||||
//       Please use the DQN_HEADER_COPY_BEGIN and DQN_HEADER_COPY_END unfortunately.
 | 
			
		||||
#define DQN_HEADER_COPY_PROTOTYPE(func_return, func_name_and_types) func_return func_name_and_types
 | 
			
		||||
 | 
			
		||||
// NOTE: Copy all contents from the file between the begin and end macro
 | 
			
		||||
#define DQN_HEADER_COPY_BEGIN
 | 
			
		||||
#define DQN_HEADER_COPY_END
 | 
			
		||||
 | 
			
		||||
// NOTE: Copy comments by writing comments with the prefix, "// @"
 | 
			
		||||
// @ Hello this comment will be copied to the output
 | 
			
		||||
 | 
			
		||||
// NOTE: Example Input
 | 
			
		||||
#if 0
 | 
			
		||||
    #include "DqnHeader.h"
 | 
			
		||||
 | 
			
		||||
    // @ ptr1: Pointer to the first block of memory
 | 
			
		||||
    // @ ptr2: Pointer to the second block of memory
 | 
			
		||||
    // @ num_bytes: The number of bytes to compare in both blocks of memory
 | 
			
		||||
    DQN_HEADER_COPY_PROTOTYPE(int, Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes))
 | 
			
		||||
    {
 | 
			
		||||
        int result = memcmp(ptr1, ptr2, num_bytes);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DQN_HEADER_COPY_BEGIN
 | 
			
		||||
    struct HelloWorld
 | 
			
		||||
    {
 | 
			
		||||
        int foo, bar;
 | 
			
		||||
    };
 | 
			
		||||
    DQN_HEADER_COPY_END
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// NOTE: Example Output
 | 
			
		||||
#if 0
 | 
			
		||||
    // @ ptr1: Pointer to the first block of memory
 | 
			
		||||
    // @ ptr2: Pointer to the second block of memory
 | 
			
		||||
    // @ num_bytes: The number of bytes to compare in both blocks of memory
 | 
			
		||||
    int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes);
 | 
			
		||||
    struct HelloWorld
 | 
			
		||||
    {
 | 
			
		||||
        int foo, bar;
 | 
			
		||||
    };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DQN_HEADER_H */
 | 
			
		||||
 | 
			
		||||
#ifdef DQN_HEADER_IMPLEMENTATION
 | 
			
		||||
@ -10,12 +53,13 @@
 | 
			
		||||
#define _CRT_SECURE_NO_WARNINGS // NOTE: Undefined at end of file
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
 | 
			
		||||
#define DQN_USE_PRIMITIVE_TYPEDEFS
 | 
			
		||||
#define DQN_IMPLEMENTATION
 | 
			
		||||
#include "Dqn.h"
 | 
			
		||||
 | 
			
		||||
char const *Dqn_Header__ParseFunctionReturnType(char const *ptr, isize *len)
 | 
			
		||||
char const *ParseFunctionReturnType(char const *ptr, isize *len)
 | 
			
		||||
{
 | 
			
		||||
    char const *result = Dqn_StrSkipWhitespace(ptr);
 | 
			
		||||
    char const *result = Dqn_Str_SkipWhitespace(ptr);
 | 
			
		||||
    isize result_len   = 0;
 | 
			
		||||
    for (int scope = 0; ptr; ptr++) // NOTE: Parse the function return type
 | 
			
		||||
    {
 | 
			
		||||
@ -37,7 +81,7 @@ char const *Dqn_Header__ParseFunctionReturnType(char const *ptr, isize *len)
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char const *Dqn_Header__ParseFunctionNameAndParameters(char const *ptr, isize *len)
 | 
			
		||||
char const *ParseFunctionNameAndParameters(char const *ptr, isize *len)
 | 
			
		||||
{
 | 
			
		||||
    char const *result = ptr;
 | 
			
		||||
    int result_len = 0;
 | 
			
		||||
@ -56,7 +100,7 @@ char const *Dqn_Header__ParseFunctionNameAndParameters(char const *ptr, isize *l
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char const *Dqn_Header__ParseFunctionComment(char const *ptr, isize *len)
 | 
			
		||||
char const *ParseFunctionComment(char const *ptr, isize *len)
 | 
			
		||||
{
 | 
			
		||||
    while (ptr[0] != '"') ptr++;
 | 
			
		||||
    ptr++;
 | 
			
		||||
@ -80,11 +124,35 @@ char const *Dqn_Header__ParseFunctionComment(char const *ptr, isize *len)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum struct HeaderEntryType
 | 
			
		||||
{
 | 
			
		||||
    Prototype,
 | 
			
		||||
    Comment,
 | 
			
		||||
    CopyBegin,
 | 
			
		||||
    Count
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct HeaderEntry
 | 
			
		||||
{
 | 
			
		||||
    HeaderEntryType type;
 | 
			
		||||
    union
 | 
			
		||||
    {
 | 
			
		||||
        struct
 | 
			
		||||
        {
 | 
			
		||||
            Dqn_Slice<char> return_val;
 | 
			
		||||
            Dqn_Slice<char> name_and_args;
 | 
			
		||||
        } function_decl;
 | 
			
		||||
 | 
			
		||||
        Dqn_Slice<char> comment;
 | 
			
		||||
        Dqn_Slice<char> copy_range;
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (argc < 1)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(stdout, "DqnHeader Usage: %s [<source code filename>, ...]\n", argv[0]);
 | 
			
		||||
        fprintf(stdout, "Header Usage: %s [<source code filename>, ...]\n", argv[0]);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -93,7 +161,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
    {
 | 
			
		||||
        char const *file = argv[arg_index];
 | 
			
		||||
        isize buf_size   = 0;
 | 
			
		||||
        char *buf        = Dqn_FileReadWithArena(&arena, file, &buf_size);
 | 
			
		||||
        char *buf        = Dqn_File_ReadWithArena(&arena, file, &buf_size);
 | 
			
		||||
        if (!buf)
 | 
			
		||||
        {
 | 
			
		||||
            fprintf(stderr, "Failed to read file: %s\n", file);
 | 
			
		||||
@ -105,14 +173,6 @@ int main(int argc, char *argv[])
 | 
			
		||||
        char constexpr HEADER_COPY_BEGIN[]     = "DQN_HEADER_COPY_BEGIN";
 | 
			
		||||
        char constexpr HEADER_COPY_END[]       = "DQN_HEADER_COPY_END";
 | 
			
		||||
 | 
			
		||||
        enum struct FindString
 | 
			
		||||
        {
 | 
			
		||||
            HeaderPrototype,
 | 
			
		||||
            HeaderComment,
 | 
			
		||||
            HeaderCopyBegin,
 | 
			
		||||
            Count
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        char const *find_list[]            = {HEADER_COPY_PROTOTYPE, HEADER_COMMENT, HEADER_COPY_BEGIN};
 | 
			
		||||
        isize constexpr find_string_lens[] = {
 | 
			
		||||
            Dqn_CharCountI(HEADER_COPY_PROTOTYPE),
 | 
			
		||||
@ -120,68 +180,130 @@ int main(int argc, char *argv[])
 | 
			
		||||
            Dqn_CharCountI(HEADER_COPY_BEGIN),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        isize num_header_entries = 0;
 | 
			
		||||
        {
 | 
			
		||||
            char const *ptr          = buf;
 | 
			
		||||
            char const *ptr_end      = buf + buf_size;
 | 
			
		||||
            isize ptr_len            = buf_size;
 | 
			
		||||
            isize matched_find_index = -1;
 | 
			
		||||
            for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len);
 | 
			
		||||
                 token;
 | 
			
		||||
                 token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len))
 | 
			
		||||
            {
 | 
			
		||||
                ptr = token + find_string_lens[matched_find_index];
 | 
			
		||||
                num_header_entries++;
 | 
			
		||||
                ptr_len = ptr_end - ptr;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        HeaderEntry *header_entries    = DQN_MEM_ARENA_ALLOC_ARRAY(&arena, HeaderEntry, num_header_entries);
 | 
			
		||||
        isize header_entries_index     = 0;
 | 
			
		||||
        isize max_prototype_return_val = 0;
 | 
			
		||||
 | 
			
		||||
        char const *ptr          = buf;
 | 
			
		||||
        char const *ptr_end      = buf + buf_size;
 | 
			
		||||
        isize ptr_len            = buf_size;
 | 
			
		||||
        isize matched_find_index = -1;
 | 
			
		||||
        for (char const *token = Dqn_StrMultiFind(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len);
 | 
			
		||||
        for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len);
 | 
			
		||||
             token;
 | 
			
		||||
             token = Dqn_StrMultiFind(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len))
 | 
			
		||||
             token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len))
 | 
			
		||||
        {
 | 
			
		||||
            if (matched_find_index == (isize)FindString::HeaderPrototype)
 | 
			
		||||
            HeaderEntry *entry = header_entries + header_entries_index++;
 | 
			
		||||
            entry->type           = static_cast<HeaderEntryType>(matched_find_index);
 | 
			
		||||
            if (matched_find_index == (isize)HeaderEntryType::Prototype)
 | 
			
		||||
            {
 | 
			
		||||
                ptr                   = token + find_string_lens[matched_find_index] + 1 /*macro start parenthesis*/;
 | 
			
		||||
                isize func_type_len   = 0;
 | 
			
		||||
                char const *func_type = Dqn_Header__ParseFunctionReturnType(ptr, &func_type_len);
 | 
			
		||||
                char const *func_type = ParseFunctionReturnType(ptr, &func_type_len);
 | 
			
		||||
 | 
			
		||||
                ptr                   = func_type + func_type_len + 1; // Ptr is at macro comma, skip the comma
 | 
			
		||||
                ptr                   = Dqn_StrSkipWhitespace(ptr);
 | 
			
		||||
                ptr                   = Dqn_Str_SkipWhitespace(ptr);
 | 
			
		||||
                isize func_name_len   = 0;
 | 
			
		||||
                char const *func_name = Dqn_Header__ParseFunctionNameAndParameters(ptr, &func_name_len);
 | 
			
		||||
                char const *func_name = ParseFunctionNameAndParameters(ptr, &func_name_len);
 | 
			
		||||
 | 
			
		||||
                entry->function_decl.return_val  = Dqn_AsprintfSlice(&arena, "%.*s", func_type_len, func_type);
 | 
			
		||||
                entry->function_decl.name_and_args = Dqn_AsprintfSlice(&arena, "%.*s", func_name_len, func_name);
 | 
			
		||||
                ptr = func_name + func_name_len + 1; // Ptr is at macro closing paren, skip the paren
 | 
			
		||||
                fprintf(stdout, "%.*s %.*s;\n", (int)func_type_len, func_type, (int)func_name_len, func_name);
 | 
			
		||||
 | 
			
		||||
                max_prototype_return_val = DQN_MAX(max_prototype_return_val, func_type_len);
 | 
			
		||||
            }
 | 
			
		||||
            else if (matched_find_index == (isize)FindString::HeaderComment)
 | 
			
		||||
            else if (matched_find_index == (isize)HeaderEntryType::Comment)
 | 
			
		||||
            {
 | 
			
		||||
                char const *comment_start = token;
 | 
			
		||||
                ptr                       = token;
 | 
			
		||||
                while (ptr[0] != '\n' && ptr[0] != '\r')
 | 
			
		||||
                    ptr++;
 | 
			
		||||
 | 
			
		||||
                isize comment_len = ptr - comment_start;
 | 
			
		||||
                fprintf(stdout, "%.*s\n", (int)comment_len, comment_start);
 | 
			
		||||
 | 
			
		||||
                entry->comment.buf = DQN_MEM_ARENA_ALLOC_ARRAY(&arena, char, comment_len);
 | 
			
		||||
                DQN_FOR_EACH(comment_index, comment_len)
 | 
			
		||||
                {
 | 
			
		||||
                    // NOTE: We capture "// @", and we want to skip the @ symbol, its ugly which is at the index 3
 | 
			
		||||
                    // Also if a space is given after the '@' symbol then skip that too.
 | 
			
		||||
                    char ch = comment_start[comment_index];
 | 
			
		||||
                    if (comment_index == 3 && ch == '@') continue;
 | 
			
		||||
                    if (comment_index == 4 && ch == ' ') continue;
 | 
			
		||||
                    entry->comment.buf[entry->comment.len++] = ch;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                while (entry->comment.len > 0 && Dqn_Char_IsWhitespace(entry->comment.buf[entry->comment.len - 1]))
 | 
			
		||||
                    entry->comment.len--;
 | 
			
		||||
                ptr = comment_start + comment_len;
 | 
			
		||||
            }
 | 
			
		||||
            else if (matched_find_index == (isize)FindString::HeaderCopyBegin)
 | 
			
		||||
            else if (matched_find_index == (isize)HeaderEntryType::CopyBegin)
 | 
			
		||||
            {
 | 
			
		||||
                ptr                    = token + find_string_lens[matched_find_index];
 | 
			
		||||
                ptr                    = Dqn_StrSkipWhitespace(ptr);
 | 
			
		||||
                ptr                    = Dqn_Str_SkipWhitespace(ptr);
 | 
			
		||||
                char const *copy_start = ptr;
 | 
			
		||||
                char const *copy_end   = Dqn_StrFind(ptr, HEADER_COPY_END, ptr_len, Dqn_CharCountI(HEADER_COPY_END));
 | 
			
		||||
                char const *copy_end   = Dqn_Str_Find(ptr, HEADER_COPY_END, ptr_len, Dqn_CharCountI(HEADER_COPY_END));
 | 
			
		||||
                if (!copy_end)
 | 
			
		||||
                {
 | 
			
		||||
                    fprintf(stderr, "Header copy begin macro: %s not matched with a copy end macro: %s", HEADER_COPY_BEGIN, HEADER_COPY_END);
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                isize copy_len = copy_end - copy_start;
 | 
			
		||||
                auto mem_scope = Dqn_MemArenaScopedRegion(&arena);
 | 
			
		||||
                char *sanitised_copy  = (char *)MEM_ARENA_ALLOC(&arena, copy_len);
 | 
			
		||||
                isize sanitised_len = 0;
 | 
			
		||||
                isize copy_len        = copy_end - copy_start;
 | 
			
		||||
                entry->copy_range.buf = (char *)DQN_MEM_ARENA_ALLOC(&arena, copy_len);
 | 
			
		||||
                DQN_FOR_EACH(copy_index, copy_len)
 | 
			
		||||
                {
 | 
			
		||||
                    char ch = copy_start[copy_index];
 | 
			
		||||
                    if (ch == '\r') continue;
 | 
			
		||||
                    sanitised_copy[sanitised_len++] = ch;
 | 
			
		||||
                    entry->copy_range.buf[entry->copy_range.len++] = ch;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ptr = copy_end;
 | 
			
		||||
                fprintf(stdout, "%.*s\n", (int)sanitised_len, sanitised_copy);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ptr_len = ptr_end - ptr;
 | 
			
		||||
        }
 | 
			
		||||
        DQN_ASSERT(header_entries_index == num_header_entries);
 | 
			
		||||
 | 
			
		||||
        DQN_FOR_EACH(entry_index, header_entries_index)
 | 
			
		||||
        {
 | 
			
		||||
            HeaderEntry const *entry = header_entries + entry_index;
 | 
			
		||||
            switch(entry->type)
 | 
			
		||||
            {
 | 
			
		||||
                case HeaderEntryType::Prototype:
 | 
			
		||||
                {
 | 
			
		||||
                    isize remaining_space = max_prototype_return_val - entry->function_decl.return_val.len + 1;
 | 
			
		||||
                    fprintf(stdout, "%.*s", (int)entry->function_decl.return_val.len, entry->function_decl.return_val.str);
 | 
			
		||||
                    DQN_FOR_EACH(space, remaining_space) fputs(" ", stdout);
 | 
			
		||||
                    fprintf(stdout, " %.*s;\n", (int)entry->function_decl.name_and_args.len, entry->function_decl.name_and_args.str);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
                case HeaderEntryType::Comment:
 | 
			
		||||
                {
 | 
			
		||||
                    fprintf(stdout, "%.*s\n", (int)entry->comment.len, entry->comment.buf);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
                case HeaderEntryType::CopyBegin:
 | 
			
		||||
                {
 | 
			
		||||
                    fprintf(stdout, "%.*s\n", (int)entry->copy_range.len, entry->copy_range.buf);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										556
									
								
								Code/DqnHeader_Generated.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										556
									
								
								Code/DqnHeader_Generated.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,556 @@
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Typedefs, Macros, Utils
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
constexpr Dqn_usize                       Dqn_ArrayCount(T const (&)[N]);
 | 
			
		||||
constexpr Dqn_isize                       Dqn_ArrayCountI(T const (&)[N]);
 | 
			
		||||
constexpr Dqn_usize                       Dqn_CharCount(char const (&)[N]);
 | 
			
		||||
constexpr Dqn_isize                       Dqn_CharCountI(char const (&)[N]);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Logging
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
constexpr inline char const *             Dqn_LogTypeTag(Dqn_LogType type);
 | 
			
		||||
// NOTE: Set the callback to get called whenever a log message has been printed
 | 
			
		||||
#define DQN_LOG_CALLBACK(name) void name(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *log_str)
 | 
			
		||||
typedef DQN_LOG_CALLBACK(Dqn_LogCallback);
 | 
			
		||||
Dqn_LogCallback *Dqn_log_callback;
 | 
			
		||||
 | 
			
		||||
#define DQN_LOG_E(fmt, ...) Dqn_Log(Dqn_LogType::Error,   DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
#define DQN_LOG_D(fmt, ...) Dqn_Log(Dqn_LogType::Debug,   DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
#define DQN_LOG_W(fmt, ...) Dqn_Log(Dqn_LogType::Warning, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
#define DQN_LOG_I(fmt, ...) Dqn_Log(Dqn_LogType::Info,    DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
#define DQN_LOG_M(fmt, ...) Dqn_Log(Dqn_LogType::Info,    DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
#define DQN_LOG(log_type, fmt, ...) Dqn_Log(log_type,    DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Math
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
union Dqn_V2I
 | 
			
		||||
{
 | 
			
		||||
  struct { Dqn_i32 x, y; };
 | 
			
		||||
  struct { Dqn_i32 w, h; };
 | 
			
		||||
  struct { Dqn_i32 min, max; };
 | 
			
		||||
  Dqn_i32 e[2];
 | 
			
		||||
 | 
			
		||||
  constexpr Dqn_V2I() = default;
 | 
			
		||||
  constexpr Dqn_V2I(Dqn_f32 x_, Dqn_f32 y_): x((Dqn_i32)x_), y((Dqn_i32)y_) {}
 | 
			
		||||
  constexpr Dqn_V2I(Dqn_i32 x_, Dqn_i32 y_): x(x_), y(y_) {}
 | 
			
		||||
  constexpr Dqn_V2I(Dqn_i32 xy):         x(xy), y(xy) {}
 | 
			
		||||
 | 
			
		||||
  constexpr bool     operator!=(Dqn_V2I other) const { return !(*this == other);                }
 | 
			
		||||
  constexpr bool     operator==(Dqn_V2I other) const { return (x == other.x) && (y == other.y); }
 | 
			
		||||
  constexpr bool     operator>=(Dqn_V2I other) const { return (x >= other.x) && (y >= other.y); }
 | 
			
		||||
  constexpr bool     operator<=(Dqn_V2I other) const { return (x <= other.x) && (y <= other.y); }
 | 
			
		||||
  constexpr bool     operator< (Dqn_V2I other) const { return (x <  other.x) && (y <  other.y); }
 | 
			
		||||
  constexpr bool     operator> (Dqn_V2I other) const { return (x >  other.x) && (y >  other.y); }
 | 
			
		||||
  constexpr Dqn_V2I  operator- (Dqn_V2I other) const { Dqn_V2I result(x - other.x, y - other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator+ (Dqn_V2I other) const { Dqn_V2I result(x + other.x, y + other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator* (Dqn_V2I other) const { Dqn_V2I result(x * other.x, y * other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator* (Dqn_f32 other) const { Dqn_V2I result(x * other,   y * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator* (Dqn_i32 other) const { Dqn_V2I result(x * other,   y * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator/ (Dqn_V2I other) const { Dqn_V2I result(x / other.x, y / other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator/ (Dqn_f32 other) const { Dqn_V2I result(x / other,   y / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2I  operator/ (Dqn_i32 other) const { Dqn_V2I result(x / other,   y / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2I &operator*=(Dqn_V2I other)       { *this = *this * other;                    return *this;  }
 | 
			
		||||
  constexpr Dqn_V2I &operator*=(Dqn_f32 other)       { *this = *this * other;                    return *this;  }
 | 
			
		||||
  constexpr Dqn_V2I &operator*=(Dqn_i32 other)       { *this = *this * other;                    return *this;  }
 | 
			
		||||
  constexpr Dqn_V2I &operator-=(Dqn_V2I other)       { *this = *this - other;                    return *this;  }
 | 
			
		||||
  constexpr Dqn_V2I &operator+=(Dqn_V2I other)       { *this = *this + other;                    return *this;  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Dqn_V2
 | 
			
		||||
{
 | 
			
		||||
  struct { Dqn_f32 x, y; };
 | 
			
		||||
  struct { Dqn_f32 w, h; };
 | 
			
		||||
  struct { Dqn_f32 min, max; };
 | 
			
		||||
  Dqn_f32 e[2];
 | 
			
		||||
 | 
			
		||||
  constexpr Dqn_V2() = default;
 | 
			
		||||
  constexpr Dqn_V2(Dqn_f32 a)         : x(a),        y(a)        {}
 | 
			
		||||
  constexpr Dqn_V2(Dqn_i32 a)         : x((Dqn_f32)a),   y((Dqn_f32)a)   {}
 | 
			
		||||
  constexpr Dqn_V2(Dqn_f32 x_, Dqn_f32 y_): x(x_),       y(y_)       {}
 | 
			
		||||
  constexpr Dqn_V2(Dqn_i32 x_, Dqn_i32 y_): x((Dqn_f32)x_),  y((Dqn_f32)y_)  {}
 | 
			
		||||
  constexpr Dqn_V2(Dqn_V2I a)         : x((Dqn_f32)a.x), y((Dqn_f32)a.y) {}
 | 
			
		||||
 | 
			
		||||
  constexpr bool    operator!=(Dqn_V2  other) const { return !(*this == other);                }
 | 
			
		||||
  constexpr bool    operator==(Dqn_V2  other) const { return (x == other.x) && (y == other.y); }
 | 
			
		||||
  constexpr bool    operator>=(Dqn_V2  other) const { return (x >= other.x) && (y >= other.y); }
 | 
			
		||||
  constexpr bool    operator<=(Dqn_V2  other) const { return (x <= other.x) && (y <= other.y); }
 | 
			
		||||
  constexpr bool    operator< (Dqn_V2  other) const { return (x <  other.x) && (y <  other.y); }
 | 
			
		||||
  constexpr bool    operator> (Dqn_V2  other) const { return (x >  other.x) && (y >  other.y); }
 | 
			
		||||
  constexpr Dqn_V2  operator- (Dqn_V2  other) const { Dqn_V2 result(x - other.x, y - other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator+ (Dqn_V2  other) const { Dqn_V2 result(x + other.x, y + other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator* (Dqn_V2  other) const { Dqn_V2 result(x * other.x, y * other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator* (Dqn_f32 other) const { Dqn_V2 result(x * other,   y * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator* (Dqn_i32 other) const { Dqn_V2 result(x * other,   y * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator/ (Dqn_V2  other) const { Dqn_V2 result(x / other.x, y / other.y); return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator/ (Dqn_f32 other) const { Dqn_V2 result(x / other,   y / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2  operator/ (Dqn_i32 other) const { Dqn_V2 result(x / other,   y / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V2 &operator*=(Dqn_V2  other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator*=(Dqn_f32 other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator*=(Dqn_i32 other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator/=(Dqn_V2  other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator/=(Dqn_f32 other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator/=(Dqn_i32 other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator-=(Dqn_V2  other)       { *this = *this - other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V2 &operator+=(Dqn_V2  other)       { *this = *this + other;               return *this;  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Dqn_V3
 | 
			
		||||
{
 | 
			
		||||
  struct { Dqn_f32 x, y, z; };
 | 
			
		||||
  struct { Dqn_f32 r, g, b; };
 | 
			
		||||
  Dqn_V2  xy;
 | 
			
		||||
  Dqn_f32 e[3];
 | 
			
		||||
 | 
			
		||||
  constexpr Dqn_V3() = default;
 | 
			
		||||
  constexpr Dqn_V3(Dqn_f32 a)                 : x(a),        y(a),       z(a)        {}
 | 
			
		||||
  constexpr Dqn_V3(Dqn_i32 a)                 : x((Dqn_f32)a),   y((Dqn_f32)a),  z((Dqn_f32)a)   {}
 | 
			
		||||
  constexpr Dqn_V3(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_): x(x_),       y(y_),      z(z_)       {}
 | 
			
		||||
  constexpr Dqn_V3(Dqn_i32 x_, Dqn_i32 y_, Dqn_f32 z_): x((Dqn_f32)x_),  y((Dqn_f32)y_), z((Dqn_f32)z_)  {}
 | 
			
		||||
  constexpr Dqn_V3(Dqn_V2  xy, Dqn_f32 z_)        : x(xy.x),     y(xy.y),    z(z_)       {}
 | 
			
		||||
 | 
			
		||||
  constexpr bool   operator!= (Dqn_V3  other) const { return !(*this == other);                }
 | 
			
		||||
  constexpr bool   operator== (Dqn_V3  other) const { return (x == other.x) && (y == other.y) && (z == other.z); }
 | 
			
		||||
  constexpr bool   operator>= (Dqn_V3  other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); }
 | 
			
		||||
  constexpr bool   operator<= (Dqn_V3  other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); }
 | 
			
		||||
  constexpr bool   operator<  (Dqn_V3  other) const { return (x <  other.x) && (y <  other.y) && (z <  other.z); }
 | 
			
		||||
  constexpr bool   operator>  (Dqn_V3  other) const { return (x >  other.x) && (y >  other.y) && (z >  other.z); }
 | 
			
		||||
  constexpr Dqn_V3 operator-  (Dqn_V3  other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator+  (Dqn_V3  other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator*  (Dqn_V3  other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator*  (Dqn_f32 other) const { Dqn_V3 result(x * other,   y * other,   z * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator*  (Dqn_i32 other) const { Dqn_V3 result(x * other,   y * other,   z * other);   return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator/  (Dqn_V3  other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator/  (Dqn_f32 other) const { Dqn_V3 result(x / other,   y / other,   z / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V3 operator/  (Dqn_i32 other) const { Dqn_V3 result(x / other,   y / other,   z / other);   return result; }
 | 
			
		||||
  constexpr Dqn_V3 &operator*=(Dqn_V3  other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator*=(Dqn_f32 other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator*=(Dqn_i32 other)       { *this = *this * other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator/=(Dqn_V3  other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator/=(Dqn_f32 other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator/=(Dqn_i32 other)       { *this = *this / other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator-=(Dqn_V3  other)       { *this = *this - other;               return *this;  }
 | 
			
		||||
  constexpr Dqn_V3 &operator+=(Dqn_V3  other)       { *this = *this + other;               return *this;  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Dqn_V4
 | 
			
		||||
{
 | 
			
		||||
  struct { Dqn_f32 x, y, z, w; };
 | 
			
		||||
  struct { Dqn_f32 r, g, b, a; };
 | 
			
		||||
  Dqn_V3 rgb;
 | 
			
		||||
  Dqn_f32 e[4];
 | 
			
		||||
 | 
			
		||||
  constexpr Dqn_V4() = default;
 | 
			
		||||
  constexpr Dqn_V4(Dqn_f32 xyzw)                      : x(xyzw),    y(xyzw),    z(xyzw),    w(xyzw)    {}
 | 
			
		||||
  constexpr Dqn_V4(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_, Dqn_f32 w_): x(x_),      y(y_),      z(z_),      w(w_)      {}
 | 
			
		||||
  constexpr Dqn_V4(Dqn_i32 x_, Dqn_i32 y_, Dqn_i32 z_, Dqn_i32 w_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_), w((Dqn_f32)w_) {}
 | 
			
		||||
  constexpr Dqn_V4(Dqn_V3 xyz, Dqn_f32 w_)                : x(xyz.x),  y(xyz.y),   z(xyz.z),   w(w_)       {}
 | 
			
		||||
 | 
			
		||||
  constexpr bool    operator!=(Dqn_V4  other) const { return !(*this == other);            }
 | 
			
		||||
  constexpr bool    operator==(Dqn_V4  other) const { return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); }
 | 
			
		||||
  constexpr bool    operator>=(Dqn_V4  other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z) && (w >= other.w); }
 | 
			
		||||
  constexpr bool    operator<=(Dqn_V4  other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z) && (w <= other.w); }
 | 
			
		||||
  constexpr bool    operator< (Dqn_V4  other) const { return (x <  other.x) && (y <  other.y) && (z <  other.z) && (w <  other.w); }
 | 
			
		||||
  constexpr bool    operator> (Dqn_V4  other) const { return (x >  other.x) && (y >  other.y) && (z >  other.z) && (w >  other.w); }
 | 
			
		||||
  constexpr Dqn_V4  operator- (Dqn_V4  other) const { Dqn_V4 result(x - other.x, y - other.y, z - other.z, w - other.w); return result;  }
 | 
			
		||||
  constexpr Dqn_V4  operator+ (Dqn_V4  other) const { Dqn_V4 result(x + other.x, y + other.y, z + other.z, w + other.w); return result;  }
 | 
			
		||||
  constexpr Dqn_V4  operator* (Dqn_V4  other) const { Dqn_V4 result(x * other.x, y * other.y, z * other.z, w * other.w); return result;  }
 | 
			
		||||
  constexpr Dqn_V4  operator* (Dqn_f32 other) const { Dqn_V4 result(x * other,   y * other,   z * other,   w * other);   return result;  }
 | 
			
		||||
  constexpr Dqn_V4  operator* (Dqn_i32 other) const { Dqn_V4 result(x * other,   y * other,   z * other,   w * other);   return result;  }
 | 
			
		||||
  constexpr Dqn_V4  operator/ (Dqn_f32 other) const { Dqn_V4 result(x / other,   y / other,   z / other,   w / other);   return result;  }
 | 
			
		||||
  constexpr Dqn_V4 &operator*=(Dqn_V4  other)       { *this = *this * other;                                             return *this;   }
 | 
			
		||||
  constexpr Dqn_V4 &operator*=(Dqn_f32 other)       { *this = *this * other;                                             return *this;   }
 | 
			
		||||
  constexpr Dqn_V4 &operator*=(Dqn_i32 other)       { *this = *this * other;                                             return *this;   }
 | 
			
		||||
  constexpr Dqn_V4 &operator-=(Dqn_V4  other)       { *this = *this - other;                                             return *this;   }
 | 
			
		||||
  constexpr Dqn_V4 &operator+=(Dqn_V4  other)       { *this = *this + other;                                             return *this;   }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dqn_Rect
 | 
			
		||||
{
 | 
			
		||||
    Dqn_V2 min, max;
 | 
			
		||||
    Dqn_Rect() = default;
 | 
			
		||||
    Dqn_Rect(Dqn_V2  min, Dqn_V2 max) : min(min), max(max) {}
 | 
			
		||||
    Dqn_Rect(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dqn_RectI32
 | 
			
		||||
{
 | 
			
		||||
    Dqn_V2I min, max;
 | 
			
		||||
    Dqn_RectI32() = default;
 | 
			
		||||
    Dqn_RectI32(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
union Dqn_Mat4
 | 
			
		||||
{
 | 
			
		||||
    Dqn_f32 e[16];
 | 
			
		||||
    Dqn_V4  row[4];
 | 
			
		||||
    Dqn_f32 row_major[4][4];
 | 
			
		||||
    Dqn_f32 operator[](Dqn_usize i) const { return e[i]; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T> int                 Dqn_MemCmpType(T const *ptr1, T const *ptr2);
 | 
			
		||||
template <typename T> T *                 Dqn_MemZero(T *src);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_MemArena
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
using Dqn_MemSize = Dqn_usize;
 | 
			
		||||
struct Dqn_MemBlock
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: Read only state
 | 
			
		||||
    Dqn_b32       allocated_by_user_or_fixed_mem;
 | 
			
		||||
    void         *memory;
 | 
			
		||||
    Dqn_MemSize   size;
 | 
			
		||||
    Dqn_MemSize   used;
 | 
			
		||||
    Dqn_MemBlock *prev;
 | 
			
		||||
    Dqn_MemBlock *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum Dqn_MemArenaFlag
 | 
			
		||||
{
 | 
			
		||||
    Dqn_MemArenaFlag_NoCRTAllocation = (1 << 0), // If my_calloc/my_free aren't null, it defaults to calloc and free, setting this flag disables that
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void *(Dqn_MemArenaCallocFunction)(size_t bytes);
 | 
			
		||||
typedef void  (Dqn_MemArenaFreeFunction)  (void *ptr, size_t bytes_to_free);
 | 
			
		||||
struct Dqn_MemArena
 | 
			
		||||
{
 | 
			
		||||
    // NOTE: Configuration (fill once)
 | 
			
		||||
    Dqn_MemArenaCallocFunction *my_calloc; // If nullptr, use CRT calloc unless disabled in flags
 | 
			
		||||
    Dqn_MemArenaFreeFunction   *my_free;   // If nullptr, use CRT free unless disabled in flags
 | 
			
		||||
    Dqn_u32                     flags;
 | 
			
		||||
 | 
			
		||||
    // NOTE: Read Only
 | 
			
		||||
    Dqn_u8        fixed_mem[DQN_KILOBYTES(16)];
 | 
			
		||||
    Dqn_MemBlock  fixed_mem_block;
 | 
			
		||||
    Dqn_MemBlock *curr_mem_block;
 | 
			
		||||
    Dqn_MemBlock *top_mem_block;
 | 
			
		||||
    Dqn_MemSize   highest_used_mark;
 | 
			
		||||
    int           total_allocated_mem_blocks;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Dqn_MemArenaScopedRegion
 | 
			
		||||
{
 | 
			
		||||
    Dqn_MemArenaScopedRegion(Dqn_MemArena *arena);
 | 
			
		||||
    ~Dqn_MemArenaScopedRegion();
 | 
			
		||||
    Dqn_MemArena *arena;
 | 
			
		||||
    Dqn_MemBlock *curr_mem_block;
 | 
			
		||||
    Dqn_usize         curr_mem_block_used;
 | 
			
		||||
    Dqn_MemBlock *top_mem_block;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING)
 | 
			
		||||
    #define DQN_DEBUG_ARGS , char const *file, Dqn_isize file_len, char const *func, Dqn_isize func_len, Dqn_isize line
 | 
			
		||||
    #define DQN_DEBUG_PARAMS , DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__
 | 
			
		||||
#else
 | 
			
		||||
    #define DQN_DEBUG_ARGS
 | 
			
		||||
    #define DQN_DEBUG_PARAMS
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DQN_MEM_ARENA_ALLOC(arena, size)             Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, num)     (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_ALLOC_STRUCT(arena, T)         (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_RESERVE(arena, size)           Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_CLEAR_USED(arena)              Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS);
 | 
			
		||||
#define DQN_MEM_ARENA_FREE(arena)                    Dqn_MemArena_Free
 | 
			
		||||
 | 
			
		||||
// -----------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: String Builder
 | 
			
		||||
//
 | 
			
		||||
// -----------------------------------------------------------------------------------------------
 | 
			
		||||
// The necessary length to build the string, it returns the length including the null-terminator
 | 
			
		||||
template <Dqn_usize N> Dqn_isize          Dqn_StringBuilder_BuildLen(Dqn_StringBuilder<N> const *builder);
 | 
			
		||||
template <Dqn_usize N> void               Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder<N> const *builder, char *dest, Dqn_usize dest_size);
 | 
			
		||||
template <Dqn_usize N> char *             Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder<N> *builder, Dqn_isize *len = nullptr);
 | 
			
		||||
template <Dqn_usize N> char *             Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder<N> *builder, Dqn_MemArena *arena, Dqn_isize *len = nullptr);
 | 
			
		||||
template <Dqn_usize N> void               Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, va_list va);
 | 
			
		||||
template <Dqn_usize N> void               Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder<N> *builder, char const *fmt, ...);
 | 
			
		||||
template <Dqn_usize N> void               Dqn_StringBuilder_Append(Dqn_StringBuilder<N> *builder, char const *str, Dqn_isize len = -1);
 | 
			
		||||
template <Dqn_usize N> void               Dqn_StringBuilder_AppendChar(Dqn_StringBuilder<N> *builder, char ch);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_Slices
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> inline Dqn_Slice<T> Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, T const *src, Dqn_isize len);
 | 
			
		||||
template <typename T> inline Dqn_Slice<T> Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, Dqn_Slice<T> const src);
 | 
			
		||||
template <typename T> inline Dqn_Slice<T> Dqn_Slice_Copy(Dqn_MemArena *arena, T const *src, Dqn_isize len);
 | 
			
		||||
template <typename T> inline Dqn_Slice<T> Dqn_Slice_Copy(Dqn_MemArena *arena, Dqn_Slice<T> const src);
 | 
			
		||||
template <typename T> inline bool         Dqn_Slice_Equals(Dqn_Slice<T> const a, Dqn_Slice<T> const b);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_Asprintf (Allocate Sprintf)
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> Dqn_Slice<char>     Dqn_AsprintfSlice(T *arena, char const *fmt, va_list va);
 | 
			
		||||
template <typename T> Dqn_Slice<char>     Dqn_AsprintfSlice(T *arena, char const *fmt, ...);
 | 
			
		||||
template <typename T> char *              Dqn_Asprintf(T *arena, int *len, char const *fmt, ...);
 | 
			
		||||
template <typename T> char *              Dqn_Asprintf(T *arena, char const *fmt, ...);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_FixedArray
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
#define DQN_FIXED_ARRAY_TEMPLATE template <typename T, int MAX_>
 | 
			
		||||
#define DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray<T, MAX_>
 | 
			
		||||
DQN_FIXED_ARRAY_TEMPLATE struct Dqn_FixedArray
 | 
			
		||||
{
 | 
			
		||||
    T         data[MAX_];
 | 
			
		||||
    Dqn_isize len;
 | 
			
		||||
    Dqn_isize Max()                   const { return MAX_; }
 | 
			
		||||
 | 
			
		||||
    T       &operator[] (Dqn_isize i)       { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return  data[i]; }
 | 
			
		||||
    T       *begin      ()                  { return data; }
 | 
			
		||||
    T       *end        ()                  { return data + len; }
 | 
			
		||||
    T       *operator+  (Dqn_isize i)       { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; }
 | 
			
		||||
 | 
			
		||||
    T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return  data[i]; }
 | 
			
		||||
    T const *begin      ()            const { return data; }
 | 
			
		||||
    T const *end        ()            const { return data + len; }
 | 
			
		||||
    T const *operator+  (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DQN_FIXED_ARRAY_TEMPLATE_DECL             Dqn_FixedArray_Init(T const *item, int num);
 | 
			
		||||
T *                                       Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *items, Dqn_isize num);
 | 
			
		||||
T *                                       Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const item);
 | 
			
		||||
T *                                       Dqn_FixedArray_Make(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num);
 | 
			
		||||
void                                      Dqn_FixedArray_Clear(DQN_FIXED_ARRAY_TEMPLATE_DECL *a);
 | 
			
		||||
void                                      Dqn_FixedArray_EraseStable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index);
 | 
			
		||||
void                                      Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index);
 | 
			
		||||
void                                      Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num);
 | 
			
		||||
T *                                       Dqn_FixedArray_Peek(DQN_FIXED_ARRAY_TEMPLATE_DECL *a);
 | 
			
		||||
Dqn_isize                                 Dqn_FixedArray_GetIndex(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *entry);
 | 
			
		||||
T *                                       Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, EqualityProc IsEqual);
 | 
			
		||||
T *                                       Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T *entry);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_FixedStack
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
template <typename T, int MAX_> using Dqn_FixedStack = DQN_FIXED_ARRAY_TEMPLATE_DECL;
 | 
			
		||||
template <typename T, int MAX_> T    Dqn_FixedStack_Pop  (Dqn_FixedStack<T, MAX_> *array)         { T result = *Dqn_FixedArray_Peek(array); Dqn_FixedArray_Pop(array, 1); return result; }
 | 
			
		||||
template <typename T, int MAX_> T   *Dqn_FixedStack_Peek (Dqn_FixedStack<T, MAX_> *array)         { return Dqn_FixedArray_Peek(array); }
 | 
			
		||||
template <typename T, int MAX_> T   *Dqn_FixedStack_Push (Dqn_FixedStack<T, MAX_> *array, T item) { return Dqn_FixedArray_Add(array, item); }
 | 
			
		||||
template <typename T, int MAX_> void Dqn_FixedStack_Clear(Dqn_FixedStack<T, MAX_> *array)         { Dqn_FixedArray_Clear(array); }
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_StaticArray
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
template <typename T> struct Dqn_StaticArray
 | 
			
		||||
{
 | 
			
		||||
    T       *data;
 | 
			
		||||
    Dqn_isize    len;
 | 
			
		||||
    Dqn_isize    max;
 | 
			
		||||
    T const  operator[](Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return  data[i]; }
 | 
			
		||||
    T        operator[](Dqn_isize i)       { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return  data[i]; }
 | 
			
		||||
    T const *begin    ()         const { return data; }
 | 
			
		||||
    T const *end      ()         const { return data + len; }
 | 
			
		||||
    T       *begin    ()               { return data; }
 | 
			
		||||
    T       *end      ()               { return data + len; }
 | 
			
		||||
    T const *operator+(Dqn_isize i) const  { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; }
 | 
			
		||||
    T       *operator+(Dqn_isize i)        { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T> Dqn_StaticArray<T>  Dqn_StaticArray_InitMemory   (T *memory, Dqn_isize max, Dqn_isize len = 0);
 | 
			
		||||
template <typename T> T                 * Dqn_StaticArray_Add          (Dqn_StaticArray<T> *a, T const *items, Dqn_isize num);
 | 
			
		||||
template <typename T> T                 * Dqn_StaticArray_Add          (Dqn_StaticArray<T> *a, T const item);
 | 
			
		||||
template <typename T> T                 * Dqn_StaticArray_Make         (Dqn_StaticArray<T> *a, Dqn_isize num);
 | 
			
		||||
template <typename T> void                Dqn_StaticArray_Clear        (Dqn_StaticArray<T> *a);
 | 
			
		||||
template <typename T> void                Dqn_StaticArray_EraseStable  (Dqn_StaticArray<T> *a, Dqn_isize index);
 | 
			
		||||
template <typename T> void                Dqn_StaticArray_EraseUnstable(Dqn_StaticArray<T> *a, Dqn_isize index);
 | 
			
		||||
template <typename T> void                Dqn_StaticArray_Pop          (Dqn_StaticArray<T> *a, Dqn_isize num);
 | 
			
		||||
template <typename T> T                 * Dqn_StaticArray_Peek         (Dqn_StaticArray<T> *a);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_FixedString
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
template <Dqn_isize MAX_>
 | 
			
		||||
struct Dqn_FixedString
 | 
			
		||||
{
 | 
			
		||||
    union { char data[MAX_]; char str[MAX_]; char buf[MAX_]; };
 | 
			
		||||
    Dqn_isize       len;
 | 
			
		||||
    Dqn_isize       Max()                  const { return MAX_; }
 | 
			
		||||
 | 
			
		||||
    Dqn_FixedString()                            { data[0] = 0; len = 0; }
 | 
			
		||||
    Dqn_FixedString(char const *fmt, ...)
 | 
			
		||||
    {
 | 
			
		||||
        *this = {};
 | 
			
		||||
        va_list va;
 | 
			
		||||
        va_start(va, fmt);
 | 
			
		||||
        Dqn_FixedString_AppendVFmt(this, fmt, va);
 | 
			
		||||
        va_end(va);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char const &operator[]   (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
 | 
			
		||||
    char       &operator[]   (Dqn_isize i)       { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; }
 | 
			
		||||
    char const *begin        ()        const { return data; }
 | 
			
		||||
    char const *end          ()        const { return data + len; }
 | 
			
		||||
    char       *begin        ()              { return data; }
 | 
			
		||||
    char       *end          ()              { return data + len; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <Dqn_isize MAX_> void            Dqn_FixedString_Clear(Dqn_FixedString<MAX_> *str);
 | 
			
		||||
template <Dqn_isize MAX_> void            Dqn_FixedString_AppendVFmt(Dqn_FixedString<MAX_> *str, char const *fmt, va_list va);
 | 
			
		||||
template <Dqn_isize MAX_> void            Dqn_FixedString_AppendFmt(Dqn_FixedString<MAX_> *str, char const *fmt, ...);
 | 
			
		||||
template <Dqn_isize MAX_> void            Dqn_FixedString_Append(Dqn_FixedString<MAX_> *str, char const *src, Dqn_isize len = -1);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_Dqn_U64Str
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
struct Dqn_U64Str
 | 
			
		||||
{
 | 
			
		||||
    // Points to the start of the str in the buffer, not necessarily buf since
 | 
			
		||||
    // we write into the buffer in reverse
 | 
			
		||||
    char *start;
 | 
			
		||||
    char buf[27]; // NOTE(doyle): 27 is the maximum size of Dqn_u64 including commas
 | 
			
		||||
    int len;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Helpers
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
int                                       Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes);
 | 
			
		||||
void *                                    Dqn_MemCopy(void *dest, void const *src, size_t num_bytes);
 | 
			
		||||
void *                                    Dqn_MemMove(void *dest, void const *src, size_t num_bytes);
 | 
			
		||||
void *                                    Dqn_MemSet(void *src, char ch, Dqn_usize num_bytes);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Logging
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
void                                      Dqn_LogV(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va);
 | 
			
		||||
void                                      Dqn_Log(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_MemArena
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
void *                                    Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS);
 | 
			
		||||
void                                      Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS);
 | 
			
		||||
Dqn_b32                                   Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS);
 | 
			
		||||
void                                      Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS);
 | 
			
		||||
void                                      Dqn_MemArena_ClearUsed(Dqn_MemArena *arena DQN_DEBUG_ARGS);
 | 
			
		||||
Dqn_MemArenaScopedRegion                  Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Vectors
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_V2I                                   Dqn_V2_ToV2I(Dqn_V2 a);
 | 
			
		||||
Dqn_V2                                    Dqn_V2_Max(Dqn_V2 a, Dqn_V2 b);
 | 
			
		||||
Dqn_V2                                    Dqn_V2_Abs(Dqn_V2 a);
 | 
			
		||||
Dqn_f32                                   Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b);
 | 
			
		||||
Dqn_f32                                   Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b);
 | 
			
		||||
Dqn_V2                                    Dqn_V2_Normalise(Dqn_V2 a);
 | 
			
		||||
Dqn_V2                                    Dqn_V2_Perpendicular(Dqn_V2 a);
 | 
			
		||||
Dqn_f32                                   Dqn_V4_Dot(Dqn_V4 const *a, Dqn_V4 const *b);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Rect
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_Rect                                  Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size);
 | 
			
		||||
Dqn_V2                                    Dqn_Rect_Center(Dqn_Rect rect);
 | 
			
		||||
Dqn_b32                                   Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p);
 | 
			
		||||
Dqn_b32                                   Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b);
 | 
			
		||||
Dqn_V2                                    Dqn_Rect_Size(Dqn_Rect rect);
 | 
			
		||||
Dqn_Rect                                  Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amount);
 | 
			
		||||
Dqn_Rect                                  Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b);
 | 
			
		||||
Dqn_Rect                                  Dqn_Rect_FromRectI32(Dqn_RectI32 a);
 | 
			
		||||
Dqn_V2I                                   Dqn_RectI32_Size(Dqn_RectI32 rect);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Math Utils
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_V2                                    Dqn_LerpV2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Dqn_Mat4
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_Mat4                                  Dqn_Mat4_Identity();
 | 
			
		||||
Dqn_Mat4                                  Dqn_Mat4_Scale3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z);
 | 
			
		||||
Dqn_Mat4                                  Dqn_Mat4_ScaleV3(Dqn_V3 vec);
 | 
			
		||||
Dqn_Mat4                                  Dqn_Mat4_Translate3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z);
 | 
			
		||||
Dqn_Mat4                                  Dqn_Mat4_TranslateV3(Dqn_V3 vec);
 | 
			
		||||
Dqn_Mat4                                  operator*(Dqn_Mat4 const &a, Dqn_Mat4 const &b);
 | 
			
		||||
Dqn_V4                                    operator*(Dqn_Mat4 const &mat, Dqn_V4 const &vec);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Helper Functions
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
void                                      Dqn_Bit_UnsetInplace(Dqn_u32 *flags, Dqn_u32 bitfield);
 | 
			
		||||
void                                      Dqn_Bit_SetInplace(Dqn_u32 *flags, Dqn_u32 bitfield);
 | 
			
		||||
Dqn_b32                                   Dqn_Bit_IsSet(Dqn_u32 flags, Dqn_u32 bitfield);
 | 
			
		||||
Dqn_b32                                   Dqn_Bit_IsNotSet(Dqn_u32 flags, Dqn_u32 bitfield);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Safe Arithmetic
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_i64                                   Dqn_Safe_AddI64(Dqn_i64 a, Dqn_i64 b);
 | 
			
		||||
Dqn_i64                                   Dqn_Safe_MulI64(Dqn_i64 a, Dqn_i64 b);
 | 
			
		||||
Dqn_u64                                   Dqn_Safe_AddU64(Dqn_u64 a, Dqn_u64 b);
 | 
			
		||||
Dqn_u64                                   Dqn_Safe_MulU64(Dqn_u64 a, Dqn_u64 b);
 | 
			
		||||
int                                       Dqn_Safe_TruncateISizeToInt(Dqn_isize val);
 | 
			
		||||
Dqn_i32                                   Dqn_Safe_TruncateISizeToI32(Dqn_isize val);
 | 
			
		||||
Dqn_i8                                    Dqn_Safe_TruncateISizeToI8(Dqn_isize val);
 | 
			
		||||
Dqn_u32                                   Dqn_Safe_TruncateUSizeToU32(Dqn_u64 val);
 | 
			
		||||
int                                       Dqn_Safe_TruncateUSizeToI32(Dqn_usize val);
 | 
			
		||||
int                                       Dqn_Safe_TruncateUSizeToInt(Dqn_usize val);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: Char Helpers
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_b32                                   Dqn_Char_IsAlpha(char ch);
 | 
			
		||||
Dqn_b32                                   Dqn_Char_IsDigit(char ch);
 | 
			
		||||
Dqn_b32                                   Dqn_Char_IsAlphaNum(char ch);
 | 
			
		||||
Dqn_b32                                   Dqn_Char_IsWhitespace(char ch);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: String Helpers
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
Dqn_b32                                   Dqn_Str_Equals(char const *a, Dqn_isize a_len, char const *b, Dqn_isize b_len = -1);
 | 
			
		||||
char const *                              Dqn_Str_FindMulti(char const *buf, char const *find_list[], Dqn_isize const *find_string_lens, Dqn_isize find_len, Dqn_isize *match_index, Dqn_isize buf_len = -1);
 | 
			
		||||
char const *                              Dqn_Str_Find(char const *buf, char const *find, Dqn_isize buf_len = -1, Dqn_isize find_len = -1);
 | 
			
		||||
Dqn_b32                                   Dqn_Str_Match(char const *src, char const *find, int find_len);
 | 
			
		||||
char const *                              Dqn_Str_SkipToChar(char const *src, char ch);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextAlphaNum(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextDigit(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextChar(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextWord(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextWhitespace(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipWhitespace(char const *src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToCharInPlace(char const **src, char ch);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextAlphaNumInPlace(char const **src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextCharInPlace(char const **src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextWhitespaceInPlace(char const **src);
 | 
			
		||||
char const *                              Dqn_Str_SkipToNextWordInPlace(char const **src);
 | 
			
		||||
char const *                              Dqn_Str_SkipWhitespaceInPlace(char const **src);
 | 
			
		||||
Dqn_u64                                   Dqn_Str_ToU64(char const *buf, int len = -1);
 | 
			
		||||
Dqn_i64                                   Dqn_Str_ToI64(char const *buf, int len = -1);
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
// NOTE: File
 | 
			
		||||
//
 | 
			
		||||
// -------------------------------------------------------------------------------------------------
 | 
			
		||||
char *                                    Dqn_File_ReadWithArena(Dqn_MemArena *arena, char const *file, Dqn_isize *file_size);
 | 
			
		||||
							
								
								
									
										2533
									
								
								Code/DqnInspect.h
									
									
									
									
									
								
							
							
						
						
									
										2533
									
								
								Code/DqnInspect.h
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,53 +0,0 @@
 | 
			
		||||
struct V3 {
 | 
			
		||||
  V3(float a, float b, float c) { (void)a; (void)b; (void)c; }
 | 
			
		||||
  float a, b, c;
 | 
			
		||||
};
 | 
			
		||||
struct V4 { float test; };
 | 
			
		||||
 | 
			
		||||
template <typename T, int Size>
 | 
			
		||||
struct Array { T data[Size]; };
 | 
			
		||||
 | 
			
		||||
enum struct OpenGLShader { Vertex, Count, };
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT struct SampleStruct
 | 
			
		||||
{
 | 
			
		||||
    int             ebo                                 DQN_INSPECT_META(char const *DisplayName = "Element Buffer Object"), vbo, vao DQN_INSPECT_META(char const *DisplayName = "Vertex Array Object", int OpenGLVersion = 330);
 | 
			
		||||
    const int *const a;
 | 
			
		||||
    int const *const b, c, *d, *e;
 | 
			
		||||
    V4              draw_color                          DQN_INSPECT_META(char const *DisplayName = "HelloWorld");
 | 
			
		||||
// #if 0
 | 
			
		||||
// #endif
 | 
			
		||||
    Array<V3, 32>   lights;
 | 
			
		||||
    Array<V4, 32>   camera_matrixes;
 | 
			
		||||
    char          **bitmaps;
 | 
			
		||||
    int             shaders[(int)OpenGLShader::Count];
 | 
			
		||||
    void           *win32_handle;
 | 
			
		||||
    V3              lighting_ambient_coeff;
 | 
			
		||||
    int             draw_call_count;
 | 
			
		||||
 | 
			
		||||
    const int f;
 | 
			
		||||
    int const g;
 | 
			
		||||
    int *const h;
 | 
			
		||||
    int const* i;
 | 
			
		||||
    int ****const j, k, **l, *m;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT enum struct EnumWithMetadata
 | 
			
		||||
{
 | 
			
		||||
    Rect   DQN_INSPECT_META(char const *FilePath = "Rect.vert", V3 Coords = V3(1, 2, 3)),
 | 
			
		||||
    Square DQN_INSPECT_META(char const *FilePath = "Square.vert"),
 | 
			
		||||
    Count,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT_FUNCTION(b = {}, c = nullptr, e = false, f = 1, g = "Hello world")
 | 
			
		||||
void Function1(int a, float b, char const *c, bool e, int f, char *g)
 | 
			
		||||
{
 | 
			
		||||
    (void)a; (void)b; (void)c; (void)e; (void)f; (void)g;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT_FUNCTION(foo = V3(10, 20, 50), bar = {120, 150, 20})
 | 
			
		||||
void *Function2(V3 foo, V3 bar, ...) { (void)foo; (void)bar; return nullptr; }
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT_FUNCTION()
 | 
			
		||||
Array<int const *, 3> const *const Function3(Array<int, 32> const *foobar) { (void)foobar; return {}; }
 | 
			
		||||
@ -1,425 +0,0 @@
 | 
			
		||||
// This is an auto generated file using DqnInspect
 | 
			
		||||
 | 
			
		||||
 // NOTE: These macros are undefined at the end of the file so to not pollute namespace
 | 
			
		||||
#define ARRAY_COUNT(array) sizeof(array)/sizeof((array)[0])
 | 
			
		||||
#define CHAR_COUNT(str) (ARRAY_COUNT(str) - 1)
 | 
			
		||||
#define STR_AND_LEN(str) str, CHAR_COUNT(str)
 | 
			
		||||
 | 
			
		||||
enum struct DqnInspectMemberType
 | 
			
		||||
{
 | 
			
		||||
    SampleStruct,
 | 
			
		||||
    SampleStruct_a,
 | 
			
		||||
    SampleStruct_b,
 | 
			
		||||
    SampleStruct_c,
 | 
			
		||||
    SampleStruct_d,
 | 
			
		||||
    SampleStruct_e,
 | 
			
		||||
    SampleStruct_f,
 | 
			
		||||
    SampleStruct_g,
 | 
			
		||||
    SampleStruct_h,
 | 
			
		||||
    SampleStruct_i,
 | 
			
		||||
    SampleStruct_j,
 | 
			
		||||
    SampleStruct_k,
 | 
			
		||||
    SampleStruct_l,
 | 
			
		||||
    SampleStruct_m,
 | 
			
		||||
    EnumWithMetadata,
 | 
			
		||||
    SampleStruct_ebo,
 | 
			
		||||
    SampleStruct_vao,
 | 
			
		||||
    SampleStruct_vbo,
 | 
			
		||||
    SampleStruct_lights,
 | 
			
		||||
    SampleStruct_bitmaps,
 | 
			
		||||
    SampleStruct_shaders,
 | 
			
		||||
    EnumWithMetadata_Rect,
 | 
			
		||||
    EnumWithMetadata_Count,
 | 
			
		||||
    EnumWithMetadata_Square,
 | 
			
		||||
    SampleStruct_draw_color,
 | 
			
		||||
    SampleStruct_win32_handle,
 | 
			
		||||
    SampleStruct_camera_matrixes,
 | 
			
		||||
    SampleStruct_draw_call_count,
 | 
			
		||||
    SampleStruct_lighting_ambient_coeff,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum struct DqnInspectDeclType
 | 
			
		||||
{
 | 
			
		||||
    NotAvailable_,
 | 
			
		||||
    V3_,
 | 
			
		||||
    V4_,
 | 
			
		||||
    int_,
 | 
			
		||||
    Array_,
 | 
			
		||||
    int_Ptr_,
 | 
			
		||||
    V3,_32_,
 | 
			
		||||
    V4,_32_,
 | 
			
		||||
    int_Ptr_Ptr_,
 | 
			
		||||
    void_Ptr_,
 | 
			
		||||
    char_Ptr_Ptr_,
 | 
			
		||||
    int_const_,
 | 
			
		||||
    int_Ptr_const_,
 | 
			
		||||
    int_const_Ptr_,
 | 
			
		||||
    SampleStruct_,
 | 
			
		||||
    char_const_Ptr_,
 | 
			
		||||
    Array_V3,_32_,
 | 
			
		||||
    Array_V4,_32_,
 | 
			
		||||
    int_Ptr_Ptr_Ptr_Ptr_const_,
 | 
			
		||||
    EnumWithMetadata_,
 | 
			
		||||
    int_const_Ptr_const_,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum struct DqnInspectMetaType
 | 
			
		||||
{
 | 
			
		||||
    DisplayName,
 | 
			
		||||
    OpenGLVersion,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// ..\Data\DqnInspect_TestData.h
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef DQN_INSPECT_DQNINSPECT_TESTDATA_H
 | 
			
		||||
#define DQN_INSPECT_DQNINSPECT_TESTDATA_H
 | 
			
		||||
 | 
			
		||||
char const * DqnInspectMetadata_SampleStruct_ebo_DisplayName = "Element Buffer Object";
 | 
			
		||||
char const * DqnInspectMetadata_SampleStruct_vao_DisplayName = "Vertex Array Object";
 | 
			
		||||
int DqnInspectMetadata_SampleStruct_vao_OpenGLVersion = 330;
 | 
			
		||||
char const * DqnInspectMetadata_SampleStruct_draw_color_DisplayName = "HelloWorld";
 | 
			
		||||
 | 
			
		||||
DqnInspectMetadata const DqnInspectMetadata_SampleStruct_ebo[] =
 | 
			
		||||
{
 | 
			
		||||
    { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_ebo_DisplayName},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DqnInspectMetadata const DqnInspectMetadata_SampleStruct_vao[] =
 | 
			
		||||
{
 | 
			
		||||
    { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_vao_DisplayName},
 | 
			
		||||
    { DqnInspectDeclType::int_, DqnInspectMetaType::OpenGLVersion, &DqnInspectMetadata_SampleStruct_vao_OpenGLVersion},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DqnInspectMetadata const DqnInspectMetadata_SampleStruct_draw_color[] =
 | 
			
		||||
{
 | 
			
		||||
    { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_draw_color_DisplayName},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DqnInspectMember const DqnInspect_SampleStruct_Members[] =
 | 
			
		||||
{
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_ebo, STR_AND_LEN("ebo"),
 | 
			
		||||
        offsetof(SampleStruct, ebo),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->ebo), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        DqnInspectMetadata_SampleStruct_ebo, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_ebo), // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_vbo, STR_AND_LEN("vbo"),
 | 
			
		||||
        offsetof(SampleStruct, vbo),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->vbo), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_vao, STR_AND_LEN("vao"),
 | 
			
		||||
        offsetof(SampleStruct, vao),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->vao), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        DqnInspectMetadata_SampleStruct_vao, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_vao), // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_a, STR_AND_LEN("a"),
 | 
			
		||||
        offsetof(SampleStruct, a),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_const_, STR_AND_LEN("int *const"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->a), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_const_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_b, STR_AND_LEN("b"),
 | 
			
		||||
        offsetof(SampleStruct, b),
 | 
			
		||||
        DqnInspectDeclType::int_const_Ptr_const_, STR_AND_LEN("int const *const"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->b), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_const_Ptr_const_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_c, STR_AND_LEN("c"),
 | 
			
		||||
        offsetof(SampleStruct, c),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->c), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_d, STR_AND_LEN("d"),
 | 
			
		||||
        offsetof(SampleStruct, d),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->d), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_e, STR_AND_LEN("e"),
 | 
			
		||||
        offsetof(SampleStruct, e),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->e), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_draw_color, STR_AND_LEN("draw_color"),
 | 
			
		||||
        offsetof(SampleStruct, draw_color),
 | 
			
		||||
        DqnInspectDeclType::V4_, STR_AND_LEN("V4"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->draw_color), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::V4_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        DqnInspectMetadata_SampleStruct_draw_color, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_draw_color), // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_lights, STR_AND_LEN("lights"),
 | 
			
		||||
        offsetof(SampleStruct, lights),
 | 
			
		||||
        DqnInspectDeclType::Array_V3,_32_, STR_AND_LEN("Array<V3, 32>"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->lights), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::Array_, DqnInspectDeclType::V3,_32_,
 | 
			
		||||
        STR_AND_LEN("V3, 32"), // template_child_expr
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_camera_matrixes, STR_AND_LEN("camera_matrixes"),
 | 
			
		||||
        offsetof(SampleStruct, camera_matrixes),
 | 
			
		||||
        DqnInspectDeclType::Array_V4,_32_, STR_AND_LEN("Array<V4, 32>"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->camera_matrixes), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::Array_, DqnInspectDeclType::V4,_32_,
 | 
			
		||||
        STR_AND_LEN("V4, 32"), // template_child_expr
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_bitmaps, STR_AND_LEN("bitmaps"),
 | 
			
		||||
        offsetof(SampleStruct, bitmaps),
 | 
			
		||||
        DqnInspectDeclType::char_Ptr_Ptr_, STR_AND_LEN("char **"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->bitmaps), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::char_Ptr_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        2, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_shaders, STR_AND_LEN("shaders"),
 | 
			
		||||
        offsetof(SampleStruct, shaders),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->shaders), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {ARRAY_COUNT(((SampleStruct *)0)->shaders), 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_win32_handle, STR_AND_LEN("win32_handle"),
 | 
			
		||||
        offsetof(SampleStruct, win32_handle),
 | 
			
		||||
        DqnInspectDeclType::void_Ptr_, STR_AND_LEN("void *"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->win32_handle), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::void_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_lighting_ambient_coeff, STR_AND_LEN("lighting_ambient_coeff"),
 | 
			
		||||
        offsetof(SampleStruct, lighting_ambient_coeff),
 | 
			
		||||
        DqnInspectDeclType::V3_, STR_AND_LEN("V3"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->lighting_ambient_coeff), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::V3_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_draw_call_count, STR_AND_LEN("draw_call_count"),
 | 
			
		||||
        offsetof(SampleStruct, draw_call_count),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->draw_call_count), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_f, STR_AND_LEN("f"),
 | 
			
		||||
        offsetof(SampleStruct, f),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->f), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_g, STR_AND_LEN("g"),
 | 
			
		||||
        offsetof(SampleStruct, g),
 | 
			
		||||
        DqnInspectDeclType::int_const_, STR_AND_LEN("int const"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->g), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_const_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_h, STR_AND_LEN("h"),
 | 
			
		||||
        offsetof(SampleStruct, h),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_const_, STR_AND_LEN("int *const"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->h), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_const_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_i, STR_AND_LEN("i"),
 | 
			
		||||
        offsetof(SampleStruct, i),
 | 
			
		||||
        DqnInspectDeclType::int_const_Ptr_, STR_AND_LEN("int const*"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->i), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_const_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_j, STR_AND_LEN("j"),
 | 
			
		||||
        offsetof(SampleStruct, j),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_Ptr_Ptr_Ptr_const_, STR_AND_LEN("int ****const"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->j), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_Ptr_Ptr_Ptr_const_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        4, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_k, STR_AND_LEN("k"),
 | 
			
		||||
        offsetof(SampleStruct, k),
 | 
			
		||||
        DqnInspectDeclType::int_, STR_AND_LEN("int"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->k), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        0, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_l, STR_AND_LEN("l"),
 | 
			
		||||
        offsetof(SampleStruct, l),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_Ptr_, STR_AND_LEN("int **"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->l), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        2, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        DqnInspectMemberType::SampleStruct_m, STR_AND_LEN("m"),
 | 
			
		||||
        offsetof(SampleStruct, m),
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"),
 | 
			
		||||
        sizeof(((SampleStruct *)0)->m), // full_decl_type_sizeof
 | 
			
		||||
        DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_,
 | 
			
		||||
        nullptr, 0, // template_child_expr and template_child_expr_len
 | 
			
		||||
        1, // array_dimensions
 | 
			
		||||
        {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,
 | 
			
		||||
        nullptr, 0, // metadata array
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DqnInspectStruct const DqnInspect_SampleStruct_Struct =
 | 
			
		||||
{
 | 
			
		||||
    STR_AND_LEN("SampleStruct"),
 | 
			
		||||
    DqnInspect_SampleStruct_Members, // members
 | 
			
		||||
    ARRAY_COUNT(DqnInspect_SampleStruct_Members) // members_len
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DqnInspectStruct const *DqnInspect_Struct(SampleStruct const *)
 | 
			
		||||
{
 | 
			
		||||
    DqnInspectStruct const *result = &DqnInspect_SampleStruct_Struct;
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char const *DqnInspect_EnumWithMetadata_Strings[] = {"Rect", "Square", "Count", };
 | 
			
		||||
 | 
			
		||||
char const *DqnInspectEnum_Stringify(EnumWithMetadata val, int *len = nullptr)
 | 
			
		||||
{
 | 
			
		||||
    if (val == EnumWithMetadata::Rect)   { if (len) *len = CHAR_COUNT("Rect"); return DqnInspect_EnumWithMetadata_Strings[0]; }
 | 
			
		||||
    if (val == EnumWithMetadata::Square) { if (len) *len = CHAR_COUNT("Square"); return DqnInspect_EnumWithMetadata_Strings[1]; }
 | 
			
		||||
    if (val == EnumWithMetadata::Count)  { if (len) *len = CHAR_COUNT("Count"); return DqnInspect_EnumWithMetadata_Strings[2]; }
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int DqnInspectEnum_Count(EnumWithMetadata) { return 3; }
 | 
			
		||||
 | 
			
		||||
char const * DqnInspectMetadata_FilePath(EnumWithMetadata val)
 | 
			
		||||
{
 | 
			
		||||
    if (val == EnumWithMetadata::Rect) { return "Rect.vert"; }
 | 
			
		||||
    if (val == EnumWithMetadata::Square) { return "Square.vert"; }
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool DqnInspectMetadata_Coords(EnumWithMetadata val, V3 *value = nullptr)
 | 
			
		||||
{
 | 
			
		||||
    if (val == EnumWithMetadata::Rect) { *value = V3(1, 2, 3); return true; }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void                               Function1(int a, float b = {}, char const * c = nullptr, bool e = false, int f = 1, char * g = "Hello world");
 | 
			
		||||
void *                             Function2(V3 foo = V3(10, 20, 50), V3 bar = {120, 150, 20}, ...);
 | 
			
		||||
Array<int const *, 3> const *const Function3(Array<int, 32> const * foobar);
 | 
			
		||||
 | 
			
		||||
#endif // DQN_INSPECT_DQNINSPECT_TESTDATA_H
 | 
			
		||||
 | 
			
		||||
DqnInspectStruct const *DqnInspect_Struct(DqnInspectDeclType type)
 | 
			
		||||
{
 | 
			
		||||
    (void)type;
 | 
			
		||||
#ifdef DQN_INSPECT_DQNINSPECT_TESTDATA_H
 | 
			
		||||
    if (type == DqnInspectDeclType::SampleStruct_) return &DqnInspect_SampleStruct_Struct;
 | 
			
		||||
#endif // DQN_INSPECT_DQNINSPECT_TESTDATA_H
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#undef ARRAY_COUNT
 | 
			
		||||
#undef CHAR_COUNT
 | 
			
		||||
#undef STR_AND_LEN
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio 15
 | 
			
		||||
VisualStudioVersion = 15.0.28307.168
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "DqnInspect", "..\..\Bin\DqnInspect.exe", "{52E81ACE-0533-48AA-878A-78CAFC30857B}"
 | 
			
		||||
	ProjectSection(DebuggerProjectSystem) = preProject
 | 
			
		||||
		PortSupplier = 00000000-0000-0000-0000-000000000000
 | 
			
		||||
		Executable = F:\Home\Code\dqn\Bin\DqnInspect.exe
 | 
			
		||||
		RemoteMachine = THAI-XPS13
 | 
			
		||||
		StartingDirectory = F:\Home\Code\dqn\Data\
 | 
			
		||||
		Arguments = DqnInspect_TestData.h
 | 
			
		||||
		Environment = Default
 | 
			
		||||
		LaunchingEngine = 00000000-0000-0000-0000-000000000000
 | 
			
		||||
		UseLegacyDebugEngines = No
 | 
			
		||||
		LaunchSQLEngine = No
 | 
			
		||||
		AttachLaunchAction = No
 | 
			
		||||
	EndProjectSection
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Release|x64 = Release|x64
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
			
		||||
		{52E81ACE-0533-48AA-878A-78CAFC30857B}.Release|x64.ActiveCfg = Release|x64
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ExtensibilityGlobals) = postSolution
 | 
			
		||||
		SolutionGuid = {38BBCDD2-0DF9-4BD5-B72B-50926B5827FE}
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
							
								
								
									
										62
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								readme.md
									
									
									
									
									
								
							@ -1,43 +1,53 @@
 | 
			
		||||
# Dqn
 | 
			
		||||
Personal utility library.
 | 
			
		||||
 | 
			
		||||
## DqnInspect
 | 
			
		||||
A simple C++ introspection metaprogram designed as a prebuild step and generates type information for the inspected types. It is a minimal single header file licensed in the public domain with only CRT dependencies. It is only able to parse C-like C++, i.e. Plain Old Data types only.
 | 
			
		||||
## DqnHeader
 | 
			
		||||
A simple C++ introspection metaprogram designed as a prebuild step and generates a summary of function prototypes and comments in a header file based on annotations. It is not designed to be used as a header file for compilation and will most likely fail syntax rules if tried.
 | 
			
		||||
 | 
			
		||||
The generated file is written to stdout.
 | 
			
		||||
 | 
			
		||||
### Build
 | 
			
		||||
Build DqnHeader by defining `DQN_HEADER_IMPLEMENTATION` before compiling and execute it as follows
 | 
			
		||||
 | 
			
		||||
`DqnHeader.exe SourceCode.h > GeneratedFile.h`
 | 
			
		||||
 | 
			
		||||
### Usage
 | 
			
		||||
Annotate the C++ code using `DQN_INSPECT`, i.e.
 | 
			
		||||
Include `DqnHeader.h` in a file and use the macros, annotations as described.
 | 
			
		||||
  * Extract function prototypes using the `DQN_HEADER_COPY_PROTOTYPE` macro
 | 
			
		||||
  * Copy comments by writing comments with `// @` as the prefix
 | 
			
		||||
  * Copy many lines of code by enclosing it in `DQN_HEADER_COPY_BEGIN` and `DQN_HEADER_COPY_END` macros
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
DQN_INSPECT struct Entity
 | 
			
		||||
#include "DqnHeader.h"
 | 
			
		||||
 | 
			
		||||
// @ ptr1: Pointer to the first block of memory
 | 
			
		||||
// @ ptr2: Pointer to the second block of memory
 | 
			
		||||
// @ num_bytes: The number of bytes to compare in both blocks of memory
 | 
			
		||||
DQN_HEADER_COPY_PROTOTYPE(int, Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes))
 | 
			
		||||
{
 | 
			
		||||
    V2 pos;
 | 
			
		||||
    V2 size;
 | 
			
		||||
    int result = memcmp(ptr1, ptr2, num_bytes);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DQN_INSPECT enum struct SomeEnum
 | 
			
		||||
DQN_HEADER_COPY_BEGIN
 | 
			
		||||
struct HelloWorld
 | 
			
		||||
{
 | 
			
		||||
    Hello,
 | 
			
		||||
    Foo
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
And then build DqnInspect by defining `DQN_INSPECT_EXECUTABLE_IMPLEMENTATION` before compiling and execute it as follows
 | 
			
		||||
 | 
			
		||||
`DqnInspect.exe SourceCode.h > SourceCodeInspected.h`
 | 
			
		||||
 | 
			
		||||
Include and use the file in code
 | 
			
		||||
    int foo, bar;
 | 
			
		||||
};
 | 
			
		||||
DQN_HEADER_COPY_END
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
#include "DqnReflect.h"
 | 
			
		||||
#include "SourceCode.h"
 | 
			
		||||
#include "SourceCodeInspected.h"
 | 
			
		||||
SomeEnum enum = SomeEnum::Hello;
 | 
			
		||||
printf("%s\n", DqnInspect_EnumString(enum)); // prints Hello
 | 
			
		||||
 | 
			
		||||
Entity entity = {};
 | 
			
		||||
DqnInspect_Struct const *inspector = DqnInspect_GetStruct(&entity);
 | 
			
		||||
for (int i = 0; i < inspector->members_len; ++i)
 | 
			
		||||
    printf("%s\n", inspector->members[i].name);
 | 
			
		||||
Which generates the following output
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
// @ ptr1: Pointer to the first block of memory
 | 
			
		||||
// @ ptr2: Pointer to the second block of memory
 | 
			
		||||
// @ num_bytes: The number of bytes to compare in both blocks of memory
 | 
			
		||||
int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes);
 | 
			
		||||
struct HelloWorld
 | 
			
		||||
{
 | 
			
		||||
    int foo, bar;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user