Add support custom sized operator deletes (#952)

If a class doesn't provide a `T::operator delete(void *)` but does have
a `T::operator delete(void *, size_t)` the latter is invoked by a
`delete someT`.  Pybind currently only look for and call the former;
this commit adds detection and calling of the latter when the former
doesn't exist.
diff --git a/tests/test_class.py b/tests/test_class.py
index 611a287..9236400 100644
--- a/tests/test_class.py
+++ b/tests/test_class.py
@@ -127,3 +127,55 @@
     assert m.implicitly_convert_variable(UserType(5)) == 5
 
     assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5))
+
+
+def test_operator_new_delete(capture):
+    """Tests that class-specific operator new/delete functions are invoked"""
+
+    class SubAliased(m.AliasedHasOpNewDelSize):
+        pass
+
+    with capture:
+        a = m.HasOpNewDel()
+        b = m.HasOpNewDelSize()
+        d = m.HasOpNewDelBoth()
+    assert capture == """
+        A new 8
+        A placement-new 8
+        B new 4
+        B placement-new 4
+        D new 32
+        D placement-new 32
+    """
+    sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)
+    sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)
+    with capture:
+        c = m.AliasedHasOpNewDelSize()
+        c2 = SubAliased()
+    assert capture == (
+        "C new " + sz_alias + "\nC placement-new " + sz_noalias + "\n" +
+        "C new " + sz_alias + "\nC placement-new " + sz_alias + "\n"
+    )
+
+    with capture:
+        del a
+        ConstructorStats.detail_reg_inst()
+        del b
+        ConstructorStats.detail_reg_inst()
+        del d
+        ConstructorStats.detail_reg_inst()
+    assert capture == """
+        A delete
+        B delete 4
+        D delete
+    """
+
+    with capture:
+        del c
+        ConstructorStats.detail_reg_inst()
+        del c2
+        ConstructorStats.detail_reg_inst()
+    assert capture == (
+        "C delete " + sz_noalias + "\n" +
+        "C delete " + sz_alias + "\n"
+    )