diff options
Diffstat (limited to 'src/path-search-result.cpp')
-rw-r--r-- | src/path-search-result.cpp | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/src/path-search-result.cpp b/src/path-search-result.cpp index 2d9f6ebd..fb2c41ca 100644 --- a/src/path-search-result.cpp +++ b/src/path-search-result.cpp @@ -1,38 +1,70 @@ #include "path-search.hpp" #include "path-search-result.hpp" #include "compat/assert.hpp" +#include <utility> namespace floormat { -path_search_result::path_search_result() : _next{nullptr} {} -size_t path_search_result::size() const { return _path.size(); } -path_search_result::operator bool() const { return !_path.empty(); } -path_search_result::operator ArrayView<const global_coords>() const { return {_path.data(), _path.size()}; } -const global_coords* path_search_result::begin() const { return _path.data(); } -const global_coords* path_search_result::end() const { return _path.data() + _path.size(); } +std::unique_ptr<path_search_result::node> path_search_result::_pool; // NOLINT -const global_coords& path_search_result::operator[](size_t index) const +path_search_result::path_search_result() { - fm_debug_assert(index < _path.size()); - return data()[index]; + if (_pool) + { + auto ptr = std::move(_pool); + fm_debug_assert(ptr->vec.empty()); + auto next = std::move(ptr->_next); + _node = std::move(ptr); + _pool = std::move(next); + } + else + { + _node = std::make_unique<node>(); + _node->vec.reserve(min_length); + } +} + +path_search_result::~path_search_result() noexcept +{ + fm_debug_assert(_node); + _node->vec.clear(); + _node->_next = std::move(_pool); + _pool = std::move(_node); } -const global_coords* path_search_result::data() const +path_search_result::path_search_result(const path_search_result& x) noexcept { - fm_debug_assert(!_next); - return _path.data(); + fm_debug_assert(x._node); + auto self = path_search_result{}; + self._node->vec = x._node->vec; + _node = std::move(self._node); } -path_search_result::path_search_result(ArrayView<const global_coords> array) : _next{nullptr} +path_search_result& path_search_result::operator=(const path_search_result& x) noexcept { - _path.reserve(std::max(array.size(), min_length)); - _path = {array.begin(), array.end()}; + fm_debug_assert(_node); + fm_debug_assert(!_node->_next); + if (&x != this) + _node->vec = x._node->vec; + return *this; } -path_search_result::path_search_result(const path_search_result& other) : _next{nullptr} +path_search_result::node::node() noexcept = default; +size_t path_search_result::size() const { return _node->vec.size(); } +const global_coords* path_search_result::data() const { return _node->vec.data(); } +path_search_result::operator bool() const { return !_node->vec.empty(); } + +path_search_result::operator ArrayView<const global_coords>() const { - _path.reserve(std::max(min_length, other._path.size())); - _path = {other._path.begin(), other._path.end()}; + fm_debug_assert(_node); + return {_node->vec.data(), _node->vec.size()}; +} + +const global_coords& path_search_result::operator[](size_t index) const +{ + fm_debug_assert(_node); + fm_debug_assert(index < _node->vec.size()); + return data()[index]; } } // namespace floormat |