完成vector容器
This commit is contained in:
106
TinySTL/Vector.h
106
TinySTL/Vector.h
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _VECTOR_H_
|
#ifndef _VECTOR_H_
|
||||||
#define _VECTOR_H_
|
#define _VECTOR_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <algorithm>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Allocator.h"
|
#include "Allocator.h"
|
||||||
@@ -11,7 +13,7 @@ namespace TinySTL{
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template<class T>
|
template<class T>
|
||||||
class viter: public iterator<random_access_iterator<T, ptrdiff_t>, T>{
|
class viter : public TinySTL::iterator<TinySTL::random_access_iterator_tag, T>{
|
||||||
private:
|
private:
|
||||||
T * ptr_;
|
T * ptr_;
|
||||||
private:
|
private:
|
||||||
@@ -22,6 +24,8 @@ namespace TinySTL{
|
|||||||
viter(const viter& vit);
|
viter(const viter& vit);
|
||||||
viter& operator = (const viter& vit);
|
viter& operator = (const viter& vit);
|
||||||
|
|
||||||
|
operator void* (){ return ptr_; }//change to the primitive pointer type
|
||||||
|
|
||||||
T& operator *(){ return *ptr_; }
|
T& operator *(){ return *ptr_; }
|
||||||
T *operator ->(){ return &(operator *()); }
|
T *operator ->(){ return &(operator *()); }
|
||||||
|
|
||||||
@@ -69,6 +73,7 @@ namespace TinySTL{
|
|||||||
}
|
}
|
||||||
}// end of anonymous namespace
|
}// end of anonymous namespace
|
||||||
|
|
||||||
|
//********* vector *************
|
||||||
template<class T, class Alloc = allocator<T>>
|
template<class T, class Alloc = allocator<T>>
|
||||||
class vector{
|
class vector{
|
||||||
private:
|
private:
|
||||||
@@ -79,12 +84,12 @@ namespace TinySTL{
|
|||||||
typedef Alloc dataAllocator;
|
typedef Alloc dataAllocator;
|
||||||
//Alloc dataAllocator;
|
//Alloc dataAllocator;
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
typedef viter<T> iterator;
|
typedef viter<T> iterator;
|
||||||
typedef iterator pointer;
|
typedef iterator pointer;
|
||||||
typedef T& reference;
|
typedef T& reference;
|
||||||
typedef size_t size_type;
|
typedef size_t size_type;
|
||||||
typedef typename iterator::difference_type difference_type;
|
typedef typename iterator::difference_type difference_type;
|
||||||
public:
|
public:
|
||||||
//<2F><><EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD><D8BA><EFBFBD>
|
//<2F><><EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD><D8BA><EFBFBD>
|
||||||
vector()
|
vector()
|
||||||
@@ -97,8 +102,7 @@ namespace TinySTL{
|
|||||||
vector(vector&& v);
|
vector(vector&& v);
|
||||||
vector& operator = (const vector& v);
|
vector& operator = (const vector& v);
|
||||||
~vector(){
|
~vector(){
|
||||||
dataAllocator::destroy(start_, finish_);
|
destroyAndDeallocateAll();
|
||||||
dataAllocator::deallocate(start_, endOfStorage_ - start_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
@@ -129,26 +133,27 @@ namespace TinySTL{
|
|||||||
std::swap(endOfStorage_, v.endOfStorage_);
|
std::swap(endOfStorage_, v.endOfStorage_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO
|
|
||||||
void push_back(const value_type& value);
|
void push_back(const value_type& value);
|
||||||
void pop_back(){
|
void pop_back(){
|
||||||
--finish_;
|
--finish_;
|
||||||
dataAllocator::destroy(finish_);
|
dataAllocator::destroy(finish_);
|
||||||
}
|
}
|
||||||
//TODO
|
|
||||||
iterator insert(iterator position, const value_type& val);
|
iterator insert(iterator position, const value_type& val);
|
||||||
//TODO
|
void insert(iterator position, const size_type& n, const value_type& val);
|
||||||
void insert(iterator position, size_type n, const value_type& val);
|
|
||||||
//TODO
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
void insert(iterator position, InputIterator first, InputIterator last);
|
void insert(iterator position, InputIterator first, InputIterator last);
|
||||||
//TODO
|
|
||||||
iterator erase(iterator position);
|
iterator erase(iterator position);
|
||||||
iterator erase(iterator first, iterator last);
|
iterator erase(iterator first, iterator last);
|
||||||
|
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ŀռ<C4BF><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>Ŀռ<C4BF><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
Alloc get_allocator(){ return dataAllocator; }
|
Alloc get_allocator(){ return dataAllocator; }
|
||||||
private:
|
private:
|
||||||
|
void destroyAndDeallocateAll(){
|
||||||
|
if (capacity() != 0){
|
||||||
|
dataAllocator::destroy(start_, finish_);
|
||||||
|
dataAllocator::deallocate(start_, endOfStorage_ - start_);
|
||||||
|
}
|
||||||
|
}
|
||||||
void allocateAndFillN(const size_type n, const value_type& value){
|
void allocateAndFillN(const size_type n, const value_type& value){
|
||||||
start_ = dataAllocator::allocate(n);
|
start_ = dataAllocator::allocate(n);
|
||||||
TinySTL::uninitialized_fill_n(start_, n, value);
|
TinySTL::uninitialized_fill_n(start_, n, value);
|
||||||
@@ -169,7 +174,15 @@ namespace TinySTL{
|
|||||||
void vector_aux(Integer n, Integer value, std::true_type){
|
void vector_aux(Integer n, Integer value, std::true_type){
|
||||||
allocateAndFillN(n, value);
|
allocateAndFillN(n, value);
|
||||||
}
|
}
|
||||||
};
|
template<class InputIterator>
|
||||||
|
void insert_aux(iterator position, InputIterator first, InputIterator last, std::false_type);
|
||||||
|
template<class Integer>
|
||||||
|
void insert_aux(iterator position, Integer n, Integer value, std::true_type);
|
||||||
|
template<class InputIterator>
|
||||||
|
void reallocateAndCopy(iterator position, InputIterator first, InputIterator last);
|
||||||
|
void reallocateAndFillN(iterator position, const size_type& n, const value_type& val);
|
||||||
|
};// end of class vector
|
||||||
|
|
||||||
//***********************<2A><><EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>***********************
|
//***********************<2A><><EFBFBD>죬<EFBFBD><ECA3AC><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>***********************
|
||||||
template<class T, class Alloc>
|
template<class T, class Alloc>
|
||||||
vector<T, Alloc>::vector(const size_type n){
|
vector<T, Alloc>::vector(const size_type n){
|
||||||
@@ -221,6 +234,67 @@ namespace TinySTL{
|
|||||||
}
|
}
|
||||||
return viter<T>(first);
|
return viter<T>(first);
|
||||||
}
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
template<class InputIterator>
|
||||||
|
void vector<T, Alloc>::reallocateAndCopy(iterator position, InputIterator first, InputIterator last){
|
||||||
|
difference_type oldCapacity = endOfStorage_ - start_;
|
||||||
|
oldCapacity = oldCapacity ? oldCapacity : 1;
|
||||||
|
difference_type newCapacity = oldCapacity + std::max(oldCapacity, last - first);
|
||||||
|
|
||||||
|
T *newStart = dataAllocator::allocate(newCapacity);
|
||||||
|
T *newEndOfStorage = newStart + newCapacity;
|
||||||
|
T *newFinish = uninitialized_copy(begin(), position, newStart);
|
||||||
|
newFinish = uninitialized_copy(first, last, newFinish);
|
||||||
|
newFinish = uninitialized_copy(position, end(), newFinish);
|
||||||
|
|
||||||
|
destroyAndDeallocateAll();
|
||||||
|
start_ = newStart;
|
||||||
|
finish_ = newFinish;
|
||||||
|
endOfStorage_ = newEndOfStorage;
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
template<class InputIterator>
|
||||||
|
void vector<T, Alloc>::insert_aux(iterator position,
|
||||||
|
InputIterator first, InputIterator last,
|
||||||
|
std::false_type){
|
||||||
|
difference_type locationLeft = endOfStorage_ - finish_; // the size of left storage
|
||||||
|
difference_type locationNeed = last - first;
|
||||||
|
|
||||||
|
if (locationLeft >= locationNeed){
|
||||||
|
auto tempPtr = end() - 1;
|
||||||
|
for (; tempPtr - position >= 0; --tempPtr){//move the [position, finish_) back
|
||||||
|
*(tempPtr + locationNeed) = *tempPtr;
|
||||||
|
}
|
||||||
|
uninitialized_copy(first, last, position);
|
||||||
|
finish_ += locationNeed;
|
||||||
|
}else{
|
||||||
|
reallocateAndCopy(position, first, last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
template<class Integer>
|
||||||
|
void vector<T, Alloc>::insert_aux(iterator position, Integer n, Integer value, std::true_type){
|
||||||
|
vector<value_type> v(n, value);
|
||||||
|
insert(position, v.begin(), v.end());
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
template<class InputIterator>
|
||||||
|
void vector<T, Alloc>::insert(iterator position, InputIterator first, InputIterator last){
|
||||||
|
insert_aux(position, first, last, typename std::is_integral<InputIterator>::type());
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
void vector<T, Alloc>::insert(iterator position, const size_type& n, const value_type& val){
|
||||||
|
insert_aux(position, n, val, typename std::is_integral<value_type>::type());
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
typename vector<T, Alloc>::iterator vector<T, Alloc>::insert(iterator position, const value_type& val){
|
||||||
|
insert(position, 1, val);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
template<class T, class Alloc>
|
||||||
|
void vector<T, Alloc>::push_back(const value_type& value){
|
||||||
|
insert(end(), value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -12,7 +12,27 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
TinySTL::vector<std::string> svec(10, "hello world");
|
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||||
|
//TinySTL::vector<int> svec(array, array + 5);
|
||||||
|
//svec.erase(svec.begin() + 1, svec.begin() + 4);//1,5
|
||||||
|
TinySTL::vector<int> svec;
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(1);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(2);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(3);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(4);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(5);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(6);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
svec.push_back(7);
|
||||||
|
cout << svec.capacity() << endl;
|
||||||
|
//svec.insert(svec.begin() + 0, array, array + 10);
|
||||||
|
//svec.insert(svec.begin()+0, 10, 99);
|
||||||
for (auto s : svec){ cout << s << endl; }
|
for (auto s : svec){ cout << s << endl; }
|
||||||
system("pause");
|
system("pause");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user