adding stl_binders
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38297db..24dd8cb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,6 +128,7 @@
   example/example14.cpp
   example/example15.cpp
   example/example16.cpp
+  example/example17.cpp
   example/issues.cpp
 )
 
diff --git a/example/example.cpp b/example/example.cpp
index b4199e8..470684a 100644
--- a/example/example.cpp
+++ b/example/example.cpp
@@ -25,6 +25,7 @@
 void init_ex14(py::module &);
 void init_ex15(py::module &);
 void init_ex16(py::module &);
+void init_ex17(py::module &);
 void init_issues(py::module &);
 
 #if defined(PYBIND11_TEST_EIGEN)
@@ -50,6 +51,7 @@
     init_ex14(m);
     init_ex15(m);
     init_ex16(m);
+    init_ex17(m);
     init_issues(m);
 
     #if defined(PYBIND11_TEST_EIGEN)
diff --git a/example/example17.cpp b/example/example17.cpp
new file mode 100644
index 0000000..8c30457
--- /dev/null
+++ b/example/example17.cpp
@@ -0,0 +1,27 @@
+/*
+    example/example17.cpp -- Usade of stl_binders functions
+
+    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
+
+    All rights reserved. Use of this source code is governed by a
+    BSD-style license that can be found in the LICENSE file.
+*/
+
+#include "example.h"
+
+#include <pybind11/stl_binders.h>
+
+class A
+{
+public:
+	A() = delete;
+};
+
+void init_ex17(py::module &m)
+{
+	pybind11::class_<A>(m, "A");
+
+    py::vector_binder<int>(m, "VectorInt");
+
+    py::vector_binder<A>(m, "VectorA");
+}
diff --git a/example/example17.py b/example/example17.py
new file mode 100644
index 0000000..5385280
--- /dev/null
+++ b/example/example17.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+from __future__ import print_function
+
+from example import VectorInt, VectorA
+
+v_int = VectorInt(2)
+print( v_int.size() )
+
+print( bool(v_int) )
+
+v_int2 = VectorInt(2)
+print( v_int == v_int2 )
+
+v_int2[1] = 1
+print( v_int != v_int2 )
+
+v_int2.push_back(2)
+v_int2.push_back(3)
+print(v_int2)
+
+v_a = VectorA()
diff --git a/example/example17.ref b/example/example17.ref
new file mode 100644
index 0000000..09489f1
--- /dev/null
+++ b/example/example17.ref
@@ -0,0 +1,5 @@
+2
+True
+True
+True
+VectorInt[0, 1, 2, 3]
diff --git a/include/pybind11/stl_binders.h b/include/pybind11/stl_binders.h
new file mode 100644
index 0000000..4dbd0b6
--- /dev/null
+++ b/include/pybind11/stl_binders.h
@@ -0,0 +1,184 @@
+/*
+    pybind11/std_binders.h: Convenience wrapper functions for STL containers with C++ like interface
+
+    Copyright (c) 2016 Sergey Lyskov
+
+    All rights reserved. Use of this source code is governed by a
+    BSD-style license that can be found in the LICENSE file.
+*/
+
+#ifndef _INCLUDED_std_binders_h_
+#define _INCLUDED_std_binders_h_
+
+#include "common.h"
+#include "operators.h"
+
+#include <type_traits>
+#include <utility>
+#include <algorithm>
+#include <sstream>
+
+
+NAMESPACE_BEGIN(pybind11)
+
+template<typename T>
+constexpr auto has_equal_operator(int) -> decltype( std::declval<T>() == std::declval<T>(), bool()) { return true; }
+template<typename T>
+constexpr bool has_equal_operator(...) { return false; }
+
+
+
+template<typename T>
+constexpr auto has_not_equal_operator(int) -> decltype( std::declval<T>() != std::declval<T>(), bool()) { return true; }
+template<typename T>
+constexpr bool has_not_equal_operator(...) { return false; }
+
+
+
+namespace has_insertion_operator_implementation {
+enum class False {};
+struct any_type {
+    template<typename T> any_type( T const& );
+};
+False operator<<( std::ostream const&, any_type const& );
+}
+template<typename T>
+constexpr bool has_insertion_operator()
+{
+	using namespace has_insertion_operator_implementation;
+	return std::is_same< decltype( std::declval<std::ostringstream&>() << std::declval<T>() ), std::ostream & >::value;
+}
+
+
+template <typename T, typename Allocator = std::allocator<T>, typename holder_type = std::unique_ptr< std::vector<T, Allocator> > >
+class vector_binder
+{
+	using Vector = std::vector<T, Allocator>;
+	using SizeType = typename Vector::size_type;
+
+	using Class_ = pybind11::class_<Vector, holder_type >;
+
+	// template<typename U = T, typename std::enable_if< std::is_constructible<U>{} >::type * = nullptr>
+	// void maybe_constructible(Class_ &cl) {
+	// 	cl.def(pybind11::init<>());
+	// }
+	// template<typename U = T, typename std::enable_if< !std::is_constructible<U>{} >::type * = nullptr>
+	// void maybe_constructible(Class_ &cl) {}
+
+	template<typename U = T, typename std::enable_if< std::is_default_constructible<U>{} >::type * = nullptr>
+	void maybe_default_constructible(Class_ &cl) {
+		cl.def(pybind11::init<SizeType>());
+		cl.def("resize", (void (Vector::*)(SizeType count)) &Vector::resize, "changes the number of elements stored");
+	}
+	template<typename U = T, typename std::enable_if< !std::is_default_constructible<U>{} >::type * = nullptr>
+	void maybe_default_constructible(Class_ &) {}
+
+
+	template<typename U = T, typename std::enable_if< std::is_copy_constructible<U>{} >::type * = nullptr>
+	void maybe_copy_constructible(Class_ &cl) {
+		cl.def(pybind11::init< Vector const &>());
+	}
+	template<typename U = T, typename std::enable_if< !std::is_copy_constructible<U>{} >::type * = nullptr>
+	void vector_bind_maybe_copy_constructible(Class_ &) {}
+
+
+	template<typename U = T, typename std::enable_if< has_equal_operator<U>(0) >::type * = nullptr>
+	void maybe_has_equal_operator(Class_ &cl) {
+	    cl.def(pybind11::self == pybind11::self);
+	    cl.def(pybind11::self != pybind11::self);
+
+		cl.def("count", [](Vector const &v, T const & value) { return std::count(v.begin(), v.end(), value); }, "counts the elements that are equal to value");
+	}
+	template<typename U = T, typename std::enable_if< !has_equal_operator<U>(0) >::type * = nullptr>
+	void maybe_has_equal_operator(Class_ &) {}
+
+
+	template<typename U = T, typename std::enable_if< has_not_equal_operator<U>(0) >::type * = nullptr>
+	void maybe_has_not_equal_operator(Class_ &cl) {
+	    cl.def(pybind11::self != pybind11::self);
+	}
+	template<typename U = T, typename std::enable_if< !has_not_equal_operator<U>(0) >::type * = nullptr>
+	void maybe_has_not_equal_operator(Class_ &) {}
+
+
+	template<typename U = T, typename std::enable_if< has_insertion_operator<U>() >::type * = nullptr>
+	void maybe_has_insertion_operator(Class_ &cl, std::string name) {
+		cl.def("__repr__", [name](typename vector_binder<T>::Vector &v) {
+				std::ostringstream s;
+				s << name << '[';
+				for(uint i=0; i<v.size(); ++i) {
+					s << v[i];
+					if( i != v.size() -1 ) s << ", ";
+				}
+				s << ']';
+				return s.str();
+			});
+
+	}
+	template<typename U = T, typename std::enable_if< !has_insertion_operator<U>() >::type * = nullptr>
+	void maybe_has_insertion_operator(Class_ &, char const *) {}
+
+
+
+
+public:
+	vector_binder(pybind11::module &m, char const *name) {
+		Class_ cl(m, name);
+
+		cl.def(pybind11::init<>());
+
+		//maybe_constructible(cl);
+		maybe_default_constructible(cl);
+		maybe_copy_constructible(cl);
+
+		// Capacity
+		cl.def("empty",         &Vector::empty,         "checks whether the container is empty");
+		cl.def("size",          &Vector::size,          "returns the number of elements");
+		cl.def("max_size",      &Vector::max_size,      "returns the maximum possible number of elements");
+		cl.def("reserve",       &Vector::reserve,       "reserves storage");
+		cl.def("capacity",      &Vector::capacity,      "returns the number of elements that can be held in currently allocated storage");
+		cl.def("shrink_to_fit", &Vector::shrink_to_fit, "reduces memory usage by freeing unused memory");
+
+		// Modifiers
+		cl.def("clear",                                     &Vector::clear,     "clears the contents");
+		cl.def("push_back",    (void (Vector::*)(const T&)) &Vector::push_back, "adds an element to the end");
+		cl.def("pop_back",                                  &Vector::pop_back,  "removes the last element");
+		cl.def("swap",                                      &Vector::swap,      "swaps the contents");
+
+		cl.def("erase", [](Vector &v, SizeType i) {
+			if (i >= v.size()) throw pybind11::index_error();
+			v.erase( v.begin() + i );
+		}, "erases element at index");
+
+		// Python friendly bindings
+		#ifdef PYTHON_ABI_VERSION // Python 3+
+			cl.def("__bool__",    [](Vector &v) -> bool { return v.size(); }); // checks whether the container has any elements in it
+		#else
+			cl.def("__nonzero__", [](Vector &v) -> bool { return v.size(); }); // checks whether the container has any elements in it
+		#endif
+
+		cl.def("__getitem__", [](Vector const &v, SizeType i) {
+			if (i >= v.size()) throw pybind11::index_error();
+			return v[i];
+		});
+
+		cl.def("__setitem__", [](Vector &v, SizeType i, T const & t) {
+            if (i >= v.size()) throw pybind11::index_error();
+            v[i] = t;
+		});
+
+		cl.def("__len__", &Vector::size);
+
+		// Comparisons
+		maybe_has_equal_operator(cl);
+		maybe_has_not_equal_operator(cl);
+
+		// Printing
+		maybe_has_insertion_operator(cl, name);
+	}
+};
+
+
+NAMESPACE_END(pybind11)
+
+#endif // _INCLUDED_std_binders_h_