No description
Find a file
Jack Stouffer dffdfc74af
Some checks failed
CI / linux-arm64 (push) Has been cancelled
CI / linux-x64 (push) Has been cancelled
CI / macos-arm (push) Has been cancelled
CI / windows-x64 (push) Has been cancelled
working verison of fixed hash maps with tombstones
2025-12-25 15:33:35 -05:00
.github/workflows debug windows ci 2025-11-07 23:32:19 -05:00
docs change static hash map nomenclature 2025-12-16 13:53:06 -05:00
src working verison of fixed hash maps with tombstones 2025-12-25 15:33:35 -05:00
tests working verison of fixed hash maps with tombstones 2025-12-25 15:33:35 -05:00
tools working verison of fixed hash maps with tombstones 2025-12-25 15:33:35 -05:00
vendor working on new tools layout 2025-12-19 15:23:18 -05:00
.gitignore work 2025-12-22 02:12:47 -05:00
build_tools working on new tools layout 2025-12-19 15:23:18 -05:00
deleteme.sh working on hash maps 2025-12-25 14:12:12 -05:00
DESIGN.md working on tooling 2025-12-23 14:55:07 -05:00
IDEAS.md work 2025-11-12 13:09:15 -05:00
LICENSE.md Start porting from jss 2025-09-24 21:48:14 -04:00
README.md docs 2025-12-06 16:15:53 -05:00
run_test_suite refactor, move away from single header file libs 2025-12-20 13:33:36 -05:00
THIRD_PARTY_NOTICE.md change static hash map nomenclature 2025-12-16 13:53:06 -05:00

not finished yet

Jack's Standard Library

A collection of single header file libraries designed to replace usage of the C Standard Library with more modern, safe, and simple alternatives for C11/C23.

Why

See the DESIGN.md file for more info.

What's Included

Jack's Standard Library Core

jsl_core.h

  • All other libraries within this project require the core
  • Common macros
    • Target platform information, e.g. OS, ISA, pointer size, and host compiler
    • min, max, between
    • bitflag checks
    • Alias macros for different intrinsic names on different compilers
    • including portable C fallbacks for missing intrinsics on MSVC
  • A buffer type called a fat pointer
    • used everywhere
    • standardizes that pointers should carry their length
    • vastly simplifies functions like file reading
  • Common string and buffer utilities for fat pointers
    • things like fat pointer memcmp, memcpy, substring search, etc.
  • An arena allocator
    • a.k.a a monotonic, region, or bump allocator
    • They are easy to create, use, reset-able, allocators
    • Great for things with known lifetimes (which is 99% of the things you allocate)
    • See the DESIGN.md file more information
  • A snprintf replacement
    • works directly with fat pointers
    • Removes all compiler specific weirdness
  • A string builder container type

Jack's Standard Library File Utilities

jsl_files.h

  • Requires the standard library at link time, as they use OS level calls
    • Linux is the only OS to have a robust syscall API
  • Simple, cross platform file I/O
    • Intended for scripts or getting things going at the start of the project
    • In serious code, you would use I/O more tailored to your specific use case
    • e.g. atomic, package formats, async, etc.
  • Contains
    • file reading, writing, and get file size
    • mkdir
    • a fprintf replacement

Jack's Standard Library Unicode

jsl_unicode.h

WARNING On MSVC you must pass /utf-8 or else you will get incorrect code generation!

  • utf-8 to utf-16 conversion
  • utf-16 to utf-8 conversion

Jack's Standard Library Templates

cli/

  • Type safe, generated containers
  • Unlike a lot of C containers, these are built with "before compile" code generation.
  • Each container instance generates code with your value types rather than using void* plus length everywhere
  • Built with arenas in mind
  • dynamic array
  • hash map
  • hash set

What's Not Included

  • A scanf alternative for fat pointers
  • Sorting
  • Threading
  • Atomic operations
  • Date/time utilities
  • Random numbers

This is not to say these things will never be added in the future. But everything in the above list (other than date/time) is pretty situation or platform dependent. One size fits all solutions are not appropriate for things like atomics or threading.

What's Supported

Official support:

  • Standards modes C11, C17, C23
  • Windows
    • MSVC and clang
    • x86_64
    • 32 bit pointer mode supported, must have 64bit registers
  • macOS
    • gcc and clang
    • x86_64 and ARM little endian
    • 32 bit pointer mode supported, must have 64bit registers
  • Linux
    • gcc and clang
    • x86_64 and ARM little endian
    • 32 bit pointer mode supported, must have 64bit registers
  • WebAssembly
    • clang and emscripten
    • WASM32

This might work on other POSIX systems with other C compilers, but I have not tested it. This will not work on other compilers on Windows without edits.

Usage

  1. Copy the jacks_standard_library.h file into your repo
  2. Include the header like normally in each source file:
#include "jacks_standard_library.h"
  1. Then, in ONE AND ONLY ONE file, do this:
#define JSL_IMPLEMENTATION
#include "jacks_standard_library.h"

This should probably be in the "main" file for your program, but it doesn't have to be. You can also define an empty .c file with this as the only thing in it if that would more easily integrate into your build.

One note is that this library does not depend on the C standard library to be available at link time if you don't want to use it. However, it does require the "compile time" headers stddef.h, stdint.h, and stdbool.h (if using < C23). You'll also have to define the replacement functions for the C standard library functions like assert and memcmp. See the "Preprocessor Switches" section for more information.

Note On Compile Flags

In an attempt to be as compatible with as many projects as possible, these libraries are verified with a very strict warning subset and with many clang/gcc runtime sanitizers.

The following shows the most restrictive, verified set of flags tested for each compiler.

MSVC:

/W4 /WX /std:c11

clang:

-std=c11 -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wconditional-uninitialized -Wcomma -Widiomatic-parentheses -Wpointer-arith -Wassign-enum -Wswitch-enum -Wimplicit-fallthrough -Wnull-dereference -Wmissing-prototypes -Wundef -pedantic -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=undefined -fsanitize=pointer-compare,pointer-subtract -fsanitize=alignment -fsanitize=unreachable,return -fsanitize=signed-integer-overflow,shift,shift-base,shift-exponent -fno-sanitize-recover=all

gcc:


Testing

Each test file is compiled and run many times. For example, Clang is used to build once with sanitizers and once optimized, same with GCC. This may seem excessive but I've caught bugs with this before.

Dependencies

On windows, you will need Visual Studio, clang, and wasmtime. You need to have cl.exe, clang, and wasmtime available in the path.

On POSIX systems you will need gcc, clang, and wasmtime. You need to have gcc, clang, and wasmtime available in the path.

Running

This file runs the test suite using a meta-program style of build system. You need to bootstrap the executable first.

On POSIX

cc -o run_test_suite ./tests/bin/run_test_suite.c 

On Windows

cl /Fe"run_test_suite.exe" tests\\bin\\run_test_suite.c 

Then run your executable. Every time afterwards when you run the test program it will check if there have been changes to the test file. If there have been it will rebuild itself using the command you used to build it in the first place.

Caveats

ARM

This library is slow for ARM as I haven't gotten around to writing the NEON versions of the SIMD code for many of the functions. glibc will be significantly faster for comparable operations.

AVX512

I don't own a AVX512 compatible CPU, currently. So everything is written for AVX2 on x64.

Notes on Safety

In 99% of cases you shouldn't turn off assertions by using the NDEBUG macro or by defining an empty JSL_ASSERT function.

This library uses assertions for things like Automatic Bounds Checking (ABC). These checks prevent your program from entering an invalid state which may corrupt user data, leak memory, or allow buffer overflow attacks.

It is far, far better to crash the program rather than allow these things to happen. Obviously in a perfect world programmers would never allow a bug which could lead to a ABC assertion. But we cannot rely on perfection.

The main purported reason for turning off assertions or ABC is performance. This is "fake optimization" most of the time, i.e. following a dogma rather than using a profiler to see if an assertion is a noticeable cost in a critical path. Even if an assertion is dropping speed in a hot path, think long and hard about how bad a 20% performance loss is vs the possibility of leaking user data.

Unicode

You should have a basic knowledge of Unicode semantics before using this library. For example, this library provides length based comparison functions like jsl_fatptr_memory_compare. This function provides byte by byte comparison; if you know enough about Unicode, you should know why this is error prone for determining two string's equality.

If you don't, you should learn the following terms:

  • Code unit
  • Code point
  • Grapheme
  • How those three things are completely different from each other
  • Normalization

That would be the bare minimum needed to not shoot yourself in the foot.