1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <vector>
11
12// template <class InputIter> vector(InputIter first, InputIter last,
13//                                   const allocator_type& a);
14
15#include <vector>
16#include <cassert>
17#include <cstddef>
18
19#include "test_macros.h"
20#include "test_iterators.h"
21#include "test_allocator.h"
22#include "min_allocator.h"
23#include "asan_testing.h"
24#if TEST_STD_VER >= 11
25#include "emplace_constructible.h"
26#include "container_test_types.h"
27#endif
28
29template <class C, class Iterator, class A>
30void test(Iterator first, Iterator last, const A& a) {
31  C c(first, last, a);
32  LIBCPP_ASSERT(c.__invariants());
33  assert(c.size() == static_cast<std::size_t>(std::distance(first, last)));
34  LIBCPP_ASSERT(is_contiguous_container_asan_correct(c));
35  for (typename C::const_iterator i = c.cbegin(), e = c.cend(); i != e;
36       ++i, ++first)
37    assert(*i == *first);
38}
39
40#if TEST_STD_VER >= 11
41
42template <class T>
43struct implicit_conv_allocator : min_allocator<T> {
44  implicit_conv_allocator(void*) {}
45  implicit_conv_allocator(const implicit_conv_allocator&) = default;
46
47  template <class U>
48  implicit_conv_allocator(implicit_conv_allocator<U>) {}
49};
50
51#endif
52
53void basic_tests() {
54  {
55    int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
56    int* an = a + sizeof(a) / sizeof(a[0]);
57    std::allocator<int> alloc;
58    test<std::vector<int> >(input_iterator<const int*>(a),
59                            input_iterator<const int*>(an), alloc);
60    test<std::vector<int> >(forward_iterator<const int*>(a),
61                            forward_iterator<const int*>(an), alloc);
62    test<std::vector<int> >(bidirectional_iterator<const int*>(a),
63                            bidirectional_iterator<const int*>(an), alloc);
64    test<std::vector<int> >(random_access_iterator<const int*>(a),
65                            random_access_iterator<const int*>(an), alloc);
66    test<std::vector<int> >(a, an, alloc);
67  }
68#if TEST_STD_VER >= 11
69  {
70    int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 1, 0};
71    int* an = a + sizeof(a) / sizeof(a[0]);
72    min_allocator<int> alloc;
73    test<std::vector<int, min_allocator<int> > >(
74        input_iterator<const int*>(a), input_iterator<const int*>(an), alloc);
75    test<std::vector<int, min_allocator<int> > >(
76        forward_iterator<const int*>(a), forward_iterator<const int*>(an),
77        alloc);
78    test<std::vector<int, min_allocator<int> > >(
79        bidirectional_iterator<const int*>(a),
80        bidirectional_iterator<const int*>(an), alloc);
81    test<std::vector<int, min_allocator<int> > >(
82        random_access_iterator<const int*>(a),
83        random_access_iterator<const int*>(an), alloc);
84    test<std::vector<int, min_allocator<int> > >(a, an, alloc);
85    test<std::vector<int, implicit_conv_allocator<int> > >(a, an, nullptr);
86  }
87#endif
88}
89
90void emplaceable_concept_tests() {
91#if TEST_STD_VER >= 11
92  int arr1[] = {42};
93  int arr2[] = {1, 101, 42};
94  {
95    using T = EmplaceConstructible<int>;
96    using It = forward_iterator<int*>;
97    using Alloc = std::allocator<T>;
98    Alloc a;
99    {
100      std::vector<T> v(It(arr1), It(std::end(arr1)), a);
101      assert(v[0].value == 42);
102    }
103    {
104      std::vector<T> v(It(arr2), It(std::end(arr2)), a);
105      assert(v[0].value == 1);
106      assert(v[1].value == 101);
107      assert(v[2].value == 42);
108    }
109  }
110  {
111    using T = EmplaceConstructibleAndMoveInsertable<int>;
112    using It = input_iterator<int*>;
113    using Alloc = std::allocator<T>;
114    Alloc a;
115    {
116      std::vector<T> v(It(arr1), It(std::end(arr1)), a);
117      assert(v[0].copied == 0);
118      assert(v[0].value == 42);
119    }
120    {
121      std::vector<T> v(It(arr2), It(std::end(arr2)), a);
122      assert(v[0].value == 1);
123      assert(v[1].value == 101);
124      assert(v[2].copied == 0);
125      assert(v[2].value == 42);
126    }
127  }
128#endif
129}
130
131void test_ctor_under_alloc() {
132#if TEST_STD_VER >= 11
133  int arr1[] = {42};
134  int arr2[] = {1, 101, 42};
135  {
136    using C = TCT::vector<>;
137    using T = typename C::value_type;
138    using It = forward_iterator<int*>;
139    using Alloc = typename C::allocator_type;
140    Alloc a;
141    {
142      ExpectConstructGuard<int&> G(1);
143      C v(It(arr1), It(std::end(arr1)), a);
144    }
145    {
146      ExpectConstructGuard<int&> G(3);
147      C v(It(arr2), It(std::end(arr2)), a);
148    }
149  }
150  {
151    using C = TCT::vector<>;
152    using T = typename C::value_type;
153    using It = input_iterator<int*>;
154    using Alloc = typename C::allocator_type;
155    Alloc a;
156    {
157      ExpectConstructGuard<int&> G(1);
158      C v(It(arr1), It(std::end(arr1)), a);
159    }
160    {
161      //ExpectConstructGuard<int&> G(3);
162      //C v(It(arr2), It(std::end(arr2)), a);
163    }
164  }
165#endif
166}
167
168int main() {
169  basic_tests();
170  emplaceable_concept_tests(); // See PR34898
171  test_ctor_under_alloc();
172}
173