Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gauthier Quesnel
irritator
Commits
ffde95a6
Commit
ffde95a6
authored
Mar 10, 2021
by
Gauthier Quesnel
Browse files
core: add function_ref code
parent
f93dcfb2
Changes
2
Hide whitespace changes
Inline
Side-by-side
lib/include/irritator/core.hpp
View file @
ffde95a6
...
...
@@ -260,6 +260,95 @@ almost_equal(T x, T y, int ulp)
std
::
fabs
(
x
-
y
)
<
std
::
numeric_limits
<
T
>::
min
();
}
/*****************************************************************************
*
* Definition of a lightweight std::function
*
****************************************************************************/
template
<
class
F
>
class
function_ref
;
template
<
class
R
,
class
...
Args
>
class
function_ref
<
R
(
Args
...)
>
{
public:
constexpr
function_ref
()
noexcept
=
delete
;
/// Creates a `function_ref` which refers to the same callable as `rhs`.
constexpr
function_ref
(
const
function_ref
<
R
(
Args
...)
>&
rhs
)
noexcept
=
default
;
/// Constructs a `function_ref` referring to `f`.
///
/// \synopsis template <typename F> constexpr function_ref(F &&f) noexcept
template
<
typename
F
,
std
::
enable_if_t
<!
std
::
is_same
<
std
::
decay_t
<
F
>,
function_ref
>::
value
&&
std
::
is_invocable_r
<
R
,
F
&&
,
Args
...
>::
value
>*
=
nullptr
>
constexpr
function_ref
(
F
&&
f
)
noexcept
:
obj
(
const_cast
<
void
*>
(
reinterpret_cast
<
const
void
*>
(
std
::
addressof
(
f
))))
{
cb
=
[](
void
*
obj
,
Args
...
args
)
->
R
{
return
std
::
invoke
(
*
reinterpret_cast
<
typename
std
::
add_pointer
<
F
>::
type
>
(
obj
),
std
::
forward
<
Args
>
(
args
)...);
};
}
/// Makes `*this` refer to the same callable as `rhs`.
constexpr
function_ref
<
R
(
Args
...)
>&
operator
=
(
const
function_ref
<
R
(
Args
...)
>&
rhs
)
noexcept
=
default
;
/// Makes `*this` refer to `f`.
///
/// \synopsis template <typename F> constexpr function_ref &operator=(F &&f)
/// noexcept;
template
<
typename
F
,
std
::
enable_if_t
<
std
::
is_invocable_r
<
R
,
F
&&
,
Args
...>
::
value
>*
=
nullptr
>
constexpr
function_ref
<
R
(
Args
...)
>&
operator
=
(
F
&&
f
)
noexcept
{
obj
=
reinterpret_cast
<
void
*>
(
std
::
addressof
(
f
));
cb
=
[](
void
*
obj
,
Args
...
args
)
{
return
std
::
invoke
(
*
reinterpret_cast
<
typename
std
::
add_pointer
<
F
>::
type
>
(
obj
),
std
::
forward
<
Args
>
(
args
)...);
};
return
*
this
;
}
constexpr
void
swap
(
function_ref
<
R
(
Args
...)
>&
rhs
)
noexcept
{
std
::
swap
(
obj
,
rhs
.
obj
);
std
::
swap
(
cb
,
rhs
.
cb
);
}
R
operator
()(
Args
...
args
)
const
{
return
cb
(
obj
,
std
::
forward
<
Args
>
(
args
)...);
}
private:
void
*
obj
=
nullptr
;
R
(
*
cb
)(
void
*
,
Args
...)
=
nullptr
;
};
/// Swaps the referred callables of `lhs` and `rhs`.
template
<
typename
R
,
typename
...
Args
>
constexpr
void
swap
(
function_ref
<
R
(
Args
...)
>&
lhs
,
function_ref
<
R
(
Args
...)
>&
rhs
)
noexcept
{
lhs
.
swap
(
rhs
);
}
template
<
typename
R
,
typename
...
Args
>
function_ref
(
R
(
*
)(
Args
...))
->
function_ref
<
R
(
Args
...)
>
;
template
<
typename
R
,
typename
...
Args
>
function_ref
(
R
(
*
)(
Args
...)
noexcept
)
->
function_ref
<
R
(
Args
...)
noexcept
>
;
/*****************************************************************************
*
* Definition of Time
...
...
lib/test/public-api.cpp
View file @
ffde95a6
...
...
@@ -50,6 +50,31 @@ file_output_observe(const irt::observer& obs,
fmt
::
print
(
output
->
os
,
"{},{}
\n
"
,
t
,
msg
.
real
[
0
]);
}
bool
function_ref_called
=
false
;
void
function_ref_f
()
{
function_ref_called
=
true
;
}
struct
function_ref_class
{
bool
baz_called
=
false
;
void
baz
()
{
baz_called
=
true
;
}
bool
qux_called
=
false
;
void
qux
()
{
qux_called
=
true
;
}
};
static
void
empty_fun
(
irt
::
model_id
/*id*/
)
noexcept
{}
...
...
@@ -188,6 +213,40 @@ main()
expect
(
irt
::
is_bad
(
s2
)
==
true
);
};
"function_ref"
_test
=
[]
{
{
irt
::
function_ref
<
void
(
void
)
>
fr
=
function_ref_f
;
fr
();
expect
(
function_ref_called
==
true
);
}
{
function_ref_class
o
;
auto
x
=
&
function_ref_class
::
baz
;
irt
::
function_ref
<
void
(
function_ref_class
&
)
>
fr
=
x
;
fr
(
o
);
expect
(
o
.
baz_called
);
x
=
&
function_ref_class
::
qux
;
fr
=
x
;
fr
(
o
);
expect
(
o
.
qux_called
);
}
{
auto
x
=
[]
{
return
42
;
};
irt
::
function_ref
<
int
()
>
fr
=
x
;
expect
(
fr
()
==
42
);
}
{
int
i
=
0
;
auto
x
=
[
&
i
]
{
i
=
42
;
};
irt
::
function_ref
<
void
()
>
fr
=
x
;
fr
();
expect
(
i
==
42
);
}
};
"time"
_test
=
[]
{
expect
(
irt
::
time_domain
<
irt
::
time
>::
infinity
>
irt
::
time_domain
<
irt
::
time
>::
zero
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment