improved int_ constructor
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 5792fab..1ed6146 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -227,7 +227,7 @@
             return cast(*src, policy, parent); \
         } \
         operator type*() { return &value; } \
-        operator type&() { return value; } \
+        operator type&() { return value; }
 
 #define PYBIND11_TYPE_CASTER_NUMBER(type, py_type, from_type, to_pytype) \
     template <> class type_caster<type> { \
@@ -251,41 +251,22 @@
         PYBIND11_TYPE_CASTER(type, #type); \
     };
 
-#if PY_MAJOR_VERSION >= 3
-#define PyLong_AsUnsignedLongLong_Fixed PyLong_AsUnsignedLongLong
-#define PyLong_AsLongLong_Fixed PyLong_AsLongLong
-#else
-inline PY_LONG_LONG PyLong_AsLongLong_Fixed(PyObject *o) {
-    if (PyInt_Check(o))
-        return (PY_LONG_LONG) PyLong_AsLong(o);
-    else
-        return ::PyLong_AsLongLong(o);
-}
-
-inline unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong_Fixed(PyObject *o) {
-    if (PyInt_Check(o))
-        return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLong(o);
-    else
-        return ::PyLong_AsUnsignedLongLong(o);
-}
-#endif
-
 PYBIND11_TYPE_CASTER_NUMBER(int8_t, long, PyLong_AsLong, PyLong_FromLong)
 PYBIND11_TYPE_CASTER_NUMBER(uint8_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
 PYBIND11_TYPE_CASTER_NUMBER(int16_t, long, PyLong_AsLong, PyLong_FromLong)
 PYBIND11_TYPE_CASTER_NUMBER(uint16_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
 PYBIND11_TYPE_CASTER_NUMBER(int32_t, long, PyLong_AsLong, PyLong_FromLong)
 PYBIND11_TYPE_CASTER_NUMBER(uint32_t, unsigned long, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong)
-PYBIND11_TYPE_CASTER_NUMBER(int64_t, PY_LONG_LONG, PyLong_AsLongLong_Fixed, PyLong_FromLongLong)
-PYBIND11_TYPE_CASTER_NUMBER(uint64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong_Fixed, PyLong_FromUnsignedLongLong)
+PYBIND11_TYPE_CASTER_NUMBER(int64_t, PY_LONG_LONG, detail::PyLong_AsLongLong, PyLong_FromLongLong)
+PYBIND11_TYPE_CASTER_NUMBER(uint64_t, unsigned PY_LONG_LONG, detail::PyLong_AsUnsignedLongLong, PyLong_FromUnsignedLongLong)
 
 #if defined(__APPLE__) // size_t/ssize_t are separate types on Mac OS X
 #if PY_MAJOR_VERSION >= 3
 PYBIND11_TYPE_CASTER_NUMBER(ssize_t, Py_ssize_t, PyLong_AsSsize_t, PyLong_FromSsize_t)
 PYBIND11_TYPE_CASTER_NUMBER(size_t, size_t, PyLong_AsSize_t, PyLong_FromSize_t)
 #else
-PYBIND11_TYPE_CASTER_NUMBER(ssize_t, PY_LONG_LONG, PyLong_AsLongLong_Fixed, PyLong_FromLongLong)
-PYBIND11_TYPE_CASTER_NUMBER(size_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong_Fixed, PyLong_FromUnsignedLongLong)
+PYBIND11_TYPE_CASTER_NUMBER(ssize_t, PY_LONG_LONG, detail::PyLong_AsLongLong, PyLong_FromLongLong)
+PYBIND11_TYPE_CASTER_NUMBER(size_t, unsigned PY_LONG_LONG, detail::PyLong_AsUnsignedLongLong, PyLong_FromUnsignedLongLong)
 #endif
 #endif
 
diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h
index 48e3d1f..12dc773 100644
--- a/include/pybind11/pytypes.h
+++ b/include/pybind11/pytypes.h
@@ -208,6 +208,26 @@
     PyObject *dict, *key, *value;
     ssize_t pos = 0;
 };
+
+#if PY_MAJOR_VERSION >= 3
+using ::PyLong_AsUnsignedLongLong;
+using ::PyLong_AsLongLong;
+#else
+inline PY_LONG_LONG PyLong_AsLongLong(PyObject *o) {
+    if (PyInt_Check(o))
+        return (PY_LONG_LONG) PyLong_AsLong(o);
+    else
+        return ::PyLong_AsLongLong(o);
+}
+
+inline unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *o) {
+    if (PyInt_Check(o))
+        return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLong(o);
+    else
+        return ::PyLong_AsUnsignedLongLong(o);
+}
+#endif
+
 NAMESPACE_END(detail)
 
 inline detail::accessor handle::operator[](handle key) { return detail::accessor(ptr(), key.ptr(), false); }
@@ -271,12 +291,27 @@
 class int_ : public object {
 public:
     PYBIND11_OBJECT_DEFAULT(int_, object, PyLong_Check)
-    int_(int value) : object(PyLong_FromLong((long) value), false) { }
+    int_(int32_t value) : object(PyLong_FromLong((long) value), false) { }
+    int_(int64_t value) : object(PyLong_FromLongLong((long long) value), false) { }
+    int_(uint32_t value) : object(PyLong_FromUnsignedLong((unsigned long) value), false) { }
+    int_(uint64_t value) : object(PyLong_FromUnsignedLongLong((unsigned long long) value), false) { }
+    operator int32_t() const { return (int32_t) PyLong_AsLong(m_ptr); }
+    operator uint32_t() const { return (uint32_t) PyLong_AsUnsignedLong(m_ptr); }
+    operator int64_t() const { return (int64_t) detail::PyLong_AsLongLong(m_ptr); }
+    operator uint64_t() const { return (uint64_t) detail::PyLong_AsUnsignedLongLong(m_ptr); }
+#if defined(__APPLE__) // size_t/ssize_t are separate types on Mac OS X
+#if PY_MAJOR_VERSION >= 3
     int_(size_t value) : object(PyLong_FromSize_t(value), false) { }
-#if !(defined(_WIN32) || defined(__i386__)) || defined(_WIN64)
     int_(ssize_t value) : object(PyLong_FromSsize_t(value), false) { }
+    operator size_t() const { return (size_t) PyLong_AsSize_t(m_ptr); }
+    operator ssize_t() const { return (ssize_t) PyLong_AsSsize_t(m_ptr); }
+#else
+    int_(size_t value) : object(PyLong_FromUnsignedLongLong((unsigned long long) value), false) { }
+    int_(ssize_t value) : object(PyLong_FromLongLong((long long) value), false) { }
+    operator size_t() const { return (size_t) detail::PyLong_AsUnsignedLongLong(m_ptr); }
+    operator ssize_t() const { return (ssize_t) detail::PyLong_AsLongLong(m_ptr); }
 #endif
-    operator int() const { return (int) PyLong_AsLong(m_ptr); }
+#endif
 };
 
 class float_ : public object {