Add guf_math_ckdint IMPL_STATIC etc.

This commit is contained in:
jun 2025-05-13 14:56:21 +02:00
parent 873cdf20b1
commit 6091eac820
5 changed files with 411 additions and 155 deletions

View File

@ -1,9 +1,6 @@
// #if defined(GUF_MATH_IMPL_STATIC) /*
// #define GUF_MATH_KWRDS static is parametrized: no
// #else */
// #define GUF_MATH_KWRDS
// #endif
#ifndef GUF_MATH_H #ifndef GUF_MATH_H
#define GUF_MATH_H #define GUF_MATH_H
#include "guf_common.h" #include "guf_common.h"

File diff suppressed because it is too large Load Diff

View File

@ -228,6 +228,7 @@ GUF_RAND_KWRDS double guf_rand32_normal_sample_one_f64(guf_rand32_state *state,
#include "guf_common.h" #include "guf_common.h"
#include "guf_assert.h" #include "guf_assert.h"
#include "guf_math.h" #include "guf_math.h"
#define GUF_MATH_CKDINT_IMPL_STATIC
#include "guf_math_ckdint.h" #include "guf_math_ckdint.h"
#ifdef UINT64_MAX #ifdef UINT64_MAX

View File

@ -238,6 +238,7 @@ GUF_STR_KWRDS bool guf_str_is_valid(const guf_str *str);
#include "guf_common.h" #include "guf_common.h"
#include "guf_math.h" #include "guf_math.h"
#define GUF_MATH_CKDINT_IMPL_STATIC
#include "guf_math_ckdint.h" #include "guf_math_ckdint.h"
#include <string.h> #include <string.h>

View File

@ -3,6 +3,7 @@
""" """
from dataclasses import dataclass from dataclasses import dataclass
from typing import Tuple
import textwrap import textwrap
@dataclass @dataclass
@ -20,10 +21,15 @@ class UintType:
INT_MIN: str INT_MIN: str
INT_MAX: str INT_MAX: str
def generate_ckdint_functions(int_types: list, uint_types: list) -> str: def generate_ckdint_functions(int_types: list, uint_types: list) -> Tuple[str, str]:
ckd_add_sub_uint_header = textwrap.dedent("""
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b);
""")
ckd_add_sub_uint = textwrap.dedent(""" ckd_add_sub_uint = textwrap.dedent("""
static inline guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b)
{{ {{
if (b > 0 && a > {int_max} - b) {{ if (b > 0 && a > {int_max} - b) {{
return GUF_MATH_CKD_OVERFLOW; return GUF_MATH_CKD_OVERFLOW;
@ -31,7 +37,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return GUF_MATH_CKD_SUCCESS; return GUF_MATH_CKD_SUCCESS;
}} }}
}} }}
static inline guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b)
{{ {{
if (b > a) {{ if (b > a) {{
return GUF_MATH_CKD_UNDERFLOW; return GUF_MATH_CKD_UNDERFLOW;
@ -39,15 +45,21 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return GUF_MATH_CKD_SUCCESS; return GUF_MATH_CKD_SUCCESS;
}} }}
}} }}
static inline guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b)
{{ {{
const {type} c = a * b; const {type} c = a * b;
return a != 0 && ((c / a) != b) ? GUF_MATH_CKD_OVERFLOW : GUF_MATH_CKD_SUCCESS; return a != 0 && ((c / a) != b) ? GUF_MATH_CKD_OVERFLOW : GUF_MATH_CKD_SUCCESS;
}} }}
""") """)
ckd_add_sub_int_header = textwrap.dedent("""
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b);
""")
ckd_add_sub_int = textwrap.dedent(""" ckd_add_sub_int = textwrap.dedent("""
static inline guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_add_{type_abbr}({type} a, {type} b)
{{ {{
if (b > 0 && a > {int_max} - b) {{ if (b > 0 && a > {int_max} - b) {{
return GUF_MATH_CKD_OVERFLOW; return GUF_MATH_CKD_OVERFLOW;
@ -57,7 +69,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return GUF_MATH_CKD_SUCCESS; return GUF_MATH_CKD_SUCCESS;
}} }}
}} }}
static inline guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_sub_{type_abbr}({type} a, {type} b)
{{ {{
if (b < 0 && a > {int_max} + b) {{ if (b < 0 && a > {int_max} + b) {{
return GUF_MATH_CKD_OVERFLOW; return GUF_MATH_CKD_OVERFLOW;
@ -67,7 +79,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return GUF_MATH_CKD_SUCCESS; return GUF_MATH_CKD_SUCCESS;
}} }}
}} }}
static inline guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_ckd_mul_{type_abbr}({type} a, {type} b)
{{ {{
if (b > 0) {{ if (b > 0) {{
if (a > {int_max} / b) {{ if (a > {int_max} / b) {{
@ -93,8 +105,19 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
""") """)
saturating_wrapping_int_header = textwrap.dedent("""
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result);
""")
saturating_wrapping_int = textwrap.dedent(""" saturating_wrapping_int = textwrap.dedent("""
static inline guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -114,7 +137,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -134,7 +157,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -155,7 +178,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -175,7 +198,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -197,7 +220,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -217,8 +240,18 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
""") """)
saturating_wrapping_uint_header = textwrap.dedent("""
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result);
GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result);
""")
saturating_wrapping_uint = textwrap.dedent(""" saturating_wrapping_uint = textwrap.dedent("""
static inline guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_add_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b);
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW); GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW);
@ -236,7 +269,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_sub_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b);
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_UNDERFLOW); GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_UNDERFLOW);
@ -254,7 +287,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_saturating_mul_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b);
GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW); GUF_ASSERT(check == GUF_MATH_CKD_SUCCESS || check == GUF_MATH_CKD_OVERFLOW);
@ -273,7 +306,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_add_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_add_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -281,7 +314,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_sub_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_sub_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -289,7 +322,7 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
return check; return check;
}} }}
static inline guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result) GUF_MATH_CKDINT_KWRDS guf_math_ckd_result guf_wrapping_mul_{type_abbr}({type} a, {type} b, {type} *result)
{{ {{
const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b); const guf_math_ckd_result check = guf_ckd_mul_{type_abbr}(a, b);
if (result) {{ if (result) {{
@ -299,24 +332,31 @@ def generate_ckdint_functions(int_types: list, uint_types: list) -> str:
}} }}
""") """)
text_result = "// Signed integer add/sub checks (generated with libguf/tools/ckdint-gen.py)\n" text_result = "// Signed integer arithmetic checks (generated with libguf/tools/ckdint-gen.py)\n"
text_result_header = text_result
for type in int_types: for type in int_types:
text_result += ckd_add_sub_int.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX) text_result += ckd_add_sub_int.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX)
text_result_header += ckd_add_sub_int_header.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX)
text_result += "\n// Unsigned integer add/sub checks (generated with libguf/tools/ckdint-gen.py) \n" text_result += "\n// Unsigned integer arithmetic checks (generated with libguf/tools/ckdint-gen.py) \n"
text_result_header += "\n// Unsigned integer arithmetic checks (generated with libguf/tools/ckdint-gen.py) \n"
for type in uint_types: for type in uint_types:
text_result += ckd_add_sub_uint.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX) text_result += ckd_add_sub_uint.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX)
text_result_header += ckd_add_sub_uint_header.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX)
text_result += "\n\n// Signed saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)\n"
text_result += "\n\n// Signed saturating/wrapping add/sub (generated with libguf/tools/ckdint-gen.py)\n" text_result_header += "\n\n// Signed saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)\n"
for type in int_types: for type in int_types:
text_result += saturating_wrapping_int.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX, uint_type = type.UINT_TYPE) + "\n" text_result += saturating_wrapping_int.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX, uint_type = type.UINT_TYPE) + "\n"
text_result_header += saturating_wrapping_int_header.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX, uint_type = type.UINT_TYPE) + "\n"
text_result += "\n// Unsigned saturating/wrapping add/sub (generated with libguf/tools/ckdint-gen.py)\n" text_result += "\n// Unsigned saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)\n"
text_result_header += "\n// Unsigned saturating/wrapping arithmetic (generated with libguf/tools/ckdint-gen.py)\n"
for type in uint_types: for type in uint_types:
text_result += saturating_wrapping_uint.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX) + "\n" text_result += saturating_wrapping_uint.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX) + "\n"
text_result_header += saturating_wrapping_uint_header.format(type = type.INT_TYPE, type_abbr = type.INT_TYPE_ABBR, int_min = type.INT_MIN, int_max = type.INT_MAX) + "\n"
return text_result return (text_result_header, text_result)
@ -341,7 +381,32 @@ if __name__ == "__main__":
UintType(INT_TYPE = "size_t", INT_TYPE_ABBR = "size_t", INT_MIN = "0", INT_MAX = "SIZE_MAX"), UintType(INT_TYPE = "size_t", INT_TYPE_ABBR = "size_t", INT_MIN = "0", INT_MAX = "SIZE_MAX"),
] ]
ckd_fun_code = generate_ckdint_functions(int_types = int_types, uint_types= uint_types) code_header, code_impl = generate_ckdint_functions(int_types = int_types, uint_types= uint_types)
print(ckd_fun_code) print(textwrap.dedent(
"""
#if defined(GUF_MATH_CKDINT_IMPL_STATIC)
#define GUF_MATH_CKDINT_KWRDS static inline
#else
#define GUF_MATH_CKDINT_KWRDS
#endif
#ifndef GUF_MATH_CKDINT_H
#define GUF_MATH_CKDINT_H
#include "guf_common.h"
typedef enum guf_math_ckd_result {GUF_MATH_CKD_SUCCESS = 0, GUF_MATH_CKD_OVERFLOW, GUF_MATH_CKD_UNDERFLOW} guf_math_ckd_result;
"""))
print(code_header)
print("#if defined(GUF_MATH_CKDINT_IMPL) || defined(GUF_MATH_CKDINT_IMPL_STATIC)")
print('#include "guf_assert.h"')
print(code_impl)
print("#endif\n")
print("#endif")
print("#undef GUF_MATH_CKDINT_IMPL")
print("#undef GUF_MATH_CKDINT_IMPL_STATIC\n")