Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // vector.h
- #pragma once
- #include <cassert>
- #include <cstdlib>
- #include <new>
- #include <utility>
- template <typename T>
- class Vector {
- public:
- Vector() = default;
- explicit Vector(size_t size)
- : data_(Allocate(size))
- , capacity_(size)
- , size_(size)
- {
- for (size_t i = 0; i != size; ++i) {
- new (data_ + i) T();
- }
- }
- Vector(const Vector& other)
- : data_(Allocate(other.size_))
- , capacity_(other.size_)
- , size_(other.size_)
- {
- for (size_t i = 0; i != other.size_; ++i) {
- CopyConstruct(data_ + i, other.data_[i]);
- }
- }
- ~Vector() {
- DestroyN(data_, size_);
- Deallocate(data_);
- }
- size_t Size() const noexcept {
- return size_;
- }
- size_t Capacity() const noexcept {
- return capacity_;
- }
- void Reserve(size_t new_capacity) {
- if (new_capacity <= capacity_) {
- return;
- }
- T* new_data = Allocate(new_capacity);
- for (size_t i = 0; i != size_; ++i) {
- CopyConstruct(new_data + i, data_[i]);
- }
- DestroyN(data_, size_);
- Deallocate(data_);
- data_ = new_data;
- capacity_ = new_capacity;
- }
- const T& operator[](size_t index) const noexcept {
- return const_cast<Vector&>(*this)[index];
- }
- T& operator[](size_t index) noexcept {
- assert(index < size_);
- return data_[index];
- }
- private:
- static T* Allocate(size_t n) {
- return n != 0 ? static_cast<T*>(operator new(n * sizeof(T))) : nullptr;
- }
- static void Deallocate(T* buf) noexcept {
- operator delete(buf);
- }
- static void DestroyN(T* buf, size_t n) noexcept {
- for (size_t i = 0; i != n; ++i) {
- Destroy(buf + i);
- }
- }
- static void CopyConstruct(T* buf, const T& elem) {
- new (buf) T(elem);
- }
- static void Destroy(T* buf) noexcept {
- buf->~T();
- }
- T* data_ = nullptr;
- size_t capacity_ = 0;
- size_t size_ = 0;
- };
- // main.cpp
- #include "vector.h"
- namespace {
- struct Obj {
- Obj() {
- ++num_default_constructed;
- }
- Obj(const Obj& /*other*/) {
- ++num_copied;
- }
- Obj(Obj&& /*other*/) noexcept {
- ++num_moved;
- }
- Obj& operator=(const Obj& other) = default;
- Obj& operator=(Obj&& other) = default;
- ~Obj() {
- ++num_destroyed;
- }
- static int GetAliveObjectCount() {
- return num_default_constructed + num_copied + num_moved - num_destroyed;
- }
- static void ResetCounters() {
- num_default_constructed = 0;
- num_copied = 0;
- num_moved = 0;
- num_destroyed = 0;
- }
- static inline int num_default_constructed = 0;
- static inline int num_copied = 0;
- static inline int num_moved = 0;
- static inline int num_destroyed = 0;
- };
- } // namespace
- void Test1() {
- Obj::ResetCounters();
- const size_t SIZE = 100500;
- const size_t INDEX = 10;
- const int MAGIC = 42;
- {
- Vector<int> v;
- assert(v.Capacity() == 0);
- assert(v.Size() == 0);
- v.Reserve(SIZE);
- assert(v.Capacity() == SIZE);
- assert(v.Size() == 0);
- }
- {
- Vector<int> v(SIZE);
- const auto& cv(v);
- assert(v.Capacity() == SIZE);
- assert(v.Size() == SIZE);
- assert(v[0] == 0);
- assert(&v[0] == &cv[0]);
- v[INDEX] = MAGIC;
- assert(v[INDEX] == MAGIC);
- assert(&v[100] - &v[0] == 100);
- v.Reserve(SIZE * 2);
- assert(v.Size() == SIZE);
- assert(v.Capacity() == SIZE * 2);
- assert(v[INDEX] == MAGIC);
- }
- {
- Vector<int> v(SIZE);
- v[INDEX] = MAGIC;
- const auto v_copy(v);
- assert(&v[INDEX] != &v_copy[INDEX]);
- assert(v[INDEX] == v_copy[INDEX]);
- }
- {
- Vector<Obj> v;
- v.Reserve(SIZE);
- assert(Obj::GetAliveObjectCount() == 0);
- }
- {
- Vector<Obj> v(SIZE);
- assert(Obj::GetAliveObjectCount() == SIZE);
- v.Reserve(SIZE * 2);
- assert(Obj::GetAliveObjectCount() == SIZE);
- }
- assert(Obj::GetAliveObjectCount() == 0);
- }
- int main() {
- Test1();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement