#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <math.h>

// 30-digit precision string definitions
#define PI_30_STR "3.141592653589793238462643383279"
#define E_30_STR  "2.718281828459045235360287471352"

// Macro to generate a high-performance scalar + vector math function
#define DEFINE_MATH_FUNC(name) \
static PyObject* speedmath_##name(PyObject* self, PyObject* args) { \
    PyObject* arg; \
    if (!PyArg_ParseTuple(args, "O", &arg)) return NULL; \
    if (PyFloat_Check(arg) || PyLong_Check(arg)) { \
        return PyFloat_FromDouble(name(PyFloat_AsDouble(arg))); \
    } else if (PyList_Check(arg)) { \
        Py_ssize_t size = PyList_Size(arg); \
        PyObject* result = PyList_New(size); \
        if (!result) return NULL; \
        for (Py_ssize_t i = 0; i < size; i++) { \
            PyObject* item = PyList_GetItem(arg, i); \
            double x = PyFloat_AsDouble(item); \
            if (PyErr_Occurred()) { Py_DECREF(result); return NULL; } \
            PyList_SET_ITEM(result, i, PyFloat_FromDouble(name(x))); \
        } \
        return result; \
    } \
    PyErr_SetString(PyExc_TypeError, "Expected a float or a list of floats"); \
    return NULL; \
}

// Generate the speed-demon functions
DEFINE_MATH_FUNC(sin)
DEFINE_MATH_FUNC(cos)
DEFINE_MATH_FUNC(tan)
DEFINE_MATH_FUNC(sqrt)
DEFINE_MATH_FUNC(exp)
DEFINE_MATH_FUNC(log)

// Method registration table
static PyMethodDef SpeedmathMethods[] = {
    {"sin",  speedmath_sin,  METH_VARARGS, "Calculate sine (accepts float or list)"},
    {"cos",  speedmath_cos,  METH_VARARGS, "Calculate cosine (accepts float or list)"},
    {"tan",  speedmath_tan,  METH_VARARGS, "Calculate tangent (accepts float or list)"},
    {"sqrt", speedmath_sqrt, METH_VARARGS, "Calculate square root (accepts float or list)"},
    {"exp",  speedmath_exp,  METH_VARARGS, "Calculate exponential (accepts float or list)"},
    {"log",  speedmath_log,  METH_VARARGS, "Calculate natural logarithm (accepts float or list)"},
    {NULL, NULL, 0, NULL}  // Sentinel
};

// Module definition
static struct PyModuleDef speedmathmodule = {
    PyModuleDef_HEAD_INIT,
    "speedmath",
    "A speed-demon C extension for ultra-fast math operations.",
    -1,
    SpeedmathMethods
};

// Module initialization
PyMODINIT_FUNC PyInit_speedmath(void) {
    PyObject *m = PyModule_Create(&speedmathmodule);
    if (m == NULL) return NULL;

    // Add high-speed standard float constants
    PyModule_AddObject(m, "pi", PyFloat_FromDouble(3.14159265358979323846));
    PyModule_AddObject(m, "e",  PyFloat_FromDouble(2.71828182845904523536));

    // Add absolute 30-digit precision string constants
    PyModule_AddObject(m, "PI", PyUnicode_FromString(PI_30_STR));
    PyModule_AddObject(m, "E",  PyUnicode_FromString(E_30_STR));

    return m;
}