diff --git a/ctl/array.h b/ctl/array.h index a2b5925b57e..5e532392fa4 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 c08217c769c..ecc0fffe095 100644 --- a/ctl/iterator_traits.h +++ b/ctl/iterator_traits.h @@ -2,28 +2,39 @@ // 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 +template struct iterator_traits -{ - using iterator_category = typename Iterator::iterator_category; - using value_type = typename Iterator::value_type; - using difference_type = typename Iterator::difference_type; - using pointer = typename Iterator::pointer; - using reference = typename Iterator::reference; -}; +{}; -template +template struct iterator_traits { - using iterator_category = void*; // We don't actually use this - using value_type = 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 +struct iterator_traits> +{ + using iterator_category = typename Iterator::iterator_category; + using value_type = typename Iterator::value_type; + using difference_type = typename Iterator::difference_type; + using pointer = typename Iterator::pointer; + using reference = typename Iterator::reference; }; } // namespace ctl diff --git a/ctl/map.h b/ctl/map.h index a9a6510bbaf..e3978545e02 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 00000000000..221e06a745d --- /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 +using require_input_iterator = typename ctl::enable_if< + ctl::is_convertible::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 b5837614c97..30861e27d02 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 + template> 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 + template> 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 + template> 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 9c116cd259b..c9e600d6617 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 c843f2fc827..043a41aac13 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 9e65333c319..84469b2c0ee 100644 --- a/test/ctl/vector_test.cc +++ b/test/ctl/vector_test.cc @@ -352,5 +352,13 @@ main() return 80; } + { + ctl::vector dog(8, 0); + if (dog.size() != 8) + return 81; + if (dog[0] != 0) + return 82; + } + CheckForMemoryLeaks(); }