i dont even know anymore
This commit is contained in:
parent
4e3de1cfb2
commit
67e704edab
19
Makefile
19
Makefile
|
@ -3,14 +3,20 @@ LIB=libcx
|
|||
BUILD_DIR?=build
|
||||
|
||||
COM_FLAGS = -fPIC -Isrc/include
|
||||
CC_FLAGS = -std=c23 -ggdb
|
||||
CXX_FLAGS = -std=c++23 -nostdinc++ -ggdb -fexceptions
|
||||
LD_FLAGS = -nostdlib++ -lsupc++ -ggdb -fexceptions
|
||||
CC_FLAGS = -std=c23
|
||||
CXX_FLAGS = -std=c++23 -nostdinc++
|
||||
LD_FLAGS = -nostdlib++ -lsupc++
|
||||
CC=clang
|
||||
CXX=clang
|
||||
LD=clang
|
||||
AR=ar
|
||||
|
||||
ifeq ($(DEBUG),true)
|
||||
CXX_FLAGS += -DDEBUG -ggdb
|
||||
CC_FLAGS += -DDEBUG -ggdb
|
||||
LD_FLAGS += -ggdb
|
||||
endif
|
||||
|
||||
cxx_sources=$(wildcard src/*.cpp)
|
||||
c_sources=$(wildcard src/*.c)
|
||||
objects=$(patsubst src/%.cpp,$(BUILD_DIR)/obj/%.cpp.o,$(cxx_sources)) $(patsubst src/%.c,$(BUILD_DIR)/obj/%.c.o,$(c_sources))
|
||||
|
@ -21,6 +27,13 @@ all: shared static compile_commands.json
|
|||
shared: $(BUILD_DIR)/$(LIB).so
|
||||
static: $(BUILD_DIR)/$(LIB).a
|
||||
|
||||
install: shared static
|
||||
cp -r src/include/cx /usr/local/include/
|
||||
cp $(BUILD_DIR)/libcx.a /usr/lib/
|
||||
cp $(BUILD_DIR)/libcx.so /usr/lib/
|
||||
ldconfig # updates linker cache
|
||||
cp libcx.pc /usr/lib/pkgconfig/
|
||||
|
||||
$(BUILD_DIR)/$(LIB).a: $(objects)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
|
|
10
libcx.pc
Normal file
10
libcx.pc
Normal file
|
@ -0,0 +1,10 @@
|
|||
prefix=/usr/local
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: cx
|
||||
Description: libcxx alternative
|
||||
Version: 1.0.0
|
||||
Libs: -L${libdir} -lcx
|
||||
Cflags: -I${includedir}/cx
|
63
src/include/cx/collections/buffer.hpp
Normal file
63
src/include/cx/collections/buffer.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#ifndef _H_CX_COLLECTIONS_BUFFER
|
||||
#define _H_CX_COLLECTIONS_BUFFER
|
||||
|
||||
#include <cx/libc.hpp>
|
||||
#include <cx/stddef.hpp>
|
||||
#include <cx/stl.hpp>
|
||||
|
||||
template <typename T>
|
||||
concept Buffer = requires(T t, uint8_t byte, uint8_t const* byte_ptr, size_t byte_count) {
|
||||
{ t.buf_get_raw_ptr() } -> stl::same_as<uint8_t const*>;
|
||||
{ t.buf_get_raw_mut_ptr() } -> stl::same_as<uint8_t*>;
|
||||
{ t.buf_get_size() } -> stl::same_as<size_t>;
|
||||
{ t.buf_push_byte(byte) } -> stl::same_as<void>;
|
||||
{ t.buf_append_bytes(byte_ptr, byte_count) } -> stl::same_as<void>;
|
||||
};
|
||||
|
||||
class BufferContainer {
|
||||
private:
|
||||
uint8_t* inner;
|
||||
size_t len;
|
||||
size_t size;
|
||||
|
||||
public:
|
||||
BufferContainer() {
|
||||
this->inner = (uint8_t*)libc::malloc(1024);
|
||||
this->size = 1024;
|
||||
}
|
||||
|
||||
~BufferContainer() {
|
||||
libc::free(this->inner);
|
||||
}
|
||||
|
||||
void resize(size_t bytes) {
|
||||
this->inner = (uint8_t*)libc::realloc(this->inner, bytes);
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
uint8_t const* buf_get_raw_ptr() {
|
||||
return (uint8_t const*)this->inner;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
size_t buf_get_size() {
|
||||
return this->size;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
void buf_push_byte(uint8_t byte) {
|
||||
if (this->size <= this->len) {
|
||||
this->resize(this->size * 2);
|
||||
}
|
||||
this->inner[this->len++] = byte;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
void buf_append_bytes(uint8_t const* byte_ptr, size_t byte_count) {
|
||||
for (size_t i = 0; i < byte_count; i++) {
|
||||
this->buf_push_byte(byte_ptr[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !_H_CX_COLLECTIONS_BUFFER
|
|
@ -120,6 +120,28 @@ public:
|
|||
// nv.capacity = this->capacity;
|
||||
return nv;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
uint8_t const* buf_get_raw_ptr() {
|
||||
return (uint8_t const*)this->items;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
size_t buf_get_size() {
|
||||
return this->count;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
void buf_push_byte(uint8_t byte) {
|
||||
this->push(byte);
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
void buf_append_bytes(uint8_t const* byte_ptr, size_t byte_count) {
|
||||
for (size_t i = 0; i < byte_count; i++) {
|
||||
this->buf_push_byte(byte_ptr[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _H_LIBCX_COLLECTIONS_VEC
|
|
@ -2,10 +2,7 @@
|
|||
#define _H_LIBCX_FORMAT_BASE_TYPES
|
||||
|
||||
#include <cx/string.hpp>
|
||||
|
||||
extern "C" {
|
||||
int snprintf(char* __restrict s, size_t maxlen, const char* __restrict format, ...);
|
||||
}
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
template <typename T>
|
||||
struct Formatter;
|
||||
|
@ -14,7 +11,7 @@ template <>
|
|||
struct Formatter<int> {
|
||||
static String fmt_to_str(const int& val) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%d", val);
|
||||
libc::snprintf(buf, sizeof(buf), "%d", val);
|
||||
return String(buf);
|
||||
}
|
||||
};
|
||||
|
@ -37,7 +34,7 @@ template <>
|
|||
struct Formatter<float> {
|
||||
static String fmt_to_str(const float& val) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%f", val);
|
||||
libc::snprintf(buf, sizeof(buf), "%f", val);
|
||||
return String(buf);
|
||||
}
|
||||
};
|
||||
|
@ -46,7 +43,7 @@ template <>
|
|||
struct Formatter<double> {
|
||||
static String fmt_to_str(const double& val) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%f", val);
|
||||
libc::snprintf(buf, sizeof(buf), "%f", val);
|
||||
return String(buf);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,25 +1,21 @@
|
|||
#ifndef _H_LIBCX_IO_PRINT
|
||||
#define _H_LIBCX_IO_PRINT
|
||||
|
||||
#include <cx/io/stdout.hpp>
|
||||
#include <cx/string.hpp>
|
||||
#include <cx/stl.hpp>
|
||||
#include <cx/format/fmt.hpp>
|
||||
|
||||
extern "C" {
|
||||
int putchar(int c);
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
void print(const char* fmt, Types... args) {
|
||||
String s = format(fmt, args...);
|
||||
char* cs = s.as_cstr();
|
||||
for (int i = 0; i < s.len(); i++) {
|
||||
putchar(cs[i]);
|
||||
}
|
||||
Stdout<String>::write(stl::move(s));
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
void println(const char* fmt, Types... args) {
|
||||
print(fmt, args...);
|
||||
putchar('\n');
|
||||
Stdout<String>::write(String("\n"));
|
||||
}
|
||||
|
||||
#endif // !_H_LIBCX_IO_PRINT
|
7
src/include/cx/io/read.hpp
Normal file
7
src/include/cx/io/read.hpp
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _H_LIBCX_IO_PRINT
|
||||
#define _H_LIBCX_IO_PRINT
|
||||
|
||||
#include <cx/format/fmt.hpp>
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
#endif // !_H_LIBCX_IO_PRINT
|
11
src/include/cx/io/shell.hpp
Normal file
11
src/include/cx/io/shell.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _H_CX_IO_SHELL
|
||||
#define _H_CX_IO_SHELL
|
||||
|
||||
#include <cx/std.hpp>
|
||||
|
||||
namespace shell {
|
||||
void clear();
|
||||
void move_cursor(size_t row, size_t col);
|
||||
} // namespace shell
|
||||
|
||||
#endif // !_H_CX_IO_SHELL
|
25
src/include/cx/io/stderr.hpp
Normal file
25
src/include/cx/io/stderr.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _H_LIBCX_IO_STDERR
|
||||
#define _H_LIBCX_IO_STDERR
|
||||
|
||||
#include "cx/result.hpp"
|
||||
#include <cx/collections/buffer.hpp>
|
||||
#include <cx/std.hpp>
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
template <Buffer T>
|
||||
class Stderr {
|
||||
static Result<size_t> write(T& buf) {
|
||||
int res = libc::write(stderr, buf.buf_get_raw_ptr(), buf.buf_get_size());
|
||||
if (res < 0) {
|
||||
return Result<size_t>::err("Failed to write to stderr");
|
||||
}
|
||||
return Result<size_t>::ok(res);
|
||||
}
|
||||
|
||||
static Result<void> flush(T& buf) {
|
||||
libc::fflush((FILE*)stderr);
|
||||
return Result<void>::ok();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
50
src/include/cx/io/stdin.hpp
Normal file
50
src/include/cx/io/stdin.hpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#ifndef _H_LIBCX_IO_STDIN
|
||||
#define _H_LIBCX_IO_STDIN
|
||||
|
||||
#include "cx/result.hpp"
|
||||
#include <cx/collections/buffer.hpp>
|
||||
#include <cx/std.hpp>
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
template <Buffer T>
|
||||
class Stdin {
|
||||
// This will clear the buffer
|
||||
Result<void, const char*> read_fill_buf(T&& buf) {
|
||||
read(stdin, buf.buf_get_raw_mut_ptr(), buf.buf_get_size()());
|
||||
return Result<void, const char*>::ok();
|
||||
}
|
||||
|
||||
Result<void, const char*> read_till_eof(T&& buf) {
|
||||
const int buf_size = 1024;
|
||||
char* int_buf = (char*)libc::malloc(buf_size + 1);
|
||||
while (libc::fgets(int_buf, buf_size, stdin) != NULL) {
|
||||
if (libc::feof(stdin) != 0) {
|
||||
for (int i = 0; i < strlen(int_buf); i++) {
|
||||
buf.buf_push_byte(int_buf[i]);
|
||||
}
|
||||
return Result<void, const char*>::ok();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < strlen(int_buf); i++) {
|
||||
buf.buf_push_byte(int_buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Result<void, const char*> read_line(T&& buf) {
|
||||
const int buf_size = 1024;
|
||||
char* int_buf = (char*)libc::malloc(buf_size + 1);
|
||||
while (libc::fgets(int_buf, buf_size, stdin) != NULL) {
|
||||
if (int_buf[strlen(int_buf) - 1] == '\n') {
|
||||
for (int i = 0; i < strlen(int_buf); i++) {
|
||||
buf.buf_push_byte(int_buf[i]);
|
||||
}
|
||||
return Result<void, const char*>::ok();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < strlen(int_buf); i++) {
|
||||
buf.buf_push_byte(int_buf[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !_H_LIBCX_IO_STDIN
|
25
src/include/cx/io/stdout.hpp
Normal file
25
src/include/cx/io/stdout.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef _H_LIBCX_IO_STDOUT
|
||||
#define _H_LIBCX_IO_STDOUT
|
||||
|
||||
#include "cx/result.hpp"
|
||||
#include <cx/collections/buffer.hpp>
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
template <Buffer T>
|
||||
class Stdout {
|
||||
public:
|
||||
static Result<size_t> write(T&& buf) {
|
||||
int res = libc::write(stdout, buf.buf_get_raw_ptr(), buf.buf_get_size());
|
||||
if (res < 0) {
|
||||
return Result<size_t>::err("Failed to write to stdout");
|
||||
}
|
||||
return Result<size_t>::ok(res);
|
||||
}
|
||||
|
||||
static Result<void> flush(T&& buf) {
|
||||
libc::fflush((FILE*)stdout);
|
||||
return Result<void>::ok();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
29
src/include/cx/libc.hpp
Normal file
29
src/include/cx/libc.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef _H_CX_LIBC
|
||||
#define _H_CX_LIBC
|
||||
#include <cx/stddef.hpp>
|
||||
|
||||
typedef void FILE;
|
||||
|
||||
#define stdin 0
|
||||
#define stdout 1
|
||||
#define stderr 2
|
||||
|
||||
namespace libc {
|
||||
extern "C" {
|
||||
void* malloc(size_t size);
|
||||
void* realloc(void* ptr, size_t size);
|
||||
void free(void* ptr);
|
||||
int snprintf(char* __restrict s, size_t maxlen, const char* __restrict format, ...);
|
||||
int putchar(int c);
|
||||
int puts(const char* s);
|
||||
char* getenv(const char* name);
|
||||
ssize_t write(int fd, const void* buf, size_t n);
|
||||
ssize_t read(int fd, void* buf, size_t nbytes);
|
||||
// returns buf on success, and NULL on error or when end of file occurs while no characters have been read.
|
||||
char* fgets(char* buf, int size, FILE* stream);
|
||||
int feof(FILE* stream);
|
||||
int fflush(FILE* stream);
|
||||
}
|
||||
} // namespace libc
|
||||
|
||||
#endif // _H_CX_LIBC
|
|
@ -2,10 +2,7 @@
|
|||
#ifndef _H_LIBCX_OPTION
|
||||
#define _H_LIBCX_OPTION
|
||||
#include <cx/stl.hpp>
|
||||
|
||||
extern "C" {
|
||||
int puts(const char* s);
|
||||
}
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
template <typename T>
|
||||
class Option {
|
||||
|
@ -41,9 +38,9 @@ public:
|
|||
|
||||
T& expect(const char* str) {
|
||||
if (!has_value) {
|
||||
puts("PANIC: Unwrapped a None Option: ");
|
||||
puts(str);
|
||||
puts("\n");
|
||||
libc::puts("PANIC: Unwrapped a None Option: ");
|
||||
libc::puts(str);
|
||||
libc::puts("\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return this->storage;
|
||||
|
@ -51,7 +48,7 @@ public:
|
|||
|
||||
T& unwrap() {
|
||||
if (!has_value) {
|
||||
puts("PANIC: Unwrapped a None Option\n");
|
||||
libc::puts("PANIC: Unwrapped a None Option\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return this->storage;
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
#define _H_LIBCX_RESULT
|
||||
|
||||
#include <cx/stl.hpp>
|
||||
#include <cx/libc.hpp>
|
||||
|
||||
extern "C" {
|
||||
int puts(const char* s);
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
template <typename E = const char*>
|
||||
struct ResultErrBase {
|
||||
bool is_okay = true;
|
||||
E err_data;
|
||||
|
@ -44,7 +41,7 @@ struct ResultErrBase {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, typename E>
|
||||
template <typename T, typename E = const char*>
|
||||
class Result : private ResultErrBase<E> {
|
||||
T ok_data;
|
||||
|
||||
|
@ -86,9 +83,9 @@ public:
|
|||
|
||||
T& expect(const char* str) {
|
||||
if (!this->is_ok()) {
|
||||
puts("PANIC: Unwrapped result with error: ");
|
||||
puts(str);
|
||||
puts("\n");
|
||||
libc::puts("PANIC: Unwrapped result with error: ");
|
||||
libc::puts(str);
|
||||
libc::puts("\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return &this->ok_data;
|
||||
|
@ -96,7 +93,7 @@ public:
|
|||
|
||||
T& unwrap() {
|
||||
if (!this->is_ok()) {
|
||||
puts("PANIC: Unwrapped result with error\n");
|
||||
libc::puts("PANIC: Unwrapped result with error\n");
|
||||
__builtin_trap();
|
||||
}
|
||||
return &this->ok_data;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _H_LIBCX_STDDEF
|
||||
|
||||
#include <cx/stl.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
using size_t = decltype(sizeof(int));
|
||||
using ssize_t = stl::make_signed_t<size_t>;
|
||||
using ptrdiff_t = decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));
|
||||
using nullptr_t = decltype(nullptr);
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@ namespace stl {
|
|||
#include <cx/stl/void_t.hpp>
|
||||
#include <cx/stl/is_referenceable.hpp>
|
||||
#include <cx/stl/is_integral.hpp>
|
||||
#include <cx/stl/conditional.hpp>
|
||||
#include <cx/stl/is_unsigned.hpp>
|
||||
#include <cx/stl/make_unsigned.hpp>
|
||||
#include <cx/stl/make_signed.hpp>
|
||||
} // namespace stl
|
||||
|
||||
#endif // _H_LIBCX_STL
|
45
src/include/cx/stl/conditional.hpp
Normal file
45
src/include/cx/stl/conditional.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef _H_CX_STL_CONDITIONAL
|
||||
#define _H_CX_STL_CONDITIONAL
|
||||
|
||||
template <bool>
|
||||
struct _IfImpl;
|
||||
|
||||
template <>
|
||||
struct _IfImpl<true> {
|
||||
template <class _IfRes, class _ElseRes>
|
||||
using _Select = _IfRes;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct _IfImpl<false> {
|
||||
template <class _IfRes, class _ElseRes>
|
||||
using _Select = _ElseRes;
|
||||
};
|
||||
|
||||
template <bool _Cond, class _IfRes, class _ElseRes>
|
||||
using _If = typename _IfImpl<_Cond>::template _Select<_IfRes, _ElseRes>;
|
||||
|
||||
template <bool _Bp, class _If, class _Then>
|
||||
struct conditional {
|
||||
using type = _If;
|
||||
};
|
||||
|
||||
// _Pragma("clang diagnostic push")
|
||||
// #if __has_warning("-Winvalid-specialization")
|
||||
// _Pragma("clang diagnostic ignored -Winvalid-specialization")
|
||||
// #endif
|
||||
template <class _If, class _Then>
|
||||
struct conditional<false, _If, _Then> {
|
||||
using type = _Then;
|
||||
};
|
||||
|
||||
// _Pragma("clang diagnostic pop")
|
||||
|
||||
template <bool _Bp, class _IfRes, class _ElseRes>
|
||||
using conditional_t = typename conditional<_Bp, _IfRes, _ElseRes>::type;
|
||||
|
||||
// Helper so we can use "conditional_t" in all language versions.
|
||||
template <bool _Bp, class _If, class _Then>
|
||||
using __conditional_t = typename conditional<_Bp, _If, _Then>::type;
|
||||
|
||||
#endif // !_H_CX_STL_CONDITIONAL
|
29
src/include/cx/stl/is_unsigned.hpp
Normal file
29
src/include/cx/stl/is_unsigned.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef _H_CX_STL_IS_UNSIGNED
|
||||
#define _H_CX_STL_IS_UNSIGNED
|
||||
#if __has_builtin(__is_unsigned)
|
||||
|
||||
#include <cx/stl/integral_constant.hpp>
|
||||
#include <cx/stl/is_integral.hpp>
|
||||
|
||||
template <class _Tp>
|
||||
struct is_unsigned : _BoolConstant<__is_unsigned(_Tp)> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_unsigned_v = __is_unsigned(_Tp);
|
||||
|
||||
#else // __has_builtin(__is_unsigned)
|
||||
|
||||
template <class _Tp, bool = is_integral<_Tp>::value>
|
||||
inline constexpr bool __is_unsigned_v = false;
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_unsigned_v<_Tp, true> = _Tp(0) < _Tp(-1);
|
||||
|
||||
template <class _Tp>
|
||||
struct is_unsigned : integral_constant<bool, __is_unsigned_v<_Tp>> {};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool is_unsigned_v = __is_unsigned_v<_Tp>;
|
||||
|
||||
#endif // __has_builtin(__is_unsigned)
|
||||
#endif // !_H_CX_STL_IS_UNSIGNED
|
52
src/include/cx/stl/make_signed.hpp
Normal file
52
src/include/cx/stl/make_signed.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef _H_LIBCX_STL_MAKE_SIGNED
|
||||
#define _H_LIBCX_STL_MAKE_SIGNED
|
||||
#if __has_builtin(__make_signed)
|
||||
|
||||
template <class _Tp>
|
||||
using __make_signed_t = __make_signed(_Tp);
|
||||
|
||||
#else
|
||||
using __signed_types = __type_list<signed char, signed short, signed int, signed long, signed long long
|
||||
#if _CX_HAS_INT128
|
||||
,
|
||||
__int128_t
|
||||
#endif
|
||||
>;
|
||||
|
||||
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
|
||||
struct __make_signed{};
|
||||
|
||||
template <class _Tp>
|
||||
struct __make_signed<_Tp, true> {
|
||||
typedef typename __find_first<__signed_types, sizeof(_Tp)>::type type;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
template <> struct __make_signed<bool, true> {};
|
||||
template <> struct __make_signed< signed short, true> {typedef short type;};
|
||||
template <> struct __make_signed<unsigned short, true> {typedef short type;};
|
||||
template <> struct __make_signed< signed int, true> {typedef int type;};
|
||||
template <> struct __make_signed<unsigned int, true> {typedef int type;};
|
||||
template <> struct __make_signed< signed long, true> {typedef long type;};
|
||||
template <> struct __make_signed<unsigned long, true> {typedef long type;};
|
||||
template <> struct __make_signed< signed long long, true> {typedef long long type;};
|
||||
template <> struct __make_signed<unsigned long long, true> {typedef long long type;};
|
||||
# if _CX_HAS_INT128
|
||||
template <> struct __make_signed<__int128_t, true> {typedef __int128_t type;};
|
||||
template <> struct __make_signed<__uint128_t, true> {typedef __int128_t type;};
|
||||
# endif
|
||||
// clang-format on
|
||||
|
||||
template <class _Tp>
|
||||
using __make_signed_t = __copy_cv_t<_Tp, typename __make_signed<__remove_cv_t<_Tp>>::type>;
|
||||
|
||||
#endif // __has_builtin(__make_signed)
|
||||
|
||||
template <class _Tp>
|
||||
struct make_signed {
|
||||
using type = __make_signed_t<_Tp>;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using make_signed_t = __make_signed_t<_Tp>;
|
||||
#endif // _H_LIBCX_STL_MAKE_SIGNED
|
63
src/include/cx/stl/make_unsigned.hpp
Normal file
63
src/include/cx/stl/make_unsigned.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#ifndef _H_LIBCX_STL_MAKE_UNSIGNED
|
||||
#define _H_LIBCX_STL_MAKE_UNSIGNED
|
||||
|
||||
#include <cx/stl/is_unsigned.hpp>
|
||||
#include <cx/stl/conditional.hpp>
|
||||
#if __has_builtin(__make_unsigned)
|
||||
|
||||
template <class _Tp>
|
||||
using __make_unsigned_t = __make_unsigned(_Tp);
|
||||
|
||||
#else
|
||||
using __unsigned_types = __type_list<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long
|
||||
#if _CX_HAS_INT128
|
||||
,
|
||||
__uint128_t
|
||||
#endif
|
||||
>;
|
||||
|
||||
template <class _Tp, bool = is_integral<_Tp>::value || is_enum<_Tp>::value>
|
||||
struct __make_unsigned{};
|
||||
|
||||
template <class _Tp>
|
||||
struct __make_unsigned<_Tp, true> {
|
||||
typedef typename __find_first<__unsigned_types, sizeof(_Tp)>::type type;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
template <> struct __make_unsigned<bool, true> {};
|
||||
template <> struct __make_unsigned< signed short, true> {typedef unsigned short type;};
|
||||
template <> struct __make_unsigned<unsigned short, true> {typedef unsigned short type;};
|
||||
template <> struct __make_unsigned< signed int, true> {typedef unsigned int type;};
|
||||
template <> struct __make_unsigned<unsigned int, true> {typedef unsigned int type;};
|
||||
template <> struct __make_unsigned< signed long, true> {typedef unsigned long type;};
|
||||
template <> struct __make_unsigned<unsigned long, true> {typedef unsigned long type;};
|
||||
template <> struct __make_unsigned< signed long long, true> {typedef unsigned long long type;};
|
||||
template <> struct __make_unsigned<unsigned long long, true> {typedef unsigned long long type;};
|
||||
# if _CX_HAS_INT128
|
||||
template <> struct __make_unsigned<__int128_t, true> {typedef __uint128_t type;};
|
||||
template <> struct __make_unsigned<__uint128_t, true> {typedef __uint128_t type;};
|
||||
# endif
|
||||
// clang-format on
|
||||
|
||||
template <class _Tp>
|
||||
using __make_unsigned_t = __copy_cv_t<_Tp, typename __make_unsigned<__remove_cv_t<_Tp>>::type>;
|
||||
|
||||
#endif // __has_builtin(__make_unsigned)
|
||||
|
||||
template <class _Tp>
|
||||
struct make_unsigned {
|
||||
using type = __make_unsigned_t<_Tp>;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using make_unsigned_t = __make_unsigned_t<_Tp>;
|
||||
|
||||
template <class _Tp>
|
||||
__make_unsigned_t<_Tp> __to_unsigned_like(_Tp __x) {
|
||||
return static_cast<__make_unsigned_t<_Tp>>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
using __copy_unsigned_t = __conditional_t<is_unsigned<_Tp>::value, __make_unsigned_t<_Up>, _Up>;
|
||||
#endif // _H_LIBCX_STL_MAKE_UNSIGNED
|
|
@ -23,6 +23,16 @@ public:
|
|||
String fmt_to_str();
|
||||
// IMPL: Clone
|
||||
String clone();
|
||||
// IMPL: Buffer
|
||||
uint8_t const* buf_get_raw_ptr();
|
||||
// IMPL: Buffer
|
||||
uint8_t* buf_get_raw_mut_ptr();
|
||||
// IMPL: Buffer
|
||||
size_t buf_get_size();
|
||||
// IMPL: Buffer
|
||||
void buf_push_byte(uint8_t byte);
|
||||
// IMPL: Buffer
|
||||
void buf_append_bytes(uint8_t const* byte_ptr, size_t byte_count);
|
||||
};
|
||||
|
||||
#endif // _H_LIBCX_STRING
|
|
@ -1,9 +1,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <cx/std.hpp>
|
||||
|
||||
// #include <cx/std.hpp>
|
||||
|
||||
namespace std {
|
||||
void __glibcxx_assert_fail(char const* file, int line, char const* func, char const* info) {
|
||||
println("{}:{}:{}: {}", file, line, func, info);
|
||||
// println("{}:{}:{}: {}", file, line, func, info);
|
||||
}
|
||||
|
||||
void terminate() {
|
||||
|
|
12
src/io/shell.cpp
Normal file
12
src/io/shell.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <cx/io/shell.hpp>
|
||||
#include <cx/std.hpp>
|
||||
|
||||
namespace shell {
|
||||
void clear() {
|
||||
println("\e[1;1H\e[2J"); // unix only AFAIK
|
||||
}
|
||||
|
||||
void move_cursor(size_t row, size_t col) {
|
||||
println("\e[{};{}H", row, col);
|
||||
}
|
||||
} // namespace shell
|
|
@ -1,7 +1,7 @@
|
|||
#include <cx/io/print.hpp>
|
||||
#include <string.h>
|
||||
#include <cx/logger.hpp>
|
||||
|
||||
#include <cx/libc.hpp>
|
||||
using namespace log;
|
||||
|
||||
#define C_RS "\x1b[0m"
|
||||
|
@ -19,10 +19,8 @@ using namespace log;
|
|||
#define C_UL "\x1b[4m"
|
||||
#define C_BLINK "\x1b[5m"
|
||||
|
||||
extern "C" char* getenv(const char* name);
|
||||
|
||||
Logger::Logger() {
|
||||
char* val = getenv("CPLUS_LOG");
|
||||
char* val = libc::getenv("CPLUS_LOG");
|
||||
if (val != NULL) {
|
||||
if (strcmp(val, "OFF") == 0) {
|
||||
this->set_log_level(LOG_OFF);
|
||||
|
@ -37,7 +35,7 @@ Logger::Logger() {
|
|||
}
|
||||
}
|
||||
|
||||
val = getenv("CPLUS_LOG_COLOR");
|
||||
val = libc::getenv("CPLUS_LOG_COLOR");
|
||||
// clang-format off
|
||||
if (val != NULL) {
|
||||
if (
|
||||
|
|
|
@ -50,3 +50,28 @@ String String::clone() {
|
|||
s._chars = this->_chars.clone();
|
||||
return s;
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
uint8_t const* String::buf_get_raw_ptr() {
|
||||
return (uint8_t const*)this->_chars.to_ptr();
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
uint8_t* String::buf_get_raw_mut_ptr() {
|
||||
return (uint8_t*)this->_chars.to_ptr();
|
||||
}
|
||||
|
||||
// IMPL: Buffer
|
||||
size_t String::buf_get_size() {
|
||||
return this->len();
|
||||
}
|
||||
|
||||
void String::buf_push_byte(uint8_t byte) {
|
||||
this->push((char)byte);
|
||||
}
|
||||
|
||||
void String::buf_append_bytes(uint8_t const* byte_ptr, size_t byte_count) {
|
||||
for (size_t i = 0; i < byte_count; i++) {
|
||||
this->buf_push_byte(byte_ptr[i]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user