#include "Tutorial.h" void ValueTutorial() { /// .Value /// Value is sort of equivalent of polymorphic data types from scripting languages like Python /// or JavaSript. `Value` can represent values of concrete types, some types also have /// extended interoperability with `Value` and it is then possible to e.g. compare `Value`s /// containing such types against each other or serialize them for persistent storage. /// Usually, Value compatible types define typecast operator to `Value` and constructor /// from `Value`, so that interaction is for the most part seamless: Value a = 1; Value b = 2.34; Value c = GetSysDate(); Value d = "hello"; DUMP(a); DUMP(b); DUMP(c); DUMP(d); int x = a; double y = b; Date z = c; String s = d; DUMP(x); DUMP(y); DUMP(z); DUMP(s); /// As for primitive types, Value seamlessly works with `int`, `int64`, `bool` and `double`. /// Casting `Value` to a type that it does not contain throws an exception: try { s = a; DUMP(s); // we never get here.... } catch(ValueTypeError) { LOG("Failed Value conversion"); } /// However, conversion between related types is possible (as long as it is supported by /// these types): double i = a; int j = b; Time k = c; WString t = d; DUMP(i); DUMP(j); DUMP(k); DUMP(t); /// To determine type of value stored in `Value`, you can use `Is` method: DUMP(a.Is()); DUMP(a.Is()); DUMP(b.Is()); DUMP(c.Is()); DUMP(c.Is()); DUMP(d.Is()); /// Note that Is tests for absolute type match, not for compatible types. For that reason, /// for widely used compatible types helper functions are defined: DUMP(IsNumber(a)); DUMP(IsNumber(b)); DUMP(IsDateTime(c)); DUMP(IsString(d)); /// }