This repository is StormByte Base: the C++26 foundation of the StormByte suite.
It is the module every other StormByte library links. Public headers live under StormByte/ and cover exceptions, Expected, little-endian serialization, strings, paths, UUID v4, bitmasks, clonable types, a reentrant ThreadLock, and the StormByte::Type concepts.
The suite is split on purpose. Buffer, Config, Crypto, Database, Logger, Multimedia, Network and System are other repositories. They depend on this one; this one does not implement them.
- Exceptions —
StormByte::Exceptionwithstd::formatmessages andconst char*storage (DLL-safe on Windows). - Expected —
Expected<T, E>on top ofstd::expected, references viareference_wrapper, errors asshared_ptr<E>, plusUnexpected. - Serialization —
Serializable<T>tovector<byte>, always little-endian, no BOM and no version tag. Optional / pair / container / trivial /Detail::Codec<T>. - Strings — case, split, UTF-8 ↔ wide, human-readable numbers and byte sizes, newline sanitizing.
- System — temp files, cwd, executable directory,
Sleepforchronodurations. - UUID — RFC 4122 version 4 (
GenerateUUIDv4). - Bitmask — CRTP flags over
Type::UnsignedEnum. - Clonable — virtual
Clone/Moveintoshared_ptrorunique_ptr. - ThreadLock — owner-thread reentry;
Unlockfrom a non-owner is a no-op. - Type concepts —
StormByte::Type::*(String,Container,Optional,Pair, enums, …). Noenable_if/void_tnext to them. - Platform / visibility —
WINDOWS/LINUX/MACOS,BIT32/BIT64,CLANG/GCC/MSVC(clang-cl isCLANG, notMSVC).
| Module | Role | API |
|---|---|---|
| Base | This repository | /StormByte |
| Buffer | FIFO, SharedFIFO, Ring, Producer/Consumer and multi-stage pipelines | /StormByte-Buffer |
| Config | Human-readable text and versioned binary documents (groups, lists, raw bytes) | /StormByte-Config |
| Crypto | Hash, compress, encrypt, sign and key agreement — Crypto++ never leaves the private tree | /StormByte-Crypto |
| Database | One API over SQLite, PostgreSQL and MariaDB | /StormByte-Database |
| Logger | Stream logger with levels, headers, human-readable sizes and redaction (ThreadedLog) |
/StormByte-Logger |
| Multimedia | Decode, encode and containers without raw FFmpeg types; codecs enabled only if present | /StormByte-Multimedia |
| Network | Framed packets, Client/Server, IPv4/IPv6 TCP and Buffer pipelines (compress/encrypt) | /StormByte-Network |
| System | Processes, pipes and environment variables across Linux, Windows and macOS | /StormByte-System |
Needs a C++26 compiler and CMake 3.28 or newer.
git clone https://github.com/StormBytePP/StormByte.git
cd StormByte
cmake -S . -B build
cmake --build buildHeaders are #include <StormByte/….hxx>. Namespace root is StormByte.
#include <StormByte/exception.hxx>
#include <iostream>
using namespace StormByte;
void process_data(int value) {
if (value < 0)
throw Exception("Invalid value: {}", value);
}
int main() {
try {
process_data(-5);
} catch (const Exception& e) {
std::cerr << e.what() << std::endl;
}
}Errors are shared_ptr<E>. Read them with result.error()->what().
#include <StormByte/expected.hxx>
#include <StormByte/exception.hxx>
#include <iostream>
using namespace StormByte;
Expected<int, Exception> divide(int a, int b) {
if (b == 0)
return Unexpected<Exception>("Division by zero");
return a / b;
}Error::Code exists for std::error_code integration. The enum has no enumerators yet.
Wire is little-endian. Deserialize reads a prefix; leftover bytes stay with the caller. Custom types specialize StormByte::Detail::Codec<T> (Size / Write / Read), not Serializable<T>.
#include <StormByte/serializable.hxx>
#include <iostream>
#include <string>
#include <vector>
using namespace StormByte;
int main() {
int number = 42;
auto blob = Serializable<int>(number).Serialize();
auto back = Serializable<int>::Deserialize(blob);
if (back)
std::cout << back.value() << std::endl;
std::string text = "Hello, World!";
auto sblob = Serializable<std::string>(text).Serialize();
auto sback = Serializable<std::string>::Deserialize(sblob);
std::vector<int> numbers{1, 2, 3};
auto vblob = Serializable<std::vector<int>>(numbers).Serialize();
auto vback = Serializable<std::vector<int>>::Deserialize(
std::span<const std::byte>(vblob.data(), vblob.size()));
}wstring / u16string / u32string travel as uint64 UTF-8 length + UTF-8 bytes. Host wchar_t width never appears on the wire.
#include <StormByte/string.hxx>
#include <iostream>
#include <queue>
using namespace StormByte::String;
int main() {
auto parts = Explode("path/to/file.txt", '/');
auto words = Split("Hello World from StormByte");
auto n = HumanReadable(1234567890ull, Format::HumanReadableNumber);
auto sz = HumanReadable(1536000ull, Format::HumanReadableBytes);
auto utf8 = UTF8Encode(L"Hello, 世界!");
auto wide = UTF8Decode(utf8);
}CurrentPath() is the process cwd. ExecutablePath() is the directory of the running binary (NOPATH if it cannot be resolved).
#include <StormByte/system.hxx>
#include <chrono>
using namespace StormByte::System;
using namespace std::chrono_literals;
int main() {
auto tmp = TempFileName("myapp");
auto cwd = CurrentPath();
auto exe = ExecutablePath();
Sleep(500ms);
}#include <StormByte/uuid.hxx>
#include <iostream>
int main() {
std::cout << StormByte::GenerateUUIDv4() << std::endl;
}The owner may Lock() again. Another thread blocks. Unlock() from a non-owner does nothing.
#include <StormByte/clonable.hxx>
#include <memory>
using namespace StormByte;
class Shape : public Clonable<Shape, std::shared_ptr<Shape>> {
public:
virtual std::shared_ptr<Shape> Clone() const override = 0;
virtual std::shared_ptr<Shape> Move() override = 0;
};#include <StormByte/type_traits.hxx>
#include <string>
#include <vector>
#include <optional>
using namespace StormByte;
static_assert(Type::String<std::string>);
static_assert(Type::Container<std::vector<int>>);
static_assert(Type::Optional<std::optional<int>>);Type::Detail::swap_endian always reverses bytes. Serializable decides when to call it (host not little-endian).
Needs an unsigned scoped enum. Operators return the derived CRTP type. Helpers are Add, Remove, Has, HasAny, HasNone, Value (not Any / None).
#include <StormByte/bitmask.hxx>
using namespace StormByte;
enum class MyFlags : uint8_t { FlagA = 0x01, FlagB = 0x02 };
class MyBitmask : public Bitmask<MyBitmask, MyFlags> {
public:
using Bitmask<MyBitmask, MyFlags>::Bitmask;
};Issues only on this repository. Fork and open a pull request against master.
GNU Lesser General Public License version 3 or later. See LICENSE and https://www.gnu.org/licenses/lgpl-3.0.html.