Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
228fefb
Start migrating code
shewitt-au Mar 8, 2026
3e6358a
More migration
shewitt-au Mar 8, 2026
2fac595
Comments
shewitt-au Mar 8, 2026
b3a3e3f
Fix range validation
shewitt-au Mar 9, 2026
3fbc92d
Pass locale as narrow string
shewitt-au Mar 9, 2026
325902d
Move non-windows code
shewitt-au Mar 9, 2026
071c311
Rename function
shewitt-au Mar 9, 2026
54df362
POSIX formatting
shewitt-au Mar 9, 2026
d579341
More POSIX formatting
shewitt-au Mar 9, 2026
0d02d53
Use libwolv typedefs
shewitt-au Mar 9, 2026
8cb961f
Start replacing bools with enums in APi
shewitt-au Mar 9, 2026
2e3ba28
Consolidate flags
shewitt-au Mar 10, 2026
f19b0a8
Fix non-windows build error
shewitt-au Mar 10, 2026
48c41e9
Remove unused include
shewitt-au Mar 10, 2026
08cef5a
Rename some flags
shewitt-au Mar 10, 2026
59e7cab
Flags and stuff
shewitt-au Mar 10, 2026
cab3ab8
Make date and time selectable --- UNTESTED CODE
shewitt-au Mar 10, 2026
5b745eb
Make date and time selectable --- UNTESTED CODE
shewitt-au Mar 10, 2026
1934a94
Make date and time selectable --- UNTESTED CODE
shewitt-au Mar 10, 2026
ef9be59
Remove some debugging code
shewitt-au Mar 11, 2026
968bdde
Remove some debugging code (missed a bit)
shewitt-au Mar 11, 2026
98c8d99
Fix includes
shewitt-au Mar 12, 2026
e194cd1
Small changes
shewitt-au Mar 12, 2026
a41e7f0
Size std::string after to utf8 conv.
shewitt-au Mar 12, 2026
6673698
Windows/POSIX locale abstraction
shewitt-au Mar 12, 2026
fbccfc8
Work on locale abstraction
shewitt-au Mar 12, 2026
570796f
Work on locale abstraction
shewitt-au Mar 13, 2026
d0d0227
SOOBuffer: fix includes. Work on locale abstraction.
shewitt-au Mar 13, 2026
616bc42
Work on POISX formatting
shewitt-au Mar 13, 2026
2911b5b
Fix POSIX build error
shewitt-au Mar 13, 2026
5abdf98
POSOX hacks (temp)
shewitt-au Mar 14, 2026
c313ef0
Merge branch 'F2592-Locale-date-time' of /mnt/c/projects/SteveImHex/l…
shewitt-au Mar 14, 2026
e4258bd
Changes from WSL build
shewitt-au Mar 14, 2026
e5f34a8
Add support for some flags on non-Windows builds
shewitt-au Mar 14, 2026
3528e72
Move soo_buffer to containers
shewitt-au Mar 14, 2026
792088f
Move some impl out of header file
shewitt-au Mar 14, 2026
c1b142b
Rename function
shewitt-au Mar 14, 2026
e077265
Fix Linux compiler errors
shewitt-au Mar 14, 2026
b0b5096
Rename class
shewitt-au Mar 14, 2026
71ea6b9
Rename class (WSL)
shewitt-au Mar 14, 2026
cfe4d50
Rename function
shewitt-au Mar 14, 2026
8c68267
Rename stuff
shewitt-au Mar 14, 2026
d432ae3
How?
shewitt-au Mar 14, 2026
fb10034
Rename
shewitt-au Mar 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions libs/containers/include/wolv/container/soo_buffer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#pragma once
// soo_buffer.hpp
/*
* Small Object Optimization Buffer
*
* A buffer for POD types that keeps small allocations on the stack and
* transparently moves to heap storage when the size exceeds a configurable
* limit. During reallocation, the contents of the previous buffer may
* optionally be copied to the new one.
*/

#include <cstddef>
#include <type_traits>
#include <cstdlib>
#include <initializer_list>

namespace {

template <typename T>
struct NewAlloc {
static T* alloc(T* old, size_t sz) {
delete [] old;
return new T[sz];
}

static void free(T* p) {
delete[] p;
}

static void copy(T* desc, T* src, size_t sz) {}
};

template <typename T>
struct RealloceAlloc {
static T* alloc(T* old, size_t sz) {
return static_cast<T*>(realloc(old, sz*sizeof(T)));
}

static void free(T* p) {
::free(p);
}

static void copy(T* desc, T* src, size_t sz) {
memcpy(desc, src, sz*sizeof(T));
}
};

} // namespace

namespace wolv::util {

// T - Type
// SZ - Size in Ts of stack buffer
// UseRealloc - If true copies the contents of the old buffer to the new on reallocation
template <typename T, size_t SZ, bool UseRealloc=false>
class SOOBuffer {
static_assert(std::is_trivially_copyable_v<T>&& std::is_standard_layout_v<T>,
"SOOBuffer only supports trivial, standard-layout types");

using Alloc = std::conditional_t<UseRealloc, RealloceAlloc<T>, NewAlloc<T>>;

public:
using elementType = T;
static const size_t smallSZ = SZ;

SOOBuffer(size_t cap = 0) {
m_size = SZ;
grow(cap);
}

SOOBuffer(const SOOBuffer&) = delete;
SOOBuffer& operator=(const SOOBuffer&) = delete;
SOOBuffer(SOOBuffer&&) = delete;
SOOBuffer& operator=(SOOBuffer&&) = delete;

~SOOBuffer() {
if (!isSmall())
Alloc::free(m_heap);
}

T* data() {
return isSmall() ? m_small : m_heap;
}

const T* data() const {
return isSmall() ? m_small : m_heap;
}

operator T* () {
return data();
}

operator const T* () const {
return data();
}

T& operator[](size_t i) {
return data()[i];
}

const T& operator[](size_t i) const {
return data()[i];
}

size_t small_size() const {
return smallSZ;
}

bool isSmall() const {
return m_size <= SZ;
}

size_t size() const {
return m_size;
}

void grow(size_t sz) {
if (sz > m_size) { // we never get smaller
growBuffer(sz);
}
}

void grow(size_t sz, std::initializer_list<T**> ptrs) {
if (sz <= m_size) { // we never get smaller
return;
}

T *pOldBase = data();
growBuffer(sz);
T *pNewBase = data();

for (T** p : ptrs) {
*p = (*p - pOldBase) + pNewBase;
}
}

private:
void growBuffer(size_t sz) {
if (isSmall()) {
T *pHeap = Alloc::alloc(NULL, sz);
Alloc::copy(pHeap, m_small, SZ);
m_heap = pHeap;
}
else {
m_heap = Alloc::alloc(m_heap, sz);
}
m_size = sz;
}

size_t m_size = 0;

union {
T* m_heap;
T m_small[SZ];
};
};

} // namespace wolv::util
8 changes: 7 additions & 1 deletion libs/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@ project(libwolv-utils)
# Add library
add_library(${PROJECT_NAME} STATIC
source/utils/string.cpp
source/utils/date_time_format.cpp
)

add_subdirectory(lib/jthread)

target_include_directories(${PROJECT_NAME} PUBLIC include)
target_link_libraries(${PROJECT_NAME} PUBLIC wolv::types jthread)
target_link_libraries(${PROJECT_NAME}
PUBLIC
wolv::types
wolv::containers
jthread
)
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")

string(REPLACE "libwolv-" "" PROJECT_NAME_SPACE ${PROJECT_NAME})
Expand Down
106 changes: 106 additions & 0 deletions libs/utils/include/wolv/utils/date_time_format.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#pragma once
// date_time_format.hpp

#include <optional>
#include <string>
#include <type_traits>

#include <wolv/types.hpp>

#if defined(OS_WINDOWS)
# include <windows.h>
#else
# include <locale.h>
#endif // #if defined(OS_WINDOWS)

namespace wolv::util {

#if defined(OS_WINDOWS)

class Locale {
public:
Locale() = default;
explicit Locale(const char *str);
explicit Locale(const std::string &str);
Locale(const Locale &copyMe) = default;

~Locale() = default;

Locale& operator=(const Locale &copyMe);

void set(const char *str);
void set(const std::string &str);

operator const char*() const {
return m_locale.c_str();
}

private:
std::string m_locale;
};

#else

class Locale {
public:
Locale();
explicit Locale(const char *str);
explicit Locale(const std::string &str);
Locale(const Locale &copyMe);

~Locale();

Locale& operator=(const Locale &copyMe);

void set(const char *str);
void set(const std::string &str);

operator locale_t() const {
return m_locale;
}

private:
void setInvalid();
void free();

bool m_valid;
locale_t m_locale;
};

#endif

enum class DTOpts {
TT32 = 0b0000, // 32-bits
TT64 = 0b0001, // 64-bits
TTMask = 0b0001,

DandT = 0b0110, // date and time
D = 0b0100, // date
T = 0b0010, // time
DTMask = 0b0110,

ShortDate = 0b0000,
LongDate = 0b1000,
DateFmtMask = 0b1000
};

constexpr DTOpts operator|(DTOpts a, DTOpts b) noexcept {
using T = std::underlying_type_t<DTOpts>;
return static_cast<DTOpts>(static_cast<T>(a) | static_cast<T>(b));
}

constexpr DTOpts operator&(DTOpts a, DTOpts b) noexcept {
using T = std::underlying_type_t<DTOpts>;
return static_cast<DTOpts>(static_cast<T>(a) & static_cast<T>(b));
}

#if defined(OS_WINDOWS)
std::optional<SYSTEMTIME> timeTToSystemTime(i64 t, DTOpts sz = DTOpts::TT64);
std::optional<std::string> formatSystemTime(LPCSTR lc, const SYSTEMTIME* pss, DTOpts opts = DTOpts::LongDate);

std::optional<std::string> formatTT(const Locale &lc, wolv::i64 t, DTOpts opts = DTOpts::TT64|DTOpts::DandT|DTOpts::LongDate);
#else
std::optional<std::string> formatTT(const Locale &lc, wolv::i64 t, DTOpts opts = DTOpts::TT64|DTOpts::DandT|DTOpts::LongDate);
#endif

} // namespace wolv::util
Loading
Loading