Skip to content
Robert Rüger edited this page Dec 17, 2018 · 9 revisions
  • Will the FTL work with my compiler?

    Unfortunately, it will probably only work if you are using a fairly recent compiler that comes with an integreated CPP like preprocessor. The FTL is tested on ifort >17 and gfortran >7 and nagfor 6.2 right now. I try to test everything you could do with the FTL in the set of unit tests included in the repository, so if you sucessfully compile those and they all pass, your compiler should be fine.

    Note that even with gfortran >7, the unit tests currently have a memory leak, due to the fact that gfortran does not implement finalization of function return values. Hopefully, they will fix this at some point.

    I was trying to maintain compatibility with older compilers, but it's just too much of a pain and I don't have the time to implement workarounds for all the bugs in old compilers ...

  • What's the deal with ftlMove and ftlSwap

    ftlMove is a small subroutine that moves the contents of a derived type from one instance to another. All FTL types define this function, so that they can be moved around without unnecessary copies to temporaries. As an example you can think of ftlMove for ftlDynArray as an equivalent to Fortran's move_alloc intrinsic for plain old arrays. ftlSwap is also provided to conveniently swap instances of FTL types.

    It is also a good practice to implement the ftlMove subroutine for the template types that are put into the FTL containers. If a template type provides the ftlMove methods one can define the FTL_TEMPLATE_TYPE_PROVIDES_FTLMOVE macro before template instantiation and the containers will internally use ftlMove where possible, e.g. when shifting the elements in an ftlDynArray after deleting an element in the middle. It is also extremely useful for some of the ftlAlgorithms like ftlSort which need to swap lots of instances of the template type. The performance gains can be massive if the template type is large and expensive to copy. The signature of the ftlMove function could look like this:

    subroutine ftlMove(src, dest)
       type(YourType), intent(inout) :: src
       type(YourType), intent(out)   :: dest

    The intents in this signature are not a requirement, but inout on the source and out on the destination makes sense. You might also want to declare the subroutine elemental, though this is not required by the FTL containers.

    Note that it is not necesssary to define ftlSwap for your template types. After all swapping two instances can always be done by (cheaply) moving to a temporary. So ftlMove is all that is needed.

  • Can I put derived types with owning pointers into FTL containers?

    Yes, you can! The FTL has full support for template types that own resources through pointers. However there are some requirements:

    • Your type should have a defined elemental and type-bound assignment that makes a deep copy, i.e. not only copies the pointers but makes a copy of the data pointed to. The assignment absolutely has to be type-bound. If it is not, it will not be triggered automatically when other derived types containing it are assigned. That would (for some reason) trigger the intrinsic assignment which makes a shallow copy of owning pointers. This issue has been discussed here on StackOverflow. Actually, I see no reason to ever use a non-type bound assigment in modern Fortran code. The assignment also has to be elemental (but can be impure). Otherwise intrinsic assignment would be triggered when assigning arrays of your template type, which happens for example inside ftlDynArray. You probably want an elemental assignment anyway. I can't think of a reason not to make a defined assignment elemental.
    • Your type has to have an elemental finalizer that cleans up the owned resources. All of the cleanup in the FTL relies on the Fortran 2003 finalization. If this is not how your type cleans up after itself, you can currently not put it into FTL containers. Note that the finalizer has to be elemental. Your probably want that anyway for all finalizers, as otherwise the elements of an array of that type are not finalized when the array goes out of scope. Note that you can declare the finalizer impure (that is a Fortran 2008 feature) if necessary. The finalizer should also be safe to call on already finalized objects, i.e. deallocate should be protected by an if(allocated()) and so on.
    • Optionally, your type might also want to implement ftlMove, see the above FAQ entry.

    Have a look at the derived type in instantiations/derived_types/Leaky.f90. This type allocates memory through a pointer and hence requires finalization. That all of this works is tested in the FTL unit tests, so if your type follows this example you should be fine.

  • Can I put polymorphic types into FTL containers?

    No, unfortunately not. At least if you mean having a container of e.g. ShapeType that then stores instances of the derived CircleType and TriangleType. I don't think I can make that possible with the current Fortran standard, at least not for ftlDynArray.

    As a workaround you can make a derived type (e.g. ShapeContainerElement) that contains a single allocatable ShapeType and then put that one into the FTL containers.

  • Can I use the FTL in a proprietary application?

    Yes, you can. Section 3 of the GNU Lesser General Public License permits the inclusion of material from header files into proprietary code. Since the FTL is mostly a collection of header files, (almost) the entire library is covered under section 3. However, if you fix bugs in or otherwise improve the FTL, you are required to publish these changes.

    The Fortran Template Library is an Open Source project supported by Software for Chemistry and Materials BV (SCM). Note that as an exception to the LGPL license, you agree to grant SCM a BSD 3-clause license to the contributions you commit to this Github repository or provide to SCM in another manner.

Clone this wiki locally