CList is a circular doubly linked list container: Access elements with get, get_front, get_back, and modify them with set, set_front, set_back. O(1) insertions/removals at head or tail. Supports copy/move semantics. Type-safe via string type metadata. C++ RAII wrapper ensures automatic memory management.
Code reference for C and C++ APIs for the respective Fossil Logic library.
HEADER REFERENCE #
#ifndef FOSSIL_TOFU_CIRCALIRLIST_H
#define FOSSIL_TOFU_CIRCALIRLIST_H
#include "tofu.h"
#ifdef __cplusplus
extern "C"
{
#endif
// *****************************************************************************
// Type definitions
// *****************************************************************************
// Node structure for the circular doubly linked list
typedef struct fossil_tofu_clist_node_t {
fossil_tofu_t data;
struct fossil_tofu_clist_node_t* prev;
struct fossil_tofu_clist_node_t* next;
} fossil_tofu_clist_node_t;
// Circular doubly linked list structure
typedef struct fossil_tofu_clist_t {
fossil_tofu_clist_node_t* head; // Head node
char* type; // Data type string
} fossil_tofu_clist_t;
// *****************************************************************************
// Function prototypes
// *****************************************************************************
/**
* Create a new circular linked list container with the specified data type.
*
* @param type A string representing the data type for the list elements.
* @return Pointer to the newly created circular linked list container, or NULL on failure.
*/
fossil_tofu_clist_t* fossil_tofu_clist_create_container(char* type);
/**
* Create a new circular linked list container with default settings.
*
* @return Pointer to the newly created default circular linked list container, or NULL on failure.
*/
fossil_tofu_clist_t* fossil_tofu_clist_create_default(void);
/**
* Create a deep copy of an existing circular linked list container.
*
* @param other Pointer to the source circular linked list to copy.
* @return Pointer to the newly created copy, or NULL on failure.
*/
fossil_tofu_clist_t* fossil_tofu_clist_create_copy(const fossil_tofu_clist_t* other);
/**
* Move the contents of an existing circular linked list container to a new container.
* The source container is left in an empty or invalid state.
*
* @param other Pointer to the source circular linked list to move.
* @return Pointer to the newly created container with moved contents, or NULL on failure.
*/
fossil_tofu_clist_t* fossil_tofu_clist_create_move(fossil_tofu_clist_t* other);
/**
* Destroy a circular linked list container and free all associated memory.
*
* @param clist Pointer to the circular linked list container to destroy.
*/
void fossil_tofu_clist_destroy(fossil_tofu_clist_t* clist);
// *****************************************************************************
// Utility functions
// *****************************************************************************
/**
* Insert a new element into the circular linked list.
* The new element is added at the tail and linked back to the head.
*
* @param clist Pointer to the circular linked list container.
* @param data String data to insert as a new element.
* @return 0 on success, non-zero on failure.
*/
int32_t fossil_tofu_clist_insert(fossil_tofu_clist_t* clist, char *data);
/**
* Remove an element from the circular linked list.
* Typically removes the tail or a designated element.
*
* @param clist Pointer to the circular linked list container.
* @return 0 on success, non-zero on failure.
*/
int32_t fossil_tofu_clist_remove(fossil_tofu_clist_t* clist);
/**
* Reverse the order of elements in the circular linked list by swapping next and prev pointers.
*
* @param clist Pointer to the circular linked list container.
*/
void fossil_tofu_clist_reverse(fossil_tofu_clist_t* clist);
/**
* Get the number of elements currently stored in the circular linked list.
*
* @param clist Pointer to the circular linked list container.
* @return The number of elements in the list.
*/
size_t fossil_tofu_clist_size(const fossil_tofu_clist_t* clist);
/**
* Check if the circular linked list contains any elements.
*
* @param clist Pointer to the circular linked list container.
* @return true if the list is not empty, false if it is empty.
*/
bool fossil_tofu_clist_not_empty(const fossil_tofu_clist_t* clist);
/**
* Check if the circular linked list pointer is not a null pointer.
*
* @param clist Pointer to the circular linked list container.
* @return true if the pointer is valid, false if it is NULL.
*/
bool fossil_tofu_clist_not_cnullptr(const fossil_tofu_clist_t* clist);
/**
* Check if the circular linked list is empty (contains no elements).
*
* @param clist Pointer to the circular linked list container.
* @return true if the list is empty, false otherwise.
*/
bool fossil_tofu_clist_is_empty(const fossil_tofu_clist_t* clist);
/**
* Check if the circular linked list pointer is a null pointer.
*
* @param clist Pointer to the circular linked list container.
* @return true if the pointer is NULL, false otherwise.
*/
bool fossil_tofu_clist_is_cnullptr(const fossil_tofu_clist_t* clist);
// *****************************************************************************
// Getter and setter functions
// *****************************************************************************
/**
* Get the element at the specified index in the circular linked list.
*
* @param clist Pointer to the circular linked list container.
* @param index Zero-based index of the element to retrieve.
* @return Pointer to the string data at the specified index, or NULL if out of range.
*/
char *fossil_tofu_clist_get(const fossil_tofu_clist_t* clist, size_t index);
/**
* Get the first (head) element in the circular linked list.
*
* @param clist Pointer to the circular linked list container.
* @return Pointer to the string data of the first element, or NULL if the list is empty.
*/
char *fossil_tofu_clist_get_front(const fossil_tofu_clist_t* clist);
/**
* Get the last (tail) element in the circular linked list.
*
* @param clist Pointer to the circular linked list container.
* @return Pointer to the string data of the last element, or NULL if the list is empty.
*/
char *fossil_tofu_clist_get_back(const fossil_tofu_clist_t* clist);
/**
* Set the element at the specified index in the circular linked list.
* Overwrites the data at the given index.
*
* @param clist Pointer to the circular linked list container.
* @param index Zero-based index of the element to set.
* @param element String data to set at the specified index.
*/
void fossil_tofu_clist_set(fossil_tofu_clist_t* clist, size_t index, char *element);
/**
* Set the first (head) element in the circular linked list.
* Overwrites the data of the first element.
*
* @param clist Pointer to the circular linked list container.
* @param element String data to set as the first element.
*/
void fossil_tofu_clist_set_front(fossil_tofu_clist_t* clist, char *element);
/**
* Set the last (tail) element in the circular linked list.
* Overwrites the data of the last element.
*
* @param clist Pointer to the circular linked list container.
* @param element String data to set as the last element.
*/
void fossil_tofu_clist_set_back(fossil_tofu_clist_t* clist, char *element);
#ifdef __cplusplus
}
#include <string>
#include <cstddef> // For size_t
#include <stdexcept> // For exceptions
namespace fossil {
namespace tofu {
/**
* @class CList
* @brief C++ RAII wrapper for the C circular linked list API.
*
* This class provides safe, type-checked, and exception-aware access to the
* underlying C circular doubly linked list implementation. It manages memory
* automatically and exposes familiar C++ methods for list operations.
*/
class CList {
private:
fossil_tofu_clist_t* clist_; /**< Pointer to the circular linked list container (C API) */
public:
/**
* @brief Constructor: Creates a circular linked list with a specific data type.
* @param type String representing the data type for the list elements.
* @throws std::runtime_error If creation fails.
*/
explicit CList(const std::string& type) {
clist_ = fossil_tofu_clist_create_container(const_cast<char*>(type.c_str()));
if (!clist_) {
throw std::runtime_error("Failed to create circular linked list");
}
}
/**
* @brief Default constructor: Creates an empty circular linked list.
* @throws std::runtime_error If creation fails.
*/
CList() {
clist_ = fossil_tofu_clist_create_default();
if (!clist_) {
throw std::runtime_error("Failed to create circular linked list");
}
}
/**
* @brief Copy constructor: Creates a deep copy of another CList.
* @param other Reference to the CList to copy.
* @throws std::runtime_error If copy creation fails.
*/
CList(const CList& other) {
clist_ = fossil_tofu_clist_create_copy(other.clist_);
if (!clist_) {
throw std::runtime_error("Failed to copy circular linked list");
}
}
/**
* @brief Move constructor: Transfers ownership from another CList.
* The source CList is left in a valid but empty state.
* @param other Rvalue reference to the CList to move.
*/
CList(CList&& other) noexcept {
clist_ = fossil_tofu_clist_create_move(other.clist_);
other.clist_ = nullptr;
}
/**
* @brief Destructor: Destroys the circular linked list and frees all resources.
*/
~CList() {
if (clist_) {
fossil_tofu_clist_destroy(clist_);
}
}
/**
* @brief Insert a new element into the circular linked list.
* @param data String data to insert as a new element.
* @return 0 on success, non-zero on failure.
*/
int insert(const std::string& data) {
return fossil_tofu_clist_insert(clist_, const_cast<char*>(data.c_str()));
}
/**
* @brief Remove an element from the circular linked list.
* @return 0 on success, non-zero on failure.
*/
int remove() {
return fossil_tofu_clist_remove(clist_);
}
/**
* @brief Reverse the order of elements in the circular linked list.
*/
void reverse() {
fossil_tofu_clist_reverse(clist_);
}
/**
* @brief Get the number of elements in the circular linked list.
* @return Number of elements in the list.
*/
size_t size() const {
return fossil_tofu_clist_size(clist_);
}
/**
* @brief Check if the circular linked list contains any elements.
* @return true if not empty, false otherwise.
*/
bool not_empty() const {
return fossil_tofu_clist_not_empty(clist_);
}
/**
* @brief Check if the circular linked list pointer is valid (not nullptr).
* @return true if valid, false otherwise.
*/
bool not_cnullptr() const {
return fossil_tofu_clist_not_cnullptr(clist_);
}
/**
* @brief Check if the circular linked list is empty.
* @return true if empty, false otherwise.
*/
bool is_empty() const {
return fossil_tofu_clist_is_empty(clist_);
}
/**
* @brief Check if the circular linked list pointer is nullptr.
* @return true if nullptr, false otherwise.
*/
bool is_cnullptr() const {
return fossil_tofu_clist_is_cnullptr(clist_);
}
/**
* @brief Get the element at the specified index.
* @param index Zero-based index of the element to retrieve.
* @return std::string containing the element data.
* @throws std::out_of_range If index is invalid.
*/
std::string get(size_t index) const {
char* result = fossil_tofu_clist_get(clist_, index);
if (result) {
return std::string(result);
}
throw std::out_of_range("Index out of range");
}
/**
* @brief Get the first (head) element in the list.
* @return std::string containing the front element data.
* @throws std::runtime_error If retrieval fails.
*/
std::string get_front() const {
char* result = fossil_tofu_clist_get_front(clist_);
if (result) {
return std::string(result);
}
throw std::runtime_error("Failed to get front element");
}
/**
* @brief Get the last (tail) element in the list.
* @return std::string containing the back element data.
* @throws std::runtime_error If retrieval fails.
*/
std::string get_back() const {
char* result = fossil_tofu_clist_get_back(clist_);
if (result) {
return std::string(result);
}
throw std::runtime_error("Failed to get back element");
}
/**
* @brief Set the element at the specified index.
* @param index Zero-based index of the element to set.
* @param element String data to set at the specified index.
*/
void set(size_t index, const std::string& element) {
fossil_tofu_clist_set(clist_, index, const_cast<char*>(element.c_str()));
}
/**
* @brief Set the first (head) element in the list.
* @param element String data to set as the first element.
*/
void set_front(const std::string& element) {
fossil_tofu_clist_set_front(clist_, const_cast<char*>(element.c_str()));
}
/**
* @brief Set the last (tail) element in the list.
* @param element String data to set as the last element.
*/
void set_back(const std::string& element) {
fossil_tofu_clist_set_back(clist_, const_cast<char*>(element.c_str()));
}
};
} // namespace tofu
} // namespace fossil
#endif
#endif /* FOSSIL_TOFU_FRAMEWORK_H */SAMPLE CODE C #
#include "fossil/tofu/clist.h"
#include <stdio.h>
int main() {
fossil_clist_t* clist = fossil_clist_create_container("cstr");
fossil_clist_insert(clist, "alpha");
fossil_clist_insert(clist, "beta");
printf("Front: %s\n", fossil_clist_get_front(clist));
printf("Back: %s\n", fossil_clist_get_back(clist));
fossil_clist_set_front(clist, "gamma");
printf("New Front: %s\n", fossil_clist_get_front(clist));
fossil_clist_remove(clist);
printf("Front after removal: %s\n", fossil_clist_get_front(clist));
fossil_clist_destroy(clist);
return 0;
}
SAMPLE CODE C++ #
#include "fossil/tofu/clist.h"
#include <iostream>
using namespace fossil::tofu;
int main() {
CList clist("cstr");
clist.insert("alpha");
clist.insert("beta");
std::cout << "Front: " << clist.get_front() << "\n";
std::cout << "Back: " << clist.get_back() << "\n";
clist.set_front("gamma");
std::cout << "New Front: " << clist.get_front() << "\n";
clist.remove();
std::cout << "Front after removal: " << clist.get_front() << "\n";
std::cout << "Size: " << clist.size() << "\n";
return 0;
}