Created
February 16, 2017 03:10
-
-
Save wawiesel/8a0ec409aa91ac0c2261508439335890 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module variant_m | |
use iso_c_binding | |
type variant | |
!type(C_PTR) :: instance | |
end type | |
interface static_cast | |
module procedure static_cast_c_int | |
module procedure static_cast_c_float | |
end interface | |
contains | |
function static_cast_c_int( x ) result(f) | |
integer(c_int),intent(in) :: x | |
type(variant),pointer :: f | |
f=>null() | |
!f%instance = C_NULL_PTR | |
write(*,*)'here c_int with x=',x | |
end function | |
function static_cast_c_float( x ) result(f) | |
real(c_float),intent(in) :: x | |
type(variant),pointer :: f | |
!f%instance = C_NULL_PTR | |
f=>null() | |
write(*,*)'here c_float with x=',x | |
end function | |
function fmt_format(this_fmt,x1,x2,x3,x4,x5,x6,x7) result(string2) | |
character(*),intent(in) :: this_fmt | |
type(variant),optional,pointer,intent(in) :: x1,x2,x3,x4,x5,x6,x7 | |
character(len=:),allocatable :: string2 | |
write(*,*)'in catcher' | |
allocate( character(len=100+len(this_fmt)) :: string2 ) | |
string2='abc'//this_fmt | |
end function | |
subroutine fmt_print_err(this_fmt,x1,x2,x3,x4,x5,x6,x7) | |
character(*),intent(in) :: this_fmt | |
type(variant),optional,pointer,intent(in) :: x1,x2,x3,x4,x5,x6,x7 | |
character(len=:),allocatable :: string2 | |
write(*,*)'in catcher2' | |
string2=fmt_format(this_fmt,x1,x2,x3,x4,x5,x6,x7) | |
write(0,*)string2 | |
end subroutine | |
subroutine fmt_print_out(this_fmt,x1,x2,x3,x4,x5,x6,x7) | |
character(*),intent(in) :: this_fmt | |
type(variant),optional,pointer,intent(in) :: x1,x2,x3,x4,x5,x6,x7 | |
character(len=:),allocatable :: string2 | |
write(*,*)'in catcher3' | |
string2=fmt_format(this_fmt,x1,x2,x3,x4,x5,x6,x7) | |
write(6,*)string2 | |
end subroutine | |
end module | |
program main | |
use variant_m | |
character(len=:),allocatable :: string,string2 | |
write(*,*)'before' | |
string2= fmt_format( "{}", static_cast(0.5) ) | |
string2= fmt_format( "{}{}", static_cast(1), static_cast(0.7) ) | |
call fmt_print_out( "{}{}", static_cast(1), static_cast(0.7) ) | |
call fmt_print_err( "{}{}", static_cast(1), static_cast(0.7) ) | |
end program |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a proof of principle for how we can create some fortran bindings to the awesome C++ fmt library. Basically we need a macro that takes something like
fmt_format_macro( "{}{}", x, y) and expands to fmt_format("{}{}",static_cast(x),static_cast(y)) which will call the overloaded static_cast function which will take any of the C-bound fortran types and return a "variant" which is a fortran binding to a c-type that is the union of all types. This type will become the pivot for calling "fmt::format" on the C++ side. We'll basically have to provide UP to some number of arguments (like 20)?
Clear as mud?