#include <cassert>
#include <cinttypes>
#include <cstring>
#include <string>
#if !FUNCTIONAL_PROVIDED
static std::string
impl_name =
"jau/functional.hpp";
#endif
#ifndef FUNCTIONAL_IMPL
#define FUNCTIONAL_IMPL 1
#endif
public:
const int loops = 1000000;
fprintf(stderr, "Implementation: functional %d, is_rtti_available %d, limited_lambda_id %d\n",
{
volatile int i = 100;
{
return i + a;
};
fprintf(stderr, "lambda.ref: %s\n", fa0.toString().c_str());
}
{
return i + a;
};
fprintf(stderr, "lambda.copy: %s\n", fa0.toString().c_str());
}
}
{
return a + 100;
} ;
fprintf(stderr, "lambda.plain: %s\n", f_1.toString().c_str());
}
#if ( FUNCTIONAL_IMPL == 1 )
{
if( 0 == x ) {
return 1;
} else {
return x * self(x-1);
}
} );
fprintf(stderr, "ylambda.plain1 %s\n", f_1.toString().c_str());
}
{
if( 0 == x ) {
return 1;
} else {
return x * self(x-1);
}
} );
fprintf(stderr, "ylambda.plain2 %s\n", f_1.toString().c_str());
}
#endif
{
typedef void(*cfunc)();
} );
fprintf(stderr, "freeA.0 %s\n", fl_0.toString().c_str());
}
{
jau::function<int(
int)> f2a_0(
this, &TestFunction01::func02a_member);
fprintf(stderr, "member: %s\n", f2a_0.toString().c_str());
}
{
jau::function<void(
int&,
int)> f2a_0(
this, &TestFunction01::func12a_member);
fprintf(stderr, "member: %s\n", f2a_0.toString().c_str());
}
{
int offset100 = 100;
typedef int(*cfunc)(int&, int);
(cfunc) ( [](int& capture, int i)->int {
int res = i+10000+capture;
return res;
} ) );
fprintf(stderr, "capval.small: %s\n", f5_o100_1.toString().c_str());
}
{
struct blob {
int offset100 = 100;
uint64_t lala0 = 0;
uint64_t lala1 = 1;
uint64_t lala2 = 2;
uint64_t lala3 = 3;
return offset100 == rhs.offset100 &&
lala0 == rhs.lala0 &&
lala1 == rhs.lala1 &&
lala2 == rhs.lala2 &&
lala3 == rhs.lala3;
}
{ return !( *this == rhs ); }
};
blob b0;
typedef int(*cfunc)(blob&, int);
(cfunc) ( [](blob& capture, int i)->int {
int res = i+10000+capture.offset100;
return res;
} ) );
fprintf(stderr, "capval.big: %s\n", f5_o100_1.toString().c_str());
}
{
int offset100 = 100;
typedef int(*cfunc)(int*, int);
jau::function<int(
int)> f7_o100_1 = jau::bind_capref<int, int, int>(&offset100,
(cfunc) ( [](int* capture, int i)->int {
int res = i+10000+(*capture);
return res;;
} ) );
fprintf(stderr, "capref: %s\n", f7_o100_1.toString().c_str());
}
{
std::function<int(int i)> func4a_stdlambda = [](int i)->int {
int res = i+100;
return res;;
};
fprintf(stderr, "std.lambda pl: %s\n", f.toString().c_str());
fprintf(stderr, " (net std.lambda): sizeof %zu\n", sizeof(func4a_stdlambda));
}
{
volatile int i = 100;
std::function<int(int)> func4a_stdlambda = [&](int a) -> int {
return i + a;
};
fprintf(stderr, "std.lambda cp: %s\n", f.toString().c_str());
fprintf(stderr, " (net std.lambda): sizeof %zu\n", sizeof(func4a_stdlambda));
}
}
INFO("Test 00_usage: START");
{
BENCHMARK("free_rawfunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + TestFunction01::Func03a_static(i);
}
return r;
};
}
{
native_func_t f = TestFunction01::Func03a_static;
BENCHMARK("free_cfuncptr") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
std::function<int(int)> f = TestFunction01::Func03a_static;
BENCHMARK("free_stdfunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
BENCHMARK("free_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
BENCHMARK("member_rawfunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + func02a_member(i);
}
return r;
};
}
{
using namespace std::placeholders;
auto f = std::bind(&TestFunction01::func02a_member, this, _1);
BENCHMARK("member_stdbind_unspec") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
BENCHMARK("member_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
int offset100 = 100;
int(*func5a_capture)(int&, int) = [](int& capture, int i)->int {
int res = i+capture;
return res;
};
BENCHMARK("capval_small_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
struct blob {
int offset100 = 100;
uint64_t lala0 = 0;
uint64_t lala1 = 1;
uint64_t lala2 = 2;
uint64_t lala3 = 3;
return offset100 == rhs.offset100 &&
lala0 == rhs.lala0 &&
lala1 == rhs.lala1 &&
lala2 == rhs.lala2 &&
lala3 == rhs.lala3;
}
{ return !( *this == rhs ); }
};
blob b0;
typedef int(*cfunc)(blob&, int);
(cfunc) ( [](blob& capture, int i)->int {
int res = i+10000+capture.offset100;
return res;
} ) );
BENCHMARK("capval_big_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
int offset100 = 100;
int(*func7a_capture)(int*, int) = [](int* capture, int i)->int {
int res = i+*capture;
return res;
};
BENCHMARK("capref_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
std::function<int(int i)> f = [](int i)->int {
int res = i+100;
return res;;
};
BENCHMARK("lambda_plain_std_function") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
return 100+ a;
};
BENCHMARK("lambda_plain_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
volatile int captured = 100;
std::function<int(int)> f = [&](int a) -> int {
return captured + a;
};
BENCHMARK("lambda_capt_std_function") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
{
volatile int captured = 100;
return captured + a;
};
BENCHMARK("lambda_capt_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
#if ( FUNCTIONAL_IMPL == 1 )
{
(void)self;
return 100+x;
} );
BENCHMARK("ylambda_none_jaufunc") {
volatile int r=0;
for(
int i=0; i<
loops; ++i) {
r = r + f(i);
}
return r;
};
}
#endif
REQUIRE( true == true );
INFO("Test 00_usage: END");
}
private:
typedef int(*native_func_t)(int);
typedef std::function<int(int)> std_func_t;
typedef int(*MyCFunc0)(int);
int func02a_member(int i) {
int res = i+100;
return res;;
}
int func02b_member(int i) noexcept {
int res = i+1000;
return res;
}
static int Func03a_static(int i) {
int res = i+100;
return res;
}
static int Func03b_static(int i) noexcept {
int res = i+1000;
return res;
}
void func12a_member(int& r, const int i) {
r = i+100;
}
void func12b_member(int& r, const int i) noexcept {
r = i+1000;
}
static void Func13a_static(int& r, const int i) {
r = i+100;
}
static void Func13b_static(int& r, const int i) noexcept {
r = i+1000;
}
void func20a_member() {
}
static void Func20a_static() {
}
static int i = 100;
return i + a;
};
return f;
}
int i = 100;
return i + a;
};
return f;
}
};
void test00_usage()
Unit test covering most variants of jau::function<R(A...)
Class template jau::function is a general-purpose static-polymorphic function wrapper.
static constexpr const bool limited_lambda_id
Static constexpr boolean indicating whether resulting type_info uniqueness is limited for lambda func...
bool operator!=(const alphabet &lhs, const alphabet &rhs) noexcept
std::string to_string(const alphabet &v) noexcept
bool operator==(const alphabet &lhs, const alphabet &rhs) noexcept
consteval_cxx20 bool is_rtti_available() noexcept
Returns true if compiled with RTTI available.
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
jau::function< R(A...)> bind_free(R(*func)(A...)) noexcept
Bind given non-void free-function to an anonymous function using func::free_target_t.
jau::function< R(A...)> bind_std(uint64_t id, std::function< R(A...)> func) noexcept
Bind given non-void std::function to an anonymous function using func::std_target_t.
jau::function< R(A...)> bind_capval(const I &data, R(*func)(I &, A...)) noexcept
Bind given data by copying the captured value and the given non-void function to an anonymous functio...
jau::function< R(A...)> bind_capref(I *data_ptr, R(*func)(I *, A...)) noexcept
Bind given data by passing the captured reference (pointer) to the value and non-void function to an ...
@ lambda
Denotes a func::lambda_target_t.
@ capref
Denotes a func::capref_target_t.
@ member
Denotes a func::member_target_t.
@ free
Denotes a func::free_target_t.
@ std
Denotes a func::std_target_t.
@ ylambda
Denotes a func::ylambda_target_t.
METHOD_AS_TEST_CASE(TestFunction01::test00_usage, "00_usage")
static std::string impl_name