• Bruce Merry's avatar
    feat: add `.keys` and `.values` to bind_map (#3310) · b3573ac9
    Bruce Merry authored
    
    
    * Add `.keys` and `.values` to bind_map
    
    Both of these implement views (rather than just iterators), and `.items`
    is also upgraded to a view. In practical terms, this allows a view to be
    iterated multiple times and have its size taken, neither of which works
    with an iterator.
    
    The views implement `__len__`, `__iter__`, and the keys view implements
    `__contains__`. Testing membership also works in item and value views
    because Python falls back to iteration. This won't be optimal
    for item values since it's linear rather than O(log n) or O(1), but I
    didn't fancy trying to get all the corner cases to match Python
    behaviour (tuple of wrong types, wrong length tuple, not a tuple etc).
    
    Missing relative to Python dictionary views is `__reversed__` (only
    added to Python in 3.8). Implementing that could break code that binds
    custom map classes which don't provide `rbegin`/`rend` (at least without
    doing clever things with SFINAE), so I've not tried.
    
    The size increase on my system is 131072 bytes, which is rather large
    (5%) but also suspiciously round (2^17) and makes me suspect some
    quantisation effect.
    
    * bind_map: support any object in __contains__
    
    Add extra overload of `__contains__` (for both the map itself and
    KeysView) which takes an arbitrary object and returns false.
    
    * Take py::object by const reference in __contains__
    
    To keep clang-tidy happy.
    
    * Removing stray `py::` (detected via interactive testing in Google environment).
    Co-authored-by: default avatarRalf W. Grosse-Kunstleve <rwgk@google.com>
    b3573ac9
test_stl_binders.py 7.9 KB