!
!  Common array manipulations
!
!  This file is part of Munipack.
!
!  Munipack is free software: you can redistribute it and/or modify
!  it under the terms of the GNU General Public License as published by
!  the Free Software Foundation, either version 3 of the License, or
!  (at your option) any later version.
!  
!  Munipack is distributed in the hope that it will be useful,
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!  GNU General Public License for more details.
!  
!  You should have received a copy of the GNU General Public License
!  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.
!

module muniarrays

  integer, parameter, private :: dbl = selected_real_kind(15)

  interface reallocate
     module procedure reallocate_i,reallocate_s,reallocate_d,reallocate_c
  end interface reallocate

contains

subroutine reallocate_i(x,n)

  implicit none
  integer, dimension(:),allocatable,intent(in out) :: x
  integer :: n
  integer, dimension(:),allocatable :: y
  
  allocate(y(n))

  if( n < size(x) )then
     y = x(1:n)
  else if( n > size(x) )then
     y(1:size(x)) = x
  else
     y = x
  end if

  deallocate(x)
  allocate(x(n))
  x(1:size(y)) = y
  deallocate(y)

end subroutine reallocate_i

subroutine reallocate_s(x,n)

  implicit none
  real, dimension(:),allocatable,intent(inout) :: x
  integer :: n
  real, dimension(:),allocatable :: y
  
  allocate(y(n))

  if( n < size(x) )then
     y = x(1:n)
  else if( n > size(x) )then
     y(1:size(x)) = x
  else
     y = x
  end if

  deallocate(x)
  allocate(x(n))
  x(1:size(y)) = y
  deallocate(y)

end subroutine reallocate_s

subroutine reallocate_d(x,n)

  implicit none
  real(dbl), dimension(:),allocatable,intent(inout) :: x
  integer :: n
  real(dbl), dimension(:),allocatable :: y
  
  allocate(y(n))

  if( n < size(x) )then
     y = x(1:n)
  else if( n > size(x) )then
     y(1:size(x)) = x
  else
     y = x
  end if

  deallocate(x)
  allocate(x(n))
  x(1:size(y)) = y
  deallocate(y)

end subroutine reallocate_d

subroutine reallocate_c(x,n)

  implicit none
  character(len=*), dimension(:),allocatable,intent(inout) :: x
  integer :: n
  character(len=len(x)), dimension(:),allocatable :: y
  
  allocate(y(n))

  if( n < size(x) )then
     y = x(1:n)
  else if( n > size(x) )then
     y(1:size(x)) = x
  else
     y = x
  end if

  deallocate(x)
  allocate(x(n))
  x(1:size(y)) = y
  deallocate(y)

end subroutine reallocate_c

end module muniarrays
