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