3d游戏引擎的Utilities模块实现

1.Vector.h

#pragma once

#include "CommonHeaders.h"

namespace primal::utl

{

template<typename T, bool destruct = true>

class vector

{

public:

vector() = default;

constexpr vector(u64 count)

{

resize(count);

}

constexpr explicit vector(u64 count, const T& value)

{

resize(count,value);

}

/*

template<typename it,typename = std::enable_if_t<std::_Is_iterator_v<it>,int> = 0>

constexpr explicit vector(it first, it last)

{

for (; first != last; ++first)

{

emplace_back(*first);

}

}

*/

constexpr vector(const vector& o)

{

*this = o;

}

constexpr vector(vector&& o)

: _capacity{ o._capacity }, _size{ o.size }, _data{o.data}

{

o.reset();

}

constexpr vector& operator=(const vector& o)

{

assert(this != std::addressof(o));

if (this != std::addressof(o))

{

clear();

reserve(o._size);

for (auto& item : o)

{

emplace_back(item);

}

assert(_size == o._size);

}

return *this;

}

constexpr vector& operator=(vector&& o)

{

assert(this != std::addressof(o));

if (this != std::addressof(o))

{

destroy();

move(o);

}

return *this;

}

~vector() { destroy(); }

constexpr void push_back(const T& value)

{

emplace_back(value);

}

constexpr void push_back(T&& value)

{

emplace_back(std::move(value));

}

template<typename... params>

constexpr decltype(auto) emplace_back(params&&... p)

{

if (_size == _capacity)

{

reserve(((_capacity + 1) * 3) >> 1);

}

assert(_size < _capacity);

T* const item{ new(std::addressof(_data_size)) T(std::forward<params>(p)...); };

++_size;

return *item;

}

constexpr void resize(u64 new_size)

{

static_assert(std::is_default_constructible_v<T>::value,

"Type must be default-constructable."

);

if (new_size > _size)

{

reserve(new_size);

while (_size < new_size)

{

emplace_back();

}

}

else

{

if constexpr (destruct)

{

destruct_range(new_size, _size);

}

_size = new_size;

}

assert(new_size == _size);

}

constexpr void resize(u64 new_size,const T& value)

{

static_assert(std::is_copy_constructible_v<T>::value,

"Type must be copy-constructable."

);

if (new_size > _size)

{

reserve(new_size);

while (_size < new_size)

{

emplace_back(value);

}

}

else

{

if constexpr (destruct)

{

destruct_range(new_size, _size);

}

_size = new_size;

}

assert(new_size == _size);

}

constexpr void reserve(u64 new_capacity)

{

if (new_capacity > _capacity)

{

void* new_buffer{ realloc(_data,new_capacity * sizeof(T)) };

if (new_buffer)

{

_data = static_cast<T*>(new_buffer);

_capacity = new_capacity;

}

}

}

constexpr T* const erase(u64 index)

{

assert(_data && index < _size);

return erase(std::addressof(_dataindex));

}

constexpr T* const erase(T* const item)

{

assert(_data && item >= std::addressof(_data0) &&

item < std::addressof(_data_size)

);

if constexpr (destruct) item->~T();

--_size;

if (item < std::addressof(_data_size))

{

memcpy(item, item + 1, (std::addressof(_data_size) - item) * sizeof(T));

}

return item;

}

constexpr T* const erase_unordered(u64 index)

{

assert(_data && index < _size);

return erase_unordered(std::addressof(_dataindex));

}

constexpr T* const erase_unordered(T* const item)

{

assert(_data && item >= std::addressof(_data0) &&

item < std::addressof(_data_size)

);

if constexpr (destruct) item->~T();

--_size;

if (item < std::addressof(_data_size))

{

memcpy(item, std::addressof(_data_size), sizeof(T));

}

return item;

}

constexpr void clear()

{

if constexpr (destruct)

{

destruct_range(0, _size);

}

_size = 0;

}

constexpr void swap(vector& o)

{

if (this != std::addressof(o))

{

auto temp(std::move(o));

o.move(*this);

move(temp);

}

}

\[nodiscard] constexpr T* data()

{

return _data;

}

\[nodiscard] constexpr T* const data() const

{

return _data;

}

\[nodiscard] constexpr bool empty() const

{

return _size == 0;

}

\[nodiscard] constexpr u64 size() const

{

return _size;

}

\[nodiscard] constexpr u64 capacity() const

{

return _capacity;

}

\[nodiscard] constexpr T& operator\[\](u64 index)

{

assert(_data && index < _size);

return _dataindex;

}

\[nodiscard] constexpr const T& operator\[\](u64 index) const

{

assert(_data && index < _size);

return _dataindex;

}

\[nodiscard] constexpr T& front()

{

assert(_data && _size);

return _data0;

}

\[nodiscard] constexpr const T& front() const

{

assert(_data && _size);

return _data0;

}

\[nodiscard] constexpr T& back()

{

assert(_data && _size);

return _data_size - 1;

}

\[nodiscard] constexpr const T& back() const

{

assert(_data && _size);

return _data_size - 1;

}

\[nodiscard] constexpr T* begin()

{

assert(_data);

return std::addressof(_data0);

}

\[nodiscard] constexpr const T* begin() const

{

assert(_data);

return std::addressof(_data0);

}

\[nodiscard] constexpr T* end()

{

assert(_data);

return std::addressof(_data_size);

}

\[nodiscard] constexpr const T* end() const

{

assert(_data);

return std::addressof(_data_size);

}

private:

constexpr void move(vector& o)

{

_capacity = o._capacity;

_size = o._size;

_data = o._data;

o.reset();

}

constexpr void reset()

{

_capacity = 0;

_size = 0;

_data = nullptr;

}

constexpr void destruct_range(u64 first, u64 last)

{

assert(destruct);

assert(first <= _size && last <= _size && first <= last);

if (_data)

{

for (; first != last; ++first)

{

_datafirst.~T();

}

}

}

constexpr void destroy()

{

assert(\& {return _capacity ? _data != nullptr : _data == nullptr; }());

clear();

_capacity = 0;

if (_data) free(_data);

_data = nullptr;

}

u64 _capacity{ 0 };

u64 _size{ 0 };

T* _data{ nullptr };

};

}

相关推荐
rannn_1116 小时前
【力扣hot100】238、41、73题解
java·算法·leetcode·开发
QN1幻化引擎6 小时前
认知场的涌现动力学:结构证明、Phi度量与意识签名电池
人工智能·深度学习·神经网络·算法·机器学习·agi
lingran__6 小时前
C++ 高阶数据结构:AVL 树万字详解|原理、四种旋转、key‑value 实现、调试校验、set/map/红黑树 底层前置知识
数据结构·c++·二叉搜索树·平衡二叉树·avl树·红黑树前置
爱和冰阔落6 小时前
【Linux】两个毫无关系的进程怎么通信?命名管道 FIFO 从原理到 Server/Client 实战
android·linux·数据库·c++·vim
码匠许师傅14 小时前
【C++ 面试真题】C++ 的 const 和 constexpr 有什么区别?
c++·面试
坚持编程的菜鸟15 小时前
模拟实现memmove
c语言·算法·模拟实现memmove
wabs66617 小时前
关于图论【最短路径之Dijkstra算法(堆优化版)|卡码网47.参加科学大会的思考】
数据结构·算法·图论·优先级队列·邻接表·小顶堆·卡码网
果果燕17 小时前
实习笔记(一):NFS、Samba、VNC、Git、CMake、systemd、内核、交叉编译
linux·arm开发·c++·笔记·git
坚持编程的菜鸟17 小时前
编写判断大小端程序
c语言·算法·判断大小端
papaofdoudou17 小时前
判断排列逆序奇偶性的乘积判别法(范德蒙德符号法)
人工智能·算法