예제 #1
0
def _CreateInputParameter(func_name, ast_param, arg, args):
    """Return a string to create C++ stack var named arg. args += arg getter."""
    ptype = ast_param.type
    ctype = ptype.cpp_type
    smartptr = (ctype.startswith('::std::unique_ptr')
                or ctype.startswith('::std::shared_ptr'))
    # std::function special case
    if not ctype:
        assert ptype.callable, 'Non-callable param has empty cpp_type'
        if len(ptype.callable.returns) > 1:
            raise ValueError('Callbacks may not have any output parameters, '
                             '%s param %s has %d' %
                             (func_name, ast_param.name.native,
                              len(ptype.callable.returns) - 1))
        args.append('std::move(%s)' % arg)
        return 'std::function<%s> %s;' % (astutils.StdFuncParamStr(
            ptype.callable), arg)
    # T*
    if ptype.cpp_raw_pointer:
        if ptype.cpp_toptr_conversion:
            args.append(arg)
            return '%s %s;' % (ctype, arg)
        t = ctype[:-1]
        if ctype.endswith('*'):
            if ptype.cpp_abstract:
                if ptype.cpp_touniqptr_conversion:
                    args.append(arg + '.get()')
                    return '::std::unique_ptr<%s> %s;' % (t, arg)
            elif ptype.cpp_has_public_dtor:
                # Create a copy on stack and pass its address.
                if ptype.cpp_has_def_ctor:
                    args.append('&' + arg)
                    return '%s %s;' % (t, arg)
                else:
                    args.append('&%s.value()' % arg)
                    return '::gtl::optional<%s> %s;' % (t, arg)
        raise TypeError("Can't convert %s to %s" % (ptype.lang_type, ctype))
    if (smartptr or ptype.cpp_abstract) and not ptype.cpp_touniqptr_conversion:
        raise TypeError(
            'Can\'t create "%s" variable (C++ type %s) in function %s'
            ', no valid conversion defined' %
            (ast_param.name.native, ctype, func_name))
    # unique_ptr<T>, shared_ptr<T>
    if smartptr:
        args.append('std::move(%s)' % arg)
        return '%s %s;' % (ctype, arg)
    # T, [const] T&
    if ptype.cpp_toptr_conversion:
        args.append('*' + arg)
        return '%s* %s;' % (ctype, arg)
    if ptype.cpp_abstract:  # for AbstractType &
        args.append('*' + arg)
        return 'std::unique_ptr<%s> %s;' % (ctype, arg)
    # Create a copy on stack (even fot T&, most cases should have to_T* conv).
    if ptype.cpp_has_def_ctor:
        args.append('std::move(%s)' % arg)
        return '%s %s;' % (ctype, arg)
    else:
        args.append(arg + '.value()')
        return '::gtl::optional<%s> %s;' % (ctype, arg)
예제 #2
0
파일: pyext.py 프로젝트: yijunyu/clif
 def WrapCallable(self, c, fname, retnum, line_number):
   """Process callable return type AST.Type c."""
   assert c.HasField('callable'), ('WrapCallable called on AST that has no'
                                   ' "callable":\n' + str(c))
   cname = Ident(c.callable.name.cpp_name) or fname+'_ret%d_lambda' % retnum
   wname = 'lambda_'+cname
   for i, r in enumerate(c.callable.returns):
     if r.type.HasField('callable'):
       for s in self.WrapCallable(r.type, cname, i, line_number):
         yield s
   if not c.cpp_type:
     assert c.callable, 'Non-callable param has empty cpp_type'
     c.cpp_type = 'std::function<%s>' % astutils.StdFuncParamStr(c.callable)
   for s in gen.FunctionCall(
       '', wname, doc=c.lang_type,
       catch=self.catch_cpp_exceptions and not c.callable.cpp_noexcept,
       call=['void* fp = PyCapsule_GetPointer(self, typeid(%s).name());'
             % c.cpp_type,
             'if (fp == nullptr) return nullptr;',
             '(*static_cast<%s*>(fp))' % c.cpp_type],
       postcall_init=None, typepostconversion=self.typemap,
       func_ast=c.callable, lineno=line_number): yield s
   defname = wname + '_def'
   yield gen.FromFunctionDef(c.cpp_type, defname, wname,
                             VARARGS if len(c.callable.params) else NOARGS,
                             'Calls '+c.cpp_type)
   self.types.add(types.CallableType(c.cpp_type, c.lang_type, defname))
예제 #3
0
파일: pyext.py 프로젝트: sr-gi/clif
 def WrapOneCallable(self, c, fname, ret_or_arg, line_number, class_ns,
                     only_pyobjas):
     """Process callable return or param type of AST.Type c."""
     assert c.HasField('callable'), (
         'WrapOneCallable called on AST that has no'
         ' "callable":\n' + str(c))
     cname = Ident(
         c.callable.name.cpp_name) or fname + '_%s_lambda' % ret_or_arg
     wname = 'lambda_' + cname
     for s in self._WrapAllCallables(c.callable, cname, line_number,
                                     class_ns, not only_pyobjas):
         yield s
     if only_pyobjas is ret_or_arg.startswith('ret'):
         # Clif_PyObjFrom() for this callable is not needed (only Clif_PyObjAs()).
         return
     if not c.cpp_type:
         assert c.callable, 'Non-callable param has empty cpp_type'
         c.cpp_type = 'std::function<%s>' % astutils.StdFuncParamStr(
             c.callable)
     if c.cpp_type in self.types_std_function_cpp_types:
         return
     self.types_std_function_cpp_types.add(c.cpp_type)
     for s in gen.FunctionCall(
             '',
             wname,
             doc=c.lang_type,
             catch=self.catch_cpp_exceptions
             and not c.callable.cpp_noexcept,
             call=[
                 'void* fp = PyCapsule_GetPointer(self, typeid(%s).name());'
                 % c.cpp_type, 'if (fp == nullptr) return nullptr;',
                 '(*static_cast<%s*>(fp))' % c.cpp_type
             ],
             postcall_init=None,
             typepostconversion=self.typemap,
             func_ast=c.callable,
             lineno=line_number):
         yield s
     defname = wname + '_def'
     yield ''
     yield gen.FromFunctionDef(
         c.cpp_type, defname, wname,
         VARARGS if len(c.callable.params) else NOARGS,
         'Calls ' + c.cpp_type)
     if class_ns:
         defname = class_ns + '::' + defname
     self.types.append(types.CallableType(c.cpp_type, c.lang_type, defname))