Algorithms The dynamic variable is accompanied by a number of algorithms, but also works with most standard C++ algorithms. Count Counts the number of matching keys or values in a dynamic variable. #include <trial/dynamic/algorithm/count.hpp> There are two count algorithms. One counts matching keys, and the other counts matching values. They are located in the dynamic::key and dynamic::value namespaces respectively. Expression Return type Semantics Conditions key::count(v, t) size_type Counts elements with key t in dynamic variable. Requires: T is a supported type. Effects: std::count(v.key_begin(), v.key_end(), t) Returns: Number of elements in v matching t. value::count(v, t) size_type Counts elements with value t in dynamic variable. Requires: T is a supported type. Effects: std::count(v.begin(), v.end(), t) Returns: Number of elements in v matching t. Find Finds an element by key or by value in a dynamic variable. #include <trial/dynamic/algorithm/find.hpp> Expression Return type Semantics Conditions key::find(v, t) key_iterator Finds element with key in dynamic variable. Requires: T is a supported type. Effects: std::find(v.key_begin(), v.key_end(), t) Returns: Iterator pointing to element in v matching t, or v.key_end() if not such element exits. value::find(v, t) iterator Finds element with value in dynamic variable. Requires: T is a supported type. Effects: std::find(v.begin(), v.end(), t) Returns: Iterator pointing to element in v matching t, or v.end() if not such element exits. Visit Invokes a function call operator on a visitor object with the stored value of the dynamic variable as the function parameter. #include <trial/dynamic/algorithm/visit.hpp> In addition to various ways of doing type checking, we can also invoke a typed callback on a customized visitor object. The function call operator always takes a single input parameter whose type is one of the supported types. The normal C++ function overloading rules applies when selecting which function call operator to invoke. struct my_visitor { template <typename T> void operator()(T value) { std::cout << value << std::end; } }; int main() { dynamic::variable data = { true, 2, 3.0, "alpha" }; my_visitor visitor; dynamic::visit(vistor, data); return 0; } The function call operator may return a value. All function call operators must use the same return type, which is also the return type of the dynamic::visit algorithm. struct my_returning_visitor { template <typename T> dynamic::symbol::value operator()(T value) { dynamic::variable tmp(value); return tmp.symbol(); } }; int main() { dynamic::variable data = { true, 2, 3.0, "alpha" }; my_returning_visitor visitor; auto symbol = dynamic::visit(vistor, data); assert(symbol == dynamic::symbol::array); return 0; } #include <algorithm> The dynamic variable works with standard C++ algorithms that require at most bi-directional iterators. Some algorithms assume that if they take two ranges, then the second range is at least as long as the first. dynamic::nullable is an empty container, so it cannot be used as the second range. The algorithms listed in the table below have been verified. Excluded are sorting algorithms and algorithms requiring special operators apart from operator+ (e.g. std::inner_product without binary predicates.) Algorithm Caveat std::accumulate None. std::adjacent_find None. std::all_of None. std::any_of None. std::binary_search None. std::copy None. std::copy_backward None. std::count None. std::count_if None. std::equal Using dynamic::nullable as the first range causes true to be returned regardless of the second range. Using dynamic::nullable as the second range causes undefined behavior. std::equal_range None. std::find Using dynamic::nullable as the range causes nothing to be found. std::find_if Using dynamic::nullable as the range causes nothing to be found. std::insert_iterator None. std::iota Only arithmetic types can be inserted. std::is_partitioned None. std::is_sorted None. std::lexicographical_compare None. std::lower_bound None. std::max_element None. std::mismatch Using dynamic::nullable as the second range causes undefined behavior. std::move None. std::move_backward None. std::none_of None. std::partial_sum None. std::partition None. std::partition_point None. std::remove In associated arrays entries are removed by value but the key order is kept. std::replace Cannot insert container as new value because iterators will be changed during replacement. std::reverse None. std::rotate No effect on singular values. std::search Using dynamic::nullable as the second range always returns the first entry. std::stable_partition None. std::swap_ranges Using dynamic::nullable as the first range has no effect. Using dynamic::nullable as the second range causes undefined behavior. std::transform None. std::unique None. std::upper_bound None.