Shuffle Algorithm

The Fossil Algorithm Shuffle module provides a configurable, runtime-driven interface for randomizing arrays of arbitrary element types. By identifying both the data type and the shuffle strategy using string identifiers, the API supports classic Fisher–Yates, inside-out, secure, and seeded shuffling modes with consistent behavior across numeric, floating-point, and string data. The core fossil_algorithm_shuffle_exec function performs in-place randomized permutation and returns structured error codes for invalid configuration, unknown types, or unsupported algorithms. Utility functions allow callers to query whether a type is supported and retrieve its element size, while the C++ wrapper exposes a simplified, modern interface using std::string and static helper functions.

HEADER REFERENCE #

#ifndef FOSSIL_ALGORITHM_SHUFFLE_H
#define FOSSIL_ALGORITHM_SHUFFLE_H

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

// ======================================================
// Fossil Algorithm Shuffle — Exec Interface
// ======================================================

/**
 * @brief Executes an array shuffle using string-based configuration.
 *
 * Provides a flexible runtime interface to randomize arrays of various types
 * using algorithm, type, and mode specified by string identifiers.
 *
 * Example:
 * @code
 * int32_t values[] = {1, 2, 3, 4, 5};
 * fossil_algorithm_shuffle_exec(values, 5, "i32", "fisher-yates", "auto", 0);
 * @endcode
 *
 * @param base Pointer to the array to shuffle.
 * @param count Number of elements in the array.
 * @param type_id String identifier for data type (e.g., "i32", "f64", "cstr").
 * @param algorithm_id String identifier for shuffle algorithm ("auto", "fisher-yates", "inside-out", etc.).
 * @param mode_id String identifier for shuffle mode ("auto", "seeded", "secure").
 * @param seed Optional seed value (ignored if mode is "auto" or "secure").
 * @return int Status code:
 *   - `0` on success
 *   - `-1` invalid input
 *   - `-2` unknown type
 *   - `-3` unknown algorithm
 */
int fossil_algorithm_shuffle_exec(
    void *base,
    size_t count,
    const char *type_id,
    const char *algorithm_id,
    const char *mode_id,
    uint64_t seed
);

// ======================================================
// Extended Utility API
// ======================================================

/**
 * @brief Returns the byte size of a type based on its string identifier.
 *
 * @param type_id Type identifier (e.g., "i32", "f64", "cstr").
 * @return size_t Size of the type in bytes, or 0 if unknown.
 */
size_t fossil_algorithm_shuffle_type_sizeof(const char *type_id);

/**
 * @brief Checks whether the given type identifier is supported.
 *
 * @param type_id Type identifier string.
 * @return bool True if supported, false otherwise.
 */
bool fossil_algorithm_shuffle_type_supported(const char *type_id);

#ifdef __cplusplus
}

#include <string>

namespace fossil {

    namespace algorithm {

        /**
         * @brief RAII-friendly C++ wrapper for Fossil shuffle algorithms.
         *
         * Provides static methods to shuffle arrays using various algorithms.
         * All methods are thin wrappers around the C API, accepting raw pointers
         * and shuffle options. Default options are used if none are provided.
         *
         * Usage:
         *   - Pass a pointer to the array, element count, type, algorithm, mode, and seed.
         *   - Returns status code (0 on success, negative on error).
         */
        class Shuffle
        {
        public:
            /**
             * @brief Shuffles an array using the Fossil C API.
             *
             * @param base Pointer to the array to shuffle.
             * @param count Number of elements in the array.
             * @param type_id String identifier for data type (e.g., "i32", "f64", "cstr").
             * @param algorithm_id String identifier for shuffle algorithm ("auto", "fisher-yates", "inside-out", etc.).
             * @param mode_id String identifier for shuffle mode ("auto", "seeded", "secure").
             * @param seed Optional seed value (ignored if mode is "auto" or "secure").
             * @return int Status code (0 on success, negative on error).
             */
            static int exec(
            void *base,
            size_t count,
            const std::string &type_id,
            const std::string &algorithm_id = "auto",
            const std::string &mode_id = "auto",
            uint64_t seed = 0
            ) {
            return fossil_algorithm_shuffle_exec(
                base,
                count,
                type_id.c_str(),
                algorithm_id.c_str(),
                mode_id.c_str(),
                seed
            );
            }

            /**
             * @brief Returns the byte size of a type based on its string identifier.
             *
             * @param type_id Type identifier (e.g., "i32", "f64", "cstr").
             * @return size_t Size of the type in bytes, or 0 if unknown.
             */
            static size_t type_sizeof(const std::string &type_id) {
            return fossil_algorithm_shuffle_type_sizeof(type_id.c_str());
            }

            /**
             * @brief Checks whether the given type identifier is supported.
             *
             * @param type_id Type identifier string.
             * @return bool True if supported, false otherwise.
             */
            static bool type_supported(const std::string &type_id) {
            return fossil_algorithm_shuffle_type_supported(type_id.c_str());
            }
        };

    } // namespace bluecrab

} // namespace fossil

#endif

#endif

SAMPLE CODE C #

#include "fossil/algorithm/shuffle.h"
#include <stdio.h>

int main(void) {
    int32_t values[] = { 1, 2, 3, 4, 5 };

    int status = fossil_algorithm_shuffle_exec(
        values,
        5,
        "i32",           // type
        "fisher-yates",  // algorithm
        "seeded",        // mode
        12345            // seed
    );

    if (status == 0) {
        printf("Shuffled: ");
        for (size_t i = 0; i < 5; ++i)
            printf("%d ", values[i]);
        printf("\n");
    } else {
        printf("Shuffle error %d\n", status);
    }

    printf("i32 size = %zu\n", fossil_algorithm_shuffle_type_sizeof("i32"));
    printf("supports f64? %s\n",
           fossil_algorithm_shuffle_type_supported("f64") ? "yes" : "no");

    return 0;
}

SAMPLE CODE C++ #

#include "fossil/algorithm/shuffle.h"
#include <iostream>
#include <vector>

using fossil::algorithm::Shuffle;

int main() {
    std::vector<double> data = { 0.5, 1.2, 3.8, 7.4, 9.9 };

    int status = Shuffle::exec(
        data.data(),
        data.size(),
        "f64",
        "inside-out",
        "seeded",
        98765
    );

    if (status == 0) {
        std::cout << "Shuffled values: ";
        for (double v : data)
            std::cout << v << " ";
        std::cout << "\n";
    } else {
        std::cout << "Shuffle error " << status << "\n";
    }

    std::cout << "f64 size = " << Shuffle::type_sizeof("f64") << "\n";
    std::cout << "supports cstr? "
              << (Shuffle::type_supported("cstr") ? "yes" : "no") << "\n";

    return 0;
}

What are your feelings

Updated on December 4, 2025