diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-11-19 00:08:33 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-12-20 15:35:58 +0100 |
commit | d241eaf1b209dcfb05656842dd6250067b704d99 (patch) | |
tree | 49f34f6226f4614611d16ba6332b1b50b51a4712 /asl | |
parent | 58200ce939a591008a8d9406f437252ce2b175cf (diff) |
Add allocator, start work on box
Diffstat (limited to 'asl')
-rw-r--r-- | asl/BUILD.bazel | 4 | ||||
-rw-r--r-- | asl/allocator.cpp | 38 | ||||
-rw-r--r-- | asl/allocator.hpp | 28 | ||||
-rw-r--r-- | asl/box.hpp | 19 | ||||
-rw-r--r-- | asl/format.cpp | 28 | ||||
-rw-r--r-- | asl/format.hpp | 44 | ||||
-rw-r--r-- | asl/io.hpp | 8 | ||||
-rw-r--r-- | asl/layout.hpp | 6 | ||||
-rw-r--r-- | asl/memory.hpp | 5 | ||||
-rw-r--r-- | asl/meta.hpp | 6 | ||||
-rw-r--r-- | asl/print.cpp | 6 | ||||
-rw-r--r-- | asl/print.hpp | 4 | ||||
-rw-r--r-- | asl/tests/box_tests.cpp | 6 | ||||
-rw-r--r-- | asl/tests/format_tests.cpp | 23 | ||||
-rw-r--r-- | asl/tests/meta_tests.cpp | 1 | ||||
-rw-r--r-- | asl/utility.hpp | 6 |
16 files changed, 172 insertions, 60 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index 0841a86..20a1651 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -1,8 +1,10 @@ cc_library(
name = "asl",
hdrs = [
+ "allocator.hpp",
"annotations.hpp",
"assert.hpp",
+ "box.hpp",
"config.hpp",
"format.hpp",
"functional.hpp",
@@ -19,6 +21,7 @@ cc_library( "utility.hpp",
],
srcs = [
+ "allocator.cpp",
"format.cpp",
"print.cpp",
],
@@ -36,6 +39,7 @@ cc_library( "//asl/testing",
],
) for name in [
+ "box",
"format",
"functional",
"integers",
diff --git a/asl/allocator.cpp b/asl/allocator.cpp new file mode 100644 index 0000000..9559637 --- /dev/null +++ b/asl/allocator.cpp @@ -0,0 +1,38 @@ +#include "asl/allocator.hpp"
+#include "asl/assert.hpp"
+#include "asl/utility.hpp"
+#include "asl/memory.hpp"
+
+#include <cstdlib>
+
+// @Todo zalloc
+// @Todo Cookies
+// @Todo Debug values
+
+void* asl::GlobalHeap::alloc(const layout& layout)
+{
+ void* ptr = ::_aligned_malloc(
+ static_cast<size_t>(layout.size),
+ static_cast<size_t>(layout.align));
+ ASL_ASSERT(ptr != nullptr); // @Todo panic
+ return ptr;
+}
+
+void* asl::GlobalHeap::realloc(void* old_ptr, const layout& old_layout, const layout& new_layout)
+{
+ if (new_layout.align <= old_layout.align)
+ {
+ void* new_ptr = ::realloc(old_ptr, static_cast<size_t>(new_layout.size));
+ ASL_ASSERT(new_ptr != nullptr); // @Todo panic
+ return new_ptr;
+ }
+
+ void* new_ptr = alloc(new_layout);
+ asl::memcpy(new_ptr, old_ptr, asl::min(old_layout.size, new_layout.size));
+ return new_ptr;
+}
+
+void asl::GlobalHeap::dealloc(void* ptr, const layout&)
+{
+ ::free(ptr);
+}
diff --git a/asl/allocator.hpp b/asl/allocator.hpp new file mode 100644 index 0000000..b6c1a9a --- /dev/null +++ b/asl/allocator.hpp @@ -0,0 +1,28 @@ +#pragma once
+
+#include "asl/layout.hpp"
+#include "asl/meta.hpp"
+
+namespace asl
+{
+
+template<typename T>
+concept allocator = requires(T& alloc, layout layout, void* ptr)
+{
+ { alloc.alloc(layout) } -> same_as<void*>;
+ { alloc.realloc(ptr, layout, layout) } -> same_as<void*>;
+ alloc.dealloc(ptr, layout);
+};
+
+class GlobalHeap
+{
+public:
+ static void* alloc(const layout&);
+ static void* realloc(void* ptr, const layout& old, const layout& new_layout);
+ static void dealloc(void* ptr, const layout&);
+};
+static_assert(allocator<GlobalHeap>);
+
+using DefaultAllocator = GlobalHeap;
+
+} // namespace asl
diff --git a/asl/box.hpp b/asl/box.hpp new file mode 100644 index 0000000..0cab66b --- /dev/null +++ b/asl/box.hpp @@ -0,0 +1,19 @@ +#pragma once
+
+#include "asl/allocator.hpp"
+#include "asl/annotations.hpp"
+
+namespace asl
+{
+
+template<is_object T, allocator Allocator = DefaultAllocator>
+class box
+{
+ T* m_ptr;
+ ASL_NO_UNIQUE_ADDRESS Allocator m_alloc;
+
+public:
+};
+
+} // namespace asl
+
diff --git a/asl/format.cpp b/asl/format.cpp index d25bade..461fc77 100644 --- a/asl/format.cpp +++ b/asl/format.cpp @@ -4,11 +4,11 @@ #include "asl/memory.hpp"
void asl::format_internals::format(
- writer* writer,
+ Writer* writer,
string_view fmt,
span<const type_erased_arg> args)
{
- formatter f(writer);
+ Formatter f(writer);
const auto* arg_it = args.begin();
const auto* arg_end = args.end();
@@ -74,22 +74,22 @@ void asl::format_internals::format( f.write(fmt);
}
-void asl::AslFormat(formatter& f, const char* str)
+void asl::AslFormat(Formatter& f, const char* str)
{
f.write({str, asl::strlen(str)});
}
-void asl::AslFormat(formatter& f, float)
+void asl::AslFormat(Formatter& f, float)
{
f.write("<FLOAT>"); // @Todo Float formatting
}
-void asl::AslFormat(formatter& f, double)
+void asl::AslFormat(Formatter& f, double)
{
f.write("<DOUBLE>"); // @Todo Float formatting
}
-void asl::AslFormat(formatter& f, bool v)
+void asl::AslFormat(Formatter& f, bool v)
{
if (v)
{
@@ -101,22 +101,22 @@ void asl::AslFormat(formatter& f, bool v) }
}
-void asl::AslFormat(formatter& f, uint8_t v)
+void asl::AslFormat(Formatter& f, uint8_t v)
{
AslFormat(f, static_cast<uint64_t>(v));
}
-void asl::AslFormat(formatter& f, uint16_t v)
+void asl::AslFormat(Formatter& f, uint16_t v)
{
AslFormat(f, static_cast<uint64_t>(v));
}
-void asl::AslFormat(formatter& f, uint32_t v)
+void asl::AslFormat(Formatter& f, uint32_t v)
{
AslFormat(f, static_cast<uint64_t>(v));
}
-void asl::AslFormat(formatter& f, uint64_t v)
+void asl::AslFormat(Formatter& f, uint64_t v)
{
static constexpr char s_pairs_storage[] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4',
@@ -180,22 +180,22 @@ void asl::AslFormat(formatter& f, uint64_t v) f.write(string_view(buffer, kMaxDigits).substr(cursor));
}
-void asl::AslFormat(formatter& f, int8_t v)
+void asl::AslFormat(Formatter& f, int8_t v)
{
AslFormat(f, static_cast<int64_t>(v));
}
-void asl::AslFormat(formatter& f, int16_t v)
+void asl::AslFormat(Formatter& f, int16_t v)
{
AslFormat(f, static_cast<int64_t>(v));
}
-void asl::AslFormat(formatter& f, int32_t v)
+void asl::AslFormat(Formatter& f, int32_t v)
{
AslFormat(f, static_cast<int64_t>(v));
}
-void asl::AslFormat(formatter& f, int64_t v)
+void asl::AslFormat(Formatter& f, int64_t v)
{
if (v < 0)
{
diff --git a/asl/format.hpp b/asl/format.hpp index 57be45d..7cf3917 100644 --- a/asl/format.hpp +++ b/asl/format.hpp @@ -9,10 +9,10 @@ namespace asl
{
-class formatter;
+class Formatter;
template<typename T>
-concept formattable = requires (formatter& f, const T& value)
+concept formattable = requires (Formatter& f, const T& value)
{
AslFormat(f, value);
};
@@ -23,10 +23,10 @@ namespace format_internals struct type_erased_arg
{
const void* data;
- void (*fn)(formatter&, const void*);
+ void (*fn)(Formatter&, const void*);
template<formattable T>
- static constexpr void erased_fn(formatter& f, const void* data)
+ static constexpr void erased_fn(Formatter& f, const void* data)
{
AslFormat(f, *reinterpret_cast<const T*>(data));
}
@@ -38,16 +38,16 @@ struct type_erased_arg {}
};
-void format(writer*, string_view fmt, span<const type_erased_arg> args);
+void format(Writer*, string_view fmt, span<const type_erased_arg> args);
} // namespace internals
-class formatter
+class Formatter
{
- writer* m_writer;
+ Writer* m_writer;
public:
- explicit constexpr formatter(writer* writer)
+ explicit constexpr Formatter(Writer* writer)
: m_writer{writer}
{}
@@ -58,7 +58,7 @@ public: };
template<formattable... Args>
-void format(writer* w, string_view fmt, const Args&... args)
+void format(Writer* w, string_view fmt, const Args&... args)
{
if constexpr (types_count<Args...> > 0)
{
@@ -75,26 +75,26 @@ void format(writer* w, string_view fmt, const Args&... args) }
template<isize_t N>
-void AslFormat(formatter& f, const char (&str)[N])
+void AslFormat(Formatter& f, const char (&str)[N])
{
f.write(str, N - 1);
}
-void AslFormat(formatter& f, const char* str);
+void AslFormat(Formatter& f, const char* str);
-void AslFormat(formatter& f, float);
-void AslFormat(formatter& f, double);
+void AslFormat(Formatter& f, float);
+void AslFormat(Formatter& f, double);
-void AslFormat(formatter& f, bool);
+void AslFormat(Formatter& f, bool);
-void AslFormat(formatter& f, uint8_t);
-void AslFormat(formatter& f, uint16_t);
-void AslFormat(formatter& f, uint32_t);
-void AslFormat(formatter& f, uint64_t);
+void AslFormat(Formatter& f, uint8_t);
+void AslFormat(Formatter& f, uint16_t);
+void AslFormat(Formatter& f, uint32_t);
+void AslFormat(Formatter& f, uint64_t);
-void AslFormat(formatter& f, int8_t);
-void AslFormat(formatter& f, int16_t);
-void AslFormat(formatter& f, int32_t);
-void AslFormat(formatter& f, int64_t);
+void AslFormat(Formatter& f, int8_t);
+void AslFormat(Formatter& f, int16_t);
+void AslFormat(Formatter& f, int32_t);
+void AslFormat(Formatter& f, int64_t);
} // namespace asl
@@ -7,12 +7,12 @@ namespace asl
{
-class writer
+class Writer
{
public:
- writer() = default;
- ASL_DELETE_COPY_MOVE(writer);
- virtual ~writer() = default;
+ Writer() = default;
+ ASL_DELETE_COPY_MOVE(Writer);
+ virtual ~Writer() = default;
virtual void write(span<const byte>) = 0;
};
diff --git a/asl/layout.hpp b/asl/layout.hpp index 06fbe10..2295a1c 100644 --- a/asl/layout.hpp +++ b/asl/layout.hpp @@ -24,6 +24,12 @@ struct layout {
return layout{ size_of<T>, align_of<T> };
}
+
+ template<is_object T>
+ static constexpr layout array(isize_t size)
+ {
+ return layout{ size_of<T> * size, align_of<T> };
+ }
};
} // namespace asl
diff --git a/asl/memory.hpp b/asl/memory.hpp index 33b10fe..23aa392 100644 --- a/asl/memory.hpp +++ b/asl/memory.hpp @@ -15,6 +15,11 @@ constexpr isize_t memcmp(const void* a, const void* b, isize_t size) return __builtin_memcmp(a, b, static_cast<size_t>(size));
}
+constexpr void memcpy(void* dst, const void* src, isize_t size)
+{
+ __builtin_memcpy(dst, src, static_cast<size_t>(size));
+}
+
constexpr isize_t strlen(const char* s)
{
return static_cast<isize_t>(__builtin_strlen(s));
diff --git a/asl/meta.hpp b/asl/meta.hpp index e64b4f2..552bf0c 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -21,10 +21,10 @@ template<typename U, typename V> struct _select_helper<true, U, V> template<bool kSelect, typename U, typename V> using select_t = _select_helper<kSelect, U, V>::type;
-template<typename U, typename V> struct _is_same_helper : false_type {};
-template<typename T> struct _is_same_helper<T, T> : true_type {};
+template<typename U, typename V> struct _same_as_helper : false_type {};
+template<typename T> struct _same_as_helper<T, T> : true_type {};
-template<typename U, typename V> concept same_as = _is_same_helper<U, V>::value && _is_same_helper<V, U>::value;
+template<typename U, typename V> concept same_as = _same_as_helper<U, V>::value && _same_as_helper<V, U>::value;
template<typename T> auto _as_lref_helper(int) -> id<T&>;
template<typename T> auto _as_lref_helper(...) -> id<T>;
diff --git a/asl/print.cpp b/asl/print.cpp index 6f81f19..17f00c8 100644 --- a/asl/print.cpp +++ b/asl/print.cpp @@ -3,7 +3,7 @@ #include <cstdio>
// @Todo Optimize this, maybe make buffered
-class ConsoleWriter : public asl::writer
+class ConsoleWriter : public asl::Writer
{
FILE* m_handle;
@@ -18,13 +18,13 @@ public: }
};
-asl::writer* asl::print_internals::get_stdout_writer()
+asl::Writer* asl::print_internals::get_stdout_writer()
{
static ConsoleWriter s_writer{stdout};
return &s_writer;
}
-asl::writer* asl::print_internals::get_stderr_writer()
+asl::Writer* asl::print_internals::get_stderr_writer()
{
static ConsoleWriter s_writer{stderr};
return &s_writer;
diff --git a/asl/print.hpp b/asl/print.hpp index 4e7d07a..208bcb2 100644 --- a/asl/print.hpp +++ b/asl/print.hpp @@ -9,8 +9,8 @@ namespace print_internals {
// @Todo Make print writers thread safe
-writer* get_stdout_writer();
-writer* get_stderr_writer();
+Writer* get_stdout_writer();
+Writer* get_stderr_writer();
} // namespace print_internals
diff --git a/asl/tests/box_tests.cpp b/asl/tests/box_tests.cpp new file mode 100644 index 0000000..6c4d543 --- /dev/null +++ b/asl/tests/box_tests.cpp @@ -0,0 +1,6 @@ +#include "asl/box.hpp"
+
+#include "asl/testing/testing.hpp"
+
+static_assert(sizeof(asl::box<int>) == sizeof(int*));
+
diff --git a/asl/tests/format_tests.cpp b/asl/tests/format_tests.cpp index cb7a13f..a8c1ad6 100644 --- a/asl/tests/format_tests.cpp +++ b/asl/tests/format_tests.cpp @@ -1,26 +1,25 @@ #include "asl/format.hpp"
#include "asl/testing/testing.hpp"
-#include "asl/print.hpp"
-
-#include <cstdlib>
-#include <cstring>
-#include <cassert>
-#include <cstdio>
-
-// @Todo Improve this to use our utilities, not the C stdlib
+#include "asl/allocator.hpp"
static_assert(asl::formattable<decltype("Hello")>);
-class StringSink : public asl::writer
+class StringSink : public asl::Writer
{
+ // @Todo Use string, once we have it, or a buffer
isize_t m_current_len{};
char* m_data{};
public:
void write(asl::span<const asl::byte> str) override
{
- m_data = (char*)realloc(m_data, (size_t)(m_current_len + str.size()));
- memcpy(m_data + m_current_len, str.data(), (size_t)str.size());
+ m_data = reinterpret_cast<char*>(asl::GlobalHeap::realloc(
+ m_data,
+ asl::layout::array<char>(m_current_len),
+ asl::layout::array<char>(m_current_len + str.size())));
+
+ asl::memcpy(m_data + m_current_len, str.data(), str.size());
+
m_current_len += str.size();
}
@@ -29,7 +28,7 @@ public: void reset()
{
m_current_len = 0;
- free(m_data);
+ asl::GlobalHeap::dealloc(m_data, asl::layout::array<char>(m_current_len));
m_data = nullptr;
}
};
diff --git a/asl/tests/meta_tests.cpp b/asl/tests/meta_tests.cpp index 40b9046..354cea6 100644 --- a/asl/tests/meta_tests.cpp +++ b/asl/tests/meta_tests.cpp @@ -35,6 +35,7 @@ static_assert(!asl::trivially_copy_constructible<NonCopyConstructible>); static_assert(asl::move_constructible<int>);
static_assert(asl::move_constructible<TriviallyMoveConstructible>);
static_assert(asl::move_constructible<MoveConstructible>);
+static_assert(asl::move_constructible<CopyConstructible>);
static_assert(!asl::move_constructible<NonMoveConstructible>);
static_assert(asl::trivially_move_constructible<int>);
diff --git a/asl/utility.hpp b/asl/utility.hpp index d54d965..7740eff 100644 --- a/asl/utility.hpp +++ b/asl/utility.hpp @@ -24,6 +24,12 @@ constexpr U bit_cast(T value) requires (size_of<T> == size_of<U>) return __builtin_bit_cast(U, value);
}
+template<typename T>
+T min(T a, T b)
+{
+ return (a <= b) ? a : b;
+}
+
#define ASL_DELETE_COPY(T) \
T(const T&) = delete; \
T& operator=(const T&) = delete;
|