diff --git a/.clang-format b/.clang-format index 35cce5e..d7b3f42 100644 --- a/.clang-format +++ b/.clang-format @@ -177,7 +177,7 @@ RequiresClausePosition: OwnLine RequiresExpressionIndentation: OuterScope SeparateDefinitionBlocks: Always ShortNamespaceLines: 1 -SortIncludes: CaseSensitive +SortIncludes: Never SortJavaStaticImport: Before SortUsingDeclarations: LexicographicNumeric SpaceAfterCStyleCast: false diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d4d8817 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/test/test", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + + ] +} \ No newline at end of file diff --git a/src/include/collections/vec.hpp b/src/include/collections/vec.hpp index de4b934..e24c75d 100644 --- a/src/include/collections/vec.hpp +++ b/src/include/collections/vec.hpp @@ -3,13 +3,13 @@ #include "result.hpp" #include +#include #include -#include template class Vec { private: - T* items; + T* items = nullptr; size_t count = 0; size_t capacity = 0; @@ -24,14 +24,14 @@ public: if (this->count <= n) { return Option(); } - return Option(this->items[n]); + return Option(&this->items[n]); } Option nth(const size_t n) const { if (this->count <= n) { return Option(); } - return Option(this->items[n]); + return Option(&this->items[n]); } Option pop() { @@ -88,6 +88,17 @@ public: this->count = 0; } + T* to_ptr() { + // Special case for cstr + // makes items[count] a null value so the cstr is valid + // TODO: Maybe make Vec::to_ptr only do this when T is char + if (this->count >= this->capacity) { + this->reserve(this->capacity * 2); + } + this->items[this->count] = (T)NULL; + return this->items; + } + static Vec from_ptr(const T* ptr, size_t len) { Vec vec = Vec(); for (size_t i = 0; i < len; i++) { @@ -100,11 +111,13 @@ public: return this->count; } + // IMPL: Clone Vec clone() { Vec nv = Vec(); - nv.items = new T(*this->items); - nv.count = this->count; - nv.capacity = this->capacity; + nv = *this; + // nv.items = new T(*this->items); + // nv.count = this->count; + // nv.capacity = this->capacity; return nv; } }; diff --git a/src/include/format/base_types.hpp b/src/include/format/base_types.hpp new file mode 100644 index 0000000..0a41e59 --- /dev/null +++ b/src/include/format/base_types.hpp @@ -0,0 +1,54 @@ +#ifndef _H_LIBCP_FORMAT_BASE_TYPES +#define _H_LIBCP_FORMAT_BASE_TYPES + +#include + +extern "C" { +int snprintf(char* __restrict s, size_t maxlen, const char* __restrict format, ...); +} + +template +struct Formatter; + +template <> +struct Formatter { + static String fmt_to_str(const int& val) { + char buf[32]; + snprintf(buf, sizeof(buf), "%d", val); + return String(buf); + } +}; + +template <> +struct Formatter { + static String fmt_to_str(const char* val) { + return String(val); + } +}; + +template <> +struct Formatter { + static String fmt_to_str(char* val) { + return String(val); + } +}; + +template <> +struct Formatter { + static String fmt_to_str(const float& val) { + char buf[32]; + snprintf(buf, sizeof(buf), "%f", val); + return String(buf); + } +}; + +template <> +struct Formatter { + static String fmt_to_str(const double& val) { + char buf[32]; + snprintf(buf, sizeof(buf), "%f", val); + return String(buf); + } +}; + +#endif // !_H_LIBCP_FORMAT_BASE_TYPES diff --git a/src/include/format/fmt.hpp b/src/include/format/fmt.hpp index 16a46cf..6d7af90 100644 --- a/src/include/format/fmt.hpp +++ b/src/include/format/fmt.hpp @@ -1,12 +1,91 @@ #ifndef _H_LIBCP_FORMAT_FMT #define _H_LIBCP_FORMAT_FMT -#include +#include +#include +#include +#include #include +#include "format/base_types.hpp" + template concept Format = requires(T t) { - { t.fmt_as_str() } -> same_as; + { t.fmt_to_str() } -> stl::same_as; +} || requires(T t) { + { Formatter::fmt_to_str(t) } -> stl::same_as; }; +#ifndef __CONCEPT_ONLY + +namespace __internal { + String format(Vec& args, String& _fmt) { + const char* fmt = _fmt.as_cstr(); + String str = String(); + size_t args_idx = 0; + for (size_t i = 0; i < strlen(fmt); i++) { + if (fmt[i] == '{') { + if (fmt[i + 1] == '{') { + str.push('{'); + str.push('{'); + i += 1; + continue; + } + if (fmt[i + 1] == '}') { + i += 1; + String* arg = args.nth(args_idx).unwrap(); + str.push_str(*arg); + args_idx += 1; + } + continue; + } + str.push(fmt[i]); + } + return str; + } + + template + String format(Vec& args, String& fmt, T var1, Types... var2) { + using ActualType = stl::remove_cvref_t; + + if constexpr (requires(ActualType v) { v.fmt_to_str(); }) { + args.push(var1.fmt_to_str()); + } else { + args.push(Formatter::fmt_to_str(var1)); + } + + return __internal::format(args, fmt, var2...); + } +} // namespace __internal + +template +String format(const char* fmt, Types... vars) { + Vec args = Vec(); + String fmt_ = String(fmt); + return __internal::format(args, fmt_, vars...); +} + +template +struct Formatter> { + static String fmt_to_str(Vec& val) { + String s = String(); + s.push('['); + if (val.len() == 0) { + s.push(']'); + return s; + } + String tmp1 = format("{}", *val.nth(0).unwrap()).fmt_to_str(); + s.push_str(tmp1); + for (size_t i = 1; i < val.len(); i++) { + s.push_str(", "); + + String tmp2 = format("{}", *val.nth(i).unwrap()); + s.push_str(tmp2); + } + s.push(']'); + return s; + } +}; + +#endif // __CONCEPT_ONLY #endif // _H_LIBCP_FORMAT_FMT \ No newline at end of file diff --git a/src/include/io/print.hpp b/src/include/io/print.hpp new file mode 100644 index 0000000..fc6918a --- /dev/null +++ b/src/include/io/print.hpp @@ -0,0 +1,23 @@ +#ifndef _H_LIBCP_IO_PRINT +#define _H_LIBCP_IO_PRINT + +#include + +extern "C" { +int puts(const char* s); +int putchar(int c); +} + +template +void print(const char* fmt, Types... args) { + String s = format(fmt, args...); + puts(s.as_cstr()); +} + +template +void println(const char* fmt, Types... args) { + print(fmt, args...); + putchar('\n'); +} + +#endif // !_H_LIBCP_IO_PRINT diff --git a/src/include/std.hpp b/src/include/std.hpp index 4342a2c..66accf4 100644 --- a/src/include/std.hpp +++ b/src/include/std.hpp @@ -2,9 +2,12 @@ #ifndef _H_LIBCP #define _H_LIBCP -namespace std { -#include +#include + +#include +#include +#include #include -} // namespace std +#include #endif // _H_LIBCP \ No newline at end of file diff --git a/src/include/stddef.hpp.old b/src/include/stddef.hpp.old deleted file mode 100644 index 4130a03..0000000 --- a/src/include/stddef.hpp.old +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _H_LIBCP_STDDEF -#define _H_LIBCP_STDDEF - - -#if defined(__x86_64__) || defined(_M_X64) - using size_t = unsigned long; - using ptrdiff_t = long; - using intptr_t = long; - using uintptr_t = unsigned long; -#elif defined(__i386__) || defined(_M_IX86) - using size_t = unsigned int; - using ptrdiff_t = int; - using intptr_t = int; - using uintptr_t = unsigned int; -#else - #error "Unsupported architecture for my_std types nya~" -#endif - -// Exact-width types — assuming standard model (you can static_assert later!) -using int8_t = signed char; -using int16_t = short; -using int32_t = int; -using int64_t = long long; - -using uint8_t = unsigned char; -using uint16_t = unsigned short; -using uint32_t = unsigned int; -using uint64_t = unsigned long long; - -#endif // _H_LIBCP_STDDEF diff --git a/src/include/stl.hpp b/src/include/stl.hpp index 11e9290..de62858 100644 --- a/src/include/stl.hpp +++ b/src/include/stl.hpp @@ -7,6 +7,7 @@ namespace stl { #include #include #include +#include #include } // namespace stl diff --git a/src/include/stl/remove_cvref.hpp b/src/include/stl/remove_cvref.hpp new file mode 100644 index 0000000..3441240 --- /dev/null +++ b/src/include/stl/remove_cvref.hpp @@ -0,0 +1,28 @@ +#ifndef _H_LIBCP_STL_REMOVE_CVREF +#define _H_LIBCP_STL_REMOVE_CVREF + +#include + +// For gcc +// template +// struct __remove_cvref_gcc { +// using type = __remove_cvref(_Tp); +// }; +// template +// using __remove_cvref_t _LIBCPP_NODEBUG = typename __remove_cvref_gcc<_Tp>::type; + +template +using __remove_cvref_t = __remove_cvref(_Tp); + +template +using __is_same_uncvref = is_same<__remove_cvref_t<_Tp>, __remove_cvref_t<_Up>>; + +template +struct remove_cvref { + using type = __remove_cvref(_Tp); +}; + +template +using remove_cvref_t = __remove_cvref_t<_Tp>; + +#endif // _H_LIBCP_STL_REMOVE_CVREF diff --git a/src/include/string.hpp b/src/include/string.hpp index e50be04..703f250 100644 --- a/src/include/string.hpp +++ b/src/include/string.hpp @@ -14,6 +14,11 @@ public: size_t len(); void clear(); Vec& chars(); + char* const as_cstr(); + void push(char c); + void push_str(String& str); + // void push_str(String&& str); + void push_str(const char* str); // IMPL: Format String fmt_to_str(); // IMPL: Clone diff --git a/src/lib.cpp b/src/lib.cpp deleted file mode 100644 index 8b13789..0000000 --- a/src/lib.cpp +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/string.cpp b/src/string.cpp index 328598b..2797580 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -2,7 +2,7 @@ #include String::String(const char* str) { - this->_chars.from_ptr((char*)str, strlen(str)); + this->_chars = Vec::from_ptr((char*)str, strlen(str)); } size_t String::len() { @@ -21,6 +21,30 @@ String String::fmt_to_str() { return this->clone(); } +char* const String::as_cstr() { + return this->_chars.to_ptr(); +} + +void String::push(char c) { + this->_chars.push(c); +} + +void String::push_str(String& str) { + Vec chrs = str.chars(); + + for (size_t i = 0; i < chrs.len(); i++) { + // SAFETY: Always Valid + this->push(*chrs.nth(i).unwrap()); + } +} + +void String::push_str(const char* str) { + for (size_t i = 0; i < strlen(str); i++) { + this->push(str[i]); + } +} + +// IMPL: Clone String String::clone() { String s = String(); s._chars = this->_chars.clone(); diff --git a/test/test b/test/test index 5cacb8b..3c121e4 100755 Binary files a/test/test and b/test/test differ diff --git a/test/test.cpp b/test/test.cpp index 30e5956..2339b49 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,13 +1,11 @@ -#include -#include -#include +#include int main(int argc, char* argv[]) { - Vec* v = new Vec(); - v->push(69); - v->push(420); - size_t ft = v->pop().unwrap(); - size_t sn = v->pop().unwrap(); - printf("ft: %zu sn: %zu\n", ft, sn); + Vec v = Vec(); + v.push(1); + v.push(2); + v.push(3); + v.push(4); + println("Hello!!!! {}, {}, {}, {}", "meow", 420.0, 49, v); return 0; } \ No newline at end of file