Skip to content

Instantly share code, notes, and snippets.

@wawiesel
Created February 16, 2017 03:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wawiesel/8a0ec409aa91ac0c2261508439335890 to your computer and use it in GitHub Desktop.
Save wawiesel/8a0ec409aa91ac0c2261508439335890 to your computer and use it in GitHub Desktop.
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
@wawiesel
Copy link
Author

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment