From a2796e645c1abbaf31d91e9632747e21b51d7503 Mon Sep 17 00:00:00 2001
From: Martin Beseda <martinbeseda@seznam.cz>
Date: Sun, 3 Jun 2018 01:04:31 +0200
Subject: [PATCH] NEW: Added classes abstract_base_t and container_t.

---
 src/CMakeLists.txt      |  25 +++----
 src/abstract_base_m.f90 |  25 +++++++
 src/container_m.f90     | 149 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+), 12 deletions(-)
 create mode 100644 src/abstract_base_m.f90
 create mode 100644 src/container_m.f90

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0712789d..b6db2876 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,29 +1,30 @@
 project(Modules)
 enable_language(Fortran)
 
+set_property(GLOBAL PROPERTY LINKER_LANGUAGE Fortran)
+
+
+add_library(abstract_base_m SHARED abstract_base_m.f90)
+
 add_library(normal_m SHARED normal_m.f90)
-set_target_properties(normal_m PROPERTIES LINKER_LANGUAGE Fortran)
 
 add_library(data_kinds_4neuro_m SHARED data_kinds_4neuro_m.f90)
-set_target_properties(data_kinds_4neuro_m PROPERTIES LINKER_LANGUAGE Fortran)
+
+add_library(container_m SHARED container_m.f90)
+target_link_libraries(container_m abstract_base_m data_kinds_4neuro_m)
 
 add_library(time_measurement_m SHARED time_measurement_m.f90)
-set_target_properties(time_measurement_m PROPERTIES LINKER_LANGUAGE Fortran)
-target_link_libraries(time_measurement_m data_kinds_4neuro_m)
+target_link_libraries(time_measurement_m data_kinds_4neuro_m abstract_base_m)
 
 add_library(neuron_m SHARED neuron_m.f90)
-set_target_properties(neuron_m PROPERTIES LINKER_LANGUAGE Fortran)
-target_link_libraries(neuron_m time_measurement_m normal_m)
+target_link_libraries(neuron_m time_measurement_m normal_m abstract_base_m)
 
 add_library(connection_m SHARED connection_m.f90)
-set_target_properties(connection_m PROPERTIES LINKER_LANGUAGE Fortran)
-target_link_libraries(connection_m neuron_m time_measurement_m normal_m)
+target_link_libraries(connection_m neuron_m time_measurement_m normal_m abstract_base_m)
 
 add_library(interconnection_m SHARED net_m.f90)
-set_target_properties(interconnection_m PROPERTIES LINKER_LANGUAGE Fortran)
-target_link_libraries(interconnection_m data_kinds_4neuro_m time_measurement_m)
+target_link_libraries(interconnection_m data_kinds_4neuro_m time_measurement_m abstract_base_m)
 
 add_library(net_m SHARED net_m.f90)
-set_target_properties(net_m PROPERTIES LINKER_LANGUAGE Fortran)
-target_link_libraries(net_m interconnection_m data_kinds_4neuro_m time_measurement_m neuron_m connection_m)
+target_link_libraries(net_m interconnection_m data_kinds_4neuro_m time_measurement_m neuron_m connection_m abstract_base_m)
 
diff --git a/src/abstract_base_m.f90 b/src/abstract_base_m.f90
new file mode 100644
index 00000000..81849449
--- /dev/null
+++ b/src/abstract_base_m.f90
@@ -0,0 +1,25 @@
+!> Module containing a class abstract_base_t, which is a parental 
+!! class for all other classes in 4neuro. It makes creating a 
+!! common container for all classes possible.
+!!
+!! @author Martin Beseda
+!! @date 2018
+module abstract_base_m
+
+    implicit none
+
+    public
+
+    !------------------!-----------------------------------------
+    ! Type definitions !
+    !------------------!    
+
+    !-----------------------!------------------------------------
+    ! class abstract_base_t !
+    !-----------------------!
+
+    !> Abstract class covering all the other classes in 4neuro
+    type, abstract :: abstract_base_t
+    end type
+
+end module abstract_base_m
diff --git a/src/container_m.f90 b/src/container_m.f90
new file mode 100644
index 00000000..9e484020
--- /dev/null
+++ b/src/container_m.f90
@@ -0,0 +1,149 @@
+!> Module containing declaration of a container type 'container_t'.
+!! This class "wraps" pointers, so it's possible to store them
+!! into arrays.
+!!
+!! @author Martin Beseda
+!! @date 2018
+module container_m
+    use abstract_base_m
+    use data_kinds_4neuro_m
+
+    implicit none
+
+    public
+
+    !> Represents a container for a single container_t pointer
+    type :: container_t
+        private
+        class(abstract_base_t), pointer :: content
+
+    contains
+        !> Getter for the private 'content' component
+        !! @return Pointer to the contained container (type container_t, pointer)
+        procedure :: get_content => get_content_container_impl
+
+        !> Setter for the private 'content' component
+        !! @param[in] content Pointer to the container (type container_t, pointer)
+        procedure :: set_content => set_content_container_impl
+
+        !> Scalar desctructor for single instances of the class container_t
+        final :: destroy_container
+
+        !> Array desctructor for arrays of instances of the class container_t
+        final :: destroy_container_array
+
+    end type container_t
+
+    interface container_t
+        !> Constructor of container_t class
+        !! @return Instance of the class container_t with nullified content
+        module procedure :: new_container_empty
+
+        !> Constructor of container_t class
+        !! @param[in] content_in container to be contained (pointer)
+        !! @return Pointer to the instance of the class container_t with assigned content
+        module procedure :: new_container_assigned
+    end interface container_t
+
+contains
+        !--------------!------------------------------------------------------------------------
+        ! Constructors !
+        !--------------!
+
+        !> Constructor of container_t class
+        !! @return Instance of the class container_t with nullified content
+        function new_container_empty() result(new_obj)
+            type(container_t) :: new_obj
+#ifdef TIME_PROFILING
+            real                                 :: start_time
+            call time_profiling_start(start_time)
+#endif
+            new_obj%content => null()
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time, 'new_container_empty')
+#endif
+        end function new_container_empty
+
+        !> Constructor of container_t class
+        !! @param[in] content_in connection to be contained (pointer)
+        !! @return Pointer to the instance of the class connection_t with assigned content
+        function new_container_assigned(content_in) result(new_obj)
+            class(abstract_base_t), pointer, intent(in) :: content_in
+            type(container_t)                           :: new_obj
+#ifdef TIME_PROFILING
+            real                                        :: start_time
+            call time_profiling_start(start_time)
+#endif
+            new_obj%content => content_in
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time, 'new_container_assigned')
+#endif
+        end function new_container_assigned
+
+        !--------------!------------------------------------------------------------------------
+        ! Destructors  !
+        !--------------!
+        !> Scalar desctructor for single instances of the class container_t
+        subroutine destroy_container(this)
+            type(container_t), intent(inout) :: this
+#ifdef TIME_PROFILING
+            real                              :: start_time
+            call time_profiling_start(start_time)
+#endif
+            nullify(this%content)
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time, 'destroy_container')
+#endif
+        end subroutine destroy_container
+
+        !> Array desctructor for arrays of instances of the class container_t
+        subroutine destroy_container_array(this)
+            type(container_t), intent(inout) :: this(:)
+            integer :: i
+#ifdef TIME_PROFILING
+            real                              :: start_time
+            call time_profiling_start(start_time)
+#endif
+            do i = 1, size(this)
+                nullify(this(i)%content)
+            end do
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time, 'destroy_container_array')
+#endif
+        end subroutine destroy_container_array
+
+        !-------------------!------------------------------------------------------------------
+        ! Getters & Setters !
+        !-------------------!
+
+        !> Getter for the private 'content' component
+        !! @return Pointer to the contained connection (type connection_t, pointer)
+        function get_content_container_impl(this) result(content)
+            class(container_t), intent(in)   :: this
+            class(abstract_base_t), pointer  :: content
+#ifdef TIME_PROFILING
+            real                             :: start_time
+            call time_profiling_start(start_time)
+#endif
+            content => this%content
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time,'get_content_container_impl')
+#endif
+        end function get_content_container_impl
+
+        !> Setter for the private 'content' component
+        !! @param[in] content Pointer to the connection (type connection_t, pointer)
+        subroutine set_content_container_impl(this, content)
+            class(container_t), intent(inout)           :: this
+            class(abstract_base_t), pointer, intent(in) :: content
+#ifdef TIME_PROFILING
+            real                                        :: start_time
+            call time_profiling_start(start_time)
+#endif
+            this%content => content
+#ifdef TIME_PROFILING
+            call time_profiling_stop(start_time,'set_content_container_impl')
+#endif
+        end subroutine set_content_container_impl
+
+end module container_m
-- 
GitLab