From 40b444dc435cdc1fb0fec8952aa931ea623fd2ec Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Thu, 3 Feb 2022 13:01:38 -0500 Subject: [PATCH 1/5] chore: add clang-format --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2014cb2b42..4a5cb147e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -141,6 +141,11 @@ repos: entry: PyBind|Numpy|Cmake|CCache|PyTest exclude: .pre-commit-config.yaml +- repo: https://github.com/pre-commit/mirrors-clang-format + rev: "v13.0.0" + hooks: + - id: clang-format + - repo: local hooks: - id: check-style From 1ee16a89b62831e2c33bd84e961fec90da0a233b Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Feb 2022 06:47:27 -0800 Subject: [PATCH 2/5] Removing check-style (Classic check-style) Ported from @henryiii's https://github.com/pybind/pybind11/pull/3683/commits/53056b1b0eeb4136b0d7362a8261b6b59658e0a7 --- .pre-commit-config.yaml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4a5cb147e4..c31cab71c7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -145,12 +145,3 @@ repos: rev: "v13.0.0" hooks: - id: clang-format - -- repo: local - hooks: - - id: check-style - name: Classic check-style - language: system - types: - - c++ - entry: ./tools/check-style.sh From 58da37ce8bc297c648efba27bcd56a572e04b0b2 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Feb 2022 07:19:19 -0800 Subject: [PATCH 3/5] Manual line breaks to pre-empt undesired `clang-format`ing. Informed by work under https://github.com/pybind/pybind11/pull/3683: https://github.com/pybind/pybind11/commit/60b7eb410fefe2b23aeb6906f2a9184e91b11a15 https://github.com/pybind/pybind11/commit/59572e65598b4b9f2c9ae0b8a0e5fcb6d65c7f92 --- include/pybind11/detail/common.h | 4 +++- include/pybind11/iostream.h | 3 ++- include/pybind11/pybind11.h | 33 +++++++++++++++++--------------- include/pybind11/pytypes.h | 10 +++++++--- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 14788b6523..2a06e1f06c 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -842,7 +842,9 @@ PYBIND11_NAMESPACE_END(detail) #if defined(_MSC_VER) # pragma warning(push) -# pragma warning(disable: 4275) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. +# pragma warning(disable: 4275) +// warning C4275: An exported class was derived from a class that wasn't exported. +// Can be ignored when derived from a STL class. #endif /// C++ bindings of builtin Python exceptions class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error { diff --git a/include/pybind11/iostream.h b/include/pybind11/iostream.h index 8c0772c281..d6cf223726 100644 --- a/include/pybind11/iostream.h +++ b/include/pybind11/iostream.h @@ -164,7 +164,8 @@ PYBIND11_NAMESPACE_END(detail) .. code-block:: cpp { - py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; + py::scoped_ostream_redirect output{ + std::cerr, py::module::import("sys").attr("stderr")}; std::cout << "Hello, World!"; } \endrst */ diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 560c3e0c1b..6b30110354 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1168,8 +1168,8 @@ class module_ : public object { Adds an object to the module using the given name. Throws if an object with the given name already exists. - ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 has - established will, in most cases, break things. + ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 + has established will, in most cases, break things. \endrst */ PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { if (!overwrite && hasattr(*this, name)) { @@ -2560,10 +2560,11 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty PYBIND11_NAMESPACE_END(detail) /** \rst - Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr. + Try to retrieve a python method by the provided name from the instance pointed to by the + this_ptr. - :this_ptr: The pointer to the object the overridden method should be retrieved for. This should be - the first non-trampoline class encountered in the inheritance chain. + :this_ptr: The pointer to the object the overridden method should be retrieved for. This should + be the first non-trampoline class encountered in the inheritance chain. :name: The name of the overridden Python method to retrieve. :return: The Python method by this name from the object or an empty function wrapper. \endrst */ @@ -2588,9 +2589,10 @@ template function get_override(const T *this_ptr, const char *name) { } while (false) /** \rst - Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn' - from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return - the appropriate type. See :ref:`overriding_virtuals` for more information. This macro should be used when the method + Macro to populate the virtual method in the trampoline class. This macro tries to look up a + method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument + conversions to call this method and return the appropriate type. + See :ref:`overriding_virtuals` for more information. This macro should be used when the method name in C is not the same as the method name in Python. For example with `__str__`. .. code-block:: cpp @@ -2611,8 +2613,8 @@ template function get_override(const T *this_ptr, const char *name) { } while (false) /** \rst - Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it - throws if no override can be found. + Macro for pure virtual functions, this function is identical to + :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found. \endrst */ #define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \ do { \ @@ -2621,9 +2623,10 @@ template function get_override(const T *this_ptr, const char *name) { } while (false) /** \rst - Macro to populate the virtual method in the trampoline class. This macro tries to look up the method - from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return - the appropriate type. This macro should be used if the method name in C and in Python are identical. + Macro to populate the virtual method in the trampoline class. This macro tries to look up the + method from the Python side, deals with the :ref:`gil` and necessary argument conversions to + call this method and return the appropriate type. This macro should be used if the method name + in C and in Python are identical. See :ref:`overriding_virtuals` for more information. .. code-block:: cpp @@ -2648,8 +2651,8 @@ template function get_override(const T *this_ptr, const char *name) { PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) /** \rst - Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`, except that it throws - if no override can be found. + Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`, + except that it throws if no override can be found. \endrst */ #define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \ PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index d39e71045c..31632e31f7 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -337,7 +337,9 @@ PYBIND11_NAMESPACE_END(detail) #if defined(_MSC_VER) # pragma warning(push) -# pragma warning(disable: 4275 4251) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. +# pragma warning(disable: 4275 4251) +// warning C4275: An exported class was derived from a class that wasn't exported. +// Can be ignored when derived from a STL class. #endif /// Fetch and hold an error which was already set in Python. An instance of this is typically /// thrown to propagate python-side errors back through C++ which can either be caught manually or @@ -1745,7 +1747,8 @@ class memoryview : public object { See also: Python C API documentation for `PyMemoryView_FromBuffer`_. - .. _PyMemoryView_FromBuffer: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer + .. _PyMemoryView_FromBuffer: + https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer :param ptr: Pointer to the buffer. :param itemsize: Byte size of an element. @@ -1800,7 +1803,8 @@ class memoryview : public object { See also: Python C API documentation for `PyMemoryView_FromBuffer`_. - .. _PyMemoryView_FromMemory: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory + .. _PyMemoryView_FromMemory: + https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory \endrst */ static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) { PyObject* ptr = PyMemoryView_FromMemory( From 2f78a4ae2f1c0bf23edd22d7b374efaed47757fa Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Feb 2022 16:03:14 -0800 Subject: [PATCH 4/5] Manual curation of clang-format diffs involving source code comments. Very labor-intensive and dull. --- .clang-format | 1 + include/pybind11/buffer_info.h | 6 ++- include/pybind11/cast.h | 7 +++- include/pybind11/chrono.h | 3 +- include/pybind11/detail/common.h | 20 ++++++---- include/pybind11/detail/internals.h | 12 ++++-- include/pybind11/detail/type_caster_base.h | 3 +- include/pybind11/numpy.h | 3 +- include/pybind11/options.h | 3 +- include/pybind11/pybind11.h | 24 ++++++++---- include/pybind11/pytypes.h | 3 +- include/pybind11/stl_bind.h | 9 +++-- tests/constructor_stats.h | 6 ++- tests/test_class.cpp | 43 ++++++++++++---------- tests/test_kwargs_and_defaults.cpp | 6 ++- tests/test_modules.cpp | 3 +- tests/test_numpy_array.cpp | 3 +- tests/test_numpy_dtypes.cpp | 8 ++-- tests/test_virtual_functions.cpp | 27 ++++++++------ 19 files changed, 118 insertions(+), 72 deletions(-) diff --git a/.clang-format b/.clang-format index 8e0fd8b014..474b4b61e9 100644 --- a/.clang-format +++ b/.clang-format @@ -15,5 +15,6 @@ IndentWidth: 4 Language: Cpp SpaceAfterCStyleCast: true Standard: Cpp11 +StatementMacros: ['PyObject_HEAD'] TabWidth: 4 ... diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 1dd6955527..1f22baa3bd 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -44,10 +44,12 @@ struct buffer_info { void *ptr = nullptr; // Pointer to the underlying storage ssize_t itemsize = 0; // Size of individual items in bytes ssize_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() + std::string format; // For homogeneous buffers, this should be set to + // format_descriptor::format() ssize_t ndim = 0; // Number of dimensions std::vector shape; // Shape of the tensor (1 entry per dimension) - std::vector strides; // Number of bytes between adjacent entries (for each per dimension) + std::vector strides; // Number of bytes between adjacent entries + // (for each per dimension) bool readonly = false; // flag to indicate if the underlying storage may be written to buffer_info() = default; diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index cfec7e5f0e..d616156509 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -994,7 +994,9 @@ PYBIND11_NAMESPACE_BEGIN(detail) template ::value, int>> object object_or_cast(T &&o) { return pybind11::cast(std::forward(o)); } -struct override_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the PYBIND11_OVERRIDE_OVERRIDE macro +// Placeholder type for the unneeded (and dead code) static variable in the +// PYBIND11_OVERRIDE_OVERRIDE macro +struct override_unused {}; template using override_caster_t = conditional_t< cast_is_temporary_value_reference::value, make_caster, override_unused>; @@ -1461,7 +1463,8 @@ handle type::handle_of() { }} /// Lets you pass a type containing a `,` through a macro parameter without needing a separate -/// typedef, e.g.: `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType), PYBIND11_TYPE(Parent), f, arg)` +/// typedef, e.g.: +/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType), PYBIND11_TYPE(Parent), f, arg)` #define PYBIND11_TYPE(...) __VA_ARGS__ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h index b24533b903..cfa635a011 100644 --- a/include/pybind11/chrono.h +++ b/include/pybind11/chrono.h @@ -38,7 +38,8 @@ template class duration_caster { using rep = typename type::rep; using period = typename type::period; - using days = std::chrono::duration>; // signed 25 bits required by the standard. + // signed 25 bits required by the standard. + using days = std::chrono::duration>; bool load(handle src, bool) { using namespace std::chrono; diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 2a06e1f06c..aa3c617c49 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -42,8 +42,9 @@ # endif # endif #elif defined(_MSC_VER) && __cplusplus == 199711L -// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented) -// Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer +// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully +// implemented). Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 +// or newer. # if _MSVC_LANG >= 201402L # define PYBIND11_CPP14 # if _MSVC_LANG > 201402L && _MSC_VER >= 1910 @@ -722,8 +723,8 @@ template constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } PYBIND11_NAMESPACE_END(constexpr_impl) -/// Return the index of the first type in Ts which satisfies Predicate. Returns sizeof...(Ts) if -/// none match. +/// Return the index of the first type in Ts which satisfies Predicate. +/// Returns sizeof...(Ts) if none match. template class Predicate, typename... Ts> constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate::value...); } @@ -872,7 +873,9 @@ PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError) PYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError) PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError) PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) -PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error +PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or + /// handle::call fail due to a type + /// casting error PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally [[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } @@ -976,13 +979,14 @@ class any_container { template ::value>> any_container(It first, It last) : v(first, last) { } - // Implicit conversion constructor from any arbitrary container type with values convertible to T + // Implicit conversion constructor from any arbitrary container type + // with values convertible to T template ())), T>::value>> // NOLINTNEXTLINE(google-explicit-constructor) any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { } - // initializer_list's aren't deducible, so don't get matched by the above template; we need this - // to explicitly allow implicit conversion from one: + // initializer_list's aren't deducible, so don't get matched by the above template; + // we need this to explicitly allow implicit conversion from one: template ::value>> any_container(const std::initializer_list &c) : any_container(c.begin(), c.end()) { } diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index 911ec3df41..9c895c3878 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -146,18 +146,22 @@ struct override_hash { /// Whenever binary incompatible changes are made to this structure, /// `PYBIND11_INTERNALS_VERSION` must be incremented. struct internals { - type_map registered_types_cpp; // std::type_index -> pybind11's type information - std::unordered_map> registered_types_py; // PyTypeObject* -> base type_info(s) + // std::type_index -> pybind11's type information + type_map registered_types_cpp; + // PyTypeObject* -> base type_info(s) + std::unordered_map> registered_types_py; std::unordered_multimap registered_instances; // void * -> instance* std::unordered_set, override_hash> inactive_override_cache; type_map> direct_conversions; std::unordered_map> patients; std::forward_list registered_exception_translators; - std::unordered_map shared_data; // Custom data to be shared across extensions + std::unordered_map shared_data; // Custom data to be shared across + // extensions #if PYBIND11_INTERNALS_VERSION == 4 std::vector unused_loader_patient_stack_remove_at_v5; #endif - std::forward_list static_strings; // Stores the std::strings backing detail::c_str() + std::forward_list static_strings; // Stores the std::strings backing + // detail::c_str() PyTypeObject *static_property_type; PyTypeObject *default_metaclass; PyObject *instance_base; diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index ea5ef6a2be..34100c3ae2 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -426,7 +426,8 @@ PYBIND11_NOINLINE void instance::allocate_layout() { space += t->holder_size_in_ptrs; // holder instance } size_t flags_at = space; - space += size_in_ptrs(n_types); // status bytes (holder_constructed and instance_registered) + space += size_in_ptrs(n_types); // status bytes (holder_constructed and + // instance_registered) // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values, // in particular, need to be 0). Use Python's memory allocation functions: in Python 3.6 diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index 57f0c90948..489587835d 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -325,7 +325,8 @@ template struct array_info : array_info using remove_all_extents_t = typename array_info::type; template using is_pod_struct = all_of< - std::is_standard_layout, // since we're accessing directly in memory we need a standard layout type + std::is_standard_layout, // since we're accessing directly in memory + // we need a standard layout type #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803) // libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after 5) // don't implement is_trivially_copyable, so approximate it diff --git a/include/pybind11/options.h b/include/pybind11/options.h index d74db1c68d..810e5e0104 100644 --- a/include/pybind11/options.h +++ b/include/pybind11/options.h @@ -51,7 +51,8 @@ class options { struct state { bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. - bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. + bool show_function_signatures = true; //< Include auto-generated function signatures + // in docstrings. }; static state &global_state() { diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 6b30110354..a7897b2656 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -242,7 +242,8 @@ class cpp_function : public function { rec->nargs_pos = cast_in::args_pos >= 0 ? static_cast(cast_in::args_pos) - : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if we have a kw_only + : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if + // we have a kw_only rec->has_args = cast_in::args_pos >= 0; rec->has_kwargs = cast_in::has_kwargs; @@ -263,7 +264,8 @@ class cpp_function : public function { static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos, "py::pos_only must come before py::kw_only"); } - /* Generate a readable signature describing the function's arguments and return value types */ + /* Generate a readable signature describing the function's arguments and return + value types */ static constexpr auto signature = const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name; PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types(); @@ -400,7 +402,8 @@ class cpp_function : public function { handle th((PyObject *) tinfo->type); signature += th.attr("__module__").cast() + "." + - th.attr("__qualname__").cast(); // Python 3.3+, but we backport it to earlier versions + // Python 3.3+, but we backport it to earlier versions + th.attr("__qualname__").cast(); } else if (rec->is_new_style_constructor && arg_index == 0) { // A new-style `__init__` takes `self` as `value_and_holder`. // Rewrite it to the proper class type. @@ -639,7 +642,8 @@ class cpp_function : public function { const function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr), *it = overloads; - /* Need to know how many arguments + keyword arguments there are to pick the right overload */ + /* Need to know how many arguments + keyword arguments there are to pick the right + overload */ const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in); handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr, @@ -715,7 +719,8 @@ class cpp_function : public function { function_call call(func, parent); - size_t args_to_copy = (std::min)(pos_args, n_args_in); // Protect std::min with parentheses + // Protect std::min with parentheses + size_t args_to_copy = (std::min)(pos_args, n_args_in); size_t args_copied = 0; // 0. Inject new-style `self` argument @@ -955,7 +960,8 @@ class cpp_function : public function { - catch the exception and call PyErr_SetString or PyErr_SetObject to set a standard (or custom) Python exception, or - do nothing and let the exception fall through to the next translator, or - - delegate translation to the next translator by throwing a new type of exception. */ + - delegate translation to the next translator by throwing a new type of exception. + */ auto &local_exception_translators = get_local_internals().registered_exception_translators; if (detail::apply_exception_translators(local_exception_translators)) { @@ -1196,7 +1202,8 @@ class module_ : public object { static module_ create_extension_module(const char *name, const char *doc, module_def *def) { #if PY_MAJOR_VERSION >= 3 // module_def is PyModuleDef - def = new (def) PyModuleDef { // Placement new (not an allocation). + // Placement new (not an allocation). + def = new (def) PyModuleDef { /* m_base */ PyModuleDef_HEAD_INIT, /* m_name */ name, /* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr, @@ -1455,7 +1462,8 @@ class class_ : public detail::generic_type { none_of...>::value || // no base class arguments, or: ( constexpr_sum(is_pyobject::value...) == 1 && // Exactly one base constexpr_sum(is_base::value...) == 0 && // no template option bases - none_of...>::value), // no multiple_inheritance attr + // no multiple_inheritance attr + none_of...>::value), "Error: multiple inheritance bases must be specified via class_ template options"); type_record record; diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 31632e31f7..bdb3b9174f 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -161,7 +161,8 @@ class object_api : public pyobject_tag { /// Return the object's current reference count int ref_count() const { return static_cast(Py_REFCNT(derived().ptr())); } - // TODO PYBIND11_DEPRECATED("Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()") + // TODO PYBIND11_DEPRECATED( + // "Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()") handle get_type() const; private: diff --git a/include/pybind11/stl_bind.h b/include/pybind11/stl_bind.h index 6db1faf404..2f997d6b03 100644 --- a/include/pybind11/stl_bind.h +++ b/include/pybind11/stl_bind.h @@ -44,7 +44,8 @@ struct is_comparable< container_traits::is_comparable>> : std::true_type { }; -/* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ +/* For a vector/map data structure, recursively check the value type + (which is std::pair for maps) */ template struct is_comparable::is_vector>> { static constexpr const bool value = @@ -384,7 +385,8 @@ template auto vector_if_insertion_operator(Cl } // Provide the buffer interface for vectors if we have data() and we have a format for it -// GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer +// GCC seems to have "void std::vector::data()" - doing SFINAE on the existence of data() +// is insufficient, we need to check it returns an appropriate pointer template struct vector_has_data_and_format : std::false_type {}; template @@ -408,7 +410,8 @@ void vector_buffer_impl(Class_& cl, std::true_type) { static_assert(vector_has_data_and_format::value, "There is not an appropriate format descriptor for this vector"); - // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here + // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard + // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here format_descriptor::format(); cl.def_buffer([](Vector& v) -> buffer_info { diff --git a/tests/constructor_stats.h b/tests/constructor_stats.h index 8ee4047925..ccb623e1c3 100644 --- a/tests/constructor_stats.h +++ b/tests/constructor_stats.h @@ -72,8 +72,10 @@ inspection/testing in python) by using the functions with `print_` replaced with class ConstructorStats { protected: - std::unordered_map _instances; // Need a map rather than set because members can shared address with parents - std::list _values; // Used to track values (e.g. of value constructors) + std::unordered_map _instances; // Need a map rather than set because members can + // shared address with parents + std::list _values; // Used to track values + // (e.g. of value constructors) public: int default_constructions = 0; int copy_constructions = 0; diff --git a/tests/test_class.cpp b/tests/test_class.cpp index 7445b3c026..851bc00ca0 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -22,7 +22,8 @@ #include #if defined(_MSC_VER) -# pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier +# pragma warning(disable: 4324) +// warning C4324: structure was padded due to alignment specifier #endif // test_brace_initialization @@ -534,22 +535,24 @@ CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared); #define CHECK_BROKEN(N) static_assert(std::is_same>::value, \ "Breaks1 has wrong type!"); -//// Two holder classes: -//typedef py::class_, std::unique_ptr>, std::unique_ptr>> Breaks1; -//CHECK_BROKEN(1); -//// Two aliases: -//typedef py::class_, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2; -//CHECK_BROKEN(2); -//// Holder + 2 aliases -//typedef py::class_, std::unique_ptr>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3; -//CHECK_BROKEN(3); -//// Alias + 2 holders -//typedef py::class_, std::unique_ptr>, BreaksTramp<-4>, std::shared_ptr>> Breaks4; -//CHECK_BROKEN(4); -//// Invalid option (not a subclass or holder) -//typedef py::class_, BreaksTramp<-4>> Breaks5; -//CHECK_BROKEN(5); -//// Invalid option: multiple inheritance not supported: -//template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {}; -//typedef py::class_, BreaksBase<-6>, BreaksBase<-7>> Breaks8; -//CHECK_BROKEN(8); +#ifdef PYBIND11_NEVER_DEFINED_EVER +// Two holder classes: +typedef py::class_, std::unique_ptr>, std::unique_ptr>> Breaks1; +CHECK_BROKEN(1); +// Two aliases: +typedef py::class_, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2; +CHECK_BROKEN(2); +// Holder + 2 aliases +typedef py::class_, std::unique_ptr>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3; +CHECK_BROKEN(3); +// Alias + 2 holders +typedef py::class_, std::unique_ptr>, BreaksTramp<-4>, std::shared_ptr>> Breaks4; +CHECK_BROKEN(4); +// Invalid option (not a subclass or holder) +typedef py::class_, BreaksTramp<-4>> Breaks5; +CHECK_BROKEN(5); +// Invalid option: multiple inheritance not supported: +template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {}; +typedef py::class_, BreaksBase<-6>, BreaksBase<-7>> Breaks8; +CHECK_BROKEN(8); +#endif diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index 0e262dad2f..d09630a8cd 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -153,10 +153,12 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { // These should fail to compile: +#ifdef PYBIND11_NEVER_DEFINED_EVER // argument annotations are required when using kw_only -// m.def("bad_kw_only1", [](int) {}, py::kw_only()); + m.def("bad_kw_only1", [](int) {}, py::kw_only()); // can't specify both `py::kw_only` and a `py::args` argument -// m.def("bad_kw_only2", [](int i, py::args) {}, py::kw_only(), "i"_a); + m.def("bad_kw_only2", [](int i, py::args) {}, py::kw_only(), "i"_a); +#endif // test_function_signatures (along with most of the above) struct KWClass { void foo(int, float) {} }; diff --git a/tests/test_modules.cpp b/tests/test_modules.cpp index ce61c1a25c..ba80a64c9a 100644 --- a/tests/test_modules.cpp +++ b/tests/test_modules.cpp @@ -49,7 +49,8 @@ TEST_SUBMODULE(modules, m) { .def(py::init<>()) .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) - .def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default + .def_readwrite("a1", &B::a1) // def_readonly uses an internal + // reference return policy by default .def_readwrite("a2", &B::a2); // This is intentionally "py::module" to verify it still can be used in place of "py::module_" diff --git a/tests/test_numpy_array.cpp b/tests/test_numpy_array.cpp index bc1797845b..17fc4de2ec 100644 --- a/tests/test_numpy_array.cpp +++ b/tests/test_numpy_array.cpp @@ -399,7 +399,8 @@ TEST_SUBMODULE(numpy_array, sm) { // test_initializer_list // Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous - sm.def("array_initializer_list1", []() { return py::array_t(1); }); // { 1 } also works, but clang warns about it + sm.def("array_initializer_list1", []() { return py::array_t(1); }); + // { 1 } also works for the above, but clang warns about it sm.def("array_initializer_list2", []() { return py::array_t({ 1, 2 }); }); sm.def("array_initializer_list3", []() { return py::array_t({ 1, 2, 3 }); }); sm.def("array_initializer_list4", []() { return py::array_t({ 1, 2, 3, 4 }); }); diff --git a/tests/test_numpy_dtypes.cpp b/tests/test_numpy_dtypes.cpp index 468a89a3c9..a6566c5c65 100644 --- a/tests/test_numpy_dtypes.cpp +++ b/tests/test_numpy_dtypes.cpp @@ -308,10 +308,12 @@ TEST_SUBMODULE(numpy_dtypes, m) { PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, "x", __y__, "y"); - // If uncommented, this should produce a static_assert failure telling the user that the struct +#ifdef PYBIND11_NEVER_DEFINED_EVER + // If enabled, this should produce a static_assert failure telling the user that the struct // is not a POD type -// struct NotPOD { std::string v; NotPOD() : v("hi") {}; }; -// PYBIND11_NUMPY_DTYPE(NotPOD, v); + struct NotPOD { std::string v; NotPOD() : v("hi") {}; }; + PYBIND11_NUMPY_DTYPE(NotPOD, v); +#endif // Check that dtypes can be registered programmatically, both from // initializer lists of field descriptors and from other containers. diff --git a/tests/test_virtual_functions.cpp b/tests/test_virtual_functions.cpp index 7fb90cc591..e13b301b71 100644 --- a/tests/test_virtual_functions.cpp +++ b/tests/test_virtual_functions.cpp @@ -376,9 +376,12 @@ TEST_SUBMODULE(virtual_functions, m) { public: using OverrideTest::OverrideTest; std::string str_value() override { PYBIND11_OVERRIDE(std::string, OverrideTest, str_value); } - // Not allowed (uncommenting should hit a static_assert failure): we can't get a reference - // to a python numeric value, since we only copy values in the numeric type caster: -// std::string &str_ref() override { PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref); } + // Not allowed (enabling the below should hit a static_assert failure): we can't get a + // reference to a python numeric value, since we only copy values in the numeric type + // caster: +#ifdef PYBIND11_NEVER_DEFINED_EVER + std::string &str_ref() override { PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref); } +#endif // But we can work around it like this: private: std::string _tmp; @@ -395,7 +398,9 @@ TEST_SUBMODULE(virtual_functions, m) { py::class_(m, "OverrideTest") .def(py::init()) .def("str_value", &OverrideTest::str_value) -// .def("str_ref", &OverrideTest::str_ref) +#ifdef PYBIND11_NEVER_DEFINED_EVER + .def("str_ref", &OverrideTest::str_ref) +#endif .def("A_value", &OverrideTest::A_value) .def("A_ref", &OverrideTest::A_ref); @@ -498,11 +503,11 @@ class PyD_Repeat : public D_Repeat { // Inheritance approach 2: templated trampoline classes. // // Advantages: -// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one for -// any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes and 11 -// methods (repeat). -// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and can -// properly inherit constructors. +// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one +// for any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes +// and 11 methods (repeat). +// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and +// can properly inherit constructors. // // Disadvantage: // - the compiler must still generate and compile 14 different methods (more, even, than the 11 @@ -524,8 +529,8 @@ class PyB_Tpl : public PyA_Tpl { int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); } double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); } }; -// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can -// use PyB_Tpl and PyB_Tpl for the trampoline classes instead): +// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these +// (we can use PyB_Tpl and PyB_Tpl for the trampoline classes instead): /* template class PyC_Tpl : public PyB_Tpl { public: From 590822a15a87a7907fbbaf3391b871127133db76 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 9 Feb 2022 16:11:09 -0800 Subject: [PATCH 5/5] Automatic clang-format changes (NO manual changes). --- include/pybind11/attr.h | 210 ++-- include/pybind11/buffer_info.h | 104 +- include/pybind11/cast.h | 742 +++++++----- include/pybind11/chrono.h | 112 +- include/pybind11/complex.h | 22 +- include/pybind11/detail/class.h | 66 +- include/pybind11/detail/common.h | 882 ++++++++------ include/pybind11/detail/descr.h | 81 +- include/pybind11/detail/init.h | 238 ++-- include/pybind11/detail/internals.h | 117 +- include/pybind11/detail/type_caster_base.h | 308 ++--- include/pybind11/detail/typeid.h | 9 +- include/pybind11/eigen.h | 395 ++++--- include/pybind11/embed.h | 36 +- include/pybind11/eval.h | 83 +- include/pybind11/functional.h | 12 +- include/pybind11/gil.h | 46 +- include/pybind11/iostream.h | 41 +- include/pybind11/numpy.h | 1028 ++++++++++------- include/pybind11/operators.h | 253 ++-- include/pybind11/options.h | 42 +- include/pybind11/pybind11.h | 1210 +++++++++++--------- include/pybind11/pytypes.h | 817 +++++++------ include/pybind11/stl.h | 136 ++- include/pybind11/stl/filesystem.h | 41 +- include/pybind11/stl_bind.h | 465 ++++---- tests/constructor_stats.h | 123 +- tests/cross_module_gil_utils.cpp | 38 +- tests/local_bindings.h | 37 +- tests/object.h | 60 +- tests/pybind11_cross_module_tests.cpp | 82 +- tests/pybind11_tests.cpp | 19 +- tests/pybind11_tests.h | 26 +- tests/test_async.cpp | 5 +- tests/test_buffers.cpp | 66 +- tests/test_builtin_casters.cpp | 295 +++-- tests/test_call_policies.cpp | 43 +- tests/test_callbacks.cpp | 56 +- tests/test_chrono.cpp | 31 +- tests/test_class.cpp | 262 +++-- tests/test_constants_and_functions.cpp | 67 +- tests/test_copy_move.cpp | 170 ++- tests/test_custom_type_casters.cpp | 100 +- tests/test_docstring_options.cpp | 55 +- tests/test_eigen.cpp | 182 +-- tests/test_embed/catch.cpp | 8 +- tests/test_embed/external_module.cpp | 9 +- tests/test_embed/test_interpreter.cpp | 58 +- tests/test_enum.cpp | 83 +- tests/test_eval.cpp | 27 +- tests/test_exceptions.cpp | 93 +- tests/test_factory_constructors.cpp | 94 +- tests/test_gil_scoped.cpp | 43 +- tests/test_iostream.cpp | 30 +- tests/test_kwargs_and_defaults.cpp | 238 ++-- tests/test_local_bindings.cpp | 34 +- tests/test_methods_and_attributes.cpp | 194 ++-- tests/test_modules.cpp | 66 +- tests/test_multiple_inheritance.cpp | 137 ++- tests/test_numpy_array.cpp | 245 ++-- tests/test_numpy_dtypes.cpp | 237 ++-- tests/test_numpy_vectorize.cpp | 29 +- tests/test_opaque_types.cpp | 11 +- tests/test_operator_overloading.cpp | 170 +-- tests/test_pickling.cpp | 6 +- tests/test_pytypes.cpp | 165 ++- tests/test_sequences_and_iterators.cpp | 222 ++-- tests/test_smart_ptr.cpp | 90 +- tests/test_stl.cpp | 233 ++-- tests/test_stl_binders.cpp | 53 +- tests/test_tagbased_polymorphic.cpp | 82 +- tests/test_thread.cpp | 6 +- tests/test_virtual_functions.cpp | 279 ++--- 73 files changed, 7028 insertions(+), 5127 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 669c72614e..c009cd391d 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -20,54 +20,62 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// @{ /// Annotation for methods -struct is_method { handle class_; +struct is_method { + handle class_; explicit is_method(const handle &c) : class_(c) {} }; /// Annotation for operators -struct is_operator { }; +struct is_operator {}; /// Annotation for classes that cannot be subclassed -struct is_final { }; +struct is_final {}; /// Annotation for parent scope -struct scope { handle value; +struct scope { + handle value; explicit scope(const handle &s) : value(s) {} }; /// Annotation for documentation -struct doc { const char *value; +struct doc { + const char *value; explicit doc(const char *value) : value(value) {} }; /// Annotation for function names -struct name { const char *value; +struct name { + const char *value; explicit name(const char *value) : value(value) {} }; /// Annotation indicating that a function is an overload associated with a given "sibling" -struct sibling { handle value; +struct sibling { + handle value; explicit sibling(const handle &value) : value(value.ptr()) {} }; /// Annotation indicating that a class derives from another given type -template struct base { +template +struct base { - PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute + PYBIND11_DEPRECATED( + "base() was deprecated in favor of specifying 'T' as a template argument to class_") + base() {} // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute }; /// Keep patient alive while nurse lives -template struct keep_alive { }; +template +struct keep_alive {}; /// Annotation indicating that a class is involved in a multiple inheritance relationship -struct multiple_inheritance { }; +struct multiple_inheritance {}; /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class -struct dynamic_attr { }; +struct dynamic_attr {}; /// Annotation which enables the buffer protocol for a type -struct buffer_protocol { }; +struct buffer_protocol {}; /// Annotation which requests that a special metaclass is created for a type struct metaclass { @@ -78,7 +86,7 @@ struct metaclass { metaclass() {} /// Override pybind11's default metaclass - explicit metaclass(handle value) : value(value) { } + explicit metaclass(handle value) : value(value) {} }; /// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that @@ -99,15 +107,16 @@ struct custom_type_setup { }; /// Annotation that marks a class as local to the module: -struct module_local { const bool value; +struct module_local { + const bool value; constexpr explicit module_local(bool v = true) : value(v) {} }; /// Annotation to mark enums as an arithmetic type -struct arithmetic { }; +struct arithmetic {}; /// Mark a function for addition at the beginning of the existing overload chain instead of the end -struct prepend { }; +struct prepend {}; /** \rst A call policy which places one or more guard variables (``Ts...``) around the function call. @@ -127,9 +136,13 @@ struct prepend { }; return foo(args...); // forwarded arguments }); \endrst */ -template struct call_guard; +template +struct call_guard; -template <> struct call_guard<> { using type = detail::void_type; }; +template <> +struct call_guard<> { + using type = detail::void_type; +}; template struct call_guard { @@ -154,7 +167,8 @@ PYBIND11_NAMESPACE_BEGIN(detail) enum op_id : int; enum op_type : int; struct undefined_t; -template struct op_; +template +struct op_; void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); /// Internal data structure which holds metadata about a keyword argument @@ -166,15 +180,16 @@ struct argument_record { bool none : 1; ///< True if None is allowed when loading argument_record(const char *name, const char *descr, handle value, bool convert, bool none) - : name(name), descr(descr), value(value), convert(convert), none(none) { } + : name(name), descr(descr), value(value), convert(convert), none(none) {} }; -/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) +/// Internal data structure which holds metadata about a bound function (signature, overloads, +/// etc.) struct function_record { function_record() : is_constructor(false), is_new_style_constructor(false), is_stateless(false), - is_operator(false), is_method(false), has_args(false), - has_kwargs(false), prepend(false) { } + is_operator(false), is_method(false), has_args(false), has_kwargs(false), + prepend(false) {} /// Function name char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ @@ -189,13 +204,13 @@ struct function_record { std::vector args; /// Pointer to lambda function which converts arguments and performs the actual call - handle (*impl) (function_call &) = nullptr; + handle (*impl)(function_call &) = nullptr; /// Storage for the wrapped function pointer and captured data, if any - void *data[3] = { }; + void *data[3] = {}; /// Pointer to custom destructor for 'data' (if needed) - void (*free_data) (function_record *ptr) = nullptr; + void (*free_data)(function_record *ptr) = nullptr; /// Return value policy associated with this function return_value_policy policy = return_value_policy::automatic; @@ -251,7 +266,7 @@ struct function_record { struct type_record { PYBIND11_NOINLINE type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), - default_holder(true), module_local(false), is_final(false) { } + default_holder(true), module_local(false), is_final(false) {} /// Handle to the parent scope handle scope; @@ -310,22 +325,22 @@ struct type_record { /// Is the class inheritable from python classes? bool is_final : 1; - PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) { auto *base_info = detail::get_type_info(base, false); if (!base_info) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + - "\" referenced unknown base type \"" + tname + "\""); + pybind11_fail("generic_type: type \"" + std::string(name) + + "\" referenced unknown base type \"" + tname + "\""); } if (default_holder != base_info->default_holder) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + - (default_holder ? "does not have" : "has") + - " a non-default holder type while its base \"" + tname + "\" " + - (base_info->default_holder ? "does not" : "does")); + pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + + (default_holder ? "does not have" : "has") + + " a non-default holder type while its base \"" + tname + "\" " + + (base_info->default_holder ? "does not" : "does")); } bases.append((PyObject *) base_info->type); @@ -340,14 +355,13 @@ struct type_record { } }; -inline function_call::function_call(const function_record &f, handle p) : - func(f), parent(p) { +inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) { args.reserve(f.nargs); args_convert.reserve(f.nargs); } /// Tag for a new-style `__init__` defined in `detail/init.h` -struct is_new_style_constructor { }; +struct is_new_style_constructor {}; /** * Partial template specializations to process custom attributes provided to @@ -355,60 +369,79 @@ struct is_new_style_constructor { }; * fields in the type_record and function_record data structures or executed at * runtime to deal with custom call policies (e.g. keep_alive). */ -template struct process_attribute; +template +struct process_attribute; -template struct process_attribute_default { +template +struct process_attribute_default { /// Default implementation: do nothing - static void init(const T &, function_record *) { } - static void init(const T &, type_record *) { } - static void precall(function_call &) { } - static void postcall(function_call &, handle) { } + static void init(const T &, function_record *) {} + static void init(const T &, type_record *) {} + static void precall(function_call &) {} + static void postcall(function_call &, handle) {} }; /// Process an attribute specifying the function's name -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring (provided as a C-style string) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const char *d, function_record *r) { r->doc = const_cast(d); } static void init(const char *d, type_record *r) { r->doc = const_cast(d); } }; -template <> struct process_attribute : process_attribute { }; +template <> +struct process_attribute : process_attribute {}; /// Process an attribute indicating the function's return value policy -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const return_value_policy &p, function_record *r) { r->policy = p; } }; -/// Process an attribute which indicates that this is an overloaded function associated with a given sibling -template <> struct process_attribute : process_attribute_default { +/// Process an attribute which indicates that this is an overloaded function associated with a +/// given sibling +template <> +struct process_attribute : process_attribute_default { static void init(const sibling &s, function_record *r) { r->sibling = s.value; } }; /// Process an attribute which indicates that this function is a method -template <> struct process_attribute : process_attribute_default { - static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } +template <> +struct process_attribute : process_attribute_default { + static void init(const is_method &s, function_record *r) { + r->is_method = true; + r->scope = s.class_; + } }; /// Process an attribute which indicates the parent scope of a method -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const scope &s, function_record *r) { r->scope = s.value; } }; /// Process an attribute which indicates that this function is an operator -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const is_operator &, function_record *r) { r->is_operator = true; } }; -template <> struct process_attribute : process_attribute_default { - static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } +template <> +struct process_attribute + : process_attribute_default { + static void init(const is_new_style_constructor &, function_record *r) { + r->is_new_style_constructor = true; + } }; inline void check_kw_only_arg(const arg &a, function_record *r) { @@ -425,7 +458,8 @@ inline void append_self_arg_if_needed(function_record *r) { } /// Process a keyword argument attribute (*without* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg &a, function_record *r) { append_self_arg_if_needed(r); r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); @@ -435,7 +469,8 @@ template <> struct process_attribute : process_attribute_default { }; /// Process a keyword argument attribute (*with* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg_v &a, function_record *r) { if (r->is_method && r->args.empty()) { r->args.emplace_back( @@ -445,18 +480,20 @@ template <> struct process_attribute : process_attribute_default { if (!a.value) { #if !defined(NDEBUG) std::string descr("'"); - if (a.name) descr += std::string(a.name) + ": "; + if (a.name) + descr += std::string(a.name) + ": "; descr += a.type + "'"; if (r->is_method) { if (r->name) - descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; + descr += " in method '" + (std::string) str(r->scope) + "." + + (std::string) r->name + "'"; else descr += " in method of '" + (std::string) str(r->scope) + "'"; } else if (r->name) { descr += " in function '" + (std::string) r->name + "'"; } - pybind11_fail("arg(): could not convert default argument " - + descr + " into a Python object (type not registered yet?)"); + pybind11_fail("arg(): could not convert default argument " + descr + + " into a Python object (type not registered yet?)"); #else pybind11_fail("arg(): could not convert default argument " "into a Python object (type not registered yet?). " @@ -470,7 +507,8 @@ template <> struct process_attribute : process_attribute_default { }; /// Process a keyword-only-arguments-follow pseudo argument -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const kw_only &, function_record *r) { append_self_arg_if_needed(r); if (r->has_args && r->nargs_pos != static_cast(r->args.size())) { @@ -482,20 +520,23 @@ template <> struct process_attribute : process_attribute_default struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const pos_only &, function_record *r) { append_self_arg_if_needed(r); r->nargs_pos_only = static_cast(r->args.size()); if (r->nargs_pos_only > r->nargs_pos) { pybind11_fail("pos_only(): cannot follow a py::args() argument"); } - // It also can't follow a kw_only, but a static_assert in pybind11.h checks that + // It also can't follow a kw_only, but a static_assert in pybind11.h checks that } }; -/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) +/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees +/// that) template -struct process_attribute::value>> : process_attribute_default { +struct process_attribute::value>> + : process_attribute_default { static void init(const handle &h, type_record *r) { r->bases.append(h); } }; @@ -508,7 +549,9 @@ struct process_attribute> : process_attribute_default> { /// Process a multiple inheritance attribute template <> struct process_attribute : process_attribute_default { - static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } + static void init(const multiple_inheritance &, type_record *r) { + r->multiple_inheritance = true; + } }; template <> @@ -554,34 +597,41 @@ template <> struct process_attribute : process_attribute_default {}; template -struct process_attribute> : process_attribute_default> { }; +struct process_attribute> : process_attribute_default> {}; /** * Process a keep_alive call policy -- invokes keep_alive_impl during the * pre-call handler if both Nurse, Patient != 0 and use the post-call handler * otherwise */ -template struct process_attribute> : public process_attribute_default> { +template +struct process_attribute> + : public process_attribute_default> { template = 0> - static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } + static void precall(function_call &call) { + keep_alive_impl(Nurse, Patient, call, handle()); + } template = 0> - static void postcall(function_call &, handle) { } + static void postcall(function_call &, handle) {} template = 0> - static void precall(function_call &) { } + static void precall(function_call &) {} template = 0> - static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } + static void postcall(function_call &call, handle ret) { + keep_alive_impl(Nurse, Patient, call, ret); + } }; /// Recursively iterate over variadic template arguments -template struct process_attributes { - static void init(const Args&... args, function_record *r) { +template +struct process_attributes { + static void init(const Args &...args, function_record *r) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); using expander = int[]; (void) expander{ 0, ((void) process_attribute::type>::init(args, r), 0)...}; } - static void init(const Args&... args, type_record *r) { + static void init(const Args &...args, type_record *r) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r); PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r); using expander = int[]; @@ -613,7 +663,7 @@ using extract_guard_t = typename exactly_one_t, Extr /// Check the number of named arguments at compile time template ::value...), - size_t self = constexpr_sum(std::is_same::value...)> + size_t self = constexpr_sum(std::is_same::value...)> constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs); return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs; diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 1f22baa3bd..f98a4bbd7c 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -44,8 +44,8 @@ struct buffer_info { void *ptr = nullptr; // Pointer to the underlying storage ssize_t itemsize = 0; // Size of individual items in bytes ssize_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to - // format_descriptor::format() + std::string format; // For homogeneous buffers, this should be set to + // format_descriptor::format() ssize_t ndim = 0; // Number of dimensions std::vector shape; // Shape of the tensor (1 entry per dimension) std::vector strides; // Number of bytes between adjacent entries @@ -54,10 +54,15 @@ struct buffer_info { buffer_info() = default; - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), - shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), + shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) { pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); } @@ -67,36 +72,55 @@ struct buffer_info { } template - buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in), readonly) { } - - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size, bool readonly=false) - : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) { } + buffer_info(T *ptr, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : buffer_info(private_ctr_tag(), + ptr, + sizeof(T), + format_descriptor::format(), + static_cast(shape_in->size()), + std::move(shape_in), + std::move(strides_in), + readonly) {} + + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t size, + bool readonly = false) + : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {} template - buffer_info(T *ptr, ssize_t size, bool readonly=false) - : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(T *ptr, ssize_t size, bool readonly = false) + : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) {} template - buffer_info(const T *ptr, ssize_t size, bool readonly=true) - : buffer_info(const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(const T *ptr, ssize_t size, bool readonly = true) + : buffer_info( + const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) {} explicit buffer_info(Py_buffer *view, bool ownview = true) - : buffer_info(view->buf, view->itemsize, view->format, view->ndim, + : buffer_info( + view->buf, + view->itemsize, + view->format, + view->ndim, {view->shape, view->shape + view->ndim}, /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects * ignore this flag and return a view with NULL strides. * When strides are NULL, build them manually. */ view->strides - ? std::vector(view->strides, view->strides + view->ndim) - : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), + ? std::vector(view->strides, view->strides + view->ndim) + : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), (view->readonly != 0)) { this->m_view = view; this->ownview = ownview; } buffer_info(const buffer_info &) = delete; - buffer_info& operator=(const buffer_info &) = delete; + buffer_info &operator=(const buffer_info &) = delete; buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); } @@ -115,17 +139,28 @@ struct buffer_info { } ~buffer_info() { - if (m_view && ownview) { PyBuffer_Release(m_view); delete m_view; } + if (m_view && ownview) { + PyBuffer_Release(m_view); + delete m_view; + } } Py_buffer *view() const { return m_view; } Py_buffer *&view() { return m_view; } -private: - struct private_ctr_tag { }; - buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container &&shape_in, detail::any_container &&strides_in, bool readonly) - : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) { } +private: + struct private_ctr_tag {}; + + buffer_info(private_ctr_tag, + void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container &&shape_in, + detail::any_container &&strides_in, + bool readonly) + : buffer_info( + ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {} Py_buffer *m_view = nullptr; bool ownview = false; @@ -133,17 +168,22 @@ struct buffer_info { PYBIND11_NAMESPACE_BEGIN(detail) -template struct compare_buffer_info { - static bool compare(const buffer_info& b) { +template +struct compare_buffer_info { + static bool compare(const buffer_info &b) { return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); } }; -template struct compare_buffer_info::value>> { - static bool compare(const buffer_info& b) { - return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || - ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || - ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); +template +struct compare_buffer_info::value>> { + static bool compare(const buffer_info &b) { + return (size_t) b.itemsize == sizeof(T) + && (b.format == format_descriptor::value + || ((sizeof(T) == sizeof(long)) + && b.format == (std::is_unsigned::value ? "L" : "l")) + || ((sizeof(T) == sizeof(size_t)) + && b.format == (std::is_unsigned::value ? "N" : "n"))); } }; diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index d616156509..3d31fedc5b 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -10,11 +10,11 @@ #pragma once -#include "pytypes.h" #include "detail/common.h" #include "detail/descr.h" #include "detail/type_caster_base.h" #include "detail/typeid.h" +#include "pytypes.h" #include #include #include @@ -30,35 +30,42 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) -template class type_caster : public type_caster_base { }; -template using make_caster = type_caster>; +template +class type_caster : public type_caster_base {}; +template +using make_caster = type_caster>; // Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T -template typename make_caster::template cast_op_type cast_op(make_caster &caster) { +template +typename make_caster::template cast_op_type cast_op(make_caster &caster) { return caster.operator typename make_caster::template cast_op_type(); } -template typename make_caster::template cast_op_type::type> +template +typename make_caster::template cast_op_type::type> cast_op(make_caster &&caster) { - return std::move(caster).operator - typename make_caster::template cast_op_type::type>(); + return std::move(caster).operator typename make_caster:: + template cast_op_type::type>(); } -template class type_caster> { +template +class type_caster> { private: using caster_t = make_caster; caster_t subcaster; - using reference_t = type&; - using subcaster_cast_op_type = - typename caster_t::template cast_op_type; - - static_assert(std::is_same::type &, subcaster_cast_op_type>::value || - std::is_same::value, - "std::reference_wrapper caster requires T to have a caster with an " - "`operator T &()` or `operator const T &()`"); + using reference_t = type &; + using subcaster_cast_op_type = typename caster_t::template cast_op_type; + + static_assert( + std::is_same::type &, subcaster_cast_op_type>::value + || std::is_same::value, + "std::reference_wrapper caster requires T to have a caster with an " + "`operator T &()` or `operator const T &()`"); + public: bool load(handle src, bool convert) { return subcaster.load(src, convert); } static constexpr auto name = caster_t::name; - static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { + static handle + cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { // It is definitely wrong to take ownership of this pointer, so mask that rvp if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic) { @@ -66,7 +73,8 @@ template class type_caster> { } return caster_t::cast(&src.get(), policy, parent); } - template using cast_op_type = std::reference_wrapper; + template + using cast_op_type = std::reference_wrapper; explicit operator std::reference_wrapper() { return cast_op(subcaster); } }; @@ -93,24 +101,25 @@ public: template \ using cast_op_type = pybind11::detail::movable_cast_op_type -template using is_std_char_type = any_of< - std::is_same, /* std::string */ +template +using is_std_char_type = any_of, /* std::string */ #if defined(PYBIND11_HAS_U8STRING) - std::is_same, /* std::u8string */ + std::is_same, /* std::u8string */ #endif - std::is_same, /* std::u16string */ - std::is_same, /* std::u32string */ - std::is_same /* std::wstring */ ->; - + std::is_same, /* std::u16string */ + std::is_same, /* std::u32string */ + std::is_same /* std::wstring */ + >; template struct type_caster::value && !is_std_char_type::value>> { using _py_type_0 = conditional_t; - using _py_type_1 = conditional_t::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; + using _py_type_1 = conditional_t::value, + _py_type_0, + typename std::make_unsigned<_py_type_0>::type>; using py_type = conditional_t::value, double, _py_type_1>; -public: +public: bool load(handle src, bool convert) { py_type py_value; @@ -140,14 +149,13 @@ struct type_caster::value && !is_std_char_t // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls. #if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION) object index; - if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) + if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) index = reinterpret_steal(PyNumber_Index(src.ptr())); if (!index) { PyErr_Clear(); if (!convert) return false; - } - else { + } else { src_or_index = index; } } @@ -156,8 +164,8 @@ struct type_caster::value && !is_std_char_t py_value = as_unsigned(src_or_index.ptr()); } else { // signed integer: py_value = sizeof(T) <= sizeof(long) - ? (py_type) PyLong_AsLong(src_or_index.ptr()) - : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); + ? (py_type) PyLong_AsLong(src_or_index.ptr()) + : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); } } @@ -166,12 +174,14 @@ struct type_caster::value && !is_std_char_t // Check to see if the conversion is valid (integers should match exactly) // Signed/unsigned checks happen elsewhere - if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && py_value != (py_type) (T) py_value)) { + if (py_err + || (std::is_integral::value && sizeof(py_type) != sizeof(T) + && py_value != (py_type) (T) py_value)) { PyErr_Clear(); if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) { auto tmp = reinterpret_steal(std::is_floating_point::value - ? PyNumber_Float(src.ptr()) - : PyNumber_Long(src.ptr())); + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr())); PyErr_Clear(); return load(tmp, false); } @@ -182,32 +192,40 @@ struct type_caster::value && !is_std_char_t return true; } - template + template static typename std::enable_if::value, handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyFloat_FromDouble((double) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) <= sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) <= sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_SIGNED((long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) <= sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) <= sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) > sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) > sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromLongLong((long long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) > sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) > sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromUnsignedLongLong((unsigned long long) src); } @@ -215,7 +233,8 @@ struct type_caster::value && !is_std_char_t PYBIND11_TYPE_CASTER(T, const_name::value>("int", "float")); }; -template struct void_caster { +template +struct void_caster { public: bool load(handle src, bool) { if (src && src.is_none()) { @@ -229,9 +248,11 @@ template struct void_caster { PYBIND11_TYPE_CASTER(T, const_name("None")); }; -template <> class type_caster : public void_caster {}; +template <> +class type_caster : public void_caster {}; -template <> class type_caster : public type_caster { +template <> +class type_caster : public type_caster { public: using type_caster::cast; @@ -268,16 +289,20 @@ template <> class type_caster : public type_caster { return none().inc_ref(); } - template using cast_op_type = void*&; + template + using cast_op_type = void *&; explicit operator void *&() { return value; } static constexpr auto name = const_name("capsule"); + private: void *value = nullptr; }; -template <> class type_caster : public void_caster { }; +template <> +class type_caster : public void_caster {}; -template <> class type_caster { +template <> +class type_caster { public: bool load(handle src, bool convert) { if (!src) { @@ -296,14 +321,14 @@ template <> class type_caster { Py_ssize_t res = -1; if (src.is_none()) { - res = 0; // None is implicitly converted to False + res = 0; // None is implicitly converted to False } - #if defined(PYPY_VERSION) +#if defined(PYPY_VERSION) // On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists else if (hasattr(src, PYBIND11_BOOL_ATTR)) { res = PyObject_IsTrue(src.ptr()); } - #else +#else // Alternate approach for CPython: this does the same as the above, but optimized // using the CPython API so as to avoid an unneeded attribute lookup. else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) { @@ -311,7 +336,7 @@ template <> class type_caster { res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); } } - #endif +#endif if (res == 0 || res == 1) { value = (res != 0); return true; @@ -327,20 +352,25 @@ template <> class type_caster { }; // Helper class for UTF-{8,16,32} C++ stl strings: -template struct string_caster { +template +struct string_caster { using CharT = typename StringType::value_type; // Simplify life by being able to assume standard char sizes (the standard only guarantees // minimums, but Python requires exact sizes) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char size != 1"); #if defined(PYBIND11_HAS_U8STRING) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char8_t size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char8_t size != 1"); #endif - static_assert(!std::is_same::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); - static_assert(!std::is_same::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); + static_assert(!std::is_same::value || sizeof(CharT) == 2, + "Unsupported char16_t size != 2"); + static_assert(!std::is_same::value || sizeof(CharT) == 4, + "Unsupported char32_t size != 4"); // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, - "Unsupported wchar_t size != 2/4"); + "Unsupported wchar_t size != 2/4"); static constexpr size_t UTF_N = 8 * sizeof(CharT); bool load(handle src, bool) { @@ -364,7 +394,10 @@ template struct string_caster { return false; temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } + if (!temp) { + PyErr_Clear(); + return false; + } load_src = temp; #endif } @@ -385,11 +418,19 @@ template struct string_caster { } #endif - auto utfNbytes = reinterpret_steal(PyUnicode_AsEncodedString( - load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); - if (!utfNbytes) { PyErr_Clear(); return false; } + auto utfNbytes + = reinterpret_steal(PyUnicode_AsEncodedString(load_src.ptr(), + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr)); + if (!utfNbytes) { + PyErr_Clear(); + return false; + } - const auto *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + const auto *buffer + = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); // Skip BOM for UTF-16/32 if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) { @@ -406,7 +447,8 @@ template struct string_caster { return true; } - static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + static handle + cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { const char *buffer = reinterpret_cast(src.data()); auto nbytes = ssize_t(src.size() * sizeof(CharT)); handle s = decode_utfN(buffer, nbytes); @@ -421,14 +463,19 @@ template struct string_caster { private: static handle decode_utfN(const char *buffer, ssize_t nbytes) { #if !defined(PYPY_VERSION) - return - UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : - UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : - PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); + return UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) + : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) + : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); #else - // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as well), - // so bypass the whole thing by just passing the encoding as a string value, which works properly: - return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); + // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as + // well), so bypass the whole thing by just passing the encoding as a string value, which + // works properly: + return PyUnicode_Decode(buffer, + nbytes, + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr); #endif } @@ -451,27 +498,33 @@ template struct string_caster { } template - bool load_bytes(enable_if_t::value, handle>) { return false; } + bool load_bytes(enable_if_t::value, handle>) { + return false; + } }; template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster> {}; #ifdef PYBIND11_HAS_STRING_VIEW template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster, true> {}; #endif // Type caster for C-style strings. We basically use a std::string type caster, but also add the // ability to use None as a nullptr char* (which the string caster doesn't allow). -template struct type_caster::value>> { +template +struct type_caster::value>> { using StringType = std::basic_string; using StringCaster = type_caster; StringCaster str_caster; bool none = false; CharT one_char = 0; + public: bool load(handle src, bool convert) { if (!src) { @@ -521,10 +574,10 @@ template struct type_caster 1 && str_len <= 4) { auto v0 = static_cast(value[0]); // low bits only: 0-127 @@ -539,7 +592,8 @@ template struct type_caster(((v0 & 3) << 6) + (static_cast(value[1]) & 0x3F)); + one_char = static_cast(((v0 & 3) << 6) + + (static_cast(value[1]) & 0x3F)); return one_char; } // Otherwise we have a single character, but it's > U+00FF @@ -566,16 +620,18 @@ template struct type_caster using cast_op_type = pybind11::detail::cast_op_type<_T>; + template + using cast_op_type = pybind11::detail::cast_op_type<_T>; }; // Base implementation for std::tuple and std::pair -template class Tuple, typename... Ts> class tuple_caster { +template