- Notifications
You must be signed in to change notification settings - Fork0
Here I present my way to implement Fortran templates for create dynamic data structures using preprocessor directives.
License
alexispaz/FortranTemplates
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A set offortran templates to createdynamic data structures usingpreprocessor directives.
A data structure for an arbitrary data type can be easily constructed bydefining a few preprocessor variables and including the corresponding filesdistributed in theinclude folder as it is shown inthe simple examplebelow.
Further examples can be found in thesrc folder. Compile those usingautotools:
autoreconf -fi && ./configure && makeor meson:
meson setup build --prefix=$PWD/usr --reconfigure && meson install -C build/To compile the following example, do not forget to add-I$(path_to_include_files) and use.F90 extension to activate preprocessing.
module intrinsic_class! Here we declare the type of the dynamic data structure (DDS)! 1. _NODE define the name of the data type of the DDS! 2. _CLASS or _TYPE is the data type of the objects handle by the DDS. ! If the DDS use _CLASS, it can be polymorphic. If not, it use _TYPE! 3. include file name allow to select between the different DDS, e.g linked list, double linked list, etc. #define _NODE integer_dlist#define _CLASS integer#include "dlist_header.inc"contains! Here we declare the procedures of the new integer_dlist DDS.! Definition should match the one used in the header#define _NODE integer_dlist#define _CLASS integer#include "dlist_body.inc"end module intrinsic_classprogram exampleuse intrinsic_classtype(integer_dlist),target:: rlisttype(integer_dlist),pointer:: ptrinteger,target :: iinteger :: ji=3! Add, allocate and copy and item (i.e. allocated in the list)! rlist: head -> 2 call rlist%add_after()call rlist%next%source(2)! Add second item! rlist: head -> 3 -> 2 call rlist%add_after()call rlist%next%source(i)! Add third item as a pointer (i.e. allcoated elswhere) ! rlist: head -> o -> 3 -> 2 with o -> icall rlist%add_after()call rlist%next%point(i)! Print the list (output: 3 3 2)ptr=>rlistdo j=1,3 ptr=>ptr%next print *, ptr%oend do ! Change the target of the first nodei=4! Print the list (output: 4 3 2)ptr=>rlistdo j=1,3 ptr=>ptr%next print *, ptr%oend do end program exampleHARD andSOFT modes can be activated by a preprocesor variable. For example
#SOFT#define _NODE integer_dlist#define _CLASS integer#include "dlist_body.inc"ASOFT declaration means that objects in the structure can only be pointers.
AHARD declaration means that objects will be allocated in each node.
If neitherSOFT orHARD is used, then the strucutre can hold pointers orallocations.
#declare _NODE <LL name> #declare _CLASS <data type> #include list_header.incAny other type or object can be used. A common way to iterate might be:
type(_NODE),pointer :: headclass(_NODE),pointer :: node...node => headdo while(associated(node)) ... !work with node%obj ("cycle" do not advance the node) node => node%nextenddoThe problem with this iteration is that acycle fortran keyword will skip theadvance of the node pointer to the next element. To fix that, I just skip(avoid to use) the data object associated with first node of the list (thehead node) and start the iteration in this way:
node => headdo while(associated(node%next)) node => node%next ... !work with node%obj ("cycle" advance the list) enddoSame that LL but it also allows to iterate backwards:
node => taildo while(associated(node)) ... !work with node%obj node => node%prevenddoTo makecycle keyword work, seeLL template
CDLL might not have any particular head, so to iterate it requires to keep atotal count of the items to avoid infinite loops. Leaving the first node with anull obj might be a way to avoid tracking the number of items:
node => head%nextdo while(associated(node%obj)) ... !work with node%obj node => node%nextenddoCDLL simplify the procedures of adding and removing nodes avoiding theassociation check needed for the beginning and final nodes of a DLL.
CDLL requires a constructor, which is in contrast to LL and DLL.
Other way to iterate that does not require empty head
node => head%prevdo node => node%next ... !work with node%obj if(associated(node%next,alist)) exitenddoAn array that automatically reallocate when needed.
An array of a user defined type that contains a pointer. With this structureeach element of the array might point to a different target.
Fortran Preprocessor Templates for Dynamic Data Structures (FPT-DDS) is hostedingithub with a BSD 3-Clause License.
About
Here I present my way to implement Fortran templates for create dynamic data structures using preprocessor directives.
Resources
License
Uh oh!
There was an error while loading.Please reload this page.