aboutsummaryrefslogtreecommitdiff
path: root/tests/move-only-function
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-04-20 11:01:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-04-20 11:01:04 +0200
commit5389747f4fff27f85404c96ae969c0c1c7924d76 (patch)
tree1bb521763a40bcfcc069b776eae3d0e95a5f8746 /tests/move-only-function
parente9cf760289b47767fdacc6a98fb2040d35a63d49 (diff)
Add butl::move_only_function[_ex] similar to C++23 std::move_only_function
Diffstat (limited to 'tests/move-only-function')
-rw-r--r--tests/move-only-function/buildfile6
-rw-r--r--tests/move-only-function/driver.cxx149
2 files changed, 155 insertions, 0 deletions
diff --git a/tests/move-only-function/buildfile b/tests/move-only-function/buildfile
new file mode 100644
index 0000000..9012fd6
--- /dev/null
+++ b/tests/move-only-function/buildfile
@@ -0,0 +1,6 @@
+# file : tests/move-only-function/buildfile
+# license : MIT; see accompanying LICENSE file
+
+import libs = libbutl%lib{butl}
+
+exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/move-only-function/driver.cxx b/tests/move-only-function/driver.cxx
new file mode 100644
index 0000000..b94d674
--- /dev/null
+++ b/tests/move-only-function/driver.cxx
@@ -0,0 +1,149 @@
+// file : tests/move-only-function/driver.cxx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+#include <memory> // unique_ptr
+#include <utility> // move()
+
+#include <libbutl/move-only-function.hxx>
+
+#undef NDEBUG
+#include <cassert>
+
+using namespace std;
+
+static int
+func (int v)
+{
+ return v + 1;
+}
+
+struct functor
+{
+ int i;
+
+ int
+ operator() (int v)
+ {
+ return v + i;
+ }
+};
+
+int
+main ()
+{
+ using butl::move_only_function_ex;
+
+ // Attempt to copy-construct or copy-assign should not compile.
+ // Also check non-collable.
+ //
+#if 0
+ {
+ using ft = move_only_function_ex<int (int)>;
+ ft f;
+ ft f2 (f);
+ ft f3; f3 = f;
+ ft f4 (123);
+ }
+#endif
+
+ // NULL.
+ //
+ {
+ using ft = move_only_function_ex<int (int)>;
+
+ ft f1;
+ assert (!f1);
+
+ ft f2 (nullptr);
+ assert (f2 == nullptr);
+
+ f1 = func;
+ assert (f1 != nullptr);
+ f1 = nullptr;
+ assert (!f1);
+
+ int (*f) (int) = nullptr;
+ f2 = f;
+ assert (!f2);
+ }
+
+ // Function.
+ //
+ {
+ using ft = move_only_function_ex<int (int)>;
+
+ ft f (func);
+
+ assert (f (1) == 2);
+
+ ft f1 (move (f));
+ assert (!f);
+ assert (f1 (1) == 2);
+
+ f = &func;
+
+ assert (f (1) == 2);
+
+ assert (f.target<int (*) (int)> () != nullptr);
+ assert (f1.target<int (*) (int)> () != nullptr);
+ }
+
+ // Functor.
+ //
+ {
+ using ft = move_only_function_ex<int (int)>;
+
+ ft f (functor {1});
+
+ assert (f (1) == 2);
+
+ ft f1 (move (f));
+ assert (!f);
+ assert (f1 (1) == 2);
+
+ f = functor {2};
+
+ assert (f (1) == 3);
+
+ assert (ft (functor {1}).target<functor> () != nullptr);
+ }
+
+ // Lambda.
+ //
+ {
+ using ft = move_only_function_ex<int (int)>;
+
+ ft f ([p = unique_ptr<int> (new int (1))] (int v)
+ {
+ return *p + v;
+ });
+
+ assert (f (1) == 2);
+
+ ft f1 (move (f));
+ assert (!f);
+ assert (f1 (1) == 2);
+
+ f = ([p = unique_ptr<int> (new int (2))] (int v)
+ {
+ return *p + v;
+ });
+
+ assert (f (1) == 3);
+ }
+
+ // Void result.
+ //
+ {
+ using ft = move_only_function_ex<void (int)>;
+
+ ft f ([] (int v)
+ {
+ assert (v == 1);
+ });
+
+ f (1);
+ ft f1 (move (f));
+ f1 (1);
+ }
+}