Trial.Dynamic
Overview
Trial.Dynamic is a C++11 header-only library with a C++ dynamic variable similar to the Javascript dynamic variable.
-
dynamic::variableis a tagged union whose type and value can change dynamically during program execution. -
dynamic::variablesupports fundamental data types[1][2] and strings. -
dynamic::variablesupports arrays and associative arrays and can therefore act as a heterogenous tree data structure. -
dynamic::variablemeets the requirements of Container and therefore works with standard C++ algorithms.
The resemblance between dynamic::variable and std::variant
is obvious, but there are also notable differences. While std::variant supports
custom types, dynamic::variable is restricted to the above-mentioned data types
and containers. This restriction enables dynamic::variable to adhere to the
Container concept, and thus to have a richer interface that works with algorithms.
dynamic::variable is intended for tasks like handling configuration data, parse
tree for network protocols, and protocol serialization.
Introduction by Example
All examples throughout this documentation assumes the following prologue:
#include <trial/dynamic/variable.hpp>
namespace dynamic = trial::dynamic;
A default-initialized
dynamic::variable has no value. No value is represented as the dynamic::nullable
type.
// Create an empty variable
dynamic::variable data;
assert(data.is<dynamic::nullable>());
assert(data == dynamic::null);
We can morph the above variable into a boolean type simply by assigning a boolean value to it.
// Change into boolean
data = true;
assert(data.is<bool>());
assert(data == true);
We can even morph it into an array by assigning an initializer list to it.
// Change into array
data = { 1, 20, 300 };
assert(data.is<dynamic::array>());
assert(data.size() == 3);
assert(data[0] == 1);
assert(data[1] == 20);
assert(data[2] == 300);
Now that the variable contains an array of integers, it makes sense to calculate its sum.
#include <numeric>
// Calculate sum
auto sum = std::accumulate(data.begin(), data.end(), dynamic::variable());
assert(sum == 1 + 20 + 300);
Finally we morph our variable into an associative array.
// Change into associative array
data =
{
{ "alpha", null }, // nullable
{ "bravo", true }, // boolean
{ "charlie", 2 }, // integer
{ "delta", 3.0 }, // floating-point number
{ "echo", "blue" }, // string
{ "foxtrot", { 1, 2, 3 } }, // nested array of integers
{ "golf", { { "level", 2 } } } // nested associative array
};
assert(data.is<dynamic::map>());
assert(data.size() == 7);
char, wchar_t, char16_t, and char32_t) are not supported directly, but only indirectly via strings.
void is not a regular type, so it has been replaced with the dynamic::nullable type and the dynamic::null value.