A Modern, Modular C++20 Toolkit for High-Performance Generic Programming — Featuring POD Utilities, Immutable Structures, Coroutine Generators, Concept-Driven Abstractions, and Lightweight Object Pools.
JH Toolkit 1.3.1
introduces targeted enhancements to the POD system, along with early preparations for Conan
packaging via GitHub CI.
- ✅
pod::string_view
: Now supports selectable hash algorithms viahash(jh::utils::hash_fn::c_hash)
, while keeping API and default behavior unchanged (fnv1a64
). - 🆕
pod::bytes_view
: Adds a.hash(...)
method with the same selectable hash algorithm support.
enum class c_hash : std::uint8_t {
fnv1a64 = 0, // default
fnv1_64 = 1,
djb2 = 2,
sdbm = 3
};
- The hash value is computed purely from raw byte content, ignoring type semantics.
- If
data == nullptr
or an invalid enum is provided, the return value is-1
.
💡 These changes make hash computation more flexible while maintaining full backward compatibility.
Conan packages are now distributed as .tar.gz
archives attached to GitHub Release Assets.
Available (v1.3.1):
- 🧩
jh-toolkit-pod
— Header-only (platform independent) - 🛠️
jh-toolkit
— Full builds for:- Linux x86_64
- macOS ARM64
- ✅ Conan 2.x is used, with modern profile support and CMake toolchains.
- 📦 GitHub Packages is not used, as it does not support Conan 2.x.
- Conan 1.x is still supported, but only under organization-owned repositories.
- This limits its functionality and long-term maintainability.
- ⛔ We do not use Conan 1.x due to lack of features and security limitations.
- ❌ Windows builds are excluded, since Conan 2.x on MSYS2/UCRT64 incorrectly injects MSVC dependencies.
- 🚫 Linux ARM64 builds are skipped in CI, due to lack of native runner or fully working QEMU + Docker setup on GitHub-hosted agents.
⚙️ All
.tar.gz
packages are compiled and archived via GitHub CI during each tagged release.
They’re ideal for CI/CD environments or machines matching the same OS + compiler configuration.
Package Name | Platform Dependent | Compiler Dependent | Description |
---|---|---|---|
jh-toolkit-pod |
❌ | ❌ | Header-only, platform-agnostic POD module |
jh-toolkit-linux-x86_64 |
✅ | ✅ (GCC 12+) | Built on ubuntu-latest , GCC toolchain |
jh-toolkit-macos-arm64 |
✅ | ✅ (Clang 16+) | Built on macos-latest , Homebrew LLVM |
- ✅ Fast setup for automation and testing pipelines
- ✅ Consistent behavior across CI and release environments
- ✅ Perfect for pre-baked CI runners, offline machines, or mirrored artifacts
# Download from GitHub Releases
wget https://github.com/JeongHan-Bae/JH-Toolkit/releases/download/JH-Toolkit-1.3.1/jh-toolkit-linux-x86_64-1.3.1.tar.gz
# Inject into local Conan 2.x cache
mkdir -p ~/.conan2/p/jh-toolkit
tar -xzf jh-toolkit-linux-x86_64-1.3.1.tar.gz -C ~/.conan2/p/jh-toolkit
🔍 Inspect cache layout using
conan list
orconan cache path
If your environment differs from our CI presets, you can still build from source 📥 — always tailored to your toolchain.
- C++20 (mandatory)
- CMake 3.14+ (for library usage)
- CMake 3.20+ (for full compilation and installation)
- Git (required for Debug mode builds)
- A modern C++20 compiler
✅ CI-tested and recommended toolchains:
Platform | Recommended Compiler | Notes |
---|---|---|
Linux | GCC 12+ | CI uses ubuntu-latest with GCC 12 |
macOS | Apple Clang 16+ (Xcode 15.3+) or LLVM Clang 16+ via Homebrew |
Use Homebrew LLVM if your Xcode version is older |
Windows | MSYS2 UCRT64 (GCC 13+) | Older mingw64 may lack support for std::ranges ; use ucrt64 to ensure correctness |
jh-toolkit
depends on full support for:std::ranges::subrange
,views
concepts
,requires
constraints- coroutine features (
co_yield
,co_return
) - aggregate initialization across POD inheritance
- ✅ Minimum supported versions:
- GCC 11+
- Clang 15+
- ✅ CI-tested:
- GCC 12+
- LLVM Clang 15+ (macOS)
- MSYS2 UCRT64 GCC 13+ (Windows)
-
MSVC (Microsoft Visual C++)
Compilation with MSVC is explicitly prohibited.
Any MSVC toolchain will trigger a hard error viainclude/jh/utils/platform.h
:🛑 Why?
- Incomplete support for C++20
concepts
,ranges
, and coroutine semantics - Unstable
SFINAE
and template constraints - ABI and STL inconsistencies across versions
✅ Alternatives:
- MSYS2 (UCRT64) with GCC
- WSL2 + Ubuntu GCC
- MINGW-Clang for Windows
- Incomplete support for C++20
- JH Toolkit does not support 32-bit platforms (e.g., x86, ARMv7).
- A hard
static_assert(sizeof(std::size_t) == 8)
check will prevent compilation on such targets. - This guarantees ABI consistency and avoids silent miscompilation from fake
-m64
flags or macro spoofing.
- Native Windows ARM64 toolchains (e.g., MSYS2
mingw64
orclang64
for ARM64) are not fully supported. - They often lack required
std::ranges
and concept resolution features. - ✅ Recommended:
- Use WSL2 + Ubuntu + GCC for reliable ARM64 builds on Windows
- Or cross-compile from a known-good x86_64 Linux system
- Older
mingw64
toolchains (e.g., GitHub runners, system MinGW) lack full support forstd::ranges
,concepts
, and coroutine semantics.- ✅ However,
jh::pod
modules are fully supported even on older MinGW variants.- ✅ If you're only using
jh-toolkit
as a header-only POD utility, then any modern C++20-capable MinGW will work.
✅ Toolchains bundled with modern environments like CLion, MSYS2, or VSCode + MSYS2 typically ship with GCC 12+ or 13+, and are fully compatible.
🛠 For full module support (
generator
,immutable_str
,views
,pool
, etc.), we recommend:
pacman -Syu
pacman -S --needed mingw-w64-ucrt-x86_64-toolchain
Ensure your project explicitly enables C++20, otherwise jh-toolkit
will not compile:
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
❌ JH Toolkit is not intended for embedded systems or constrained environments. Internals are optimized for 64-bit environments with modern allocators and cache alignment.
✅ For Android/iOS, use
add_subdirectory(jh-toolkit)
for tight ABI control — avoid usingfind_package()
for mobile builds; prefer manual inclusion.
📦 You may embed source directly and limit to
jh::pod
for ultra-minimal use cases.
If you can't use CMake 3.20+
, you can still:
- Include source directly in your CMake tree
- Use
#include "jh/..."
- Link individual
.cpp
manually (non-header-only modules)
✅ Local embedding works reliably on:
- Linux/macOS desktops
- CI runners
- Mobile cross-compilation
🚫 Not recommended for:
- 32-bit builds
- Bare-metal / embedded
- MSVC-based platforms
git clone https://github.com/JeongHan-Bae/jh-toolkit.git
git clone --branch 1.3.x-LTS --depth=1 https://github.com/JeongHan-Bae/jh-toolkit.git
👉 Or download from: JH Toolkit Latest LTS Release
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
sudo cmake --install build
This installs the complete jh-toolkit
:
- Provides full header sets and implementation.
- Use
jh::jh-toolkit
andjh::jh-toolkit-impl
.
Recommended on development machines or when full functionality is needed.
cmake -B build-pod -DCMAKE_BUILD_TYPE=Release -DTAR=POD
cmake --build build-pod
sudo cmake --install build-pod
This installs only the POD system:
- A lightweight, header-only C++20 template library.
- Use
jh::jh-toolkit-pod
.
Recommended for minimal deployment, embedding, or when implementation is not needed.
📖 See docs/pod.md for usage details.
You can selectively build and install specific components using:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DTAR=POD,ALL
- The
TAR
option accepts a comma-separated list of target modules to include. - Currently supported values:
POD
,ALL
- Targets are individually downloadable and usable depending on your deployment needs.
Use case examples:
Usage Context | Suggested TAR Value |
What It Builds |
---|---|---|
Minimal runtime | POD |
Header-only POD system |
Development machine | ALL |
Everything: headers + implementation |
Shared dependency | POD,ALL |
All targets available in local build |
✅
TAR=POD,ALL
makes all targets available without restricting modularity.
This allows dependent projects to only link what they need.
Build Mode | CMake Targets Available | Description |
---|---|---|
TAR=ALL (default) |
jh::jh-toolkit , jh::jh-toolkit-impl |
Full header set + implementation |
TAR=POD |
jh::jh-toolkit-pod |
Header-only POD module |
TAR=POD,ALL |
All above targets | Maximum availability, optional usage |
All modes are compatible with:
find_package(jh-toolkit REQUIRED)
Then link only the targets your project needs.
If installation is successful, you should be able to include and use jh-toolkit
in a minimal program:
#include <jh/immutable_str> // or <jh/immutable_str.h>
#include <iostream>
int main() {
auto pool = jh::pool<jh::immutable_str>();
const auto str = pool.acquire("Hello, JH Toolkit!");
std::cout << str->view() << std::endl;
return 0;
}
If this compiles and runs successfully, jh-toolkit
is correctly installed.
Add jh-toolkit
to your project:
cmake_minimum_required(VERSION 3.14)
project(my_project LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(jh-toolkit REQUIRED)
add_executable(my_project main.cpp)
target_link_libraries(my_project PRIVATE jh::jh-toolkit) # For header-only modules
target_link_libraries(my_project PRIVATE jh::jh-toolkit-impl) # For compiled components
Build and test the project using standard Debug
or performance-friendly FastDebug
modes:
cmake -B build-debug -DCMAKE_BUILD_TYPE=Debug
or
cmake -B build-debug -DCMAKE_BUILD_TYPE=FastDebug
then
cmake --build build-debug
ctest --test-dir build-debug --output-on-failure
- All unit tests are registered with
ctest
. - Most modules are mature and run limited randomized iterations (e.g., 128 rounds).
- Suitable for rapid regression checks and automation pipelines.
Mode | Optimization | Debug Info | Use Case |
---|---|---|---|
Debug | -O0 |
✅ -g |
Traditional debug builds; full symbolic debugging |
FastDebug | -O2 |
✅ -g |
Faster test execution with minimal optimization bias |
FastDebug only applies -O2 -g
and intentionally avoids more aggressive compiler behaviors:
- ❌ No
-march=native
- ❌ No auto-vectorization (
-ftree-vectorize
) - ❌ No loop unrolling (
-funroll-loops
) - ❌ No SIMD-only code paths
This ensures consistent runtime behavior and portability across CI runners or developer machines.
✅ FastDebug mode not only speeds up testing, but also helps identify bugs that only appear under compiler optimizations (e.g., undefined behavior, aliasing issues, optimization-elided side effects).
- 🧪 All modules are covered by unit tests for behavioral correctness.
- Modules like
generator
andpool
are stable but not yet micro-optimized. - Core utility types such as
immutable_str
andruntime_arr
are micro-optimized and designed for practical performance without sacrificing safety or clarity.
- Modules like
Some core modules include lightweight, embedded benchmarks in their test suites to validate real-world performance without requiring a full benchmarking framework.
- 🧪 Modules with benchmarks:
immutable_str
: A fully immutable, thread-safe string type optimized for hashing and interning.runtime_arr
: A fixed-size, non-resizable heap array with raw-layout speed and STL compatibility.
- 🧪 Modules without active benchmarks:
generator
,pool
: Stable but not micro-optimized yet.
- Benchmarks demonstrate that optimized modules are typically comparable to STL in performance.
- In specific cases, custom structures even outperform STL by reducing allocation or indirection overhead.
- Overhead remains predictable and minimal across compilers and optimization levels.
- 🚀 Run test binaries directly to view timing output (no need for
ctest
). - 📚 Module documentation includes brief benchmark context and insights.
❗ No separate
benchmark/
directory ortests/benchmark.cpp
exists; new performance testing will be added only when necessary.
- 🔧 Benchmarks, examples, and debugging tools are disabled in Release builds.
- 🚫 Install is disabled in Debug builds to prevent accidental system changes.
- 🔁 Randomized test rounds are capped (e.g. 128 iterations) for long-verified modules — ensuring reasonable CI duration without sacrificing coverage.
Modern C++20 header-only components focused on zero-cost abstraction, type safety, and performance-conscious design.
pod
— A lightweight system of POD-like value types (pod::pair
,array
,optional
,bitflags
, etc.), optimized for serialization and placement-new.sequence
— Minimal C++20 concept for forward-iterable sequences; foundation forview
operations.iterator
— Iterator detection,iterator_t<>
alias, and validation concepts (input_iterator
, etc.).views
— Lazy, allocation-free range adapters:enumerate
,zip
, and more; compatible with allsequence
s.
generator
— Coroutine-based generator/stream-style interfaces.pool
/sim_pool
— Shared pointer-based object pools with automatic deduplication.immutable_str
— ABI-stable, thread-safe immutable strings withstd::string_view
interop.
Finalized C++ types intended for immutable, compact, and semantically clear ownership.
runtime_arr
— Fixed-size, move-only runtime buffer; STL-compatible, allocator-aware, withreset_all()
for reuse.
While JH Toolkit is a modern C++20 library, its design philosophy embraces several key Pythonic principles,
making C++ development more expressive, efficient, and intuitive. These principles shape how jh-toolkit
is
structured, promoting readability, maintainability, and performance.
"If it walks like a duck and quacks like a duck, it must be a duck."
- How JH Toolkit Implements This:
jh::pool<T>
automatically detects compatible types (requiresT::hash()
andoperator==
).jh::sequence
validates immutable iteration at compile time, without requiring explicit inheritance.jh::iterator<>
concepts ensure iterators conform to expected behavior, rather than relying on inheritance.
"Better to compute only when needed than to compute everything upfront."
- How JH Toolkit Implements This:
jh::generator<T, U>
defers computation using coroutines.jh::immutable_str
delays hash computation until the firsthash()
call, avoiding unnecessary processing.jh::pool<T>
manages objects dynamically, avoiding upfront allocation.
"Memory management should be handled by the system, not by the user."
- How JH Toolkit Implements This:
jh::sim_pool<T, Hash, Eq>
usesstd::weak_ptr<T>
to automatically expire objects.jh::pool<T>
ensures memory deduplication without requiring manual object tracking.- Automatic cleanup is built into pooling mechanisms, similar to Python’s garbage collection.
"Code should be clear in its intentions and prevent implicit conversions that cause ambiguity."
- How JH Toolkit Implements This:
jh::immutable_str
prohibits implicit conversions that could lead to data races.jh::generator<T, U>
is explicitly move-only, preventing unintended copies.- Concept-based design enforces correctness at compile time.
"Code is read more often than it is written."
- How JH Toolkit Implements This:
- Encapsulates complexity into reusable, well-documented modules.
- Uses concepts to provide clear type constraints rather than relying on SFINAE.
- Promotes modularity and interoperability with standard C++20 features.
By following these Pythonic principles, JH Toolkit makes modern C++ more ergonomic, helping developers write * concise, expressive, and high-performance* code while reducing boilerplate and maintenance costs.
JH Toolkit follows snake_case
naming conventions, aligning with C++ standard library (std
) rather than the
more common camelCase
or CapitalCase
styles used by other third-party libraries. This choice is intentional and
deeply rooted in our goal of providing a seamless, toolkit-like experience for developers.
"A toolkit should feel like a natural extension of the language."
-
The C++ Standard Library (
std
) usessnake_case
for its core utilities, including:- Type traits (
std::is_same_v
,std::decay_t
) - Containers (
std::vector
,std::unordered_map
) - Iterators & Algorithms (
std::next
,std::find_if
) - Concepts in C++20 (
std::same_as
,std::convertible_to
)
- Type traits (
-
By mirroring
std
naming conventions, JH Toolkit blends naturally into the developer's codebase, reducing * cognitive overhead*.
"JH Toolkit is not just a utility collection; it's a core toolkit."
- Many third-party C++ libraries, especially frameworks, use
CamelCase
(Boost
,Qt
) orCapitalCase
(Eigen
,OpenCV
). - However, JH Toolkit is a toolkit for generic data structures and utilities, not a high-level framework.
- Using
snake_case
ensures users interact with JH Toolkit just like they do withstd
, making it feel native to modern C++ development.
"The best tools are the ones that feel like they were always there."
snake_case
improves readability when dealing with template-heavy, generic code.- Developers using JH Toolkit alongside
std
will experience a uniform interface, making it easier to:- Mix and match
std
andjh
components. - Reduce friction when integrating
jh-toolkit
into existing projects. - Lower the learning curve for new users already familiar with
std
.
- Mix and match
"Following the direction of the standard makes long-term maintenance easier."
- C++ is increasingly adopting concept-based design and modern generic programming paradigms.
- JH Toolkit embraces these trends by ensuring consistent naming conventions for concepts, iterators, and utilities.
- By aligning with
std
, JH Toolkit remains future-proof and less likely to require adaptation when integrating with new standard features.
Developed by JeongHan-Bae
📧 [email protected]
🔗 GitHub Profile
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
Contributions are welcome! Feel free to open issues and pull requests to enhance the library.
🚀 Enjoy coding with jh-toolkit
!