generic integer type handling
diff --git a/example/example11.ref b/example/example11.ref
index cfcfe41..728e804 100644
--- a/example/example11.ref
+++ b/example/example11.ref
@@ -1,13 +1,3 @@
-Help on built-in function kw_func
-
-kkww__ffuunncc(...)
-    Signature : (x : int32_t, y : int32_t) -> None
-
-Help on built-in function kw_func2
-
-kkww__ffuunncc22(...)
-    Signature : (x : int32_t = 100, y : int32_t = 200) -> None
-
 kw_func(x=5, y=10)
 kw_func(x=5, y=10)
 kw_func(x=5, y=10)
@@ -17,3 +7,13 @@
 kw_func(x=100, y=10)
 kw_func(x=5, y=10)
 kw_func(x=5, y=10)
+Help on built-in function kw_func
+
+kkww__ffuunncc(...) method of builtins.PyCapsule instance
+    Signature : (x : int, y : int) -> None
+
+Help on built-in function kw_func2
+
+kkww__ffuunncc22(...) method of builtins.PyCapsule instance
+    Signature : (x : int = 100, y : int = 200) -> None
+
diff --git a/example/example2.ref b/example/example2.ref
index 64d2afa..a63c3cd 100644
--- a/example/example2.ref
+++ b/example/example2.ref
@@ -1,14 +1,10 @@
-15
-5
-Example2: No constructor defined!
-can't set attribute
-key: key2, value=value2
 key: key, value=value
+key: key2, value=value2
 key: key, value=value
 key: key2, value=value2
 key: key3
-key: key2
 key: key1
+key: key2
 key: key1
 key: key2
 key: key3
@@ -17,105 +13,107 @@
 list item 1: value2
 list item 0: value
 list item 1: value2
+15
+5
+example.Example2: No constructor defined!
+can't set attribute
 This exception was intentionally thrown.
-(u'test', True)
-(5L, u'test', True)
+('test', True)
+(5, 'test', True)
 Help on class Example2 in module example
 
-class EExxaammppllee22(__builtin__.object)
+class EExxaammppllee22(builtins.object)
  |  Example 2 documentation
  |  
  |  Methods defined here:
  |  
- |  ____iinniitt____(...)
- |      x.__init__(...) initializes x; see help(type(x)) for signature
+ |  ____iinniitt____(self, /, *args, **kwargs)
+ |      Initialize self.  See help(type(self)) for accurate signature.
  |  
- |  ggeett__ddiicctt(...)
- |      Signature : (Example2) -> dict
+ |  ____nneeww____ = <built-in method __new__ of example.Example2_meta object>
+ |  ggeett__ddiicctt(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> dict
  |      
  |      Return a Python dictionary
  |  
- |  ggeett__ddiicctt__22(...)
- |      Signature : (Example2) -> dict<str, str>
+ |  ggeett__ddiicctt__22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> dict<str, str>
  |      
  |      Return a C++ dictionary
  |  
- |  ggeett__lliisstt(...)
- |      Signature : (Example2) -> list
+ |  ggeett__lliisstt(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> list
  |      
  |      Return a Python list
  |  
- |  ggeett__lliisstt__22(...)
- |      Signature : (Example2) -> list<str>
+ |  ggeett__lliisstt__22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> list<str>
  |      
  |      Return a C++ list
  |  
- |  ggeett__sseett(...)
- |      Signature : (Example2) -> set
+ |  ggeett__sseett(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> set
  |      
  |      Return a Python set
  |  
- |  ggeett__sseett22(...)
- |      Signature : (Example2) -> set
+ |  ggeett__sseett22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> set
  |      
  |      Return a C++ set
  |  
- |  ppaaiirr__ppaasssstthhrroouugghh(...)
- |      Signature : (Example2, (bool, str)) -> (str, bool)
+ |  nneeww__iinnssttaannccee(...) from builtins.PyCapsule
+ |      Signature : () -> example.Example2
+ |      
+ |      Return an instance
+ |  
+ |  ppaaiirr__ppaasssstthhrroouugghh(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, (bool, str)) -> (str, bool)
  |      
  |      Return a pair in reversed order
  |  
- |  pprriinntt__ddiicctt(...)
- |      Signature : (Example2, dict) -> None
+ |  pprriinntt__ddiicctt(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, dict) -> None
  |      
  |      Print entries of a Python dictionary
  |  
- |  pprriinntt__ddiicctt__22(...)
- |      Signature : (Example2, dict<str, str>) -> None
+ |  pprriinntt__ddiicctt__22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, dict<str, str>) -> None
  |      
  |      Print entries of a C++ dictionary
  |  
- |  pprriinntt__lliisstt(...)
- |      Signature : (Example2, list) -> None
+ |  pprriinntt__lliisstt(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, list) -> None
  |      
  |      Print entries of a Python list
  |  
- |  pprriinntt__lliisstt__22(...)
- |      Signature : (Example2, list<str>) -> None
+ |  pprriinntt__lliisstt__22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, list<str>) -> None
  |      
  |      Print entries of a C++ list
  |  
- |  pprriinntt__sseett(...)
- |      Signature : (Example2, set) -> None
+ |  pprriinntt__sseett(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, set) -> None
  |      
  |      Print entries of a Python set
  |  
- |  pprriinntt__sseett__22(...)
- |      Signature : (Example2, set<str>) -> None
+ |  pprriinntt__sseett__22(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, set<str>) -> None
  |      
  |      Print entries of a C++ set
  |  
- |  tthhrrooww__eexxcceeppttiioonn(...)
- |      Signature : (Example2) -> None
+ |  tthhrrooww__eexxcceeppttiioonn(...) from builtins.PyCapsule
+ |      Signature : (example.Example2) -> None
  |      
  |      Throw an exception
  |  
- |  ttuuppllee__ppaasssstthhrroouugghh(...)
- |      Signature : (Example2, (bool, str, int32_t)) -> (int32_t, str, bool)
+ |  ttuuppllee__ppaasssstthhrroouugghh(...) from builtins.PyCapsule
+ |      Signature : (example.Example2, (bool, str, int)) -> (int, str, bool)
  |      
  |      Return a triple in reversed order
  |  
  |  ----------------------------------------------------------------------
  |  Data and other attributes defined here:
  |  
- |  ____nneeww____ = <built-in method __new__ of Example2_meta object>
- |      T.__new__(S, ...) -> a new object with type S, a subtype of T
- |  
  |  ____ppyybbiinndd1111____ = <capsule object NULL>
- |  
- |  nneeww__iinnssttaannccee = <built-in method new_instance of PyCapsule object>
- |      Signature : () -> Example2
- |      
- |      Return an instance
 
 Destructing Example2
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index 1ed6146..0c7da1a 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -191,7 +191,7 @@
 };
 
 /// Generic type caster for objects stored on the heap
-template <typename type> class type_caster : public type_caster_custom {
+template <typename type, typename Enable = void> class type_caster : public type_caster_custom {
 public:
     static descr name() { return typeid(type); }
 
@@ -229,49 +229,74 @@
         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> { \
-    public: \
-        bool load(PyObject *src, bool) { \
-            py_type py_value = from_type(src); \
-            if ((py_value == (py_type) -1 && PyErr_Occurred()) || \
-                (std::numeric_limits<type>::is_integer && \
-                 sizeof(py_type) != sizeof(type) && \
-                 (py_value < (py_type) std::numeric_limits<type>::min() || \
-                  py_value > (py_type) std::numeric_limits<type>::max()))) { \
-                PyErr_Clear(); \
-                return false; \
-            } \
-            value = (type) py_value; \
-            return true; \
-        } \
-        static PyObject *cast(type src, return_value_policy /* policy */, PyObject * /* parent */) { \
-            return to_pytype((py_type) src); \
-        } \
-        PYBIND11_TYPE_CASTER(type, #type); \
-    };
+template <typename T>
+struct type_caster<
+    T, typename std::enable_if<std::is_integral<T>::value ||
+                               std::is_floating_point<T>::value>::type> {
+    typedef typename std::conditional<sizeof(T) <= sizeof(long), long, long long>::type _py_type_0;
+    typedef typename std::conditional<std::is_signed<T>::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>::type _py_type_1;
+    typedef typename std::conditional<std::is_floating_point<T>::value, double, _py_type_1>::type py_type;
+public:
 
-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, detail::PyLong_AsLongLong, PyLong_FromLongLong)
-PYBIND11_TYPE_CASTER_NUMBER(uint64_t, unsigned PY_LONG_LONG, detail::PyLong_AsUnsignedLongLong, PyLong_FromUnsignedLongLong)
+    bool load(PyObject *src, bool) {
+        py_type py_value;
 
-#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, detail::PyLong_AsLongLong, PyLong_FromLongLong)
-PYBIND11_TYPE_CASTER_NUMBER(size_t, unsigned PY_LONG_LONG, detail::PyLong_AsUnsignedLongLong, PyLong_FromUnsignedLongLong)
-#endif
-#endif
+        if (std::is_floating_point<T>::value) {
+            py_value = (py_type) PyFloat_AsDouble(src);
+        } else if (sizeof(T) <= sizeof(long)) {
+            if (std::is_signed<T>::value)
+                py_value = (py_type) PyLong_AsLong(src);
+            else
+                py_value = (py_type) PyLong_AsUnsignedLong(src);
+        } else {
+            if (std::is_signed<T>::value)
+                py_value = (py_type) detail::PyLong_AsLongLong(src);
+            else
+                py_value = (py_type) detail::PyLong_AsUnsignedLongLong(src);
+        }
 
-PYBIND11_TYPE_CASTER_NUMBER(float, double, PyFloat_AsDouble, PyFloat_FromDouble)
-PYBIND11_TYPE_CASTER_NUMBER(double, double, PyFloat_AsDouble, PyFloat_FromDouble)
+        if ((py_value == (py_type) -1 && PyErr_Occurred()) ||
+            (std::is_integral<T>::value && sizeof(py_type) != sizeof(T) &&
+               (py_value < (py_type) std::numeric_limits<T>::min() ||
+                py_value > (py_type) std::numeric_limits<T>::max()))) {
+            PyErr_Clear();
+            return false;
+        }
+
+        value = (T) py_value;
+        return true;
+    }
+
+    static PyObject *cast(T src, return_value_policy /* policy */, PyObject * /* parent */) {
+        if (std::is_floating_point<T>::value) {
+            return PyFloat_FromDouble((double) src);
+        } else if (sizeof(T) <= sizeof(long)) {
+            if (std::is_signed<T>::value)
+                return PyLong_FromLong((long) src);
+            else
+                return PyLong_FromUnsignedLong((unsigned long) src);
+        } else {
+            if (std::is_signed<T>::value)
+                return PyLong_FromLongLong((long long) src);
+            else
+                return PyLong_FromUnsignedLongLong((unsigned long long) src);
+        }
+    }
+
+    static PyObject *cast(const T *src, return_value_policy policy, PyObject *parent) {
+        return cast(*src, policy, parent);
+    }
+
+    static descr name() {
+        return std::is_floating_point<T>::value ? "float" : "int";
+    }
+
+    operator T*() { return &value; }
+    operator T&() { return value; }
+
+protected:
+    T value;
+};
 
 template <> class type_caster<void_type> {
 public:
diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h
index 12dc773..b7f42dc 100644
--- a/include/pybind11/pytypes.h
+++ b/include/pybind11/pytypes.h
@@ -11,6 +11,7 @@
 
 #include "common.h"
 #include <utility>
+#include <type_traits>
 
 NAMESPACE_BEGIN(pybind11)
 
@@ -213,16 +214,16 @@
 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);
+inline long long PyLong_AsLongLong(PyObject *o) {
+    if (PyInt_Check(o)) /// workaround: PyLong_AsLongLong doesn't accept 'int' on Python 2.x
+        return (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);
+inline unsigned long long PyLong_AsUnsignedLongLong(PyObject *o) {
+    if (PyInt_Check(o)) /// workaround: PyLong_AsUnsignedLongLong doesn't accept 'int' on Python 2.x
+        return (unsigned long long) PyLong_AsUnsignedLong(o);
     else
         return ::PyLong_AsUnsignedLongLong(o);
 }
@@ -291,27 +292,37 @@
 class int_ : public object {
 public:
     PYBIND11_OBJECT_DEFAULT(int_, object, PyLong_Check)
-    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) { }
-    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
-#endif
+    template <typename T,
+              typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+    int_(T value) {
+        if (sizeof(T) <= sizeof(long)) {
+            if (std::is_signed<T>::value)
+                m_ptr = PyLong_FromLong((long) value);
+            else
+                m_ptr = PyLong_FromUnsignedLong((unsigned long) value);
+        } else {
+            if (std::is_signed<T>::value)
+                m_ptr = PyLong_FromLongLong((long long) value);
+            else
+                m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value);
+        }
+    }
+
+    template <typename T,
+              typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+    operator T() const {
+        if (sizeof(T) <= sizeof(long)) {
+            if (std::is_signed<T>::value)
+                return (T) PyLong_AsLong(m_ptr);
+            else
+                return (T) PyLong_AsUnsignedLong(m_ptr);
+        } else {
+            if (std::is_signed<T>::value)
+                return (T) detail::PyLong_AsLongLong(m_ptr);
+            else
+                return (T) detail::PyLong_AsUnsignedLongLong(m_ptr);
+        }
+    }
 };
 
 class float_ : public object {