ADC/net/adc_net_concepts.h
Timur A. Fatkhullin 8d6e1bb59c ...
2024-11-06 00:15:20 +03:00

221 lines
9.3 KiB
C++

#pragma once
/*
ABSTRACT DEVICE COMPONENTS LIBRARY
*/
#include <concepts>
#include "../common/adc_traits.h"
/* DEFINITIONS OF NETWORK COMPONENTS INTERFACES */
namespace adc::interfaces
{
template <traits::adc_time_duration_c... Ts>
struct adc_duration_common_type;
template <traits::adc_time_duration_c T1, traits::adc_time_duration_c T2>
struct adc_duration_common_type<T1, T2> : std::common_type<T1, T2> {
};
template <traits::adc_time_duration_c T1, traits::adc_time_duration_c T2, traits::adc_time_duration_c... Ts>
struct adc_duration_common_type<T1, T2, Ts...> : adc_duration_common_type<std::common_type_t<T1, T2>, Ts...> {
};
template <traits::adc_time_duration_c... Ts>
using adc_duration_common_type_t = typename adc_duration_common_type<Ts...>::type;
/* all STL helper duration types */
using adc_common_duration_t = adc_duration_common_type_t<std::chrono::nanoseconds,
std::chrono::microseconds,
std::chrono::milliseconds,
std::chrono::seconds,
std::chrono::minutes,
std::chrono::hours,
std::chrono::days,
std::chrono::weeks,
std::chrono::months,
std::chrono::years>;
// concepts for asynchronous operation callback callable first argument type (asynchronous operation error)
// 1) the type must be convertible to boolean and
// a) true - asynchronous operation completed without errors
// b) false - an error occured
template <typename ERRT>
concept adc_async_callback_err_t = std::convertible_to<std::remove_cvref_t<ERRT>, bool> ||
requires(const std::remove_cvref_t<ERRT> err) { err.operator bool(); };
// concepts for asynchronous opereration callback callable
// 1) the type must be a callable with at least 1 input argument
// 2) the first argument type must satisfy the concept adc_async_callback_err_t
template <typename T>
concept adc_async_callback_t = traits::adc_is_callable<T> && (traits::adc_func_traits<T>::arity >= 1) &&
adc_async_callback_err_t<traits::adc_func_arg1_t<T>>;
/*
struct NetService {
typedef ImplementationDependentT netservice_ident_t;
typedef ImplementationDependentT async_call_ctx_t;
typedef ImplementationDependentT endpoint_t;
template<typename Rep, typename Period>
auto asyncAccept(const endpoint_t&, async_call_ctx_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period>
auto asyncConnect(const endpoint_t&, async_call_ctx_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period, adc::traits::adc_input_char_range R>
auto asyncSend(const R&, async_call_ctx_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period>
auto asyncReceived(async_call_ctx_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period>
auto accept(const endpoint_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period>
auto connect(const endpoint_t&, const std::chrono::duration<Rep, Period>&)
template<typename Rep, typename Period, adc::traits::adc_input_char_range R>
auto send(const R&, const std::chrono::duration<Rep, Period>&)
template<adc::traits::adc_output_char_range R, typename Rep, typename Period>
R receive(const std::chrono::duration<Rep, Period>&)
}
*/
template <typename SRVT>
concept adc_netservice_c = requires(SRVT srv, const SRVT srv_const) {
// concept adc_netservice_c = std::movable<SRVT> && requires(SRVT srv, const SRVT srv_const) {
typename SRVT::netservice_ident_t; // service identificator type
typename SRVT::send_msg_t; // sending message type
typename SRVT::recv_msg_t; // receiving message type
typename SRVT::timeout_t; // a type representing timeout (e.g. time duration)
typename SRVT::endpoint_t; // a type representing endpoint of the network service
// underlying protocol
// asynchronous operation error
requires adc_async_callback_err_t<typename SRVT::async_callback_err_t>;
// callback callables for asynchronous operations
requires adc_async_callback_t<typename SRVT::async_connect_callback_t>;
requires adc_async_callback_t<typename SRVT::async_send_callback_t>;
requires adc_async_callback_t<typename SRVT::async_receive_callback_t>;
// acceptor type
requires std::is_class_v<typename SRVT::acceptor_t>;
requires adc_async_callback_t<typename SRVT::acceptor_t::async_accept_callback_t>;
requires requires(typename SRVT::acceptor_t acc) {
acc.asyncAccept(std::declval<typename SRVT::acceptor_t::async_accept_callback_t>(),
std::declval<const typename SRVT::timeout_t&>());
// { acc.accept(std::declval<const typename SRVT::timeout_t&>()) } -> std::same_as<SRVT>;
acc.accept(std::declval<const typename SRVT::timeout_t&>());
};
// netservice_ident_t ident() const
{ srv_const.ident() } -> std::same_as<typename SRVT::netservice_ident_t>;
// typename SRVT::async_call_ctx_t;
// asynchronous (non-blocking) operations
// srv.asyncAccept(std::declval<const typename SRVT::endpoint_t&>(), std::declval<typename
// SRVT::async_call_ctx_t&>(),
// std::declval<const typename SRVT::timeout_t&>());
srv.asyncConnect(std::declval<const typename SRVT::endpoint_t&>(),
std::declval<typename SRVT::async_connect_callback_t>(),
std::declval<const typename SRVT::timeout_t&>());
srv.asyncSend(std::declval<const typename SRVT::send_msg_t&>(),
std::declval<typename SRVT::async_send_callback_t>(),
std::declval<const typename SRVT::timeout_t&>());
srv.asyncReceive(std::declval<typename SRVT::async_receive_callback_t>(),
std::declval<const typename SRVT::timeout_t&>());
// synchronous (blocking) operations
// srv.accept(std::declval<const typename SRVT::endpoint_t&>(), std::declval<const typename SRVT::timeout_t&>());
srv.connect(std::declval<const typename SRVT::endpoint_t&>(), std::declval<const typename SRVT::timeout_t&>());
srv.send(std::declval<const typename SRVT::send_msg_t&>(), std::declval<const typename SRVT::timeout_t&>());
{ srv.receive(std::declval<const typename SRVT::timeout_t&>()) } -> std::same_as<typename SRVT::recv_msg_t>;
srv.close();
};
/* NETWORK SESSION */
template <typename SESST>
concept adc_netsession_c =
std::derived_from<SESST, std::enable_shared_from_this<SESST>> && requires(SESST sess, const SESST sess_const) {
typename SESST::netsession_ident_t;
requires adc_netservice_c<typename SESST::netservice_t>;
typename SESST::netsession_ctx_t;
requires std::constructible_from<SESST, const typename SESST::netsession_ident_t,
// std::shared_ptr<typename SESST::netservice_t>,
typename SESST::netservice_t, typename SESST::netsession_ctx_t>;
// netsession_ident_t ident() const
{ sess_const.ident() } -> std::same_as<typename SESST::netsession_ident_t>;
sess.start();
sess.stop();
};
/* NETWORK SESSION-LEVEL PROTOCOL */
template <typename SESS_PROTOT, typename BUFFT = std::string_view>
concept adc_netsession_proto_c =
traits::adc_input_char_range<BUFFT> && 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<typename SESS_PROTOT::proto_ident_t>;
// typename SESS_PROTOT::search_result_t;
// search for the first occurence of valid protocol sequence in input user byte sequence
// the method must return std::tuple<begin, end, flag>:
// start - input range iterator of the sequence first byte
// stop - input range iterator of the sequence end ("after-the-last" byte!!!)
// flag - true if valid sequence was found, false - otherwise
{
proto.search(std::declval<const BUFFT&>())
// } -> std::same_as<std::tuple<std::ranges::iterator_t<BUFFT>, std::ranges::iterator_t<BUFFT>, bool>>;
} -> traits::adc_view_or_output_char_range;
// construct netsession protocol representation of input user byte sequence
// the method must return a range of char range views or output char range
{ proto.toProto(std::declval<const BUFFT&>()) } -> traits::adc_range_of_view_or_output_char_range;
// return user byte sequence from input netsession protocol representation
// the method must return a view of char range or output char range
{ proto.fromProto(std::declval<const BUFFT&>()) } -> traits::adc_view_or_output_char_range;
};
} // namespace adc::interfaces