initial version
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/.vscode
|
||||||
|
/.devcontainer
|
||||||
|
/.github
|
||||||
|
/build
|
||||||
|
/.cache
|
||||||
|
.clang-format
|
5
CMakeLists.txt
Normal file
5
CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
Project(STLite-ACM-2024)
|
||||||
|
include(CTest)
|
||||||
|
add_subdirectory(vector)
|
||||||
|
enable_testing()
|
4
vector/CMakeLists.txt
Normal file
4
vector/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
add_executable(one ${CMAKE_CURRENT_SOURCE_DIR}/data/one/code.cpp)
|
||||||
|
add_test(NAME vector_one COMMAND one >/tmp/one_out.txt
|
||||||
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_out.txt>/tmp/one_diff.txt)
|
@ -5,28 +5,28 @@
|
|||||||
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <exception>
|
||||||
namespace sjtu
|
#include <iterator>
|
||||||
{
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
namespace sjtu {
|
||||||
/**
|
/**
|
||||||
* a data container like std::vector
|
* a data container like std::vector
|
||||||
* store data in a successive memory and support random access.
|
* store data in a successive memory and support random access.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class vector
|
class vector {
|
||||||
{
|
std::allocator<T> alloc;
|
||||||
|
size_t allocated_length;
|
||||||
|
size_t current_length;
|
||||||
|
T *raw_beg, *raw_end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
* a type for actions of the elements of a vector, and you should write
|
|
||||||
* a class named const_iterator with same interfaces.
|
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* you can see RandomAccessIterator at CppReference for help.
|
* you can see RandomAccessIterator at CppReference for help.
|
||||||
*/
|
*/
|
||||||
class const_iterator;
|
class const_iterator;
|
||||||
class iterator
|
class iterator {
|
||||||
{
|
|
||||||
// The following code is written for the C++ type_traits library.
|
// The following code is written for the C++ type_traits library.
|
||||||
// Type traits is a C++ feature for describing certain properties of a type.
|
// Type traits is a C++ feature for describing certain properties of a type.
|
||||||
// For instance, for an iterator, iterator::value_type is the type that the
|
// For instance, for an iterator, iterator::value_type is the type that the
|
||||||
@ -38,189 +38,436 @@ public:
|
|||||||
// https://en.cppreference.com/w/cpp/header/type_traits
|
// https://en.cppreference.com/w/cpp/header/type_traits
|
||||||
// About value_type: https://blog.csdn.net/u014299153/article/details/72419713
|
// About value_type: https://blog.csdn.net/u014299153/article/details/72419713
|
||||||
// About iterator_category: https://en.cppreference.com/w/cpp/iterator
|
// About iterator_category: https://en.cppreference.com/w/cpp/iterator
|
||||||
|
friend class vector<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using pointer = T *;
|
using pointer = T *;
|
||||||
using reference = T &;
|
using reference = T &;
|
||||||
using iterator_category = std::output_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
vector<T> *domain;
|
||||||
* TODO add data members
|
T *raw_pointer;
|
||||||
* just add whatever you want.
|
iterator(vector<T> *domain, T *raw_pointer) : domain(domain), raw_pointer(raw_pointer) {}
|
||||||
*/
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* return a new iterator which pointer n-next elements
|
* return a new iterator which pointer n-next elements
|
||||||
* as well as operator-
|
* as well as operator-
|
||||||
*/
|
*/
|
||||||
iterator operator+(const int &n) const
|
iterator operator+(const int &n) const {
|
||||||
{
|
iterator temp = *this;
|
||||||
//TODO
|
temp.raw_pointer += n;
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
iterator operator-(const int &n) const
|
iterator operator-(const int &n) const {
|
||||||
{
|
iterator temp = *this;
|
||||||
//TODO
|
temp.raw_pointer -= n;
|
||||||
|
return temp;
|
||||||
}
|
}
|
||||||
// return the distance between two iterators,
|
// return the distance between two iterators,
|
||||||
// if these two iterators point to different vectors, throw invaild_iterator.
|
// if these two iterators point to different vectors, throw invaild_iterator.
|
||||||
int operator-(const iterator &rhs) const
|
int operator-(const iterator &rhs) const {
|
||||||
{
|
if (domain != rhs.domain) throw invalid_iterator();
|
||||||
//TODO
|
return raw_pointer - rhs.raw_pointer;
|
||||||
}
|
}
|
||||||
iterator& operator+=(const int &n)
|
iterator &operator+=(const int &n) {
|
||||||
{
|
raw_pointer += n;
|
||||||
//TODO
|
return *this;
|
||||||
}
|
}
|
||||||
iterator& operator-=(const int &n)
|
iterator &operator-=(const int &n) {
|
||||||
{
|
raw_pointer -= n;
|
||||||
//TODO
|
return *this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* TODO iter++
|
* TODO iter++
|
||||||
*/
|
*/
|
||||||
iterator operator++(int) {}
|
iterator operator++(int) {
|
||||||
|
iterator temp = *this;
|
||||||
|
raw_pointer++;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* TODO ++iter
|
* TODO ++iter
|
||||||
*/
|
*/
|
||||||
iterator& operator++() {}
|
iterator &operator++() {
|
||||||
|
raw_pointer++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* TODO iter--
|
* TODO iter--
|
||||||
*/
|
*/
|
||||||
iterator operator--(int) {}
|
iterator operator--(int) {
|
||||||
|
iterator temp = *this;
|
||||||
|
raw_pointer--;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* TODO --iter
|
* TODO --iter
|
||||||
*/
|
*/
|
||||||
iterator& operator--() {}
|
iterator &operator--() {
|
||||||
|
raw_pointer--;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* TODO *it
|
* TODO *it
|
||||||
*/
|
*/
|
||||||
T& operator*() const{}
|
T &operator*() const { return *raw_pointer; }
|
||||||
/**
|
/**
|
||||||
* a operator to check whether two iterators are same (pointing to the same memory address).
|
* a operator to check whether two iterators are same (pointing to the same memory address).
|
||||||
*/
|
*/
|
||||||
bool operator==(const iterator &rhs) const {}
|
bool operator==(const iterator &rhs) const { return raw_pointer == rhs.raw_pointer; }
|
||||||
bool operator==(const const_iterator &rhs) const {}
|
bool operator==(const const_iterator &rhs) const { return raw_pointer == rhs.raw_pointer; }
|
||||||
/**
|
/**
|
||||||
* some other operator for iterator.
|
* some other operator for iterator.
|
||||||
*/
|
*/
|
||||||
bool operator!=(const iterator &rhs) const {}
|
bool operator!=(const iterator &rhs) const { return raw_pointer != rhs.raw_pointer; }
|
||||||
bool operator!=(const const_iterator &rhs) const {}
|
bool operator!=(const const_iterator &rhs) const { return raw_pointer != rhs.raw_pointer; }
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
* has same function as iterator, just for a const object.
|
* has same function as iterator, just for a const object.
|
||||||
*/
|
*/
|
||||||
class const_iterator
|
class const_iterator {
|
||||||
{
|
friend class vector<T>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using pointer = T *;
|
using pointer = T *;
|
||||||
using reference = T &;
|
using reference = T &;
|
||||||
using iterator_category = std::output_iterator_tag;
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*TODO*/
|
const vector<T> *domain;
|
||||||
|
const T *raw_pointer;
|
||||||
|
const_iterator(const vector<T> *domain, const T *raw_pointer) : domain(domain), raw_pointer(raw_pointer) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* return a new iterator which pointer n-next elements
|
||||||
|
* as well as operator-
|
||||||
|
*/
|
||||||
|
const_iterator operator+(const int &n) const {
|
||||||
|
const_iterator temp = *this;
|
||||||
|
temp.raw_pointer += n;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
const_iterator operator-(const int &n) const {
|
||||||
|
const_iterator temp = *this;
|
||||||
|
temp.raw_pointer -= n;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
// return the distance between two iterators,
|
||||||
|
// if these two iterators point to different vectors, throw invaild_iterator.
|
||||||
|
int operator-(const const_iterator &rhs) const {
|
||||||
|
if (domain != rhs.domain) throw invalid_iterator();
|
||||||
|
return raw_pointer - rhs.raw_pointer;
|
||||||
|
}
|
||||||
|
const_iterator &operator+=(const int &n) {
|
||||||
|
raw_pointer += n;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
const_iterator &operator-=(const int &n) {
|
||||||
|
raw_pointer -= n;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO iter++
|
||||||
|
*/
|
||||||
|
const_iterator operator++(int) {
|
||||||
|
const_iterator temp = *this;
|
||||||
|
raw_pointer++;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO ++iter
|
||||||
|
*/
|
||||||
|
const_iterator &operator++() {
|
||||||
|
raw_pointer++;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO iter--
|
||||||
|
*/
|
||||||
|
const_iterator operator--(int) {
|
||||||
|
const_iterator temp = *this;
|
||||||
|
raw_pointer--;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO --iter
|
||||||
|
*/
|
||||||
|
const_iterator &operator--() {
|
||||||
|
raw_pointer--;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* TODO *it
|
||||||
|
*/
|
||||||
|
const T &operator*() const { return *raw_pointer; }
|
||||||
|
/**
|
||||||
|
* a operator to check whether two iterators are same (pointing to the same memory address).
|
||||||
|
*/
|
||||||
|
bool operator==(const iterator &rhs) const { return raw_pointer == rhs.raw_pointer; }
|
||||||
|
bool operator==(const const_iterator &rhs) const { return raw_pointer == rhs.raw_pointer; }
|
||||||
|
/**
|
||||||
|
* some other operator for iterator.
|
||||||
|
*/
|
||||||
|
bool operator!=(const iterator &rhs) const { return raw_pointer != rhs.raw_pointer; }
|
||||||
|
bool operator!=(const const_iterator &rhs) const { return raw_pointer != rhs.raw_pointer; }
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* TODO Constructs
|
* TODO Constructs
|
||||||
* At least two: default constructor, copy constructor
|
* At least two: default constructor, copy constructor
|
||||||
*/
|
*/
|
||||||
vector() {}
|
vector() {
|
||||||
vector(const vector &other) {}
|
raw_beg = alloc.allocate(1);
|
||||||
/**
|
raw_end = raw_beg;
|
||||||
* TODO Destructor
|
allocated_length = 1;
|
||||||
*/
|
current_length = 0;
|
||||||
~vector() {}
|
}
|
||||||
|
vector(const vector &other) {
|
||||||
|
raw_beg = alloc.allocate(other.allocated_length);
|
||||||
|
raw_end = raw_beg + other.current_length;
|
||||||
|
allocated_length = other.allocated_length;
|
||||||
|
current_length = other.current_length;
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.construct(raw_beg + i, other.raw_beg[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector(vector &&other) noexcept {
|
||||||
|
raw_beg = other.raw_beg;
|
||||||
|
raw_end = other.raw_end;
|
||||||
|
allocated_length = other.allocated_length;
|
||||||
|
current_length = other.current_length;
|
||||||
|
other.raw_beg = nullptr;
|
||||||
|
other.raw_end = nullptr;
|
||||||
|
other.allocated_length = 0;
|
||||||
|
other.current_length = 0;
|
||||||
|
}
|
||||||
|
~vector() {
|
||||||
|
if (raw_beg != nullptr) {
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* TODO Assignment operator
|
* TODO Assignment operator
|
||||||
*/
|
*/
|
||||||
vector &operator=(const vector &other) {}
|
vector &operator=(const vector &other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
if (raw_beg != nullptr) {
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
}
|
||||||
|
raw_beg = alloc.allocate(other.allocated_length);
|
||||||
|
raw_end = raw_beg + other.current_length;
|
||||||
|
allocated_length = other.allocated_length;
|
||||||
|
current_length = other.current_length;
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.construct(raw_beg + i, other.raw_beg[i]);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* assigns specified element with bounds checking
|
* assigns specified element with bounds checking
|
||||||
* throw index_out_of_bound if pos is not in [0, size)
|
* throw index_out_of_bound if pos is not in [0, size)
|
||||||
*/
|
*/
|
||||||
T & at(const size_t &pos) {}
|
T &at(const size_t &pos) {
|
||||||
const T & at(const size_t &pos) const {}
|
if (pos < 0 || pos >= current_length) throw index_out_of_bound();
|
||||||
|
return raw_beg[pos];
|
||||||
|
}
|
||||||
|
const T &at(const size_t &pos) const {
|
||||||
|
if (pos < 0 || pos >= current_length) throw index_out_of_bound();
|
||||||
|
return raw_beg[pos];
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* assigns specified element with bounds checking
|
* assigns specified element with bounds checking
|
||||||
* throw index_out_of_bound if pos is not in [0, size)
|
* throw index_out_of_bound if pos is not in [0, size)
|
||||||
* !!! Pay attentions
|
* !!! Pay attentions
|
||||||
* In STL this operator does not check the boundary but I want you to do.
|
* In STL this operator does not check the boundary but I want you to do.
|
||||||
*/
|
*/
|
||||||
T & operator[](const size_t &pos) {}
|
T &operator[](const size_t &pos) {
|
||||||
const T & operator[](const size_t &pos) const {}
|
if (pos < 0 || pos >= current_length) throw index_out_of_bound();
|
||||||
|
return raw_beg[pos];
|
||||||
|
}
|
||||||
|
const T &operator[](const size_t &pos) const {
|
||||||
|
if (pos < 0 || pos >= current_length) throw index_out_of_bound();
|
||||||
|
return raw_beg[pos];
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* access the first element.
|
* access the first element.
|
||||||
* throw container_is_empty if size == 0
|
* throw container_is_empty if size == 0
|
||||||
*/
|
*/
|
||||||
const T & front() const {}
|
const T &front() const {
|
||||||
|
if (current_length == 0) throw container_is_empty();
|
||||||
|
return raw_beg[0];
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* access the last element.
|
* access the last element.
|
||||||
* throw container_is_empty if size == 0
|
* throw container_is_empty if size == 0
|
||||||
*/
|
*/
|
||||||
const T & back() const {}
|
const T &back() const {
|
||||||
|
if (current_length == 0) throw container_is_empty();
|
||||||
|
return raw_end[-1];
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* returns an iterator to the beginning.
|
* returns an iterator to the beginning.
|
||||||
*/
|
*/
|
||||||
iterator begin() {}
|
iterator begin() { return iterator(this, raw_beg); }
|
||||||
const_iterator cbegin() const {}
|
const_iterator cbegin() const { return const_iterator(this, raw_beg); }
|
||||||
/**
|
/**
|
||||||
* returns an iterator to the end.
|
* returns an iterator to the end.
|
||||||
*/
|
*/
|
||||||
iterator end() {}
|
iterator end() { return iterator(this, raw_end); }
|
||||||
const_iterator cend() const {}
|
const_iterator cend() const { return const_iterator(this, raw_end); }
|
||||||
/**
|
/**
|
||||||
* checks whether the container is empty
|
* checks whether the container is empty
|
||||||
*/
|
*/
|
||||||
bool empty() const {}
|
bool empty() const { return current_length == 0; }
|
||||||
/**
|
/**
|
||||||
* returns the number of elements
|
* returns the number of elements
|
||||||
*/
|
*/
|
||||||
size_t size() const {}
|
size_t size() const { return current_length; }
|
||||||
/**
|
/**
|
||||||
* clears the contents
|
* clears the contents
|
||||||
*/
|
*/
|
||||||
void clear() {}
|
void clear() {
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
current_length = 0;
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
raw_beg = alloc.allocate(1);
|
||||||
|
raw_end = raw_beg;
|
||||||
|
allocated_length = 1;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* inserts value before pos
|
* inserts value before pos
|
||||||
* returns an iterator pointing to the inserted value.
|
* returns an iterator pointing to the inserted value.
|
||||||
*/
|
*/
|
||||||
iterator insert(iterator pos, const T &value) {}
|
iterator insert(iterator pos, const T &value) {
|
||||||
|
if (pos.raw_pointer < raw_beg || pos.raw_pointer > raw_end) throw invalid_iterator();
|
||||||
|
if (current_length == allocated_length) {
|
||||||
|
size_t new_allocated_length = allocated_length * 2;
|
||||||
|
T *new_raw_beg = alloc.allocate(new_allocated_length);
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.construct(new_raw_beg + i, std::move(raw_beg[i]));
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
raw_beg = new_raw_beg;
|
||||||
|
raw_end = raw_beg + current_length;
|
||||||
|
allocated_length = new_allocated_length;
|
||||||
|
}
|
||||||
|
for (T *i = raw_end; i != pos.raw_pointer; --i) {
|
||||||
|
alloc.construct(i, std::move(*(i - 1)));
|
||||||
|
alloc.destroy(i - 1);
|
||||||
|
}
|
||||||
|
alloc.construct(pos.raw_pointer, value);
|
||||||
|
raw_end++;
|
||||||
|
current_length++;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* inserts value at index ind.
|
* inserts value at index ind.
|
||||||
* after inserting, this->at(ind) == value
|
* after inserting, this->at(ind) == value
|
||||||
* returns an iterator pointing to the inserted value.
|
* returns an iterator pointing to the inserted value.
|
||||||
* throw index_out_of_bound if ind > size (in this situation ind can be size because after inserting the size will increase 1.)
|
* throw index_out_of_bound if ind > size (in this situation ind can be size because after inserting the size will
|
||||||
|
* increase 1.)
|
||||||
*/
|
*/
|
||||||
iterator insert(const size_t &ind, const T &value) {}
|
iterator insert(const size_t &ind, const T &value) {
|
||||||
|
if (ind < 0 || ind > current_length) throw index_out_of_bound();
|
||||||
|
if (current_length == allocated_length) {
|
||||||
|
size_t new_allocated_length = allocated_length * 2;
|
||||||
|
T *new_raw_beg = alloc.allocate(new_allocated_length);
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.construct(new_raw_beg + i, std::move(raw_beg[i]));
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
raw_beg = new_raw_beg;
|
||||||
|
raw_end = raw_beg + current_length;
|
||||||
|
allocated_length = new_allocated_length;
|
||||||
|
}
|
||||||
|
for (T *i = raw_end; i != raw_beg + ind; --i) {
|
||||||
|
alloc.construct(i, std::move(*(i - 1)));
|
||||||
|
alloc.destroy(i - 1);
|
||||||
|
}
|
||||||
|
alloc.construct(raw_beg + ind, value);
|
||||||
|
raw_end++;
|
||||||
|
current_length++;
|
||||||
|
return iterator(this, raw_beg + ind);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* removes the element at pos.
|
* removes the element at pos.
|
||||||
* return an iterator pointing to the following element.
|
* return an iterator pointing to the following element.
|
||||||
* If the iterator pos refers the last element, the end() iterator is returned.
|
* If the iterator pos refers the last element, the end() iterator is returned.
|
||||||
*/
|
*/
|
||||||
iterator erase(iterator pos) {}
|
iterator erase(iterator pos) {
|
||||||
|
if (pos.raw_pointer < raw_beg || pos.raw_pointer >= raw_end) throw invalid_iterator();
|
||||||
|
for (T *i = pos.raw_pointer; i != raw_end - 1; ++i) {
|
||||||
|
alloc.construct(i, std::move(*(i + 1)));
|
||||||
|
alloc.destroy(i + 1);
|
||||||
|
}
|
||||||
|
raw_end--;
|
||||||
|
current_length--;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* removes the element with index ind.
|
* removes the element with index ind.
|
||||||
* return an iterator pointing to the following element.
|
* return an iterator pointing to the following element.
|
||||||
* throw index_out_of_bound if ind >= size
|
* throw index_out_of_bound if ind >= size
|
||||||
*/
|
*/
|
||||||
iterator erase(const size_t &ind) {}
|
iterator erase(const size_t &ind) {
|
||||||
|
if (ind < 0 || ind >= current_length) throw index_out_of_bound();
|
||||||
|
for (T *i = raw_beg + ind; i != raw_end - 1; ++i) {
|
||||||
|
alloc.construct(i, std::move(*(i + 1)));
|
||||||
|
alloc.destroy(i + 1);
|
||||||
|
}
|
||||||
|
raw_end--;
|
||||||
|
current_length--;
|
||||||
|
return iterator(this, raw_beg + ind);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* adds an element to the end.
|
* adds an element to the end.
|
||||||
*/
|
*/
|
||||||
void push_back(const T &value) {}
|
void push_back(const T &value) {
|
||||||
|
if (current_length == allocated_length) {
|
||||||
|
size_t new_allocated_length = allocated_length * 2;
|
||||||
|
T *new_raw_beg = alloc.allocate(new_allocated_length);
|
||||||
|
for (size_t i = 0; i < current_length; ++i) {
|
||||||
|
alloc.construct(new_raw_beg + i, std::move(raw_beg[i]));
|
||||||
|
alloc.destroy(raw_beg + i);
|
||||||
|
}
|
||||||
|
alloc.deallocate(raw_beg, allocated_length);
|
||||||
|
raw_beg = new_raw_beg;
|
||||||
|
raw_end = raw_beg + current_length;
|
||||||
|
allocated_length = new_allocated_length;
|
||||||
|
}
|
||||||
|
alloc.construct(raw_end, value);
|
||||||
|
raw_end++;
|
||||||
|
current_length++;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* remove the last element from the end.
|
* remove the last element from the end.
|
||||||
* throw container_is_empty if size() == 0
|
* throw container_is_empty if size() == 0
|
||||||
*/
|
*/
|
||||||
void pop_back() {}
|
void pop_back() {
|
||||||
|
if (current_length == 0) throw container_is_empty();
|
||||||
|
alloc.destroy(raw_end - 1);
|
||||||
|
raw_end--;
|
||||||
|
current_length--;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace sjtu
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user