From cc35b618802437c4ca1f4a6e65ba868b7ed98a6d Mon Sep 17 00:00:00 2001 From: Sam Yates <halfflat@gmail.com> Date: Fri, 12 Aug 2016 17:42:15 +0200 Subject: [PATCH] Add 'nop_function' helper for trivial functions. --- src/util/nop.hpp | 29 +++++++++++++++ tests/unit/CMakeLists.txt | 1 + tests/unit/test_nop.cpp | 75 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/util/nop.hpp create mode 100644 tests/unit/test_nop.cpp diff --git a/src/util/nop.hpp b/src/util/nop.hpp new file mode 100644 index 00000000..8315e93f --- /dev/null +++ b/src/util/nop.hpp @@ -0,0 +1,29 @@ +#pragma once + +/* + * Provide object that implicitly converts to + * a std::function object that does nothing but return a + * default-constructed type or void. + */ + +#include <functional> + +namespace nest { +namespace mc { +namespace util { + +static struct nop_function_t { + template <typename R, typename... Args> + operator std::function<R (Args...)>() const { + return [](Args...) { return R{}; }; + } + + template <typename... Args> + operator std::function<void (Args...)>() const { + return [](Args...) { }; + } +} nop_function; + +} // namespace util +} // namespace mc +} // namespace nest diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index fb1b9369..83c537b2 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -21,6 +21,7 @@ set(TEST_SOURCES test_mask_stream.cpp test_matrix.cpp test_mechanisms.cpp + test_nop.cpp test_optional.cpp test_parameters.cpp test_point.cpp diff --git a/tests/unit/test_nop.cpp b/tests/unit/test_nop.cpp new file mode 100644 index 00000000..cf131d9e --- /dev/null +++ b/tests/unit/test_nop.cpp @@ -0,0 +1,75 @@ +#include "gtest.h" +#include "util/nop.hpp" + +using namespace nest::mc::util; + +TEST(nop,void_fn) { + std::function<void ()> f{nop_function}; + + EXPECT_TRUE(f); + f(); // should do nothing + + bool flag = false; + f = [&]() { flag = true; }; + f(); + EXPECT_TRUE(flag); + + flag = false; + f = nop_function; + f(); + EXPECT_FALSE(flag); + + // with some arguments + std::function<void (int, int)> g{nop_function}; + EXPECT_TRUE(g); + g(2, 3); // should do nothing + + int sum = 0; + g = [&](int a, int b) { sum = a+b; }; + g(2, 3); + EXPECT_EQ(5, sum); + + sum = 0; + g = nop_function; + g(2, 3); + EXPECT_EQ(0, sum); +} + +struct check_default { + int value = 100; + + check_default() = default; + explicit check_default(int n): value(n) {} +}; + +TEST(nop,default_return_fn) { + std::function<check_default ()> f{nop_function}; + + EXPECT_TRUE(f); + auto result = f(); + EXPECT_EQ(result.value, 100); + + f = []() { return check_default(17); }; + result = f(); + EXPECT_EQ(result.value, 17); + + f = nop_function; + result = f(); + EXPECT_EQ(result.value, 100); + + std::function<check_default (double, double)> g{nop_function}; + + EXPECT_TRUE(g); + result = g(1.4, 1.5); + EXPECT_EQ(result.value, 100); + + g = [](double x, double y) { return check_default{(int)(x*y)}; }; + result = g(1.4, 1.5); + EXPECT_EQ(result.value, 2); + + g = nop_function; + result = g(1.4, 1.5); + EXPECT_EQ(result.value, 100); + +} + -- GitLab