/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Assertions.h" #include "mozilla/FunctionRef.h" #include "mozilla/UniquePtr.h" #define CHECK(c) \ do { \ bool cond = !!(c); \ MOZ_RELEASE_ASSERT(cond, "Failed assertion: " #c); \ } while (false) int addConstRefs(const int& arg1, const int& arg2) { return arg1 + arg2; } void incrementPointer(int* arg) { (*arg)++; } int increment(int arg) { return arg + 1; } int incrementUnique(mozilla::UniquePtr ptr) { return *ptr + 1; } static bool helloWorldCalled = false; void helloWorld() { helloWorldCalled = true; } struct S { static int increment(int arg) { return arg + 1; } }; struct Incrementor { int operator()(int arg) { return arg + 1; } }; static void TestNonmemberFunction() { mozilla::FunctionRef f(&increment); CHECK(f(42) == 43); } static void TestStaticMemberFunction() { mozilla::FunctionRef f(&S::increment); CHECK(f(42) == 43); } static void TestFunctionObject() { auto incrementor = Incrementor(); mozilla::FunctionRef f(incrementor); CHECK(f(42) == 43); } static void TestLambda() { // Test non-capturing lambda auto lambda1 = [](int arg) { return arg + 1; }; mozilla::FunctionRef f(lambda1); CHECK(f(42) == 43); // Test capturing lambda int one = 1; auto lambda2 = [one](int arg) { return arg + one; }; mozilla::FunctionRef g(lambda2); CHECK(g(42) == 43); mozilla::FunctionRef h([](int arg) { return arg + 1; }); CHECK(h(42) == 43); } static void TestOperatorBool() { mozilla::FunctionRef f1; CHECK(!static_cast(f1)); mozilla::FunctionRef f2 = increment; CHECK(static_cast(f2)); mozilla::FunctionRef f3 = nullptr; CHECK(!static_cast(f3)); } static void TestReferenceParameters() { mozilla::FunctionRef f = &addConstRefs; int x = 1; int y = 2; CHECK(f(x, y) == 3); } static void TestVoidNoParameters() { mozilla::FunctionRef f = &helloWorld; CHECK(!helloWorldCalled); f(); CHECK(helloWorldCalled); } static void TestPointerParameters() { mozilla::FunctionRef f = &incrementPointer; int x = 1; f(&x); CHECK(x == 2); } static void TestImplicitFunctorTypeConversion() { auto incrementor = Incrementor(); mozilla::FunctionRef f = incrementor; short x = 1; CHECK(f(x) == 2); } static void TestImplicitLambdaTypeConversion() { mozilla::FunctionRef f = [](short arg) { return arg + 1; }; short x = 1; CHECK(f(x) == 2); } static void TestImplicitFunctionPointerTypeConversion() { mozilla::FunctionRef f = &increment; short x = 1; CHECK(f(x) == 2); } static void TestMoveOnlyArguments() { mozilla::FunctionRef)> f(&incrementUnique); CHECK(f(mozilla::MakeUnique(5)) == 6); } int main() { TestNonmemberFunction(); TestStaticMemberFunction(); TestFunctionObject(); TestLambda(); TestOperatorBool(); TestReferenceParameters(); TestPointerParameters(); TestVoidNoParameters(); TestImplicitFunctorTypeConversion(); TestImplicitLambdaTypeConversion(); TestImplicitFunctionPointerTypeConversion(); TestMoveOnlyArguments(); printf("TestFunctionRef OK!\n"); return 0; }