mirror of https://github.com/davisking/dlib.git
Added call_if_valid()
This commit is contained in:
parent
e7ec6b7777
commit
7dcc7b4ebc
|
@ -3,6 +3,7 @@
|
|||
#ifndef DLIB_METApROGRAMMING_Hh_
|
||||
#define DLIB_METApROGRAMMING_Hh_
|
||||
|
||||
#include "algs.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
@ -62,6 +63,45 @@ namespace dlib
|
|||
// base case
|
||||
template <> struct make_compile_time_integer_range<0> { typedef compile_time_integer_list<> type; };
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template <
|
||||
typename Funct,
|
||||
typename... Args,
|
||||
typename int_<decltype(std::declval<Funct>()(std::declval<Args>()...))>::type = 0
|
||||
>
|
||||
bool call_if_valid (
|
||||
special_,
|
||||
Funct&& f, Args&&... args
|
||||
)
|
||||
{
|
||||
f(std::forward<Args>(args)...);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Funct,
|
||||
typename... Args
|
||||
>
|
||||
bool call_if_valid (
|
||||
general_,
|
||||
Funct&& /*f*/, Args&&... /*args*/
|
||||
) { return false; }
|
||||
}
|
||||
|
||||
template <typename Funct, typename... Args>
|
||||
bool call_if_valid(Funct&& f, Args&&... args)
|
||||
/*!
|
||||
ensures
|
||||
- if f(std::forward<Args>(args)...) is a valid expression then we evaluate it and return
|
||||
true. Otherwise we do nothing and return false.
|
||||
!*/
|
||||
{
|
||||
return impl::call_if_valid(special_(), f, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <dlib/algs.h>
|
||||
#include <dlib/metaprogramming.h>
|
||||
|
||||
#include "tester.h"
|
||||
|
||||
|
@ -70,6 +71,41 @@ namespace
|
|||
}
|
||||
|
||||
|
||||
void test_call_if_valid()
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
auto foo = [&](int a, int b) { value += a + b; };
|
||||
auto bar = [&](std::string) { value++; };
|
||||
auto baz = [&]() { value++; };
|
||||
|
||||
DLIB_TEST(value == 0);
|
||||
DLIB_TEST(call_if_valid(baz));
|
||||
DLIB_TEST(value == 1);
|
||||
DLIB_TEST(!call_if_valid(foo));
|
||||
DLIB_TEST(value == 1);
|
||||
DLIB_TEST(!call_if_valid(bar));
|
||||
DLIB_TEST(value == 1);
|
||||
DLIB_TEST(call_if_valid(bar, "stuff"));
|
||||
DLIB_TEST(value == 2);
|
||||
DLIB_TEST(!call_if_valid(baz, "stuff"));
|
||||
DLIB_TEST(value == 2);
|
||||
DLIB_TEST(call_if_valid(foo, 3, 1));
|
||||
DLIB_TEST(value == 6);
|
||||
DLIB_TEST(!call_if_valid(bar, 3, 1));
|
||||
DLIB_TEST(value == 6);
|
||||
|
||||
|
||||
// make sure stateful lambdas are modified when called
|
||||
value = 0;
|
||||
auto stateful = [&value, i = value]() mutable { ++i; value = i; };
|
||||
DLIB_TEST(call_if_valid(stateful));
|
||||
DLIB_TEST(value == 1);
|
||||
DLIB_TEST(call_if_valid(stateful));
|
||||
DLIB_TEST(value == 2);
|
||||
DLIB_TEST(call_if_valid(stateful));
|
||||
DLIB_TEST(value == 3);
|
||||
}
|
||||
|
||||
|
||||
class metaprogramming_tester : public tester
|
||||
|
@ -85,6 +121,7 @@ namespace
|
|||
)
|
||||
{
|
||||
metaprogramming_test();
|
||||
test_call_if_valid();
|
||||
}
|
||||
} a;
|
||||
|
||||
|
|
Loading…
Reference in New Issue