Last active
September 10, 2018 06:41
-
-
Save jeremyong/73a6e2ee012360592c3cfb95119bec82 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <vector> | |
#include <vulkan/vulkan.hpp> | |
namespace vkf | |
{ | |
template <typename Type, typename Dispatch = vk::DispatchLoaderStatic> | |
class VkUniqueVector | |
{ | |
using Container = std::vector<Type>; | |
using Deleter = typename vk::UniqueHandleTraits<Type, Dispatch>::deleter; | |
// This is being used right now because the "destroy" member function is protected and we need to access it without inheritance | |
struct Hack : public Deleter | |
{ | |
template <typename T> | |
using Destroyer = void (Deleter::*)(T); | |
template <typename T> | |
static Destroyer<T> get_destroyer() | |
{ | |
return &Hack::destroy; | |
} | |
}; | |
public: | |
VkUniqueVector() = default; | |
VkUniqueVector(const VkUniqueVector&) = delete; | |
VkUniqueVector& operator=(const VkUniqueVector&) = delete; | |
VkUniqueVector(VkUniqueVector&& other) | |
: m_data{std::move(other.m_data)} | |
, m_deleters{std::move(other.m_deleters)} | |
{ | |
} | |
VkUniqueVector& operator=(VkUniqueVector&& other) | |
{ | |
if (this == &other) | |
{ | |
return *this; | |
} | |
m_data = std::move(other.m_data); | |
m_deleters = std::move(other.m_deleters); | |
return *this; | |
} | |
~VkUniqueVector() | |
{ | |
cleanup(); | |
} | |
Type emplace_back(vk::UniqueHandle<Type, Dispatch>&& handle) | |
{ | |
Type result = m_data.emplace_back(*handle); | |
handle.release(); | |
m_deleters.emplace_back(std::move(static_cast<Deleter>(handle))); | |
return result; | |
} | |
void reserve(size_t size) | |
{ | |
m_data.reserve(size); | |
m_deleters.reserve(size); | |
} | |
void clear() | |
{ | |
cleanup(); | |
m_data.clear(); | |
m_deleters.clear(); | |
} | |
uint32_t size() const | |
{ | |
return static_cast<uint32_t>(m_data.size()); | |
} | |
bool empty() const | |
{ | |
return m_data.empty(); | |
} | |
const Type* data() const | |
{ | |
return m_data.data(); | |
} | |
Type* data() | |
{ | |
return m_data.data(); | |
} | |
Type operator[](size_t i) const | |
{ | |
return m_data[i]; | |
} | |
typename Container::iterator begin() | |
{ | |
return m_data.begin(); | |
} | |
typename Container::iterator end() | |
{ | |
return m_data.end(); | |
} | |
typename Container::const_iterator begin() const | |
{ | |
return m_data.cbegin(); | |
} | |
typename Container::iterator end() const | |
{ | |
return m_data.cend(); | |
} | |
typename Container::iterator rbegin() | |
{ | |
return m_data.rbegin(); | |
} | |
typename Container::iterator rend() | |
{ | |
return m_data.rend(); | |
} | |
typename Container::iterator rbegin() const | |
{ | |
return m_data.crbegin(); | |
} | |
typename Container::iterator rend() const | |
{ | |
return m_data.crend(); | |
} | |
private: | |
void cleanup() | |
{ | |
for (size_t i = 0; i != m_data.size(); ++i) | |
{ | |
auto& deleter = m_deleters[i]; | |
(deleter.*Hack::get_destroyer<Type>())(m_data[i]); | |
} | |
} | |
Container m_data; | |
std::vector<Deleter> m_deleters; | |
}; | |
} // namespace vkf |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment