Tofu Vector

Tofu Vector is a dynamic, type-aware container library for C and C++ that allows storing and manipulating sequences of fossil_tofu_t elements efficiently. It provides a rich set of operations including push, pop, insert, erase, and direct element access with both index-based and front/back operations. The library is designed for high performance with amortized O(1) insertion at the end and safe memory management. It also supports type-awareness, copy/move semantics, and optional type-safety through the C++ wrapper class, making it suitable for both low-level C programming and modern C++ development.

HEADER REFERENCE #

#ifndef FOSSIL_TOFU_VECTOR_H
#define FOSSIL_TOFU_VECTOR_H

#include "tofu.h"

#ifdef __cplusplus
extern "C" {
#endif

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

typedef struct {
    fossil_tofu_t* data;
    size_t size;
    size_t capacity;
    char* type;
} fossil_tofu_vector_t;

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

/**
 * Create a new vector with the specified expected type.
 * 
 * Time complexity: O(1)
 *
 * @param expected_type The expected type of elements in the vector.
 * @return              The created vector.
 */
fossil_tofu_vector_t* fossil_tofu_vector_create_container(char* type);

/**
 * Create a new vector with default values.
 * 
 * Time complexity: O(1)
 *
 * @return The created vector.
 */
fossil_tofu_vector_t* fossil_tofu_vector_create_default(void);

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

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

/**
 * Erase the contents of the vector and fossil_tofu_free allocated memory.
 * 
 * Time complexity: O(n)
 *
 * @param vector The vector to erase.
 */
void fossil_tofu_vector_destroy(fossil_tofu_vector_t* vector);

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

/**
 * Add an element to the end of the vector.
 * 
 * Amortized time complexity: O(1)
 *
 * @param vector  The vector to which the element will be added.
 * @param element The element to add.
 */
void fossil_tofu_vector_push_back(fossil_tofu_vector_t* vector, char *element);

/**
 * Add an element to the front of the vector.
 * 
 * Time complexity: O(n)
 *
 * @param vector  The vector to which the element will be added.
 * @param element The element to add.
 */
void fossil_tofu_vector_push_front(fossil_tofu_vector_t* vector, char *element);

/**
 * Add an element at the specified index in the vector.
 * 
 * Time complexity: O(n)
 *
 * @param vector  The vector to which the element will be added.
 * @param index   The index at which to add the element.
 * @param element The element to add.
 */
void fossil_tofu_vector_push_at(fossil_tofu_vector_t* vector, size_t index, char *element);

/**
 * Remove the last element from the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to remove the last element.
 */
void fossil_tofu_vector_pop_back(fossil_tofu_vector_t* vector);

/**
 * Remove the first element from the vector.
 * 
 * Time complexity: O(n)
 *
 * @param vector The vector from which to remove the first element.
 */
void fossil_tofu_vector_pop_front(fossil_tofu_vector_t* vector);

/**
 * Remove the element at the specified index in the vector.
 * 
 * Time complexity: O(n)
 *
 * @param vector The vector from which to remove the element.
 * @param index  The index at which to remove the element.
 */
void fossil_tofu_vector_pop_at(fossil_tofu_vector_t* vector, size_t index);

/**
 * Remove all elements from the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to remove all elements.
 */
void fossil_tofu_vector_erase(fossil_tofu_vector_t* vector);

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

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

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

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

/**
 * Get the size of the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector for which to get the size.
 * @return       The size of the vector.
 */
size_t fossil_tofu_vector_size(const fossil_tofu_vector_t* vector);

/**
 * Get the capacity of the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector for which to get the capacity.
 * @return       The capacity of the vector.
 */
size_t fossil_tofu_vector_capacity(const fossil_tofu_vector_t* vector);

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

/**
 * Get the element at the specified index in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to get the element.
 * @param index  The index of the element to get.
 * @return       The element at the specified index.
 */
char *fossil_tofu_vector_get(const fossil_tofu_vector_t* vector, size_t index);

/**
 * Get the first element in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to get the first element.
 * @return       The first element in the vector.
 */
char *fossil_tofu_vector_get_front(const fossil_tofu_vector_t* vector);

/**
 * Get the last element in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to get the last element.
 * @return       The last element in the vector.
 */
char *fossil_tofu_vector_get_back(const fossil_tofu_vector_t* vector);

/**
 * Get the element at the specified index in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector The vector from which to get the element.
 * @param index  The index of the element to get.
 * @return       The element at the specified index.
 */
char *fossil_tofu_vector_get_at(const fossil_tofu_vector_t* vector, size_t index);

/**
 * Set the element at the specified index in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector  The vector 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_vector_set(fossil_tofu_vector_t* vector, size_t index, char *element);

/**
 * Set the first element in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector  The vector in which to set the first element.
 * @param element The element to set.
 */
void fossil_tofu_vector_set_front(fossil_tofu_vector_t* vector, char *element);

/**
 * Set the last element in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector  The vector in which to set the last element.
 * @param element The element to set.
 */
void fossil_tofu_vector_set_back(fossil_tofu_vector_t* vector, char *element);

/**
 * Set the element at the specified index in the vector.
 * 
 * Time complexity: O(1)
 *
 * @param vector  The vector 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_vector_set_at(fossil_tofu_vector_t* vector, size_t index, char *element);

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

namespace fossil {

    namespace tofu {

        /**
         * A wrapper class for the fossil_tofu_vector_t structure, providing a C++ interface
         * for managing dynamic arrays of elements.
         */
        class Vector {
        public:
            /**
             * Default constructor. Creates a new vector with default values.
             * Throws a runtime_error if the vector creation fails.
             */
            Vector() : vector(fossil_tofu_vector_create_default()) {
                if (fossil_tofu_vector_is_cnullptr(vector)) {
                    throw std::runtime_error("Failed to create vector");
                }
            }

            /**
             * Constructor that creates a new vector with the specified type.
             * Throws a runtime_error if the vector creation fails.
             *
             * @param type The expected type of elements in the vector.
             */
            Vector(const std::string& type) : vector(fossil_tofu_vector_create_container(const_cast<char*>(type.c_str()))) {
                if (fossil_tofu_vector_is_cnullptr(vector)) {
                    throw std::runtime_error("Failed to create vector");
                }
            }

            /**
             * Copy constructor. Creates a new vector by copying an existing vector.
             * Throws a runtime_error if the vector creation fails.
             *
             * @param other The vector to copy.
             */
            Vector(const Vector& other) : vector(fossil_tofu_vector_create_copy(other.vector)) {
                if (fossil_tofu_vector_is_cnullptr(vector)) {
                    throw std::runtime_error("Failed to create vector");
                }
            }

            /**
             * Move constructor. Creates a new vector by moving an existing vector.
             * Does not throw exceptions.
             *
             * @param other The vector to move.
             */
            Vector(Vector&& other) noexcept : vector(fossil_tofu_vector_create_move(other.vector)) {
                other.vector = nullptr;
            }

            /**
             * Destructor. Destroys the vector and frees allocated memory.
             */
            ~Vector() {
                if (vector) {
                    fossil_tofu_vector_destroy(vector);
                }
            }

            /**
             * Adds an element to the end of the vector.
             *
             * @param element The element to add.
             */
            void push_back(const std::string& element) {
                fossil_tofu_vector_push_back(vector, const_cast<char*>(element.c_str()));
            }

            /**
             * Adds an element to the front of the vector.
             *
             * @param element The element to add.
             */
            void push_front(const std::string& element) {
                fossil_tofu_vector_push_front(vector, const_cast<char*>(element.c_str()));
            }

            /**
             * Adds an element at the specified index in the vector.
             *
             * @param index   The index at which to add the element.
             * @param element The element to add.
             */
            void push_at(size_t index, const std::string& element) {
                fossil_tofu_vector_push_at(vector, index, const_cast<char*>(element.c_str()));
            }

            /**
             * Removes the last element from the vector.
             */
            void pop_back() {
                fossil_tofu_vector_pop_back(vector);
            }

            /**
             * Removes the first element from the vector.
             */
            void pop_front() {
                fossil_tofu_vector_pop_front(vector);
            }

            /**
             * Removes the element at the specified index in the vector.
             *
             * @param index The index at which to remove the element.
             */
            void pop_at(size_t index) {
                fossil_tofu_vector_pop_at(vector, index);
            }

            /**
             * Removes all elements from the vector.
             */
            void erase() {
                fossil_tofu_vector_erase(vector);
            }

            /**
             * Checks if the vector is empty.
             *
             * @return True if the vector is empty, false otherwise.
             */
            bool is_empty() const {
                return fossil_tofu_vector_is_empty(vector);
            }

            /**
             * Gets the size of the vector.
             *
             * @return The size of the vector.
             */
            size_t size() const {
                return fossil_tofu_vector_size(vector);
            }

            /**
             * Gets the element at the specified index in the vector.
             *
             * @param index The index of the element to get.
             * @return      The element at the specified index.
             */
            std::string get(size_t index) const {
                return std::string(fossil_tofu_vector_get(vector, index));
            }

            /**
             * Gets the first element in the vector.
             *
             * @return The first element in the vector.
             */
            std::string get_front() const {
                return std::string(fossil_tofu_vector_get_front(vector));
            }

            /**
             * Gets the last element in the vector.
             *
             * @return The last element in the vector.
             */
            std::string get_back() const {
                return std::string(fossil_tofu_vector_get_back(vector));
            }

            /**
             * Gets the element at the specified index in the vector.
             *
             * @param index The index of the element to get.
             * @return      The element at the specified index.
             */
            std::string get_at(size_t index) const {
                return std::string(fossil_tofu_vector_get_at(vector, index));
            }

            /**
             * Sets the element at the specified index in the vector.
             *
             * @param index   The index at which to set the element.
             * @param element The element to set.
             */
            void set(size_t index, const std::string& element) {
                fossil_tofu_vector_set(vector, index, const_cast<char*>(element.c_str()));
            }

            /**
             * Sets the first element in the vector.
             *
             * @param element The element to set.
             */
            void set_front(const std::string& element) {
                fossil_tofu_vector_set_front(vector, const_cast<char*>(element.c_str()));
            }

            /**
             * Sets the last element in the vector.
             *
             * @param element The element to set.
             */
            void set_back(const std::string& element) {
                fossil_tofu_vector_set_back(vector, const_cast<char*>(element.c_str()));
            }

            /**
             * Sets the element at the specified index in the vector.
             *
             * @param index   The index at which to set the element.
             * @param element The element to set.
             */
            void set_at(size_t index, const std::string& element) {
                fossil_tofu_vector_set_at(vector, index, const_cast<char*>(element.c_str()));
            }

        private:
            /**
             * A pointer to the underlying fossil_tofu_vector_t structure.
             */
            fossil_tofu_vector_t* vector;
        };

    } // namespace tofu

} // namespace fossil

#endif

#endif /* FOSSIL_TOFU_FRAMEWORK_H */

SAMPLE CODE C #

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

int main() {
    // Create a default vector
    fossil_vector_t* vec = fossil_vector_create_default();

    // Add elements
    fossil_vector_push_back(vec, "Hello");
    fossil_vector_push_back(vec, "World");

    // Access elements
    printf("First: %s\n", fossil_vector_get_front(vec));
    printf("Last: %s\n", fossil_vector_get_back(vec));

    // Insert element at index 1
    fossil_vector_push_at(vec, 1, "Fossil");

    // Iterate and print
    for (size_t i = 0; i < fossil_vector_size(vec); i++) {
        printf("Element %zu: %s\n", i, fossil_vector_get_at(vec, i));
    }

    // Remove last element
    fossil_vector_pop_back(vec);

    // Cleanup
    fossil_vector_destroy(vec);

    return 0;
}

SAMPLE CODE C++ #

#include "fossil/tofu/vector.h"
#include <iostream>

int main() {
    using namespace fossil::tofu;

    // Create a vector with type "string"
    Vector vec("cstr");

    // Add elements
    vec.push_back("Hello");
    vec.push_back("World");

    // Access elements
    std::cout << "First: " << vec.get_front() << std::endl;
    std::cout << "Last: " << vec.get_back() << std::endl;

    // Insert element at index 1
    vec.push_at(1, "Fossil");

    // Iterate and print
    for (size_t i = 0; i < vec.size(); i++) {
        std::cout << "Element " << i << ": " << vec.get_at(i) << std::endl;
    }

    // Remove first element
    vec.pop_front();

    return 0;
}

What are your feelings

Updated on September 27, 2025