! This file is part of mctc-lib. ! ! Licensed under the Apache License, Version 2.0 (the "License"); ! you may not use this file except in compliance with the License. ! You may obtain a copy of the License at ! ! http://www.apache.org/licenses/LICENSE-2.0 ! ! Unless required by applicable law or agreed to in writing, software ! distributed under the License is distributed on an "AS IS" BASIS, ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ! See the License for the specific language governing permissions and ! limitations under the License. !> Reallocation implementation for resizing arrays module mctc_io_resize use mctc_env_accuracy, only : wp implicit none private public :: resize !> Overloaded resize interface interface resize module procedure :: resize_char module procedure :: resize_int module procedure :: resize_logical module procedure :: resize_real module procedure :: resize_real_2d end interface resize !> Initial size for dynamic sized arrays integer, parameter :: initial_size = 64 contains !> Reallocate list of integers pure subroutine resize_int(var, n) !> Instance of the array to be resized integer, allocatable, intent(inout) :: var(:) !> Dimension of the final array size integer, intent(in), optional :: n integer, allocatable :: tmp(:) integer :: this_size, new_size if (allocated(var)) then this_size = size(var, 1) call move_alloc(var, tmp) else this_size = initial_size end if if (present(n)) then new_size = n else new_size = this_size + this_size/2 + 1 end if allocate(var(new_size)) if (allocated(tmp)) then this_size = min(size(tmp, 1), size(var, 1)) var(:this_size) = tmp(:this_size) deallocate(tmp) end if end subroutine resize_int !> Reallocate list of characters pure subroutine resize_char(var, n) !> Instance of the array to be resized character(len=*), allocatable, intent(inout) :: var(:) !> Dimension of the final array size integer, intent(in), optional :: n character(len=:), allocatable :: tmp(:) integer :: this_size, new_size if (allocated(var)) then this_size = size(var, 1) call move_alloc(var, tmp) else this_size = initial_size end if if (present(n)) then new_size = n else new_size = this_size + this_size/2 + 1 end if allocate(var(new_size)) if (allocated(tmp)) then this_size = min(size(tmp, 1), size(var, 1)) var(:this_size) = tmp(:this_size) deallocate(tmp) end if end subroutine resize_char !> Reallocate list of logicals pure subroutine resize_logical(var, n) !> Instance of the array to be resized logical, allocatable, intent(inout) :: var(:) !> Dimension of the final array size integer, intent(in), optional :: n logical, allocatable :: tmp(:) integer :: this_size, new_size if (allocated(var)) then this_size = size(var, 1) call move_alloc(var, tmp) else this_size = initial_size end if if (present(n)) then new_size = n else new_size = this_size + this_size/2 + 1 end if allocate(var(new_size)) if (allocated(tmp)) then this_size = min(size(tmp, 1), size(var, 1)) var(:this_size) = tmp(:this_size) deallocate(tmp) end if end subroutine resize_logical !> Reallocate list of reals pure subroutine resize_real(var, n) !> Instance of the array to be resized real(wp), allocatable, intent(inout) :: var(:) !> Dimension of the final array size integer, intent(in), optional :: n real(wp), allocatable :: tmp(:) integer :: this_size, new_size if (allocated(var)) then this_size = size(var, 1) call move_alloc(var, tmp) else this_size = initial_size end if if (present(n)) then new_size = n else new_size = this_size + this_size/2 + 1 end if allocate(var(new_size)) if (allocated(tmp)) then this_size = min(size(tmp, 1), size(var, 1)) var(:this_size) = tmp(:this_size) deallocate(tmp) end if end subroutine resize_real !> Reallocate list of reals pure subroutine resize_real_2d(var, n) !> Instance of the array to be resized real(wp), allocatable, intent(inout) :: var(:,:) !> Dimension of the final array size integer, intent(in), optional :: n real(wp), allocatable :: tmp(:,:) integer :: order, this_size, new_size if (allocated(var)) then order = size(var, 1) this_size = size(var, 2) call move_alloc(var, tmp) else order = 3 this_size = initial_size end if if (present(n)) then new_size = n else new_size = this_size + this_size/2 + 1 end if allocate(var(order, new_size)) if (allocated(tmp)) then this_size = min(size(tmp, 2), size(var, 2)) var(:, :this_size) = tmp(:, :this_size) deallocate(tmp) end if end subroutine resize_real_2d end module mctc_io_resize