Type detection: Difference between revisions

Line 294:
I don't know how to print this.
</pre>
 
=={{header|Fortran}}==
 
Fortran 2008 and later can do this with general types, using ‘class(*)’.
 
Polymorphism involving types derived from a base type can be done in Fortran 2003 and later.
 
There is also an overload mechanism that can be used to give procedures that take different types the same name, but I presume the task is for run-time type polymorphism rather than for templates or overloads.
 
Below I use ‘class(*)’, which seems best to satisfy the task description. The ‘print_text’ subroutine is used to print a string, an array of strings, and an input file.
 
<lang fortran>program input_type_detection_demo
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
type(text_block_t) :: text_block
integer :: i
 
call print_text ('Print me.')
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text (source)
class(*), intent(in) :: source
 
select type (source)
 
type is (character(len = *))
! Print a single character string.
write (*, '(A)') source
 
class is (text_block_t)
! Print an array of lines.
block
integer :: i
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end block
 
type is (integer)
! Print a file.
block
character(len = 10000) :: line_buffer
integer :: stat
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end block
 
class default
! There is no handler for the type.
error stop
 
end select
end subroutine print_text
 
end program input_type_detection_demo</lang>
 
{{out}}
$ gfortran type_detection-fortran.f90 && ./a.out
<pre>Print me.
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
program input_type_detection_demo
implicit none
 
type text_block_t
character(len = 10000), allocatable :: lines(:)
end type text_block_t
 
type(text_block_t) :: text_block
integer :: i
 
call print_text ('Print me.')
 
allocate (text_block%lines(1:10))
do i = 1, 10
write (text_block%lines(i), '("i = ", I0)') i
end do
call print_text (text_block)
 
open (100, file = 'type_detection-fortran.f90', action = 'read')
call print_text (100)
close (100)
 
contains
 
subroutine print_text (source)
class(*), intent(in) :: source
 
select type (source)
 
type is (character(len = *))
! Print a single character string.
write (*, '(A)') source
 
class is (text_block_t)
! Print an array of lines.
block
integer :: i
do i = lbound (source%lines, 1), ubound (source%lines, 1)
write (*, '(A)') trim (source%lines(i))
end do
end block
 
type is (integer)
! Print a file.
block
character(len = 10000) :: line_buffer
integer :: stat
read (source, '(A)', iostat = stat) line_buffer
do while (stat == 0)
write (*, '(A)') trim (line_buffer)
read (source, '(A)', iostat = stat) line_buffer
end do
end block
 
class default
! There is no handler for the type.
error stop
 
end select
end subroutine print_text
 
end program input_type_detection_demo</pre>
 
=={{header|Go}}==
1,448

edits