Hermes
Common Utilities

Welcome, here I will present the very basic tools that hermes provides to help you during development. The classes and data types listed here are used throughout the entire library and I hope you could use them in your code too.

Before anything, I would like to list here the very primitive types that you will find in hermes/common/defs.h:

name description
i8,i16,i32, andi64 signed integers, respectively int8_t, int16_t, int32_t, and int64_t
u8,u16,u32, andu64 unsigned integers, respectively uint8_t, uint16_t, uint32_t, and uint64_t
byte 8-bit unsigned (uint8_t)
f32 and f64 floating-point types, respectively float and double

Sometimes you want to somehow, work with the types in unusual ways. The hermes::DataTypes is an auxiliary namespace that provides some functions that convert between the declared types, and the enum class hermes::DataType, that holds labels for each of the types above:

int main() {
// extract class from type
auto u8_type = hermes::DataTypes::typeFrom<u8>();
// check type size
// get type name (string)
return 0;
}
static std::string typeName(DataType type)
Gets DataType string name.
Definition: defs.h:183
static u32 typeSize(DataType type)
Computes number of bytes from DataType.
Definition: defs.h:163
Data type definitions.

Indices and Sizes

A common task is the iteration over multi-dimensional arrays and index ranges. Hermes offers 2-dimensional and 3-dimensional index and size operations that may facilitate these tasks with the following types:

// integer based indices
hermes::index2; // (i,j)
hermes::index3; // (i,j,k)
// unsigned integer based sizes
hermes::size2; // (width, height)
hermes::size3; // (width, height, depth)
Holds 2-dimensional size.
Definition: size.h:47
Holds 2-dimensional size.
Definition: size.h:142
Holds 2-dimensional integer index coordinates.
Definition: index.h:50
Holds 3-dimensional index coordinates.
Definition: index.h:362

You can do all sort of arithmetic operations between them. But you can also work with range of indices as well:

// ranges represent a half-open interval [lower, upper)
Represents a closed-open range of indices [lower, upper)
Definition: index.h:283
Represents a closed-open range of indices [lower, upper),.
Definition: index.h:532

which can be useful when you want to iterate over such type of indices:

int main() {
// let's iterate over all indices in [(0,0), (9,9)]
hermes::size2 size(10, 10);
for(auto index : hermes::range2(size)) {
// access index coordinates as
index.i;
index.j;
}
return 0;
}
Set of multi-dimensional integer iterators.

Strings

Some functions of strings can be found in hermes::Str. Here are some examples of what you can do:

int main() {
// strip string sides
hermes::Str::strip(" asd \n", " \n"); // "asd"
// split into substrings
hermes::Str::split("1,2,3", ","); // {"1","2","3"}
// join strings
hermes::Str::join({"a","b","c"}, ","); // "a,b,c"
// concatenate
hermes::Str::concat("a", " ", 2); // "a 2"
// format
hermes::Str::format("{} has {} letters", "word", 4); // "word has 4 letters
// numbers
hermes::Str::isInteger("-234235"); // true
hermes::Str::isNumber("-2e5"); // true
hermes::Str::binaryToHex(10); // "0x1010"
hermes::Str::addressOf(ptr); // ptr address value "0xFF..."
// regex match
hermes::Str::match_r("subsequence123". "\\b(sub)([^ ]*)"); // true
// regex contains
hermes::Str::contains_r("subsequence123", "\\b(sub)"); // true
// and more ...
return 0;
}
static std::string concat(const Args &... args)
Concatenates multiple elements_ into a single string.
Definition: str.h:212
static std::string strip(const std::string &s, const std::string &patterns=" \t\n")
Definition: str.cpp:149
static std::string binaryToHex(T input_n, bool uppercase=true, bool strip_leading_zeros=false)
Get ascii representation of raw bit data of input_n
Definition: str.h:267
static std::string join(const std::vector< std::string > &v, const std::string &separator="")
Concatenate strings together separated by a separator.
Definition: str.cpp:137
static bool isNumber(const std::string &s)
Checks if string represents a number.
Definition: str.cpp:205
static std::vector< std::string > split(const std::string &s, const std::string &delimiters=" ")
Splits a string into tokens separated by delimiters.
Definition: str.cpp:170
static std::string addressOf(uintptr_t ptr, u32 digit_count=8)
Generates hexadecimal representation of memory address.
Definition: str.h:291
static std::string format(const std::string &fmt, Ts &&... args)
Definition: str.h:170
static bool isInteger(const std::string &s)
Checks if string represents an integer.
Definition: str.cpp:187
String utils.

An instance of hermes::Str is just a std::string wrapper with an << operator. So you can do stuff like:

s = s << "bla";
String class and set of string functions.
Definition: str.h:53

Files

The hermes::Filesystem provides some shell-like functions that can help you with files and directories. A auxiliary class is the hermes::Path, which holds a filesystem path for a file or directory.

With hermes::Path in hands, you can ask all sorts of things like file extension, directory name, absolute path, etc. You can also test if your file or directory exists and create it if necessary. You can also construct your path like this:

#include <hermes/common/filesystem.h>
int main() {
hermes::Path parent("parent_folder");
auto child = parent / "child";
// now child is the path "parent/child"
// you can create this path if necessary
if(!child.exists())
child.mkdir();
// the same goes with a file
hermes::Path file("parent_folder/file.txt");
if(!file.exists())
file.touch();
// you could, for example check the file extension
HERMES_LOG(file.extension());
// the file name
HERMES_LOG(file.name());
// you can also check what type of path you have
child.isDirectory();
file.isFile();
// in the case of the file, you can read
auto content = file.read();
// and write
file.writeTo("files content");
return 0;
}
Representation of a directory/file in the filesystem.
Definition: file_system.h:48
#define HERMES_LOG(FMT,...)
Logs into info log stream.
Definition: logging.h:363

Sometimes you want to iterate over directories and files, find or copy. Here are examples of how you can do:

#include <hermes/common/filesystem.h>
int main() {
// copy files
hermes::Filesystem::copyFile("source/path", "destination/path");
// find files recursively using regular expressions
// also sort the results
hermes::Filesystem::find("root/path",
"*.cpp", // look for cpp files
hermes::find_options::recursive |
hermes::find_options::sort);
// list only files in a directory, recursively
hermes::FileSystem::ls("root/path",
hermes::ls_options::files |
hermes::ls_options::recursive);
// list a directory, putting directories first
hermes::FileSystem::ls("root/path",
hermes::ls_options::group_directories_first);
return 0;
}
static std::vector< Path > ls(const Path &path, ls_options options=ls_options::none)
Lists files inside a directory.
Definition: file_system.cpp:426

Parsing Arguments

Reading command line arguments or parsing command strings can be done with hermes::ArgParser:

int main(int argc, char** argv) {
hermes::ArgParser parser("my program", "description");
// define a simple float argument
parser.addArgument("--float_argument", "description");
// an required argument
parser.addArgument("--int_argument", "argument description", true);
// parse arguments
parser.parse(argc, argv);
// access argument value with default value
parser.get<int>("--int_argument", 0);
// check if argument was given
if(parser.check("--float_argument"))
HERMES_LOG_VARIABLE(parser.get<float>("--float_argument"));
return 0;
}
Simple argument parser.
Command line argument parser.
Definition: arg_parser.h:64
#define HERMES_LOG_VARIABLE(A)
Logs variable name and value into info log stream.
Definition: logging.h:404

For the code above, you code pass arguments like this:

./a.out --int_argument 3 --float_argument 2.0

It works by parsing all arguments, in order, pairing tokens separated by spaces. So you don't need to explicitly put the names of the arguments if you don't want to:

./a.out 3 --float_argument 2.0

In that case, 3 will be parsed and considered to be the value of your --int_argument, because the parser will follow the addArgument order.