Floating Insertions
===================

A floating insertion is a string containing C/C++ code which is literally
inserted into the C++ that Felix generates.

Insertion Locations
-------------------


There are two locations for the insertion:

  1. *header* insertions go near the top of the generated header file
  2. *body* insertions go near the top of the generated body file *after* 
     `#include` directives, but before any definitions generated by Felix


.. code-block:: felix

   header '#include "interface"`;
   body 'void implementation() {}';


Polymorphic Insertions
----------------------

There are two kinds of insertions:

  1. plain insertions
  2. polymorphic insertions

A plain insertion is inserted as written. A polymorphic insertion is
inserted as written except that it may contain type parameters written
using the `?9` kind of notation. Polymorphic insertions must be named
and dummy parameters specified, as with a C type binding:

.. code-block:: felix

  //$ In place list reversal: unsafe!
  // second arg is a dummy to make overload work
  proc rev[T,PLT=&list[T]] : &list[T] = "_rev($1,(?1*)0);" requires _iprev_[T,PLT];

  body _iprev_[T,PLT]=
    """
    static void _rev(?2 plt, ?1*) // second arg is a dummy
    { // in place reversal
      struct node_t { void *tail; ?1 elt; };
      void *nutail = 0; 
      void *cur = *plt;
      while(cur)
      {
        void *oldtail = ((node_t*)FLX_VNP(cur))->tail;   // save old tail in temp
        ((node_t*)FLX_VNP(cur))->tail = nutail;          // overwrite current node tail
        nutail = cur;                                   // set new tail to current
        cur = oldtail;                                  // set current to saved old tail
      }
      *plt = nutail;                                    // overwrite 
    }
    """
  ;

In this example we defined a function `_rev` in C++, used to reverse a list in place.
The insertion containing it, `_iprev_[T,PLT]` is polymorphic, the actuual types
are specified in the C bindings for `rev`.

Requires Clause
---------------

C bindings may specify a `requires` clause with a list of requirements.
For floating insertions there are three options:

  1. require literally given header
  2. require literally given body
  3. require by insertion tag name

Insertions themselves may have requirements.

Tag names
---------

Insertion tag names are scoped by classes and may require explicit
qualification. However the tag namespace is independent of ordinary
definitions.

Any number of insertions may have the same tag name.


Closure Formation
-----------------

When a named requirement is triggered, all the insertions with
that tag name, and any insertions they themselves require,
recursively, will be inserted. Requiring a non-existant tag
is an error.

Circular references are permitted.

Order of Insertion
------------------

Insertion of the same kind defined in the same Felix file retain
their order in the generated output, in otherwords, they're emitted
in the order of writing, not the order of dependence.

If a text has been emitted, it will not be emitted again:
duplication is eliminated. Note this rule applies to polymorphic
insertions *after* substitution of types.

Global Insertions
-----------------

An unnamed insertion specified by a `requires` statement
is taken as a requirement of all C bindings and floating 
insertions in the class containing it, including any nested
classes.

Triggering Insertions
---------------------

Insertions are only triggered if the C binding or insertion
they're attached to is actually used in the final program.
This reduces the output to what is actually needed.




