- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Since the standard allows us to use User-Defined Derived-Type I/O (The Formatted/Unformatted Read/Write), Is there any good ideas that It can be accomplished for unlimited polymorphic entities? unlimited polymorphic entities can be any type, intrinsic and derived. So should all the possibilities be evaluated in a SELECT TYPE structure or is there any shortcuts for doing that ? The former indeed could be a massive amount of work if there's a lot of user-defined derived types waits. Appriciate any suggestion.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All I can think of is to have SELECT TYPE cases for possible intrinsic types (and kinds), and then for derived types use TYPE DEFAULT and reference a type-bound procedure for the type that does whatever is needed for the output. I agree it is a lot of work and maybe there's a different approach to structuring your application that would make this unnecessary.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Steve. It seems this maybe the only way. I'll rethink about the structure issues.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
File i/0 with derived types can be very straightforward if you use the WinAPI functions directly, since they provide the granular control which is needed (and is missing from Fortran); on Windows, this is what the Fortran functions are converted to anyway by the compiler. So file i/o for an array of a UDT with arbitrary content becomes:
CALL rw_file ('W', ihandl, array_size*SIZEOF(yourUDT), LOC(yourUDT), 0)
where the file has previously been opened and is denoted by handle ihandl.
RECURSIVE SUBROUTINE rw_file (rwmode, ihandl, nbytes, loc_pointer, offset) IMPLICIT NONE SAVE CHARACTER(LEN=1), INTENT(IN) :: rwmode INTEGER(HANDLE), INTENT(IN) :: ihandl INTEGER, INTENT(IN) :: nbytes, loc_pointer INTEGER, INTENT(IN), OPTIONAL :: offset INTEGER :: rval INTEGER :: nact ! position pointer if offset is provided IF (PRESENT(offset)) rval = SetFilePointer (ihandl, offset, NULL, FILE_BEGIN) IF (rwmode == 'R') THEN IF (ReadFile (ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to read LOC(nact), & ! actual bytes read NULL_OVERLAPPED) == 0) THEN banner(1) = 'Error reading file' CALL API_error (851, 1) END IF ELSE IF (WriteFile (ihandl, & ! file handle loc_pointer, & ! address of data nbytes, & ! byte count to write LOC(nact), & ! actual bytes written NULL_OVERLAPPED) == 0) THEN banner(1) = 'Error writing file' CALL API_error (852, 1) END IF END IF END SUBROUTINE rw_file
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Paul Curtis wrote:
File i/0 with derived types can be very straightforward if you use the WinAPI functions directly, since they provide the granular control which is needed (and is missing from Fortran); on Windows, this is what the Fortran functions are converted to anyway by the compiler. So file i/o for an array of a UDT with arbitrary content becomes:
CALL rw_file ('W', ihandl, array_size*SIZEOF(yourUDT), LOC(yourUDT), 0)
This approach excludes derived types with type parameters, ultimate pointer components, or ultimate allocatable components - which is an approximate superset of the types that require user defined io procedures in the first place (otherwise Fortran unformatted io pretty much already does this).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Ianh-- why yes, my approach "excludes derived types with type parameters, ultimate pointer components, or ultimate allocatable components..."
I must be a newbie, only written maybe a million lines of Fortran over the last 40+ years, but I cannot imagine a context for which any of that stuff would be appropriate, and which would clearly render a program completely unfixable when it goes off the rails. Only my minority report; good luck to you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The API approach solves the problem. I'm here more to seek a Fortran way to do that, thanks for your suggestion, Paul and lanH.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page