feely_pona/feely_pona_stdlib.h

148 lines
4.4 KiB
C++

#if defined(_CLANGD)
#pragma once
#include "feely_pona_unity.h"
#endif
template <typename T>
struct FP_SentinelListLink
{
T data;
FP_SentinelListLink<T> *next;
FP_SentinelListLink<T> *prev;
};
template <typename T>
struct FP_SentinelList
{
Dqn_usize size;
FP_SentinelListLink<T> *sentinel;
};
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_Front(FP_SentinelList<T> *list)
{
FP_SentinelListLink<T> *result = nullptr;
if (list && list->sentinel && list->sentinel->next)
result = list->sentinel->next;
return result;
}
template <typename T>
bool FP_SentinelList_Iterate(FP_SentinelList<T> *list, FP_SentinelListLink<T> **it)
{
if (!list || !list->sentinel || !it)
return false;
if (!DQN_CHECK(list->sentinel->next && list->sentinel->prev))
return false;
if (!(*it))
*it = list->sentinel;
bool result = list && (*it)->next != list->sentinel;
if (result)
(*it) = (*it)->next;
return result;
}
template <typename T>
FP_SentinelList<T> FP_SentinelList_Init(TELY_ChunkPool *pool)
{
FP_SentinelList<T> result = {};
result.sentinel = TELY_ChunkPool_New(pool, FP_SentinelListLink<T>);
result.sentinel->next = result.sentinel->prev = result.sentinel;
return result;
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_Make(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
{
FP_SentinelListLink<T> *result = FP_SentinelList_MakeBefore(list, list->sentinel, pool);
return result;
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_Add(FP_SentinelList<T> *list, TELY_ChunkPool *pool, const T& data)
{
FP_SentinelListLink<T> *result = FP_SentinelList_Make(list, pool);
result->data = data;
return result;
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_MakeBefore(FP_SentinelList<T> *list, FP_SentinelListLink<T> *link, TELY_ChunkPool *pool)
{
DQN_ASSERT(list->sentinel->next);
DQN_ASSERT(list->sentinel->prev);
DQN_ASSERT(list->sentinel->prev->next == list->sentinel);
DQN_ASSERT(list->sentinel->next->prev == list->sentinel);
FP_SentinelListLink<T> *result = TELY_ChunkPool_New(pool, FP_SentinelListLink<T>);
result->next = link;
result->prev = link->prev;
result->next->prev = result;
result->prev->next = result;
list->size++;
return result;
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_MakeAfter(FP_SentinelList<T> *list, FP_SentinelListLink<T> *link, TELY_ChunkPool *pool)
{
DQN_ASSERT(list->sentinel->next);
DQN_ASSERT(list->sentinel->prev);
DQN_ASSERT(list->sentinel->prev->next == list->sentinel);
DQN_ASSERT(list->sentinel->next->prev == list->sentinel);
FP_SentinelListLink<T> *result = TELY_ChunkPool_New(pool, FP_SentinelListLink<T>);
result->next = link->next;
result->prev = link;
result->next->prev = result;
result->prev->next = result;
list->size++;
return result;
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_Erase(FP_SentinelList<T> *list, FP_SentinelListLink<T> *link, TELY_ChunkPool *pool)
{
FP_SentinelListLink<T> *result = link->prev;
link->next->prev = link->prev;
link->prev->next = link->next;
TELY_ChunkPool_Dealloc(pool, link);
list->size--;
return result;
}
template <typename T>
void FP_SentinelList_Clear(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
{
if (!list || !pool)
return;
for (FP_SentinelListLink<T> *link = nullptr; FP_SentinelList_Iterate(list, &link); )
link = FP_SentinelList_Erase(list, link, pool);
}
template <typename T>
void FP_SentinelList_Deinit(FP_SentinelList<T> *list, TELY_ChunkPool *pool)
{
if (!list || !pool)
return;
FP_SentinelList_Clear(list, pool);
TELY_ChunkPool_Dealloc(pool, list->sentinel);
*list = {};
}
template <typename T>
FP_SentinelListLink<T> *FP_SentinelList_Find(FP_SentinelList<T> const *list, T const &find)
{
FP_SentinelListLink<T> *result = nullptr;
for (FP_SentinelListLink<T> *link = nullptr;
!result && FP_SentinelList_Iterate<T>(DQN_CAST(FP_SentinelList<T> *)list, &link); ) {
if (link->data == find)
result = link;
}
return result;
}