// Copyright 2025 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include // UniqueBuffer and SharedBuffer are a lighter alternative to std::vector. // The main benefit is that elements are not value-initialized like in vector. // That can be quite a bit of unecessary overhead when allocating a large buffer. namespace Common { namespace detail { template class BufferBase final { public: using PtrType = decltype(MakeFunc(1)); using value_type = PtrType::element_type; using size_type = std::size_t; BufferBase() {} BufferBase(PtrType ptr, size_type new_size) : m_ptr{std::move(ptr)}, m_size{new_size} {} explicit BufferBase(size_type new_size) : BufferBase{MakeFunc(new_size), new_size} {} BufferBase(const BufferBase&) = default; BufferBase& operator=(const BufferBase&) = default; BufferBase(BufferBase&& other) { swap(other); } BufferBase& operator=(BufferBase&& other) { reset(); swap(other); return *this; } void assign(PtrType ptr, size_type new_size) { BufferBase{std::move(ptr), new_size}.swap(*this); } void reset(size_type new_size = 0) { BufferBase{new_size}.swap(*this); } std::pair extract() { std::pair result = {std::move(m_ptr), m_size}; reset(); return result; } void swap(BufferBase& other) { std::swap(m_ptr, other.m_ptr); std::swap(m_size, other.m_size); } size_type size() const { return m_size; } bool empty() const { return m_size == 0; } value_type* get() { return m_ptr.get(); } const value_type* get() const { return m_ptr.get(); } value_type* data() { return m_ptr.get(); } const value_type* data() const { return m_ptr.get(); } value_type* begin() { return m_ptr.get(); } value_type* end() { return m_ptr.get() + m_size; } const value_type* begin() const { return m_ptr.get(); } const value_type* end() const { return m_ptr.get() + m_size; } value_type& operator[](size_type index) { return m_ptr[index]; } const value_type& operator[](size_type index) const { return m_ptr[index]; } private: PtrType m_ptr; size_type m_size = 0; }; } // namespace detail template using UniqueBuffer = detail::BufferBase>; // TODO: std::make_shared_for_overwrite requires GCC 12.1+ // template // using SharedBuffer = detail::BufferBase>; } // namespace Common