CxxUtils is a lightweight C++ utility library designed to streamline common tasks in C++ projects. It provides utilities for handling function traits, unicode conversion, reversed iteration, compression, custom exception handling, enhanced memory management, random number generation, and multithreading. Each utility is modular, allowing you to use only the components you need.
- Function Traits: Simplify function type inspection with templates.
- Unicode Conversion: Convert between UTF-8 and Unicode (wstring).
- Reversed Iteration: Easily iterate over containers in reverse.
- Compression: Compress and decompress data using zlib.
- Virtual File System: Define user file systems, mount them, and open files seamlessly.
- Logger: Lightweight debugging macros.
- Custom Exception Handling: Enhanced exception handling with file and line tracking.
- Memory Management: Improved smart pointers, including enhanced
WeakPtr. - Enum flags: Create flags using enums with supporting And, Or and other operators.
- Periodic Task: Manage periodic tasks efficiently.
- Termination Signal Handling: Handle
SIGTERMwith custom wait functions. - Option Parser: Parse argv options.
Follow these instructions to set up the project locally and get it running.
Ensure you have the following tools installed:
- CMake: A cross-platform build system.
-
Create a build directory and navigate into it:
mkdir build cd build -
Run CMake to configure the project:
cmake ..
-
Build the project:
make
Include the CxxUtils directory in your project and link against any dependencies if needed (e.g., zlib for compressor.h).
Then simply include the necessary headers in your project. For example:
#include "CxxUtils/function_traits.h"
#include "CxxUtils/logger.h"
// Example usage of function traits
void myFunction(int, double) {}
int main() {
static_assert(CxxUtils::function_traits<decltype(myFunction)>::arity == 2, "Function should have 2 arguments.");
CxxUtils::LogDebug("Function has expected number of arguments.");
return 0;
}Located in function_traits.h, this module provides templates for extracting function arity, result type, and argument types.
Example:
#include "CxxUtils/function_traits.h"
void myFunction(int, double) {}
constexpr auto argCount = CxxUtils::function_traits<decltype(myFunction)>::arity;The unicode.h module provides functions to convert between UTF-8 std::string and std::wstring.
Example:
#include "CxxUtils/unicode.h"
std::wstring wideStr = CxxUtils::s2ws("Hello");
std::string utf8Str = CxxUtils::ws2s(wideStr);reversed.h contains a C++11 wrapper to iterate over containers in reverse.
Example:
#include "CxxUtils/reversed.h"
#include <vector>
std::vector<int> vec = {1, 2, 3, 4};
for (int x : CxxUtils::reverse(vec)) {
// Process x in reverse order
}rwlock.h contains a C++11 implementation of mutex using pthread library
Example:
#include "CxxUtils/rwlock.h"
CxxUtils::rwlock lock;
lock.wrlock(); // unique lock
lock.unlock();
lock.rdlock(); // shared lock
lock.unlock();compressor.h includes functions for compressing and decompressing data using zlib.
Example:
#include "CxxUtils/compressor.h"
#include <vector>
std::vector<uint8_t> data = { /* your data */ };
auto compressed = CxxUtils::zlib::compress(data/*, Z_BEST_COMPRESSION*/);
auto decompressed = CxxUtils::zlib::decompress(compressed/*, sizeof(data)*/);The Virtual File System (VFS) subsystem allows mounting custom file systems and accessing files as if they were part of the native filesystem. This abstraction supports various file types and locations, such as in-memory data or compressed archives.
vfs/istream.h: Interface class forCxxUtils::istream, enabling custom input streams.vfs/streambuf.h: Custom implementation ofstd::streambuffor reading data fromCxxUtils::istream.vfs/ifstream.h: A specialized input file stream that supports both virtual and native file systems. It extendsstd::istreamand offers additional utilities.vfs/utils.h: Utility classes such asSharedStdStream,PartStream, andRamStreamfor handling specialized stream sources.
Example:
#include <CxxUtils/vfs/vfs.h>
#include <CxxUtils/vfs/tarfs.h>
#include <CxxUtils/vfs/ifstream.h>
#include <CxxUtils/registrar.h>
// Register an tar archive as file system at the mount point "mnt/test"
static CxxUtils::Registrar archiveFS([]{ CxxUtils::vfs::mount<CxxUtils::TarFS>("mnt/test", "archive.tar"); });
int main() {
// Accessing files in the native filesystem
CxxUtils::ifstream nativeFile("hostdir/nativeFile.txt");
// Accessing files in the custom virtual file system
CxxUtils::ifstream virtualFile("mnt/test/dir2/file1", std::ios::bin);
// Reading from a file (STL-style usage)
std::array<char, 100> buffer {};
virtualFile.read(buffer.data(), buffer.size());
// Using custom read API
auto vectorBuffer = virtualFile.readVector<uint8_t>(50);
std::istream& ref = virtualFile; // CxxUtils::ifstream is derived from std::istream
ref.seekg(0, std::ios::beg); // so you can use standard API as well with it
return 0;
}logger.h includes debugging macros for logging messages.
Example:
#include "CxxUtils/logger.h"
CxxUtils::LogPanic() << "Test panic message";
CxxUtils::LogError() << "Test error message";
CxxUtils::LogWarning() << "Test warning message";
CxxUtils::LogInfo() << "Test info message";
CxxUtils::LogDebug() << "Test debug message";
CxxUtils::LogTrace() << "Test trace message";
CxxUtils::LogWarning("Formatted %s message", "warning") << " again" << 234u << "," << 1.2;
CxxUtils::LogWarning("Formatted %s message", "warning").append(" appended %u, %0.1f", 234u, 1.2f);The exception.h module provides a custom exception class with file and line information.
Example:
#include "CxxUtils/exception.h"
try {
throw CxxUtils::Exception("An error occurred");
} catch (const CxxUtils::Exception& exception) {
CxxUtils::LogError("Exception! %s:%d: %s: %s",
exception.file(), exception.line(),
exception.function(), exception.what());
}memory.h contains an enhanced lightweight wrappers around reference and pointer types.
Example:
#include "CxxUtils/memory.h"
CxxUtils::UniquePtr<std::vector<int>> uniquePtr = std::make_unique<std::vector<int>>();
CxxUtils::SharedPtr<std::vector<int>> sharedPtr = std::make_shared<std::vector<int>>();
CxxUtils::WeakPtr<std::vector<int>> weakPtr = sharedPtr;
CxxUtils::Instance<std::vector<int>> instance;
CxxUtils::Reference<std::vector<int>> instanceRef = instance;enum_flags.h contains template class for supporting flags based on enums
Example:
#include "CxxUtils/enum_flags.h"
enum class Flags : std::uint32_t {
None = 0,
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2
};
CxxUtils::EnumFlags<Flags> flags{Flags::Flag2, Flags::Flag1};
if (flags & Flags::Flag1) onFlag1Set();periotic_task.h provides a multithreaded periodic task scheduler for efficiently managing concurrent tasks.
Example:
#include "CxxUtils/periotic_task.h"
// PeriodicFunction example
CxxUtils::PeriodicFunction task(100ms, []{ CxxUtils::LogInfo() << "Periodic message"; });
task.start();
// PeriodicTask class example
class CustomPeriodicTask : final public PeriodicTask {
public:
CustomPeriodicTask() : PeriodicTask(100ms) {}
private:
void onExecute() final;
void onStart() final; // optional
void onStop() final; // optional
};
The sigterm.h includes a function to wait for a SIGTERM or SIGINT signal.
Example:
#include "CxxUtils/sigterm.h"
CxxUtils::TerminationSignal::wait();The option_parser.h provides the OptionParser class for parsing command-line options.
Example:
#include "CxxUtils/option_parser.h"
CxxUtils::OptionParser options {argc, argv,
CxxUtils::Option{'p', {"port", "Set server port", "1234"}},
CxxUtils::Option{'l', {"login", "Set user name", "user"}},
CxxUtils::Option{'s', {"password", "Set user password", ""}},
CxxUtils::Option{'f', { "Set foreground mode" }},
};
uint16_t port = options['p'];
const char *login = options['l'];
const char *password = options['s'];
bool is_foreground = options['f'];Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.