Type detection: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) |
|||
Line 294: | Line 294: | ||
I don't know how to print this. |
I don't know how to print this. |
||
</pre> |
</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}}== |
=={{header|Go}}== |