Enable detection of private operator new on MSVC

MSVC 2015 Update 3 and 2017 can handle enough expression SFINAE
to make this work now.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 0226a6e..3934971 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -492,23 +492,12 @@
 
 protected:
     typedef void *(*Constructor)(const void *stream);
-#if !defined(_MSC_VER)
     /* Only enabled when the types are {copy,move}-constructible *and* when the type
        does not have a private operator new implementaton. */
     template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) {
         return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; }
     template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) {
         return [](const void *arg) -> void * { return (void *) new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg)))); }; }
-#else
-    /* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations.
-       Use a workaround that only tests for constructibility for now. */
-    template <typename T = type, typename = enable_if_t<is_copy_constructible<T>::value>>
-    static Constructor make_copy_constructor(const T *value) {
-        return [](const void *arg) -> void * { return new T(*((const T *)arg)); }; }
-    template <typename T = type, typename = enable_if_t<std::is_move_constructible<T>::value>>
-    static Constructor make_move_constructor(const T *value) {
-        return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *)arg))); }; }
-#endif
 
     static Constructor make_copy_constructor(...) { return nullptr; }
     static Constructor make_move_constructor(...) { return nullptr; }
diff --git a/tests/test_copy_move.cpp b/tests/test_copy_move.cpp
index 898fc39..90ca6da 100644
--- a/tests/test_copy_move.cpp
+++ b/tests/test_copy_move.cpp
@@ -98,6 +98,12 @@
 };
 }}
 
+struct PrivateOpNew {
+    int value = 1;
+
+private:
+    void *operator new(size_t bytes);
+};
 
 test_initializer copy_move_policies([](py::module &m) {
     py::class_<lacking_copy_ctor>(m, "lacking_copy_ctor")
@@ -174,4 +180,11 @@
     m.attr("has_optional") = false;
 #endif
 
+    // #70 compilation issue if operator new is not public
+    py::class_<PrivateOpNew>(m, "PrivateOpNew").def_readonly("value", &PrivateOpNew::value);
+    m.def("private_op_new_value", []() { return PrivateOpNew(); });
+    m.def("private_op_new_reference", []() -> const PrivateOpNew & {
+        static PrivateOpNew x{};
+        return x;
+    }, py::return_value_policy::reference);
 });
diff --git a/tests/test_copy_move.py b/tests/test_copy_move.py
index d6479c5..386fce7 100644
--- a/tests/test_copy_move.py
+++ b/tests/test_copy_move.py
@@ -98,3 +98,14 @@
     assert c_c.copy_assignments == 2
     assert c_c.copy_constructions == 5
     assert c_m.alive() + c_mc.alive() + c_c.alive() == 0
+
+
+def test_private_op_new():
+    """An object with a private `operator new` cannot be returned by value"""
+    import pybind11_tests as m
+
+    with pytest.raises(RuntimeError) as excinfo:
+        m.private_op_new_value()
+    assert "the object is neither movable nor copyable" in str(excinfo.value)
+
+    assert m.private_op_new_reference().value == 1
diff --git a/tests/test_issues.cpp b/tests/test_issues.cpp
index cab9ddf..6d88d9a 100644
--- a/tests/test_issues.cpp
+++ b/tests/test_issues.cpp
@@ -77,16 +77,6 @@
 void init_issues(py::module &m) {
     py::module m2 = m.def_submodule("issues");
 
-#if !defined(_MSC_VER)
-    // Visual Studio 2015 currently cannot compile this test
-    // (see the comment in type_caster_base::make_copy_constructor)
-    // #70 compilation issue if operator new is not public
-    class NonConstructible { private: void *operator new(size_t bytes) throw(); };
-    py::class_<NonConstructible>(m, "Foo");
-    m2.def("getstmt", []() -> NonConstructible * { return nullptr; },
-        py::return_value_policy::reference);
-#endif
-
     // #137: const char* isn't handled properly
     m2.def("print_cchar", [](const char *s) { return std::string(s); });