// file : tests/move-only-function/driver.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #include // unique_ptr #include // move() #include #undef NDEBUG #include 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; ft f; ft f2 (f); ft f3; f3 = f; ft f4 (123); } #endif // NULL. // { using ft = move_only_function_ex; 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; 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 () != nullptr); assert (f1.target () != nullptr); } // Functor. // { using ft = move_only_function_ex; 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 () != nullptr); } // Lambda. // { using ft = move_only_function_ex; ft f ([p = unique_ptr (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 (new int (2))] (int v) { return *p + v; }); assert (f (1) == 3); } // Void result. // { using ft = move_only_function_ex; ft f ([] (int v) { assert (v == 1); }); f (1); ft f1 (move (f)); f1 (1); } }