2015-09-07 04:43:34 +03:00
|
|
|
/* -*- 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/Function.h"
|
|
|
|
|
2016-03-12 00:49:13 +03:00
|
|
|
using mozilla::function;
|
2015-09-07 04:43:34 +03:00
|
|
|
|
|
|
|
#define CHECK(c) \
|
|
|
|
do { \
|
|
|
|
bool cond = !!(c); \
|
|
|
|
MOZ_RELEASE_ASSERT(cond, "Failed assertion: " #c); \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
struct ConvertibleToInt
|
|
|
|
{
|
|
|
|
operator int() const { return 42; }
|
|
|
|
};
|
|
|
|
|
|
|
|
int increment(int arg) { return arg + 1; }
|
|
|
|
|
|
|
|
struct S {
|
2015-10-11 20:53:00 +03:00
|
|
|
S() {}
|
2015-09-07 04:43:34 +03:00
|
|
|
static int increment(int arg) { return arg + 1; }
|
2015-10-11 20:53:00 +03:00
|
|
|
int decrement(int arg) { return arg - 1;}
|
|
|
|
int sum(int arg1, int arg2) const { return arg1 + arg2;}
|
2015-09-07 04:43:34 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Incrementor {
|
|
|
|
int operator()(int arg) { return arg + 1; }
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestNonmemberFunction()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f = &increment;
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(f(42) == 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestStaticMemberFunction()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f = &S::increment;
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(f(42) == 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestFunctionObject()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f = Incrementor();
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(f(42) == 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestLambda()
|
|
|
|
{
|
|
|
|
// Test non-capturing lambda
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f = [](int arg){ return arg + 1; };
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(f(42) == 43);
|
|
|
|
|
|
|
|
// Test capturing lambda
|
|
|
|
int one = 1;
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> g = [one](int arg){ return arg + one; };
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(g(42) == 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestDefaultConstructionAndAssignmentLater()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f; // allowed
|
2015-09-07 04:43:34 +03:00
|
|
|
// Would get an assertion if we tried calling f now.
|
|
|
|
f = &increment;
|
|
|
|
CHECK(f(42) == 43);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestReassignment()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(int)> f = &increment;
|
2015-09-07 04:43:34 +03:00
|
|
|
CHECK(f(42) == 43);
|
|
|
|
f = [](int arg){ return arg + 2; };
|
|
|
|
CHECK(f(42) == 44);
|
|
|
|
}
|
|
|
|
|
2015-10-11 20:53:00 +03:00
|
|
|
static void
|
|
|
|
TestMemberFunction()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(S&, int)> f = &S::decrement;
|
2015-10-11 20:53:00 +03:00
|
|
|
S s;
|
|
|
|
CHECK((f(s, 1) == 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
TestConstMemberFunction()
|
|
|
|
{
|
2016-03-12 00:49:13 +03:00
|
|
|
function<int(const S*, int, int)> f = &S::sum;
|
2015-10-11 20:53:00 +03:00
|
|
|
const S s;
|
|
|
|
CHECK((f(&s, 1, 1) == 2));
|
|
|
|
}
|
2015-09-07 04:43:34 +03:00
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
|
|
|
TestNonmemberFunction();
|
|
|
|
TestStaticMemberFunction();
|
|
|
|
TestFunctionObject();
|
|
|
|
TestLambda();
|
|
|
|
TestDefaultConstructionAndAssignmentLater();
|
|
|
|
TestReassignment();
|
2015-10-11 20:53:00 +03:00
|
|
|
TestMemberFunction();
|
|
|
|
TestConstMemberFunction();
|
2015-09-07 04:43:34 +03:00
|
|
|
return 0;
|
|
|
|
}
|