Browse Source

Vk: make Queue move-only.

Mostly for consistency with everything else. If it proves to be
annoying, it can get removed again -- but suddenly realizing it's needed
would be much more painful and breaking user code.
pull/494/head
Vladimír Vondruš 5 years ago
parent
commit
b81d35d8ac
  1. 13
      src/Magnum/Vk/Queue.cpp
  2. 26
      src/Magnum/Vk/Queue.h
  3. 28
      src/Magnum/Vk/Test/QueueTest.cpp

13
src/Magnum/Vk/Queue.cpp

@ -39,4 +39,17 @@ Queue Queue::wrap(Device& device, VkQueue handle) {
Queue::Queue(NoCreateT): _device{}, _handle{} {} Queue::Queue(NoCreateT): _device{}, _handle{} {}
Queue::Queue(Queue&& other) noexcept: _device{other._device}, _handle{other._handle} {
other._handle = {};
}
Queue::~Queue() = default;
Queue& Queue::operator=(Queue&& other) noexcept {
using std::swap;
swap(other._device, _device);
swap(other._handle, _handle);
return *this;
}
}} }}

26
src/Magnum/Vk/Queue.h

@ -67,6 +67,32 @@ class MAGNUM_VK_EXPORT Queue {
*/ */
explicit Queue(NoCreateT); explicit Queue(NoCreateT);
/* The class *technically* doesn't need to be move-only, it's done only
for consistency and to make room for possible future move-only
state. If move-only proves to be annoying, it might get removed --
going the other way would be much more painful and breaking user
code. */
/** @brief Copying is not allowed */
Queue(const Queue&) = delete;
/** @brief Move constructor */
Queue(Queue&& other) noexcept;
/**
* @brief Destructor
*
* Queues are associated with the device they come from, so no explicit
* destruction is needed.
*/
~Queue();
/** @brief Copying is not allowed */
Queue& operator=(const Queue&) = delete;
/** @brief Move assignment */
Queue& operator=(Queue&& other) noexcept;
/** @brief Underlying @type_vk{Queue} handle */ /** @brief Underlying @type_vk{Queue} handle */
VkQueue handle() { return _handle; } VkQueue handle() { return _handle; }
/** @overload */ /** @overload */

28
src/Magnum/Vk/Test/QueueTest.cpp

@ -34,12 +34,16 @@ struct QueueTest: TestSuite::Tester {
explicit QueueTest(); explicit QueueTest();
void constructNoCreate(); void constructNoCreate();
void constructCopy();
void constructMove();
void wrap(); void wrap();
}; };
QueueTest::QueueTest() { QueueTest::QueueTest() {
addTests({&QueueTest::constructNoCreate, addTests({&QueueTest::constructNoCreate,
&QueueTest::constructCopy,
&QueueTest::constructMove,
&QueueTest::wrap}); &QueueTest::wrap});
} }
@ -54,6 +58,30 @@ void QueueTest::constructNoCreate() {
CORRADE_VERIFY(!(std::is_convertible<NoCreateT, Queue>::value)); CORRADE_VERIFY(!(std::is_convertible<NoCreateT, Queue>::value));
} }
void QueueTest::constructCopy() {
CORRADE_VERIFY(!std::is_copy_constructible<Queue>{});
CORRADE_VERIFY(!std::is_copy_assignable<Queue>{});
}
void QueueTest::constructMove() {
Device device{NoCreate};
Queue a = Queue::wrap(device, reinterpret_cast<VkQueue>(0xbadcafe));
VkQueue handle = a.handle();
CORRADE_VERIFY(a.handle());
Queue b = std::move(a);
CORRADE_VERIFY(!a.handle());
CORRADE_COMPARE(b.handle(), handle);
Queue c{NoCreate};
c = std::move(b);
CORRADE_VERIFY(!b.handle());
CORRADE_COMPARE(c.handle(), handle);
CORRADE_VERIFY(std::is_nothrow_move_constructible<Queue>::value);
CORRADE_VERIFY(std::is_nothrow_move_assignable<Queue>::value);
}
void QueueTest::wrap() { void QueueTest::wrap() {
/* Queues are not getting destroyed in any way, so it's enough to do it in /* Queues are not getting destroyed in any way, so it's enough to do it in
a non-Vulkan-enabled test */ a non-Vulkan-enabled test */

Loading…
Cancel
Save