Mercurial > malikania
changeset 104:385ba70b93e3
Common: add weak_array class
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 02 Sep 2017 11:24:42 +0200 |
parents | 41e5722da2ae |
children | 0a4a246d765b |
files | libcommon/CMakeLists.txt libcommon/malikania/weak_array.hpp tests/libcommon/weak_array/CMakeLists.txt tests/libcommon/weak_array/main.cpp |
diffstat | 4 files changed, 170 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/libcommon/CMakeLists.txt Mon Aug 21 20:59:18 2017 +0200 +++ b/libcommon/CMakeLists.txt Sat Sep 02 11:24:42 2017 +0200 @@ -27,6 +27,7 @@ ${libmlk-common_SOURCE_DIR}/malikania/size.hpp ${libmlk-common_SOURCE_DIR}/malikania/tileset.hpp ${libmlk-common_SOURCE_DIR}/malikania/util.hpp + ${libmlk-common_SOURCE_DIR}/malikania/weak_array.hpp ) set(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/malikania/weak_array.hpp Sat Sep 02 11:24:42 2017 +0200 @@ -0,0 +1,79 @@ +/* + * weak_array.hpp -- implement a cache array of weak values + * + * Copyright (c) 2013-2017 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_WEAK_ARRAY_HPP +#define MALIKANIA_WEAK_ARRAY_HPP + +/** + * \file weak_array.hpp + * \brief Implement a cache array of weak values. + */ + +#include <memory> +#include <vector> + +namespace mlk { + +/** + * \brief Implement a cache array of weak values. + */ +template <typename T> +class weak_array : public std::vector<std::weak_ptr<T>> { +public: + /** + * Find a value by a predicate. + * + * The predicate must have the following signature: + * + * ````cpp + * bool f(const std::shared_ptr<T>& value) const noexcept + * ```` + * + * \param pred the predicate + * \return nullptr if not found + */ + template <typename Predicate> + std::shared_ptr<T> find_if(Predicate&& pred) const noexcept + { + for (const auto& value : *this) { + auto sp = value.lock(); + + if (sp && pred(sp)) + return sp; + } + + return nullptr; + } + + /** + * Remove values that have no more referenced. + */ + void purge() + { + for (auto it = this->begin(); it != this->end(); ) { + if (!it->lock()) + it = this->erase(it); + else + it++; + } + } +}; + +} // !mlk + +#endif // !MALIKANIA_WEAK_ARRAY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libcommon/weak_array/CMakeLists.txt Sat Sep 02 11:24:42 2017 +0200 @@ -0,0 +1,23 @@ +# +# CMakeLists.txt -- CMake build system for malikania +# +# Copyright (c) 2013-2017 Malikania Authors +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +malikania_create_test( + NAME weak_array + LIBRARIES libmlk-common + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/libcommon/weak_array/main.cpp Sat Sep 02 11:24:42 2017 +0200 @@ -0,0 +1,67 @@ +/* + * main.cpp -- test weak_array + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define BOOST_TEST_MODULE "weak_array" +#include <boost/test/unit_test.hpp> + +#include <malikania/weak_array.hpp> + +namespace mlk { + +class weak_array_fixture { +protected: + weak_array<int> array_; +}; + +BOOST_FIXTURE_TEST_SUITE(weak_array_suite, weak_array_fixture) + +BOOST_AUTO_TEST_CASE(reuse) +{ + auto value = std::make_shared<int>(123); + + array_.push_back(value); + array_.push_back(std::make_shared<int>(256)); + + auto it1 = array_.find_if([] (auto ptr) { + return *ptr = 123; + }); + auto it2 = array_.find_if([] (auto ptr) { + return *ptr = 123; + }); + + BOOST_TEST(it1 == value); + BOOST_TEST(it2 == value); + BOOST_TEST(it1 == it2); + BOOST_TEST(*it1 == 123); + BOOST_TEST(*it2 == 123); +} + +BOOST_AUTO_TEST_CASE(not_found) +{ + array_.push_back(std::make_shared<int>(123)); + + auto v = array_.find_if([] (auto ptr) { + return *ptr = 123; + }); + + BOOST_TEST(!v); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // !mlk