diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000000..e29d929897 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,13 @@ +FormatStyle: file + +Checks: ' +llvm-namespace-comment, +modernize-use-override, +readability-container-size-empty, +modernize-use-using, +modernize-use-equals-default, +modernize-use-auto, +modernize-use-emplace, +' + +HeaderFilterRegex: 'pybind11/.*h' diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e83c31565d..4cdd7aab02 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -164,6 +164,30 @@ name, pre-commit): pre-commit install ``` +### Clang-Tidy + +To run Clang tidy, the following recipe should work. Files will be modified in +place, so you can use git to monitor the changes. + +```bash +docker run --rm -v $PWD:/pybind11 -it silkeh/clang:10 +apt-get update && apt-get install python3-dev python3-pytest +cmake -S pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);-fix" +cmake --build build +``` + +### Include what you use + +To run include what you use, install (`brew install include-what-you-use` on +macOS), then run: + +```bash +cmake -S . -B build-iwyu -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=$(which include-what-you-use) +cmake --build build +``` + +The report is sent to stderr; you can pip it into a file if you wish. + ### Build recipes This builds with the Intel compiler (assuming it is in your path, along with a @@ -186,7 +210,6 @@ cmake -S pybind11/ -B build cmake --build build ``` - [pre-commit]: https://pre-commit.com [pybind11.readthedocs.org]: http://pybind11.readthedocs.org/en/latest [issue tracker]: https://github.com/pybind/pybind11/issues diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index e92f96e6ef..191219326d 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,3 +17,19 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - uses: pre-commit/action@v2.0.0 + + clang-tidy: + name: Clang-Tidy + runs-on: ubuntu-latest + container: silkeh/clang:10 + steps: + - uses: actions/checkout@v2 + + - name: Install requirements + run: apt-get update && apt-get install -y python3-dev python3-pytest + + - name: Configure + run: cmake -S . -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--warnings-as-errors=*" + + - name: Build + run: cmake --build build -j 2 diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index aedbf62f1c..d0a8b34b8f 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -40,8 +40,9 @@ struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) /// Annotation indicating that a class derives from another given type template struct base { + PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } + base() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute }; /// Keep patient alive while nurse lives @@ -61,7 +62,7 @@ struct metaclass { handle value; PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") - metaclass() {} + metaclass() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute /// Override pybind11's default metaclass explicit metaclass(handle value) : value(value) { } diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 8349a46b8b..308be06a33 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -24,7 +24,7 @@ struct buffer_info { 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() { } + 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) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c588bd2f38..e3573e90d5 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -59,7 +59,7 @@ class loader_life_support { Py_CLEAR(ptr); // A heuristic to reduce the stack's capacity (e.g. after long recursive calls) - if (stack.capacity() > 16 && stack.size() != 0 && stack.capacity() / stack.size() > 2) + if (stack.capacity() > 16 && !stack.empty() && stack.capacity() / stack.size() > 2) stack.shrink_to_fit(); } @@ -163,7 +163,7 @@ inline const std::vector &all_type_info(PyTypeObject *type) */ PYBIND11_NOINLINE inline detail::type_info* get_type_info(PyTypeObject *type) { auto &bases = all_type_info(type); - if (bases.size() == 0) + if (bases.empty()) return nullptr; if (bases.size() > 1) pybind11_fail("pybind11::detail::get_type_info: type has multiple pybind11-registered bases"); @@ -220,7 +220,7 @@ struct value_and_holder { {} // Default constructor (used to signal a value-and-holder not found by get_value_and_holder()) - value_and_holder() {} + value_and_holder() = default; // Used for past-the-end iterator value_and_holder(size_t index) : index{index} {} @@ -432,7 +432,7 @@ PYBIND11_NOINLINE inline std::string error_string() { #if !defined(PYPY_VERSION) if (scope.trace) { - PyTracebackObject *trace = (PyTracebackObject *) scope.trace; + auto *trace = (PyTracebackObject *) scope.trace; /* Get the deepest trace possible */ while (trace->tb_next) @@ -1244,7 +1244,7 @@ template struct string_caster { load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); if (!utfNbytes) { PyErr_Clear(); return false; } - const CharT *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); if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 value = StringType(buffer, length); @@ -1258,7 +1258,7 @@ template struct string_caster { static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { const char *buffer = reinterpret_cast(src.data()); - ssize_t nbytes = ssize_t(src.size() * sizeof(CharT)); + auto nbytes = ssize_t(src.size() * sizeof(CharT)); handle s = decode_utfN(buffer, nbytes); if (!s) throw error_already_set(); return s; @@ -1364,7 +1364,7 @@ template struct type_caster 1 && str_len <= 4) { - unsigned char v0 = static_cast(value[0]); + auto v0 = static_cast(value[0]); size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence @@ -1929,7 +1929,7 @@ inline namespace literals { String literal version of `arg` \endrst */ constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } -} +} // namespace literals PYBIND11_NAMESPACE_BEGIN(detail) diff --git a/include/pybind11/chrono.h b/include/pybind11/chrono.h index ac3d34e06a..cbe9acec35 100644 --- a/include/pybind11/chrono.h +++ b/include/pybind11/chrono.h @@ -33,9 +33,9 @@ PYBIND11_NAMESPACE_BEGIN(detail) template class duration_caster { public: typedef typename type::rep rep; - typedef typename type::period period; + using period = typename type::period; - typedef std::chrono::duration> days; + using days = std::chrono::duration>; bool load(handle src, bool) { using namespace std::chrono; @@ -98,7 +98,7 @@ template class duration_caster { // This is for casting times on the system clock into datetime.datetime instances template class type_caster> { public: - typedef std::chrono::time_point type; + using type = std::chrono::time_point; bool load(handle src, bool) { using namespace std::chrono; diff --git a/include/pybind11/detail/class.h b/include/pybind11/detail/class.h index 8d36744f27..b4a11c0a04 100644 --- a/include/pybind11/detail/class.h +++ b/include/pybind11/detail/class.h @@ -592,7 +592,7 @@ inline PyObject* make_new_python_type(const type_record &rec) { auto &internals = get_internals(); auto bases = tuple(rec.bases); - auto base = (bases.size() == 0) ? internals.instance_base + auto base = (bases.empty()) ? internals.instance_base : bases[0].ptr(); /* Danger zone: from now (and until PyType_Ready), make sure to @@ -616,7 +616,7 @@ inline PyObject* make_new_python_type(const type_record &rec) { type->tp_doc = tp_doc; type->tp_base = type_incref((PyTypeObject *)base); type->tp_basicsize = static_cast(sizeof(instance)); - if (bases.size() > 0) + if (!bases.empty()) type->tp_bases = bases.release().ptr(); /* Don't inherit base __init__ */ diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 7d6530cc80..0986521ac0 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -537,17 +537,17 @@ template class... Predicates> using satisfies_none_of /// Strip the class from a method type template struct remove_class { }; -template struct remove_class { typedef R type(A...); }; -template struct remove_class { typedef R type(A...); }; +template struct remove_class { using type = R (A...); }; +template struct remove_class { using type = R (A...); }; /// Helper template to strip away type modifiers -template struct intrinsic_type { typedef T type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; -template struct intrinsic_type { typedef typename intrinsic_type::type type; }; +template struct intrinsic_type { using type = T; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; +template struct intrinsic_type { using type = typename intrinsic_type::type; }; template using intrinsic_t = typename intrinsic_type::type; /// Helper type to replace 'void' in some expressions @@ -761,7 +761,7 @@ struct nodelete { template void operator()(T*) { } }; PYBIND11_NAMESPACE_BEGIN(detail) template struct overload_cast_impl { - constexpr overload_cast_impl() {} // MSVC 2015 needs this + constexpr overload_cast_impl() {}; // NOLINT(modernize-use-equals-default): MSVC 2015 needs this template constexpr auto operator()(Return (*pf)(Args...)) const noexcept diff --git a/include/pybind11/iostream.h b/include/pybind11/iostream.h index eaf92dfa49..48479f2d17 100644 --- a/include/pybind11/iostream.h +++ b/include/pybind11/iostream.h @@ -30,7 +30,7 @@ class pythonbuf : public std::streambuf { object pywrite; object pyflush; - int overflow(int c) { + int overflow(int c) override { if (!traits_type::eq_int_type(c, traits_type::eof())) { *pptr() = traits_type::to_char_type(c); pbump(1); @@ -38,7 +38,10 @@ class pythonbuf : public std::streambuf { return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof(); } - int sync() { + // This function must be non-virtual to be called in a destructor. If the + // rare MSVC test failure shows up with this version, then this should be + // simplified to a fully qualified call. + int _sync() { if (pbase() != pptr()) { // This subtraction cannot be negative, so dropping the sign str line(pbase(), static_cast(pptr() - pbase())); @@ -54,6 +57,10 @@ class pythonbuf : public std::streambuf { return 0; } + int sync() override { + return _sync(); + } + public: pythonbuf(object pyostream, size_t buffer_size = 1024) @@ -67,8 +74,8 @@ class pythonbuf : public std::streambuf { pythonbuf(pythonbuf&&) = default; /// Sync before destroy - ~pythonbuf() { - sync(); + ~pythonbuf() override { + _sync(); } }; diff --git a/include/pybind11/numpy.h b/include/pybind11/numpy.h index c0b38ce202..4c99aca88a 100644 --- a/include/pybind11/numpy.h +++ b/include/pybind11/numpy.h @@ -281,7 +281,7 @@ template struct is_complex : std::false_type { }; template struct is_complex> : std::true_type { }; template struct array_info_scalar { - typedef T type; + using type = T; static constexpr bool is_array = false; static constexpr bool is_empty = false; static constexpr auto extents = _(""); @@ -1296,7 +1296,7 @@ class common_iterator { m_strides.back() = static_cast(strides.back()); for (size_type i = m_strides.size() - 1; i != 0; --i) { size_type j = i - 1; - value_type s = static_cast(shape[i]); + auto s = static_cast(shape[i]); m_strides[j] = strides[j] + m_strides[i] - strides[i] * s; } } @@ -1539,7 +1539,7 @@ struct vectorize_helper { ssize_t nd = 0; std::vector shape(0); auto trivial = broadcast(buffers, nd, shape); - size_t ndim = (size_t) nd; + auto ndim = (size_t) nd; size_t size = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies()); diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 866a62dc0f..3185d4bd76 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -55,7 +55,7 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object class cpp_function : public function { public: - cpp_function() { } + cpp_function() = default; cpp_function(std::nullptr_t) { } /// Construct a cpp_function from a vanilla function pointer @@ -165,7 +165,7 @@ class cpp_function : public function { /* Get a pointer to the capture object */ auto data = (sizeof(capture) <= sizeof(call.func.data) ? &call.func.data : call.func.data[0]); - capture *cap = const_cast(reinterpret_cast(data)); + auto *cap = const_cast(reinterpret_cast(data)); /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */ return_value_policy policy = return_value_policy_override::policy(call.func.policy); @@ -420,7 +420,7 @@ class cpp_function : public function { } /* Install docstring */ - PyCFunctionObject *func = (PyCFunctionObject *) m_ptr; + auto *func = (PyCFunctionObject *) m_ptr; if (func->m_ml->ml_doc) std::free(const_cast(func->m_ml->ml_doc)); func->m_ml->ml_doc = strdup(signatures.c_str()); @@ -465,7 +465,7 @@ class cpp_function : public function { *it = overloads; /* Need to know how many arguments + keyword arguments there are to pick the right overload */ - const size_t n_args_in = (size_t) PyTuple_GET_SIZE(args_in); + 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, result = PYBIND11_TRY_NEXT_OVERLOAD; @@ -543,7 +543,7 @@ class cpp_function : public function { self_value_and_holder.type->dealloc(self_value_and_holder); call.init_self = PyTuple_GET_ITEM(args_in, 0); - call.args.push_back(reinterpret_cast(&self_value_and_holder)); + call.args.emplace_back(reinterpret_cast(&self_value_and_holder)); call.args_convert.push_back(false); ++args_copied; } @@ -626,7 +626,7 @@ class cpp_function : public function { } // 3. Check everything was consumed (unless we have a kwargs arg) - if (kwargs && kwargs.size() > 0 && !func.has_kwargs) + if (kwargs && !kwargs.empty() && !func.has_kwargs) continue; // Unconsumed kwargs, but no py::kwargs argument to accept them // 4a. If we have a py::args argument, create a new tuple with leftovers @@ -814,7 +814,7 @@ class cpp_function : public function { } if (kwargs_in) { auto kwargs = reinterpret_borrow(kwargs_in); - if (kwargs.size() > 0) { + if (!kwargs.empty()) { if (some_args) msg += "; "; msg += "kwargs: "; bool first = true; @@ -860,7 +860,7 @@ class module : public object { explicit module(const char *name, const char *doc = nullptr) { if (!options::show_user_defined_docstrings()) doc = nullptr; #if PY_MAJOR_VERSION >= 3 - PyModuleDef *def = new PyModuleDef(); + auto *def = new PyModuleDef(); std::memset(def, 0, sizeof(PyModuleDef)); def->m_name = name; def->m_doc = doc; @@ -1020,7 +1020,7 @@ class generic_type : public object { void install_buffer_funcs( buffer_info *(*get_buffer)(PyObject *, void *), void *get_buffer_data) { - PyHeapTypeObject *type = (PyHeapTypeObject*) m_ptr; + auto *type = (PyHeapTypeObject*) m_ptr; auto tinfo = detail::get_type_info(&type->ht_type); if (!type->ht_type.tp_as_buffer) @@ -1242,7 +1242,7 @@ class class_ : public detail::generic_type { template class_& def_buffer(Func &&func) { struct capture { Func func; }; - capture *ptr = new capture { std::forward(func) }; + auto *ptr = new capture { std::forward(func) }; install_buffer_funcs([](PyObject *obj, void *ptr) -> buffer_info* { detail::make_caster caster; if (!caster.load(obj, false)) @@ -1789,7 +1789,7 @@ template ()).first), typename... Extra> iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) { - typedef detail::iterator_state state; + using state = detail::iterator_state; if (!detail::get_type_info(typeid(state), false)) { class_(handle(), "iterator", pybind11::module_local()) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index c1219fc2eb..9563e22f15 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -35,7 +35,7 @@ namespace accessor_policies { struct sequence_item; struct list_item; struct tuple_item; -} +} // namespace accessor_policies using obj_attr_accessor = accessor; using str_attr_accessor = accessor; using item_accessor = accessor; @@ -331,7 +331,7 @@ class error_already_set : public std::runtime_error { error_already_set(const error_already_set &) = default; error_already_set(error_already_set &&) = default; - inline ~error_already_set(); + inline ~error_already_set() override; /// Give the currently-held error back to Python, if any. If there is currently a Python error /// already set it is cleared first. After this call, the current object no longer stores the @@ -976,7 +976,7 @@ inline namespace literals { String literal version of `str` \endrst */ inline str operator"" _s(const char *s, size_t size) { return {s, size}; } -} +} // namespace literals /// \addtogroup pytypes /// @{ @@ -1351,7 +1351,7 @@ class buffer : public object { buffer_info request(bool writable = false) const { int flags = PyBUF_STRIDES | PyBUF_FORMAT; if (writable) flags |= PyBUF_WRITABLE; - Py_buffer *view = new Py_buffer(); + auto *view = new Py_buffer(); if (PyObject_GetBuffer(m_ptr, view, flags) != 0) { delete view; throw error_already_set(); diff --git a/include/pybind11/stl_bind.h b/include/pybind11/stl_bind.h index 47368f0280..9d8ed0c825 100644 --- a/include/pybind11/stl_bind.h +++ b/include/pybind11/stl_bind.h @@ -223,7 +223,7 @@ void vector_modifiers(enable_if_treserve((size_t) slicelength); for (size_t i=0; i> &initializers() { } test_initializer::test_initializer(Initializer init) { - initializers().push_back(init); + initializers().emplace_back(init); } test_initializer::test_initializer(const char *submodule_name, Initializer init) { - initializers().push_back([=](py::module &parent) { + initializers().emplace_back([=](py::module &parent) { auto m = parent.def_submodule(submodule_name); init(m); }); diff --git a/tests/test_class.cpp b/tests/test_class.cpp index e7eaa83eaa..b0e3d3a4b6 100644 --- a/tests/test_class.cpp +++ b/tests/test_class.cpp @@ -103,7 +103,7 @@ TEST_SUBMODULE(class_, m) { BaseClass() = default; BaseClass(const BaseClass &) = default; BaseClass(BaseClass &&) = default; - virtual ~BaseClass() {} + virtual ~BaseClass() = default; }; struct DerivedClass1 : BaseClass { }; struct DerivedClass2 : BaseClass { }; @@ -353,7 +353,7 @@ TEST_SUBMODULE(class_, m) { // test_reentrant_implicit_conversion_failure // #1035: issue with runaway reentrant implicit conversion struct BogusImplicitConversion { - BogusImplicitConversion(const BogusImplicitConversion &) { } + BogusImplicitConversion(const BogusImplicitConversion &) = default; }; py::class_(m, "BogusImplicitConversion") @@ -407,7 +407,7 @@ TEST_SUBMODULE(class_, m) { py::class_(m, "IsNonFinalFinal", py::is_final()); struct PyPrintDestructor { - PyPrintDestructor() {} + PyPrintDestructor() = default; ~PyPrintDestructor() { py::print("Print from destructor"); } @@ -425,14 +425,14 @@ template class BreaksBase { public: }; template class BreaksTramp : public BreaksBase {}; // These should all compile just fine: -typedef py::class_, std::unique_ptr>, BreaksTramp<1>> DoesntBreak1; -typedef py::class_, BreaksTramp<2>, std::unique_ptr>> DoesntBreak2; -typedef py::class_, std::unique_ptr>> DoesntBreak3; -typedef py::class_, BreaksTramp<4>> DoesntBreak4; -typedef py::class_> DoesntBreak5; -typedef py::class_, std::shared_ptr>, BreaksTramp<6>> DoesntBreak6; -typedef py::class_, BreaksTramp<7>, std::shared_ptr>> DoesntBreak7; -typedef py::class_, std::shared_ptr>> DoesntBreak8; +using DoesntBreak1 = py::class_, std::unique_ptr>, BreaksTramp<1>>; +using DoesntBreak2 = py::class_, BreaksTramp<2>, std::unique_ptr>>; +using DoesntBreak3 = py::class_, std::unique_ptr>>; +using DoesntBreak4 = py::class_, BreaksTramp<4>>; +using DoesntBreak5 = py::class_>; +using DoesntBreak6 = py::class_, std::shared_ptr>, BreaksTramp<6>>; +using DoesntBreak7 = py::class_, BreaksTramp<7>, std::shared_ptr>>; +using DoesntBreak8 = py::class_, std::shared_ptr>>; #define CHECK_BASE(N) static_assert(std::is_same>::value, \ "DoesntBreak" #N " has wrong type!") CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8); diff --git a/tests/test_constants_and_functions.cpp b/tests/test_constants_and_functions.cpp index e8ec74b7bc..f607795593 100644 --- a/tests/test_constants_and_functions.cpp +++ b/tests/test_constants_and_functions.cpp @@ -74,7 +74,7 @@ struct C { # pragma GCC diagnostic pop #endif }; -} +} // namespace test_exc_sp TEST_SUBMODULE(constants_and_functions, m) { diff --git a/tests/test_copy_move.cpp b/tests/test_copy_move.cpp index 34f1c618d5..05d5c47677 100644 --- a/tests/test_copy_move.cpp +++ b/tests/test_copy_move.cpp @@ -19,14 +19,14 @@ struct empty { }; struct lacking_copy_ctor : public empty { - lacking_copy_ctor() {} + lacking_copy_ctor() = default; lacking_copy_ctor(const lacking_copy_ctor& other) = delete; }; template <> lacking_copy_ctor empty::instance_ = {}; struct lacking_move_ctor : public empty { - lacking_move_ctor() {} + lacking_move_ctor() = default; lacking_move_ctor(const lacking_move_ctor& other) = delete; lacking_move_ctor(lacking_move_ctor&& other) = delete; }; diff --git a/tests/test_custom_type_casters.cpp b/tests/test_custom_type_casters.cpp index 9485d3cdb2..d565add264 100644 --- a/tests/test_custom_type_casters.cpp +++ b/tests/test_custom_type_casters.cpp @@ -58,7 +58,8 @@ template <> struct type_caster { return py::none().release(); } }; -}} +} // namespace detail +} // namespace pybind11 // test_custom_caster_destruction class DestructionTester { @@ -79,7 +80,8 @@ template <> struct type_caster { return py::bool_(true).release(); } }; -}} +} // namespace detail +} // namespace pybind11 TEST_SUBMODULE(custom_type_casters, m) { // test_custom_type_casters diff --git a/tests/test_exceptions.cpp b/tests/test_exceptions.cpp index 537819d987..6187f2efba 100644 --- a/tests/test_exceptions.cpp +++ b/tests/test_exceptions.cpp @@ -13,7 +13,7 @@ class MyException : public std::exception { public: explicit MyException(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} + const char * what() const noexcept override {return message.c_str();} private: std::string message = ""; }; @@ -22,7 +22,7 @@ class MyException : public std::exception { class MyException2 : public std::exception { public: explicit MyException2(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} + const char * what() const noexcept override {return message.c_str();} private: std::string message = ""; }; @@ -41,7 +41,7 @@ class MyException3 { class MyException4 : public std::exception { public: explicit MyException4(const char * m) : message{m} {} - virtual const char * what() const noexcept override {return message.c_str();} + const char * what() const noexcept override {return message.c_str();} private: std::string message = ""; }; diff --git a/tests/test_factory_constructors.cpp b/tests/test_factory_constructors.cpp index f70ed3335b..dcfabacf36 100644 --- a/tests/test_factory_constructors.cpp +++ b/tests/test_factory_constructors.cpp @@ -58,13 +58,13 @@ class TestFactory4 : public TestFactory3 { public: TestFactory4() : TestFactory3() { print_default_created(this); } TestFactory4(int v) : TestFactory3(v) { print_created(this, v); } - virtual ~TestFactory4() { print_destroyed(this); } + ~TestFactory4() override { print_destroyed(this); } }; // Another class for an invalid downcast test class TestFactory5 : public TestFactory3 { public: TestFactory5(int i) : TestFactory3(i) { print_created(this, i); } - virtual ~TestFactory5() { print_destroyed(this); } + ~TestFactory5() override { print_destroyed(this); } }; class TestFactory6 { @@ -88,8 +88,8 @@ class PyTF6 : public TestFactory6 { PyTF6(PyTF6 &&f) : TestFactory6(std::move(f)) { print_move_created(this); } PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); } PyTF6(std::string s) : TestFactory6((int) s.size()) { alias = true; print_created(this, s); } - virtual ~PyTF6() { print_destroyed(this); } - int get() override { PYBIND11_OVERRIDE(int, TestFactory6, get, /*no args*/); } + ~PyTF6() override { print_destroyed(this); } + int get() override { PYBIND11_OVERLOAD(int, TestFactory6, get, /*no args*/); } }; class TestFactory7 { @@ -109,8 +109,7 @@ class PyTF7 : public TestFactory7 { PyTF7(int i) : TestFactory7(i) { alias = true; print_created(this, i); } PyTF7(PyTF7 &&f) : TestFactory7(std::move(f)) { print_move_created(this); } PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); } - virtual ~PyTF7() { print_destroyed(this); } - int get() override { PYBIND11_OVERRIDE(int, TestFactory7, get, /*no args*/); } + ~PyTF7() override { print_destroyed(this); } }; diff --git a/tests/test_numpy_array.cpp b/tests/test_numpy_array.cpp index caa052549c..33f1d7857c 100644 --- a/tests/test_numpy_array.cpp +++ b/tests/test_numpy_array.cpp @@ -212,7 +212,7 @@ TEST_SUBMODULE(numpy_array, sm) { .def(py::init<>()) .def("numpy_view", [](py::object &obj) { py::print("ArrayClass::numpy_view()"); - ArrayClass &a = obj.cast(); + auto &a = obj.cast(); return py::array_t({2}, {4}, a.data, obj); } ); @@ -362,7 +362,7 @@ TEST_SUBMODULE(numpy_array, sm) { // test_array_resize // reshape array to 2D without changing size sm.def("array_reshape2", [](py::array_t a) { - const ssize_t dim_sz = (ssize_t)std::sqrt(a.size()); + const auto dim_sz = (ssize_t)std::sqrt(a.size()); if (dim_sz * dim_sz != a.size()) throw std::domain_error("array_reshape2: input array total size is not a squared integer"); a.resize({dim_sz, dim_sz}); diff --git a/tests/test_opaque_types.cpp b/tests/test_opaque_types.cpp index 0d20d9a01c..594c45a089 100644 --- a/tests/test_opaque_types.cpp +++ b/tests/test_opaque_types.cpp @@ -60,7 +60,7 @@ TEST_SUBMODULE(opaque_types, m) { m.def("get_null_str_value", [](char *ptr) { return reinterpret_cast(ptr); }); m.def("return_unique_ptr", []() -> std::unique_ptr { - StringList *result = new StringList(); + auto *result = new StringList(); result->push_back("some value"); return std::unique_ptr(result); }); diff --git a/tests/test_operator_overloading.cpp b/tests/test_operator_overloading.cpp index d176c4644b..d55495471a 100644 --- a/tests/test_operator_overloading.cpp +++ b/tests/test_operator_overloading.cpp @@ -73,7 +73,7 @@ namespace std { // Not a good hash function, but easy to test size_t operator()(const Vector2 &) { return 4; } }; -} +} // namespace std // Not a good abs function, but easy to test. std::string abs(const Vector2&) { diff --git a/tests/test_sequences_and_iterators.cpp b/tests/test_sequences_and_iterators.cpp index 1ce0451092..545dc45d08 100644 --- a/tests/test_sequences_and_iterators.cpp +++ b/tests/test_sequences_and_iterators.cpp @@ -200,7 +200,7 @@ TEST_SUBMODULE(sequences_and_iterators, m) { size_t start, stop, step, slicelength; if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) throw py::error_already_set(); - Sequence *seq = new Sequence(slicelength); + auto *seq = new Sequence(slicelength); for (size_t i = 0; i < slicelength; ++i) { (*seq)[i] = s[start]; start += step; } diff --git a/tests/test_smart_ptr.cpp b/tests/test_smart_ptr.cpp index bea90691d4..60c2e692e5 100644 --- a/tests/test_smart_ptr.cpp +++ b/tests/test_smart_ptr.cpp @@ -27,7 +27,8 @@ namespace pybind11 { namespace detail { struct holder_helper> { static const T *get(const ref &p) { return p.get_ptr(); } }; -}} +} // namespace detail +} // namespace pybind11 // The following is not required anymore for std::shared_ptr, but it should compile without error: PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr); @@ -97,9 +98,9 @@ TEST_SUBMODULE(smart_ptr, m) { class MyObject1 : public Object { public: MyObject1(int value) : value(value) { print_created(this, toString()); } - std::string toString() const { return "MyObject1[" + std::to_string(value) + "]"; } + std::string toString() const override { return "MyObject1[" + std::to_string(value) + "]"; } protected: - virtual ~MyObject1() { print_destroyed(this); } + ~MyObject1() override { print_destroyed(this); } private: int value; }; @@ -207,7 +208,7 @@ TEST_SUBMODULE(smart_ptr, m) { class MyObject4b : public MyObject4a { public: MyObject4b(int i) : MyObject4a(i) { print_created(this); } - ~MyObject4b() { print_destroyed(this); } + ~MyObject4b() override { print_destroyed(this); } }; py::class_(m, "MyObject4b") .def(py::init()); @@ -338,7 +339,7 @@ TEST_SUBMODULE(smart_ptr, m) { // test_shared_ptr_gc // #187: issue involving std::shared_ptr<> return value policy & garbage collection struct ElementBase { - virtual ~ElementBase() { } /* Force creation of virtual table */ + virtual ~ElementBase() = default; /* Force creation of virtual table */ ElementBase() = default; ElementBase(const ElementBase&) = delete; }; diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index b230717d2f..0590162770 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp @@ -47,7 +47,7 @@ struct TplCtorClass { namespace std { template <> struct hash { size_t operator()(const TplCtorClass &) const { return 0; } }; -} +} // namespace std template