Mercurial > code
changeset 654:5f00a9691da5
pexec: add convenient wrapper for std::optional
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 21 Jan 2019 20:39:31 +0100 |
parents | 87e1f4c7da76 |
children | a0239cca29fa |
files | cpp/CMakeLists.txt cpp/pexec/CMakeLists.txt cpp/pexec/pexec.hpp cpp/pexec/test/main.cpp |
diffstat | 4 files changed, 140 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/cpp/CMakeLists.txt Tue Jan 08 21:19:17 2019 +0100 +++ b/cpp/CMakeLists.txt Mon Jan 21 20:39:31 2019 +0100 @@ -20,4 +20,5 @@ add_subdirectory(is_number) add_subdirectory(join) add_subdirectory(json_util) +add_subdirectory(pexec) add_subdirectory(to_int)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpp/pexec/CMakeLists.txt Mon Jan 21 20:39:31 2019 +0100 @@ -0,0 +1,22 @@ +# +# CMakeLists.txt -- code building for common code +# +# Copyright (c) 2016-2019 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. +# + +code_define_module( + NAME pexec + SOURCES pexec.hpp +)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpp/pexec/pexec.hpp Mon Jan 21 20:39:31 2019 +0100 @@ -0,0 +1,32 @@ +/* + * pexec.hpp -- wrap an unsafe function and return an optional + * + * Copyright (c) 2016-2019 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. + */ + +#include <functional> +#include <optional> + +template <typename Func, typename... Args> +auto pexec(Func&& func, Args&&... args) +{ + using type = std::invoke_result_t<Func, Args...>; + + try { + return std::optional<type>(std::invoke(std::forward<Func>(func), std::forward<Args>(args)...)); + } catch (...) { + return std::optional<type>(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpp/pexec/test/main.cpp Mon Jan 21 20:39:31 2019 +0100 @@ -0,0 +1,85 @@ +/* + * main.cpp -- test pexec function + * + * Copyright (c) 2016-2019 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. + */ + +#define BOOST_TEST_MODULE "pexec" +#include <boost/test/unit_test.hpp> + +#include "pexec.hpp" + +namespace { + +int add(int x, int y) noexcept +{ + return x + y; +} + +int fail(double) +{ + throw std::runtime_error("failed"); +} + +class math { +public: + int add(int x, int y) const noexcept + { + return x + y; + } + + int fail(double) const + { + throw std::runtime_error("failed"); + } +}; + +BOOST_AUTO_TEST_SUITE(free) + +BOOST_AUTO_TEST_CASE(simple) +{ + BOOST_TEST(pexec(add, 10, 20).value() == 30); +} + +BOOST_AUTO_TEST_CASE(error) +{ + BOOST_TEST(!pexec(fail, 5.5)); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(member) + +BOOST_AUTO_TEST_CASE(simple) +{ + math m; + + BOOST_TEST(pexec(&math::add, &m, 10, 20).value() == 30); + BOOST_TEST(pexec(&math::add, std::ref(m), 10, 20).value() == 30); + BOOST_TEST(pexec(&math::add, m, 10, 20).value() == 30); +} + +BOOST_AUTO_TEST_CASE(error) +{ + math m; + + BOOST_TEST(!pexec(&math::fail, &m, 5.5)); + BOOST_TEST(!pexec(&math::fail, std::ref(m), 5.5)); + BOOST_TEST(!pexec(&math::fail, m, 5.5)); +} + +BOOST_AUTO_TEST_SUITE_END() + +} // !namespace