#pragma once /* ABSTRACT DEVICE COMPONENTS LIBRARY */ #include #include #include "../common/adc_traits.h" /* DEFINITIONS OF NETWORK COMPONENTS INTERFACES */ namespace adc::traits { template // from https://stackoverflow.com/questions/74383254/concept-that-models-only-the-stdchrono-duration-types concept adc_time_duration_c = requires { [](std::type_identity>) {}(std::type_identity()); }; template struct adc_duration_common_type; template struct adc_duration_common_type : std::common_type { }; template struct adc_duration_common_type : adc_duration_common_type, Ts...> { }; template using adc_duration_common_type_t = typename adc_duration_common_type::type; /* all STL helper duration types */ using adc_common_duration_t = adc_duration_common_type_t; /* struct NetService { typedef ImplementationDependentT netservice_ident_t; typedef ImplementationDependentT async_ctx_t; typedef ImplementationDependentT endpoint_t; template auto asyncAccept(const endpoint_t&, async_ctx_t&, const std::chrono::duration&) template auto asyncConnect(const endpoint_t&, async_ctx_t&, const std::chrono::duration&) template auto asyncSend(const R&, async_ctx_t&, const std::chrono::duration&) template auto asyncReceived(async_ctx_t&, const std::chrono::duration&) template auto accept(const endpoint_t&, const std::chrono::duration&) template auto connect(const endpoint_t&, const std::chrono::duration&) template auto send(const R&, const std::chrono::duration&) template R received(const std::chrono::duration&) } */ template concept adc_netservice_c = adc_input_char_range && adc_output_char_range && adc_time_duration_c && requires(SRVT srv, const SRVT srv_const) { typename SRVT::netservice_ident_t; // netservice_ident_t ident() const { srv_const.ident() } -> std::same_as; typename SRVT::async_ctx_t; typename SRVT::endpoint_t; // asynchronous (non-blocking) operations asyncAccept(std::declval(), std::declval(), std::declval()); asyncConnect(std::declval(), std::declval(), std::declval()); asyncSend(std::declval(), std::declval(), std::declval()); asyncReceive(std::declval(), std::declval()); // synchronous (blocking) operations accept(std::declval(), std::declval()); connect(std::declval(), std::declval()); send(std::declval(), std::declval()); { receive(std::declval()) } -> std::same_as; // requires requires { // [](SRVT& srv_obj, const typename SRVT::endpoint_t& endpoint, const typename // SRVT::async_ctx_t& ctx, // const DURT& timeout) { // srv_obj.asyncAccept(endpoint, ctx, timeout); // srv_obj.asyncConnect(endpoint, ctx, timeout); // srv_obj.accept(endpoint, timeout); // srv_obj.connect(endpoint, timeout); // }(srv, typename SRVT::endpoint_t(), typename SRVT::async_ctx_t(), // std::chrono::seconds(1)); // [](SRVT& srv_obj, const R& msg, const // typename SRVT::async_ctx_t& ctx, // const DURT& timeout) { // srv_obj.asyncSend(msg, ctx, timeout); // srv_obj.send(msg, timeout); // }(srv, std::span(), typename SRVT::async_ctx_t(), // std::chrono::seconds(1)); // [](SRVT& srv_obj, R& msg, const typename // SRVT::async_ctx_t& ctx, // const DURT& timeout) { // srv_obj.asyncReceive(ctx, timeout); // msg = srv_obj.receive(timeout); // }(srv, std::string(), typename SRVT::async_ctx_t(), std::chrono::seconds(1)); // }; }; /* NETWORK SESSION */ template concept adc_netsession_c = std::derived_from> && requires(SESST sess, const SESST sess_const) { typename SESST::netsession_ident_t; // netsession_ident_t ident() const { sess_const.ident() } -> std::same_as; sess.start(); sess.stop(); }; /* NETWORK SESSION-LEVEL PROTOCOL */ template concept adc_netsession_proto_c = requires(SESS_PROTOT proto, const SESS_PROTOT proto_const) { typename SESS_PROTOT::proto_ident_t; // proto_ident_t ident() const (const method) { proto_const.ident() } -> std::same_as; [](const SESS_PROTOT& proto, IT begin, IT end) -> std::tuple { return proto.parse(begin, end); }; // must return a view of R-range! [](SESS_PROTOT obj, const R& r) -> std::ranges::view auto { return obj.from(r); }( proto, std::string()); }; } // namespace adc::traits