• Laramie Leavitt's avatar
    Adjusting `type_caster<std::reference_wrapper<T>>` to support const/non-const... · 5469c238
    Laramie Leavitt authored
    Adjusting `type_caster<std::reference_wrapper<T>>` to support const/non-const propagation in `cast_op`. (#2705)
    
    
    * Allow type_caster of std::reference_wrapper<T> to be the same as a native reference.
    
    Before, both std::reference_wrapper<T> and std::reference_wrapper<const T> would
    invoke cast_op<type>. This doesn't allow the type_caster<> specialization for T
    to distinguish reference_wrapper types from value types.
    
    After, the type_caster<> specialization invokes cast_op<type&>, which allows
    reference_wrapper to behave in the same way as a native reference type.
    
    * Add tests/examples for std::reference_wrapper<const T>
    
    * Add tests which use mutable/immutable variants
    
    This test is a chimera; it blends the pybind11 casters with a custom
    pytype implementation that supports immutable and mutable calls.
    
    In order to detect the immutable/mutable state, the cast_op needs
    to propagate it, even through e.g. std::reference<const T>
    
    Note: This is still a work in progress; some things are crashing,
    which likely means that I have a refcounting bug or something else
    missing.
    
    * Add/finish tests that distinguish const& from &
    
    Fixes the bugs in my custom python type implementation,
    demonstrate test that requires const& and reference_wrapper<const T>
    being treated differently from Non-const.
    
    * Add passing a const to non-const method.
    
    * Demonstrate non-const conversion of reference_wrapper in tests.
    
    Apply formatting presubmit check.
    
    * Fix build errors from presubmit checks.
    
    * Try and fix a few more CI errors
    
    * More CI fixes.
    
    * More CI fixups.
    
    * Try and get PyPy to work.
    
    * Additional minor fixups. Getting close to CI green.
    
    * More ci fixes?
    
    * fix clang-tidy warnings from presubmit
    
    * fix more clang-tidy warnings
    
    * minor comment and consistency cleanups
    
    * PyDECREF -> Py_DECREF
    
    * copy/move constructors
    
    * Resolve codereview comments
    
    * more review comment fixes
    
    * review comments: remove spurious &
    
    * Make the test fail even when the static_assert is commented out.
    
    This expands the test_freezable_type_caster a bit by:
    1/ adding accessors .is_immutable and .addr to compare identity
    from python.
    2/ Changing the default cast_op of the type_caster<> specialization
    to return a non-const value. In normal codepaths this is a reasonable
    default.
    3/ adding roundtrip variants to exercise the by reference, by pointer
    and by reference_wrapper in all call paths.  In conjunction with 2/, this
    demonstrates the failure case of the existing std::reference_wrpper conversion,
    which now loses const in a similar way that happens when using the default cast_op_type<>.
    
    * apply presubmit formatting
    
    * Revert inclusion of test_freezable_type_caster
    
    There's some concern that this test is a bit unwieldly because of the use
    of the raw <Python.h> functions. Removing for now.
    
    * Add a test that validates const references propagation.
    
    This test verifies that cast_op may be used to correctly detect
    const reference types when used with std::reference_wrapper.
    
    * mend
    
    * Review comments based changes.
    
    1. std::add_lvalue_reference<type> -> type&
    2. Simplify the test a little more; we're never returning the ConstRefCaster
    type so the class_ definition can be removed.
    
    * formatted files again.
    
    * Move const_ref_caster test to builtin_casters
    
    * Review comments: use cast_op and adjust some comments.
    
    * Simplify ConstRefCasted test
    
    I like this version better as it moves the assertion that matters
    back into python.
    5469c238
test_builtin_casters.cpp 12.4 KB