/*Demonstrates class meta data.
Basically, we make use of the compiler's
data about a class.  We can add to the
compilers data arbitrary items, either string or
or int or F64 (if you typecast).

This stuff is not high performance.
Don't get carried away -- it might be slow.
*/

U0 RankOut(I64 i)
{
    " %z", i, "Cadet\0Ensign\0Captain\0Admiral\0President\0";
}

class Test1Struct
{
    I64 age         print_str "%2d" default_val 38;
    I64 color       default_val RED; //Accepts expressions
    I64 rank        print_str "%1d" default_val 6/2 output_fun &RankOut;
};

class Test2Struct
{
    I64 age             print_str "%2d" default_val 38 percentile 54.20;
    I64 rank            print_str "%1d" default_val 5;
    I64 serial_num      print_str "%6d" default_val 123456;
};

U0 DumpStruct(U8 *_d, U8 *class_name=lastclass)
{//lastclass is keyword.    See ::/Demo/LastClass.ZC.
    CHashClass  *tmpc = HashFind(class_name, Fs->hash_table, HTT_CLASS);
    U8          *print_str;
    I64         *q, default_val;
    U0         (*fp_output_fun)(I64 i);
    F64          percentile;
    if (!tmpc)
        return;
    CMemberList *ml;

    ml = tmpc->member_list_and_root;
    while (ml)
    {
        "%s:", ml->str;

        //All our items are I64's.  If you want, you can check
        //the data type of the member variable.  See ClassRep().
        q = _d + ml->offset;

        if (print_str = MemberMetaData("print_str", ml))
            "" print_str, *q;

            //This is slightly ambiguous -- if no meta is present it will return zero.
        if (default_val = MemberMetaData("default_val", ml))
            " default:%d", default_val;

            //This corrects for the ambiguity, allowing zero percentile.
        if (MemberMetaFind("percentile", ml))
        {//check if it exists
            //We could use the CMemberListMeta structure returned by
            //MemberMetaFind() and save a search.
            percentile = MemberMetaData("percentile", ml)(F64);
            " percentile: %5.2f", percentile;
        }

        if (fp_output_fun = MemberMetaData("output_fun", ml))
            (*fp_output_fun)(*q);
        '\n';
        ml = ml->next;
    }
}

Test1Struct t1;
t1.age  = 44;
t1.rank = 3;

DumpStruct(&t1);

Test2Struct t2;
t2.age          = 22;
t2.rank         = 2;
t2.serial_num   = 55555;

DumpStruct(&t2);