#pragma once #include #include "transfer.hpp" namespace saw { namespace rmt { struct Loopback {}; } template class data_server, Encoding, rmt::Loopback> { private: typename impl::data_server_redux>::type>::type values_; public: /** * Get data from client */ template error_or send(const data& dat, id store_id){ auto& vals = std::get>>(values_); try { auto insert_res = vals.emplace(std::make_pair(store_id.get_value(), std::move(dat))); if(!insert_res.second){ return make_error(); } }catch(std::exception& ){ return make_error(); } return void_t{}; } /** * */ template error_or allocate(id store_id){ return make_error(); } template error_or> receive(id store_id){ auto& vals = std::get>>(values_); auto find_res = vals.find(store_id.get_value()); if(find_res == vals.end()){ return make_error(); } auto& dat = find_res->second; return dat; } template error_or erase(id store_id){ auto& vals = std::get>>(values_); auto erase_op = vals.erase(store_id.get_value()); if(erase_op == 0u){ return make_error(); } return void_t{}; } template error_or*> find(id store_id){ auto& vals = std::get>>(values_); auto find_res = vals.find(store_id.get_value()); if(find_res == vals.end()){ return make_error(); } auto& dat = find_res->second; return &dat; } }; /** * Client for transporting data to remote and receiving data back */ template class data_client, Encoding, rmt::Loopback> { private: /** * Corresponding server for this client */ data_server, Encoding, rmt::Loopback>* srv_; /** * The next id for identifying issues on the remote side. */ uint64_t next_id_; public: /** * Main constructor */ data_client(data_server, Encoding, rmt::Loopback>& srv__): srv_{&srv__}, next_id_{0u} {} /** * Send data to the remote. */ template error_or> send(const data& dat){ id dat_id{next_id_}; auto eov = srv_->send(dat, dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } ++next_id_; return dat_id; } /** * Receive data */ template conveyor> receive(id dat_id){ auto eov = srv_->receive(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto& val = eov.get_value(); return std::move(val); } /** * Erase data */ template error_or erase(id dat_id){ return srv_->erase(dat_id); } /** * An exception for the Loopback backend. Here we can safely use find from * the client side. */ template error_or*> find(id dat_id){ auto eov = srv_->find(dat_id); if(eov.is_error()){ auto& err = eov.get_error(); return std::move(err); } auto val = eov.get_value(); return val; } }; }