ADC/net/adc_netservice.h
Timur A. Fatkhullin ebe93f1d74 ...
2024-06-17 23:39:58 +03:00

124 lines
3.0 KiB
C++

#pragma once
/*
ABSTRACT DEVICE COMPONENTS LIBRARY
*/
#include <chrono>
#include <utility>
#include "adc_netmsg.h"
namespace adc
{
namespace traits
{
template <typename T>
// from https://stackoverflow.com/questions/74383254/concept-that-models-only-the-stdchrono-duration-types
concept adc_time_duration_c = requires {
[]<class Rep, class Period>(std::type_identity<std::chrono::duration<Rep, Period>>) {}(std::type_identity<T>());
};
} // namespace traits
/* The class incapsulates network operations */
template <typename ImplT>
class AdcNetService : public ImplT
{
public:
using impl_t = ImplT;
using typename ImplT::endpoint_t;
using typename ImplT::timeout_t;
template <typename... ImplCtorArgTs>
AdcNetService(ImplCtorArgTs&&... ctor_args) : impl_t(std::forward<ImplCtorArgTs>(ctor_args)...)
{
}
virtual ~AdcNetService() = default;
/* asynchronuos operations */
// start accepting client connections (server side)
template <typename... ArgTs>
auto asyncAccept(const endpoint_t& end_point, const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::asyncAccept(end_point, timeout, std::forward<ArgTs>(args)...);
}
// open connection (client side)
template <typename... ArgTs>
auto asyncConnect(const endpoint_t& end_point, const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::asyncConnect(end_point, timeout, std::forward<ArgTs>(args)...);
}
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
auto asyncSend(const NetMessageT& msg, const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::asyncSend(msg, timeout, std::forward<ArgTs>(args)...);
}
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
auto asyncReceive(const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::asyncReceive(timeout, std::forward<ArgTs>(args)...);
}
/* blocking operations (throw exceptions if there is an error) */
template <typename... ArgTs>
auto connect(const endpoint_t& endpoint, const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::connect(endpoint, timeout, std::forward<ArgTs>(args)...);
}
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
auto send(const NetMessageT& msg, const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::send(msg, timeout, std::forward<ArgTs>(args)...);
}
template <traits::adc_netmessage_c NetMessageT, typename... ArgTs>
NetMessageT receive(const timeout_t& timeout, ArgTs&&... args)
{
return impl_t::receive(timeout, std::forward<ArgTs>(args)...);
}
template <typename... ArgTs>
auto close(ArgTs&&... args)
{
return impl_t::close(std::forward<ArgTs>(args)...);
}
};
namespace traits
{
template <typename T>
concept adc_netservice_c = requires {
typename T::impl_t;
std::derived_from<T, AdcNetService<typename T::impl_t>>;
};
} // namespace traits
} // namespace adc