1.6. Generic primitive bindings

Felix provides a way of creating generic primitive bindings. A generic binding is a binding to a family of C++ types, functions, or procedured, parameterised by one or more types. Generic bindings are roughly equivalent to templates, and can be used to bind to templates, although that isn't the only use.

Here is a simple example illustrating generic primitive bindings.

Start felix section to tut/examples/tut_bind134.flx[1 /1 ]
     1: #line 376 "./lpsrc/flx_tut_bind.pak"
     2: 
     3: // include STL vector template
     4: header """
     5: #include <iostream>
     6: #include <vector>
     7: """;
     8: 
     9: // declare non-generic primitives int and long
    10: // and some output procedures
    11: type int = "int";
    12: type long = "long";
    13: proc endl:1= "std::cout << std::endl;";
    14: proc print: long = "std::cout << $1;";
    15: 
    16: // define a generic cast
    17: // here ?2 means the second generic type parameter
    18: 
    19: fun cast[t1,t2]:t1->t2 = "(?2)($1)";
    20: print (cast [int,long] 1); endl;
    21: 
    22: // declare generic binding for vector
    23: // ?1 is replaced by the first type argument
    24: // when the type vector is instantiated
    25: // the name t is a placeholder used for consistency
    26: 
    27: type vector[t] = "std::vector<?1>";
    28: 
    29: // declare print routine for vector
    30: // notice that the type 'vector t'
    31: // describes a vector of objects
    32: // of type t, the type of the generic parameter
    33: //
    34: // in a type expression, the generic type vector
    35: // is used 'as a function' and applied to the
    36: // its argument, the parameter t in this case,
    37: // with the same syntax
    38: 
    39: proc vprint[t]: vector[t] = """
    40:   {
    41:     std::vector<?1> v = $1;
    42:     for(
    43:       std::vector<?1>::iterator p = v.begin();
    44:       p != v.end();
    45:       ++p
    46:     )
    47:       std::cout << *p << " ";
    48:   }
    49: """;
    50: 
    51: // a generic procedure for appending to a vector
    52: // this procedure takes a pointer to a vector of t
    53: // and a value of type t and appends the value
    54: // to the vector
    55: proc append[t]:&(vector[t])*t="$1->push_back($2);";
    56: 
    57: // make an empty vector of int
    58: var v : vector[int];
    59: 
    60: // put 1,2,3 into the vector
    61: append[int](&v,1);
    62: append[int](&v,2);
    63: append[int](&v,3);
    64: 
    65: // print the vector
    66: vprint[int] v; endl();
    67: 
End felix section to tut/examples/tut_bind134.flx[1]