fork download
  1. #include <iostream>
  2. #include <initializer_list>
  3. #include <memory>
  4.  
  5. using namespace std;
  6.  
  7. struct out_of_range { /* . . . */ }; // class used to report range access errors
  8.  
  9. /*
  10.  
  11. template<typename T, typename A>
  12. class vector;
  13.  
  14. template<typename T, typename A>
  15. class Range_checked_iterator // bad design?
  16. {
  17.   private:
  18.   typename vector<T, A>::iterator pos;
  19.   public:
  20.   Range_checked_iterator(vector<T, A>::iterator arg) : pos{arg} { }
  21.  
  22.   char& operator*() { return *pos; }
  23.   Range_checked_iterator& operator++();
  24.  
  25.   bool operator==(const Range_checked_iterator& other) const
  26.   { return pos == other.pos; }
  27.   bool operator!=(const Range_checked_iterator& other) const
  28.   { return !(*this==other); }
  29. };
  30.  
  31. // namespace std definitions here
  32.  
  33. template <typename T, typename A>
  34. Range_checked_iterator& Range_checked_iterator<T,A>::operator++()
  35. {
  36.   // if (pos == )
  37.   // if pos is equal to the end() of the vector
  38. }
  39. */
  40.  
  41. template<typename T, typename A = allocator<T>>
  42. class vector {
  43. /*
  44.   invariant:
  45.   if 0<=n<sz, elem[n] is element n
  46.   sz<=space;
  47.   if sz<space there is space for (space–sz) doubles after elem[sz–1]
  48. */
  49. A alloc;
  50. int sz; // the size
  51. T* elem; // pointer to the elements (or 0)
  52. int space; // number of elements plus number of free slots
  53. public:
  54. vector() : sz{0}, elem{nullptr}, space{0} { }
  55.  
  56. vector(const vector&); // copy constructor
  57. vector& operator=(const vector&); // copy assignment
  58.  
  59. vector(vector&&); // move constructor
  60. vector& operator=(vector&&); // move assignment
  61.  
  62. ~vector() { delete[] elem; } // destructor
  63.  
  64. T& at(int n); // checked access
  65. const T& at(int n) const; // checked access
  66.  
  67. T& operator[ ](int n) { return elem[n]; } // access: return reference
  68. const T& operator[](int n) const { return elem[n]; }
  69.  
  70. int size() const { return sz; }
  71. int capacity() const { return space; }
  72.  
  73. void resize(int newsize, T def = T()); // growth
  74. void push_back(const T& val);
  75. void reserve(int newalloc);
  76.  
  77. vector(initializer_list<double> lst) // initializer-list constructor
  78. :sz{lst.size()}, elem{new T[sz]} // uninitialized memory
  79. // for elements
  80. {
  81. copy( lst.begin(),lst.end(),elem); // initialize (using std::copy(); §B.5.2)
  82. }
  83.  
  84. //---------------------20.5 code---------------------------
  85.  
  86. using size_type = unsigned long;
  87. using value_type = T;
  88. using iterator = T*;
  89. using const_iterator = const T*;
  90.  
  91. //--------------------------------
  92.  
  93. /*
  94.   iterator operator++()
  95.   {
  96.   // this doesn't get executed
  97.   if (this == (elem + sz - 1)) // *this doesn't work either
  98.   {
  99.   cout << "This is the last index. Can't go any further." << endl;
  100.   }
  101.   return *this;
  102.   }
  103.   */
  104.  
  105. //--------------------------------
  106.  
  107. iterator begin()
  108. {
  109. return elem;
  110. }
  111. const_iterator begin() const;
  112. iterator end()
  113. {
  114. return elem + sz;
  115. }
  116. const_iterator end() const;
  117. vector& back()
  118. {
  119. return elem + sz - 1;
  120. }
  121. const vector& back() const;
  122. // size_type size();
  123.  
  124. //---------------------20.5 code---------------------------
  125.  
  126. //---------------------20.8 code---------------------------
  127.  
  128. // using iterator = T*; // T* is the simplest possible iterator
  129. // I declared this above line on line 54.
  130.  
  131. iterator insert(iterator p, const T& val);
  132. iterator erase(iterator p);
  133.  
  134. //---------------------20.8 code---------------------------
  135.  
  136. };
  137.  
  138. template <typename Elem>
  139. class vector<Elem>::iterator {
  140. Elem* el;
  141. public:
  142. operator * () { return *el; }
  143. iterator operator++()
  144. {
  145. // this doesn't get executed
  146. if (this == (elem + sz - 1)) // *this doesn't work either
  147. {
  148. cout << "This is the last index. Can't go any further." << endl;
  149. }
  150. return *this;
  151. }
  152. };
  153.  
  154. //---------------------20.8 code--------------------------
  155.  
  156. /*
  157.  
  158. template<typename T, typename A> // requires Element<T>() &&
  159.   // Allocator<A>() (§19.3.3)
  160. typename vector<T,A>::iterator vector<T,A>::erase(iterator p)
  161. {
  162.   if (p==end()) return p;
  163.   for (auto pos = p+1; pos!=end(); ++pos)
  164.   *(pos-1) = *pos; // copy element “one position to the left”
  165.   alloc.destroy(&*(end()-1)); // destroy surplus copy of last element
  166.   --sz;
  167.   return p;
  168. }
  169.  
  170. template<typename T, typename A> // requires Element<T>() &&
  171.   // Allocator<A>() (§19.3.3)
  172. typename vector<T,A>::iterator vector<T,A>::insert(iterator p, const T& val)
  173. {
  174.   int index = p-begin();
  175.   if (size()==capacity())
  176.   reserve(size()==0?8:2*size()); // make sure we have space
  177.  
  178.   // first copy last element into uninitialized space:
  179.   alloc.construct(elem+sz,*back());
  180.  
  181.   ++sz;
  182.   iterator pp = begin()+index; // the place to put val
  183.   for (auto pos = end()-1; pos!=pp; --pos)
  184.   *pos = *(pos-1); // copy elements one position to the right
  185.   *(begin()+index) = val; // “insert” val
  186.   return pp;
  187. }
  188.  
  189. */
  190.  
  191. //---------------------20.8 code--------------------------
  192.  
  193. template<typename T, typename A > T& vector<T,A>::at(int n)
  194. {
  195. if (n<0 || sz<=n) throw ::out_of_range();
  196. return elem[n];
  197. }
  198.  
  199. template<typename T, typename A>
  200. vector<T, A>::vector(const vector& arg)
  201. // allocate elements, then initialize them by copying
  202. :sz{arg.sz}, elem{new T[arg.sz]}
  203. {
  204. copy(arg,arg+sz,elem); // std::copy(); see §B.5.2
  205. }
  206.  
  207. template<typename T, typename A>
  208. vector<T, A>& vector<T, A>::operator=(const vector& a)
  209. {
  210. if (this==&a) return *this; // self-assignment, no work needed
  211.  
  212. if (a.sz<=space) { // enough space, no need for new allocation
  213. for (int i = 0; i<a.sz; ++i) elem[i] = a.elem[i]; // copy elements
  214. sz = a.sz;
  215. return *this;
  216. }
  217.  
  218. T* p = new T[a.sz]; // allocate new space
  219. for (int i = 0; i<a.sz; ++i) p[i] = a.elem[i]; // copy elements
  220. delete[] elem; // deallocate old space
  221. space = sz = a.sz; // set new size
  222. elem = p; // set new elements
  223. return *this; // return a self-reference
  224. }
  225.  
  226. template<typename T, typename A>
  227. vector<T,A>::vector(vector&& a)
  228. :sz{a.sz}, elem{a.elem} // copy a’s elem and sz
  229. {
  230. a.sz = 0; // make a the empty vector
  231. a.elem = nullptr;
  232. }
  233.  
  234. template<typename T, typename A>
  235. vector<T, A>& vector<T, A>::operator=(vector&& a) // move a to this vector
  236. {
  237. delete[] elem; // deallocate old space
  238. elem = a.elem; // copy a’s elem and sz
  239. sz = a.sz;
  240. a.elem = nullptr; // make a the empty vector
  241. a.sz = 0;
  242. return *this; // return a self-reference (see §17.10)
  243. }
  244.  
  245. template<typename T, typename A>
  246. void vector<T,A>::reserve(int newalloc)
  247. {
  248. if (newalloc<=space) return; // never decrease allocation
  249. T* p = alloc.allocate(newalloc); // allocate new space
  250. for (int i=0; i<sz; ++i) alloc.construct(&p[i],elem[i]); // copy
  251. for (int i=0; i<sz; ++i) alloc.destroy(&elem[i]); // destroy
  252. alloc.deallocate(elem,space); // deallocate old space
  253. elem = p;
  254. space = newalloc;
  255. }
  256.  
  257. template<typename T, typename A>
  258. void vector<T,A>::resize(int newsize, T val)
  259. {
  260. reserve(newsize);
  261. for (int i=sz; i<newsize; ++i) alloc.construct(&elem[i],val); // construct
  262. for (int i = newsize; i<sz; ++i) alloc.destroy(&elem[i]); // destroy
  263. sz = newsize;
  264. }
  265.  
  266. template<typename T, typename A>
  267. void vector<T,A>::push_back(const T& val)
  268. {
  269. if (space==0) reserve(8); // start with space for 8 elements
  270. else if (sz==space) reserve(2*space); // get more space
  271. alloc.construct(&elem[sz],val); // add val at end
  272. ++sz; // increase the size
  273. }
  274.  
  275. int main()
  276. {
  277. vector<int> v{1, 2, 3, 4, 5};
  278. for (int i = 0; i < v.size(); i++)
  279. {
  280. cout << v[i] << endl;
  281. }
  282. v.push_back(6);
  283. vector<int>::iterator it = v.begin();
  284. for (; it != v.end(); it++)
  285. {
  286. cout << *it << endl;
  287. }
  288. cout << "---------------------------------------------" << endl;
  289. ++it;
  290. cout << *it << endl;
  291. ++it;
  292. cout << *it << endl;
  293. ++it;
  294. cout << *it << endl;
  295. ++it;
  296. cout << *it << endl;
  297. ++it;
  298. cout << *it << endl;
  299. return 0;
  300. }
  301.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:139:21: error: invalid class name in declaration of ‘class vector<Elem>::iterator’
 class vector<Elem>::iterator {
                     ^~~~~~~~
prog.cpp: In instantiation of ‘vector<T, A>::vector(std::initializer_list<double>) [with T = int; A = std::allocator<int>]’:
prog.cpp:277:32:   required from here
prog.cpp:78:33: warning: narrowing conversion of ‘lst.std::initializer_list<_E>::size<double>()’ from ‘std::initializer_list<double>::size_type {aka long unsigned int}’ to ‘int’ inside { } [-Wnarrowing]
                     :sz{lst.size()}, elem{new T[sz]}   // uninitialized memory
                         ~~~~~~~~^~
stdout
Standard output is empty