Tofu Stack

ToFu Stack is a type-safe, dynamic stack container for fossil_tofu_t elements. It supports standard stack operations—push (insert), pop (remove), and top retrieval—along with random access via index. The library provides C and C++ interfaces with copy and move semantics, capacity handling, and robust memory management. The C++ wrapper offers an object-oriented API for safe and convenient usage.

HEADER REFERENCE #

#ifndef FOSSIL_TOFU_STACK_H
#define FOSSIL_TOFU_STACK_H

#include "tofu.h"

#ifdef __cplusplus
extern "C"
{
#endif

// *****************************************************************************
// Type definitions
// *****************************************************************************

// Stack structure
typedef struct fossil_tofu_stack_node_t {
    fossil_tofu_t data; // Data stored in the stack node
    struct fossil_tofu_stack_node_t* next; // Pointer to the next node
} fossil_tofu_stack_node_t;

typedef struct fossil_tofu_stack_t {
    char* type; // Type of the stack
    fossil_tofu_stack_node_t* top; // Pointer to the top node of the stack
} fossil_tofu_stack_t;

// *****************************************************************************
// Function prototypes
// *****************************************************************************

/**
 * Create a new stack with the specified data type.
 *
 * @param list_type The type of data the stack will store.
 * @return          The created stack.
 * @note            Time complexity: O(1)
 */
fossil_tofu_stack_t* fossil_tofu_stack_create_container(char* type);

/**
 * Create a new stack with default values.
 * 
 * Time complexity: O(1)
 *
 * @return The created stack.
 */
fossil_tofu_stack_t* fossil_tofu_stack_create_default(void);

/**
 * Create a new stack by copying an existing stack.
 * 
 * Time complexity: O(n)
 *
 * @param other The stack to copy.
 * @return      The created stack.
 */
fossil_tofu_stack_t* fossil_tofu_stack_create_copy(const fossil_tofu_stack_t* other);

/**
 * Create a new stack by moving an existing stack.
 * 
 * Time complexity: O(1)
 *
 * @param other The stack to move.
 * @return      The created stack.
 */
fossil_tofu_stack_t* fossil_tofu_stack_create_move(fossil_tofu_stack_t* other);

/**
 * Erase the contents of the stack and fossil_tofu_free allocated memory.
 *
 * @param stack The stack to erase.
 * @note        Time complexity: O(n)
 */
void fossil_tofu_stack_destroy(fossil_tofu_stack_t* stack);

// *****************************************************************************
// Utility functions
// *****************************************************************************

/**
 * Insert data into the stack.
 *
 * @param stack The stack to insert data into.
 * @param data  The data to insert.
 * @return      The error code indicating the success or failure of the operation.
 * @note        Time complexity: O(1)
 */
int32_t fossil_tofu_stack_insert(fossil_tofu_stack_t* stack, char *data);

/**
 * Remove data from the stack.
 *
 * @param stack       The stack to remove data from.
 * @return            The error code indicating the success or failure of the operation.
 * @note              Time complexity: O(1)
 */
int32_t fossil_tofu_stack_remove(fossil_tofu_stack_t* stack);

/**
 * Get the size of the stack.
 *
 * @param stack The stack for which to get the size.
 * @return      The size of the stack.
 * @note        Time complexity: O(n)
 */
size_t fossil_tofu_stack_size(const fossil_tofu_stack_t* stack);

/**
 * Check if the stack is not empty.
 *
 * @param stack The stack to check.
 * @return      True if the stack is not empty, false otherwise.
 * @note        Time complexity: O(1)
 */
bool fossil_tofu_stack_not_empty(const fossil_tofu_stack_t* stack);

/**
 * Check if the stack is not a null pointer.
 *
 * @param stack The stack to check.
 * @return      True if the stack is not a null pointer, false otherwise.
 * @note        Time complexity: O(1)
 */
bool fossil_tofu_stack_not_cnullptr(const fossil_tofu_stack_t* stack);

/**
 * Check if the stack is empty.
 *
 * @param stack The stack to check.
 * @return      True if the stack is empty, false otherwise.
 * @note        Time complexity: O(1)
 */
bool fossil_tofu_stack_is_empty(const fossil_tofu_stack_t* stack);

/**
 * Check if the stack is a null pointer.
 *
 * @param stack The stack to check.
 * @return      True if the stack is a null pointer, false otherwise.
 * @note        Time complexity: O(1)
 */
bool fossil_tofu_stack_is_cnullptr(const fossil_tofu_stack_t* stack);

/**
 * Get the top element of the stack.
 *
 * @param stack         The stack to get the top element from.
 * @return              The top element of the stack or the default value if the stack is empty.
 * @note                Time complexity: O(1)
 */
fossil_tofu_t fossil_tofu_stack_top(fossil_tofu_stack_t* stack);

// *****************************************************************************
// Getter and setter functions
// *****************************************************************************

/**
 * Get the element at the specified index in the stack.
 * 
 * Time complexity: O(n)
 *
 * @param stack The stack from which to get the element.
 * @param index The index of the element to get.
 * @return      The element at the specified index.
 */
fossil_tofu_t fossil_tofu_stack_get(const fossil_tofu_stack_t* stack, size_t index);

/**
 * Set the element at the specified index in the stack.
 * 
 * Time complexity: O(n)
 *
 * @param stack   The stack in which to set the element.
 * @param index   The index at which to set the element.
 * @param element The element to set.
 */
void fossil_tofu_stack_set(fossil_tofu_stack_t* stack, size_t index, fossil_tofu_t element);

#ifdef __cplusplus
}
#include <stdexcept>
#include <string>

namespace fossil {

    namespace tofu {

        /**
         * A C++ wrapper class for the fossil_tofu_stack_t structure, providing a more
         * user-friendly interface for stack operations.
         */
        class Stack {
            public:
                /**
                 * Constructor to create a stack with a specified type.
                 *
                 * @param type The type of data the stack will store.
                 * @throws std::runtime_error If the stack creation fails.
                 */
                Stack(const std::string& type) {
                    stack_ = fossil_tofu_stack_create_container(const_cast<char*>(type.c_str()));
                    if (!stack_) {
                        throw std::runtime_error("Failed to create stack.");
                    }
                }

                /**
                 * Default constructor to create a stack with default values.
                 *
                 * @throws std::runtime_error If the stack creation fails.
                 */
                Stack() {
                    stack_ = fossil_tofu_stack_create_default();
                    if (!stack_) {
                        throw std::runtime_error("Failed to create stack.");
                    }
                }

                /**
                 * Copy constructor to create a stack by copying another stack.
                 *
                 * @param other The stack to copy.
                 * @throws std::runtime_error If the stack creation fails.
                 */
                Stack(const Stack& other) {
                    stack_ = fossil_tofu_stack_create_copy(other.stack_);
                    if (!stack_) {
                        throw std::runtime_error("Failed to create stack.");
                    }
                }

                /**
                 * Destructor to destroy the stack and free allocated memory.
                 */
                ~Stack() {
                    fossil_tofu_stack_destroy(stack_);
                }

                /**
                 * Insert data into the stack.
                 *
                 * @param data The data to insert.
                 * @return     The error code indicating the success or failure of the operation.
                 */
                int32_t insert(const std::string& data) {
                    return fossil_tofu_stack_insert(stack_, const_cast<char*>(data.c_str()));
                }

                /**
                 * Remove data from the stack.
                 *
                 * @return The error code indicating the success or failure of the operation.
                 */
                int32_t remove() {
                    return fossil_tofu_stack_remove(stack_);
                }

                /**
                 * Get the size of the stack.
                 *
                 * @return The size of the stack.
                 */
                size_t size() const {
                    return fossil_tofu_stack_size(stack_);
                }

                /**
                 * Check if the stack is not empty.
                 *
                 * @return True if the stack is not empty, false otherwise.
                 */
                bool not_empty() const {
                    return fossil_tofu_stack_not_empty(stack_);
                }

                /**
                 * Check if the stack is not a null pointer.
                 *
                 * @return True if the stack is not a null pointer, false otherwise.
                 */
                bool not_cnullptr() const {
                    return fossil_tofu_stack_not_cnullptr(stack_);
                }

                /**
                 * Check if the stack is empty.
                 *
                 * @return True if the stack is empty, false otherwise.
                 */
                bool is_empty() const {
                    return fossil_tofu_stack_is_empty(stack_);
                }

                /**
                 * Check if the stack is a null pointer.
                 *
                 * @return True if the stack is a null pointer, false otherwise.
                 */
                bool is_cnullptr() const {
                    return fossil_tofu_stack_is_cnullptr(stack_);
                }

                /**
                 * Get the top element of the stack.
                 *
                 * @return The top element of the stack or the default value if the stack is empty.
                 */
                fossil_tofu_t top() {
                    return fossil_tofu_stack_top(stack_);
                }

                /**
                 * Get the element at the specified index in the stack.
                 *
                 * @param index The index of the element to get.
                 * @return      The element at the specified index.
                 */
                fossil_tofu_t get(size_t index) const {
                    return fossil_tofu_stack_get(stack_, index);
                }

                /**
                 * Set the element at the specified index in the stack.
                 *
                 * @param index   The index at which to set the element.
                 * @param element The element to set.
                 */
                void set(size_t index, fossil_tofu_t element) {
                    fossil_tofu_stack_set(stack_, index, element);
                }

            private:
                /**
                 * Pointer to the underlying fossil_tofu_stack_t structure.
                 */
                fossil_tofu_stack_t* stack_;
        };

    } // namespace tofu

} // namespace fossil

#endif

#endif /* FOSSIL_TOFU_FRAMEWORK_H */

SAMPLE CODE C #

#include "fossil/tofu/stack.h"
#include <stdio.h>

int main() {
    fossil_stack_t* stack = fossil_stack_create_default();

    // Insert elements
    fossil_stack_insert(stack, "apple");
    fossil_stack_insert(stack, "banana");
    fossil_stack_insert(stack, "cherry");

    // Access top element
    printf("Top: %s\n", fossil_stack_top(stack).data);

    // Remove top element
    fossil_stack_remove(stack);
    printf("New top: %s\n", fossil_stack_top(stack).data);

    // Access elements by index
    for (size_t i = 0; i < fossil_stack_size(stack); i++) {
        printf("Element %zu: %s\n", i, fossil_stack_get(stack, i).data);
    }

    fossil_stack_destroy(stack);
    return 0;
}

SAMPLE CODE C++ #

#include "fossil/tofu/stack.h"
#include <iostream>
using namespace fossil::tofu;

int main() {
    Stack stack("cstr");

    // Insert elements
    stack.insert("apple");
    stack.insert("banana");
    stack.insert("cherry");

    // Access top element
    std::cout << "Top: " << stack.top().data << std::endl;

    // Remove top element
    stack.remove();
    std::cout << "New top: " << stack.top().data << std::endl;

    // Access elements by index
    for (size_t i = 0; i < stack.size(); i++) {
        std::cout << "Element " << i << ": " << stack.get(i).data << std::endl;
    }

    return 0;
}

What are your feelings

Updated on September 27, 2025