221 lines
6.0 KiB
C++
221 lines
6.0 KiB
C++
#include "memory.h"
|
|
|
|
#include <vector>
|
|
#include <unordered_set>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
|
|
namespace fugg {
|
|
namespace detail {
|
|
template<typename I, typename O>
|
|
struct ArrowProxy {
|
|
I value;
|
|
|
|
O* operator->() {
|
|
return reinterpret_cast<O*>(&value);
|
|
}
|
|
|
|
O& operator*() {
|
|
return *(operator->)();
|
|
}
|
|
};
|
|
|
|
struct RawVector {
|
|
uintptr_t begin;
|
|
uintptr_t end;
|
|
uintptr_t end_capacity;
|
|
};
|
|
|
|
template<typename T>
|
|
struct RawUniquePointer {
|
|
uintptr_t ptr;
|
|
};
|
|
|
|
template<typename T>
|
|
struct RawHashTable {
|
|
RawUniquePointer<uintptr_t[]> bucket_list;
|
|
uintptr_t first_node;
|
|
size_t capacity;
|
|
float unknown;
|
|
};
|
|
|
|
struct RawBasicString {
|
|
uintptr_t data;
|
|
size_t size;
|
|
size_t cap;
|
|
};
|
|
static_assert(
|
|
sizeof(RawBasicString) == sizeof(std::string),
|
|
"RawBasicString needs to have same size of std::string"
|
|
);
|
|
|
|
template <class _CharT, size_t = sizeof(_CharT)>
|
|
struct __padding
|
|
{
|
|
unsigned char __xx[sizeof(_CharT)-1];
|
|
};
|
|
|
|
template <class _CharT>
|
|
struct __padding<_CharT, 1>
|
|
{
|
|
};
|
|
|
|
}
|
|
|
|
// template<typename T>
|
|
// class String {
|
|
// using RawString = detail::RawBasicString<char>;
|
|
|
|
// public:
|
|
// explicit String(const uintptr_t& offset) : offset_(offset) { }
|
|
// };
|
|
|
|
// static_assert(
|
|
// sizeof(String) == sizeof(std::string),
|
|
// "String needs to have the same size of std::string"
|
|
// );
|
|
|
|
// A class that facilitates handling vectors that are allocated in a module.
|
|
template<typename T>
|
|
class Vector {
|
|
using RawVector = detail::RawVector;
|
|
|
|
ModulePointer<T> begin_;
|
|
ModulePointer<T> end_;
|
|
ModulePointer<T> end_capacity_;
|
|
|
|
public:
|
|
detail::ArrowProxy<RawVector, std::vector<T>> operator->() {
|
|
auto temp = RawVector {
|
|
.begin = begin_.as_pointer(),
|
|
.end = end_.as_pointer(),
|
|
.end_capacity = end_capacity_.as_pointer(),
|
|
};
|
|
|
|
return { temp };
|
|
}
|
|
|
|
auto begin() {
|
|
return operator->()->begin();
|
|
}
|
|
|
|
auto end() {
|
|
return operator->()->end();
|
|
}
|
|
};
|
|
|
|
static_assert(
|
|
sizeof(Vector<int>) == sizeof(std::vector<int>),
|
|
"Vector needs to have the same size of std::vector"
|
|
);
|
|
|
|
template<class T>
|
|
class BasicString {
|
|
using RawBasicString = detail::RawBasicString;
|
|
|
|
struct __long {
|
|
ModulePointer<T> data;
|
|
size_t size;
|
|
size_t cap;
|
|
};
|
|
|
|
enum {__min_cap = (sizeof(__long) - 1) / sizeof(T) > 2 ?
|
|
(sizeof(__long) - 1) / sizeof(T) : 2};
|
|
struct __short {
|
|
T data[__min_cap];
|
|
struct : detail::__padding<T>
|
|
{
|
|
unsigned char size;
|
|
};
|
|
};
|
|
|
|
union {
|
|
__long __l;
|
|
__short __s;
|
|
};
|
|
|
|
public:
|
|
explicit BasicString() {
|
|
memset(&__l, 0, sizeof(__long));
|
|
}
|
|
|
|
explicit BasicString(const std::basic_string<T>& existing) {
|
|
// Copy the data to the stack.
|
|
auto temp = *reinterpret_cast<const RawBasicString*>(&existing);
|
|
// If the string is using the __long representation, we need to
|
|
// change the pointer to pointer into the module memory.
|
|
auto is_small = -1 < (char)reinterpret_cast<__short*>(&temp)->size;
|
|
|
|
if(!is_small) {
|
|
temp.data = RuntimePointer<const char>(existing.c_str()).as_raw();
|
|
}
|
|
|
|
memcpy(&__l, &temp, sizeof(RawBasicString));
|
|
}
|
|
|
|
detail::ArrowProxy<RawBasicString, std::basic_string<T>> operator->() const {
|
|
// Copy the data to the stack.
|
|
auto temp = *reinterpret_cast<const RawBasicString*>(&__l);
|
|
// If the string is using the __long representation, we need to
|
|
// change the pointer to pointer into the module memory.
|
|
auto is_small = -1 < (char)__s.size;
|
|
|
|
if(!is_small) {
|
|
temp.data = __l.data.as_pointer();
|
|
}
|
|
|
|
return { temp };
|
|
}
|
|
|
|
|
|
std::basic_string<T>& operator*() {
|
|
return *(operator->)();
|
|
}
|
|
|
|
};
|
|
|
|
using String = BasicString<char>;
|
|
static_assert(sizeof(String) == sizeof(std::string), "String needs to be the same size as std::string.");
|
|
|
|
template<typename T>
|
|
class HashTable {
|
|
// struct __hash_node_base {
|
|
// using node_base_pointer = uintptr_t;
|
|
// using __first_node = __hash_node_base;
|
|
|
|
// node_base_pointer next;
|
|
// };
|
|
|
|
// struct __hash_node : public __hash_node_base {
|
|
// typedef T __node_value_type;
|
|
|
|
// size_t __hash_;
|
|
// __node_value_type __value_;
|
|
// };
|
|
|
|
|
|
// using __node_pointer = __hash_node_base::node_base_pointer;
|
|
// using __node_base_type = __hash_node_base;
|
|
// using __next_pointer = __node_pointer;
|
|
|
|
// using RawUniquePointer = detail::RawUniquePointer;
|
|
// using BucketList = RawUniquePointer<__next_pointer[]>;
|
|
// using __first_node = __hash_node_base::__first_node;
|
|
|
|
// BucketList bucketlist;
|
|
// __first_node first;
|
|
|
|
|
|
|
|
// typedef T* _NodePtr;
|
|
// typedef __hash_node_types<_NodePtr> type;
|
|
// typedef typename __make_hash_node_types<value_type>::type _NodeTypes;
|
|
// typedef typename _NodeTypes::__next_pointer __next_pointer;
|
|
// typedef unique_ptr<__next_pointer[]> __bucket_list;
|
|
// __bucket_list __bucket_list_;
|
|
|
|
// ModulePointer<
|
|
// RawUniquePointer<uintptr_t[]> bucket_list;
|
|
|
|
};
|
|
} |