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