Example #1
0
File: method.py Project: wwll/pclpy
 def to_str(self, prefix, class_var_name):
     params = self.cppmethod["parameters"]
     doc = clean_doxygen(self.cppmethod.get("doxygen", ""))
     args = make_pybind_argument_list(params)
     if "operator" in self.cppmethod["name"]:
         message = "Operators not implemented (%s)" % (self.cppmethod["name"],)
         ret_val = "// " + message
     elif self.needs_lambda_call:
         message = "Non templated function disambiguation not implemented (%s)" % (self.cppmethod["name"],)
         ret_val = "// " + message
     #     """ Example of how to implement for kdtreeFlann:
     #     .def("nearest_k_search", []
     #     (Class &class_, const PointT &point, int k,
     #               std::vector<int> &k_indices, std::vector<float> &k_sqr_distances)
     #                {return class_.nearestKSearch(point, k, k_indices, k_sqr_distances);},
     #                                                  "point"_a,
     #                                                  "k"_a,
     #                                                  "k_indices"_a,
     #                                                  "k_sqr_distances"_a
     #                                                  )
     #                                                  """
     elif any("**" in param["type"].replace(" ", "") for param in params):
         message = "Double pointer arguments are not supported by pybind11 (%s)" % (self.cppmethod["name"],)
         ret_val = "// " + message
     elif self.is_boost_function_callback():
         s = '{cls_var}.def("{name}", []({cls} &v, {types} &cb) {ob} v.{name}(cb); {cb}, R"({doc})")'
         types = self.list_parameter_types(prefix, template_types=None)
         types = types.replace("boost::function", "std::function")
         data = {"name": self.name,
                 "cls": prefix,
                 "cls_var": class_var_name,
                 "types": types,
                 "ob": "{ob}",  # will get formatted later
                 "cb": "{cb}",
                 "doc": doc,
                 }
         ret_val = s.format(**data)
     elif self.templated_types:
         return_values = []
         names = list(self.templated_types.keys())
         types = list(self.templated_types.values())
         for types_combination in product(*types):
             template_types = tuple(zip(names, types_combination))
             disamb = self.make_disambiguation(prefix, template_types=template_types)
             return_values.append(self.disambiguated_function_call(class_var_name, disamb, args))
         ret_val = return_values
     elif self.is_an_overload:
         disamb = self.make_disambiguation(prefix)
         ret_val = self.disambiguated_function_call(class_var_name, disamb, args)
     else:
         s = '{cls_var}.def{static}("{name}", &{cls}{name}{args}, R"({doc})")'
         data = {"name": self.name,
                 "static": self.static_value(),
                 "cls": (prefix + "::") if prefix else "",
                 "cls_var": class_var_name,
                 "args": args,
                 "doc": doc,
                 }
         ret_val = s.format(**data)
     return ret_val
Example #2
0
File: method.py Project: wwll/pclpy
 def disambiguated_function_call(self, cls_var, disamb, args):
     doc = clean_doxygen(self.cppmethod.get("doxygen", ""))
     return '{cls_var}.def{static}("{name}", {disamb}{args}, R"({doc})")'.format(cls_var=cls_var,
                                                                                 name=self.name,
                                                                                 disamb=disamb,
                                                                                 static=self.static_value(),
                                                                                 args=args,
                                                                                 doc=doc)
Example #3
0
    def to_str(self, class_var_name, class_enums_names):
        def default(p):
            val = p.get("defaultValue", "")
            if val:
                if val in class_enums_names:
                    val = "Class::" + val
                val = val.replace(
                    " ", "")  # CppHeaderParser addsspace to float values
                val = "=" + val
            return val

        def init_param_type(param):
            type_ = param["raw_type"]
            type_only_last_element = type_.split("::")[-1]
            class_with_param_name = (param["method"]["name"],
                                     param["raw_type"])
            class_typedefs = param["method"]["parent"]["typedefs"]["public"]
            custom = CUSTOM_OVERLOAD_TYPES.get(
                (param["method"]["parent"]["name"], type_))
            if custom:
                type_ = "typename " + custom
            elif param.get("enum"):
                type_ = "Class::%s" % param.get("enum").split("::")[-1]
            elif type_only_last_element in class_typedefs:
                type_ = type_only_last_element
            elif class_with_param_name in INHERITED_ENUMS:
                type_ = "Class::" + type_only_last_element
            if param.get("pointer"):
                type_ += "*"
            return type_

        if any("**" in param["type"].replace(" ", "")
               for param in self.params):
            message = "Double pointer arguments are not supported by pybind11 (%s)" % (
                self.cppconstructor["name"], )
            return "// " + message

        if len(self.params):
            s = '{cls_var}.def(py::init<{params_types}>(), {params_names}, R"({doc})")'
            types = ", ".join([init_param_type(p) for p in self.params])
            names = ", ".join(
                ['"%s"_a%s' % (p["name"], default(p)) for p in self.params])
            data = {
                "params_types": types,
                "params_names": names,
                "cls_var": class_var_name
            }
        else:
            s = '{cls_var}.def(py::init<>(), R"({doc})")'
            data = {"cls_var": class_var_name}
        data["doc"] = clean_doxygen(self.cppconstructor.get("doxygen", ""))
        return s.format(**data)
Example #4
0
 def to_str(self):
     if self.is_templated:
         s = 'py::class_<Class{inherits}{ptr}> {cls_var}(m, suffix.c_str(), R"({doc})")'
     else:
         s = 'py::class_<Class{inherits}{ptr}> {cls_var}(m, "{name}", R"({doc})")'
     ptr = ", boost::shared_ptr<Class>"
     if self.class_["name"] in DONT_HOLD_WITH_BOOST_SHARED_PTR:
         ptr = ""
     data = {
         "name": self.class_name,
         "cls_var": self.CLS_VAR,
         # "original_name": self.class_name,
         "inherits": (", %s" % self.inherits) if self.inherits else "",
         "ptr": ptr,
         "doc": clean_doxygen(self.class_.get("doxygen", "")),
     }
     return s.format(**data)
Example #5
0
    def to_str(self, class_var_name, class_enums_names):

        def default(p):
            val = p.get("defaultValue", "")
            if val:
                if val in class_enums_names:
                    val = "Class::" + val
                elif p.get('enum') and p.get('enum') not in val:
                    val = p.get('enum') + '::' + val
                val = val.replace(" ", "")  # CppHeaderParser adds a space to float values
                if re.search(r"(?<!\.)\d+f$", val):  # "50f" -> "50.0f"
                    val = val.replace('f', '.0f')
                search = re.search(r"1e(-?\d+)", val)  # "1e-4.0" -> "0.0001"
                if search:
                    val = str(1 * 10 ** int(search.group(1)))
                val = "=" + val
            return val

        def init_param_type(param):
            type_ = param["raw_type"]
            type_only_last_element = type_.split("::")[-1]
            class_with_param_name = (param["method"]["name"], param["raw_type"])
            class_typedefs = param["method"]["parent"]["typedefs"]["public"]
            custom = CUSTOM_OVERLOAD_TYPES.get((param["method"]["parent"]["name"], type_))
            if custom:
                type_ = custom
            elif param.get("enum"):
                if param.get('enum').startswith('pcl::'):
                    type_ = param.get('enum')
                else:
                    type_ = "Class::%s" % param.get("enum").split("::")[-1]
            elif type_only_last_element in class_typedefs:
                type_ = type_only_last_element
            elif class_with_param_name in INHERITED_ENUMS:
                type_ = "Class::" + type_only_last_element
            if all(c in type_ for c in "<>"):
                type_ = "typename " + type_
            if param.get("pointer"):
                type_ += "*"
            if param["constant"] and not type_.startswith("const "):
                type_ = "const " + type_
            if param["reference"] and not type_.endswith("&"):
                type_ += " &"
            return type_

        if any("**" in param["type"].replace(" ", "") for param in self.params):
            message = "Double pointer arguments are not supported by pybind11 (%s)" % (self.cppconstructor["name"],)
            return "// " + message

        if len(self.params):
            s = '{cls_var}.def(py::init<{params_types}>(), {params_names}, R"({doc})")'
            types = ", ".join([init_param_type(p) for p in self.params])
            names = ", ".join(['"%s"_a%s' % (p["name"], default(p)) for p in self.params])
            data = {"params_types": types,
                    "params_names": names,
                    "cls_var": class_var_name}
        else:
            s = '{cls_var}.def(py::init<>(), R"({doc})")'
            data = {"cls_var": class_var_name}
        data["doc"] = clean_doxygen(self.cppconstructor.get("doxygen", ""))
        return s.format(**data)