Merge pull request #408 from dranikpg/app-constructor

Generic app constructor
This commit is contained in:
Farook Al-Sammarraie 2022-05-24 00:46:14 +03:00 committed by GitHub
commit 0fb91aebbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 0 deletions

View File

@ -60,6 +60,12 @@ namespace crow
Crow()
{}
/// Construct Crow with a subset of middleware
template<typename... Ts>
Crow(Ts&&... ts):
middlewares_(make_middleware_tuple(std::forward<Ts>(ts)...))
{}
/// Process an Upgrade request
///
@ -492,6 +498,17 @@ namespace crow
cv_started_.wait(lock);
}
private:
template<typename... Ts>
std::tuple<Middlewares...> make_middleware_tuple(Ts&&... ts)
{
auto fwd = std::forward_as_tuple((ts)...);
return std::make_tuple(
std::forward<Middlewares>(
black_magic::tuple_extract<Middlewares, decltype(fwd)>(fwd))...);
}
private:
std::uint8_t timeout_{5};
uint16_t port_ = 80;

View File

@ -281,6 +281,30 @@ namespace crow
static const int value = 1 + tuple_index<T, std::tuple<Types...>>::value;
};
// Extract element from forward tuple or get default
#ifdef CROW_CAN_USE_CPP14
template<typename T, typename Tup>
typename std::enable_if<has_type<T&, Tup>::value, typename std::decay<T>::type&&>::type
tuple_extract(Tup& tup)
{
return std::move(std::get<T&>(tup));
}
#else
template<typename T, typename Tup>
typename std::enable_if<has_type<T&, Tup>::value, T&&>::type
tuple_extract(Tup& tup)
{
return std::move(std::get<tuple_index<T&, Tup>::value>(tup));
}
#endif
template<typename T, typename Tup>
typename std::enable_if<!has_type<T&, Tup>::value, T>::type
tuple_extract(Tup&)
{
return T{};
}
// Kind of fold expressions in C++11
template<bool...>
struct bool_pack;

View File

@ -1514,6 +1514,21 @@ TEST_CASE("local_middleware")
app.stop();
} // local_middleware
struct OnlyMoveConstructor
{
OnlyMoveConstructor(int) {}
OnlyMoveConstructor(const OnlyMoveConstructor&) = delete;
OnlyMoveConstructor(OnlyMoveConstructor&&) = default;
};
TEST_CASE("app_constructor")
{
App<NullMiddleware, OnlyMoveConstructor, FirstMW<false>, SecondMW<false>>
app1(OnlyMoveConstructor(1), SecondMW<false>{});
App<NullMiddleware, OnlyMoveConstructor, FirstMW<false>, SecondMW<false>>
app2(FirstMW<false>{}, OnlyMoveConstructor(1));
} // app_constructor
TEST_CASE("middleware_blueprint")
{
// Same logic as middleware_context, but middleware is added with blueprints