-
A simple fully header-only lib for C++ to make your code sesion fells fun and kinda more Python-y feel. This lib in inteded for simple libs and everyday coding, not for big/enteprise project on that actually matter on you life or money.
This project is entirely in C++, if you see like LLVM IR and Assembly on the github page, don't worry, it's just a testings and WON'T be included in instalation package, also those are generated with
clang++ -S -emit-llvmandclang++ -S. -
I have to admit, like 80% of those codes are AI-generated, if you find any flaw, please tell me on issues or you can submit you code on issues or you can fork on your own :D
-
Better markdown for this documentation is typed using Notion.so here (under construction)
-
Files What is this? Tools/Casting.hppType Casting aliases Tools/Clock.hppTime & Clock utilities Tools/Edges.hppMin/max getter for types Tools/Files.hppI/O files utility Tools/FormatNumber.hppNumber formatter Tools/IVec.hpp"Improved Vector", custom made container Tools/Linking.hppLinking utility to dynamic linked (.dll) using windows API Tools/OS.hppSome utilities using OS APIs Tools/Random.hppRandom Number generator Tools/RandomHW.hppHardware-level random generator (x86 only) Tools/Randomizer.hppStuff to make random number (used by Random and RandomHW) Tools/Rounding.hppPython-like rounding utility Tools/Style.hppText styler for str Tools/StyleW.hppText styler for wstr Tools/Types.hppType aliases Tools/Vector.hppPyhton-like functions for vector Tools/VectorSlice.hppVector slicing function Tools/OS.hppOS (Windows, Linux, and MacOS) API utility Tools/Version.hppVersion infos of this library -
Folder What is this? Tools/Deprecated/*Deprecated libs, because it'll break you project instead making coding more fun and productive++ Tools/IVec/*Improved vector implementations Tools/OS/*Some utilities using OS APIs implementations Tools/Random/*Random number implementations Tools/RandomHW/*Hardware-level random number implementations Tools/Types/*Types aliased "concept" + "using" implementations Tools/Vector/*Common operations for Vector implementations -
Files What is this? /Types/Types.clock.hppClocks & Units aliases /Types/Types.containers.hppContainers aliases /Types/Types.int.hppSigned interger aliases /Types/Types.uint.hppUnsigned integer aliases /Types/Types.float.hppFloating aliases /Types/Types.ptr.hppPointer aliases (not recommended) /Types/Types.string.hppString type aliases /Types/Types.memory.hppSmart pointer aliases -
File What is this? /IVec/IVec.hppAll include packed /IVec/IVecfmt.hppFormatter for {fmt} [deprecated, this thing has already iterators] /IVec/IVec_c.base.hppBase IVec class /IVec/IVec_c.init.hppInitializers for IVec /IVec/IVec_c.basic.hppMinimal functions /IVec/IVec_c.advanced.hppExtended functions /IVec/IVec_c.convert.hppConversion utilities to something else /IVec/IVec_c.data.hppReturn pointer data /IVec/IVec_c.getset.hppGetter and setter functions /IVec/IVec_c.iter.hppIterators functions /IVec/IVec_c.legacy.hppLegacy functions with vector-like dictions -
File What is this? /OS/{OS}.API.hppAll APIs wrapped /OS/{OS}.files.hppI/O + manage Files /OS/{OS}.proc.hppI/O to Processes /OS/{OS}.sleep.hppOS-level sleep /OS/{OS}.terminal.hppTerminal size, celar, etc -
File What is this? /Random/Random.common.hppInternal utility for other files /Random/Random.single.hppSingle number generator /Random/Random.vector.hppGenerator for std::vector<>/Random/Random.bundle.hppGenerator for std::vector<std::vector<>>/Random/Random.sbundle.hppJust like bundle, but every sub-vector's size are different -
Just like
Tools.Random, butTwister32&Twister64are initialized on single number generator. Sovector,bundle, andsbundleare repeated use ofsingle, which is not a good practice of use.File What is this? /Random.Basic/Random.basic.hppSame as Tools.Random/Random.Basic/Random.common.basic.hppSame as Tools.Random.Common/Random.Basic/Random.single.basic.hppSame as Tools.Random.Single/Random.Basic/Random.vector.basic.hppSame as Tools.Random.Vector/Random.Basic/Random.bundle.basic.hppSame as Tools.Random.Bundle/Random.Basic/Random.sbundle.basic.hppSame as Tools.Random.SBundle -
Just like
Tools.Random, but optimized for x86 command calledRDSEEDandRDRANDFile What is this? /RandomHW/RandomHW.common.hppSingle number HW generator /RandomHW/RandomHW.single.hppGenerator for std::vector<std::vector<>>/RandomHW/RandomHW.vector.hppJust like bundle, but every sub-vector's size are different/RandomHW/RandomHW.bundle.hppInternal utility for other files /RandomHW/RandomHW.sbundle.hppGenerator for std::vector<> -
File What is this? /Vector/Vector.accumulator.hppAccumulate vector values, like Summation, Product, and Average /Vector/Vector.find.hppFind value and/or index in a vector utilities /Vector/Vector.order.hppValue order utilities and return new vector /Vector/Vector.order.inl.hppValue order utilities and do it inplace /Vector/Vector.slice.hppScissors for vector, 0->nor0<-norx<->y, then return new vector/Vector/Vector.slice.inl.hppScissors for vector, and do it inplace -
This lib but make it linkable, this is NOT included in msys package pack (in folder
/Msys/*.pkg.tar.zst) and NOT installed in your/libfolder in you environment, so in deployment, this lib is STILL header only. Kinda stupid, because I compile the.hppfile instead of.cppfile.File What is this? Tools.Processed.win.hppA preprocessed Tools.hppfile, you may can use this as super poratable header-file, but I don't think you shouldTools.Processed.win.oCompiled object of ToolsProcessed.hpplibTools.aPacked with ar rcsofTools.ofile...And some other files that can describe itself from it's file name
Types aliasing to make you less typing just for data types
| Original | Aliased | Original | Aliased | Original | Aliased |
|---|---|---|---|---|---|
int8_t |
i8 |
uint8_t |
u8 |
float |
f32 |
int16_t |
i16 |
uint16_t |
u16 |
double |
f64 |
int32_t |
i32 |
uint32_t |
u32 |
long double |
fld |
int64_t |
i64 |
uint64_t |
u64 |
||
ssize_t |
sidx |
size_t |
idx |
| Original | Aliased | Original | Aliased |
|---|---|---|---|
const char* |
cstr |
std::string |
str |
const char16_t* |
cstr16 |
std::wstring |
wstr |
const char32_t* |
cstr32 |
std::u16string |
str16 |
std::u32string |
str32 |
||
std::string_view |
strview |
||
std::stringstream |
sstream |
||
std::ostringstream |
ostream |
| Original | Aliased |
|---|---|
std::vector<T> |
vec<T> |
std::array<T, idx> |
arr<T, idx> |
std::map<K, V> |
map<K, V> |
std::unordered_map<K, V> |
umap<K, V> |
std::set<T> |
set<T> |
std::unordered_set<T> |
uset<T> |
std::pair<K, V> |
pair<K, V> |
std::initializer_list<T> |
initl<T> |
std::span<T> |
span<T> |
std::tuple<T...> |
tuple<T...> |
std::list<T> |
list<T> |
| Original | Aliased |
|---|---|
std::optional<T> |
topt<T> |
std::variant<T...> |
tvar<T...> |
std::expected<A, B> |
texp<A, B> |
Another type alias that you and I may not use often
| Name | Original | Aliased |
|---|---|---|
| Pointer to data | T* |
ptr<T> |
| Pointer to constant data | const T* |
ptrcd<T> |
| Constant pointer to data | T const* |
cptr<T> |
| Constant pointer to constant data | const T *const |
cptrcd<T> |
| Original | Aliased |
|---|---|
std::unique_ptr<T> |
uptr<T> |
std::shared_ptr<T> |
sptr<T> |
std::weak_ptr<T> |
wptr<T> |
| Original | Aliased |
|---|---|
std::chrono::time_point<std::chrono::high_resolution_clock> |
HClock |
std::chrono::time_point<std::chrono::steady_clock> |
SClock |
HClock |
Clock |
| Concept | Types convered |
|---|---|
Nx32 |
i32, f32 |
Nx64 |
i64, f64 |
Int |
i8, i16, i32, i64 |
CInt |
i32, i64 |
UInt |
u8, u16, u32, u64 |
CUInt |
u32, u64 |
Float |
f32, f64, fld |
CFloat |
f32, f64 |
CSize |
idx, sidx |
Integer |
Int + UInt |
CNumber |
CInt + CUInt + CFloat + CSize |
CTypes |
CInt + CUInt + CFloat + Strings |
Numbers |
Int + UInt + Float + CSize |
Strings |
str, cstr |
WStrings |
wstr, cwstr |
Iterable |
std::ranges::range<T> |
An example of implementation:
template <Numbers T>
void CheckRange(T& min, T& max) {
if (max < min) std::swap(min, max);
}This will check given bounds, and swap them if min is bigger than max
-
This is just aliases for
static_,dynamic_,const_,reintepret_, andany_cast, because using 2 words for me looks like too verbose. -
namespace Tools::Cast { template <typename To, typename From> constexpr To scast(From&& value) noexcept; template <typename To, typename From> To dcast(From&& value); template <typename To, typename From> constexpr To ccast(From&& value) noexcept; template <typename To, typename From> constexpr To rcast(From&& value) noexcept; template <typename To> To acast(const std::any& a); template <typename To, typename From> constexpr To cast(From&& value); }
-
- Compile time conversion
- Can be evaluated on compile-time if you use constexpr
- Zero runtime overhead
-
- Numeric conversion
- Upcast/downcast non-polymorphic
-
- Runtime castings
-
- ONLY for pointers and references
- Needs RTTI
- Runtime-only (not constexpr compatible) Used for:
- Downcast polymorphic which needs runtime checking
-
- Deletes/adds qualifier "const"
- Not changing base type
-
- Deleting const from absolute const object will cause Undefined Behaviour
-
- Bit-level cast
- Most dangerous
- Always for last resort
-
- You don't know memory layout
- No other safe alternatives
-
- Runtime checked
- Will throw std::bad_any_cast if type is wrong/bad
-
- Default to static_cast
- Not trying to be smart Note:
- This Function is intended to be simple
- If you need RTTI / const removal / bit cast, use
scast/dcast/ccast/rcast
-
Should've named "limits", but I pick "Edges" just because people won't confuse
<limits>andTools.Limits, soTools.Edgeswere chosen. -
#pragma once #include <limits> // Macro shortcut #define GET_MAX(T) std::numeric_limits<T>::max() #define GET_MIN(T) std::numeric_limits<T>::min() namespace Tools::Edge { template <typename T> T GetMax(); template <typename T> T GetMin() }
GetMax<T> : To get max value of given types
GetMin<T> : To get min value of given types
code:
namespace Tools::Files {
/* -------- String -------- */
str ReadFile(const str& File);
void WriteFile(const str& File, const str& Content);
/* ---- C-style string ---- */
cstr ReadFileC(const str& File);
void WriteFileC(const str& File, cstr& Content);
/* ------ Wide String ------ */
wstr ReadFileW(const str& File);
void WriteFileW(const str& File, const wstr& Content);
}ReadFile: To read file from specified path and return content
WriteFile: To read write to specified path with given content
Suffixes:
-C : C-style string (const char*)
-W : Wide string (wstr/std::wstring)
code:
namespace Tools::FormatNumber {
/* Defaults */
template <Integer T>
str Format(const T n)
template <Float T>
str Format(const T n)
/* Customs */
template <Integer T>
str Format(const T n, Char Separator, const i32 Digits);
template <Float T>
str Format(const T n, Char Separator, const i32 Digits);
template <Float T>
str Format(const T n, Char Separator, Char Decimal, const i32 Digits);
}Parameters for 1st and 2nd functions:
T n: The number
Char Seperator: The seperator
const i32 Digits: Digis for seperation
- Seperator between N digits this is because not every country use the same formatting.
- In Europe, we use dot (.) for thousands, and comma for decimal (,), and the opposite in the US and around it.
- Some EU countries even use space for thousands seperator, usually around France or Scandinavia.
-
€1.000,50or€1 000,50in C will be1000.50$1,000.50in C will be1000.50
-
Format(314217)will return314'217Format(314217, '\'', 3)will return314'217Format(3142.17, '\'', 3)will return3'142.17Format(3142.17, '@', 2)will return31@42.17
The 3rd function has the Char Decimal, indicates you can custom character for decimals.
Example:
Format(3142.17)will return3'142,17Format(3142.17, ' ', ',', 3)will return3 142,17
IVec or "Improved Vector" is a container just like std::vector, but with better choice of diction, for example: push_back is now append (just like Python).
All description is already in IVec/IVec_c.base.hpp, descriptions are intentionally made short and simple, so even beginners can understand it.
-
template <typename T> class ivec { private: T* ivec_data; /** Helper **/ inline idx Normalize(i64 i) ; idx ivec_size; idx ivec_capacity; public: /** Data features **/ T* data(); idx size(); idx capacity(); /** Init features **/ // Default constructor ivec(); // Constructors ivec(const initl<T> Data); ivec(const vec<T>& Data); ivec(const ivec& other); ivec(ivec&& other); // DeConstructors ~ivec(); /** Basic Functions **/ void reserve(const idx Size); void resize(const idx Size, const T& fill = T{}); void append(const T& Element); void append(const T&& Element); void append(const ivec<T>& iv); void append(const vec<T>& v); void extend(const ivec<T>& v); void extend(const vec<T>& v); idx GetSize() const noexcept; /** Getter and setter **/ T pop(const idx& Index); T& operator[](idx Index); const T& operator[](idx Index) const; ivec<T>& operator=(const ivec& Other); /** Advanced **/ void sliceInl(i64 x, i64 y); void sliceIln(i64 n); ivec<T> slice(i64 x, i64 y); ivec<T> slice(i64 n); void clear(); bool isEmpty(); void appendFirst(const T& Element); void appendAt(const T& Element, idx At); bool contains(const T& Element); idx find(const T& Element); idx findFreq(const T& Element); pair<idx, vec<T>> findAll(const T& Element); /* Orders */ ivec<T> shuffle(); void shuffleInl(); ivec<T> sort(); void sortInl(); ivec<T> rsort(); void rsortInl(); ivec<T> reverse(); void reverseInl(); ivec<T> erase(T* pos); void eraseInl(T* pos); ivec<T> erase(T* begin, T* end); void eraseInl(T* begin, T* end); ivec<T> uniques(idx n = 1); void uniquesInl(idx n = 1); T popFirst(); T popLast(); u64 memory(); template<typename... Args> void emplace(Args&&... args); template<typename... Args> void emplaceFront(Args&&... args); template<typename... Args> void emplaceAt(Args&&... args, idx n); str fstr(); /** Iterators **/ T first(); T front(); T* begin(); const T* cbegin(); T& refbegin(); T last(); T back(); T* end(); const T* cend(); T& refend(); /** Conversion **/ vec<T> toVector(); span<T> toSpan(); template <idx S> arr<T, S> toArray(); T* toCArr(); /* Legacy functions */ void push_back(const T& Element); void push_front(const T& Element); T at(const idx Index); void insert(const ivec<T>& v); void insert(const vec<T>& v); void insert(const T& Element, idx At); void insert(const T* A, const T* B); };
Yes, the function name can already tell itself what are they doing. But here's the breakdown if you want it anyway
Let's start with the private functions
ivec_dataCurrent arrayivec_sizeCurrent sizeivec_capacityCurrent capacityNormalizeNormalizeri64toidx
And then public, we have a lot of sections
-
data()returns current array (raw, C-Style array) -
size()returns current size -
capacity()return current capacityIf you think size is the same as capacity, then no, size is current element count, capacity is current element count + reserved slots. So size and capacity will not alway be the same.
ivec();The default constructor with nothing in itivec(const initl<T> Data);Constructor to makeivec a{1.68, 2.71, 3.14}possibleivec(const vec<T>& Data);Constructor to auto convertstd::vectortoTools::ivecivec(const ivec& other);Same as 3rd constructor but used to copy other ivecivec(ivec&& other);Same as 4th but you write it inplace
~ivec()to remove everything
-
void reserve(const idx Size);Reserve slots, this can reduce runtime because it calls thesyscallonce -
void resize(const idx Size, const T& fill = T{});Resizesizeand fill it with 1 specified value -
void append(const T& Element);Push elements to back -
void append(const T&& Element);Push elements to back by rvalue -
void append(const ivec<T>& iv);Appendivecto currentivec, exampleivec{1, 2, 3}.append(ivec{4, 5, 6})will resultivec a{1, 2, 3, ivec{4, 5, 6}} -
void append(const vec<T>& v);Appendvecto currentivec, example is same as 11th -
void extend(const ivec<T>& v);Extend withivecto currentivec, exampleivec a{1, 2, 3}.extend(ivec{4, 5, 6})will resultivec a{1, 2, 3, 4, 5, 6} -
void extend(const vec<T>& v);Extend withvecto currentivec, example is the same as 13th -
idx GetSize() const noexcept;Basically same asstd::vector<T>::size()andTools::ivec<T>::size()
T pop(const idx& Index);To get and remove immediately selected indexT& operator[](idx Index);To get selected index with the[]thingconst T& operator[](idx Index) const;Same as before, but make it constantivec<T>& operator=(const ivec& Other);Setter to selected index
Default function is return new, suffix -
Inlindicates inline
-
void sliceInl(i64 x, i64 y);Slice inlinely from rangex..y -
void sliceInl(i64 n);Slice0..norn..Size. Positive will iterate from 0 ton(forward), negative will iterate fromivec_sizeton(backward) -
ivec<T> slice(i64 x, i64 y);Same as 20, but return new ivec -
ivec<T> slice(i64 n);Same as 21, but return new ivec -
void clear();To nuke everything inside -
bool isEmpty();Check is this thing is empty or no -
void appendFirst(const T& Element);Append an element at 1st index -
void appendAt(const T& Element, idx At);Append an element at specified index -
bool contains(const T& Element);Check if this ivec contains specific Element -
idx find(const T& Element);Find index of an element -
idx findFreq(const T& Element);Find frequency of selected element -
pair<idx, vec<T>> findAll(const T& Element);Find an element and check in which indexes appeared
-
ivec<T> shuffle();Shuffle current ivec, then return new -
void shuffleInl();Shuffle current ivec inlinely -
ivec<T> sort();Sort current ivec, then return new -
void sortInl();Sort current ivec inlinely -
ivec<T> rsort();Sort, then reverse current ivec, then return new -
void rsortInl();Sort, then reverse current ivec inlinely -
ivec<T> reverse();Reverse current ivec, then return new -
void reverseInl();Reverse current ivec inlinely -
ivec<T> erase(idx pos);(*) Erase specific position (unlike pop, this one is not return selected index(es)), then return new -
void eraseInl(idx pos);(*) Erase specific position inlinely -
ivec<T> erase(idx begin, idx end);(*) Erase specific range, then return new -
void eraseInl(idx begin, idx end);(*) Erase specific range inlinely -
ivec<T> uniques(idx n = 1);Make elements appeared maximumntimes, then return new;n=1means everything only appear once -
void uniquesInl(idx n = 1);Make elements appeared maximumntimes inlinely -
T popFirst();Get index 0 and remove immediately -
T popLast();Get index last and remove immidiately -
u64 memory();Get total memory used for current array -
void emplace(Args&&... args);Build object in array on-fly at last index -
void emplaceFront(Args&&... args);Build object in array on-fly at first index -
void emplaceAt(Args&&... args, idx n);Build object in array on-fly at specific indexsliceanderasemight be simmilar, but it's different! Example:ivec<i32> a{11, 12, 13, 14, 15, 16, 17, 18, 19, 110}; // Keep only a[1..4], delete everything else ivec<i32> a_s = a.slice(1, 4); // [12, 13, 14, 15] fmt::println("{}", a_s); // Delete only a[1..4], keep everything else ivec<i32> a_e = a.erase(1, 5); // [11, 16, 17, 18, 19, 110] fmt::println("{}", a_e);
ㅤ
str fstr();Formatted STRing, make everything everything inside and (almost) every data type into a stringvec<T> toVector();ivectostd::vectorconverterspan<T> toSpan();ivectostd::spanconverterarr<T, S> toArray();ivectostd::arrayconverterT* toCArr();ivecto raw pointer converter
-
T first();First index getter -
T first(idx n);First + n index getter -
T front();First index getter (legacy choise of diction) -
T* begin();First index iterator -
const T* cbeginConstant first index iterator -
T& refbegin();Reference of first index iterator -
T last();Last index getter -
T last(idx n);Last - n index getter -
T back();Last index getter (legacy choise of diction) -
T* end();Last index iterator -
const T* cend();Constant last index iterator -
T& refend();Reference of last index iterator
This one is to make renaming vec to ivec possible without breaking current vec codes, but only some, not everything.
-
void push_back(const T& Element);The same asstd::vector<T>::push_back -
void push_front(const T& Element);Not standard from STL, but STL-isch choise of diction -
T at(const idx Index);Specific index getter, I have absolutely zero why.ateven exist, but oké -
ivec<T> erase(T* pos);Specific index eraser with iterator, then return new -
void eraseInl(T* pos);Specific index eraser with iterator inlinely -
ivec<T> erase(T* begin, T* end);Range eraser with iterator, then return new -
void eraseInl(T* begin, T* end);Range erasee with iterator inlinely -
void insert(const ivec<T>& v);Extender like fromstd::range::insertspecificly forivec -
void insert(const vec<T>& v);Extender like fromstd::range::insertspecificly forstd::vector -
void insert(const T& Element, idx At);Append to specific index -
void insert(const T* A, const T* B);Extender like fromstd::vector<T>::insertwith iterators, yes, you can extend current container from other containerserasefunctions fromadvancedare the wrapper fromlegacy
ㅤ
This is a windows-specific tool to call a .dll during runtime.
-
namespace Tools::Linking { str GetFile( const str& File /* Base name of the .dll*/ ); T LoadSymbol( const HMODULE lib, /* File to be loaded */ const str& EntryPoint /* Entry point */ ); // Call function in .dll with any args template<typename Return, typename... Args> Return CallFunction( /* Function I */ str File, /* File to find */ str EntryPoint, /* Function to find (disable magle!) */ Args... args /* Args */ ); // Call dll with str msg void CallFunctionA( /* Function II */ str& File, /* File to find */ const str& Msg, /* Message to forward (str) */ const str& EntryPoint, /* Function to call (disable magle!) */ const int TerminalSize = 50, /* Optional Terminal size */ const bool debug = true /* Optional Debugging log */ ); // Call DLL with wstr void CallFunctionAW( /* Function II */ str& File, /* File to find */ const wstr& MsgW, /* Message to forward (wstr) */ const str& EntryPoint, /* Function to call (auto mangle on main.cpp) */ const int TerminalSize = 50, /* Optional Terminal size */ const bool debug = true /* Optional Debugging log */ ); // Call dll without any args void CallFunctionB( /* Function III */ str& File, /* File to find */ const str& EntryPoint, /* Function to call (disable magle!) */ const int TerminalSize = 50, /* Optional Terminal size */ const bool debug = true /* Optional Debugging log */ ); // Call dll file with C-like args (int argc, const char** argv) int CallFunctionC( /* Function IV A */ str& File, /* File to find */ const str& EntryPoint, /* Function to call (disable magle!) */ // const int Argc /* C argc, not really necessary */ // const char** Argv, /* C argv, not really safe, mismatch can lead to crash */ const vec<str> Args, /* C argv (+argc), but safer */ const int TerminalSize = 50, /* Optional Terminal size */ const bool debug = true /* Optional Debugging log */ ); // Slightly safer CallFunctionC int CallFunctionC_s( /* Function IV B */ const str& File, /* File to find */ const str& EntryPoint, /* Finnction to call (disable magle!) */ const vec<str>& Args, /* C Argv in vector */ int TerminalSize = 50, /* Optional Terminal size */ bool debug = true /* Optional Debugging log */ ); #if defined(ITANIUM_ENABLED) template <typename T> str RemoveSignature( const str& Func, /* Mangled function name with itanium format */ bool WithArgs = true /* Include args or not*/ ); #endif }
-
str GetFile( const str& File );
-
Resolves and returns the DLL file path based on the given base name.
-
File — Base name of the .dll file (e.g. "Test.dll")
-
Resolved file path as str
-
- Intended for internal path normalization
- Can be extended to support custom search directories
-
str File = GetFile("DynamicLib"); fmt::println("file {}", File); // DynamicLib.dll
-
T LoadSymbol( const HMODULE lib, const str& EntryPoint );
-
Loads a function symbol (entry point) from a previously loaded DLL module.
-
lib — Handle returned by LoadLibrary EntryPoint — Exported function name (must match exactly)
-
Function pointer of type T
-
Warning
⚠️ - Incorrect function signature casting will cause undefined behavior or crashes.
- Used internally only
-
template<typename Return, typename... Args> Return CallFunction( str File, str EntryPoint, Args... args );
-
Fully generic function caller for DLL exports with arbitrary arguments and return type.
-
File— Target DLL fileEntryPoint— Function name (mangling must be disabled with extern "C")Args...— Arguments forwarded to the function
-
Function return value of type Return
-
int result = Tools::Linking::CallFunction<int>( "Math.dll", "Add", 5, 3 ); fmt::prinln("5 + 3 = {}", result); // 8
-
void CallFunctionA( str& File, const str& Msg, const str& EntryPoint, const int TerminalSize = 50, const bool debug = true );
-
Calls a DLL function that accepts a narrow string (std::string / char*) message.
-
File— Target DLL fileMsg— Message forwarded to DLLEntryPoint— Exported function nameTerminalSize— Optional formatting/log widthdebug— Enables debug output
Recommended DLL Signature generation
cpp extern "C" void MyFunction(const char* msg);
-
void CallFunctionAW( str& File, const wstr& MsgW, const str& EntryPoint, const int TerminalSize = 50, const bool debug = true );
-
Wide-character version of CallFunctionA, designed for Unicode-safe messaging.
-
Recommended DLL Signature
extern "C" void MyFunction(const wchar_t* msg); -
- Useful for UTF-16 Windows APIs
- Avoids encoding mismatch issues
-
void CallFunctionB( str& File, const str& EntryPoint, const int TerminalSize = 50, const bool debug = true );
-
- Calls a DLL function that takes no parameters.
-
extern "C" void Init();
-
Tools::Linking::CallFunctionB( "Plugin.dll", "Init" );
-
int CallFunctionC( str& File, const str& EntryPoint, const vec<str> Args, const int TerminalSize = 50, const bool debug = true );
-
- Simulates int main(int argc, const char** argv) style function calls inside a DLL.
-
- Args — Safe vector representation of argv (argc inferred)
-
Recommended DLL Signature
extern "C" i32 Entry(const i32 argc, const char** argv);
-
Why vector instead of raw argv?
- Because raw pointer mismatches = instant crash.
- Vector is safer and controlled.
-
i32 CallFunctionC_s( str& File, const str& EntryPoint, const vec<str>& Args, const i32 TerminalSize = 50, bool debug = true );
-
- This is basically
CallFunctionCbut with slightly safe hacks
- This is basically
-
template <typename T> str RemoveSignature( const str& Func, bool WithArgs = true );
-
Only enabled if
__has_include(<cxxabi.h>) -
- Removes C++ mangled signatures (Itanium ABI) to produce readable function names.
-
- Debugging symbol names
- Reflection utilities
- Cross-platform demangling (Clang/GCC)
-
- This is a library for essential OS API functions, but make it easier.
-
// Terminal utils namespace Tools::OS::Terminal { i32 TerminalSize(cstr DIR = "X", const i32 offset = 0); i32 TerminalSizeWidth(const i32 offset = 0){return TerminalSize("X", offset);} i32 TerminalSizeHeight(const i32 offset = 0){return TerminalSize("Y", offset);} umap<cstr, i32> TerminalSizeMap(){ return umap<cstr, i32>{{"X", TerminalSizeWidth(0)},{"Y", TerminalSizeHeight(0)}}; } void Clear(); } // File utils namespace Tools::OS::File { // temp function to generate safer string cstr cstr_safe(strv s, str& temp); bool WriteFile(strv path, strv text); str ReadFile(strv path); bool Exists(strv path); bool Remove(strv path); bool Move(strv from, strv to); } // OS Sleep namespace Tools::OS::Sleep { inline void SleepMs(u32 ms); void SleepPrecise(f64 ms); } // Process hacks namespace Tools::OS::Process { template <typename T> T ReadFromProcess(idx PID, u32ptr Address); template <typename T> bool WriteProcess(idx PID, u32ptr Address, T data); // Current process bool IsAdmin(); // Other process bool IsAdmin(idx pid); }
-
Include file:
#if defined(__WIN32) #include "OS/Win32.API.hpp" #elif defined(__linux__) && !defined(__ANDROID__) #include "OS/Linux.API.hpp" #elif defined(__APPLE__) #include "OS/Apple.API.hpp" #endif
- The function
TerminalSizereturns current terminal size (duh), you have 2 choises,X(row) axis orY(collumn) axis. You pass it on 1st parameter. - There are 3 other function that wraps 1st function.
-Width,-Height, and-Map. 2nd and 3rd are obvious, 4th return anstd::unordered_mapofXandYaxis. Clear()are for clear the entire console screen (duh)
- You can ignore the
cstr_safefunction, it's just used internally for converting stuffs. All function are usingstd::string_viewas parameter, and maybe it'll be changed tostd::stringor maybeconst char*
- This is sleep function provides by your OS, sometimes
std::this_thread::sleep_for(std::chrono::seconds(n));can sometimes be inaccurate if you pass too complex number.
- Yes, this is some sort of a process hacking tools, you can read, write (yes, an actual writing on specified address like how game h*kcing). Please use it fairly and wisely, because wrong movement can crash your project or even you OS. Also, you can check if a process or this process is running with admin privilege.
- The function
-
- Library to make you borix text into something from like Ms. Word or something, like colors, italic, bold, etc etc. Use only
Bold,Italic,Under,Strike,ColorFG/BGonly.
- Library to make you borix text into something from like Ms. Word or something, like colors, italic, bold, etc etc. Use only
-
namespace Tools::Styling { /* RGB Color */ struct Color; /* Basic FG coloring*/ str Colorize(const str& Text, const u64 Hex); /* Helper function to extract RGB components from a 32-bit color value */ void static ExtractRGB(u32& Alpha, u8& Red, u8& Green, u8& Blue); /* Convert hex in str -> actual useable number*/ u32 ParseHex(const str& s); /* Blend color with opacity */ u32 BlendRGB(u32 color_v, i32 alpha); /* Blend FG + BG color with opacity */ u8 BlendRGB(u8 fg, u8 bg, i32 alpha); /* ---- To make everything after "0x" caps */ str CapsPtr(str& s); /* ---- Basic styles ---- */ /* Bold text */ str Bold(const str& Text = "Hello, world!"); /* Italic text */ str Italic(const str& Text = "Hello, world!"); /* Underline text */ str Under(const str& Text = "Hello, world!"); /* Strikethrough text */ str Strike(const str& Text = "Hello, world!"); /* ---- Coloring styles ---- */ /* Foreground color with opacity */ str ColorFG(const str& Text = "Hello, world!", u32 color_tx = 0xFF8A46, i32 alpha = 100); /* Background color with opacity */ str ColorBG(const str& Text = "Hello, world!", u32 color_bg = 0x092655, i32 alpha = 100); /* Foreground color with opacity using struct Color */ str ColorizeFG(const str text, Color rgb); /* Background color with opacity using struct Color */ str ColorizeBG(const str text, Color rgb); /* ---- To reset mess you've made before ---- */ void Reset(str& Text); }
-
- Same as
Tools.Style, but withstd::wstring(wstr) support, slightly different choise of diction, but still good, and maybe kinda simpler. THe Name of the functions are already describe itself.
- Same as
-
API Codes:
namespace Tools::StylingW { str Colorize(const str& Text, const u64&Hex); str CapsPtr(str& s); str Bold(const str& Text); str Italic(const str& Text); str Under(const str& Text); str Strike(const str& Text); str ColorFG(const str& Text, u32 color_tx = 0xFF8A46, i32 alpha = 100); str ColorBG(const str& Text, u32 color_bg = 0x092655, i32 alpha = 100); str ColorFG(const str& text, CommonW::Color& rgb); str ColorBG(const str& text, CommonW::Color& rgb); str Reset(const str& Text); }
-
This function is to make something like this:
----------------[ Hello! ]---------------- -
namespace Tools::Styling { str PrintMid ( const str& text = "Hello", char borderChar = '=', int offset = 0, bool printing = false ); }
-
-
Tools::Styling::PrintMid("[ My Cool C++ App! ]", '~') -
return:
~~~~~~~~~~~~~~~~[ My Cool C++ App! ]~~~~~~~~~~~~~~~~ -
Tools::Styling::PrintMid(" My magcial C++ App! ", '/') -
return:
//////////////// My magcial C++ App! ////////////////
-
-
Suffix Meaning Types Meaning IInteger (i32) VIVector i32 LLong (i64) VLVector i64 FFloat (f32) VFVector f32 DDouble (f64) VDVector f64 VVector BIBundled i32 BBundled BLBundled i64 SBScattered Bundle BFBundled f32 BFBundled f32 BDBundled f64 SBIScattered Bundled i32 SBLScattered Bundled i64 SBFScattered Bundled f32 SBDScattered Bundled f64
-
- Supported types are
i32,i64,f32, andf64.Numwill return single value,Numswill returna bunch of numbers.
namespace Tools::Random { /* Singles */ i32 RandomNumI( i32 Min = 0, // Minimum value i32 Max = 9 // Maximum value ); /* Vector */ vec<i64> RandomNumsVL( idx Count = 64, // Element count i64 Min = 0, // Minimum value i64 Max = 10 // Maximum value ); /* Bundles */ vec<vec<f32>> RandomNumsBF( idx Sub = 64, // Sub-vector count idx Count = 256, // Sub-vector element count i32 Min = 0, // Minimum i32 Max = 100 // Maximum const i32 Rounding = 2 // Value rounding (F&D only) ); /* Scattered Bundled */ vec<vec<f64>> RandomNumsSBD( idx Sub = 64, // Sub-vector count idx CountMin = 25, // Sub-vector element minimal count idx CountMax = 50, // Sub-vector element maximum count f64 Min = 0.01, // Minimum value f64 Max = 10.0, // Maximum value const i32 Rounding = 2 // Value Rounding (F&D only) ); }
- Supported types are
-
Singesreturn single random valueVectorreturns multiple random number instd::vector<T>Bundledreturns multiple random number instd::vector<std::vector<T>>Scattered Bundledreturns multiple random number instd::vector<std::vector<T>>but with different count of each sub-vector
-
- I don't recommend using singles function inside a loop, instead, generate multiple value, then iterate through that container instead
-
Basically same as
Tools.Random, but with better seeder fromx86function calledRDSEEDandRDRAND, you just add theHWon the namespace (Tools::Random->Tools::RandomHW), and you can access the functions. -
This library is limited to
x86, using this on ARM may invalid or maybe cause something bad. -
Make sure to add
-mrdseed-mrdrnd-march=nativeflag on your compiler -
API Codes
namespace Tools::RandomHW { /* Singles */ i32 RandomNumI( Twister32& gen, // Twister engine i32 min, // Minimum value i32 max // Maximum value ); /* Vector */ vec<i64> RandomNumsVL( Twister64& gen, // 64-bit Twister engine const idx Count, // Element count i64 Min, // Minimum value i64 Max // Maximum value ); /* Bundles */ vec<vec<f32>> RandomNumsBF( Twister32& gen, // 32-bit engine const idx Sub = 64, // Sub-vector count const idx Count = 32, // Sub-vector element count f32 min = 0.01, // Minimum value f32 max = 9.99 // Maximum value const i32 Rounding = 2 // value rounding (F&D only) ); /* Scattered Bundled */ vec<vec<f64>> RandomNumsSBD( Twister64& gen, // 64-bit engine idx Sub = 64, // Sub-vector count idx CountMin = 25, // Sub-vector minimum element count idx CountMax = 50, // Sub-vector maximum element count f64 Min = 0.01, // Minimum value f64 Max = 10.0, // Maximum value const i32 Rounding = 2 // value rounding (F&D only) ); }
-
- To use this, you need to test the library by running function from
commonfile calledTools::RandomHW::Tests::CheckCompatibily()namespace RandomHW::Tests { bool RDseedSupport(); pair<bool, bool> TestRandSeed(u16& outA, u16& outB); pair<bool, bool> TestRandSeed(u32& outA, u32& outB); pair<bool, bool> TestRandSeed(u64& outA, u64& outB); void CheckCompatibily(); }
- Then you need to decalre the engine with
MakeHWEngine32for 32-bit values andMakeHWEngine64for 64-bit values - Then pass it on Generators
Twister32 e32 = MakeHWEngine32(); Twister64 e64 = MakeHWEngine64(); /* 32 sub-vector, 16 elements each, with value 0.01..9.99 with 2 digis rounding */ vec<vec<f32>> Rdvvf32 RandomNumsBF(e32, 32, 16, 0.01, 9.99, 2);
- To use this, you need to test the library by running function from
Library used internally for Tools.Random and Tools.RandomHW, this just contain aliases for some objects.
- Code
#include <random> #include "Types.hpp" using Twister32 = std::mt19937; using Twister64 = std::mt19937_64; using RdDevice = std::random_device; template <Integer T> using DistInt = std::uniform_int_distribution<T>; template <Float T> using DistReal = std::uniform_real_distribution<T>;
Library to round floating numbers just like Python and common math knowledge.
-
API Codes:
namespace Tools::Round { // Internal helper f64 static BankersRound(f64 x); // Rounder template <Float T> T Round(const T value, const i32 digits); }
-
double a = 3.14159; double b = Tools::Round::Round(a, 2); fmt::println("a = {} -> {}", a, b); // a = 3.14159 -> 3.14
Library to do some calculation with vector. Those choise of diction for function names are chosen carefully so it can describe itself without you have to guess and doing unnecessary trial & error.
-
Vector/Vector.accumulator.hpp: For sum, product, and averagesVector/Vector.find.hpp: Finding utilitiesVector/Vector.order.hpp: Data order utilitiesVector/Vector.order.inl.hpp: Data order utilities inlineVector/Vector.slice.hpp: Slice elementsVector/Vector.slice.inl.hpp: Slice elements inline
-
// Accumulators namespace Tools::Vector { template<Numbers T> T Sum(const vec<T>& v); // + template<Numbers T> T Product(const vec<T>& v); // * template <Numbers T> T Avg(const vec<T>& v); } // Find namespace Tools::Vector { // Binary search template<Numbers T> T Find_binary(const vec<T>& v, const T Element); // Binary search, first index + value, return pair of index and value itself template<Numbers T> pair<idx, T> FindP_binary(const vec<T>& v, const T Element); // Linear search template <Numbers T> T Find_line(const vec<T>& v, const T Element); // Linear search, first index + value, return pair of index and value itself template <Numbers T> T FindP_line(const vec<T>& v, const T Element); // Find an element frequency template<Numbers T> idx FindFreq(const vec<T>& v, const T Element); // Find elements and frequency template<Numbers T> umap<T, idx> FindNFreq(const vec<T>& v); // Extractor template<Numbers T> vec<T> ExtractUnique(const vec<T>& v); // Remove duplicated values template<typename T> vec<T> RemoveDuplicates(const vec<T>& Data); // Remove duplicated values inline template<typename T> void RemoveDuplicatesInl(vec<T>& Data); } // Order namespace Tools::Vector { template <Numbers T> vec<T> Sort(const vec<T>& v); template <Numbers T> vec<T> Shuffle(const vec<T>& v); template <Numbers T> vec<T> Reverse(const vec<T>& v); } // Order Inline namespace Tools::VectorInl { template <Numbers T> void Sort(vec<T>& v); template <Numbers T> void Shuffle(vec<T>& v); template <Numbers T> void Reverse(vec<T>& v); } // Slices (return new) namespace Tools::Vector { template <typename T> vec<T> Slice(const vec<T>& vec, idx x, idx y); template <typename T> vec<T> Slice(const vec<T>& vec, idx n); } // Slices Inline namespace Tools::VectorInl { template <typename T> void Slice(vec<T>& vec, idx x, idx y); template <typename T> void Slice(vec<T>& vec, idx n); }
A library (but more liek shortcut) to do some calculations with Time
Target of this library:
-
Simplicity: No complex template magic - just works
-
Precision: Uses high-resolution clock by default
-
Type Safety: Concepts ensure correct usage
-
Modern C++: Leverages C++20 features
-
Zero Overhead: All operations are compile-time checked
-
namespace Tools::Clock { // Return elapsed time based on 1 time points in selectected unit template <Duration T> u64 Count(const HClock& Begin, const HClock& End); // Run function directly (no return) template <typename F, Duration T> requires std::invocable<F> u64 FunctionElapsed(F&& func); // Run function directly (with return) template <typename F, Duration T> requires (!std::same_as<std::invoke_result_t<F>, void>) u64 FunctionElapsed(F&& func, std::invoke_result_t<F>& result); // Sleep in given duration unit template <Duration T> void Sleep(u64 value); }
-
-
Elapsed time
#include <fmt/format.h> #include <Tools/Types.hpp> void Heavy() { u128 result = 0; i16 max = GET_MAX(i16); for(i16 i = 0; i < max; i++){ result += i; } fmt::println("0+1+...+{} = {}", max, result); } i32 main(){ HClock Begin = HTimeNow(); // get current time point (before task) Heavy(); // simulate some task HClock End = HTimeNow(); // get current time point (after task) fmt::println( "Heavy took {} μs", CountDuration<us>(Begin, End).count() // get elapsed time ); }
-
Run function directly (
void)#include "Tools/Clock.hpp" i32 main() { // Time a void function directly auto timeMs = Tools::Clock::FunctionElapsed<Tools::Clock::ms>([] { std::vector<i32> v(1000000); std::iota(v.begin(), v.end(), 0); std::sort(v.begin(), v.end(), std::greater<i32>()); }); fmt::println("Sorting took {} ms", timeMs); return 0; }
-
Run function directly (
T)#include "Tools/Clock.hpp" i32 main() { i32 result; // Time a function AND get its result auto timeUs = Tools::Clock::FunctionElapsed<Tools::Clock::us>( [] { return std::accumulate(std::vector<i32>(1000, 1).begin(), std::vector<i32>(1000, 1).end(), 0); }, result ); fmt::println("Sum of 1000 ones = {}", result); fmt::println("Calculation took {} μs", timeUs); return 0; }
-
Precise Sleep
#include "Tools/Clock.hpp" int main() { fmt::println("Starting..."); // Sleep for 1.5 seconds Tools::Clock::Sleep<Tools::Clock::ms>(1500); fmt::println("1.5 s (seconds) later..."); // Sleep for 250 microseconds Tools::Clock::Sleep<Tools::Clock::us>(250); fmt::println("250 μs (microseconds) later..."); return 0; }
-
-
- Time Point vs. Duration Confusion
- Wrong:
auto dur = HTimeNow();(this is a time point, not duration) - Right:
auto dur = end - begin;(this gives a duration)
- Wrong:
- Unit Selection Tips
- Use
us(microseconds) for most performance measurements - Use
ns(nanoseconds) for extremely precise measurements - Use
ms(milliseconds) for user-facing timing info
- Use
- Clock Selection Guide
HTimeNow(): Highest precision, but may vary if system clock changesTimeNow(): Steady clock, better for measuring intervals (not implemented in current API but available)
- Time Point vs. Duration Confusion