#pragma once #include #include #include #include #include #include namespace ipc { // types using byte_t = std::uint8_t; template struct uint; template <> struct uint<8 > { using type = std::uint8_t ; }; template <> struct uint<16> { using type = std::uint16_t; }; template <> struct uint<32> { using type = std::uint32_t; }; template <> struct uint<64> { using type = std::uint64_t; }; template using uint_t = typename uint::type; // constants enum : std::size_t { invalid_value = (std::numeric_limits::max)(), data_length = 64, name_length = 64, send_wait_for = 100 // ms }; enum class relat { // multiplicity of the relationship single, multi }; enum class trans { // transmission unicast, broadcast }; // producer-consumer policy flag template struct wr {}; // concept helpers template using Requires = std::enable_if_t; // pimpl small object optimization helpers template using IsImplComfortable = Requires<(sizeof(T) <= sizeof(T*)), R>; template using IsImplUncomfortable = Requires<(sizeof(T) > sizeof(T*)), R>; template constexpr auto make_impl(P&&... params) -> IsImplComfortable { T* buf {}; ::new (&buf) T { std::forward

(params)... }; return buf; } template constexpr auto impl(T* const (& p)) -> IsImplComfortable { return reinterpret_cast(&const_cast(reinterpret_cast(p))); } template constexpr auto clear_impl(T* p) -> IsImplComfortable { if (p != nullptr) impl(p)->~T(); } template constexpr auto make_impl(P&&... params) -> IsImplUncomfortable { return new T { std::forward

(params)... }; } template constexpr auto clear_impl(T* p) -> IsImplUncomfortable { delete p; } template constexpr auto impl(T* const (& p)) -> IsImplUncomfortable { return p; } template struct pimpl { template constexpr static T* make(P&&... params) { return make_impl(std::forward

(params)...); } #if __cplusplus >= 201703L constexpr void clear() { #else /*__cplusplus < 201703L*/ void clear() { #endif/*__cplusplus < 201703L*/ clear_impl(static_cast(const_cast(this))); } }; } // namespace ipc