fork download
  1. #pragma once
  2.  
  3. #include <cstddef>
  4. #include <memory>
  5. #include <type_traits>
  6. #include <cstring>
  7. #include <algorithm>
  8.  
  9. namespace ext
  10. {
  11. template<typename T>
  12. class tvector final
  13. {
  14. static_assert(std::is_trivially_copyable<T>::value,
  15. "Type must be trivially copyable");
  16. public:
  17. using value_type = T;
  18. using size_type = std::size_t;
  19. using difference_type = std::ptrdiff_t;
  20. using reference = value_type&;
  21. using const_reference = const value_type&;
  22. using pointer = value_type*;
  23. using const_pointer = const value_type*;
  24. using iterator = pointer;
  25. using const_iterator = const_pointer;
  26. using reverse_iterator = std::reverse_iterator<iterator>;
  27. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  28.  
  29. tvector()
  30. : mem_(nullptr),
  31. capacity_(1),
  32. size_(0)
  33. {
  34. reallocate();
  35. }
  36.  
  37. explicit
  38. tvector(size_t count, const T& value = T())
  39. : mem_(nullptr),
  40. capacity_(count),
  41. size_(0)
  42. {
  43. reallocate();
  44.  
  45. T* p = mem_;
  46. for(size_t i = 0; i < count; ++i)
  47. *p++ = value;
  48.  
  49. size_ = capacity_;
  50. }
  51.  
  52. template<typename InputIt>
  53. tvector(InputIt first, InputIt last)
  54. : mem_(nullptr)
  55. {
  56. capacity_ = 4;
  57. size_ = 0;
  58.  
  59. reallocate();
  60.  
  61. while(first != last)
  62. push_back(*first++);
  63. }
  64.  
  65. tvector(const tvector& o)
  66. : mem_(nullptr),
  67. size_(o.size_),
  68. capacity_(o.capacity_)
  69. {
  70. mem_ = malloc(size_ * sizeof(T));
  71. memcpy(mem_, o.mem_, size_ * sizeof(T));
  72. }
  73.  
  74. tvector(tvector&& o) noexcept
  75. : mem_(std::move(o.mem_)),
  76. size_(std::move(o.size_)),
  77. capacity_(std::move(o.capacity_))
  78. {
  79. }
  80.  
  81. tvector(std::initializer_list<T> init)
  82. : mem_(nullptr),
  83. size_(0),
  84. capacity_(2)
  85. {
  86. reallocate();
  87.  
  88. for(auto it = init.begin(); it != init.end(); ++it)
  89. push_back(*it);
  90. }
  91.  
  92. ~tvector()
  93. {
  94. free(mem_);
  95.  
  96. mem_ = nullptr;
  97. capacity_ = 0;
  98. size_ = 0;
  99. }
  100.  
  101. tvector& operator=(const tvector& o)
  102. {
  103. if(&o == this)
  104. return *this;
  105.  
  106. this->~tvector();
  107.  
  108. size_ = o.size_;
  109. capacity_ = o.capacity_;
  110.  
  111. mem_ = malloc(size_ * sizeof(T));
  112. memcpy(mem_, o.mem_, size_ * sizeof(T));
  113.  
  114. return *this;
  115. }
  116.  
  117. tvector& operator=(tvector&& o) noexcept
  118. {
  119. if(&o == this)
  120. return *this;
  121.  
  122. this->~tvector();
  123.  
  124. swap(o);
  125.  
  126. return *this;
  127. }
  128.  
  129. tvector& operator=(std::initializer_list<T> ilist)
  130. {
  131. assign(ilist);
  132.  
  133. return *this;
  134. }
  135.  
  136. void assign(size_type count, const T& value)
  137. {
  138. this->~tvector();
  139.  
  140. capacity_ = count;
  141. size_ = capacity_;
  142.  
  143. reallocate();
  144.  
  145. T* p = mem_;
  146. for(size_t i = 0; i < count; ++i)
  147. *p++ = value;
  148. }
  149.  
  150. template<typename InputIt>
  151. void assign(InputIt first, InputIt last)
  152. {
  153. this->~tvector();
  154.  
  155. capacity_ = 4;
  156.  
  157. reallocate();
  158.  
  159. while(first != last)
  160. push_back(*first++);
  161. }
  162.  
  163. void assign(std::initializer_list<T> ilist)
  164. {
  165. this->~tvector();
  166.  
  167. capacity_ = 4;
  168.  
  169. reallocate();
  170.  
  171. for(auto it = ilist.begin(); it != ilist.end(); ++it)
  172. push_back(*it);
  173. }
  174.  
  175. reference at(size_type pos)
  176. {
  177. return mem_[pos];
  178. }
  179.  
  180. const_reference at(size_type pos) const
  181. {
  182. return mem_[pos];
  183. }
  184.  
  185. reference operator[]( size_type pos )
  186. {
  187. return at(pos);
  188. }
  189.  
  190. const_reference operator[](size_type pos) const
  191. {
  192. return at(pos);
  193. }
  194.  
  195. T* data() noexcept { return mem_; }
  196. const T* data() const noexcept { return mem_; }
  197.  
  198. reference front() { return at(0); }
  199. const_reference front() const { return at(0); }
  200.  
  201. reference back() { return at(size_ - 1); }
  202. const_reference back() const { return at(size_ - 1); }
  203.  
  204. iterator begin() noexcept { return mem_; }
  205. const_iterator begin() const noexcept { return mem_; }
  206. const_iterator cbegin() const noexcept { return mem_; };
  207.  
  208. iterator end() noexcept { return mem_ + size_; }
  209. const_iterator end() const noexcept { return mem_ + size_; }
  210. const_iterator cend() const noexcept { return mem_ + size_; };
  211.  
  212. reverse_iterator rbegin() noexcept
  213. {
  214. return std::reverse_iterator<iterator>(end());
  215. }
  216.  
  217. const_reverse_iterator rbegin() const noexcept
  218. {
  219. return std::reverse_iterator<iterator>(end());
  220. }
  221.  
  222. const_reverse_iterator crbegin() const noexcept
  223. {
  224. return std::reverse_iterator<const_iterator>(end());
  225. }
  226.  
  227. reverse_iterator rend() noexcept
  228. {
  229. return std::reverse_iterator<iterator>(begin());
  230. }
  231.  
  232. const_reverse_iterator rend() const noexcept
  233. {
  234. return std::reverse_iterator<iterator>(begin());
  235. }
  236.  
  237. const_reverse_iterator crend() const noexcept
  238. {
  239. return std::reverse_iterator<iterator>(begin());
  240. }
  241.  
  242. bool empty() const noexcept { return size_ == 0; }
  243.  
  244. size_type size() const noexcept { return size_; }
  245.  
  246. void reserve(size_type new_cap)
  247. {
  248. capacity_ = new_cap;
  249. reallocate();
  250. }
  251.  
  252. size_type capacity() const noexcept { return capacity_; }
  253.  
  254. void shrink_to_fit()
  255. {
  256. capacity_ = std::max(size_, size_t(1));
  257. reallocate();
  258. }
  259.  
  260. void clear() noexcept
  261. {
  262. size_ = 0;
  263. }
  264.  
  265. iterator insert(const_iterator pos, const T& value)
  266. {
  267. iterator first = const_cast<iterator>(pos);
  268. iterator last = first + 1;
  269.  
  270. auto p = std::distance(begin(), first);
  271.  
  272. move(first, last, 1);
  273. size_++;
  274.  
  275. mem_[p] = value;
  276.  
  277. return &mem_[p];
  278. }
  279.  
  280. iterator insert(const_iterator pos, T&& value)
  281. {
  282. iterator first = const_cast<iterator>(pos);
  283. iterator last = first + 1;
  284.  
  285. auto p = std::distance(begin(), first);
  286.  
  287. move(first, last, 1);
  288.  
  289. size_++;
  290.  
  291. mem_[p] = std::move(value);
  292.  
  293. return &mem_[p];
  294. }
  295.  
  296. iterator insert(const_iterator pos, size_type count, const T& value)
  297. {
  298. if(count == 0)
  299. return const_cast<iterator>(pos);
  300.  
  301. iterator first = const_cast<iterator>(pos);
  302. iterator last = first + count;
  303.  
  304. auto p = std::distance(begin(), first);
  305.  
  306. move(first, last, count);
  307.  
  308. size_ += count;
  309.  
  310. for(auto i = p; i < count; ++i)
  311. mem_[i] = value;
  312. }
  313.  
  314. template<typename InputIt >
  315. iterator insert(const_iterator pos, InputIt first, InputIt last )
  316. {
  317. if(first == last)
  318. return const_cast<iterator>(pos);
  319.  
  320. auto count = std::distance(first, last);
  321.  
  322. iterator v_first = const_cast<iterator>(pos);
  323. iterator v_last = end();
  324.  
  325. auto p = std::distance(begin(), v_first);
  326.  
  327. move(v_first, v_last, count);
  328.  
  329. size_ += count;
  330.  
  331. auto* mem = &mem_[p];
  332. while(first != last)
  333. *mem++ = *first++;
  334.  
  335. return &mem_[p];
  336. }
  337.  
  338. iterator insert(const_iterator pos, std::initializer_list<T> ilist)
  339. {
  340. return insert(pos, ilist.begin(), ilist.end());
  341. }
  342.  
  343. template<typename... Args>
  344. iterator emplace(const_iterator pos, Args&&... args)
  345. {
  346. iterator first = const_cast<iterator>(pos);
  347. iterator last = end();
  348.  
  349. auto p = std::distance(begin(), first);
  350.  
  351. move(first, last, 1);
  352.  
  353. auto* mem = &mem_[p];
  354.  
  355. auto ptr = new(mem) T(std::forward<Args>(args)...);
  356.  
  357. size_++;
  358.  
  359. return ptr;
  360. }
  361.  
  362. iterator erase(const_iterator pos)
  363. {
  364. iterator first = const_cast<iterator>(pos) + 1;
  365. iterator last = end();
  366.  
  367. if(first == last)
  368. {
  369. size_--;
  370. return end();
  371. }
  372.  
  373. auto p = std::distance(begin(), pos);
  374.  
  375. move(first, last, -1);
  376.  
  377. size_--;
  378.  
  379. return &mem_[p];
  380. }
  381.  
  382. iterator erase(const_iterator first, const_iterator last)
  383. {
  384. auto count = std::distance(first, last);
  385.  
  386. if(last == end())
  387. {
  388. size_ -= count;
  389. return end();
  390. }
  391.  
  392. iterator v_first = const_cast<iterator>(last) - 1;
  393. iterator v_last = end();
  394.  
  395. auto p = std::distance(begin(), last);
  396.  
  397. move(v_first, v_last, -count);
  398.  
  399. size_ -= count;
  400.  
  401. return &mem_[p];
  402. }
  403.  
  404. void push_back(T&& value)
  405. {
  406. _emplace_back(std::move(value));
  407. }
  408.  
  409. void push_back(const T& value)
  410. {
  411. _emplace_back(value);
  412. }
  413.  
  414. template<typename... Args>
  415. reference emplace_back(Args&&... args)
  416. {
  417. return _emplace_back(std::forward<Args>(args)...);
  418. }
  419.  
  420. void pop_back()
  421. {
  422. size_ = size_ != 0 ? size_ - 1 : 0;
  423. }
  424.  
  425. void resize(size_type count)
  426. {
  427. resize(count, T());
  428. }
  429.  
  430. void resize(size_type count, const value_type& value)
  431. {
  432. if(count < capacity_)
  433. size_ = count;
  434. else if(count > capacity_)
  435. {
  436. grow_up(count);
  437.  
  438. T* p = &mem_[size_];
  439. for(size_t i = 0; i < (count - size_); ++i)
  440. *p++ = value;
  441.  
  442. size_ = count;
  443. }
  444. }
  445.  
  446. void swap(tvector& other) noexcept
  447. {
  448. std::swap(mem_, other.mem_);
  449. std::swap(size_, other.size_);
  450. std::swap(capacity_, other.capacity_);
  451. }
  452. private:
  453. void move(iterator first, iterator last, ssize_t to)
  454. {
  455. auto mv_sz = std::distance(first, last);
  456.  
  457. if(to > 0)
  458. {
  459. auto nsz = size_ + to;
  460. grow_up(nsz);
  461. }
  462.  
  463. memmove(first + to, first, mv_sz * sizeof(T));
  464. }
  465.  
  466. void grow_up(size_t new_size)
  467. {
  468. if(new_size < capacity_)
  469. return;
  470.  
  471. while(new_size > capacity_)
  472. capacity_ *= 2;
  473.  
  474. reallocate();
  475. }
  476.  
  477. template<typename... Args>
  478. T& _emplace_back(Args&&... args)
  479. {
  480. if(size_ + 1 > capacity_)
  481. {
  482. capacity_ *= 2;
  483. reallocate();
  484. }
  485.  
  486. T* mem = mem_ + size_;
  487.  
  488. T& ref = *new(mem) T(std::forward<Args>(args)...);
  489.  
  490. size_++;
  491.  
  492. return ref;
  493. }
  494.  
  495. void reallocate()
  496. {
  497. mem_ = (T*)realloc(mem_, capacity_ * sizeof(T));
  498. }
  499.  
  500. private:
  501. T* mem_;
  502. size_t capacity_;
  503. size_t size_;
  504. };
  505.  
  506. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:9: warning: #pragma once in main file
 #pragma once
         ^~~~
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
stdout
Standard output is empty