diff --git a/doc/changelog.dox b/doc/changelog.dox index 76e0bbeeb..75c865124 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -105,6 +105,8 @@ See also: - The @ref PixelFormat and @ref CompressedPixelFormat enums can now be saved and retrieved from @ref Corrade::Utility::Configuration / @ref Corrade::Utility::Arguments +- @ref Resource is now nothrow-movable and thus can be used with growable + @ref Containers::Array instances @subsubsection changelog-latest-changes-gl GL library diff --git a/src/Magnum/Resource.h b/src/Magnum/Resource.h index f3f936646..c44c9019d 100644 --- a/src/Magnum/Resource.h +++ b/src/Magnum/Resource.h @@ -135,10 +135,7 @@ class Resource { } /** @brief Move constructor */ - Resource(Resource&& other): manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { - /** @brief Make other's state well-defined */ - other.manager = nullptr; - } + Resource(Resource&& other) noexcept; /** @brief Destructor */ ~Resource() { @@ -149,7 +146,7 @@ class Resource { Resource& operator=(const Resource& other); /** @brief Move assignment */ - Resource& operator=(Resource&& other); + Resource& operator=(Resource&& other) noexcept; /** @brief Equality comparison */ bool operator==(const Resource& other) const { @@ -260,17 +257,21 @@ template Resource& Resource::operator=(const Resou return *this; } -template Resource& Resource::operator=(Resource&& other) { - /** @todo Just swap the values */ - if(manager) manager->decrementReferenceCount(_key); - - manager = other.manager; - _key = other._key; - lastCheck = other.lastCheck; - _state = other._state; - data = other.data; - +template Resource::Resource(Resource&& other) noexcept: manager(other.manager), _key(other._key), lastCheck(other.lastCheck), _state(other._state), data(other.data) { other.manager = nullptr; + other._key = {}; + other.lastCheck = 0; + other._state = ResourceState::Final; + other.data = nullptr; +} + +template Resource& Resource::operator=(Resource&& other) noexcept { + using std::swap; + swap(manager, other.manager); + swap(_key, other._key); + swap(lastCheck, other.lastCheck); + swap(_state, other._state); + swap(data, other.data); return *this; } diff --git a/src/Magnum/Test/ResourceManagerTest.cpp b/src/Magnum/Test/ResourceManagerTest.cpp index 48ab4f439..b44ece9f4 100644 --- a/src/Magnum/Test/ResourceManagerTest.cpp +++ b/src/Magnum/Test/ResourceManagerTest.cpp @@ -157,6 +157,9 @@ void ResourceManagerTest::constructResourceMove() { CORRADE_COMPARE(c.state(), ResourceState::Final); CORRADE_COMPARE(*c, 6432); CORRADE_COMPARE(rm.referenceCount("thing"), 1); + + CORRADE_VERIFY(std::is_nothrow_move_constructible>::value); + CORRADE_VERIFY(std::is_nothrow_move_assignable>::value); } void ResourceManagerTest::compare() {