***** Fortran/C
c_ctor_shadow_capptr:
  name: c_ctor_shadow_capptr
  comments:
  - Pass function result as a capsule field of shadow class
  - from Fortran to C.
  intent: ctor
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{cxx_type} *{cxx_var} =\t new {cxx_type}({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{cxx_var});"
  - '{c_var}->idtor = {idtor};'
  owner: caller
c_ctor_shadow_capptr_shared:
  name: c_ctor_shadow_capptr_shared
  comments:
  - Pass function result as a capsule field of shadow class
  - from Fortran to C.
  - Create a std::shared_pointer on the heap to hold the pointer to the instance.
  intent: ctor
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "std::shared_ptr<{baseclass.cxx_type}> *{c_local_shared} =\t new std::shared_ptr<{baseclass.cxx_type}>;"
  - "*{c_local_shared} = \t std::make_shared<{baseclass.cxx_type}>({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{c_local_shared});"
  - '{c_var}->idtor = {idtor};'
  c_local:
  - shared
  impl_header:
  - <memory>
  destructor_header:
  - <memory>
  destructor_name: shadow-{cxx_type}
  destructor:
  - "{cxx_type} *shared =\t reinterpret_cast<{cxx_type} *>(ptr);"
  - shared->reset();
  - delete shared;
  owner: shared
c_ctor_shadow_capsule:
  name: c_ctor_shadow_capsule
  comments:
  - Pass function result as a capsule argument from Fortran to C.
  intent: ctor
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{cxx_type} *{cxx_var} =\t new {cxx_type}({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{cxx_var});"
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  owner: caller
c_dtor:
  name: c_dtor
  comments:
  - Call the C wrapper as a subroutine.
  intent: dtor
  c_call:
  - delete {CXX_this};
  - '{C_this}->addr = {nullptr};'
  c_return_type: void
  impl_header:
  - <cstddef>
  owner: library
  lang_c:
    impl_header:
    - <stddef.h>
  lang_cxx:
    impl_header:
    - <cstddef>
c_function_bool:
  name: c_function_bool
  comments:
  - Call a function.
  intent: function
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
c_function_char:
  name: c_function_char
  comments:
  - Call the C wrapper as a subroutine.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(OUT) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - char *{c_var}
  c_call:
  - '*{c_var} = {C_call_function};'
  c_return_type: void
  owner: library
c_function_char*:
  name: c_function_char*
  comments:
  - Call a function.
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_function_char*_arg:
  name: c_function_char*_arg
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - Change function result into an argument
  - Use F_string_result_as_arg as the argument name.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
c_function_char*_buf_arg:
  name: c_function_char*_buf_arg
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - Change function result into an argument
  - Use F_string_result_as_arg as the argument name.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
c_function_char*_buf_copy:
  name: c_function_char*_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - char *getname() +len(30)
  - Copy result into caller's buffer.
  - XXX - maybe fmtdict to rename c_local_cxx as output
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
c_function_enum:
  name: c_function_enum
  comments:
  - Call a function.
  intent: function
  i_result_decl:
  - '{i_type} :: {i_var}'
  c_post_call:
  - "{c_abstract_decl} {c_var} =\t {cast_static}{c_type}{cast1}{cxx_var}{cast2};"
  owner: library
c_function_native:
  name: c_function_native
  comments:
  - Call a function.
  intent: function
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
c_function_native&:
  name: c_function_native&
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_function_native*:
  name: c_function_native*
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_function_native**:
  name: c_function_native**
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_function_native*_caller:
  name: c_function_native*_caller
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_function_native*_scalar:
  name: c_function_native*_scalar
  intent: function
  i_result_decl:
  - '{f_type} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{i_kind}'
  owner: library
c_function_shadow&_capptr:
  name: c_function_shadow&_capptr
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow&_capptr_caller:
  name: c_function_shadow&_capptr_caller
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow&_capptr_library:
  name: c_function_shadow&_capptr_library
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow&_capsule:
  name: c_function_shadow&_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
c_function_shadow&_capsule_caller:
  name: c_function_shadow&_capsule_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
c_function_shadow&_capsule_library:
  name: c_function_shadow&_capsule_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
c_function_shadow*_capptr:
  name: c_function_shadow*_capptr
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow*_capptr_caller:
  name: c_function_shadow*_capptr_caller
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow*_capptr_library:
  name: c_function_shadow*_capptr_library
  comments:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow*_capptr_shared:
  name: c_function_shadow*_capptr_shared
  comments:
  - Return a C_capsule_data_type.
  notes:
  - std::shared_ptr with a shadow class.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_shadow*_capsule:
  name: c_function_shadow*_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
c_function_shadow*_this:
  name: c_function_shadow*_this
  comments:
  - Call the C wrapper as a subroutine.
  notes:
  - Input set return_this.
  - Do not return anything.
  intent: function
  c_call:
  - '{C_call_function};'
  c_return_type: void
  owner: library
c_function_shadow<native>_capptr:
  name: c_function_shadow<native>_capptr
  comments:
  - Return an instance by value.
  notes:
  - Create memory in c_pre_call so it will survive the return.
  - owner=caller sets idtor flag to release the memory.
  - c_local_var is passed in as argument.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
c_function_shadow_capptr:
  name: c_function_shadow_capptr
  comments:
  - Return an instance by value.
  notes:
  - Create memory in c_pre_call so it will survive the return.
  - owner=caller sets idtor flag to release the memory.
  - c_local_var is passed in as argument.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
c_function_smartptr<shadow>*_capptr:
  name: c_function_smartptr<shadow>*_capptr
  comments:
  - Pass function result as a capsule field of shadow class
  - from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  owner: library
c_function_smartptr<shadow>_capptr:
  name: c_function_smartptr<shadow>_capptr
  comments:
  - Pass function result as a capsule field of shadow class
  - from Fortran to C.
  - Allocate a function result on the heap.
  - Assign to capsule in C wrapper.
  notes:
  - Used with std::shared_ptr<Object>* createChildA(void)
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
c_function_string:
  name: c_function_string
  comments:
  - Cannot return a char array by value.
  intent: function
  i_result_decl:
  - 'character(kind=C_CHAR) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  owner: library
  notimplemented: true
c_function_string&:
  name: c_function_string&
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string&_buf_arg:
  name: c_function_string&_buf_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
c_function_string&_buf_copy:
  name: c_function_string&_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
c_function_string&_copy:
  name: c_function_string&_copy
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string*:
  name: c_function_string*
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string*_buf_copy:
  name: c_function_string*_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
c_function_string*_caller:
  name: c_function_string*_caller
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string*_copy:
  name: c_function_string*_copy
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string*_library:
  name: c_function_string*_library
  comments:
  - Call a function.
  notes:
  - Fortran calling a C function without
  - any api argument - is this useful?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_post_call:
  - '{c_abstract_decl} {c_var} = {cxx_var}{cxx_member}c_str();'
  c_return:
  - return {c_var};
  owner: library
c_function_string_buf_arg:
  name: c_function_string_buf_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
c_function_string_buf_copy:
  name: c_function_string_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
c_function_struct:
  name: c_function_struct
  comments:
  - Call the C wrapper as a subroutine.
  intent: function
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{c_type} *{c_var}'
  c_call:
  - '*{c_var} = {C_call_function};'
  c_return_type: void
  owner: library
c_function_struct*:
  name: c_function_struct*
  comments:
  - C++ pointer -> void pointer -> C pointer.
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
c_function_vector<native>:
  name: c_function_vector<native>
  comments:
  - Cannot return a std::vector<native> by value.
  intent: function
  owner: library
  notimplemented: true
c_function_vector<native>_malloc:
  name: c_function_vector<native>_malloc
  comments:
  - Create empty local vector then copy result to
  - malloc allocated array.
  - Add an argument with the length of the array.
  intent: function
  i_arg_names:
  - '{i_var_size}'
  i_arg_decl:
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - size_t *{c_var_size}
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t {c_local_cxx};"
  c_call:
  - '{c_local_cxx} = {C_call_function};'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "{targs[0].cxx_type} *{c_var} =\t static_cast<{targs[0].cxx_type} *>\t(std::malloc({c_local_bytes}));"
  - "std::memcpy({c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_return_type: '{targs[0].cxx_type} *'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_function_void*:
  name: c_function_void*
  comments:
  - Call a function.
  notes:
  - XXX - f entries are the same as the i entries, share?
  intent: function
  i_result_decl:
  - 'type(C_PTR) :: {f_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_getter_native:
  name: c_getter_native
  intent: getter
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_call:
  - // skip call c_getter
  c_return:
  - return {CXX_this}->{field_name};
  owner: library
c_getter_native*:
  name: c_getter_native*
  intent: getter
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_call:
  - // skip call c_getter
  c_return:
  - return {CXX_this}->{field_name};
  owner: library
c_in_bool:
  name: c_in_bool
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_char:
  name: c_in_char
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), value{f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - char {c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_char*:
  name: c_in_char*
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_char**:
  name: c_in_char**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR), intent(IN) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - char **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_char**_buf:
  name: c_in_char**_buf
  comments:
  - Pass argument, size and len to C.
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "char **{c_local_cxx} = {c_helper_char_array_alloc}({c_var},\t {c_var_size},\t\
    \ {c_var_len});"
  c_post_call:
  - '{c_helper_char_array_free}({c_local_cxx}, {c_var_size});'
  c_temps:
  - size
  - len
  c_local:
  - cxx
  c_helper:
  - char_array_alloc
  - char_array_free
  owner: library
c_in_char*_buf:
  name: c_in_char*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_var_str}'
  c_pre_call:
  - "char * {c_var_str} = {c_helper_char_alloc}(\t{c_var},\t {c_var_len},\t {c_blanknull});"
  c_post_call:
  - '{c_helper_char_free}({c_var_str});'
  c_temps:
  - len
  - str
  c_helper:
  - char_alloc
  - char_free
  owner: library
c_in_enum:
  name: c_in_enum
  notes:
  - Use gen.cidecl to get the C interface type.
  - enums use option.F_enum_type to control the C type.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}, value{f_intent_attr} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{gen.cxxdecl.cxx_var} =\t {gen.c_to_cxx};"
  fmtdict:
    cxx_var: '{CXX_local}{c_var}'
  owner: library
c_in_native:
  name: c_in_native
  notes:
  - An intent of 'none' is used with function pointers
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_native&:
  name: c_in_native&
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_in_native*:
  name: c_in_native*
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_native**:
  name: c_in_native**
  notes:
  - Any array of pointers.  Assumed to be non-contiguous memory.
  - All Fortran can do is treat as a type(C_PTR).
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr}, value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_native*_cdesc:
  name: c_in_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_in_procedure:
  name: c_in_procedure
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'procedure({f_abstract_interface}) :: {i_var}'
  i_import:
  - '{f_abstract_interface}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_procedure_external:
  name: c_in_procedure_external
  notes:
  - EXTERNAL is not allowed in BIND(C), so force wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'procedure({f_abstract_interface}) :: {i_var}'
  i_import:
  - '{f_abstract_interface}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_procedure_funptr:
  name: c_in_procedure_funptr
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_FUNPTR), value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_FUNPTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_shadow:
  name: c_in_shadow
  comments:
  - Pass a shadow type to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr}, value :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} {c_var}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}.addr{cast2};"
  c_local:
  - cxx
  owner: library
c_in_shadow&:
  name: c_in_shadow&
  comments:
  - Pass a shadow type to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_in_shadow*:
  name: c_in_shadow*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_in_smartptr<shadow>*:
  name: c_in_smartptr<shadow>*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_in_string:
  name: c_in_string
  comments:
  - Pass a NULL terminated string to C wrapper
  notes:
  - Pass directly as argument which will construct the std::string.
  - This would work for Fortran if it explicited added C_NULL_CHAR.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - char *{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_string&:
  name: c_in_string&
  notes:
  - Similar to f_in_string*, but c_arg_call is pass by value
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_local:
  - cxx
  owner: library
c_in_string&_buf:
  name: c_in_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var},\
    \ {c_var_len}));"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_len_trim
  owner: library
c_in_string*:
  name: c_in_string*
  comments:
  - Create local std::string from the argument.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_local:
  - cxx
  owner: library
c_in_string*_buf:
  name: c_in_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var},\
    \ {c_var_len}));"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_len_trim
  owner: library
c_in_string_buf:
  name: c_in_string_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - int {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_len});
  - std::string {c_local_cxx}({c_var}, {c_local_trim});
  c_temps:
  - len
  c_local:
  - cxx
  - trim
  c_helper:
  - char_len_trim
  owner: library
c_in_struct:
  name: c_in_struct
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_struct&:
  name: c_in_struct&
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_in_struct*:
  name: c_in_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_unknown:
  name: c_in_unknown
  notes:
  - Used with MPI types
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_vector<native*>&:
  name: c_in_vector<native*>&
  comments:
  - Need to know the length of the vector from C.
  intent: in
  owner: library
  notimplemented: true
c_in_vector<native*>&_buf:
  name: c_in_vector<native*>&_buf
  comments:
  - Create a vector for pointers.
  notes:
  - Specialize for std::vector<native *>
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_len}'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_len}
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - for (size_t i=0; i < {c_var_size}; ++i) {{+
  - '{c_local_cxx}.push_back({c_var} + ({c_var_len}*i));'
  - -}}
  c_temps:
  - len
  - size
  c_local:
  - cxx
  owner: library
c_in_vector<native>&:
  name: c_in_vector<native>&
  comments:
  - Need to know the length of the vector from C.
  intent: in
  owner: library
  notimplemented: true
c_in_vector<native>&_buf:
  name: c_in_vector<native>&_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
c_in_vector<native>*_buf:
  name: c_in_vector<native>*_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
c_in_vector<native>_buf:
  name: c_in_vector<native>_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
c_in_vector<string>&:
  name: c_in_vector<string>&
  comments:
  - Need to know the length of the vector from C.
  intent: in
  owner: library
  notimplemented: true
c_in_vector<string>&_buf:
  name: c_in_vector<string>&_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
c_in_vector<string>*_buf:
  name: c_in_vector<string>*_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
c_in_vector<string>_buf:
  name: c_in_vector<string>_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
c_in_void:
  name: c_in_void
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_void*:
  name: c_in_void*
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_void**:
  name: c_in_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_in_void*_cdesc:
  name: c_in_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: in
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_inout_bool_*:
  name: c_inout_bool_*
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_inout_char*:
  name: c_inout_char*
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_inout_char*_buf:
  name: c_inout_char*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_var_str}'
  c_pre_call:
  - "char * {c_var_str} = {c_helper_char_alloc}(\t{c_var},\t {c_var_len},\t {c_blanknull});"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_var_str},\t -1);"
  - '{c_helper_char_free}({c_var_str});'
  c_temps:
  - len
  - str
  c_helper:
  - char_alloc
  - char_copy
  - char_free
  owner: library
c_inout_enum*:
  name: c_inout_enum*
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} {cxx_var} = {cast_static}{cxx_type}{cast1}*{c_var}{cast2};'
  c_post_call:
  - '*{c_var} = {cast_static}{c_type}{cast1}{cxx_var}{cast2};'
  c_local:
  - cxx
  owner: library
c_inout_native&:
  name: c_inout_native&
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_inout_native&_hidden:
  name: c_inout_native&_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: inout
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
c_inout_native*:
  name: c_inout_native*
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_inout_native*_cdesc:
  name: c_inout_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_inout_native*_hidden:
  name: c_inout_native*_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: inout
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
c_inout_shadow&:
  name: c_inout_shadow&
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_inout_shadow*:
  name: c_inout_shadow*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_inout_smartptr<shadow>*:
  name: c_inout_smartptr<shadow>*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_inout_string&:
  name: c_inout_string&
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
  lang_cxx:
    impl_header:
    - <cstring>
c_inout_string&_buf:
  name: c_inout_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var}, {c_var_len}));"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  - char_len_trim
  owner: library
c_inout_string*:
  name: c_inout_string*
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  notes:
  - XXX - the fortran wrapper is incorrect since it is passing buf
  - '  but only accepting one argument. Confused with f_inout_string*_buf'
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
  lang_cxx:
    impl_header:
    - <cstring>
c_inout_string*_buf:
  name: c_inout_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - "std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var}, {c_var_len}));"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  - char_len_trim
  owner: library
c_inout_struct&:
  name: c_inout_struct&
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_inout_struct*:
  name: c_inout_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_inout_vector<native>&_buf_copy:
  name: c_inout_vector<native>&_buf_copy
  comments:
  - Pass argument and size by reference to C.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + *{c_var_size});'
  c_post_call:
  - '*{c_var_size} = {c_local_cxx}->size()'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
  notimplemented: true
c_inout_vector<native>&_buf_malloc:
  name: c_inout_vector<native>&_buf_malloc
  comments:
  - Create local vector from arguments then copy result to
  - malloc allocated array.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}(*{c_var}, *{c_var} + *{c_var_size});'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::realloc(*{c_var},\t {c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_inout_vector<native>*_buf_copy:
  name: c_inout_vector<native>*_buf_copy
  comments:
  - Pass argument and size by reference to C.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + *{c_var_size});'
  c_post_call:
  - '*{c_var_size} = {c_local_cxx}->size()'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
  notimplemented: true
c_inout_vector<native>*_buf_malloc:
  name: c_inout_vector<native>*_buf_malloc
  comments:
  - Create local vector from arguments then copy result to
  - malloc allocated array.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}(*{c_var}, *{c_var} + *{c_var_size});'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::realloc(*{c_var},\t {c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_inout_vector<native>_buf_copy:
  name: c_inout_vector<native>_buf_copy
  comments:
  - Pass argument and size by reference to C.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + *{c_var_size});'
  c_post_call:
  - '*{c_var_size} = {c_local_cxx}->size()'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
  notimplemented: true
c_inout_vector<native>_buf_malloc:
  name: c_inout_vector<native>_buf_malloc
  comments:
  - Create local vector from arguments then copy result to
  - malloc allocated array.
  intent: inout
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}(*{c_var}, *{c_var} + *{c_var_size});'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::realloc(*{c_var},\t {c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_inout_vector<scalar>&:
  name: c_inout_vector<scalar>&
  comments:
  - Need to know the length of the vector from C.
  intent: inout
  owner: library
  notimplemented: true
c_inout_void**:
  name: c_inout_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: inout
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_inout_void*_cdesc:
  name: c_inout_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: inout
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_mixin_arg_cfi:
  name: c_mixin_arg_cfi
  comments:
  - Make the argument a CFI_desc_t.
  intent: mixin
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
c_mixin_arg_character_cfi:
  name: c_mixin_arg_character_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_local_cxx} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  c_temps:
  - cfi
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
c_mixin_arg_native_cfi:
  name: c_mixin_arg_native_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Native argument which use CFI_desc_t.
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{f_type}{f_intent_attr} :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_temps:
  - cfi
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
c_mixin_cast-argument:
  name: c_mixin_cast-argument
  comments:
  - Cast C argument to local C++ variable.
  intent: mixin
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
c_mixin_character:
  name: c_mixin_character
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  owner: library
c_mixin_cvar-capsule-fill:
  name: c_mixin_cvar-capsule-fill
  comments:
  - Assign to capsule in C wrapper.
  intent: mixin
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  owner: library
c_mixin_declare-arg:
  name: c_mixin_declare-arg
  intent: mixin
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_mixin_declare-fortran-result:
  name: c_mixin_declare-fortran-result
  intent: mixin
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
c_mixin_destructor_new-shadow-shared:
  name: c_mixin_destructor_new-shadow-shared
  intent: mixin
  destructor_header:
  - <memory>
  destructor_name: shadow-{cxx_type}
  destructor:
  - "{cxx_type} *shared =\t reinterpret_cast<{cxx_type} *>(ptr);"
  - shared->reset();
  - delete shared;
  owner: library
c_mixin_destructor_new-string:
  name: c_mixin_destructor_new-string
  intent: mixin
  destructor_name: new_string
  destructor:
  - "std::string *cxx_ptr = \treinterpret_cast<std::string *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_mixin_destructor_new-vector:
  name: c_mixin_destructor_new-vector
  intent: mixin
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_mixin_function:
  name: c_mixin_function
  comments:
  - Call a function.
  intent: mixin
  owner: library
c_mixin_function-assign-to-local:
  name: c_mixin_function-assign-to-local
  comments:
  - Call function and assign to a local C++ variable.
  intent: mixin
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_local:
  - cxx
  owner: library
c_mixin_function-assign-to-new:
  name: c_mixin_function-assign-to-new
  comments:
  - Allocate a function result on the heap.
  intent: mixin
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
c_mixin_function-return-cvar:
  name: c_mixin_function-return-cvar
  intent: mixin
  c_return:
  - return {c_var};
  c_return_type: '{c_type} *'
  owner: library
c_mixin_function_char*_cdesc:
  name: c_mixin_function_char*_cdesc
  comments:
  - Fill cdesc from char * in the C wrapper.
  intent: mixin
  c_post_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{cxx_var});"
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = {cxx_var} == {nullptr} ? 0 : {stdlib}strlen({cxx_var});'
  - '{c_var_cdesc}->size = 1;'
  - '{c_var_cdesc}->rank = 0;'
  c_helper:
  - type_defines
  owner: library
c_mixin_function_shadow_capptr:
  name: c_mixin_function_shadow_capptr
  comments:
  - Pass function result as a capsule field of shadow class
  - from Fortran to C.
  intent: mixin
  i_result_decl:
  - 'type(C_PTR) :: {i_result_ptr}'
  i_result_var: '{i_result_ptr}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
c_mixin_function_string_cdesc:
  name: c_mixin_function_string_cdesc
  comments:
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  intent: mixin
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_helper:
  - string_to_cdesc
  owner: library
c_mixin_function_vector_malloc:
  name: c_mixin_function_vector_malloc
  comments:
  - Return pointer to array type.
  - Add an argument to return the length of the array.
  intent: mixin
  i_arg_names:
  - '{i_var_size}'
  i_arg_decl:
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - size_t *{c_var_size}
  c_return_type: '{targs[0].cxx_type} *'
  c_temps:
  - size
  owner: library
c_mixin_in_character_buf:
  name: c_mixin_in_character_buf
  intent: mixin
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_temps:
  - len
  owner: library
c_mixin_inout_vector<native>_cdesc:
  name: c_mixin_inout_vector<native>_cdesc
  comments:
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  intent: mixin
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_cdesc}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "std::vector<{cxx_T}> *{c_local_cxx} = \tnew std::vector<{cxx_T}>\t(\t{c_var},\
    \ {c_var} + {c_var_size});"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - size
  - cdesc
  c_local:
  - cxx
  c_helper:
  - array_context
  - type_defines
  - copy_array
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_mixin_inout_vector_cdesc:
  name: c_mixin_inout_vector_cdesc
  comments:
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  intent: mixin
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_cdesc}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  - '{C_array_type} *{c_var_cdesc}'
  c_temps:
  - size
  - cdesc
  c_helper:
  - array_context
  owner: library
c_mixin_make-shared:
  name: c_mixin_make-shared
  comments:
  - Create a std::shared_pointer on the heap to hold the pointer to the instance.
  intent: mixin
  c_call:
  - "std::shared_ptr<{baseclass.cxx_type}> *{c_local_shared} =\t new std::shared_ptr<{baseclass.cxx_type}>;"
  - "*{c_local_shared} = \t std::make_shared<{baseclass.cxx_type}>({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{c_local_shared});"
  - '{c_var}->idtor = {idtor};'
  c_local:
  - shared
  impl_header:
  - <memory>
  owner: shared
c_mixin_native_capsule_fill:
  name: c_mixin_native_capsule_fill
  comments:
  - Assign to local capsule variable in C wrapper.
  intent: mixin
  c_post_call:
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  owner: library
c_mixin_native_cdesc_fill-cdesc:
  name: c_mixin_native_cdesc_fill-cdesc
  comments:
  - Fill cdesc from native in the C wrapper.
  intent: mixin
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  owner: library
c_mixin_native_cfi_allocatable:
  name: c_mixin_native_cfi_allocatable
  comments:
  - Allocate copy of C pointer (requires +dimension).
  intent: mixin
  c_post_call:
  - if ({c_local_cxx} != {nullptr}) {{+
  - "{c_temp_lower_decl}{c_temp_extents_decl}int SH_ret = CFI_allocate({c_var_cfi},\
    \ \t{c_temp_lower_use}, \t{c_temp_extents_use}, \t0);"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{c_local_cxx}, \t{c_var_cfi}->elem_len);"
  - -}}
  - -}}
  c_temps:
  - extents
  - lower
  owner: library
c_mixin_native_cfi_pointer:
  name: c_mixin_native_cfi_pointer
  comments:
  - Convert C pointer to Fortran pointer.
  intent: mixin
  c_post_call:
  - '{{+'
  - CFI_CDESC_T({rank}) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<{c_type} *>({c_local_cxx});
  - "{c_temp_extents_decl}{c_temp_lower_decl}int {c_local_err} = CFI_establish({c_local_cdesc},\t\
    \ {c_local_cptr},\t CFI_attribute_pointer,\t {cfi_type},\t 0,\t {rank},\t {c_temp_extents_use});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {c_temp_lower_use});"
  - -}}
  - -}}
  c_temps:
  - extents
  - lower
  c_local:
  - cptr
  - fptr
  - cdesc
  - err
  owner: library
c_mixin_noargs:
  name: c_mixin_noargs
  intent: mixin
  owner: library
c_mixin_out_native**:
  name: c_mixin_out_native**
  intent: mixin
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{c_const}{cxx_type} *{cxx_var};'
  owner: library
c_mixin_out_vector<native>_cdesc:
  name: c_mixin_out_vector<native>_cdesc
  comments:
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  - Create a std::vector on the stack and pass to C++.
  intent: mixin
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_local:
  - cxx
  c_helper:
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_mixin_out_vector_buf_malloc:
  name: c_mixin_out_vector_buf_malloc
  comments:
  - Pass raw pointer and size by reference to C.
  intent: mixin
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_temps:
  - size
  owner: library
c_mixin_shadow:
  name: c_mixin_shadow
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  owner: library
c_mixin_unknown:
  name: c_mixin_unknown
  comments:
  - Default returned by lookup_fc_stmts when group is not found.
  intent: mixin
  i_arg_names:
  - ===>i_arg_names<===
  i_arg_decl:
  - ===>i_arg_decl<===
  c_arg_decl:
  - ===>{c_var}<===
  owner: library
c_mixin_vector_cdesc_fill-cdesc:
  name: c_mixin_vector_cdesc_fill-cdesc
  comments:
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  intent: mixin
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_helper:
  - type_defines
  owner: library
c_out_bool_*:
  name: c_out_bool_*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_char*:
  name: c_out_char*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_char_*_buf:
  name: c_out_char_*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{c_helper_char_blank_fill}({c_var}, {c_var_len});'
  c_temps:
  - len
  c_helper:
  - char_blank_fill
  owner: library
c_out_enum*:
  name: c_out_enum*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  c_post_call:
  - '*{c_var} = {cast_static}{c_type}{cast1}{cxx_var}{cast2};'
  c_local:
  - cxx
  owner: library
c_out_native&:
  name: c_out_native&
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_out_native&_hidden:
  name: c_out_native&_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: out
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
c_out_native*:
  name: c_out_native*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_native*&:
  name: c_out_native*&
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_out_native**:
  name: c_out_native**
  notes:
  - Make argument type(C_PTR) from 'int ** +intent(out)+deref(raw)'
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_native***:
  name: c_out_native***
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_native**_raw:
  name: c_out_native**_raw
  notes:
  - Make argument type(C_PTR) from 'int ** +intent(out)+deref(raw)'
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_native*_cdesc:
  name: c_out_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_out_native*_hidden:
  name: c_out_native*_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: out
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
c_out_string&:
  name: c_out_string&
  notes:
  - Similar to f_out_string*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx};'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
  lang_cxx:
    impl_header:
    - <cstring>
c_out_string&_buf:
  name: c_out_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
c_out_string*:
  name: c_out_string*
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx};'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
  lang_cxx:
    impl_header:
    - <cstring>
c_out_string**:
  name: c_out_string**
  notes:
  - std::string **arg+intent(out)+dimension(size)
  - Returning a pointer to a string*. However, this needs additional
  - mapping for the C interface.  Fortran calls the +api(cdesc) variant.
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr}, value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
  notimplemented: true
c_out_string**_cdesc_copy:
  name: c_out_string**_cdesc_copy
  comments:
  - Collect information about a string argument.
  - Pass cdesc as argument to C wrapper.
  notes:
  - Pass a cdesc down to describe the memory and a capsule to hold the
  - C++ array. Copy into Fortran argument.
  - '[see also f_out_vector_&_cdesc_allocatable_targ_string_scalar]'
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - std::string *{cxx_var};
  c_post_call:
  - "{c_helper_array_string_out}(\t{c_var_cdesc},\t {cxx_var}, {c_array_size2});"
  c_temps:
  - cdesc
  c_helper:
  - array_string_out
  owner: library
c_out_string*_buf:
  name: c_out_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
c_out_struct&:
  name: c_out_struct&
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_out_struct*:
  name: c_out_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_vector<native>&:
  name: c_out_vector<native>&
  comments:
  - Need to know the length of the vector from C.
  intent: out
  owner: library
  notimplemented: true
c_out_vector<native>&_buf_copy:
  name: c_out_vector<native>&_buf_copy
  comments:
  - Pass argument and size by reference to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_size} =\t *{c_var_size} < {c_local_cxx}.size() ?\t *{c_var_size}\
    \ :\t {c_local_cxx}.size();"
  - "std::memcpy({c_var},\t {c_local_cxx}.data(),\t {c_local_size}*sizeof({c_local_cxx}[0]));"
  - '*{c_var_size} = {c_local_size};'
  c_temps:
  - size
  c_local:
  - cxx
  - size
  impl_header:
  - <cstring>
  owner: library
c_out_vector<native>&_buf_malloc:
  name: c_out_vector<native>&_buf_malloc
  comments:
  - Create empty local vector then copy result to
  - malloc allocated array.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::malloc({c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_out_vector<native>&_cdesc:
  name: c_out_vector<native>&_cdesc
  comments:
  - copy into user's existing array.
  notes:
  - c_local_cxx is always a pointer to a vector.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_out_vector<native>*_buf_copy:
  name: c_out_vector<native>*_buf_copy
  comments:
  - Pass argument and size by reference to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_size} =\t *{c_var_size} < {c_local_cxx}.size() ?\t *{c_var_size}\
    \ :\t {c_local_cxx}.size();"
  - "std::memcpy({c_var},\t {c_local_cxx}.data(),\t {c_local_size}*sizeof({c_local_cxx}[0]));"
  - '*{c_var_size} = {c_local_size};'
  c_temps:
  - size
  c_local:
  - cxx
  - size
  impl_header:
  - <cstring>
  owner: library
c_out_vector<native>*_buf_malloc:
  name: c_out_vector<native>*_buf_malloc
  comments:
  - Create empty local vector then copy result to
  - malloc allocated array.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::malloc({c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_out_vector<native>*_cdesc:
  name: c_out_vector<native>*_cdesc
  comments:
  - copy into user's existing array.
  notes:
  - c_local_cxx is always a pointer to a vector.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
c_out_vector<native>_buf_copy:
  name: c_out_vector<native>_buf_copy
  comments:
  - Pass argument and size by reference to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_size} =\t *{c_var_size} < {c_local_cxx}.size() ?\t *{c_var_size}\
    \ :\t {c_local_cxx}.size();"
  - "std::memcpy({c_var},\t {c_local_cxx}.data(),\t {c_local_size}*sizeof({c_local_cxx}[0]));"
  - '*{c_var_size} = {c_local_size};'
  c_temps:
  - size
  c_local:
  - cxx
  - size
  impl_header:
  - <cstring>
  owner: library
c_out_vector<native>_buf_malloc:
  name: c_out_vector<native>_buf_malloc
  comments:
  - Create empty local vector then copy result to
  - malloc allocated array.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: out
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - C_PTR
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} **{c_var}'
  - size_t *{c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx};'
  c_post_call:
  - "size_t {c_local_bytes} =\t {c_local_cxx}.size()*sizeof({c_local_cxx}[0]);"
  - "*{c_var} = static_cast<{targs[0].cxx_type} *>\t(std::malloc({c_local_bytes}));"
  - "std::memcpy(*{c_var},\t {c_local_cxx}.data(),\t {c_local_bytes});"
  - '*{c_var_size} = {c_local_cxx}.size();'
  c_temps:
  - size
  c_local:
  - cxx
  - bytes
  impl_header:
  - <cstdlib>
  - <cstring>
  owner: library
c_out_vector<string>&:
  name: c_out_vector<string>&
  comments:
  - Need to know the length of the vector from C.
  intent: out
  owner: library
  notimplemented: true
c_out_vector<string>&_buf_copy:
  name: c_out_vector<string>&_buf_copy
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(OUT) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
  notimplemented: true
c_out_vector<string>&_cdesc:
  name: c_out_vector<string>&_cdesc
  comments:
  - Collect information about a string argument.
  - Pass cdesc as argument to C wrapper.
  notes:
  - f_arg_decl replaces values from f_mixin_str_array.
  - This one needs to use targs.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{c_const}std::vector<std::string> {cxx_var};'
  c_post_call:
  - "{c_helper_vector_string_out}(\t{c_var_cdesc},\t {cxx_var});"
  c_temps:
  - cdesc
  c_helper:
  - vector_string_out
  owner: library
c_out_vector<string>&_cdesc_allocatable:
  name: c_out_vector<string>&_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Allocate Fortran array from cdesc.
  - Allocate a vector<string> variable.
  - Copy into Fortran allocated memory.
  - Release memory from capsule.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - std::vector<std::string> *{c_local_cxx} = new std::vector<std::string>;
  c_post_call:
  - if ({c_char_len} > 0) {{+
  - '{c_var_cdesc}->elem_len = {c_char_len};'
  - -}} else {{+
  - '{c_var_cdesc}->elem_len = {c_helper_vector_string_out_len}(*{c_local_cxx});'
  - -}}
  - '{c_var_cdesc}->size      = {c_local_cxx}->size();'
  - // XXX - Use code from c_mixin_native_capsule_fill
  - '{c_var_capsule}->addr  = {c_local_cxx};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_temps:
  - cdesc
  - capsule
  c_local:
  - cxx
  c_helper:
  - array_context
  - vector_string_allocatable
  - vector_string_out_len
  owner: library
c_out_vector<string>*_buf_copy:
  name: c_out_vector<string>*_buf_copy
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(OUT) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
  notimplemented: true
c_out_vector<string>_buf_copy:
  name: c_out_vector<string>_buf_copy
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(OUT) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
  notimplemented: true
c_out_void*&:
  name: c_out_void*&
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
c_out_void**:
  name: c_out_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
c_out_void*_cdesc:
  name: c_out_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: out
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
  lang_c:
    c_pre_call:
    - '{cxx_type} * {c_var} = {c_var_cdesc}->base_addr;'
  lang_cxx:
    c_pre_call:
    - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
c_setter:
  name: c_setter
  intent: setter
  c_call:
  - // skip call c_setter
  owner: library
c_setter_native:
  name: c_setter_native
  intent: setter
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
c_setter_native*:
  name: c_setter_native*
  intent: setter
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
c_setter_string_scalar_buf:
  name: c_setter_string_scalar_buf
  comments:
  - Extract meta data and pass to C.
  - Create std::string from Fortran meta data.
  intent: setter
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - "{CXX_this}->{field_name} = std::string({c_var},\t {c_var_len});"
  c_temps:
  - len
  owner: library
c_subroutine:
  name: c_subroutine
  intent: subroutine
  owner: library
c_subroutine_assignment_weakptr:
  name: c_subroutine_assignment_weakptr
  notes:
  - std::weak_ptr has no wrapped constructor.
  - It must be made from a std::shared_ptr with an assignment.
  - arglist[1] is the 'from' argument.
  intent: subroutine
  c_call:
  - if (SH_this == nullptr) {{+
  - SH_this = new {cxx_type}(*SHC_from_cxx);
  - self->addr = SH_this;
  - self->idtor = {idtor};
  - -}} else {{+
  - '*{CXX_this} = *{c_arglist[1].c_local_cxx};'
  - -}}
  destructor_header:
  - <memory>
  destructor_name: assignment-{cxx_type}
  destructor:
  - "auto cxx_ptr =\t reinterpret_cast<{cxx_type}*>(ptr);"
  - delete cxx_ptr;
  owner: library
f_ctor_shadow_capsule:
  name: f_ctor_shadow_capsule
  comments:
  - Pass function result as a capsule argument from Fortran to C.
  intent: ctor
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{cxx_type} *{cxx_var} =\t new {cxx_type}({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{cxx_var});"
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  owner: caller
f_ctor_shadow_capsule_shared:
  name: f_ctor_shadow_capsule_shared
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Create a std::shared_pointer on the heap to hold the pointer to the instance.
  intent: ctor
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "std::shared_ptr<{baseclass.cxx_type}> *{c_local_shared} =\t new std::shared_ptr<{baseclass.cxx_type}>;"
  - "*{c_local_shared} = \t std::make_shared<{baseclass.cxx_type}>({C_call_list});"
  - "{c_var}->addr = static_cast<{c_const}void *>(\t{c_local_shared});"
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - shared
  impl_header:
  - <memory>
  destructor_header:
  - <memory>
  destructor_name: shadow-{cxx_type}
  destructor:
  - "{cxx_type} *shared =\t reinterpret_cast<{cxx_type} *>(ptr);"
  - shared->reset();
  - delete shared;
  owner: shared
f_dtor:
  name: f_dtor
  comments:
  - Call the C wrapper as a subroutine.
  intent: dtor
  f_call:
  - call {f_call_function}({F_arg_c_call})
  c_call:
  - delete {CXX_this};
  - '{C_this}->addr = {nullptr};'
  c_return_type: void
  impl_header:
  - <cstddef>
  owner: library
f_function_bool:
  name: f_function_bool
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
f_function_char:
  name: f_function_char
  comments:
  - Call the C wrapper as a subroutine.
  intent: function
  f_arg_decl:
  - 'character :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(OUT) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - char *{c_var}
  c_call:
  - '*{c_var} = {C_call_function};'
  c_return_type: void
  owner: library
f_function_char*:
  name: f_function_char*
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_char*_allocatable:
  name: f_function_char*_allocatable
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_char*_arg:
  name: f_function_char*_arg
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - Change function result into an argument
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
f_function_char*_buf_arg:
  name: f_function_char*_buf_arg
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - Change function result into an argument
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
f_function_char*_buf_copy:
  name: f_function_char*_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  - Call function and assign to a local C++ variable.
  notes:
  - char *getname() +len(30)
  - Copy result into caller's buffer.
  - XXX - maybe fmtdict to rename c_local_cxx as output
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
f_function_char*_cdesc_allocatable:
  name: f_function_char*_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Fill cdesc from char * in the C wrapper.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - copy_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{cxx_var});"
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = {cxx_var} == {nullptr} ? 0 : {stdlib}strlen({cxx_var});'
  - '{c_var_cdesc}->size = 1;'
  - '{c_var_cdesc}->rank = 0;'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - copy_string
  - type_defines
  owner: library
f_function_char*_cdesc_pointer:
  name: f_function_char*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from char * in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{cxx_var});"
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = {cxx_var} == {nullptr} ? 0 : {stdlib}strlen({cxx_var});'
  - '{c_var_cdesc}->size = 1;'
  - '{c_var_cdesc}->rank = 0;'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - type_defines
  owner: library
f_function_char*_cfi_allocatable:
  name: f_function_char*_cfi_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - Add allocatable attribute to declaration.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - if ({cxx_var} != {nullptr}) {{+
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \tstrlen({cxx_var}));"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}, \t{c_var_cfi}->elem_len);"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_char*_cfi_arg:
  name: f_function_char*_cfi_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_char*_cfi_copy:
  name: f_function_char*_cfi_copy
  comments:
  - Copy result into caller's buffer.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx},\t -1);"
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_char*_cfi_pointer:
  name: f_function_char*_cfi_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = {cxx_nonconst_ptr};
  - size_t {c_local_len} = {stdlib}strlen({cxx_var});
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_char*_copy:
  name: f_function_char*_copy
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_char*_pointer:
  name: f_function_char*_pointer
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_char*_raw:
  name: f_function_char*_raw
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_char_cdesc_allocatable:
  name: f_function_char_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Fill cdesc from char * in the C wrapper.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - copy_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{cxx_var});"
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = {cxx_var} == {nullptr} ? 0 : {stdlib}strlen({cxx_var});'
  - '{c_var_cdesc}->size = 1;'
  - '{c_var_cdesc}->rank = 0;'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - copy_string
  - type_defines
  owner: library
f_function_char_cdesc_pointer:
  name: f_function_char_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from char * in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{cxx_var});"
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = {cxx_var} == {nullptr} ? 0 : {stdlib}strlen({cxx_var});'
  - '{c_var_cdesc}->size = 1;'
  - '{c_var_cdesc}->rank = 0;'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - type_defines
  owner: library
f_function_char_cfi_allocatable:
  name: f_function_char_cfi_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - Add allocatable attribute to declaration.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - if ({cxx_var} != {nullptr}) {{+
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \tstrlen({cxx_var}));"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}, \t{c_var_cfi}->elem_len);"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_char_cfi_pointer:
  name: f_function_char_cfi_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = {cxx_nonconst_ptr};
  - size_t {c_local_len} = {stdlib}strlen({cxx_var});
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_enum:
  name: f_function_enum
  comments:
  - Return as the Fortran bind(C) type.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_post_call:
  - "{ci_type} {c_var} =\t {cast_static}{ci_type}{cast1}{cxx_var}{cast2};"
  owner: library
f_function_native:
  name: f_function_native
  comments:
  - Call a function.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
f_function_native&:
  name: f_function_native&
  comments:
  - Return a C pointer as a type(C_PTR).
  notes:
  - Pointer to scalar.
  - type(C_PTR) is returned instead of a cdesc argument.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_function_native&_pointer:
  name: f_function_native&_pointer
  comments:
  - Return a C pointer as a type(C_PTR).
  notes:
  - Pointer to scalar.
  - type(C_PTR) is returned instead of a cdesc argument.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_function_native**:
  name: f_function_native**
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_native*_cdesc_allocatable:
  name: f_function_native*_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Allocate Fortran native array, then fill from cdesc
  - using helper copy_array.
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - '{f_type}, allocatable, target :: {f_var}{f_dimension}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - allocate({f_var}{f_array_allocate})
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},\t\
    \ kind=C_SIZE_T))"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
    - C_SIZE_T
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - copy_array
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - copy_array
  owner: library
f_function_native*_cdesc_pointer:
  name: f_function_native*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Set Fortran pointer to native array.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_function_native*_cdesc_pointer_caller:
  name: f_function_native*_cdesc_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Add a capsule argument to the Fortran wrapper.
  - Pass the capsule as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Set Fortran pointer to native array.
  notes:
  - +deref(pointer) +owner(caller)
  - The capsule contains information used to delete the memory.
  intent: function
  f_arg_name:
  - '{f_var_capsule}'
  f_arg_decl:
  - 'type({F_capsule_type}), intent(OUT) :: {f_var_capsule}'
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}%mem'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - capsule_helper
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  fmtdict:
    f_var_capsule: Crv
  owner: library
f_function_native*_cfi_allocatable:
  name: f_function_native*_cfi_allocatable
  comments:
  - Pass result as an argument to C wrapper.
  - Convert to subroutine and pass result as an argument.
  - Return an allocated copy of data.
  intent: function
  f_arg_decl:
  - '{f_type}, allocatable :: {f_var}{f_assumed_shape}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_intent_attr}, allocatable :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - if ({c_local_cxx} != {nullptr}) {{+
  - "{c_temp_lower_decl}{c_temp_extents_decl}int SH_ret = CFI_allocate({c_var_cfi},\
    \ \t{c_temp_lower_use}, \t{c_temp_extents_use}, \t0);"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{c_local_cxx}, \t{c_var_cfi}->elem_len);"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  - extents
  - lower
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_native*_cfi_pointer:
  name: f_function_native*_cfi_pointer
  comments:
  - Pass result as an argument to C wrapper.
  - Convert to subroutine and pass result as an argument.
  - Return Fortran pointer to data.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_pre_call:
  - nullify({f_var})
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_intent_attr}, pointer :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{{+'
  - CFI_CDESC_T({rank}) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<{c_type} *>({c_local_cxx});
  - "{c_temp_extents_decl}{c_temp_lower_decl}int {c_local_err} = CFI_establish({c_local_cdesc},\t\
    \ {c_local_cptr},\t CFI_attribute_pointer,\t {cfi_type},\t 0,\t {rank},\t {c_temp_extents_use});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {c_temp_lower_use});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  - extents
  - lower
  c_local:
  - cxx
  - cptr
  - fptr
  - cdesc
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_native*_pointer:
  name: f_function_native*_pointer
  comments:
  - Return a C pointer as a type(C_PTR).
  notes:
  - Pointer to scalar.
  - type(C_PTR) is returned instead of a cdesc argument.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_function_native*_pointer_caller:
  name: f_function_native*_pointer_caller
  comments:
  - Return a C pointer as a type(C_PTR).
  notes:
  - Pointer to scalar.
  - type(C_PTR) is returned instead of a cdesc argument.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_function_native*_raw:
  name: f_function_native*_raw
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: function
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_function_native*_scalar:
  name: f_function_native*_scalar
  comments:
  - Return a scalar to avoid doing the deref in Fortran.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_return:
  - return *{cxx_var};
  c_return_type: '{c_type}'
  c_need_wrapper: true
  owner: library
f_function_shadow&_capsule:
  name: f_function_shadow&_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow&_capsule_caller:
  name: f_function_shadow&_capsule_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow&_capsule_library:
  name: f_function_shadow&_capsule_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow*_capsule:
  name: f_function_shadow*_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow*_capsule_caller:
  name: f_function_shadow*_capsule_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow*_capsule_library:
  name: f_function_shadow*_capsule_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  notes:
  - Return a C_capsule_data_type.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_shadow*_this:
  name: f_function_shadow*_this
  comments:
  - Call the C wrapper as a subroutine.
  notes:
  - Input set return_this.
  - Do not return anything.
  intent: function
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  c_call:
  - '{C_call_function};'
  c_return_type: void
  owner: library
f_function_shadow<native>_capsule:
  name: f_function_shadow<native>_capsule
  comments:
  - Return an instance by value.
  notes:
  - Create memory in c_pre_call so it will survive the return.
  - owner=caller sets idtor flag to release the memory.
  - c_local_var is passed in as argument.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
f_function_shadow_capsule:
  name: f_function_shadow_capsule
  comments:
  - Return an instance by value.
  notes:
  - Create memory in c_pre_call so it will survive the return.
  - owner=caller sets idtor flag to release the memory.
  - c_local_var is passed in as argument.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
f_function_smartptr<shadow>*_capsule:
  name: f_function_smartptr<shadow>*_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Call function and assign to a local C++ variable.
  - Assign to capsule in C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  owner: library
f_function_smartptr<shadow>_capsule:
  name: f_function_smartptr<shadow>_capsule
  comments:
  - Call the C wrapper as a subroutine.
  - Pass function result as a capsule argument from Fortran to C.
  - Allocate a function result on the heap.
  - Assign to capsule in C wrapper.
  notes:
  - Used with std::shared_ptr<Object>* createChildA(void)
  intent: function
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var}->addr  = {cxx_nonconst_ptr};'
  - '{c_var}->idtor = {idtor};'
  c_return_type: void
  c_local:
  - cxx
  fmtdict:
    cxx_addr: ''
  owner: caller
f_function_string&_buf:
  name: f_function_string&_buf
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string&_buf_arg:
  name: f_function_string&_buf_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
f_function_string&_buf_copy:
  name: f_function_string&_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string&_cdesc_allocatable:
  name: f_function_string&_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string&_cdesc_allocatable_caller:
  name: f_function_string&_cdesc_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string&_cdesc_allocatable_library:
  name: f_function_string&_cdesc_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string&_cdesc_pointer:
  name: f_function_string&_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string&_cdesc_pointer_caller:
  name: f_function_string&_cdesc_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string&_cdesc_pointer_library:
  name: f_function_string&_cdesc_pointer_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string&_cfi_allocatable:
  name: f_function_string&_cfi_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string&_cfi_allocatable_caller:
  name: f_function_string&_cfi_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string&_cfi_allocatable_library:
  name: f_function_string&_cfi_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string&_cfi_arg:
  name: f_function_string&_cfi_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - if ({c_local_cxx}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx}{cxx_member}data(),\t\
    \ {c_local_cxx}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string&_cfi_copy:
  name: f_function_string&_cfi_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - if ({c_local_cxx}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx}{cxx_member}data(),\t\
    \ {c_local_cxx}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string&_cfi_pointer:
  name: f_function_string&_cfi_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string&_cfi_pointer_caller:
  name: f_function_string&_cfi_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string&_cfi_pointer_library:
  name: f_function_string&_cfi_pointer_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string*_buf:
  name: f_function_string*_buf
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string*_buf_copy:
  name: f_function_string*_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string*_cdesc_allocatable:
  name: f_function_string*_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string*_cdesc_allocatable_caller:
  name: f_function_string*_cdesc_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string*_cdesc_allocatable_library:
  name: f_function_string*_cdesc_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - copy_string
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  owner: library
f_function_string*_cdesc_pointer:
  name: f_function_string*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string*_cdesc_pointer_caller:
  name: f_function_string*_cdesc_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string*_cdesc_pointer_library:
  name: f_function_string*_cdesc_pointer_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - pointer_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - string_to_cdesc
  owner: library
f_function_string*_cfi_allocatable:
  name: f_function_string*_cfi_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string*_cfi_allocatable_caller:
  name: f_function_string*_cfi_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string*_cfi_allocatable_library:
  name: f_function_string*_cfi_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string*_cfi_copy:
  name: f_function_string*_cfi_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - if ({c_local_cxx}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx}{cxx_member}data(),\t\
    \ {c_local_cxx}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string*_cfi_pointer:
  name: f_function_string*_cfi_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string*_cfi_pointer_caller:
  name: f_function_string*_cfi_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string*_cfi_pointer_library:
  name: f_function_string*_cfi_pointer_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_buf:
  name: f_function_string_buf
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string_buf_arg:
  name: f_function_string_buf_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
    f_var_len: n{F_string_result_as_arg}
    i_var_len: n{F_string_result_as_arg}
    c_var_len: n{F_string_result_as_arg}
  owner: library
f_function_string_buf_copy:
  name: f_function_string_buf_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Pass CHARACTER and LEN to C wrapper.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - if ({cxx_var}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - len
  c_helper:
  - char_copy
  owner: library
f_function_string_cdesc_allocatable:
  name: f_function_string_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Allocate a function result on the heap.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - copy_string
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_local:
  - cxx
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  fmtdict:
    cxx_addr: ''
  destructor_name: new_string
  destructor:
  - "std::string *cxx_ptr = \treinterpret_cast<std::string *>(ptr);"
  - delete cxx_ptr;
  owner: caller
f_function_string_cdesc_allocatable_caller:
  name: f_function_string_cdesc_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Allocate a function result on the heap.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - copy_string
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_local:
  - cxx
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  fmtdict:
    cxx_addr: ''
  destructor_name: new_string
  destructor:
  - "std::string *cxx_ptr = \treinterpret_cast<std::string *>(ptr);"
  - delete cxx_ptr;
  owner: caller
f_function_string_cdesc_allocatable_library:
  name: f_function_string_cdesc_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Allocate a function result on the heap.
  - Fill cdesc from std::string using helper string_to_cdesc
  - in the C wrapper.
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - copy_string
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = new {cxx_type};'
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - "{c_helper_string_to_cdesc}(\t{c_var_cdesc},\t {cxx_addr}{cxx_var});"
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_return_type: void
  c_temps:
  - cdesc
  - capsule
  c_local:
  - cxx
  c_helper:
  - array_context
  - string_to_cdesc
  - copy_string
  fmtdict:
    cxx_addr: ''
  destructor_name: new_string
  destructor:
  - "std::string *cxx_ptr = \treinterpret_cast<std::string *>(ptr);"
  - delete cxx_ptr;
  owner: caller
f_function_string_cfi_allocatable:
  name: f_function_string_cfi_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - std::string & function()
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}.length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}.data(), \t{c_var_cfi}->elem_len);"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_cfi_allocatable_caller:
  name: f_function_string_cfi_allocatable_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string_cfi_allocatable_library:
  name: f_function_string_cfi_allocatable_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  intent: function
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, allocatable :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - "int SH_ret = CFI_allocate({c_var_cfi}, \t(CFI_index_t *) 0, \t(CFI_index_t *)\
    \ 0, \t{cxx_var}{cxx_member}length());"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{cxx_var}{cxx_member}data(), \t{cxx_var}{cxx_member}length());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  iface_header:
  - ISO_Fortran_binding.h
  impl_header:
  - <cstring>
  owner: library
f_function_string_cfi_arg:
  name: f_function_string_cfi_arg
  comments:
  - Change function result into an argument.
  - Use F_string_result_as_arg as the argument name.
  intent: function
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(OUT) :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_result_var: as-subroutine
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - if ({c_local_cxx}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx}{cxx_member}data(),\t\
    \ {c_local_cxx}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  fmtdict:
    f_var: '{F_string_result_as_arg}'
    i_var: '{F_string_result_as_arg}'
    c_var: '{F_string_result_as_arg}'
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_cfi_copy:
  name: f_function_string_cfi_copy
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_call:
  - "{gen.cxxdecl.c_local_cxx} =\t {C_call_function};"
  c_post_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - if ({c_local_cxx}{cxx_member}empty()) {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {nullptr},\t 0);"
  - -}} else {{+
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx}{cxx_member}data(),\t\
    \ {c_local_cxx}{cxx_member}size());"
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_cfi_pointer:
  name: f_function_string_cfi_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_cfi_pointer_caller:
  name: f_function_string_cfi_pointer_caller
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_string_cfi_pointer_library:
  name: f_function_string_cfi_pointer_library
  comments:
  - Call the C wrapper as a subroutine.
  - Make the argument a CFI_desc_t.
  notes:
  - XXX - consolidate with c_function*_cfi_pointer?
  - XXX - via a helper to get address and length of string
  intent: function
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=:){f_intent_attr}, pointer :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_post_call:
  - int {c_local_err};
  - if ({cxx_var} == {nullptr}) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {nullptr},\t {nullptr});"
  - -}} else {{+
  - CFI_CDESC_T(0) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<char *>({cxx_var}{cxx_member}data());
  - size_t {c_local_len} = {cxx_var}{cxx_member}length();
  - "{c_local_err} = CFI_establish({c_local_cdesc},\t {c_local_cptr},\t CFI_attribute_pointer,\t\
    \ CFI_type_char,\t {c_local_len},\t 0,\t {nullptr});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - '{c_var_cfi}->elem_len = {c_local_cdesc}->elem_len;'
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {nullptr});"
  - -}}
  - -}}
  c_return_type: void
  c_temps:
  - cfi
  c_local:
  - cptr
  - fptr
  - cdesc
  - len
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_function_struct:
  name: f_function_struct
  comments:
  - Call the C wrapper as a subroutine.
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{f_var}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{c_type} *{c_var}'
  c_call:
  - '*{c_var} = {C_call_function};'
  c_return_type: void
  owner: library
f_function_struct*_cdesc_pointer:
  name: f_function_struct*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Set Fortran pointer to native array.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_function_struct*_pointer:
  name: f_function_struct*_pointer
  comments:
  - C++ pointer -> void pointer -> C pointer.
  intent: function
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_function_vector<native>_cdesc_allocatable:
  name: f_function_vector<native>_cdesc_allocatable
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  notes:
  - Almost same as intent_out_buf.
  - Similar to f_vector_out_allocatable but must declare result variable.
  - Always return a 1-d array.
  intent: function
  f_arg_decl:
  - '{targs[0].f_type}, allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - allocate({f_var}({f_var_cdesc}%size))
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_LOC
    - C_SIZE_T
  f_temps:
  - cdesc
  f_helper:
  - copy_array
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_call:
  - '*{c_local_cxx} = {C_call_function};'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_return_type: void
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_function_vector_scalar_cdesc:
  name: f_function_vector_scalar_cdesc
  intent: function
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_post_call:
  - "call {f_helper_copy_array}(\t{temp0},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - C_LOC
    - C_SIZE_T
  f_helper:
  - copy_array
  c_helper:
  - copy_array
  owner: library
f_function_void*:
  name: f_function_void*
  comments:
  - Call a function.
  notes:
  - XXX - f entries are the same as the i entries, share?
  intent: function
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - 'type(C_PTR) :: {f_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_getter_bool:
  name: f_getter_bool
  intent: getter
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_call:
  - // skip call c_getter
  c_return:
  - return {CXX_this}->{field_name};
  owner: library
f_getter_native:
  name: f_getter_native
  intent: getter
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_call:
  - // skip call c_getter
  c_return:
  - return {CXX_this}->{field_name};
  owner: library
f_getter_native*_cdesc_pointer:
  name: f_getter_native*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Set Fortran pointer to native array.
  - Save pointer struct members in a cdesc
  - along with shape information.
  notes:
  - Similar to calling a function, but save field pointer instead.
  intent: getter
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_call:
  - '{c_var_cdesc}->base_addr = {CXX_this}->{field_name};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - type_defines
  - array_context
  owner: library
f_getter_native*_pointer:
  name: f_getter_native*_pointer
  intent: getter
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_result_decl:
  - '{i_type} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_call:
  - // skip call c_getter
  c_return:
  - return {CXX_this}->{field_name};
  owner: library
f_getter_string_cdesc_allocatable:
  name: f_getter_string_cdesc_allocatable
  comments:
  - Return argument meta data to Fortran.
  intent: getter
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - copy_string
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_call:
  - "{c_var_cdesc}->base_addr =\t const_cast<char *>(\t{CXX_this}->{field_name}.data());"
  - '{c_var_cdesc}->type = 0; // SH_CHAR;'
  - '{c_var_cdesc}->elem_len = {CXX_this}->{field_name}.size();'
  - '{c_var_cdesc}->rank = 0;'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - copy_string
  owner: library
f_getter_struct**_cdesc_raw:
  name: f_getter_struct**_cdesc_raw
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Set Fortran pointer to pointers to arrays.
  - Save pointer struct members in a cdesc
  - along with shape information.
  intent: getter
  f_arg_decl:
  - 'type(C_PTR), pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_call:
  - '{c_var_cdesc}->base_addr = {CXX_this}->{field_name};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - type_defines
  - array_context
  owner: library
f_getter_struct*_cdesc_pointer:
  name: f_getter_struct*_cdesc_pointer
  comments:
  - Call the C wrapper as a subroutine.
  - Pass cdesc as argument to C wrapper.
  - Set Fortran pointer to native array.
  - Save pointer struct members in a cdesc
  - along with shape information.
  notes:
  - Similar to calling a function, but save field pointer instead.
  intent: getter
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_call:
  - call {f_call_function}({F_arg_c_call})
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_call:
  - '{c_var_cdesc}->base_addr = {CXX_this}->{field_name};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_return_type: void
  c_temps:
  - cdesc
  c_helper:
  - array_context
  - type_defines
  - array_context
  owner: library
f_getter_struct*_fapi_pointer:
  name: f_getter_struct*_fapi_pointer
  notes:
  - XXX - unused - the getter does not need a C wrapper if api(fapi)
  - The getter can be done totally from Fortran for a pointer to a scalar.
  - Return value a function result.
  intent: getter
  f_arg_decl:
  - '{f_type}, pointer :: {f_result_var}'
  f_call:
  - call c_f_pointer({CXX_this}%{field_name}, {f_result_var})
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_need_wrapper: true
  owner: library
f_in_bool:
  name: f_in_bool
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_pre_call:
  - '{f_var_cxx} = {f_var}  ! coerce to C_BOOL'
  f_arg_call:
  - '{f_var_cxx}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_char:
  name: f_in_char
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character, value{f_intent_attr} :: {f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), value{f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - char {c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_char*:
  name: f_in_char*
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_char**:
  name: f_in_char**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR), intent(IN) :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - char **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_char**_buf:
  name: f_in_char**_buf
  comments:
  - Pass argument, size and len to C.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "char **{c_local_cxx} = {c_helper_char_array_alloc}({c_var},\t {c_var_size},\t\
    \ {c_var_len});"
  c_post_call:
  - '{c_helper_char_array_free}({c_local_cxx}, {c_var_size});'
  c_temps:
  - size
  - len
  c_local:
  - cxx
  c_helper:
  - char_array_alloc
  - char_array_free
  owner: library
f_in_char**_cfi:
  name: f_in_char**_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*){f_intent_attr} :: {f_var}(:)'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}(:)'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_var_len} = {c_var_cfi}->elem_len;
  - size_t {c_var_size} = {c_var_cfi}->dim[0].extent;
  - "char **{c_local_cxx} = {c_helper_char_array_alloc}({c_var},\t {c_var_size},\t\
    \ {c_var_len});"
  c_post_call:
  - '{c_helper_char_array_free}({c_local_cxx}, {c_var_size});'
  c_temps:
  - cfi
  - len
  - size
  c_local:
  - cxx
  c_helper:
  - char_array_alloc
  - char_array_free
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_char*_buf:
  name: f_in_char*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_var_str}'
  c_pre_call:
  - "char * {c_var_str} = {c_helper_char_alloc}(\t{c_var},\t {c_var_len},\t {c_blanknull});"
  c_post_call:
  - '{c_helper_char_free}({c_var_str});'
  c_temps:
  - len
  - str
  c_helper:
  - char_alloc
  - char_free
  owner: library
f_in_char*_capi:
  name: f_in_char*_capi
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_char*_cfi:
  name: f_in_char*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - "char *{c_local_cxx} = {c_helper_char_alloc}(\t{c_var},\t {c_var_cfi}->elem_len,\t\
    \ {c_blanknull});"
  c_post_call:
  - '{c_helper_char_free}({c_local_cxx});'
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_alloc
  - char_free
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_enum:
  name: f_in_enum
  notes:
  - Use gen.cidecl to get the C interface type.
  - enums use option.F_enum_type to control the C type.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}, value{f_intent_attr} :: {i_var}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{gen.cxxdecl.cxx_var} =\t {gen.c_to_cxx};"
  fmtdict:
    cxx_var: '{CXX_local}{c_var}'
  owner: library
f_in_native:
  name: f_in_native
  notes:
  - An intent of 'none' is used with function pointers
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_native&:
  name: f_in_native&
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_in_native*:
  name: f_in_native*
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_native**:
  name: f_in_native**
  notes:
  - Any array of pointers.  Assumed to be non-contiguous memory.
  - All Fortran can do is treat as a type(C_PTR).
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr}, value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_native*_cdesc:
  name: f_in_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_in_native*_cfi:
  name: f_in_native*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Native argument which use CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{f_type}{f_intent_attr} :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = {cast_static}{cxx_type} *{cast1}{c_var_cfi}->base_addr{cast2};'
  c_temps:
  - cfi
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_procedure:
  name: f_in_procedure
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'procedure({f_abstract_interface}) :: {f_var}'
  f_arg_call:
  - '{f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'procedure({f_abstract_interface}) :: {i_var}'
  i_import:
  - '{f_abstract_interface}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_procedure_external:
  name: f_in_procedure_external
  notes:
  - EXTERNAL is not allowed in BIND(C), so force wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'external :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'procedure({f_abstract_interface}) :: {i_var}'
  i_import:
  - '{f_abstract_interface}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_procedure_funptr:
  name: f_in_procedure_funptr
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_FUNPTR) :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_module:
    iso_c_binding:
    - C_FUNPTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_FUNPTR), value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_FUNPTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_shadow:
  name: f_in_shadow
  comments:
  - Pass a shadow type to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr}, value :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} {c_var}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}.addr{cast2};"
  c_local:
  - cxx
  owner: library
f_in_shadow&:
  name: f_in_shadow&
  comments:
  - Pass a shadow type to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_in_shadow*:
  name: f_in_shadow*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_in_smartptr<shadow>*:
  name: f_in_smartptr<shadow>*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_in_string&:
  name: f_in_string&
  notes:
  - Similar to f_in_string*, but c_arg_call is pass by value
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_local:
  - cxx
  owner: library
f_in_string&_buf:
  name: f_in_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var},\
    \ {c_var_len}));"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_len_trim
  owner: library
f_in_string&_cfi:
  name: f_in_string&_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*){f_intent_attr} :: {f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_cfi}->elem_len);
  - '{c_const}std::string {c_local_cxx}({c_var}, {c_local_trim});'
  c_temps:
  - cfi
  c_local:
  - cxx
  - trim
  c_helper:
  - char_len_trim
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_string*:
  name: f_in_string*
  comments:
  - Create local std::string from the argument.
  intent: in
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_local:
  - cxx
  owner: library
f_in_string*_buf:
  name: f_in_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var},\
    \ {c_var_len}));"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_len_trim
  owner: library
f_in_string*_cfi:
  name: f_in_string*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*){f_intent_attr} :: {f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_cfi}->elem_len);
  - '{c_const}std::string {c_local_cxx}({c_var}, {c_local_trim});'
  c_temps:
  - cfi
  c_local:
  - cxx
  - trim
  c_helper:
  - char_len_trim
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_string_buf:
  name: f_in_string_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - int {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_len});
  - std::string {c_local_cxx}({c_var}, {c_local_trim});
  c_temps:
  - len
  c_local:
  - cxx
  - trim
  c_helper:
  - char_len_trim
  owner: library
f_in_string_cfi:
  name: f_in_string_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*){f_intent_attr} :: {f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_cfi}->elem_len);
  - '{c_const}std::string {c_local_cxx}({c_var}, {c_local_trim});'
  c_temps:
  - cfi
  c_local:
  - cxx
  - trim
  c_helper:
  - char_len_trim
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_in_struct:
  name: f_in_struct
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_struct&:
  name: f_in_struct&
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_in_struct*:
  name: f_in_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_unknown:
  name: f_in_unknown
  notes:
  - Used with MPI types
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_vector<native*>&_buf:
  name: f_in_vector<native*>&_buf
  comments:
  - Create a vector for pointers.
  notes:
  - Specialize for std::vector<native *>
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {f_var}(:,:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, 1, kind=C_SIZE_T)
  - size({f_var}, 2, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_len}'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_len}
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - for (size_t i=0; i < {c_var_size}; ++i) {{+
  - '{c_local_cxx}.push_back({c_var} + ({c_var_len}*i));'
  - -}}
  c_temps:
  - len
  - size
  c_local:
  - cxx
  owner: library
f_in_vector<native>&_buf:
  name: f_in_vector<native>&_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {f_var}{f_assumed_shape}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
f_in_vector<native>*_buf:
  name: f_in_vector<native>*_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {f_var}{f_assumed_shape}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
f_in_vector<native>_buf:
  name: f_in_vector<native>_buf
  comments:
  - Pass argument and size by value to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {f_var}{f_assumed_shape}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_cxx}({c_var}, {c_var} + {c_var_size});'
  c_temps:
  - size
  c_local:
  - cxx
  owner: library
f_in_vector<string>&_buf:
  name: f_in_vector<string>&_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
f_in_vector<string>*_buf:
  name: f_in_vector<string>*_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
f_in_vector<string>_buf:
  name: f_in_vector<string>_buf
  comments:
  - Pass argument, size and len to C.
  notes:
  - XXX - need to test scalar and pointer versions
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {c_local_cxx};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_local_cxx}.push_back(\tstd::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
f_in_vector_&_cdesc_targ_native_scalar:
  name: f_in_vector_&_cdesc_targ_native_scalar
  intent: in
  owner: library
f_in_void:
  name: f_in_void
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_void*:
  name: f_in_void*
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_void**:
  name: f_in_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}{f_assumed_shape}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_void**_cfi:
  name: f_in_void**_cfi
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}{f_assumed_shape}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_in_void*_cdesc:
  name: f_in_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: in
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_inout_bool*:
  name: f_inout_bool*
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_pre_call:
  - '{f_var_cxx} = {f_var}  ! coerce to C_BOOL'
  f_arg_call:
  - '{f_var_cxx}'
  f_post_call:
  - '{f_var} = {f_var_cxx}  ! coerce to logical'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_char*:
  name: f_inout_char*
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_char*_buf:
  name: f_inout_char*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_var_str}'
  c_pre_call:
  - "char * {c_var_str} = {c_helper_char_alloc}(\t{c_var},\t {c_var_len},\t {c_blanknull});"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_var_str},\t -1);"
  - '{c_helper_char_free}({c_var_str});'
  c_temps:
  - len
  - str
  c_helper:
  - char_alloc
  - char_copy
  - char_free
  owner: library
f_inout_char*_capi:
  name: f_inout_char*_capi
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_char*_cfi:
  name: f_inout_char*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - "char *{c_local_cxx} = {c_helper_char_alloc}(\t{c_var},\t {c_var_cfi}->elem_len,\t\
    \ {c_blanknull});"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_cfi}->elem_len,\t {c_local_cxx},\t -1);"
  - '{c_helper_char_free}({c_local_cxx});'
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_alloc
  - char_copy
  - char_free
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_inout_enum*:
  name: f_inout_enum*
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} {cxx_var} = {cast_static}{cxx_type}{cast1}*{c_var}{cast2};'
  c_post_call:
  - '*{c_var} = {cast_static}{c_type}{cast1}{cxx_var}{cast2};'
  c_local:
  - cxx
  owner: library
f_inout_native&:
  name: f_inout_native&
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_inout_native&_hidden:
  name: f_inout_native&_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: inout
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
f_inout_native*:
  name: f_inout_native*
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_native*_cdesc:
  name: f_inout_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_inout_native*_cfi:
  name: f_inout_native*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Native argument which use CFI_desc_t.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{f_type}{f_intent_attr} :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} *{c_local_cxx} = {cast_static}{cxx_type} *{cast1}{c_var_cfi}->base_addr{cast2};'
  c_temps:
  - cfi
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_inout_native*_hidden:
  name: f_inout_native*_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: inout
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
f_inout_shadow&:
  name: f_inout_shadow&
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_inout_shadow*:
  name: f_inout_shadow*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_inout_smartptr<shadow>*:
  name: f_inout_smartptr<shadow>*
  comments:
  - Pass a shadow type to C wrapper.
  - Cast C argument to local C++ variable.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type({f_capsule_data_type}){f_intent_attr} :: {i_var}'
  i_module:
    '{f_module_name}':
    - '{f_capsule_data_type}'
  c_arg_decl:
  - '{c_type} * {c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}{cxx_type} * {c_local_cxx} =\t {cast_static}{c_const}{cxx_type} *{cast1}{c_var}->addr{cast2};"
  c_local:
  - cxx
  owner: library
f_inout_string&:
  name: f_inout_string&
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
f_inout_string&_buf:
  name: f_inout_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var}, {c_var_len}));"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  - char_len_trim
  owner: library
f_inout_string&_cfi:
  name: f_inout_string&_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_cfi}->elem_len);
  - '{c_const}std::string {c_local_cxx}({c_var}, {c_local_trim});'
  c_post_call:
  - "{c_helper_char_copy}({c_var},\t {c_var_cfi}->elem_len,\t {c_local_cxx}.data(),\t\
    \ {c_local_cxx}.size());"
  c_temps:
  - cfi
  c_local:
  - cxx
  - trim
  c_helper:
  - char_copy
  - char_len_trim
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_inout_string*:
  name: f_inout_string*
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  notes:
  - XXX - the fortran wrapper is incorrect since it is passing buf
  - '  but only accepting one argument. Confused with f_inout_string*_buf'
  intent: inout
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::string {c_local_cxx}({c_var});'
  c_post_call:
  - strcpy({c_var}, {c_local_cxx}.c_str());
  c_local:
  - cxx
  impl_header:
  - <cstring>
  owner: library
f_inout_string*_buf:
  name: f_inout_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - "std::string {c_local_cxx}({c_var},\t {c_helper_char_len_trim}({c_var}, {c_var_len}));"
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  - char_len_trim
  owner: library
f_inout_string*_cfi:
  name: f_inout_string*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  - size_t {c_local_trim} = {c_helper_char_len_trim}({c_var}, {c_var_cfi}->elem_len);
  - '{c_const}std::string {c_local_cxx}({c_var}, {c_local_trim});'
  c_post_call:
  - "{c_helper_char_copy}({c_var},\t {c_var_cfi}->elem_len,\t {c_local_cxx}.data(),\t\
    \ {c_local_cxx}.size());"
  c_temps:
  - cfi
  c_local:
  - cxx
  - trim
  c_helper:
  - char_copy
  - char_len_trim
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_inout_struct&:
  name: f_inout_struct&
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_inout_struct*:
  name: f_inout_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_vector<native>&_cdesc:
  name: f_inout_vector<native>&_cdesc
  comments:
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - '{f_var_cdesc}'
  f_post_call:
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - '{targs[0].f_kind}'
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - copy_array
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_cdesc}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "std::vector<{cxx_T}> *{c_local_cxx} = \tnew std::vector<{cxx_T}>\t(\t{c_var},\
    \ {c_var} + {c_var_size});"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - size
  - cdesc
  c_local:
  - cxx
  c_helper:
  - array_context
  - type_defines
  - copy_array
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_inout_vector<native>&_cdesc_allocatable:
  name: f_inout_vector<native>&_cdesc_allocatable
  comments:
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - '{f_var_cdesc}'
  f_post_call:
  - if (allocated({f_var})) deallocate({f_var})
  - allocate({f_var}({f_var_cdesc}%size))
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - '{targs[0].f_kind}'
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - array_context
  - copy_array
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_cdesc}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "std::vector<{cxx_T}> *{c_local_cxx} = \tnew std::vector<{cxx_T}>\t(\t{c_var},\
    \ {c_var} + {c_var_size});"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - size
  - cdesc
  c_local:
  - cxx
  c_helper:
  - array_context
  - type_defines
  - copy_array
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_inout_vector_buf_targ_string_scalar:
  name: f_inout_vector_buf_targ_string_scalar
  comments:
  - Pass argument, size and len to C.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::vector<{cxx_T}> {cxx_var};
  - '{{+'
  - '{c_const}char * {c_local_s} = {c_var};'
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{cxx_var}.push_back(std::string({c_local_s},\t{c_helper_char_len_trim}({c_local_s},\
    \ {c_var_len})));"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_post_call:
  - '{{+'
  - char * {c_local_s} = {c_var};
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - -{c_local_n} = std::min({cxx_var}.size(),{c_local_n});
  - for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_helper_char_copy}({c_local_s}, {c_var_len},\t {cxx_var}[{c_local_i}].data(),\t\
    \ {cxx_var}[{c_local_i}].size());"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_len_trim
  owner: library
f_inout_void**:
  name: f_inout_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}{f_assumed_shape}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_inout_void*_cdesc:
  name: f_inout_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: inout
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_mixin_arg_capsule:
  name: f_mixin_arg_capsule
  comments:
  - Add a capsule argument to the Fortran wrapper.
  - Pass the capsule as argument to C wrapper.
  intent: mixin
  f_arg_name:
  - '{f_var_capsule}'
  f_arg_decl:
  - 'type({F_capsule_type}), intent(OUT) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_capsule}%mem'
  f_temps:
  - capsule
  f_helper:
  - array_context
  - capsule_helper
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_temps:
  - capsule
  fmtdict:
    f_var_capsule: Crv
  owner: library
f_mixin_capsule_dtor:
  name: f_mixin_capsule_dtor
  comments:
  - Release memory from capsule.
  intent: mixin
  f_post_call:
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_helper:
  - capsule_dtor
  owner: library
f_mixin_char_cdesc_allocate:
  name: f_mixin_char_cdesc_allocate
  comments:
  - Allocate Fortran CHARACTER scalar, then fill from cdesc
  - using helper copy_string.
  intent: mixin
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_post_call:
  - 'allocate(character(len={f_var_cdesc}%elem_len):: {f_var})'
  - "call {f_helper_copy_string}(\t{f_var_cdesc},\t {f_var},\t {f_var_cdesc}%elem_len)"
  f_helper:
  - copy_string
  c_helper:
  - copy_string
  owner: library
f_mixin_char_cdesc_pointer:
  name: f_mixin_char_cdesc_pointer
  comments:
  - Assign Fortran pointer from cdesc using helper pointer_string.
  intent: mixin
  f_arg_decl:
  - 'character(len=:), pointer :: {f_var}'
  f_post_call:
  - "call {f_helper_pointer_string}(\t{f_var_cdesc},\t {f_var})"
  f_module:
    iso_c_binding:
    - c_f_pointer
  f_helper:
  - pointer_string
  owner: library
f_mixin_declare-as-cptr:
  name: f_mixin_declare-as-cptr
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_mixin_declare-fortran-arg:
  name: f_mixin_declare-fortran-arg
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  owner: library
f_mixin_declare-fortran-result:
  name: f_mixin_declare-fortran-result
  intent: mixin
  f_arg_decl:
  - '{f_type}{f_deref_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  owner: library
f_mixin_declare-interface-arg:
  name: f_mixin_declare-interface-arg
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  owner: library
f_mixin_function:
  name: f_mixin_function
  comments:
  - Call a function.
  intent: mixin
  f_call:
  - '{f_result_var} = {f_call_function}({F_arg_c_call})'
  owner: library
f_mixin_function-to-subroutine:
  name: f_mixin_function-to-subroutine
  comments:
  - Call the C wrapper as a subroutine.
  intent: mixin
  f_call:
  - call {f_call_function}({F_arg_c_call})
  c_return_type: void
  owner: library
f_mixin_function_c-ptr:
  name: f_mixin_function_c-ptr
  comments:
  - Return a C pointer as a type(C_PTR).
  intent: mixin
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}'
  f_declare:
  - 'type(C_PTR) :: {f_local_ptr}'
  f_call:
  - '{f_local_ptr} = {f_call_function}({F_arg_c_call})'
  f_post_call:
  - call c_f_pointer({f_local_ptr}, {f_result_var})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  f_local:
  - ptr
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_need_wrapper: true
  owner: library
f_mixin_function_ptr:
  name: f_mixin_function_ptr
  comments:
  - Return a C pointer directly as type(C_PTR).
  intent: mixin
  f_arg_decl:
  - 'type(C_PTR) :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_result_decl:
  - 'type(C_PTR) :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_mixin_function_shadow_capsule:
  name: f_mixin_function_shadow_capsule
  comments:
  - Pass function result as a capsule argument from Fortran to C.
  intent: mixin
  f_arg_decl:
  - '{f_type} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_need_wrapper: true
  owner: library
f_mixin_function_string_cfi_allocatable:
  name: f_mixin_function_string_cfi_allocatable
  intent: mixin
  f_arg_decl:
  - 'character(len=:), allocatable :: {f_var}'
  f_arg_call:
  - '{f_var}'
  f_need_wrapper: true
  owner: library
f_mixin_getter_cdesc:
  name: f_mixin_getter_cdesc
  comments:
  - Save pointer struct members in a cdesc
  - along with shape information.
  intent: mixin
  c_call:
  - '{c_var_cdesc}->base_addr = {CXX_this}->{field_name};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_helper:
  - type_defines
  - array_context
  owner: library
f_mixin_helper_array_string_allocatable:
  name: f_mixin_helper_array_string_allocatable
  comments:
  - Allocate a vector<string> variable.
  - Assign to std::string pointer from C++ function.
  - Copy into Fortran allocated memory.
  intent: mixin
  f_post_call:
  - call {f_helper_array_string_allocatable}({f_var_cdesc}, {f_var_capsule})
  f_helper:
  - array_string_allocatable
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - std::string *{cxx_var};
  c_post_call:
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size     = {c_array_size};'
  - if ({c_char_len} > 0) {{+
  - '{c_var_cdesc}->elem_len = {c_char_len};'
  - -}} else {{+
  - '{c_var_cdesc}->elem_len = {c_helper_array_string_out_len}({cxx_var}, {c_var_cdesc}->size);'
  - -}}
  c_helper:
  - array_string_allocatable
  - array_string_out_len
  owner: library
f_mixin_helper_vector_string_allocatable:
  name: f_mixin_helper_vector_string_allocatable
  comments:
  - Allocate a vector<string> variable.
  - Copy into Fortran allocated memory.
  intent: mixin
  f_post_call:
  - call {f_helper_vector_string_allocatable}({f_var_cdesc}, {f_var_capsule})
  f_helper:
  - vector_string_allocatable
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - std::vector<std::string> *{c_local_cxx} = new std::vector<std::string>;
  c_post_call:
  - if ({c_char_len} > 0) {{+
  - '{c_var_cdesc}->elem_len = {c_char_len};'
  - -}} else {{+
  - '{c_var_cdesc}->elem_len = {c_helper_vector_string_out_len}(*{c_local_cxx});'
  - -}}
  - '{c_var_cdesc}->size      = {c_local_cxx}->size();'
  - // XXX - Use code from c_mixin_native_capsule_fill
  - '{c_var_capsule}->addr  = {c_local_cxx};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_local:
  - cxx
  c_helper:
  - vector_string_allocatable
  - vector_string_out_len
  owner: library
f_mixin_in_2d_vector_buf:
  name: f_mixin_in_2d_vector_buf
  comments:
  - Pass argument, len and size to C.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {f_var}(:,:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, 1, kind=C_SIZE_T)
  - size({f_var}, 2, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_len}'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_len}
  - size_t {c_var_size}
  c_temps:
  - len
  - size
  owner: library
f_mixin_in_string_array_buf:
  name: f_mixin_in_string_array_buf
  comments:
  - Pass argument, size and len to C.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_temps:
  - size
  - len
  owner: library
f_mixin_in_vector_buf:
  name: f_mixin_in_vector_buf
  comments:
  - Pass argument and size by value to C.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {f_var}{f_assumed_shape}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}, intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t {c_var_size}
  c_temps:
  - size
  owner: library
f_mixin_inout_array_cdesc:
  name: f_mixin_inout_array_cdesc
  comments:
  - Pass argument and size to C.
  - Pass array_type to C which will fill it in.
  intent: mixin
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - '{f_var_cdesc}'
  f_module:
    iso_c_binding:
    - C_SIZE_T
  f_temps:
  - cdesc
  f_helper:
  - array_context
  owner: library
f_mixin_interface-as-cptr:
  name: f_mixin_interface-as-cptr
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_mixin_interface-as-cptr-value:
  name: f_mixin_interface-as-cptr-value
  intent: mixin
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr}, value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  owner: library
f_mixin_local-logical-var:
  name: f_mixin_local-logical-var
  intent: mixin
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_arg_call:
  - '{f_var_cxx}'
  f_module:
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  owner: library
f_mixin_native_cdesc_allocate:
  name: f_mixin_native_cdesc_allocate
  comments:
  - Allocate Fortran native array, then fill from cdesc
  - using helper copy_array.
  intent: mixin
  f_arg_decl:
  - '{f_type}, allocatable, target :: {f_var}{f_dimension}'
  f_post_call:
  - allocate({f_var}{f_array_allocate})
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},\t\
    \ kind=C_SIZE_T))"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
    - C_SIZE_T
  f_helper:
  - copy_array
  c_helper:
  - copy_array
  owner: library
f_mixin_native_cdesc_pointer:
  name: f_mixin_native_cdesc_pointer
  comments:
  - Set Fortran pointer to native array.
  intent: mixin
  f_arg_decl:
  - '{f_type}, pointer :: {f_var}{f_assumed_shape}'
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  owner: library
f_mixin_native_cdesc_raw:
  name: f_mixin_native_cdesc_raw
  comments:
  - Set Fortran pointer to pointers to arrays.
  intent: mixin
  f_arg_decl:
  - 'type(C_PTR), pointer :: {f_var}{f_assumed_shape}'
  f_post_call:
  - "call c_f_pointer(\t{f_var_cdesc}%base_addr,\t {f_result_var}{f_array_shape})"
  f_module:
    iso_c_binding:
    - C_PTR
    - c_f_pointer
  owner: library
f_mixin_out_array_cdesc_allocatable:
  name: f_mixin_out_array_cdesc_allocatable
  comments:
  - Allocate Fortran array from cdesc.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character({f_char_len}), intent(OUT), allocatable, target :: {f_var}{f_assumed_shape}'
  f_post_call:
  - allocate({f_char_type}{f_var}({f_var_cdesc}%size))
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  f_module:
    iso_c_binding:
    - C_LOC
  owner: library
f_mixin_out_native_cdesc_allocate:
  name: f_mixin_out_native_cdesc_allocate
  comments:
  - Allocate Fortran native array for argument
  - then fill from cdesc using helper copy_array.
  intent: mixin
  f_post_call:
  - allocate({f_var}{f_array_allocate})
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t {f_var_cdesc}%size)"
  f_module:
    iso_c_binding:
    - C_LOC
  f_helper:
  - copy_array
  c_helper:
  - copy_array
  fmtdict:
    f_deref_attr: ', allocatable, target'
  owner: library
f_mixin_out_native_cdesc_pointer:
  name: f_mixin_out_native_cdesc_pointer
  comments:
  - Set Fortran pointer to native array.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, pointer :: {f_var}{f_assumed_shape}'
  f_post_call:
  - call c_f_pointer({f_var_cdesc}%base_addr, {f_var}{f_array_shape})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  owner: library
f_mixin_out_string**_cfi:
  name: f_mixin_out_string**_cfi
  intent: mixin
  c_arg_call:
  - '&{c_var_cxx}'
  c_pre_call:
  - std::string *{c_var_cxx};
  c_temps:
  - cxx
  owner: library
f_mixin_out_vector_buf:
  name: f_mixin_out_vector_buf
  comments:
  - Pass argument and size by reference to C.
  intent: mixin
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  f_module:
    iso_c_binding:
    - C_SIZE_T
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  i_arg_decl:
  - '{targs[0].f_type}{f_intent_attr} :: {i_var}(*)'
  - 'integer(C_SIZE_T){f_intent_attr} :: {i_var_size}'
  i_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
  c_arg_decl:
  - '{targs[0].cxx_type} *{c_var}'
  - size_t *{c_var_size}
  c_temps:
  - size
  owner: library
f_mixin_pass_capsule:
  name: f_mixin_pass_capsule
  comments:
  - Pass local capsule as argument to C wrapper.
  intent: mixin
  f_declare:
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_capsule}'
  f_temps:
  - capsule
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_temps:
  - capsule
  owner: library
f_mixin_pass_cdesc:
  name: f_mixin_pass_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: mixin
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_mixin_pass_character_buf:
  name: f_mixin_pass_character_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: mixin
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  owner: library
f_mixin_shadow-arg:
  name: f_mixin_shadow-arg
  comments:
  - Pass a shadow type to C wrapper.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_arg_call:
  - '{f_var}%{F_derived_member}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  f_need_wrapper: true
  owner: library
f_mixin_str_array:
  name: f_mixin_str_array
  comments:
  - Collect information about a string argument.
  intent: mixin
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = SH_TYPE_CHAR'
  - '{f_var_cdesc}%elem_len = len({f_var})'
  - '{f_var_cdesc}%size = size({f_var})'
  - '{f_var_cdesc}%rank = rank({f_var}){f_cdesc_shape}'
  f_module:
    iso_c_binding:
    - C_LOC
  f_helper:
  - type_defines
  - array_context
  owner: library
f_mixin_unknown:
  name: f_mixin_unknown
  comments:
  - Default returned by lookup_fc_stmts when group is not found.
  - The values will be added to generated code to mark where each group
  - will add text.
  intent: mixin
  f_arg_decl:
  - ===>f_arg_decl<===
  f_arg_call:
  - ===>f_arg_call<===
  i_arg_names:
  - ===>i_arg_names<===
  i_arg_decl:
  - ===>i_arg_decl<===
  i_result_decl:
  - ===>i_result_decl<===
  c_arg_decl:
  - ===>{c_var}<===
  owner: library
f_mixin_use_capsule:
  name: f_mixin_use_capsule
  comments:
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: mixin
  f_declare:
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_capsule}'
  f_post_call:
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_temps:
  - capsule
  f_helper:
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_post_call:
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_temps:
  - capsule
  owner: library
f_none_bool:
  name: f_none_bool
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_pre_call:
  - '{f_var_cxx} = {f_var}  ! coerce to C_BOOL'
  f_arg_call:
  - '{f_var_cxx}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_bool*:
  name: f_none_bool*
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_arg_call:
  - '{f_var_cxx}'
  f_post_call:
  - '{f_var} = {f_var_cxx}  ! coerce to logical'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_char:
  name: f_none_char
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character, value{f_intent_attr} :: {f_var}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(kind=C_CHAR), value{f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_CHAR
  c_arg_decl:
  - char {c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_char*:
  name: f_none_char*
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_native:
  name: f_none_native
  notes:
  - An intent of 'none' is used with function pointers
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_native*:
  name: f_none_native*
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_none_void*:
  name: f_none_void*
  intent: none
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr} :: {f_var}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_bool*:
  name: f_out_bool*
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_arg_call:
  - '{f_var_cxx}'
  f_post_call:
  - '{f_var} = {f_var_cxx}  ! coerce to logical'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_char*:
  name: f_out_char*
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_char*_buf:
  name: f_out_char*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{c_helper_char_blank_fill}({c_var}, {c_var_len});'
  c_temps:
  - len
  c_helper:
  - char_blank_fill
  owner: library
f_out_char*_capi:
  name: f_out_char*_capi
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_char*_cfi:
  name: f_out_char*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - char *{c_local_cxx} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  c_post_call:
  - '{c_helper_char_blank_fill}({c_local_cxx}, {c_var_cfi}->elem_len);'
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_blank_fill
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_enum*:
  name: f_out_enum*
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cidecl.c_var}'
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  c_post_call:
  - '*{c_var} = {cast_static}{c_type}{cast1}{cxx_var}{cast2};'
  c_local:
  - cxx
  owner: library
f_out_native&:
  name: f_out_native&
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_out_native&_hidden:
  name: f_out_native&_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: out
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
f_out_native*:
  name: f_out_native*
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_native*&_cdesc:
  name: f_out_native*&_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Set Fortran pointer to native array.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - call c_f_pointer({f_var_cdesc}%base_addr, {f_var}{f_array_shape})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{c_const}{cxx_type} *{cxx_var};'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_out_native*&_cdesc_pointer:
  name: f_out_native*&_cdesc_pointer
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Set Fortran pointer to native array.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - call c_f_pointer({f_var_cdesc}%base_addr, {f_var}{f_array_shape})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{c_const}{cxx_type} *{cxx_var};'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_out_native***:
  name: f_out_native***
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_native**_cdesc_allocatable:
  name: f_out_native**_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Allocate Fortran native array for argument
  - then fill from cdesc using helper copy_array.
  - Pass local capsule as argument to C wrapper.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  notes:
  - deref(allocatable)
  - A C function with a 'int **' argument associates it
  - with a Fortran pointer.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_post_call:
  - allocate({f_var}{f_array_allocate})
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t {f_var_cdesc}%size)"
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - copy_array
  - array_context
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{c_const}{cxx_type} *{cxx_var};'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - copy_array
  fmtdict:
    f_deref_attr: ', allocatable, target'
  owner: library
f_out_native**_cdesc_pointer:
  name: f_out_native**_cdesc_pointer
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc from native in the C wrapper.
  - Set Fortran pointer to native array.
  notes:
  - deref(pointer)
  - A C function with a 'int **' argument associates it
  - with a Fortran pointer.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, pointer :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - call c_f_pointer({f_var_cdesc}%base_addr, {f_var}{f_array_shape})
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - c_f_pointer
  f_temps:
  - cdesc
  f_helper:
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{c_const}{cxx_type} *{cxx_var};'
  c_post_call:
  - '{c_var_cdesc}->base_addr = {cxx_nonconst_ptr};'
  - '{c_var_cdesc}->type = {sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({cxx_type});'
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size = {c_array_size};'
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_out_native**_cfi_allocatable:
  name: f_out_native**_cfi_allocatable
  comments:
  - Set Fortran pointer to point to cxx_var.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_intent_attr}, allocatable :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}{c_type} * {c_local_cxx};'
  c_post_call:
  - if ({c_local_cxx} != {nullptr}) {{+
  - "{c_temp_lower_decl}{c_temp_extents_decl}int SH_ret = CFI_allocate({c_var_cfi},\
    \ \t{c_temp_lower_use}, \t{c_temp_extents_use}, \t0);"
  - if (SH_ret == CFI_SUCCESS) {{+
  - "{stdlib}memcpy({c_var_cfi}->base_addr, \t{c_local_cxx}, \t{c_var_cfi}->elem_len);"
  - -}}
  - -}}
  c_temps:
  - cfi
  - extents
  - lower
  c_local:
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_native**_cfi_pointer:
  name: f_out_native**_cfi_pointer
  comments:
  - Set Fortran pointer to point to c_local_cxx.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_intent_attr}, pointer :: {i_var}{f_assumed_shape}'
  i_module:
    iso_c_binding:
    - '{f_kind}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - '{c_const}{c_type} * {c_local_cxx};'
  c_post_call:
  - '{{+'
  - CFI_CDESC_T({rank}) {c_local_fptr};
  - CFI_cdesc_t *{c_local_cdesc} = {cast_reinterpret}CFI_cdesc_t *{cast1}&{c_local_fptr}{cast2};
  - void *{c_local_cptr} = const_cast<{c_type} *>({c_local_cxx});
  - "{c_temp_extents_decl}{c_temp_lower_decl}int {c_local_err} = CFI_establish({c_local_cdesc},\t\
    \ {c_local_cptr},\t CFI_attribute_pointer,\t {cfi_type},\t 0,\t {rank},\t {c_temp_extents_use});"
  - if ({c_local_err} == CFI_SUCCESS) {{+
  - "{c_local_err} = CFI_setpointer(\t{c_var_cfi},\t {c_local_cdesc},\t {c_temp_lower_use});"
  - -}}
  - -}}
  c_temps:
  - cfi
  - extents
  - lower
  c_local:
  - cxx
  - cptr
  - fptr
  - cdesc
  - err
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_native**_raw:
  name: f_out_native**_raw
  notes:
  - Make argument type(C_PTR) from 'int ** +intent(out)+deref(raw)'
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_native*_cdesc:
  name: f_out_native*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_out_native*_cfi_allocatable:
  name: f_out_native*_cfi_allocatable
  intent: out
  owner: library
f_out_native*_hidden:
  name: f_out_native*_hidden
  comments:
  - Declare a local variable and pass to C.
  intent: out
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - '{cxx_type} {cxx_var};'
  owner: library
f_out_string&_buf:
  name: f_out_string&_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
f_out_string&_cfi:
  name: f_out_string&_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  c_post_call:
  - "{c_helper_char_copy}({c_var},\t {c_var_cfi}->elem_len,\t {c_local_cxx}.data(),\t\
    \ {c_local_cxx}.size());"
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_string**_cdesc_allocatable:
  name: f_out_string**_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Allocate Fortran array from cdesc.
  - Allocate a vector<string> variable.
  - Assign to std::string pointer from C++ function.
  - Copy into Fortran allocated memory.
  - Assign to local capsule variable in C wrapper.
  - Release memory from capsule.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character({f_char_len}), intent(OUT), allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_post_call:
  - allocate({f_char_type}{f_var}({f_var_cdesc}%size))
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - call {f_helper_array_string_allocatable}({f_var_cdesc}, {f_var_capsule})
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_module:
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - array_string_allocatable
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - std::string *{cxx_var};
  c_post_call:
  - '{c_var_cdesc}->rank = {rank};{c_array_shape}'
  - '{c_var_cdesc}->size     = {c_array_size};'
  - if ({c_char_len} > 0) {{+
  - '{c_var_cdesc}->elem_len = {c_char_len};'
  - -}} else {{+
  - '{c_var_cdesc}->elem_len = {c_helper_array_string_out_len}({cxx_var}, {c_var_cdesc}->size);'
  - -}}
  - '{c_var_capsule}->addr  = {cxx_nonconst_ptr};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_temps:
  - cdesc
  - capsule
  c_helper:
  - array_context
  - array_string_allocatable
  - array_string_out_len
  owner: library
f_out_string**_cdesc_copy:
  name: f_out_string**_cdesc_copy
  comments:
  - Collect information about a string argument.
  - Pass cdesc as argument to C wrapper.
  notes:
  - Pass a cdesc down to describe the memory and a capsule to hold the
  - C++ array. Copy into Fortran argument.
  - '[see also f_out_vector_&_cdesc_allocatable_targ_string_scalar]'
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = SH_TYPE_CHAR'
  - '{f_var_cdesc}%elem_len = len({f_var})'
  - '{f_var_cdesc}%size = size({f_var})'
  - '{f_var_cdesc}%rank = rank({f_var}){f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '&{cxx_var}'
  c_pre_call:
  - std::string *{cxx_var};
  c_post_call:
  - "{c_helper_array_string_out}(\t{c_var_cdesc},\t {cxx_var}, {c_array_size2});"
  c_temps:
  - cdesc
  c_helper:
  - array_string_out
  owner: library
f_out_string**_cfi_allocatable:
  name: f_out_string**_cfi_allocatable
  comments:
  - Make the argument a CFI_desc_t.
  notes:
  - std::string **strs +intent(out)+dimension(nstrs)+deref(allocatable),
  - int *nstrs+intent(out)+hidden
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(*){f_intent_attr} :: {i_var}{f_assumed_shape}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_var_cxx}'
  c_pre_call:
  - std::string *{c_var_cxx};
  c_post_call:
  - // Allocate and copy into {c_var}
  c_temps:
  - cfi
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_string**_cfi_copy:
  name: f_out_string**_cfi_copy
  comments:
  - Make the argument a CFI_desc_t.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(*){f_intent_attr} :: {i_var}{f_assumed_shape}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_var_cxx}'
  c_pre_call:
  - std::string *{c_var_cxx};
  c_post_call:
  - // Copy results into {c_var}
  c_temps:
  - cfi
  - cxx
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_string**_copy:
  name: f_out_string**_copy
  notes:
  - std::string **arg+intent(out)+dimension(size)
  - Returning a pointer to a string*. However, this needs additional
  - mapping for the C interface.  Fortran calls the +api(cdesc) variant.
  intent: out
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr}, value :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
  notimplemented: true
f_out_string*_buf:
  name: f_out_string*_buf
  comments:
  - Pass CHARACTER and LEN to C wrapper.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  c_post_call:
  - "{c_helper_char_copy}({c_var}, {c_var_len},\t {c_local_cxx}.data(),\t {c_local_cxx}.size());"
  c_temps:
  - len
  c_local:
  - cxx
  c_helper:
  - char_copy
  owner: library
f_out_string*_cfi:
  name: f_out_string*_cfi
  comments:
  - Make the argument a CFI_desc_t.
  - Local character argument passed as CFI_desc_t.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'character(len=*){f_intent_attr} :: {i_var}'
  c_arg_decl:
  - CFI_cdesc_t *{c_var_cfi}
  c_arg_call:
  - '&{c_local_cxx}'
  c_pre_call:
  - std::string {c_local_cxx};
  - char *{c_var} = {cast_static}char *{cast1}{c_var_cfi}->base_addr{cast2};
  c_post_call:
  - "{c_helper_char_copy}({c_var},\t {c_var_cfi}->elem_len,\t {c_local_cxx}.data(),\t\
    \ {c_local_cxx}.size());"
  c_temps:
  - cfi
  c_local:
  - cxx
  c_helper:
  - char_copy
  iface_header:
  - ISO_Fortran_binding.h
  owner: library
f_out_struct&:
  name: f_out_struct&
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_out_struct*:
  name: f_out_struct*
  notes:
  - Used with in, out, inout.
  - C pointer -> void pointer -> C++ pointer
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_vector<native>&_cdesc:
  name: f_out_vector<native>&_cdesc
  comments:
  - copy into user's existing array.
  notes:
  - c_local_cxx is always a pointer to a vector.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - copy_array
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_out_vector<native>&_cdesc_allocatable:
  name: f_out_vector<native>&_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  - Create a std::vector on the stack and pass to C++.
  notes:
  - Copy into allocated array.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - allocate({f_var}({f_var_cdesc}%size))
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_LOC
    - C_SIZE_T
  f_temps:
  - cdesc
  f_helper:
  - copy_array
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_out_vector<native>*_cdesc:
  name: f_out_vector<native>*_cdesc
  comments:
  - copy into user's existing array.
  notes:
  - c_local_cxx is always a pointer to a vector.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_SIZE_T
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - copy_array
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  - type_defines
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_out_vector<native>*_cdesc_allocatable:
  name: f_out_vector<native>*_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Fill cdesc with vector information,
  - ' Return address and size of vector data.'
  - Create a std::vector on the stack and pass to C++.
  notes:
  - Copy into allocated array.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_post_call:
  - allocate({f_var}({f_var_cdesc}%size))
  - "call {f_helper_copy_array}(\t{f_var_cdesc},\t C_LOC({f_var}),\t size({f_var},kind=C_SIZE_T))"
  f_module:
    iso_c_binding:
    - '{targs[0].f_kind}'
    - C_LOC
    - C_SIZE_T
  f_temps:
  - cdesc
  f_helper:
  - copy_array
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - "{c_const}std::vector<{cxx_T}>\t *{c_local_cxx} = new std::vector<{cxx_T}>;"
  c_post_call:
  - '{c_var_cdesc}->base_addr = {c_local_cxx}->empty() ? {nullptr} : &{c_local_cxx}->front();'
  - '{c_var_cdesc}->type = {targs[0].sh_type};'
  - '{c_var_cdesc}->elem_len = sizeof({targs[0].cxx_type});'
  - '{c_var_cdesc}->size = {c_local_cxx}->size();'
  - '{c_var_cdesc}->rank = 1;'
  - '{c_var_cdesc}->shape[0] = {c_var_cdesc}->size;'
  c_temps:
  - cdesc
  c_local:
  - cxx
  c_helper:
  - copy_array
  destructor_name: std_vector_{cxx_T}
  destructor:
  - "std::vector<{cxx_T}> *cxx_ptr = \treinterpret_cast<std::vector<{cxx_T}> *>(ptr);"
  - delete cxx_ptr;
  owner: library
f_out_vector<string>&_cdesc:
  name: f_out_vector<string>&_cdesc
  comments:
  - Collect information about a string argument.
  - Pass cdesc as argument to C wrapper.
  notes:
  - f_arg_decl replaces values from f_mixin_str_array.
  - This one needs to use targs.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{targs[0].f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = SH_TYPE_CHAR'
  - '{f_var_cdesc}%elem_len = len({f_var})'
  - '{f_var_cdesc}%size = size({f_var})'
  - '{f_var_cdesc}%rank = rank({f_var}){f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - '{c_const}std::vector<std::string> {cxx_var};'
  c_post_call:
  - "{c_helper_vector_string_out}(\t{c_var_cdesc},\t {cxx_var});"
  c_temps:
  - cdesc
  c_helper:
  - vector_string_out
  owner: library
f_out_vector<string>&_cdesc_allocatable:
  name: f_out_vector<string>&_cdesc_allocatable
  comments:
  - Pass cdesc as argument to C wrapper.
  - Pass local capsule as argument to C wrapper.
  - Allocate Fortran array from cdesc.
  - Allocate a vector<string> variable.
  - Copy into Fortran allocated memory.
  - Release memory from capsule.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character({f_char_len}), intent(OUT), allocatable, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  - 'type({F_capsule_data_type}) :: {f_var_capsule}'
  f_arg_call:
  - '{f_var_cdesc}'
  - '{f_var_capsule}'
  f_post_call:
  - allocate({f_char_type}{f_var}({f_var_cdesc}%size))
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - call {f_helper_vector_string_allocatable}({f_var_cdesc}, {f_var_capsule})
  - call {f_helper_capsule_dtor}({f_var_capsule})
  f_module:
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  - capsule
  f_helper:
  - array_context
  - array_context
  - vector_string_allocatable
  - capsule_dtor
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  - '{i_var_capsule}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  - 'type({F_capsule_data_type}), intent(OUT) :: {i_var_capsule}'
  i_import:
  - '{F_array_type}'
  - '{F_capsule_data_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  - '{C_capsule_data_type} *{c_var_capsule}'
  c_arg_call:
  - '*{c_local_cxx}'
  c_pre_call:
  - std::vector<std::string> *{c_local_cxx} = new std::vector<std::string>;
  c_post_call:
  - if ({c_char_len} > 0) {{+
  - '{c_var_cdesc}->elem_len = {c_char_len};'
  - -}} else {{+
  - '{c_var_cdesc}->elem_len = {c_helper_vector_string_out_len}(*{c_local_cxx});'
  - -}}
  - '{c_var_cdesc}->size      = {c_local_cxx}->size();'
  - // XXX - Use code from c_mixin_native_capsule_fill
  - '{c_var_capsule}->addr  = {c_local_cxx};'
  - '{c_var_capsule}->idtor = {idtor};'
  c_temps:
  - cdesc
  - capsule
  c_local:
  - cxx
  c_helper:
  - array_context
  - vector_string_allocatable
  - vector_string_out_len
  owner: library
f_out_vector_buf_targ_string_scalar:
  name: f_out_vector_buf_targ_string_scalar
  comments:
  - Pass argument, size and len to C.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*), intent(IN) :: {f_var}(:)'
  f_arg_call:
  - '{f_var}'
  - size({f_var}, kind=C_SIZE_T)
  - len({f_var}, kind=C_INT)
  f_module:
    iso_c_binding:
    - C_SIZE_T
    - C_INT
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_size}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR), intent(IN) :: {i_var}(*)'
  - 'integer(C_SIZE_T), intent(IN), value :: {i_var_size}'
  - 'integer(C_INT), intent(IN), value :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_SIZE_T
    - C_INT
  c_arg_decl:
  - const char *{c_var}
  - size_t {c_var_size}
  - int {c_var_len}
  c_arg_call:
  - '{c_local_cxx}'
  c_pre_call:
  - '{c_const}std::vector<{cxx_T}> {c_local_var};'
  c_post_call:
  - '{{+'
  - char * {c_local_s} = {c_var};
  - std::vector<{cxx_T}>::size_type
  - +{c_local_i} = 0,
  - '{c_local_n} = {c_var_size};'
  - '{c_local_n} = std::min({c_local_var}.size(),{c_local_n});'
  - -for(; {c_local_i} < {c_local_n}; {c_local_i}++) {{+
  - "{c_helper_char_copy}({c_local_s}, {c_var_len},\t {c_local_var}[{c_local_i}].data(),\t\
    \ {c_local_var}[{c_local_i}].size());"
  - '{c_local_s} += {c_var_len};'
  - -}}
  - -}}
  c_temps:
  - size
  - len
  c_local:
  - cxx
  - i
  - n
  - s
  c_helper:
  - char_copy
  owner: library
f_out_void*&:
  name: f_out_void*&
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '*{cxx_var}'
  owner: library
f_out_void**:
  name: f_out_void**
  notes:
  - Treat as an assumed length array in Fortran interface.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {f_var}{f_assumed_shape}'
  f_module:
    iso_c_binding:
    - C_PTR
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR){f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - void **{c_var}
  c_arg_call:
  - '{cxx_var}'
  owner: library
f_out_void*_cdesc:
  name: f_out_void*_cdesc
  comments:
  - Pass cdesc as argument to C wrapper.
  intent: out
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_intent_attr}, target :: {f_var}{f_assumed_shape}'
  f_declare:
  - 'type({F_array_type}) :: {f_var_cdesc}'
  f_pre_call:
  - '{f_var_cdesc}%base_addr = C_LOC({f_var})'
  - '{f_var_cdesc}%type = {sh_type}'
  - '! {f_var_cdesc}%elem_len = C_SIZEOF()'
  - '{f_var_cdesc}%size = {size}'
  - '{f_var_cdesc}%rank = {rank}{f_cdesc_shape}'
  f_arg_call:
  - '{f_var_cdesc}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_LOC
  f_temps:
  - cdesc
  f_helper:
  - type_defines
  - array_context
  f_need_wrapper: true
  i_arg_names:
  - '{i_var_cdesc}'
  i_arg_decl:
  - 'type({F_array_type}), intent(OUT) :: {i_var_cdesc}'
  i_import:
  - '{F_array_type}'
  c_arg_decl:
  - '{C_array_type} *{c_var_cdesc}'
  c_arg_call:
  - '{cxx_var}'
  c_pre_call:
  - "{cxx_type} * {c_var} = static_cast<{cxx_type} *>\t(const_cast<void *>({c_var_cdesc}->base_addr));"
  c_temps:
  - cdesc
  c_helper:
  - array_context
  owner: library
f_setter:
  name: f_setter
  intent: setter
  f_call:
  - call {f_call_function}({F_arg_c_call})
  c_call:
  - // skip call c_setter
  owner: library
f_setter_bool:
  name: f_setter_bool
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_declare:
  - 'logical(C_BOOL) :: {f_var_cxx}'
  f_pre_call:
  - '{f_var_cxx} = {f_var}  ! coerce to C_BOOL'
  f_arg_call:
  - '{f_var_cxx}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
    iso_c_binding:
    - C_BOOL
  f_temps:
  - cxx
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_setter_native:
  name: f_setter_native
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{fc_var}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_setter_native*:
  name: f_setter_native*
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_arg_call:
  - '{fc_var}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_setter_string_buf:
  name: f_setter_string_buf
  comments:
  - Extract meta data and pass to C.
  - Create std::string from Fortran meta data.
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - 'character(len=*){f_intent_attr} :: {f_var}'
  f_declare:
  - integer(C_INT) {f_var_len}
  f_pre_call:
  - '{f_var_len} = len({f_var}, kind=C_INT)'
  f_arg_call:
  - '{f_var}'
  - '{f_var_len}'
  f_module:
    iso_c_binding:
    - C_INT
  f_temps:
  - len
  f_need_wrapper: true
  i_arg_names:
  - '{i_var}'
  - '{i_var_len}'
  i_arg_decl:
  - 'character(kind=C_CHAR){f_intent_attr} :: {i_var}(*)'
  - 'integer(C_INT), value, intent(IN) :: {i_var_len}'
  i_module:
    iso_c_binding:
    - C_CHAR
    - C_INT
  c_arg_decl:
  - char *{c_var}
  - int {c_var_len}
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - "{CXX_this}->{field_name} = std::string({c_var},\t {c_var_len});"
  c_temps:
  - len
  owner: library
f_setter_struct*:
  name: f_setter_struct*
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_setter_struct**:
  name: f_setter_struct**
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - 'type(C_PTR), intent(IN) :: {i_var}{i_dimension}'
  i_module:
    iso_c_binding:
    - C_PTR
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_setter_struct*_pointer:
  name: f_setter_struct*_pointer
  intent: setter
  f_arg_name:
  - '{f_var}'
  f_arg_decl:
  - '{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_optional_attr} :: {f_var}{f_dimension}'
  f_module:
    '{f_module_name}':
    - '{f_kind}'
  i_arg_names:
  - '{i_var}'
  i_arg_decl:
  - '{i_type}{f_value_attr}{f_intent_attr} :: {i_var}{i_dimension}'
  i_module:
    '{i_module_name}':
    - '{i_kind}'
  c_arg_decl:
  - '{gen.cdecl.c_var}'
  c_arg_call:
  - '{cxx_var}'
  c_post_call:
  - '{CXX_this}->{field_name} = val;'
  owner: library
f_subroutine:
  name: f_subroutine
  intent: subroutine
  f_call:
  - call {f_call_function}({F_arg_c_call})
  owner: library
f_subroutine_assignment_weakptr:
  name: f_subroutine_assignment_weakptr
  notes:
  - std::weak_ptr has no wrapped constructor.
  - It must be made from a std::shared_ptr with an assignment.
  - arglist[1] is the 'from' argument.
  intent: subroutine
  f_call:
  - call {f_call_function}({F_arg_c_call})
  c_call:
  - if (SH_this == nullptr) {{+
  - SH_this = new {cxx_type}(*SHC_from_cxx);
  - self->addr = SH_this;
  - self->idtor = {idtor};
  - -}} else {{+
  - '*{CXX_this} = *{c_arglist[1].c_local_cxx};'
  - -}}
  destructor_header:
  - <memory>
  destructor_name: assignment-{cxx_type}
  destructor:
  - "auto cxx_ptr =\t reinterpret_cast<{cxx_type}*>(ptr);"
  - delete cxx_ptr;
  owner: library
h_helper_array_context:
  name: h_helper_array_context
  notes:
  - XXX - Create a union for addr to avoid some casts.
  - And help with debugging since ccharp will display contents.
  - Create a derived type used to communicate with C wrapper.
  - Should never be exposed to user.
  - Inspired by futher interoperability with C.
  - XXX - shape is C_LONG, maybe it should be C_PTRDIFF_T.
  c_fmtname: LIB_SHROUD_array
  include:
  - <stddef.h>
  scope: cwrap_include
  source:
  - ''
  - // helper array_context
  - struct s_LIB_SHROUD_array {+
  - void * base_addr;
  - int type;        /* type of element */
  - size_t elem_len; /* bytes-per-item or character len in c++ */
  - size_t size;     /* size of data in c++ */
  - int rank;        /* number of dimensions, 0=scalar */
  - long shape[7];
  - -};
  - typedef struct s_LIB_SHROUD_array LIB_SHROUD_array;
  f_fmtname: LIB_SHROUD_array
  derived_type:
  - ''
  - '! helper array_context'
  - 'type, bind(C) :: LIB_SHROUD_array+'
  - '! address of data'
  - 'type(C_PTR) :: base_addr = C_NULL_PTR'
  - '! type of element'
  - 'integer(C_INT) :: type'
  - '! bytes-per-item or character len of data in cxx'
  - 'integer(C_SIZE_T) :: elem_len = 0_C_SIZE_T'
  - '! size of data in cxx'
  - 'integer(C_SIZE_T) :: size = 0_C_SIZE_T'
  - '! number of dimensions'
  - 'integer(C_INT) :: rank = -1'
  - 'integer(C_LONG) :: shape(7) = 0'
  - -end type LIB_SHROUD_array
  modules:
    iso_c_binding:
    - C_NULL_PTR
    - C_PTR
    - C_SIZE_T
    - C_INT
    - C_LONG
  dependent_helpers:
  - type_defines
h_helper_array_string_allocatable:
  name: h_helper_array_string_allocatable
  notes:
  - Only used with std::string and thus C++.
  - Called from Fortran to deal with allocatable character
  - The capsule contains a pointer to a std::vector<std::string>
  - which is copied into the cdesc.
  fmtdict:
    cnamefunc: '{C_prefix}ShroudArrayStringAllocatable'
    fnamefunc: '{C_prefix}SHROUD_array_string_allocatable'
    cnameproto: void {cnamefunc}({C_array_type} *dest, {C_capsule_data_type} *src)
  api: c
  c_fmtname: LIB_ShroudArrayStringAllocatable
  scope: cwrap_impl
  proto: void LIB_ShroudArrayStringAllocatable(LIB_SHROUD_array *dest, LIB_SHROUD_capsule_data
    *src);
  source:
  - ''
  - // helper array_string_allocatable
  - // Copy the std::string array into Fortran array.
  - // Called by Fortran to deal with allocatable character.
  - // out is already blank filled.
  - void LIB_ShroudArrayStringAllocatable(LIB_SHROUD_array *dest, LIB_SHROUD_capsule_data
    *src)
  - '{+'
  - "std::string *cxxvec =\t static_cast< std::string *>\t(src->addr);"
  - LIB_ShroudArrayStringOut(dest, cxxvec, dest->size);
  - -}
  f_fmtname: LIB_SHROUD_array_string_allocatable
  interface:
  - ''
  - interface+
  - '! helper array_string_allocatable'
  - subroutine LIB_SHROUD_array_string_allocatable(dest, src) &
  - '     bind(c,name="LIB_ShroudArrayStringAllocatable")+'
  - import LIB_SHROUD_array, LIB_SHROUD_capsule_data
  - 'type(LIB_SHROUD_array), intent(IN) :: dest'
  - 'type(LIB_SHROUD_capsule_data), intent(IN) :: src'
  - -end subroutine LIB_SHROUD_array_string_allocatable
  - -end interface
  dependent_helpers:
  - capsule_data_helper
  - array_context
  - array_string_out
h_helper_array_string_out:
  name: h_helper_array_string_out
  notes:
  - Only used with std::string and thus C++.
  fmtdict:
    cnamefunc: '{C_prefix}ShroudArrayStringOut'
    cnamefunc_array_string_out: '{cnamefunc}'
    cnameproto: void {cnamefunc}({C_array_type} *outdesc, std::string *in, size_t
      nsize)
  api: cxx
  c_fmtname: LIB_ShroudArrayStringOut
  cxx_include:
  - <cstring>
  - <cstddef>
  proto_include:
  - <string>
  - <vector>
  scope: cwrap_impl
  proto: void LIB_ShroudArrayStringOut(LIB_SHROUD_array *outdesc, std::string *in,
    size_t nsize);
  source:
  - ''
  - // helper array_string_out
  - // Copy the std::vector<std::string> into Fortran array argument.
  - // Called by C++.
  - void LIB_ShroudArrayStringOut(LIB_SHROUD_array *outdesc, std::string *in, size_t
    nsize)
  - '{+'
  - size_t nvect = outdesc->size;
  - size_t len = outdesc->elem_len;
  - char *dest = static_cast<char *>(outdesc->base_addr);
  - // Clear user memory
  - std::memset(dest, ' ', nvect*len);
  - ''
  - // Copy into user memory
  - nvect = std::min(nvect, nsize);
  - for (size_t i = 0; i < nvect; ++i) {+
  - std::memcpy(dest, in[i].data(), std::min(len, in[i].length()));
  - dest += outdesc->elem_len;
  - -}
  - -}
  dependent_helpers:
  - array_context
h_helper_array_string_out_len:
  name: h_helper_array_string_out_len
  fmtdict:
    cnamefunc: '{C_prefix}ShroudArrayStringOutSize'
    cnameproto: size_t {cnamefunc}(std::string *in, size_t nsize)
  api: cxx
  c_fmtname: LIB_ShroudArrayStringOutSize
  proto_include:
  - <string>
  - <vector>
  scope: cwrap_impl
  proto: size_t LIB_ShroudArrayStringOutSize(std::string *in, size_t nsize);
  source:
  - ''
  - // helper array_string_out_len
  - // Return the maximum string length in a std::vector<std::string>.
  - size_t LIB_ShroudArrayStringOutSize(std::string *in, size_t nsize)
  - '{+'
  - size_t len = 0;
  - for (size_t i = 0; i < nsize; ++i) {+
  - len = std::max(len, in[i].length());
  - -}
  - return len;
  - -}
h_helper_capsule_data_helper:
  name: h_helper_capsule_data_helper
  notes:
  - Share info with C++ to allow Fortran to release memory.
  - Used with shadow classes and std::vector.
  scope: cwrap_include
  source:
  - ''
  - // helper capsule_data_helper
  - struct s_LIB_SHROUD_capsule_data {+
  - void *addr;     /* address of C++ memory */
  - int idtor;      /* index of destructor */
  - -};
  - typedef struct s_LIB_SHROUD_capsule_data LIB_SHROUD_capsule_data;
  f_fmtname: LIB_SHROUD_capsule_data
  derived_type:
  - ''
  - '! helper capsule_data_helper'
  - 'type, bind(C) :: LIB_SHROUD_capsule_data+'
  - 'type(C_PTR) :: addr = C_NULL_PTR  ! address of C++ memory'
  - 'integer(C_INT) :: idtor = 0       ! index of destructor'
  - -end type LIB_SHROUD_capsule_data
  modules:
    iso_c_binding:
    - C_PTR
    - C_INT
    - C_NULL_PTR
h_helper_capsule_dtor:
  name: h_helper_capsule_dtor
  notes:
  - Add the C prototype. The body is created Wrapc.write_capsule_code.
  fmtdict:
    cnamefunc: '{C_memory_dtor_function}'
    cnameproto: "void {cnamefunc}\t({C_capsule_data_type} *cap)"
    fnamefunc: '{C_prefix}SHROUD_capsule_dtor'
    fnamefunc_capsule_dtor: '{fnamefunc}'
  api: c
  c_fmtname: LIB_SHROUD_memory_destructor
  proto: "void LIB_SHROUD_memory_destructor\t(LIB_SHROUD_capsule_data *cap);"
  f_fmtname: LIB_SHROUD_capsule_dtor
  interface:
  - ''
  - interface+
  - '! helper capsule_dtor'
  - '! Delete memory in a capsule.'
  - "subroutine LIB_SHROUD_capsule_dtor(ptr)\tbind(C, name=\"LIB_SHROUD_memory_destructor\"\
    )+"
  - import LIB_SHROUD_capsule_data
  - implicit none
  - 'type(LIB_SHROUD_capsule_data), intent(INOUT) :: ptr'
  - -end subroutine LIB_SHROUD_capsule_dtor
  - -end interface
  dependent_helpers:
  - capsule_data_helper
h_helper_capsule_helper:
  name: h_helper_capsule_helper
  notes:
  - Fortran cannot be declared with both PRIVATE and BIND(C) attributes
  derived_type:
  - ''
  - '! helper capsule_helper'
  - 'type :: LIB_SHROUD_capsule+'
  - private
  - 'type(LIB_SHROUD_capsule_data) :: mem'
  - -contains
  - '+final :: SHROUD_capsule_final'
  - 'procedure :: delete => SHROUD_capsule_delete'
  - -end type LIB_SHROUD_capsule
  f_source:
  - ''
  - '! helper capsule_helper'
  - '! finalize a static LIB_SHROUD_capsule_data'
  - subroutine SHROUD_capsule_final(cap)+
  - 'type(LIB_SHROUD_capsule), intent(INOUT) :: cap'
  - call LIB_SHROUD_capsule_dtor(cap%mem)
  - -end subroutine SHROUD_capsule_final
  - ''
  - subroutine SHROUD_capsule_delete(cap)+
  - 'class(LIB_SHROUD_capsule) :: cap'
  - call LIB_SHROUD_capsule_dtor(cap%mem)
  - -end subroutine SHROUD_capsule_delete
  dependent_helpers:
  - capsule_data_helper
  - capsule_dtor
h_helper_char_alloc:
  name: h_helper_char_alloc
  notes:
  - Used by 'const char *' arguments which need to be NULL terminated
  - in the C wrapper.
  c_fmtname: ShroudCharAlloc
  c_include:
  - <string.h>
  - <stdlib.h>
  - <stddef.h>
  cxx_include:
  - <cstring>
  - <cstdlib>
  source:
  - ''
  - // helper char_alloc
  - // Copy src into new memory and null terminate.
  - // If ntrim is 0, return NULL pointer.
  - // If blanknull is 1, return NULL when string is blank.
  - static char *ShroudCharAlloc(const char *src, int nsrc, int blanknull)
  - '{+'
  - int ntrim = ShroudCharLenTrim(src, nsrc);
  - if (ntrim == 0 && blanknull == 1) {+
  - return nullptr;
  - -}
  - char *rv = (char *) std::malloc(nsrc + 1);
  - if (ntrim > 0) {+
  - std::memcpy(rv, src, ntrim);
  - -}
  - rv[ntrim] = '\0';
  - return rv;
  - -}
  dependent_helpers:
  - char_len_trim
h_helper_char_array_alloc:
  name: h_helper_char_array_alloc
  notes:
  - Used with 'char **' arguments.
  c_fmtname: ShroudStrArrayAlloc
  c_include:
  - <string.h>
  - <stdlib.h>
  cxx_include:
  - <cstring>
  - <cstdlib>
  source:
  - ''
  - // helper char_array_alloc
  - // Copy src into new memory and null terminate.
  - // char **src +size(nsrc) +len(len)
  - // CHARACTER(len) src(nsrc)
  - static char **ShroudStrArrayAlloc(const char *src, int nsrc, int len)
  - '{+'
  - "char **rv = static_cast<char **>\t(std::malloc(sizeof(char *) * nsrc));"
  - const char *src0 = src;
  - for(int i=0; i < nsrc; ++i) {+
  - int ntrim = ShroudCharLenTrim(src0, len);
  - "char *tgt = static_cast<char *>\t(std::malloc(ntrim+1));"
  - std::memcpy(tgt, src0, ntrim);
  - tgt[ntrim] = '\0';
  - rv[i] = tgt;
  - src0 += len;
  - -}
  - return rv;
  - -}
  dependent_helpers:
  - char_len_trim
h_helper_char_array_free:
  name: h_helper_char_array_free
  c_fmtname: ShroudStrArrayFree
  c_include:
  - <stdlib.h>
  cxx_include:
  - <cstdlib>
  source:
  - ''
  - // helper char_array_free
  - // Release memory allocated by ShroudStrArrayAlloc
  - static void ShroudStrArrayFree(char **src, int nsrc)
  - '{+'
  - for(int i=0; i < nsrc; ++i) {+
  - std::free(src[i]);
  - -}
  - std::free(src);
  - -}
h_helper_char_blank_fill:
  name: h_helper_char_blank_fill
  c_fmtname: ShroudCharBlankFill
  c_include:
  - <string.h>
  cxx_include:
  - <cstring>
  source:
  - ''
  - // helper char_blank_fill
  - // blank fill dest starting at trailing NULL.
  - static void ShroudCharBlankFill(char *dest, int ndest)
  - '{+'
  - int nm = std::strlen(dest);
  - if(ndest > nm) std::memset(dest+nm,' ',ndest-nm);
  - -}
h_helper_char_copy:
  name: h_helper_char_copy
  c_fmtname: ShroudCharCopy
  c_include:
  - <string.h>
  cxx_include:
  - <cstring>
  source:
  - ''
  - // helper ShroudCharCopy
  - // Copy src into dest, blank fill to ndest characters
  - // Truncate if dest is too short.
  - // dest will not be NULL terminated.
  - static void ShroudCharCopy(char *dest, int ndest, const char *src, int nsrc)
  - '{+'
  - if (src == NULL) {+
  - std::memset(dest,' ',ndest); // convert NULL pointer to blank filled string
  - -} else {+
  - if (nsrc < 0) nsrc = std::strlen(src);
  - 'int nm = nsrc < ndest ? nsrc : ndest;'
  - std::memcpy(dest,src,nm);
  - if(ndest > nm) std::memset(dest+nm,' ',ndest-nm); // blank fill
  - -}
  - -}
h_helper_char_free:
  name: h_helper_char_free
  c_fmtname: ShroudCharFree
  c_include:
  - <stdlib.h>
  cxx_include:
  - <cstdlib>
  source:
  - ''
  - // helper char_free
  - // Release memory allocated by ShroudCharAlloc
  - static void ShroudCharFree(char *src)
  - '{+'
  - if (src != NULL) {+
  - std::free(src);
  - -}
  - -}
h_helper_char_len_trim:
  name: h_helper_char_len_trim
  c_fmtname: ShroudCharLenTrim
  source:
  - ''
  - // helper char_len_trim
  - // Returns the length of character string src with length nsrc,
  - // ignoring any trailing blanks.
  - static int ShroudCharLenTrim(const char *src, int nsrc) {+
  - int i;
  - ''
  - for (i = nsrc - 1; i >= 0; i--) {+
  - if (src[i] != ' ') {+
  - break;
  - -}
  - -}
  - ''
  - return i + 1;
  - -}
  - ''
h_helper_copy_array:
  name: h_helper_copy_array
  notes:
  - XXX - Only used with std::vector and thus C++.
  - Create Fortran interface to helper function which copies an array.
  - Used with sgroup='native' types.
  - The function has C_prefix in the name since it is not file static.
  - This allows multiple wrapped libraries to coexist.
  - Create a single C routine which is called from Fortran
  - via an interface for each cxx_type.
  - XXX when f_kind == C_SIZE_T
  fmtdict:
    cnamefunc: '{C_prefix}ShroudCopyArray'
    fnamefunc: '{C_prefix}SHROUD_{hname}'
  c_fmtname: LIB_ShroudCopyArray
  c_include:
  - <string.h>
  - <stddef.h>
  cxx_include:
  - <cstring>
  - <cstddef>
  scope: cwrap_impl
  source:
  - ''
  - // helper copy_array
  - // Copy std::vector into array c_var(c_var_size).
  - // Then release std::vector.
  - // Called from Fortran.
  - "void LIB_ShroudCopyArray(LIB_SHROUD_array *data, \tvoid *c_var, \tsize_t c_var_size)"
  - '{+'
  - const void *cxx_var = data->base_addr;
  - 'int n = c_var_size < data->size ? c_var_size : data->size;'
  - n *= data->elem_len;
  - std::memcpy(c_var, cxx_var, n);
  - -}
  f_fmtname: LIB_SHROUD_copy_array
  interface:
  - ''
  - interface+
  - '! helper copy_array'
  - '! Copy contents of context into c_var.'
  - subroutine LIB_SHROUD_copy_array(context, c_var, c_var_size) &+
  - bind(C, name="LIB_ShroudCopyArray")
  - 'use iso_c_binding, only : C_PTR, C_SIZE_T'
  - import LIB_SHROUD_array
  - 'type(LIB_SHROUD_array), intent(IN) :: context'
  - 'type(C_PTR), intent(IN), value :: c_var'
  - 'integer(C_SIZE_T), value :: c_var_size'
  - -end subroutine LIB_SHROUD_copy_array
  - -end interface
  dependent_helpers:
  - array_context
h_helper_copy_string:
  name: h_helper_copy_string
  notes:
  - Deal with allocatable character.
  fmtdict:
    cnamefunc: '{C_prefix}ShroudCopyString'
    fnamefunc: '{C_prefix}SHROUD_copy_string'
  c_fmtname: LIB_ShroudCopyString
  cxx_include:
  - <cstring>
  - <cstddef>
  scope: cwrap_impl
  source:
  - ''
  - // helper copy_string
  - // Copy the char* or std::string in context into c_var.
  - // Called by Fortran to deal with allocatable character.
  - "void LIB_ShroudCopyString(\tLIB_SHROUD_array *data,\t char *c_var,\t size_t c_var_len)\
    \ {+"
  - const void *cxx_var = data->base_addr;
  - size_t n = c_var_len;
  - if (data->elem_len < n) n = data->elem_len;
  - std::memcpy(c_var, cxx_var, n);
  - -}
  f_fmtname: LIB_SHROUD_copy_string
  interface:
  - ''
  - interface+
  - '! helper copy_string'
  - '! Copy the char* or std::string in context into c_var.'
  - subroutine LIB_SHROUD_copy_string(context, c_var, c_var_size) &
  - '     bind(c,name="LIB_ShroudCopyString")+'
  - 'use, intrinsic :: iso_c_binding, only : C_CHAR, C_SIZE_T'
  - import LIB_SHROUD_array
  - 'type(LIB_SHROUD_array), intent(IN) :: context'
  - 'character(kind=C_CHAR), intent(OUT) :: c_var(*)'
  - 'integer(C_SIZE_T), value :: c_var_size'
  - -end subroutine LIB_SHROUD_copy_string
  - -end interface
  dependent_helpers:
  - array_context
h_helper_pointer_string:
  name: h_helper_pointer_string
  notes:
  - Set Fortran POINTER to string.
  - Must be a function (or a F2008 BLOCK) since fptr must
  - be declared after the string length is known.
  fmtdict:
    fnamefunc: '{C_prefix}SHROUD_pointer_string'
  f_fmtname: LIB_SHROUD_pointer_string
  f_source:
  - ''
  - '! helper pointer_string'
  - '! Assign context to an assumed-length character pointer'
  - subroutine LIB_SHROUD_pointer_string(context, var)+
  - 'use iso_c_binding, only : c_f_pointer, C_PTR'
  - implicit none
  - 'type(LIB_SHROUD_array), intent(IN) :: context'
  - 'character(len=:), pointer, intent(OUT) :: var'
  - 'character(len=context%elem_len), pointer :: fptr'
  - call c_f_pointer(context%base_addr, fptr)
  - var => fptr
  - -end subroutine LIB_SHROUD_pointer_string
  dependent_helpers:
  - array_context
h_helper_size_CFI:
  name: h_helper_size_CFI
  notes:
  - Find size of CFI array.
  c_include:
  - <stddef.h>
  cxx_include:
  - <cstddef>
  source:
  - ''
  - // helper size_CFI
  - // Compute number of items in CFI_cdesc_t
  - size_t ShroudSizeCFI(CFI_cdesc_t *desc)
  - '{+'
  - size_t nitems = 1;
  - for (int i = 0; i < desc->rank; i++) {+
  - nitems *= desc->dim[i].extent;
  - -}
  - return nitems;
  - -}
h_helper_string_to_cdesc:
  name: h_helper_string_to_cdesc
  fmtdict:
    cnamefunc: ShroudStringToCdesc
  c_fmtname: ShroudStringToCdesc
  cxx_include:
  - <cstring>
  - <cstddef>
  source:
  - ''
  - // helper string_to_cdesc
  - // Save std::string metadata into array to allow Fortran to access values.
  - // CHARACTER(len=elem_size) src
  - "static void ShroudStringToCdesc(\tLIB_SHROUD_array *cdesc,\t const std::string\
    \ * src)"
  - '{+'
  - if (src->empty()) {+
  - cdesc->base_addr = NULL;
  - cdesc->elem_len = 0;
  - -} else {+
  - "cdesc->base_addr =\t const_cast<char *>(\tsrc->data());"
  - cdesc->elem_len = src->length();
  - -}
  - cdesc->size = 1;
  - cdesc->rank = 0;  // scalar
  - -}
  dependent_helpers:
  - array_context
h_helper_type_defines:
  name: h_helper_type_defines
  notes:
  - Order derived from TS 29113
  - with the addition of unsigned types.
  scope: cwrap_include
  source:
  - ''
  - /* helper type_defines */
  - /* Shroud type defines */
  - '#define SH_TYPE_SIGNED_CHAR 1'
  - '#define SH_TYPE_SHORT       2'
  - '#define SH_TYPE_INT         3'
  - '#define SH_TYPE_LONG        4'
  - '#define SH_TYPE_LONG_LONG   5'
  - '#define SH_TYPE_SIZE_T      6'
  - ''
  - '#define SH_TYPE_UNSIGNED_SHORT       SH_TYPE_SHORT + 100'
  - '#define SH_TYPE_UNSIGNED_INT         SH_TYPE_INT + 100'
  - '#define SH_TYPE_UNSIGNED_LONG        SH_TYPE_LONG + 100'
  - '#define SH_TYPE_UNSIGNED_LONG_LONG   SH_TYPE_LONG_LONG + 100'
  - ''
  - '#define SH_TYPE_INT8_T      7'
  - '#define SH_TYPE_INT16_T     8'
  - '#define SH_TYPE_INT32_T     9'
  - '#define SH_TYPE_INT64_T    10'
  - ''
  - '#define SH_TYPE_UINT8_T    SH_TYPE_INT8_T + 100'
  - '#define SH_TYPE_UINT16_T   SH_TYPE_INT16_T + 100'
  - '#define SH_TYPE_UINT32_T   SH_TYPE_INT32_T + 100'
  - '#define SH_TYPE_UINT64_T   SH_TYPE_INT64_T + 100'
  - ''
  - /* least8 least16 least32 least64 */
  - /* fast8 fast16 fast32 fast64 */
  - /* intmax_t intptr_t ptrdiff_t */
  - ''
  - '#define SH_TYPE_FLOAT        22'
  - '#define SH_TYPE_DOUBLE       23'
  - '#define SH_TYPE_LONG_DOUBLE  24'
  - '#define SH_TYPE_FLOAT_COMPLEX       25'
  - '#define SH_TYPE_DOUBLE_COMPLEX      26'
  - '#define SH_TYPE_LONG_DOUBLE_COMPLEX 27'
  - ''
  - '#define SH_TYPE_BOOL       28'
  - '#define SH_TYPE_CHAR       29'
  - '#define SH_TYPE_CPTR       30'
  - '#define SH_TYPE_STRUCT     31'
  - '#define SH_TYPE_OTHER      32'
  derived_type:
  - ''
  - '! helper type_defines'
  - '! Shroud type defines from helper type_defines'
  - 'integer, parameter, private :: &'
  - '    SH_TYPE_SIGNED_CHAR= 1, &'
  - '    SH_TYPE_SHORT      = 2, &'
  - '    SH_TYPE_INT        = 3, &'
  - '    SH_TYPE_LONG       = 4, &'
  - '    SH_TYPE_LONG_LONG  = 5, &'
  - '    SH_TYPE_SIZE_T     = 6, &'
  - '    SH_TYPE_UNSIGNED_SHORT      = SH_TYPE_SHORT + 100, &'
  - '    SH_TYPE_UNSIGNED_INT        = SH_TYPE_INT + 100, &'
  - '    SH_TYPE_UNSIGNED_LONG       = SH_TYPE_LONG + 100, &'
  - '    SH_TYPE_UNSIGNED_LONG_LONG  = SH_TYPE_LONG_LONG + 100, &'
  - '    SH_TYPE_INT8_T    =  7, &'
  - '    SH_TYPE_INT16_T   =  8, &'
  - '    SH_TYPE_INT32_T   =  9, &'
  - '    SH_TYPE_INT64_T   = 10, &'
  - '    SH_TYPE_UINT8_T  =  SH_TYPE_INT8_T + 100, &'
  - '    SH_TYPE_UINT16_T =  SH_TYPE_INT16_T + 100, &'
  - '    SH_TYPE_UINT32_T =  SH_TYPE_INT32_T + 100, &'
  - '    SH_TYPE_UINT64_T =  SH_TYPE_INT64_T + 100, &'
  - '    SH_TYPE_FLOAT       = 22, &'
  - '    SH_TYPE_DOUBLE      = 23, &'
  - '    SH_TYPE_LONG_DOUBLE = 24, &'
  - '    SH_TYPE_FLOAT_COMPLEX      = 25, &'
  - '    SH_TYPE_DOUBLE_COMPLEX     = 26, &'
  - '    SH_TYPE_LONG_DOUBLE_COMPLEX= 27, &'
  - '    SH_TYPE_BOOL      = 28, &'
  - '    SH_TYPE_CHAR      = 29, &'
  - '    SH_TYPE_CPTR      = 30, &'
  - '    SH_TYPE_STRUCT    = 31, &'
  - '    SH_TYPE_OTHER     = 32'
h_helper_vector_string_allocatable:
  name: h_helper_vector_string_allocatable
  notes:
  - Only used with std::string and thus C++.
  - Called from Fortran.
  - The capsule contains a pointer to a std::vector<std::string>
  - which is copied into the cdesc.
  fmtdict:
    cnamefunc: '{C_prefix}ShroudVectorStringAllocatable'
    fnamefunc: '{C_prefix}SHROUD_vector_string_allocatable'
    cnameproto: void {cnamefunc}({C_array_type} *dest, {C_capsule_data_type} *src)
  api: c
  c_fmtname: LIB_ShroudVectorStringAllocatable
  scope: cwrap_impl
  proto: void LIB_ShroudVectorStringAllocatable(LIB_SHROUD_array *dest, LIB_SHROUD_capsule_data
    *src);
  source:
  - ''
  - // helper vector_string_allocatable
  - // Copy the std::vector<std::string> into Fortran array.
  - // Called by Fortran to deal with allocatable character.
  - // out is already blank filled.
  - void LIB_ShroudVectorStringAllocatable(LIB_SHROUD_array *dest, LIB_SHROUD_capsule_data
    *src)
  - '{+'
  - "std::vector<std::string> *cxxvec =\t static_cast< std::vector<std::string> *\
    \ >\t(src->addr);"
  - LIB_ShroudVectorStringOut(dest, *cxxvec);
  - -}
  f_fmtname: LIB_SHROUD_vector_string_allocatable
  interface:
  - ''
  - interface+
  - '! helper vector_string_allocatable'
  - '! Copy the char* or std::string in context into c_var.'
  - subroutine LIB_SHROUD_vector_string_allocatable(dest, src) &
  - '     bind(c,name="LIB_ShroudVectorStringAllocatable")+'
  - import LIB_SHROUD_capsule_data, LIB_SHROUD_array
  - 'type(LIB_SHROUD_array), intent(IN) :: dest'
  - 'type(LIB_SHROUD_capsule_data), intent(IN) :: src'
  - -end subroutine LIB_SHROUD_vector_string_allocatable
  - -end interface
  dependent_helpers:
  - capsule_data_helper
  - array_context
  - vector_string_out
h_helper_vector_string_out:
  name: h_helper_vector_string_out
  notes:
  - Only used with std::vector and thus C++.
  fmtdict:
    cnamefunc: '{C_prefix}ShroudVectorStringOut'
    fnamefunc: '{C_prefix}shroud_vector_string_out'
    cnamefunc_vector_string_out: '{cnamefunc}'
    cnameproto: void {cnamefunc}({C_array_type} *outdesc, std::vector<std::string>
      &in)
  api: cxx
  c_fmtname: LIB_ShroudVectorStringOut
  cxx_include:
  - <cstring>
  - <cstddef>
  proto_include:
  - <string>
  - <vector>
  scope: cwrap_impl
  proto: void LIB_ShroudVectorStringOut(LIB_SHROUD_array *outdesc, std::vector<std::string>
    &in);
  source:
  - ''
  - // helper vector_string_out
  - // Copy the std::vector<std::string> into Fortran array argument.
  - // Called by C++.
  - void LIB_ShroudVectorStringOut(LIB_SHROUD_array *outdesc, std::vector<std::string>
    &in)
  - '{+'
  - size_t nvect = outdesc->size;
  - size_t len = outdesc->elem_len;
  - char *dest = static_cast<char *>(outdesc->base_addr);
  - // Clear user memory
  - std::memset(dest, ' ', nvect*len);
  - ''
  - // Copy into user memory
  - nvect = std::min(nvect, in.size());
  - //char *dest = static_cast<char *>(outdesc->cxx.addr);
  - for (size_t i = 0; i < nvect; ++i) {+
  - std::memcpy(dest, in[i].data(), std::min(len, in[i].length()));
  - dest += outdesc->elem_len;
  - -}
  - -}
  dependent_helpers:
  - array_context
h_helper_vector_string_out_len:
  name: h_helper_vector_string_out_len
  fmtdict:
    cnamefunc: '{C_prefix}ShroudVectorStringOutSize'
    cnameproto: size_t {cnamefunc}(std::vector<std::string> &in)
  api: cxx
  c_fmtname: LIB_ShroudVectorStringOutSize
  proto_include:
  - <string>
  - <vector>
  scope: cwrap_impl
  proto: size_t LIB_ShroudVectorStringOutSize(std::vector<std::string> &in);
  source:
  - ''
  - // helper vector_string_out_len
  - // Return the maximum string length in a std::vector<std::string>.
  - size_t LIB_ShroudVectorStringOutSize(std::vector<std::string> &in)
  - '{+'
  - size_t nvect = in.size();
  - size_t len = 0;
  - for (size_t i = 0; i < nvect; ++i) {+
  - len = std::max(len, in[i].length());
  - -}
  - return len;
  - -}
h_mixin_unknown:
  name: h_mixin_unknown
root
  c
    ctor
      shadow
        capptr -- c_ctor_shadow_capptr
          shared -- c_ctor_shadow_capptr_shared
        capsule -- c_ctor_shadow_capsule
    dtor -- c_dtor
    function
      bool -- c_function_bool
      char -- c_function_char
      char* -- c_function_char*
        arg -- c_function_char*_arg
        buf
          arg -- c_function_char*_buf_arg
          copy -- c_function_char*_buf_copy
      enum -- c_function_enum
      native -- c_function_native
      native& -- c_function_native&
      native* -- c_function_native*
        caller -- c_function_native*_caller
        scalar -- c_function_native*_scalar
      native** -- c_function_native**
      shadow
        capptr -- c_function_shadow_capptr
      shadow&
        capptr -- c_function_shadow&_capptr
          caller -- c_function_shadow&_capptr_caller
          library -- c_function_shadow&_capptr_library
        capsule -- c_function_shadow&_capsule
          caller -- c_function_shadow&_capsule_caller
          library -- c_function_shadow&_capsule_library
      shadow*
        capptr -- c_function_shadow*_capptr
          caller -- c_function_shadow*_capptr_caller
          library -- c_function_shadow*_capptr_library
          shared -- c_function_shadow*_capptr_shared
        capsule -- c_function_shadow*_capsule
        this -- c_function_shadow*_this
      shadow<native>
        capptr -- c_function_shadow<native>_capptr
      smartptr<shadow>
        capptr -- c_function_smartptr<shadow>_capptr
      smartptr<shadow>*
        capptr -- c_function_smartptr<shadow>*_capptr
      string -- c_function_string
        buf
          arg -- c_function_string_buf_arg
          copy -- c_function_string_buf_copy
      string& -- c_function_string&
        buf
          arg -- c_function_string&_buf_arg
          copy -- c_function_string&_buf_copy
        copy -- c_function_string&_copy
      string* -- c_function_string*
        buf
          copy -- c_function_string*_buf_copy
        caller -- c_function_string*_caller
        copy -- c_function_string*_copy
        library -- c_function_string*_library
      struct -- c_function_struct
      struct* -- c_function_struct*
      vector<native> -- c_function_vector<native>
        malloc -- c_function_vector<native>_malloc
      void* -- c_function_void*
    getter
      native -- c_getter_native
      native* -- c_getter_native*
    in
      bool -- c_in_bool
      char -- c_in_char
      char* -- c_in_char*
        buf -- c_in_char*_buf
      char** -- c_in_char**
        buf -- c_in_char**_buf
      enum -- c_in_enum
      native -- c_in_native
      native& -- c_in_native&
      native* -- c_in_native*
        cdesc -- c_in_native*_cdesc
      native** -- c_in_native**
      procedure -- c_in_procedure
        external -- c_in_procedure_external
        funptr -- c_in_procedure_funptr
      shadow -- c_in_shadow
      shadow& -- c_in_shadow&
      shadow* -- c_in_shadow*
      smartptr<shadow>* -- c_in_smartptr<shadow>*
      string -- c_in_string
        buf -- c_in_string_buf
      string& -- c_in_string&
        buf -- c_in_string&_buf
      string* -- c_in_string*
        buf -- c_in_string*_buf
      struct -- c_in_struct
      struct& -- c_in_struct&
      struct* -- c_in_struct*
      unknown -- c_in_unknown
      vector<native*>& -- c_in_vector<native*>&
        buf -- c_in_vector<native*>&_buf
      vector<native>
        buf -- c_in_vector<native>_buf
      vector<native>& -- c_in_vector<native>&
        buf -- c_in_vector<native>&_buf
      vector<native>*
        buf -- c_in_vector<native>*_buf
      vector<string>
        buf -- c_in_vector<string>_buf
      vector<string>& -- c_in_vector<string>&
        buf -- c_in_vector<string>&_buf
      vector<string>*
        buf -- c_in_vector<string>*_buf
      void -- c_in_void
      void* -- c_in_void*
        cdesc -- c_in_void*_cdesc
      void** -- c_in_void**
    inout
      bool
        * -- c_inout_bool_*
      char* -- c_inout_char*
        buf -- c_inout_char*_buf
      enum* -- c_inout_enum*
      native& -- c_inout_native&
        hidden -- c_inout_native&_hidden
      native* -- c_inout_native*
        cdesc -- c_inout_native*_cdesc
        hidden -- c_inout_native*_hidden
      shadow& -- c_inout_shadow&
      shadow* -- c_inout_shadow*
      smartptr<shadow>* -- c_inout_smartptr<shadow>*
      string& -- c_inout_string&
        buf -- c_inout_string&_buf
      string* -- c_inout_string*
        buf -- c_inout_string*_buf
      struct& -- c_inout_struct&
      struct* -- c_inout_struct*
      vector<native>
        buf
          copy -- c_inout_vector<native>_buf_copy
          malloc -- c_inout_vector<native>_buf_malloc
      vector<native>&
        buf
          copy -- c_inout_vector<native>&_buf_copy
          malloc -- c_inout_vector<native>&_buf_malloc
      vector<native>*
        buf
          copy -- c_inout_vector<native>*_buf_copy
          malloc -- c_inout_vector<native>*_buf_malloc
      vector<scalar>& -- c_inout_vector<scalar>&
      void*
        cdesc -- c_inout_void*_cdesc
      void** -- c_inout_void**
    mixin
      arg
        cfi -- c_mixin_arg_cfi
        character
          cfi -- c_mixin_arg_character_cfi
        native
          cfi -- c_mixin_arg_native_cfi
      cast-argument -- c_mixin_cast-argument
      character -- c_mixin_character
      cvar-capsule-fill -- c_mixin_cvar-capsule-fill
      declare-arg -- c_mixin_declare-arg
      declare-fortran-result -- c_mixin_declare-fortran-result
      destructor
        new-shadow-shared -- c_mixin_destructor_new-shadow-shared
        new-string -- c_mixin_destructor_new-string
        new-vector -- c_mixin_destructor_new-vector
      function -- c_mixin_function
        char*
          cdesc -- c_mixin_function_char*_cdesc
        shadow
          capptr -- c_mixin_function_shadow_capptr
        string
          cdesc -- c_mixin_function_string_cdesc
        vector
          malloc -- c_mixin_function_vector_malloc
      function-assign-to-local -- c_mixin_function-assign-to-local
      function-assign-to-new -- c_mixin_function-assign-to-new
      function-return-cvar -- c_mixin_function-return-cvar
      in
        character
          buf -- c_mixin_in_character_buf
      inout
        vector
          cdesc -- c_mixin_inout_vector_cdesc
        vector<native>
          cdesc -- c_mixin_inout_vector<native>_cdesc
      make-shared -- c_mixin_make-shared
      native
        capsule
          fill -- c_mixin_native_capsule_fill
        cdesc
          fill-cdesc -- c_mixin_native_cdesc_fill-cdesc
        cfi
          allocatable -- c_mixin_native_cfi_allocatable
          pointer -- c_mixin_native_cfi_pointer
      noargs -- c_mixin_noargs
      out
        native** -- c_mixin_out_native**
        vector
          buf
            malloc -- c_mixin_out_vector_buf_malloc
        vector<native>
          cdesc -- c_mixin_out_vector<native>_cdesc
      shadow -- c_mixin_shadow
      unknown -- c_mixin_unknown
      vector
        cdesc
          fill-cdesc -- c_mixin_vector_cdesc_fill-cdesc
    out
      bool
        * -- c_out_bool_*
      char
        *
          buf -- c_out_char_*_buf
      char* -- c_out_char*
      enum* -- c_out_enum*
      native& -- c_out_native&
        hidden -- c_out_native&_hidden
      native* -- c_out_native*
        cdesc -- c_out_native*_cdesc
        hidden -- c_out_native*_hidden
      native*& -- c_out_native*&
      native** -- c_out_native**
        raw -- c_out_native**_raw
      native*** -- c_out_native***
      string& -- c_out_string&
        buf -- c_out_string&_buf
      string* -- c_out_string*
        buf -- c_out_string*_buf
      string** -- c_out_string**
        cdesc
          copy -- c_out_string**_cdesc_copy
      struct& -- c_out_struct&
      struct* -- c_out_struct*
      vector<native>
        buf
          copy -- c_out_vector<native>_buf_copy
          malloc -- c_out_vector<native>_buf_malloc
      vector<native>& -- c_out_vector<native>&
        buf
          copy -- c_out_vector<native>&_buf_copy
          malloc -- c_out_vector<native>&_buf_malloc
        cdesc -- c_out_vector<native>&_cdesc
      vector<native>*
        buf
          copy -- c_out_vector<native>*_buf_copy
          malloc -- c_out_vector<native>*_buf_malloc
        cdesc -- c_out_vector<native>*_cdesc
      vector<string>
        buf
          copy -- c_out_vector<string>_buf_copy
      vector<string>& -- c_out_vector<string>&
        buf
          copy -- c_out_vector<string>&_buf_copy
        cdesc -- c_out_vector<string>&_cdesc
          allocatable -- c_out_vector<string>&_cdesc_allocatable
      vector<string>*
        buf
          copy -- c_out_vector<string>*_buf_copy
      void*
        cdesc -- c_out_void*_cdesc
      void*& -- c_out_void*&
      void** -- c_out_void**
    setter -- c_setter
      native -- c_setter_native
      native* -- c_setter_native*
      string
        scalar
          buf -- c_setter_string_scalar_buf
    subroutine -- c_subroutine
      assignment
        weakptr -- c_subroutine_assignment_weakptr
  f
    ctor
      shadow
        capsule -- f_ctor_shadow_capsule
          shared -- f_ctor_shadow_capsule_shared
    dtor -- f_dtor
    function
      bool -- f_function_bool
      char -- f_function_char
        cdesc
          allocatable -- f_function_char_cdesc_allocatable
          pointer -- f_function_char_cdesc_pointer
        cfi
          allocatable -- f_function_char_cfi_allocatable
          pointer -- f_function_char_cfi_pointer
      char* -- f_function_char*
        allocatable -- f_function_char*_allocatable
        arg -- f_function_char*_arg
        buf
          arg -- f_function_char*_buf_arg
          copy -- f_function_char*_buf_copy
        cdesc
          allocatable -- f_function_char*_cdesc_allocatable
          pointer -- f_function_char*_cdesc_pointer
        cfi
          allocatable -- f_function_char*_cfi_allocatable
          arg -- f_function_char*_cfi_arg
          copy -- f_function_char*_cfi_copy
          pointer -- f_function_char*_cfi_pointer
        copy -- f_function_char*_copy
        pointer -- f_function_char*_pointer
        raw -- f_function_char*_raw
      enum -- f_function_enum
      native -- f_function_native
      native& -- f_function_native&
        pointer -- f_function_native&_pointer
      native*
        cdesc
          allocatable -- f_function_native*_cdesc_allocatable
          pointer -- f_function_native*_cdesc_pointer
            caller -- f_function_native*_cdesc_pointer_caller
        cfi
          allocatable -- f_function_native*_cfi_allocatable
          pointer -- f_function_native*_cfi_pointer
        pointer -- f_function_native*_pointer
          caller -- f_function_native*_pointer_caller
        raw -- f_function_native*_raw
        scalar -- f_function_native*_scalar
      native** -- f_function_native**
      shadow
        capsule -- f_function_shadow_capsule
      shadow&
        capsule -- f_function_shadow&_capsule
          caller -- f_function_shadow&_capsule_caller
          library -- f_function_shadow&_capsule_library
      shadow*
        capsule -- f_function_shadow*_capsule
          caller -- f_function_shadow*_capsule_caller
          library -- f_function_shadow*_capsule_library
        this -- f_function_shadow*_this
      shadow<native>
        capsule -- f_function_shadow<native>_capsule
      smartptr<shadow>
        capsule -- f_function_smartptr<shadow>_capsule
      smartptr<shadow>*
        capsule -- f_function_smartptr<shadow>*_capsule
      string
        buf -- f_function_string_buf
          arg -- f_function_string_buf_arg
          copy -- f_function_string_buf_copy
        cdesc
          allocatable -- f_function_string_cdesc_allocatable
            caller -- f_function_string_cdesc_allocatable_caller
            library -- f_function_string_cdesc_allocatable_library
        cfi
          allocatable -- f_function_string_cfi_allocatable
            caller -- f_function_string_cfi_allocatable_caller
            library -- f_function_string_cfi_allocatable_library
          arg -- f_function_string_cfi_arg
          copy -- f_function_string_cfi_copy
          pointer -- f_function_string_cfi_pointer
            caller -- f_function_string_cfi_pointer_caller
            library -- f_function_string_cfi_pointer_library
      string&
        buf -- f_function_string&_buf
          arg -- f_function_string&_buf_arg
          copy -- f_function_string&_buf_copy
        cdesc
          allocatable -- f_function_string&_cdesc_allocatable
            caller -- f_function_string&_cdesc_allocatable_caller
            library -- f_function_string&_cdesc_allocatable_library
          pointer -- f_function_string&_cdesc_pointer
            caller -- f_function_string&_cdesc_pointer_caller
            library -- f_function_string&_cdesc_pointer_library
        cfi
          allocatable -- f_function_string&_cfi_allocatable
            caller -- f_function_string&_cfi_allocatable_caller
            library -- f_function_string&_cfi_allocatable_library
          arg -- f_function_string&_cfi_arg
          copy -- f_function_string&_cfi_copy
          pointer -- f_function_string&_cfi_pointer
            caller -- f_function_string&_cfi_pointer_caller
            library -- f_function_string&_cfi_pointer_library
      string*
        buf -- f_function_string*_buf
          copy -- f_function_string*_buf_copy
        cdesc
          allocatable -- f_function_string*_cdesc_allocatable
            caller -- f_function_string*_cdesc_allocatable_caller
            library -- f_function_string*_cdesc_allocatable_library
          pointer -- f_function_string*_cdesc_pointer
            caller -- f_function_string*_cdesc_pointer_caller
            library -- f_function_string*_cdesc_pointer_library
        cfi
          allocatable -- f_function_string*_cfi_allocatable
            caller -- f_function_string*_cfi_allocatable_caller
            library -- f_function_string*_cfi_allocatable_library
          copy -- f_function_string*_cfi_copy
          pointer -- f_function_string*_cfi_pointer
            caller -- f_function_string*_cfi_pointer_caller
            library -- f_function_string*_cfi_pointer_library
      struct -- f_function_struct
      struct*
        cdesc
          pointer -- f_function_struct*_cdesc_pointer
        pointer -- f_function_struct*_pointer
      vector
        scalar
          cdesc -- f_function_vector_scalar_cdesc
      vector<native>
        cdesc
          allocatable -- f_function_vector<native>_cdesc_allocatable
      void* -- f_function_void*
    getter
      bool -- f_getter_bool
      native -- f_getter_native
      native*
        cdesc
          pointer -- f_getter_native*_cdesc_pointer
        pointer -- f_getter_native*_pointer
      string
        cdesc
          allocatable -- f_getter_string_cdesc_allocatable
      struct*
        cdesc
          pointer -- f_getter_struct*_cdesc_pointer
        fapi
          pointer -- f_getter_struct*_fapi_pointer
      struct**
        cdesc
          raw -- f_getter_struct**_cdesc_raw
    in
      bool -- f_in_bool
      char -- f_in_char
      char* -- f_in_char*
        buf -- f_in_char*_buf
        capi -- f_in_char*_capi
        cfi -- f_in_char*_cfi
      char** -- f_in_char**
        buf -- f_in_char**_buf
        cfi -- f_in_char**_cfi
      enum -- f_in_enum
      native -- f_in_native
      native& -- f_in_native&
      native* -- f_in_native*
        cdesc -- f_in_native*_cdesc
        cfi -- f_in_native*_cfi
      native** -- f_in_native**
      procedure -- f_in_procedure
        external -- f_in_procedure_external
        funptr -- f_in_procedure_funptr
      shadow -- f_in_shadow
      shadow& -- f_in_shadow&
      shadow* -- f_in_shadow*
      smartptr<shadow>* -- f_in_smartptr<shadow>*
      string
        buf -- f_in_string_buf
        cfi -- f_in_string_cfi
      string& -- f_in_string&
        buf -- f_in_string&_buf
        cfi -- f_in_string&_cfi
      string* -- f_in_string*
        buf -- f_in_string*_buf
        cfi -- f_in_string*_cfi
      struct -- f_in_struct
      struct& -- f_in_struct&
      struct* -- f_in_struct*
      unknown -- f_in_unknown
      vector
        &
          cdesc
            targ
              native
                scalar -- f_in_vector_&_cdesc_targ_native_scalar
      vector<native*>&
        buf -- f_in_vector<native*>&_buf
      vector<native>
        buf -- f_in_vector<native>_buf
      vector<native>&
        buf -- f_in_vector<native>&_buf
      vector<native>*
        buf -- f_in_vector<native>*_buf
      vector<string>
        buf -- f_in_vector<string>_buf
      vector<string>&
        buf -- f_in_vector<string>&_buf
      vector<string>*
        buf -- f_in_vector<string>*_buf
      void -- f_in_void
      void* -- f_in_void*
        cdesc -- f_in_void*_cdesc
      void** -- f_in_void**
        cfi -- f_in_void**_cfi
    inout
      bool* -- f_inout_bool*
      char* -- f_inout_char*
        buf -- f_inout_char*_buf
        capi -- f_inout_char*_capi
        cfi -- f_inout_char*_cfi
      enum* -- f_inout_enum*
      native& -- f_inout_native&
        hidden -- f_inout_native&_hidden
      native* -- f_inout_native*
        cdesc -- f_inout_native*_cdesc
        cfi -- f_inout_native*_cfi
        hidden -- f_inout_native*_hidden
      shadow& -- f_inout_shadow&
      shadow* -- f_inout_shadow*
      smartptr<shadow>* -- f_inout_smartptr<shadow>*
      string& -- f_inout_string&
        buf -- f_inout_string&_buf
        cfi -- f_inout_string&_cfi
      string* -- f_inout_string*
        buf -- f_inout_string*_buf
        cfi -- f_inout_string*_cfi
      struct& -- f_inout_struct&
      struct* -- f_inout_struct*
      vector
        buf
          targ
            string
              scalar -- f_inout_vector_buf_targ_string_scalar
      vector<native>&
        cdesc -- f_inout_vector<native>&_cdesc
          allocatable -- f_inout_vector<native>&_cdesc_allocatable
      void*
        cdesc -- f_inout_void*_cdesc
      void** -- f_inout_void**
    mixin
      arg
        capsule -- f_mixin_arg_capsule
      capsule
        dtor -- f_mixin_capsule_dtor
      char
        cdesc
          allocate -- f_mixin_char_cdesc_allocate
          pointer -- f_mixin_char_cdesc_pointer
      declare-as-cptr -- f_mixin_declare-as-cptr
      declare-fortran-arg -- f_mixin_declare-fortran-arg
      declare-fortran-result -- f_mixin_declare-fortran-result
      declare-interface-arg -- f_mixin_declare-interface-arg
      function -- f_mixin_function
        c-ptr -- f_mixin_function_c-ptr
        ptr -- f_mixin_function_ptr
        shadow
          capsule -- f_mixin_function_shadow_capsule
        string
          cfi
            allocatable -- f_mixin_function_string_cfi_allocatable
      function-to-subroutine -- f_mixin_function-to-subroutine
      getter
        cdesc -- f_mixin_getter_cdesc
      helper
        array
          string
            allocatable -- f_mixin_helper_array_string_allocatable
        vector
          string
            allocatable -- f_mixin_helper_vector_string_allocatable
      in
        2d
          vector
            buf -- f_mixin_in_2d_vector_buf
        string
          array
            buf -- f_mixin_in_string_array_buf
        vector
          buf -- f_mixin_in_vector_buf
      inout
        array
          cdesc -- f_mixin_inout_array_cdesc
      interface-as-cptr -- f_mixin_interface-as-cptr
      interface-as-cptr-value -- f_mixin_interface-as-cptr-value
      local-logical-var -- f_mixin_local-logical-var
      native
        cdesc
          allocate -- f_mixin_native_cdesc_allocate
          pointer -- f_mixin_native_cdesc_pointer
          raw -- f_mixin_native_cdesc_raw
      out
        array
          cdesc
            allocatable -- f_mixin_out_array_cdesc_allocatable
        native
          cdesc
            allocate -- f_mixin_out_native_cdesc_allocate
            pointer -- f_mixin_out_native_cdesc_pointer
        string**
          cfi -- f_mixin_out_string**_cfi
        vector
          buf -- f_mixin_out_vector_buf
      pass
        capsule -- f_mixin_pass_capsule
        cdesc -- f_mixin_pass_cdesc
        character
          buf -- f_mixin_pass_character_buf
      shadow-arg -- f_mixin_shadow-arg
      str
        array -- f_mixin_str_array
      unknown -- f_mixin_unknown
      use
        capsule -- f_mixin_use_capsule
    none
      bool -- f_none_bool
      bool* -- f_none_bool*
      char -- f_none_char
      char* -- f_none_char*
      native -- f_none_native
      native* -- f_none_native*
      void* -- f_none_void*
    out
      bool* -- f_out_bool*
      char* -- f_out_char*
        buf -- f_out_char*_buf
        capi -- f_out_char*_capi
        cfi -- f_out_char*_cfi
      enum* -- f_out_enum*
      native& -- f_out_native&
        hidden -- f_out_native&_hidden
      native* -- f_out_native*
        cdesc -- f_out_native*_cdesc
        cfi
          allocatable -- f_out_native*_cfi_allocatable
        hidden -- f_out_native*_hidden
      native*&
        cdesc -- f_out_native*&_cdesc
          pointer -- f_out_native*&_cdesc_pointer
      native**
        cdesc
          allocatable -- f_out_native**_cdesc_allocatable
          pointer -- f_out_native**_cdesc_pointer
        cfi
          allocatable -- f_out_native**_cfi_allocatable
          pointer -- f_out_native**_cfi_pointer
        raw -- f_out_native**_raw
      native*** -- f_out_native***
      string&
        buf -- f_out_string&_buf
        cfi -- f_out_string&_cfi
      string*
        buf -- f_out_string*_buf
        cfi -- f_out_string*_cfi
      string**
        cdesc
          allocatable -- f_out_string**_cdesc_allocatable
          copy -- f_out_string**_cdesc_copy
        cfi
          allocatable -- f_out_string**_cfi_allocatable
          copy -- f_out_string**_cfi_copy
        copy -- f_out_string**_copy
      struct& -- f_out_struct&
      struct* -- f_out_struct*
      vector
        buf
          targ
            string
              scalar -- f_out_vector_buf_targ_string_scalar
      vector<native>&
        cdesc -- f_out_vector<native>&_cdesc
          allocatable -- f_out_vector<native>&_cdesc_allocatable
      vector<native>*
        cdesc -- f_out_vector<native>*_cdesc
          allocatable -- f_out_vector<native>*_cdesc_allocatable
      vector<string>&
        cdesc -- f_out_vector<string>&_cdesc
          allocatable -- f_out_vector<string>&_cdesc_allocatable
      void*
        cdesc -- f_out_void*_cdesc
      void*& -- f_out_void*&
      void** -- f_out_void**
    setter -- f_setter
      bool -- f_setter_bool
      native -- f_setter_native
      native* -- f_setter_native*
      string
        buf -- f_setter_string_buf
      struct* -- f_setter_struct*
        pointer -- f_setter_struct*_pointer
      struct** -- f_setter_struct**
    subroutine -- f_subroutine
      assignment
        weakptr -- f_subroutine_assignment_weakptr
  h
    helper
      array
        context -- h_helper_array_context
        string
          allocatable -- h_helper_array_string_allocatable
          out -- h_helper_array_string_out
            len -- h_helper_array_string_out_len
      capsule
        data
          helper -- h_helper_capsule_data_helper
        dtor -- h_helper_capsule_dtor
        helper -- h_helper_capsule_helper
      char
        alloc -- h_helper_char_alloc
        array
          alloc -- h_helper_char_array_alloc
          free -- h_helper_char_array_free
        blank
          fill -- h_helper_char_blank_fill
        copy -- h_helper_char_copy
        free -- h_helper_char_free
        len
          trim -- h_helper_char_len_trim
      copy
        array -- h_helper_copy_array
        string -- h_helper_copy_string
      pointer
        string -- h_helper_pointer_string
      size
        CFI -- h_helper_size_CFI
      string
        to
          cdesc -- h_helper_string_to_cdesc
      type
        defines -- h_helper_type_defines
      vector
        string
          allocatable -- h_helper_vector_string_allocatable
          out -- h_helper_vector_string_out
            len -- h_helper_vector_string_out_len
    mixin
      unknown -- h_mixin_unknown
***** Python
py_ctor_char*:
  name: py_ctor_char*
  intent: ctor
  c_helper:
  - get_from_object_char:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_char**:
  name: py_ctor_char**
  intent: ctor
  c_helper:
  - get_from_object_charptr:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}char **{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_char**_list:
  name: py_ctor_char**_list
  intent: ctor
  c_helper:
  - get_from_object_charptr:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}char **{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_char*_numpy:
  name: py_ctor_char*_numpy
  intent: ctor
  c_helper:
  - get_from_object_char:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_char[]:
  name: py_ctor_char[]
  intent: ctor
  c_helper:
  - fill_from_PyObject_char:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_char[]_list:
  name: py_ctor_char[]_list
  intent: ctor
  c_helper:
  - fill_from_PyObject_char:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_char[]_numpy:
  name: py_ctor_char[]_numpy
  intent: ctor
  c_helper:
  - fill_from_PyObject_char:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_native:
  name: py_ctor_native
  intent: ctor
  declare:
  - '{c_type} {c_var} = 0;'
  post_call:
  - SH_obj->{field_name} = {field_name};
py_ctor_native*:
  name: py_ctor_native*
  intent: ctor
  c_helper:
  - get_from_object_{c_type}_{PY_array_arg}:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_native*_list:
  name: py_ctor_native*_list
  intent: ctor
  c_helper:
  - get_from_object_{c_type}_{PY_array_arg}:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_native*_numpy:
  name: py_ctor_native*_numpy
  intent: ctor
  c_helper:
  - get_from_object_{c_type}_{PY_array_arg}:get_from_object
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_ctor_native[]:
  name: py_ctor_native[]
  intent: ctor
  c_helper:
  - fill_from_PyObject_{c_type}_{PY_array_arg}:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_native[]_list:
  name: py_ctor_native[]_list
  intent: ctor
  c_helper:
  - fill_from_PyObject_{c_type}_{PY_array_arg}:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_native[]_numpy:
  name: py_ctor_native[]_numpy
  intent: ctor
  c_helper:
  - fill_from_PyObject_{c_type}_{PY_array_arg}:fill_from_PyObject
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_ctor_native_list:
  name: py_ctor_native_list
  intent: ctor
  declare:
  - '{c_type} {c_var} = 0;'
  post_call:
  - SH_obj->{field_name} = {field_name};
py_ctor_native_numpy:
  name: py_ctor_native_numpy
  intent: ctor
  declare:
  - '{c_type} {c_var} = 0;'
  post_call:
  - SH_obj->{field_name} = {field_name};
py_ctor_shadow:
  name: py_ctor_shadow
  intent: ctor
  call:
  - self->{PY_type_obj} = new {cxx_type}({PY_call_list});
  - if (self->{PY_type_obj} == {nullptr}) {{+
  - PyErr_NoMemory();
  - return -1;
  - -}}
  - self->{PY_type_dtor} = {capsule_order};
  c_return:
  - return 0;
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
py_ctor_struct:
  name: py_ctor_struct
  intent: ctor
  call:
  - self->{PY_type_obj} = new {cxx_type};
  - if (self->{PY_type_obj} == {nullptr}) {{+
  - PyErr_NoMemory();
  - return -1;
  - -}}
  - self->{PY_type_dtor} = {capsule_order};
  c_return:
  - return 0;
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  lang_c:
    call:
    - self->{PY_type_obj} = malloc(sizeof({cxx_type}));
    - if (self->{PY_type_obj} == {nullptr}) {{+
    - PyErr_NoMemory();
    - return -1;
    - -}}
    - self->{PY_type_dtor} = {capsule_order};
    destructor:
    - free(ptr);
  lang_cxx:
    call:
    - self->{PY_type_obj} = new {cxx_type};
    - if (self->{PY_type_obj} == {nullptr}) {{+
    - PyErr_NoMemory();
    - return -1;
    - -}}
    - self->{PY_type_dtor} = {capsule_order};
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_descr_bool:
  name: py_descr_bool
  intent: descr
  getter:
  - return PyBool_FromLong({c_var});
  setter:
  - int rv = {PY_get};
  - if (PyErr_Occurred()) {{+
  - return -1;
  - -}}
  - '{c_var} = rv;'
py_descr_char*:
  name: py_descr_char*
  intent: descr
  getter:
  - if ({c_var} == {nullptr}) {{+
  - Py_RETURN_NONE;
  - -}}
  - PyObject * rv = {ctor};
  - return rv;
  setter:
  - '{PY_typedef_converter} cvalue;'
  - Py_XDECREF({c_var_data});
  - if ({c_helper_get_from_object}({py_var}, &cvalue) == 0) {{+
  - '{c_var} = {nullptr};'
  - '{c_var_data} = {nullptr};'
  - return -1;
  - -}}
  - '{c_var} = {cast_static}{cast_type}{cast1}cvalue.data{cast2};'
  - '{c_var_data} = cvalue.dataobj;  // steal reference'
  setter_helper:
  - get_from_object_{c_type}_list:get_from_object
py_descr_char**_list:
  name: py_descr_char**_list
  intent: descr
  getter:
  - if ({c_var} == {nullptr}) {{+
  - Py_RETURN_NONE;
  - -}}
  - PyObject *rv = {c_helper_to_PyList}({c_var}, {npy_intp_size});
  - return rv;
  getter_helper:
  - to_PyList_char:to_PyList
  setter:
  - '{PY_typedef_converter} cvalue;'
  - Py_XDECREF({c_var_data});
  - if ({c_helper_get_from_object}({py_var}, &cvalue) == 0) {{+
  - '{c_var} = {nullptr};'
  - '{c_var_data} = {nullptr};'
  - // XXXX set error
  - return -1;
  - -}}
  - '{c_var} = {cast_static}{cast_type}{cast1}cvalue.data{cast2};'
  - '{c_var_data} = cvalue.dataobj;  // steal reference'
  setter_helper:
  - get_from_object_charptr:get_from_object
py_descr_char*_numpy:
  name: py_descr_char*_numpy
  intent: descr
  getter:
  - if ({c_var} == {nullptr}) {{+
  - Py_RETURN_NONE;
  - -}}
  - PyObject * rv = {ctor};
  - return rv;
  setter:
  - '{PY_typedef_converter} cvalue;'
  - Py_XDECREF({c_var_data});
  - if ({c_helper_get_from_object}({py_var}, &cvalue) == 0) {{+
  - '{c_var} = {nullptr};'
  - '{c_var_data} = {nullptr};'
  - return -1;
  - -}}
  - '{c_var} = {cast_static}{cast_type}{cast1}cvalue.data{cast2};'
  - '{c_var_data} = cvalue.dataobj;  // steal reference'
  setter_helper:
  - get_from_object_{c_type}_list:get_from_object
py_descr_char[]:
  name: py_descr_char[]
  intent: descr
  getter:
  - if ({c_var_obj} != {nullptr}) {{+
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  - -}}
  - PyObject * rv = PyString_FromString({c_var});
  - // XXX assumes is null terminated
  - return rv;
  setter:
  - Py_XDECREF({c_var_obj});
  - '{c_var_obj} = {nullptr};'
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{field_name}\",\t {c_var},\t\
    \ {npy_intp_size}) == -1) {{+"
  - return -1;
  - -}}
  setter_helper:
  - fill_from_PyObject_char:fill_from_PyObject
py_descr_char[]_list:
  name: py_descr_char[]_list
  intent: descr
  getter:
  - if ({c_var_obj} != {nullptr}) {{+
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  - -}}
  - PyObject * rv = PyString_FromString({c_var});
  - // XXX assumes is null terminated
  - return rv;
  setter:
  - Py_XDECREF({c_var_obj});
  - '{c_var_obj} = {nullptr};'
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{field_name}\",\t {c_var},\t\
    \ {npy_intp_size}) == -1) {{+"
  - return -1;
  - -}}
  setter_helper:
  - fill_from_PyObject_char:fill_from_PyObject
py_descr_char[]_numpy:
  name: py_descr_char[]_numpy
  intent: descr
  getter:
  - if ({c_var_obj} != {nullptr}) {{+
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  - -}}
  - PyObject * rv = PyString_FromString({c_var});
  - // XXX assumes is null terminated
  - return rv;
  setter:
  - Py_XDECREF({c_var_obj});
  - '{c_var_obj} = {nullptr};'
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{field_name}\",\t {c_var},\t\
    \ {npy_intp_size}) == -1) {{+"
  - return -1;
  - -}}
  setter_helper:
  - fill_from_PyObject_char:fill_from_PyObject
py_descr_native:
  name: py_descr_native
  intent: descr
  getter:
  - PyObject * rv = {ctor};
  - return rv;
  setter:
  - '{cxx_decl} = {PY_get};'
  - if (PyErr_Occurred()) {{+
  - return -1;
  - -}}
  - '{c_var} = rv;'
py_descr_native*_list:
  name: py_descr_native*_list
  intent: descr
  getter:
  - if ({c_var} == {nullptr}) {{+
  - Py_RETURN_NONE;
  - -}}
  - if ({c_var_obj} != {nullptr}) {{+
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  - -}}
  - PyObject *rv = {c_helper_to_PyList}({c_var}, {npy_intp_size});
  - return rv;
  getter_helper:
  - to_PyList_{c_type}:to_PyList
  setter:
  - '{PY_typedef_converter} cvalue;'
  - Py_XDECREF({c_var_obj});
  - if ({c_helper_get_from_object}({py_var}, &cvalue) == 0) {{+
  - '{c_var} = {nullptr};'
  - '{c_var_obj} = {nullptr};'
  - return -1;
  - -}}
  - '{c_var} = {cast_static}{cast_type}{cast1}cvalue.data{cast2};'
  - '{c_var_obj} = cvalue.obj;  // steal reference'
  setter_helper:
  - get_from_object_{c_type}_list:get_from_object
py_descr_native*_numpy:
  name: py_descr_native*_numpy
  intent: descr
  need_numpy: true
  getter:
  - if ({c_var} == {nullptr}) {{+
  - Py_RETURN_NONE;
  - -}}
  - if ({c_var_obj} != {nullptr}) {{+
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  - -}}
  - npy_intp {npy_dims_var}[{npy_rank}] = {{ {npy_intp_values} }};
  - "PyObject *rv = PyArray_SimpleNewFromData(\t{npy_rank},\t {npy_dims_var},\t {PYN_typenum},\t\
    \ {c_var_non_const});"
  - if (rv != {nullptr}) {{+
  - Py_INCREF(rv);
  - '{c_var_obj} = rv;'
  - -}}
  - return rv;
  setter:
  - '{PY_typedef_converter} cvalue;'
  - Py_XDECREF({c_var_obj});
  - if ({c_helper_get_from_object}({py_var}, &cvalue) == 0) {{+
  - '{c_var} = {nullptr};'
  - '{c_var_obj} = {nullptr};'
  - // XXXX set error
  - return -1;
  - -}}
  - '{c_var} = {cast_static}{cast_type}{cast1}cvalue.data{cast2};'
  - '{c_var_obj} = cvalue.obj;  // steal reference'
  setter_helper:
  - get_from_object_{c_type}_numpy:get_from_object
py_descr_native[]_list:
  name: py_descr_native[]_list
  intent: descr
  need_numpy: true
  getter:
  - PyObject *rv = {c_helper_to_PyList}({c_var}, {npy_intp_size});
  - return rv;
  getter_helper:
  - to_PyList_{c_type}:to_PyList
  setter:
  - Py_XDECREF({c_var_obj});
  - '{c_var_obj} = {nullptr};'
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{field_name}\",\t {c_var},\t\
    \ {npy_intp_size}) == -1) {{+"
  - return -1;
  - -}}
  setter_helper:
  - fill_from_PyObject_{c_type}_{PY_array_arg}:fill_from_PyObject
py_descr_native[]_numpy:
  name: py_descr_native[]_numpy
  intent: descr
  need_numpy: true
  getter:
  - if ({c_var_obj} == {nullptr}) {{+
  - // Create Numpy object which points to struct member.
  - npy_intp {npy_dims_var}[{rank}] = {{ {npy_intp_values} }};
  - "{c_var_obj} = PyArray_SimpleNewFromData(\t{npy_rank},\t {npy_dims_var},\t {PYN_typenum},\t\
    \ {c_var});"
  - -}}
  - Py_INCREF({c_var_obj});
  - return {c_var_obj};
  setter:
  - Py_XDECREF({c_var_obj});
  - '{c_var_obj} = {nullptr};'
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{field_name}\",\t {c_var},\t\
    \ {npy_intp_size}) == -1) {{+"
  - return -1;
  - -}}
  setter_helper:
  - fill_from_PyObject_{c_type}_{PY_array_arg}:fill_from_PyObject
py_function_bool:
  name: py_function_bool
  intent: function
  object_created: true
  declare:
  - '{PyObject} * {py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - '{py_var} = PyBool_FromLong({c_var});'
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_char:
  name: py_function_char
  intent: function
  object_created: true
  declare:
  - '{PyObject} * {py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - '{py_var} = PyString_FromStringAndSize(&{cxx_var}, 1);'
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_char*:
  name: py_function_char*
  intent: function
  fmtdict:
    ctor_expr: '{c_var}'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_enum:
  name: py_function_enum
  intent: function
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_native:
  name: py_function_native
  intent: function
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_native&_numpy:
  name: py_function_native&_numpy
  intent: function
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{npy_intp_asgn}{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t\
    \ {numpy_type},\t {cxx_nonconst_ptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_native*_list:
  name: py_function_native*_list
  intent: function
  c_helper:
  - to_PyList_{cxx_type}:to_PyList
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{py_var} = {c_helper_to_PyList}\t({cxx_var},\t {array_size});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_native*_numpy:
  name: py_function_native*_numpy
  intent: function
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{npy_intp_asgn}{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t\
    \ {numpy_type},\t {cxx_nonconst_ptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_native*_scalar:
  name: py_function_native*_scalar
  intent: function
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_shadow:
  name: py_function_shadow
  intent: function
  arg_declare:
  - '{cxx_type} *{cxx_var} = {nullptr};'
  fmtdict:
    cxx_member: ->
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  pre_call:
  - '{cxx_var} = new {cxx_type};'
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_addr}{cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = malloc(sizeof({c_type}));'
  lang_cxx:
    pre_call:
    - '{cxx_var} = new {cxx_type};'
py_function_shadow&:
  name: py_function_shadow&
  intent: function
  object_created: true
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{PyObject} * {py_var} =\t PyObject_New({PyObject}, &{PyTypeObject});"
  - '{py_var}->{PY_type_obj} = {cxx_addr}{cxx_var};'
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_shadow*:
  name: py_function_shadow*
  intent: function
  object_created: true
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{PyObject} * {py_var} =\t PyObject_New({PyObject}, &{PyTypeObject});"
  - '{py_var}->{PY_type_obj} = {cxx_addr}{cxx_var};'
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_string:
  name: py_function_string
  intent: function
  fmtdict:
    ctor_expr: "{cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size()"
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_string&:
  name: py_function_string&
  intent: function
  fmtdict:
    ctor_expr: "{cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size()"
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_string*:
  name: py_function_string*
  intent: function
  fmtdict:
    ctor_expr: "{cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size()"
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_struct*_class:
  name: py_function_struct*_class
  intent: function
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};  // struct_class
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_addr}{cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_struct*_list:
  name: py_function_struct*_list
  intent: function
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_struct*_numpy:
  name: py_function_struct*_numpy
  intent: function
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - '{npy_intp_asgn}Py_INCREF({PYN_descr});'
  - "{py_var} = PyArray_NewFromDescr(&PyArray_Type, \t{PYN_descr},\t {npy_rank}, {npy_dims_var},\
    \ \t{nullptr}, {cxx_var}, 0, {nullptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_struct_class:
  name: py_function_struct_class
  intent: function
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  fmtdict:
    cxx_addr: ''
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};  // struct_class
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  call:
  - '*{cxx_var} = {C_call_function};'
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_addr}{cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  - Py_XDECREF({py_var});
  goto_fail: true
  local:
  - cxx
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_function_struct_list:
  name: py_function_struct_list
  intent: function
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_function_struct_numpy:
  name: py_function_struct_numpy
  intent: function
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  - PyObject *{py_capsule} = {nullptr};
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  call:
  - '*{cxx_var} = {C_call_function};'
  post_call:
  - '{npy_intp_asgn}Py_INCREF({PYN_descr});'
  - "{py_var} = PyArray_NewFromDescr(&PyArray_Type, \t{PYN_descr},\t {npy_rank}, {npy_dims_var},\
    \ \t{nullptr}, {cxx_var}, 0, {nullptr});"
  - if ({py_var} == {nullptr}) goto fail;
  - "{py_capsule} = PyCapsule_New({cxx_var}, \"{PY_numpy_array_capsule_name}\", \t\
    {PY_capsule_destructor_function});"
  - if ({py_capsule} == {nullptr}) goto fail;
  - "PyCapsule_SetContext({py_capsule},\t {PY_fetch_context_function}({capsule_order}));"
  - "if (PyArray_SetBaseObject(\t{cast_reinterpret}PyArrayObject *{cast1}{py_var}{cast2},\t\
    \ {py_capsule}) < 0)\t goto fail;"
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  - Py_XDECREF({py_var});
  - Py_XDECREF({py_capsule});
  goto_fail: true
  local:
  - cxx
  - capsule
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_function_vector<native>_list:
  name: py_function_vector<native>_list
  intent: function
  object_created: true
  declare:
  - PyObject * {py_var} = {nullptr};
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{py_var} = SHROUD_to_PyList_vector_{cxx_T}\t({cxx_var});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_vector<native>_numpy:
  name: py_function_vector<native>_numpy
  intent: function
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  - PyObject *{py_capsule} = {nullptr};
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  call:
  - '*{cxx_var} = {C_call_function};'
  post_call:
  - '{npy_dims_var}[0] = {cxx_var}->size();'
  - "{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t {numpy_type},\t\
    \ {cxx_var}->data());"
  - if ({py_var} == {nullptr}) goto fail;
  - "{py_capsule} = PyCapsule_New({cxx_var}, \"{PY_numpy_array_capsule_name}\", \t\
    {PY_capsule_destructor_function});"
  - if ({py_capsule} == {nullptr}) goto fail;
  - "PyCapsule_SetContext({py_capsule},\t {PY_fetch_context_function}({capsule_order}));"
  - "if (PyArray_SetBaseObject(\t{cast_reinterpret}PyArrayObject *{cast1}{py_var}{cast2},\t\
    \ {py_capsule}) < 0)\t goto fail;"
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  - Py_XDECREF({py_var});
  - Py_XDECREF({py_capsule});
  goto_fail: true
  local:
  - cxx
  - capsule
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_function_vector_list:
  name: py_function_vector_list
  intent: function
  object_created: true
  declare:
  - PyObject * {py_var} = {nullptr};
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{py_var} = SHROUD_to_PyList_vector_{cxx_T}\t({cxx_var});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_function_vector_numpy:
  name: py_function_vector_numpy
  intent: function
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  - PyObject *{py_capsule} = {nullptr};
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  call:
  - '*{cxx_var} = {C_call_function};'
  post_call:
  - '{npy_dims_var}[0] = {cxx_var}->size();'
  - "{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t {numpy_type},\t\
    \ {cxx_var}->data());"
  - if ({py_var} == {nullptr}) goto fail;
  - "{py_capsule} = PyCapsule_New({cxx_var}, \"{PY_numpy_array_capsule_name}\", \t\
    {PY_capsule_destructor_function});"
  - if ({py_capsule} == {nullptr}) goto fail;
  - "PyCapsule_SetContext({py_capsule},\t {PY_fetch_context_function}({capsule_order}));"
  - "if (PyArray_SetBaseObject(\t{cast_reinterpret}PyArrayObject *{cast1}{py_var}{cast2},\t\
    \ {py_capsule}) < 0)\t goto fail;"
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  - Py_XDECREF({py_var});
  - Py_XDECREF({py_capsule});
  goto_fail: true
  local:
  - cxx
  - capsule
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_function_void*:
  name: py_function_void*
  intent: function
  fmtdict:
    ctor_expr: '{cxx_var}'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_implied_bool:
  name: py_implied_bool
  intent: implied
  arg_declare:
  - '{cxx_type} {c_var};'
  arg_call:
  - '{c_var}'
  call:
  - '{c_var} = {c_implied};'
py_implied_native:
  name: py_implied_native
  intent: implied
  arg_declare:
  - '{cxx_type} {c_var};'
  arg_call:
  - '{c_var}'
  call:
  - '{c_var} = {c_implied};'
py_in_bool:
  name: py_in_bool
  intent: in
  pre_call:
  - '{cxx_var} = PyObject_IsTrue({py_var});'
py_in_char:
  name: py_in_char
  intent: in
  arg_declare:
  - char *{c_var};
  arg_call:
  - '{c_var}[0]'
  parse_format: s
  parse_args:
  - '&{c_var}'
py_in_char*:
  name: py_in_char*
  intent: in
  arg_call:
  - '{c_var}'
py_in_char**:
  name: py_in_char**
  intent: in
  arg_declare:
  - '{c_const}char ** {cxx_var} = {nullptr};'
  arg_call:
  - '{cxx_var}'
  c_helper:
  - get_from_object_charptr
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{c_var}";'
  - Py_ssize_t {size_var};
  pre_call:
  - "if ({c_helper_get_from_object_charptr}\t({pytmp_var}, &{value_var}) == 0)"
  - +goto fail;-
  - '{cxx_var} = {cast_static}char **{cast1}{value_var}.data{cast2};'
  post_call:
  - Py_XDECREF({value_var}.dataobj);
  fail:
  - Py_XDECREF({value_var}.dataobj);
  goto_fail: true
py_in_enum:
  name: py_in_enum
  intent: in
  post_declare:
  - "{cxx_type} {cxx_var} =\t {cast_static}{cxx_type}{cast1}{c_var}{cast2};"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_in_native:
  name: py_in_native
  intent: in
py_in_native&:
  name: py_in_native&
  intent: in
  arg_declare:
  - '{c_type} {c_var};'
py_in_native*:
  name: py_in_native*
  intent: in
  arg_declare:
  - '{c_type} {c_var};'
  arg_call:
  - '&{c_var}'
py_in_native*_list:
  name: py_in_native*_list
  intent: in
  arg_declare:
  - '{cxx_type} * {cxx_var} = {nullptr};'
  arg_call:
  - '{cxx_var}'
  c_helper:
  - get_from_object_{cxx_type}_list:get_from_object
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject *{pytmp_var} = {nullptr};
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{c_var}";'
  - Py_ssize_t {size_var};
  post_parse:
  - "if ({c_helper_get_from_object}\t({pytmp_var}, &{value_var}) == 0)"
  - +goto fail;-
  - '{cxx_var} = {cast_static}{cxx_type} *{cast1}{value_var}.data{cast2};'
  - '{size_var} = {value_var}.size;'
  cleanup:
  - Py_XDECREF({value_var}.dataobj);
  fail:
  - Py_XDECREF({value_var}.dataobj);
  goto_fail: true
py_in_native*_numpy:
  name: py_in_native*_numpy
  intent: in
  arg_call:
  - '{c_var}'
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_ContiguousFromObject(\t\
    {pytmp_var},\t {numpy_type},\t {rank},\t {rank}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  cleanup:
  - '{PY_cleanup_decref}({py_var});'
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_in_procedure:
  name: py_in_procedure
  intent: in
py_in_shadow:
  name: py_in_shadow
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
py_in_shadow&:
  name: py_in_shadow&
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
py_in_shadow*:
  name: py_in_shadow*
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
py_in_string:
  name: py_in_string
  intent: in
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_in_string&:
  name: py_in_string&
  intent: in
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_in_string*:
  name: py_in_string*
  intent: in
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '&{cxx_var}'
  local:
  - cxx
py_in_struct&_class:
  name: py_in_struct&_class
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
py_in_struct&_numpy:
  name: py_in_struct&_numpy
  intent: in
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  cleanup:
  - '{PY_cleanup_decref}({py_var});'
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_in_struct*_class:
  name: py_in_struct*_class
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
py_in_struct*_list:
  name: py_in_struct*_list
  intent: in
  arg_call:
  - '&{cxx_var}'
py_in_struct*_numpy:
  name: py_in_struct*_numpy
  intent: in
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  fmtdict:
    cxx_member: ->
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  cleanup:
  - '{PY_cleanup_decref}({py_var});'
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_in_struct_class:
  name: py_in_struct_class
  intent: in
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
py_in_struct_list:
  name: py_in_struct_list
  intent: in
py_in_struct_numpy:
  name: py_in_struct_numpy
  intent: in
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  cleanup:
  - '{PY_cleanup_decref}({py_var});'
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_in_unknown:
  name: py_in_unknown
  intent: in
py_in_vector<native>&_list:
  name: py_in_vector<native>&_list
  intent: in
  post_declare:
  - std::vector<{cxx_T}> {cxx_var};
  arg_call:
  - '{cxx_var}'
  c_helper:
  - create_from_PyObject_vector_{cxx_T}:create_from_PyObject
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  pre_call:
  - "if ({c_helper_create_from_PyObject}\t({pytmp_var},\t \"{c_var}\",\t {cxx_var})\
    \ == -1)"
  - +goto fail;-
  goto_fail: true
  local:
  - cxx
py_in_vector<native>&_numpy:
  name: py_in_vector<native>&_numpy
  intent: in
  post_declare:
  - std::vector<{cxx_T}> {cxx_var};
  - '{cxx_T} * {data_var};'
  arg_call:
  - '{cxx_var}'
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FROM_OTF(\t{pytmp_var},\t\
    \ {numpy_type},\t NPY_ARRAY_IN_ARRAY){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a 1-D array of {cxx_T}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - '{data_var} = static_cast<{cxx_T} *>(PyArray_DATA({py_var}));'
  - "{cxx_var}.assign(\t{data_var},\t {data_var}+PyArray_SIZE({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  local:
  - cxx
py_in_void*:
  name: py_in_void*
  intent: in
  arg_call:
  - '{c_var}'
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var};
  post_parse:
  - '{c_var} = PyCapsule_GetPointer({py_var}, NULL);'
  - if (PyErr_Occurred())
  - +goto fail;-
  goto_fail: true
py_inout_bool:
  name: py_inout_bool
  intent: inout
  arg_declare:
  - bool {cxx_var};
  object_created: true
  pre_call:
  - '{cxx_var} = PyObject_IsTrue({py_var});'
  post_call:
  - '{py_var} = PyBool_FromLong({c_var});'
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_inout_bool*:
  name: py_inout_bool*
  intent: inout
  arg_declare:
  - bool {cxx_var};
  arg_call:
  - '&{cxx_var}'
  object_created: true
  pre_call:
  - '{cxx_var} = PyObject_IsTrue({py_var});'
  post_call:
  - '{py_var} = PyBool_FromLong({c_var});'
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_inout_char*:
  name: py_inout_char*
  intent: inout
  fmtdict:
    ctor_expr: '{c_var}'
  arg_call:
  - '{c_var}'
py_inout_native&:
  name: py_inout_native&
  intent: inout
  arg_declare:
  - '{c_type} {c_var};'
py_inout_native*:
  name: py_inout_native*
  intent: inout
  arg_declare:
  - '{c_type} {c_var};'
  fmtdict:
    ctor_expr: '{c_var}'
  arg_call:
  - '&{c_var}'
py_inout_native*_list:
  name: py_inout_native*_list
  intent: inout
  arg_declare:
  - '{cxx_type} * {cxx_var} = {nullptr};'
  arg_call:
  - '{cxx_var}'
  c_helper:
  - get_from_object_{cxx_type}_list:get_from_object
  - to_PyList_{cxx_type}:to_PyList
  object_created: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject *{py_var};
  - PyObject *{pytmp_var} = {nullptr};
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{c_var}";'
  - Py_ssize_t {size_var};
  post_parse:
  - "if ({c_helper_get_from_object}\t({pytmp_var}, &{value_var}) == 0)"
  - +goto fail;-
  - '{cxx_var} = {cast_static}{cxx_type} *{cast1}{value_var}.data{cast2};'
  - '{size_var} = {value_var}.size;'
  post_call:
  - "{py_var} = {c_helper_to_PyList}\t({cxx_var},\t {size_var});"
  - if ({py_var} == {nullptr}) goto fail;
  cleanup:
  - Py_XDECREF({value_var}.dataobj);
  fail:
  - Py_XDECREF({value_var}.dataobj);
  goto_fail: true
py_inout_native*_numpy:
  name: py_inout_native*_numpy
  intent: inout
  arg_call:
  - '{c_var}'
  need_numpy: true
  object_created: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FROM_OTF(\t{pytmp_var},\t\
    \ {numpy_type},\t NPY_ARRAY_INOUT_ARRAY){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_inout_shadow_*:
  name: py_inout_shadow_*
  intent: inout
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
py_inout_string:
  name: py_inout_string
  intent: inout
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_inout_string&:
  name: py_inout_string&
  intent: inout
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_inout_string*:
  name: py_inout_string*
  intent: inout
  arg_declare:
  - char *{c_var};
  post_declare:
  - '{c_const}std::string {cxx_var}({c_var});'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '&{cxx_var}'
  local:
  - cxx
py_inout_struct&_class:
  name: py_inout_struct&_class
  intent: inout
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
  object_created: true
  incref_on_return: true
py_inout_struct&_numpy:
  name: py_inout_struct&_numpy
  intent: inout
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  arg_call:
  - '*{cxx_var}'
  need_numpy: true
  object_created: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_inout_struct*_class:
  name: py_inout_struct*_class
  intent: inout
  post_declare:
  - "{c_const}{cxx_type} *{cxx_var} =\t {py_var} ? {py_var}->{PY_type_obj} : {nullptr};"
  fmtdict:
    cxx_member: ->
  object_created: true
  incref_on_return: true
py_inout_struct*_list:
  name: py_inout_struct*_list
  intent: inout
  arg_call:
  - '&{cxx_var}'
py_inout_struct*_numpy:
  name: py_inout_struct*_numpy
  intent: inout
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  need_numpy: true
  object_created: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_inout_struct_list:
  name: py_inout_struct_list
  intent: inout
py_mixin_alloc-cxx-type:
  name: py_mixin_alloc-cxx-type
  intent: mixin
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  local:
  - cxx
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_mixin_array-ContiguousFromObject:
  name: py_mixin_array-ContiguousFromObject
  intent: mixin
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_ContiguousFromObject(\t\
    {pytmp_var},\t {numpy_type},\t {rank},\t {rank}){cast2};"
py_mixin_array-FROM-OFT-in:
  name: py_mixin_array-FROM-OFT-in
  intent: mixin
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FROM_OTF(\t{pytmp_var},\t\
    \ {numpy_type},\t NPY_ARRAY_IN_ARRAY){cast2};"
py_mixin_array-FROM-OTF:
  name: py_mixin_array-FROM-OTF
  intent: mixin
  post_parse:
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FROM_OTF(\t{pytmp_var},\t\
    \ {numpy_type},\t NPY_ARRAY_INOUT_ARRAY){cast2};"
py_mixin_array-FromAny:
  name: py_mixin_array-FromAny
  intent: mixin
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_FromAny(\t{pytmp_var},\t\
    \ {PYN_descr},\t 0,\t 1,\t NPY_ARRAY_IN_ARRAY,\t {nullptr}){cast2};"
py_mixin_array-NewFromDescr:
  name: py_mixin_array-NewFromDescr
  intent: mixin
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_NewFromDescr(\t&PyArray_Type,\t\
    \ {PYN_descr},\t 0,\t {nullptr},\t {nullptr},\t {nullptr},\t 0,\t {nullptr}){cast2};"
py_mixin_array-NewFromDescr2:
  name: py_mixin_array-NewFromDescr2
  intent: mixin
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  post_call:
  - '{npy_intp_asgn}Py_INCREF({PYN_descr});'
  - "{py_var} = PyArray_NewFromDescr(&PyArray_Type, \t{PYN_descr},\t {npy_rank}, {npy_dims_var},\
    \ \t{nullptr}, {cxx_var}, 0, {nullptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_mixin_array-SimpleNew:
  name: py_mixin_array-SimpleNew
  intent: mixin
  post_parse:
  - '{npy_intp_asgn}{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_SimpleNew({npy_rank},
    {npy_dims_var}, {numpy_type}){cast2};'
py_mixin_array-SimpleNewFromData:
  name: py_mixin_array-SimpleNewFromData
  intent: mixin
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  post_call:
  - '{npy_dims_var}[0] = {cxx_var}->size();'
  - "{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t {numpy_type},\t\
    \ {cxx_var}->data());"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_mixin_array-SimpleNewFromData2:
  name: py_mixin_array-SimpleNewFromData2
  intent: mixin
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  post_call:
  - "{npy_intp_asgn}{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t\
    \ {numpy_type},\t {cxx_nonconst_ptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_mixin_array-capsule:
  name: py_mixin_array-capsule
  intent: mixin
  declare:
  - PyObject *{py_capsule} = {nullptr};
  post_call:
  - "{py_capsule} = PyCapsule_New({cxx_var}, \"{PY_numpy_array_capsule_name}\", \t\
    {PY_capsule_destructor_function});"
  - if ({py_capsule} == {nullptr}) goto fail;
  - "PyCapsule_SetContext({py_capsule},\t {PY_fetch_context_function}({capsule_order}));"
  - "if (PyArray_SetBaseObject(\t{cast_reinterpret}PyArrayObject *{cast1}{py_var}{cast2},\t\
    \ {py_capsule}) < 0)\t goto fail;"
  fail:
  - Py_XDECREF({py_capsule});
  goto_fail: true
  local:
  - capsule
py_mixin_array-get-data:
  name: py_mixin_array-get-data
  intent: mixin
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_mixin_array-parse:
  name: py_mixin_array-parse
  intent: mixin
  need_numpy: true
  parse_format: O
  parse_args:
  - '&{pytmp_var}'
  declare:
  - PyObject * {pytmp_var};
  - PyArrayObject * {py_var} = {nullptr};
  fail:
  - Py_XDECREF({py_var});
py_mixin_array_error:
  name: py_mixin_array_error
  intent: mixin
  post_parse:
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  goto_fail: true
py_mixin_ctor_array:
  name: py_mixin_ctor_array
  intent: mixin
  parse_format: O&
  parse_args:
  - '{c_helper_get_from_object}'
  - '&{value_var}'
  declare:
  - '{PY_typedef_converter} {value_var} = {PY_value_init};'
  - '{value_var}.name = "{field_name}";'
  post_call:
  - SH_obj->{field_name} = {cast_static}{c_type} *{cast1}{value_var}.data{cast2};
  - self->{PY_member_object} = {value_var}.obj;  // steal reference
py_mixin_ctor_array_fill:
  name: py_mixin_ctor_array_fill
  intent: mixin
  parse_format: O
  parse_args:
  - '&{py_var}'
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - if ({py_var} != {nullptr}) {{+
  - "if ({c_helper_fill_from_PyObject}(\t{py_var},\t \"{c_var}\",\t SH_obj->{field_name},\t\
    \ {field_size}) == -1)"
  - +goto fail;-
  - self->{PY_member_object} = {nullptr};
  - -}}
  goto_fail: true
py_mixin_cxx-as-pointer:
  name: py_mixin_cxx-as-pointer
  intent: mixin
  fmtdict:
    cxx_addr: ''
    cxx_member: ->
    cxx_deref: '*'
py_mixin_cxx-as-scalar:
  name: py_mixin_cxx-as-scalar
  intent: mixin
  fmtdict:
    cxx_addr: '&'
    cxx_member: .
    cxx_deref: ''
py_mixin_function-assign-pointee:
  name: py_mixin_function-assign-pointee
  intent: mixin
  call:
  - '*{cxx_var} = {C_call_function};'
py_mixin_function-declare:
  name: py_mixin_function-declare
  intent: mixin
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
py_mixin_function-struct-class:
  name: py_mixin_function-struct-class
  intent: mixin
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};  // struct_class
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_addr}{cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_mixin_function-void:
  name: py_mixin_function-void
  intent: mixin
  call:
  - '{C_call_function};'
py_mixin_malloc:
  name: py_mixin_malloc
  intent: mixin
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(std::malloc(\tsizeof({cxx_type}) * ({array_size})));"
  - if ({cxx_var} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  goto_fail: true
  lang_c:
    pre_call:
    - "{c_var} = malloc(\tsizeof({c_type}) * ({array_size}));"
    - if ({c_var} == {nullptr}) {{+
    - PyErr_NoMemory();
    - goto fail;
    - -}}
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(std::malloc(\tsizeof({cxx_type}) *\
      \ ({array_size})));"
    - if ({cxx_var} == {nullptr}) {{+
    - PyErr_NoMemory();
    - goto fail;
    - -}}
py_mixin_malloc_error:
  name: py_mixin_malloc_error
  intent: mixin
  pre_call:
  - if ({cxx_var} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
py_mixin_malloc_error2:
  name: py_mixin_malloc_error2
  intent: mixin
  pre_call:
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  goto_fail: true
py_mixin_shadow-create-object:
  name: py_mixin_shadow-create-object
  intent: mixin
  object_created: true
  post_call:
  - "{PyObject} * {py_var} =\t PyObject_New({PyObject}, &{PyTypeObject});"
  - '{py_var}->{PY_type_obj} = {cxx_addr}{cxx_var};'
py_mixin_string-fmtdict:
  name: py_mixin_string-fmtdict
  intent: mixin
  fmtdict:
    ctor_expr: "{cxx_var}{cxx_member}data(),\t {cxx_var}{cxx_member}size()"
py_mixin_string-fmtdict-scalar:
  name: py_mixin_string-fmtdict-scalar
  intent: mixin
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
py_mixin_template_array_error:
  name: py_mixin_template_array_error
  intent: mixin
  post_parse:
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a 1-D array of {cxx_T}\"\
    );"
  - goto fail;
  - -}}
  goto_fail: true
py_mixin_unknown:
  name: py_mixin_unknown
  intent: mixin
py_out_bool:
  name: py_out_bool
  intent: out
  arg_declare:
  - bool {cxx_var};
  object_created: true
  declare:
  - '{PyObject} * {py_var} = {nullptr};'
  post_call:
  - '{py_var} = PyBool_FromLong({c_var});'
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_out_bool*:
  name: py_out_bool*
  intent: out
  arg_declare:
  - bool {cxx_var};
  arg_call:
  - '&{cxx_var}'
  object_created: true
  declare:
  - '{PyObject} * {py_var} = {nullptr};'
  post_call:
  - '{py_var} = PyBool_FromLong({c_var});'
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_out_char*_charlen:
  name: py_out_char*_charlen
  intent: out
  arg_declare:
  - '{c_const}char {c_var}[{charlen}];  // intent(out)'
  fmtdict:
    ctor_expr: '{c_var}'
  arg_call:
  - '{c_var}'
py_out_enum*:
  name: py_out_enum*
  intent: out
  fmtdict:
    cxx_member: .
  arg_call:
  - '&{cxx_var}'
  declare:
  - '{cxx_type} {py_var};'
  post_call:
  - '*{c_var} = ({cxx_type}) {py_var};'
  local:
  - cxx
py_out_native&:
  name: py_out_native&
  intent: out
  arg_declare:
  - '{c_const}{c_type} {c_var};'
py_out_native*:
  name: py_out_native*
  intent: out
  arg_declare:
  - '{c_type} {c_var};'
  fmtdict:
    ctor_expr: '{c_var}'
  arg_call:
  - '&{c_var}'
py_out_native*&_numpy:
  name: py_out_native*&_numpy
  intent: out
  arg_declare:
  - '{c_const}{c_type} *{c_var};'
  arg_call:
  - '{cxx_var}'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject *{py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{npy_intp_asgn}{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t\
    \ {numpy_type},\t {cxx_nonconst_ptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_out_native**_list:
  name: py_out_native**_list
  intent: out
  arg_declare:
  - '{c_const}{c_type} *{c_var};'
  arg_call:
  - '&{cxx_var}'
  c_helper:
  - to_PyList_{cxx_type}:to_PyList
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{py_var} = {c_helper_to_PyList}\t({cxx_var},\t {array_size});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_out_native**_numpy:
  name: py_out_native**_numpy
  intent: out
  arg_declare:
  - '{c_const}{c_type} *{c_var};'
  arg_call:
  - '&{cxx_var}'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject *{py_var} = {nullptr};'
  call:
  - "{gen.cxxdecl.cxx_var} =\t {C_call_function};"
  post_call:
  - "{npy_intp_asgn}{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t\
    \ {numpy_type},\t {cxx_nonconst_ptr});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  fail_declare:
  - '{gen.cxxdecl.cxx_var};'
  fail_call:
  - "{cxx_var} =\t {C_call_function};"
  goto_fail: true
py_out_native**_raw:
  name: py_out_native**_raw
  intent: out
  arg_declare:
  - '{c_type} *{c_var};'
  arg_call:
  - '&{cxx_var}'
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  post_call:
  - '{py_var} = PyCapsule_New({cxx_var}, NULL, NULL);'
py_out_native*_list:
  name: py_out_native*_list
  intent: out
  arg_declare:
  - '{cxx_type} * {cxx_var} = {nullptr};'
  arg_call:
  - '{c_var}'
  c_header:
  - <stdlib.h>
  c_helper:
  - to_PyList_{cxx_type}:to_PyList
  cxx_header:
  - <cstdlib>
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(std::malloc(\tsizeof({cxx_type}) * ({array_size})));"
  - if ({cxx_var} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  post_call:
  - "{py_var} = {c_helper_to_PyList}\t({cxx_var},\t {array_size});"
  - if ({py_var} == {nullptr}) goto fail;
  cleanup:
  - '{stdlib}free({cxx_var});'
  - '{cxx_var} = {nullptr};'
  fail:
  - Py_XDECREF({py_var});
  - "if ({cxx_var} != {nullptr})\t {stdlib}free({cxx_var});"
  goto_fail: true
  lang_c:
    pre_call:
    - "{c_var} = malloc(\tsizeof({c_type}) * ({array_size}));"
    - if ({c_var} == {nullptr}) {{+
    - PyErr_NoMemory();
    - goto fail;
    - -}}
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(std::malloc(\tsizeof({cxx_type}) *\
      \ ({array_size})));"
    - if ({cxx_var} == {nullptr}) {{+
    - PyErr_NoMemory();
    - goto fail;
    - -}}
py_out_native*_numpy:
  name: py_out_native*_numpy
  intent: out
  arg_call:
  - '{c_var}'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyArrayObject * {py_var} = {nullptr};'
  post_parse:
  - '{npy_intp_asgn}{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_SimpleNew({npy_rank},
    {npy_dims_var}, {numpy_type}){cast2};'
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_out_shadow_*:
  name: py_out_shadow_*
  intent: out
  object_created: true
  declare:
  - '{PyObject} *{py_var} = {nullptr};'
  post_call:
  - "{py_var} =\t PyObject_New({PyObject}, &{PyTypeObject});"
  - if ({py_var} == {nullptr}) goto fail;
  - '{py_var}->{PY_type_obj} = {cxx_addr}{cxx_var};'
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
py_out_string:
  name: py_out_string
  intent: out
  post_declare:
  - '{c_const}std::string {cxx_var};'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_out_string&:
  name: py_out_string&
  intent: out
  post_declare:
  - '{c_const}std::string {cxx_var};'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '{cxx_var}'
  local:
  - cxx
py_out_string*:
  name: py_out_string*
  intent: out
  post_declare:
  - '{c_const}std::string {cxx_var};'
  fmtdict:
    cxx_member: .
    ctor_expr: "{cxx_var}.data(),\t {cxx_var}.size()"
  arg_call:
  - '&{cxx_var}'
  local:
  - cxx
py_out_struct&_class:
  name: py_out_struct&_class
  intent: out
  arg_declare:
  - '{cxx_type} *{cxx_var} = {nullptr};'
  fmtdict:
    cxx_member: ->
  arg_call:
  - '*{cxx_var}'
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  pre_call:
  - '{cxx_var} = new {cxx_type};'
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = malloc(sizeof({c_type}));'
  lang_cxx:
    pre_call:
    - '{cxx_var} = new {cxx_type};'
py_out_struct&_numpy:
  name: py_out_struct&_numpy
  intent: out
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  arg_call:
  - '*{cxx_var}'
  need_numpy: true
  object_created: true
  declare:
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_NewFromDescr(\t&PyArray_Type,\t\
    \ {PYN_descr},\t 0,\t {nullptr},\t {nullptr},\t {nullptr},\t 0,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_out_struct*_class:
  name: py_out_struct*_class
  intent: out
  arg_declare:
  - '{cxx_type} *{cxx_var} = {nullptr};'
  fmtdict:
    cxx_member: ->
  object_created: true
  declare:
  - PyObject *{py_var} = {nullptr};
  pre_call:
  - '{cxx_var} = new {cxx_type};'
  post_call:
  - "{py_var} = {PY_to_object_idtor_func}({cxx_addr}{cxx_var},\t {capsule_order});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = malloc(sizeof({c_type}));'
  lang_cxx:
    pre_call:
    - '{cxx_var} = new {cxx_type};'
py_out_struct*_list:
  name: py_out_struct*_list
  intent: out
  post_declare:
  - '{cxx_type} {cxx_var};'
  arg_call:
  - '&{cxx_var}'
py_out_struct*_numpy:
  name: py_out_struct*_numpy
  intent: out
  arg_declare:
  - '{cxx_type} *{cxx_var};'
  need_numpy: true
  object_created: true
  declare:
  - PyArrayObject * {py_var} = {nullptr};
  post_parse:
  - Py_INCREF({PYN_descr});
  - "{py_var} = {cast_reinterpret}PyArrayObject *{cast1}PyArray_NewFromDescr(\t&PyArray_Type,\t\
    \ {PYN_descr},\t 0,\t {nullptr},\t {nullptr},\t {nullptr},\t 0,\t {nullptr}){cast2};"
  - if ({py_var} == {nullptr}) {{+
  - "PyErr_SetString(PyExc_ValueError,\t \"{c_var} must be a {rank}-D array of {c_type}\"\
    );"
  - goto fail;
  - -}}
  pre_call:
  - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  lang_c:
    pre_call:
    - '{c_var} = PyArray_DATA({py_var});'
  lang_cxx:
    pre_call:
    - "{cxx_var} = static_cast<{cxx_type} *>\t(PyArray_DATA({py_var}));"
py_out_struct_list:
  name: py_out_struct_list
  intent: out
  post_declare:
  - '{cxx_type} {cxx_var};'
py_out_vector<native>&_list:
  name: py_out_vector<native>&_list
  intent: out
  post_declare:
  - std::vector<{cxx_T}> {cxx_var};
  arg_call:
  - '{cxx_var}'
  c_helper:
  - to_PyList_vector_{cxx_T}:to_PyList
  object_created: true
  declare:
  - PyObject * {py_var} = {nullptr};
  post_call:
  - "{py_var} = {c_helper_to_PyList}\t({cxx_var});"
  - if ({py_var} == {nullptr}) goto fail;
  fail:
  - Py_XDECREF({py_var});
  goto_fail: true
  local:
  - cxx
py_out_vector<native>&_numpy:
  name: py_out_vector<native>&_numpy
  intent: out
  arg_declare:
  - '{cxx_type} *{py_local_cxx} = {nullptr};'
  arg_call:
  - '*{cxx_var}'
  need_numpy: true
  object_created: true
  declare:
  - '{npy_intp_decl}PyObject * {py_var} = {nullptr};'
  - PyObject *{py_capsule} = {nullptr};
  pre_call:
  - '{py_local_cxx} = new {cxx_type};'
  - if ({py_local_cxx} == {nullptr}) {{+
  - PyErr_NoMemory();
  - goto fail;
  - -}}
  post_call:
  - '{npy_dims_var}[0] = {cxx_var}->size();'
  - "{py_var} = PyArray_SimpleNewFromData({npy_rank},\t {npy_dims_var},\t {numpy_type},\t\
    \ {cxx_var}->data());"
  - if ({py_var} == {nullptr}) goto fail;
  - "{py_capsule} = PyCapsule_New({cxx_var}, \"{PY_numpy_array_capsule_name}\", \t\
    {PY_capsule_destructor_function});"
  - if ({py_capsule} == {nullptr}) goto fail;
  - "PyCapsule_SetContext({py_capsule},\t {PY_fetch_context_function}({capsule_order}));"
  - "if (PyArray_SetBaseObject(\t{cast_reinterpret}PyArrayObject *{cast1}{py_var}{cast2},\t\
    \ {py_capsule}) < 0)\t goto fail;"
  destructor_name: '{cxx_type} *'
  destructor:
  - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
  - delete cxx_ptr;
  fail:
  - if ({cxx_var} != {nullptr}) {{+
  - '{PY_release_memory_function}({capsule_order}, {cxx_var});'
  - -}}
  - Py_XDECREF({py_var});
  - Py_XDECREF({py_capsule});
  goto_fail: true
  local:
  - cxx
  - capsule
  lang_c:
    pre_call:
    - '{py_local_cxx} = malloc(sizeof({cxx_type}));'
    destructor:
    - free(ptr);
  lang_cxx:
    pre_call:
    - '{py_local_cxx} = new {cxx_type};'
    destructor:
    - "{cxx_type} * cxx_ptr =\t static_cast<{cxx_type} *>(ptr);"
    - delete cxx_ptr;
py_out_void*&:
  name: py_out_void*&
  intent: out
  arg_declare:
  - void *{c_var};
  fmtdict:
    ctor_expr: '{cxx_var}'
  arg_call:
  - '{c_var}'
py_out_void**:
  name: py_out_void**
  intent: out
  arg_declare:
  - void *{c_var};
  fmtdict:
    ctor_expr: '{cxx_var}'
  arg_call:
  - '&{c_var}'
py_subroutine:
  name: py_subroutine
  intent: subroutine
  call:
  - '{C_call_function};'
root
  py
    ctor
      char* -- py_ctor_char*
        numpy -- py_ctor_char*_numpy
      char** -- py_ctor_char**
        list -- py_ctor_char**_list
      char[] -- py_ctor_char[]
        list -- py_ctor_char[]_list
        numpy -- py_ctor_char[]_numpy
      native -- py_ctor_native
        list -- py_ctor_native_list
        numpy -- py_ctor_native_numpy
      native* -- py_ctor_native*
        list -- py_ctor_native*_list
        numpy -- py_ctor_native*_numpy
      native[] -- py_ctor_native[]
        list -- py_ctor_native[]_list
        numpy -- py_ctor_native[]_numpy
      shadow -- py_ctor_shadow
      struct -- py_ctor_struct
    descr
      bool -- py_descr_bool
      char* -- py_descr_char*
        numpy -- py_descr_char*_numpy
      char**
        list -- py_descr_char**_list
      char[] -- py_descr_char[]
        list -- py_descr_char[]_list
        numpy -- py_descr_char[]_numpy
      native -- py_descr_native
      native*
        list -- py_descr_native*_list
        numpy -- py_descr_native*_numpy
      native[]
        list -- py_descr_native[]_list
        numpy -- py_descr_native[]_numpy
    function
      bool -- py_function_bool
      char -- py_function_char
      char* -- py_function_char*
      enum -- py_function_enum
      native -- py_function_native
      native&
        numpy -- py_function_native&_numpy
      native*
        list -- py_function_native*_list
        numpy -- py_function_native*_numpy
        scalar -- py_function_native*_scalar
      shadow -- py_function_shadow
      shadow& -- py_function_shadow&
      shadow* -- py_function_shadow*
      string -- py_function_string
      string& -- py_function_string&
      string* -- py_function_string*
      struct
        class -- py_function_struct_class
        list -- py_function_struct_list
        numpy -- py_function_struct_numpy
      struct*
        class -- py_function_struct*_class
        list -- py_function_struct*_list
        numpy -- py_function_struct*_numpy
      vector
        list -- py_function_vector_list
        numpy -- py_function_vector_numpy
      vector<native>
        list -- py_function_vector<native>_list
        numpy -- py_function_vector<native>_numpy
      void* -- py_function_void*
    implied
      bool -- py_implied_bool
      native -- py_implied_native
    in
      bool -- py_in_bool
      char -- py_in_char
      char* -- py_in_char*
      char** -- py_in_char**
      enum -- py_in_enum
      native -- py_in_native
      native& -- py_in_native&
      native* -- py_in_native*
        list -- py_in_native*_list
        numpy -- py_in_native*_numpy
      procedure -- py_in_procedure
      shadow -- py_in_shadow
      shadow& -- py_in_shadow&
      shadow* -- py_in_shadow*
      string -- py_in_string
      string& -- py_in_string&
      string* -- py_in_string*
      struct
        class -- py_in_struct_class
        list -- py_in_struct_list
        numpy -- py_in_struct_numpy
      struct&
        class -- py_in_struct&_class
        numpy -- py_in_struct&_numpy
      struct*
        class -- py_in_struct*_class
        list -- py_in_struct*_list
        numpy -- py_in_struct*_numpy
      unknown -- py_in_unknown
      vector<native>&
        list -- py_in_vector<native>&_list
        numpy -- py_in_vector<native>&_numpy
      void* -- py_in_void*
    inout
      bool -- py_inout_bool
      bool* -- py_inout_bool*
      char* -- py_inout_char*
      native& -- py_inout_native&
      native* -- py_inout_native*
        list -- py_inout_native*_list
        numpy -- py_inout_native*_numpy
      shadow
        * -- py_inout_shadow_*
      string -- py_inout_string
      string& -- py_inout_string&
      string* -- py_inout_string*
      struct
        list -- py_inout_struct_list
      struct&
        class -- py_inout_struct&_class
        numpy -- py_inout_struct&_numpy
      struct*
        class -- py_inout_struct*_class
        list -- py_inout_struct*_list
        numpy -- py_inout_struct*_numpy
    mixin
      alloc-cxx-type -- py_mixin_alloc-cxx-type
      array
        error -- py_mixin_array_error
      array-ContiguousFromObject -- py_mixin_array-ContiguousFromObject
      array-FROM-OFT-in -- py_mixin_array-FROM-OFT-in
      array-FROM-OTF -- py_mixin_array-FROM-OTF
      array-FromAny -- py_mixin_array-FromAny
      array-NewFromDescr -- py_mixin_array-NewFromDescr
      array-NewFromDescr2 -- py_mixin_array-NewFromDescr2
      array-SimpleNew -- py_mixin_array-SimpleNew
      array-SimpleNewFromData -- py_mixin_array-SimpleNewFromData
      array-SimpleNewFromData2 -- py_mixin_array-SimpleNewFromData2
      array-capsule -- py_mixin_array-capsule
      array-get-data -- py_mixin_array-get-data
      array-parse -- py_mixin_array-parse
      ctor
        array -- py_mixin_ctor_array
          fill -- py_mixin_ctor_array_fill
      cxx-as-pointer -- py_mixin_cxx-as-pointer
      cxx-as-scalar -- py_mixin_cxx-as-scalar
      function-assign-pointee -- py_mixin_function-assign-pointee
      function-declare -- py_mixin_function-declare
      function-struct-class -- py_mixin_function-struct-class
      function-void -- py_mixin_function-void
      malloc -- py_mixin_malloc
        error -- py_mixin_malloc_error
        error2 -- py_mixin_malloc_error2
      shadow-create-object -- py_mixin_shadow-create-object
      string-fmtdict -- py_mixin_string-fmtdict
      string-fmtdict-scalar -- py_mixin_string-fmtdict-scalar
      template
        array
          error -- py_mixin_template_array_error
      unknown -- py_mixin_unknown
    out
      bool -- py_out_bool
      bool* -- py_out_bool*
      char*
        charlen -- py_out_char*_charlen
      enum* -- py_out_enum*
      native& -- py_out_native&
      native* -- py_out_native*
        list -- py_out_native*_list
        numpy -- py_out_native*_numpy
      native*&
        numpy -- py_out_native*&_numpy
      native**
        list -- py_out_native**_list
        numpy -- py_out_native**_numpy
        raw -- py_out_native**_raw
      shadow
        * -- py_out_shadow_*
      string -- py_out_string
      string& -- py_out_string&
      string* -- py_out_string*
      struct
        list -- py_out_struct_list
      struct&
        class -- py_out_struct&_class
        numpy -- py_out_struct&_numpy
      struct*
        class -- py_out_struct*_class
        list -- py_out_struct*_list
        numpy -- py_out_struct*_numpy
      vector<native>&
        list -- py_out_vector<native>&_list
        numpy -- py_out_vector<native>&_numpy
      void*& -- py_out_void*&
      void** -- py_out_void**
    subroutine -- py_subroutine
***** Lua
lua_ctor:
  name: lua_ctor
  intent: ctor
  call:
  - "{LUA_userdata_type} * {LUA_userdata_var} =\t ({LUA_userdata_type} *) lua_newuserdata({LUA_state_var},\
    \ sizeof(*{LUA_userdata_var}));"
  - "{LUA_userdata_var}->{LUA_userdata_member} =\t new {namespace_scope}{cxx_class}({cxx_call_list});"
  - /* Add the metatable to the stack. */
  - luaL_getmetatable(L, "{LUA_metadata}");
  - /* Set the metatable on the userdata. */
  - lua_setmetatable(L, -2);
lua_dtor:
  name: lua_dtor
  intent: dtor
  call:
  - delete {LUA_userdata_var}->{LUA_userdata_member};
  - '{LUA_userdata_var}->{LUA_userdata_member} = NULL;'
lua_function_bool:
  name: lua_function_bool
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_enum:
  name: lua_function_enum
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_native:
  name: lua_function_native
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_shadow*:
  name: lua_function_shadow*
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_string:
  name: lua_function_string
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_string&:
  name: lua_function_string&
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
  post_call:
  - '{push_expr};'
lua_function_void*:
  name: lua_function_void*
  intent: function
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
lua_in_bool:
  name: lua_in_bool
  intent: in
  pre_call:
  - bool {c_var} = {pop_expr};
lua_in_enum:
  name: lua_in_enum
  intent: in
  pre_call:
  - "{cxx_type} {cxx_var} =\t {pop_expr};"
lua_in_native:
  name: lua_in_native
  intent: in
  pre_call:
  - "{cxx_type} {cxx_var} =\t {pop_expr};"
lua_in_native*:
  name: lua_in_native*
  intent: in
lua_in_procedure:
  name: lua_in_procedure
  intent: in
lua_in_shadow*:
  name: lua_in_shadow*
  intent: in
  pre_call:
  - "{cxx_type} * {cxx_var} =\t {pop_expr};"
lua_in_string&:
  name: lua_in_string&
  intent: in
  pre_call:
  - "const char * {c_var} = \t{pop_expr};"
lua_in_string*:
  name: lua_in_string*
  intent: in
  pre_call:
  - "const char * {c_var} = \t{pop_expr};"
lua_in_unknown:
  name: lua_in_unknown
  intent: in
lua_in_void:
  name: lua_in_void
  intent: in
lua_inout_native*:
  name: lua_inout_native*
  intent: inout
  pre_call:
  - // lua_inout_native*;
lua_mixin_callfunction:
  name: lua_mixin_callfunction
  intent: mixin
  call:
  - '{rv_asgn}{LUA_this_call}{function_name}({cxx_call_list});'
lua_mixin_push:
  name: lua_mixin_push
  intent: mixin
  post_call:
  - '{push_expr};'
lua_mixin_unknown:
  name: lua_mixin_unknown
  intent: mixin
lua_out_native*:
  name: lua_out_native*
  intent: out
lua_subroutine:
  name: lua_subroutine
  intent: subroutine
  call:
  - '{LUA_this_call}{function_name}({cxx_call_list});'
root
  lua
    ctor -- lua_ctor
    dtor -- lua_dtor
    function
      bool -- lua_function_bool
      enum -- lua_function_enum
      native -- lua_function_native
      shadow* -- lua_function_shadow*
      string -- lua_function_string
      string& -- lua_function_string&
      void* -- lua_function_void*
    in
      bool -- lua_in_bool
      enum -- lua_in_enum
      native -- lua_in_native
      native* -- lua_in_native*
      procedure -- lua_in_procedure
      shadow* -- lua_in_shadow*
      string& -- lua_in_string&
      string* -- lua_in_string*
      unknown -- lua_in_unknown
      void -- lua_in_void
    inout
      native* -- lua_inout_native*
    mixin
      callfunction -- lua_mixin_callfunction
      push -- lua_mixin_push
      unknown -- lua_mixin_unknown
    out
      native* -- lua_out_native*
    subroutine -- lua_subroutine
