diff --git a/ctl/array.h b/ctl/array.h
index a2b5925b5..5e532392f 100644
--- a/ctl/array.h
+++ b/ctl/array.h
@@ -37,24 +37,28 @@ struct array
     constexpr reference at(size_type pos)
     {
         if (pos >= N)
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return elems[pos];
     }
 
     constexpr const_reference at(size_type pos) const
     {
         if (pos >= N)
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return elems[pos];
     }
 
     constexpr reference operator[](size_type pos)
     {
+        if (pos >= N)
+            __builtin_trap();
         return elems[pos];
     }
 
     constexpr const_reference operator[](size_type pos) const
     {
+        if (pos >= N)
+            __builtin_trap();
         return elems[pos];
     }
 
diff --git a/ctl/iterator_traits.h b/ctl/iterator_traits.h
index c08217c76..ecc0fffe0 100644
--- a/ctl/iterator_traits.h
+++ b/ctl/iterator_traits.h
@@ -2,12 +2,33 @@
 // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
 #ifndef CTL_ITERATOR_TRAITS_H_
 #define CTL_ITERATOR_TRAITS_H_
+#include "iterator.h"
 #include "utility.h"
+#include "void_t.h"
 
 namespace ctl {
 
-template<class Iterator>
+template<typename Iterator, typename = void>
 struct iterator_traits
+{};
+
+template<typename T>
+struct iterator_traits<T*>
+{
+    using difference_type = ptrdiff_t;
+    using value_type = T;
+    using pointer = T*;
+    using reference = T&;
+    using iterator_category = ctl::random_access_iterator_tag;
+};
+
+template<typename Iterator>
+struct iterator_traits<Iterator,
+                       ctl::void_t<typename Iterator::iterator_category,
+                                   typename Iterator::value_type,
+                                   typename Iterator::difference_type,
+                                   typename Iterator::pointer,
+                                   typename Iterator::reference>>
 {
     using iterator_category = typename Iterator::iterator_category;
     using value_type = typename Iterator::value_type;
@@ -16,16 +37,6 @@ struct iterator_traits
     using reference = typename Iterator::reference;
 };
 
-template<class T>
-struct iterator_traits<T*>
-{
-    using iterator_category = void*; // We don't actually use this
-    using value_type = T;
-    using difference_type = ptrdiff_t;
-    using pointer = T*;
-    using reference = T&;
-};
-
 } // namespace ctl
 
 #endif // CTL_ITERATOR_TRAITS_H_
diff --git a/ctl/map.h b/ctl/map.h
index a9a6510bb..e3978545e 100644
--- a/ctl/map.h
+++ b/ctl/map.h
@@ -165,7 +165,7 @@ class map
     {
         auto it = find(key);
         if (it == end())
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return it->second;
     }
 
@@ -173,7 +173,7 @@ class map
     {
         auto it = find(key);
         if (it == end())
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return it->second;
     }
 
diff --git a/ctl/require_input_iterator.h b/ctl/require_input_iterator.h
new file mode 100644
index 000000000..221e06a74
--- /dev/null
+++ b/ctl/require_input_iterator.h
@@ -0,0 +1,19 @@
+// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
+// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
+#ifndef CTL_REQUIRE_INPUT_ITERATOR_H_
+#define CTL_REQUIRE_INPUT_ITERATOR_H_
+#include "enable_if.h"
+#include "is_convertible.h"
+#include "iterator.h"
+#include "iterator_traits.h"
+
+namespace ctl {
+
+template<typename InputIt>
+using require_input_iterator = typename ctl::enable_if<
+  ctl::is_convertible<typename ctl::iterator_traits<InputIt>::iterator_category,
+                      ctl::input_iterator_tag>::value>::type;
+
+} // namespace ctl
+
+#endif /* CTL_REQUIRE_INPUT_ITERATOR_H_ */
diff --git a/ctl/vector.h b/ctl/vector.h
index b5837614c..30861e27d 100644
--- a/ctl/vector.h
+++ b/ctl/vector.h
@@ -15,6 +15,7 @@
 #include "move_backward.h"
 #include "move_iterator.h"
 #include "out_of_range.h"
+#include "require_input_iterator.h"
 #include "reverse_iterator.h"
 #include "uninitialized_fill.h"
 #include "uninitialized_fill_n.h"
@@ -65,7 +66,7 @@ class vector
         resize(count);
     }
 
-    template<class InputIt>
+    template<class InputIt, typename = ctl::require_input_iterator<InputIt>>
     vector(InputIt first, InputIt last, const Allocator& alloc = Allocator())
       : alloc_(alloc), data_(nullptr), size_(0), capacity_(0)
     {
@@ -173,7 +174,7 @@ class vector
         size_ = count;
     }
 
-    template<class InputIt>
+    template<class InputIt, typename = ctl::require_input_iterator<InputIt>>
     void assign(InputIt first, InputIt last)
     {
         clear();
@@ -189,24 +190,28 @@ class vector
     reference at(size_type pos)
     {
         if (pos >= size_)
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return data_[pos];
     }
 
     const_reference at(size_type pos) const
     {
         if (pos >= size_)
-            throw ctl::out_of_range("out of range");
+            throw ctl::out_of_range();
         return data_[pos];
     }
 
     reference operator[](size_type pos)
     {
+        if (pos >= size_)
+            __builtin_trap();
         return data_[pos];
     }
 
     const_reference operator[](size_type pos) const
     {
+        if (pos >= size_)
+            __builtin_trap();
         return data_[pos];
     }
 
@@ -368,7 +373,7 @@ class vector
         return it;
     }
 
-    template<class InputIt>
+    template<class InputIt, typename = ctl::require_input_iterator<InputIt>>
     iterator insert(const_iterator pos, InputIt first, InputIt last)
     {
         difference_type count = ctl::distance(first, last);
diff --git a/libc/intrin/describebacktrace.internal.h b/libc/intrin/describebacktrace.internal.h
index 9c116cd25..c9e600d66 100644
--- a/libc/intrin/describebacktrace.internal.h
+++ b/libc/intrin/describebacktrace.internal.h
@@ -1,5 +1,5 @@
-#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_
-#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_
+#ifndef COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_
+#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_
 #include "libc/mem/alloca.h"
 #include "libc/nexgen32e/stackframe.h"
 COSMOPOLITAN_C_START_
@@ -8,4 +8,4 @@ const char *DescribeBacktrace(char[160], const struct StackFrame *) libcesque;
 #define DescribeBacktrace(x) DescribeBacktrace(alloca(160), x)
 
 COSMOPOLITAN_C_END_
-#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_INTERNAL_H_ */
+#endif /* COSMOPOLITAN_LIBC_INTRIN_DESCRIBEBACKTRACE_H_ */
diff --git a/libc/mem/malloc.c b/libc/mem/malloc.c
index c843f2fc8..043a41aac 100644
--- a/libc/mem/malloc.c
+++ b/libc/mem/malloc.c
@@ -42,4 +42,3 @@
 void *malloc(size_t n) {
   return dlmalloc(n);
 }
-
diff --git a/test/ctl/vector_test.cc b/test/ctl/vector_test.cc
index 9e65333c3..84469b2c0 100644
--- a/test/ctl/vector_test.cc
+++ b/test/ctl/vector_test.cc
@@ -352,5 +352,13 @@ main()
             return 80;
     }
 
+    {
+        ctl::vector<int> dog(8, 0);
+        if (dog.size() != 8)
+            return 81;
+        if (dog[0] != 0)
+            return 82;
+    }
+
     CheckForMemoryLeaks();
 }