Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Starting work on static members #3

Merged
merged 1 commit into from
Feb 12, 2017
Merged

[WIP] Starting work on static members #3

merged 1 commit into from
Feb 12, 2017

Conversation

aprokop
Copy link
Collaborator

@aprokop aprokop commented Jan 22, 2017

So far, the wrapper and proxy codes are generated. The remaining issue is: what is the proper access model to those functions in Fortran? I'm not sure, does Fortran have a concept of static member variables/functions?

@aprokop
Copy link
Collaborator Author

aprokop commented Jan 22, 2017

It seems like there is a nopass attribute. Is that what I should use?

@aprokop
Copy link
Collaborator Author

aprokop commented Jan 22, 2017

In case you missed the thread, @sethrj @youngmit

@aprokop
Copy link
Collaborator Author

aprokop commented Jan 22, 2017

Assuming i is a static member variable, would the proper .f90 be something like this:

! This file was automatically generated by SWIG (http://www.swig.org).
! Version 3.0.12
!
! Do not make changes to this file unless you know what you are doing--modify
! the SWIG interface file instead.
module static_members
 use, intrinsic :: ISO_C_BINDING
 implicit none

 ! PUBLIC METHODS AND TYPES
 public :: BaseClass
 ! TYPES
 type :: BaseClass
  type(C_PTR), private :: ptr = C_NULL_PTR
  logical, private :: own = .false.
 contains
  procedure :: create => swigf_new_BaseClass
  procedure :: release => swigf_delete_BaseClass
  procedure, nopass :: get_i => swigf_get_BaseClass_i
  procedure, nopass :: set_i => swigf_set_BaseClass_i
 end type

 ! WRAPPER DECLARATIONS
 private
 interface
  subroutine swigc_set_BaseClass_i(farg1) &
     bind(C, name="swigc_set_BaseClass_i")
   use, intrinsic :: ISO_C_BINDING
   integer(C_INT), intent(in) :: farg1
  end subroutine
  function swigc_get_BaseClass_i() &
     bind(C, name="swigc_get_BaseClass_i") &
     result(fresult)
   use, intrinsic :: ISO_C_BINDING
   integer(C_INT) :: fresult
  end function
  function swigc_new_BaseClass() &
     bind(C, name="swigc_new_BaseClass") &
     result(fresult)
   use, intrinsic :: ISO_C_BINDING
   type(C_PTR) :: fresult
  end function
  subroutine swigc_delete_BaseClass(farg1) &
     bind(C, name="swigc_delete_BaseClass")
   use, intrinsic :: ISO_C_BINDING
   type(C_PTR), value :: farg1
  end subroutine
 end interface

contains
  ! FORTRAN PROXY CODE
  subroutine swigf_set_BaseClass_i(i)
   use, intrinsic :: ISO_C_BINDING
   integer(C_INT), intent(in) :: i
   call swigc_set_BaseClass_i(i)
  end subroutine
  function swigf_get_BaseClass_i() &
     result(fresult)
   use, intrinsic :: ISO_C_BINDING
   integer(C_INT) :: fresult
   fresult = swigc_get_BaseClass_i()
  end function
  subroutine swigf_new_BaseClass(self)
   use, intrinsic :: ISO_C_BINDING
   class(BaseClass) :: self
   if (c_associated(self%ptr)) call self%release()
   self%ptr = swigc_new_BaseClass()
   self%own = .true.
  end subroutine

 subroutine swigf_delete_BaseClass(self)
   use, intrinsic :: ISO_C_BINDING
   class(BaseClass) :: self
   if (self%own) then
    call swigc_delete_BaseClass(self%ptr)
    self%own = .false.
   end if
   self%ptr = C_NULL_PTR
  end subroutine
end module static_members

and the test be

#define ASSERT(conditional) \
if (.not. conditional) then; \
  stop 1; \
endif


program test_static
use static_members

class(BaseClass), pointer :: v1 => null()
class(BaseClass), pointer :: v2 => null()

! Set variables
call v1%create()
call v1%set_i(2)
ASSERT(v1%get_i() == 2)

call v2%create()
call v2%set_i(3)
ASSERT(v1%get_i() == 3)

call v1%release()
call v2%release()

deallocate(v1)
deallocate(v2)

end program

or something else?

@aprokop
Copy link
Collaborator Author

aprokop commented Jan 25, 2017

I've updated the PR. I think static variables and functions should work now.

@aprokop
Copy link
Collaborator Author

aprokop commented Jan 25, 2017

I should mention the way things are done now. For every static member variable, SWIG generates a C++ wrapper called something like swigc_set_ClassName_VariableName with a corresponding Fortran proxy code. In the Fortran class interface, I rename them to set_VariableName and get_VariableName. Potentially, this may lead to collision when the class already has a function with that name, as I believe it would be mapped to the same API.

I'm not going to worry about that for now. I think for Trilinos that is going to be a rare case, partly because of the CamelCase style of function names.

@wawiesel
Copy link

wawiesel commented Feb 12, 2017

Seth asked me to weigh in here if I thought of anything to add. I am a long time Fortran user and know a fair bit of C++ as well. In C++ you can call a static either of these ways:

BaseClass::set_i(10); 
//or
BaseClass instance;
instance.set_i(10); 

but unfortunately OO Fortran doesn't really have the first concept. The NOPASS gives you the second, but for the first, you really just need to call the underlying function:

!Fortran equivalent of C++ BaseClass::set_i(10)
call BaseClass_set_i(10)

For this reason, you might want to make sure fortran-bound statics have good names and are public.

@sethrj sethrj merged commit b65853b into swig-fortran:fortran Feb 12, 2017
sethrj pushed a commit that referenced this pull request Apr 28, 2017
"CID 11151 (#3-1 of 3): Using invalid iterator (INVALIDATE_ITERATOR)18.
increment_iterator: Incrementing iterator it though it is already past
the end of its container."

Coverity does not understand 'replace_count', so warns that we may go
past self->end() (or self->rend() I guess).
sethrj pushed a commit that referenced this pull request Feb 2, 2022
os.system calls migrated to subprocess.call / Popen api calls in Tools/mkdist.py
sethrj pushed a commit that referenced this pull request Feb 2, 2022
OPTIM: Restructured the code where it checks for V8 version
sethrj pushed a commit that referenced this pull request Feb 2, 2022
sethrj pushed a commit that referenced this pull request Feb 2, 2022
* pr/new-node-fixes:
  Travis testing: Node 12 support not fully working yet
  Revert "Merge pull request #3 from tungntpham/new-node-fixes-refactor"
  OPTIM: Restructured the code where it checks for V8 version, removing duplicate code and potentially improving the readability.
  Nodejs: run tests against Node.js v12
  Add support for Node.js v12
  Replace Handle with Local depending on Node.js version
  Introduce macros to support both Handle and Local types
sethrj pushed a commit that referenced this pull request Feb 2, 2022
)

Use SWIG_TypeCast in SWIG_V8_ConvertInstancePtr if types don't match
sethrj pushed a commit that referenced this pull request Dec 1, 2022
)

Use SWIG_TypeCast in SWIG_V8_ConvertInstancePtr if types don't match
sethrj pushed a commit that referenced this pull request Dec 1, 2022
* fix-cast:
  add tests for new casting behavior
  skip tests when value is out of range
  refactor integers JS testcase to avoid repeating code
  Return uint64_t as double if is bigger than uint32_t
  Use SWIG_TypeCast in SWIG_V8_ConvertInstancePtr if types don't match (#3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants