124 lines
3.0 KiB
C++
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
|