Commit d698fbe4 authored by octal's avatar octal

Added a Http::make_handler similar to calling std::make_shared manually except...

Added a Http::make_handler similar to calling std::make_shared manually except that it checks if the handler is correctly defined
parent b8245671
...@@ -26,7 +26,7 @@ int main() { ...@@ -26,7 +26,7 @@ int main() {
Http::Endpoint server(addr); Http::Endpoint server(addr);
server.init(opts); server.init(opts);
server.setHandler(std::make_shared<HelloHandler>()); server.setHandler(Http::make_handler<HelloHandler>());
server.serve(); server.serve();
server.shutdown(); server.shutdown();
......
...@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) { ...@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) {
.threads(thr) .threads(thr)
.flags(Net::Tcp::Options::InstallSignalHandler); .flags(Net::Tcp::Options::InstallSignalHandler);
server->init(opts); server->init(opts);
server->setHandler(std::make_shared<MyHandler>()); server->setHandler(Http::make_handler<MyHandler>());
server->serve(); server->serve();
std::cout << "Shutdowning server" << std::endl; std::cout << "Shutdowning server" << std::endl;
......
...@@ -26,6 +26,23 @@ namespace Net { ...@@ -26,6 +26,23 @@ namespace Net {
namespace Http { namespace Http {
namespace details {
struct prototype_tag { };
template<typename P>
struct IsHttpPrototype {
template<typename U> static auto test(U *) -> decltype(typename U::tag());
template<typename U> static auto test(...) -> std::false_type;
static constexpr bool value =
std::is_same<decltype(test<P>(nullptr)), prototype_tag>::value;
};
};
#define HTTP_PROTOTYPE(Class) \
PROTOTYPE_OF(Net::Tcp::Handler, Class) \
typedef Net::Http::details::prototype_tag tag;
namespace Private { namespace Private {
class ParserBase; class ParserBase;
template<typename T> struct Parser; template<typename T> struct Parser;
...@@ -739,6 +756,14 @@ private: ...@@ -739,6 +756,14 @@ private:
Private::Parser<Http::Request>& getParser(const std::shared_ptr<Tcp::Peer>& peer) const; Private::Parser<Http::Request>& getParser(const std::shared_ptr<Tcp::Peer>& peer) const;
}; };
template<typename H, typename... Args>
std::shared_ptr<H> make_handler(Args&& ...args) {
static_assert(std::is_base_of<Handler, H>::value, "An http handler must inherit from the Http::Handler class");
static_assert(details::IsHttpPrototype<H>::value, "An http handler must be an http prototype, did you forget the HTTP_PROTOTYPE macro ?");
return std::make_shared<H>(std::forward<Args>(args)...);
}
} // namespace Http } // namespace Http
} // namespace Net } // namespace Net
......
...@@ -15,17 +15,9 @@ struct Prototype { ...@@ -15,17 +15,9 @@ struct Prototype {
virtual std::shared_ptr<Class> clone() const = 0; virtual std::shared_ptr<Class> clone() const = 0;
}; };
template<typename Base, typename Class>
struct Prototypable {
};
#define PROTOTYPE_OF(Base, Class) \ #define PROTOTYPE_OF(Base, Class) \
private: \ private: \
std::shared_ptr<Base> clone() const { \ std::shared_ptr<Base> clone() const { \
return std::make_shared<Class>(); \ return std::make_shared<Class>(); \
} \ } \
public: public:
#define HTTP_PROTOTYPE(Class) \
PROTOTYPE_OF(Net::Tcp::Handler, Class)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment