
рдХрдИ рд╕рд╛рд▓ рдкрд╣рд▓реЗ, C ++ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд┐рдд C ++ 11 рдорд╛рдирдХ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рдерд╛, рдЬреЛ рдмрд╣реБрдд рд╕реА рдирдИ рдЪреАрдЬреЗрдВ рд▓рд╛рдпрд╛ рдерд╛ред рдФрд░ рдореБрдЭреЗ рд░реЛрдЬрд╝рдорд░реНрд░рд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░ рдЬрд▓реНрджреА рд╕реЗ рдЬрд╛рдиреЗ рдХрд╛ рд╢реМрдХ рдерд╛ред C ++ 14 рдФрд░ 17 рдкрд░ рдЬрд╛рдПрдВ рдпрд╣ рдирд╣реАрдВ рдерд╛ред рдРрд╕рд╛ рд▓рдЧрддрд╛ рдерд╛ рдХрд┐ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рдХреЛрдИ рд╕реЗрдЯ рдирд╣реАрдВ рдерд╛ рдЬреЛ рдХрд┐ рд░реБрдЪрд┐ рдХрд╛ рд╣реЛрдЧрд╛ред рд╡рд╕рдВрдд рдореЗрдВ, рдореИрдВрдиреЗ рднрд╛рд╖рд╛ рдХреЗ рдирд╡рд╛рдЪрд╛рд░реЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдФрд░ рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдирд╡рд╛рдЪрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдкрдиреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдп рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рд▓рдВрдмрд╛ рд╕реЛрдЪрдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рдереАред рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдЖрд░рдкреАрд╕реА рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдФрд░ рдореИрдХреНрд░реЛрдЬрд╝ рдФрд░ рдХреЛрдб рдкреАрдврд╝реА рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд┐рдирд╛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ - рд╕рднреА рд╕реА ++ рдореЗрдВред рдпрд╣ рднрд╛рд╖рд╛ рдХреА рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╡ рдерд╛ред
рд╡рд┐рдЪрд╛рд░, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди, рд░реЗрдбрд┐рдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛, рд╕реБрдзрд╛рд░ - рд╕рдм рдХреБрдЫ рд╡рд╕рдВрдд рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рд╢реБрд░реБрдЖрддреА рдЧрд░реНрдорд┐рдпреЛрдВ рдореЗрдВред рдЕрдВрдд рддрдХ, рд╡реЗ рд╣реИрдмрд░ рдкрд░ рдкреЛрд╕реНрдЯ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗред
рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЕрдкрдиреЗ RPC рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рд╣реИ? рд╢рд╛рдпрдж рдкреЛрд╕реНрдЯ рдХреА рд╕рд╛рдордЧреНрд░реА рдЖрдкрдХреЛ рд▓рдХреНрд╖реНрдп, рд╡рд┐рдзрд┐рдпреЛрдВ, рд╕рд╛рдзрдиреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рд╕рдорд╛рдкреНрдд рдПрдХ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧреА рдпрд╛ рдХреБрдЫ рдЦреБрдж рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдЧреА ...
рдкрд░рд┐рдЪрдп
RPC (рджреВрд░рд╕реНрде рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЙрд▓) рдХреЛрдИ рдирдпрд╛ рд╡рд┐рд╖рдп рдирд╣реАрдВ рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдХрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВред рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рднрд┐рдиреНрди рдбреЗрдЯрд╛ рд╕реНрд╡рд░реВрдкреЛрдВ рдФрд░ рдкрд░рд┐рд╡рд╣рди рдХреЗ рд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╕рдм рдХреБрдЫ рдмрд┐рдВрджреБрдУрдВ рдореЗрдВ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:
- рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬреЗрд╢рди / Deserialization
- рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ
- рд░рд┐рдореЛрдЯ рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрди
- рд╡рд╛рдкрд╕реА рдХрд╛ рдкрд░рд┐рдгрд╛рдо
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд╛рдВрдЫрд┐рдд рд▓рдХреНрд╖реНрдп рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдПрдХ рджреВрд░рд╕реНрде рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЙрдЪреНрдЪ рдЧрддрд┐ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдФрд░ рдкреНрд░рдпреЛрдЬреНрдп рдХреЛ рддреНрдпрд╛рдЧрдиреЗ рдХрд╛ рд▓рдХреНрд╖реНрдп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рд▓реЗрдЦрди рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдЖрд░рд╛рдо рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рдВрднрд╡рддрдГ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдереЛрдбрд╝рд╛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓рдХреНрд╖реНрдп рдФрд░ рдЙрдкрдХрд░рдг рдЕрд▓рдЧ рд╣реИрдВ ... рдореИрдВ рдЖрд░рд╛рдо рдФрд░ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдкреНрд░рджрд░реНрд╢рди рдЪрд╛рд╣рддрд╛ рдерд╛ред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдиреАрдЪреЗ C ++ 14/17 рдореЗрдВ RPC рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдХрджрдо рджрд┐рдП рдЧрдП рд╣реИрдВ, рдФрд░ рдХреБрдЫ рднрд╛рд╖рд╛ рдирд╡рд╛рдЪрд╛рд░реЛрдВ рдкрд░ рдЬреЛрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдпрд╣ рд╕рд╛рдордЧреНрд░реА рд╕рд╛рдордиреЗ рдЖрдИ рд╣реИред
рд╕рд╛рдордЧреНрд░реА рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рд╣реИ рдЬреЛ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЕрдкрдиреЗ рдЖрд░рдкреАрд╕реА рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдФрд░, рд╢рд╛рдпрдж, рдЕрдм рддрдХ, рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ, рд╕рдорд╛рди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рдордирд╛ рдХрд┐рдП рдЧрдП рдЕрдиреНрдп рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдЕрдиреБрднрд╡ рдХрд╛ рд╡рд┐рд╡рд░рдг рджреЗрдЦрдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ред
рдХреНрд░рдордмрджреНрдзрддрд╛
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЖрдк рдХреЛрдб рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдореИрдВ рдПрдХ рдХрд╛рд░реНрдп рдмрдирд╛рдКрдВрдЧрд╛:
- рд╕рднреА рд╡рд┐рдзрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рд▓реМрдЯрд╛ рд╣реБрдЖ рдкрд░рд┐рдгрд╛рдо рдЯрдкрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдЦреБрдж рдХреЛ рдмреБрд▓рд╛рдпрд╛ рддрд░реАрдХреЗ рдЯреНрдпреВрдкрд▓реНрд╕ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдФрд░ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдирд╣реАрдВ рд╣реИрдВред
- рдЯреНрдпреВрдкрд▓ рдкреИрдХ рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рдмрдлрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕рдХрд╛ рдкреНрд░рд╛рд░реВрдк рддрдп рдирд╣реАрдВ рд╣реИ
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рд╕рд░рд▓реАрдХреГрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреНрд░рдорд┐рдХ рдХреЛрдб рд╣реИред
string_serializernamespace rpc::type { using buffer = std::vector<char>; }
рдФрд░ рдореБрдЦреНрдп рдлрдВрдХреНрд╢рди рдХреЛрдб, рдЬреЛ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдореБрдЦреНрдп рд╕рдорд╛рд░реЛрд╣ int main() { try { std::tuple args{10, std::string{"Test string !!!"}, 3.14}; rpc::packer::string_serializer serializer; auto pack = serializer.save(args); std::cout << "Pack data: " << std::string{begin(pack), end(pack)} << std::endl; decltype(args) params; serializer.load(pack, params);
рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд▓рд╣рдЬреЗрд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдЙрд╕ рдмрдлрд░ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдкреВрд░реЗ рдбреЗрдЯрд╛ рдПрдХреНрд╕рдЪреЗрдВрдЬ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
namespace rpc::type { using buffer = std::vector<char>; }
рд╕реАрд░рд┐рдпрд▓рд╛рдЗрдЬрд╝рд░ рдореЗрдВ рдмрдлрд╝рд▓ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ (рд╕рд╣реЗрдЬрдиреЗ) рдФрд░ рдЗрд╕реЗ рдмрдлрд╝рд░ (рд▓реЛрдб) рд╕реЗ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╣реИрдВ
рд╕рд╣реЗрдЬрдиреЗ рдХреА рд╡рд┐рдзрд┐ рдПрдХ рдЯрдкрд▓ рд▓реЗрддреА рд╣реИ рдФрд░ рдПрдХ рдмрдлрд░ рд▓реМрдЯрд╛рддреА рд╣реИред
template <typename ... T> type::buffer save(std::tuple<T ... > const &tuple) const { auto str = to_string(tuple, std::make_index_sequence<sizeof ... (T)>{}); return {begin(str), end(str)}; }
рдПрдХ рдЯреНрдпреВрдкрд▓ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИред рдРрд╕реЗ рдкреИрдЯрд░реНрди C ++ 11 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ред рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдХрд┐рд╕реА рддрд░рд╣ рдРрд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рд╕реА ++ 14 рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ - рдкреВрд░реНрдгрд╛рдВрдХ (рд╕реВрдЪрдХрд╛рдВрдХ) рдХрд╛ рдПрдХ рдХреНрд░рдоред рдореЗрдХ_рдЗрдВрдбреЗрдХреНрд╕_ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рдХрд╛рд░ рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрдХреНрд░рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:
template< class T, T... Ints > class integer_sequence; template<class T, T N> using make_integer_sequence = std::integer_sequence<T, >; template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
C ++ 11 рдореЗрдВ рдПрдХ рд╕рдорд╛рди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд▓реЗ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХрд╛ рдРрд╕рд╛ рдХреНрд░рдо рдЯрдкрд▓ рдХреЛ "рдЧреБрдЬрд░рдирд╛" рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ:
template <typename T, std::size_t ... I> std::string to_string(T const &tuple, std::index_sequence<I ... >) const { std::stringstream stream; auto put_item = [&stream] (auto const &i) { if constexpr (std::is_same_v<std::decay_t<decltype(i)>, std::string>) stream << std::quoted(i) << ' '; else stream << i << ' '; }; (put_item(std::get<I>(tuple)), ... ); return std::move(stream.str()); }
To_string рд╡рд┐рдзрд┐ рдирд╡реАрдирддрдо C ++ рдорд╛рдирдХреЛрдВ рдХреА рдХрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред
рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд▓рд╣рдЬреЗC ++ 14 рдореЗрдВ, рд▓реИрдореНрдмреНрдбрд╛ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдСрдЯреЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЧрдпрд╛ред рдпрд╣ рдЕрдХреНрд╕рд░ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордпред
C ++ 17 рдореЗрдВ рдПрдХ
рджреГрдврд╝ рд╕рдВрдХрд▓реНрдк рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдЬреЛ рдЖрдкрдХреЛ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреИрд╕реЗ:
(put_item(std::get<I>(tuple)), ... );
рджрд┐рдП рдЧрдП рдЕрдВрд╢ рдореЗрдВ, рдкреБрдЯ_рдЯреЗрдо рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдП рдЧрдП рдЯреНрдпреВрдкрд▓ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдордВрдЪ рдФрд░ рд╕рдВрдХрд▓рдХ рд╕реЗ рд╕реНрд╡рддрдВрддреНрд░ рдЕрдиреБрдХреНрд░рдо рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрддрд╛ рд╣реИред рдРрд╕рд╛ рд╣реА рдХреБрдЫ C ++ 11 рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
template <typename тАж T> void unused(T && тАж ) {}
рд▓реЗрдХрд┐рди рддрддреНрд╡реЛрдВ рдХреЛ рдХрд┐рд╕ рдХреНрд░рдо рдореЗрдВ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдпрд╣ рдХрдВрдкрд╛рдЗрд▓рд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛ред
рдХрдИ рдЙрдкрдирд╛рдо C ++ 17 рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, decay_t, рдЬрд┐рд╕рдиреЗ рдлреЙрд░реНрдо рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдХрдо рдХрд░ рджрд┐рдпрд╛:
typename decay<T>::type
рдХрдо рдирд┐рд░реНрдорд╛рдг рд▓рд┐рдЦрдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЬрдЧрд╣ рд╣реИред рдПрдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдбрд┐рдЬрд╝рд╛рдЗрди, рдЬрд╣рд╛рдВ рдЯрд╛рдЗрдк рдФрд░ рдирд╛рдо рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреЛ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЙрд▓рди рдФрд░ рдХреЛрдг рдХреЛрд╖реНрдардХ рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдбрд░рд╛рд╡рдирд╛ рд▓рдЧрддрд╛ рд╣реИред рдЖрдк рдЕрдкрдиреЗ рдХреБрдЫ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЛ рдХреИрд╕реЗ рдбрд░рд╛ рд╕рдХрддреЗ рд╣реИрдВред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╡реЗ рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ, рдЯрд╛рдЗрдкрдиреЗрдо рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреА рдЗрдЪреНрдЫрд╛ рдиреЗ рднрд╛рд╖рд╛ рдХрд╛ рдПрдХ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдирд┐рд░реНрдорд╛рдг "рдЕрдЧрд░ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрдк" рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдХрдИ рдирд┐рдЬреА рд╡рд┐рд╖рдпреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рд╕реЗ рдмрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рд╣реИред рдХрдИ рдХреЛ рд╕рд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рд╕реНрдХреЗрд▓реЗрдмрд┐рд▓рд┐рдЯреА рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдмрд╣реБрдд рдЕрдЪреНрдЫреЗ рдирд╣реАрдВ рд╣реИрдВред рд░рди-рдЯрд╛рдЗрдо / рдХрдВрдкрд╛рдЗрд▓-рдЯрд╛рдЗрдо рдкреЙрд▓рд┐рдореЛрд░реНрдлрд╝рд┐рдЬреНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдФрд░ "рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рдХрд▓реНрдк" рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдЕрдзрд┐рднрд╛рд░ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдлрд┐рд░ "рдЕрдЧрд░ рдмрд╛рдзрд╛" ... рдХреЙрдореНрдкреИрдХреНрдЯрдиреЗрд╕ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдЗрд╕рдХреЗ рдкреНрд░рддрд┐ рдЙрджрд╛рд╕реАрди рдирд╣реАрдВ рдЫреЛрдбрд╝рддреА рд╣реИред рднрд╛рд╖рд╛ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХрд╛ рдорддрд▓рдм рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдХреНрд░рдорд╛рдВрдХрди рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХрд╛рдо рдХреЗ рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдПрдХ рд╕реНрдЯреНрд░реАрдо рдкрд░ рдмрдЪрдд рд╣реЛрддреА рд╣реИ рдФрд░ рдЗрд╕рд╕реЗ рд░реАрдбрд┐рдВрдЧ рд╣реЛрддреА рд╣реИ, рддреЛ std :: quoted рдлрд╝рдВрдХреНрд╢рди рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рддрд╛рд░реЛрдВ рдХреЛ рд╕реНрдХреНрд░реАрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ рд╕реАрдорд╛рдВрдХрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЗ рдмрд┐рдирд╛ рдПрдХ рдзрд╛рд░рд╛ рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рдФрд░ рддрд┐рдерд┐рдпреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред
рдЖрдк рдЕрдм рдХреЗ рд▓рд┐рдП рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рд╡рд░реНрдгрди рдХреЗ рд╕рд╛рде рд░реБрдХ рд╕рдХрддреЗ рд╣реИрдВред Deserialization (рд▓реЛрдб) рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ
рдкрд░рд┐рд╡рд╣рди рд╕рд░рд▓ рд╣реИред рдпрд╣ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдПрдХ рдмрдлрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред
namespace rpc::type {
рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ "рдирд┐рд╖реНрдкрд╛рджрдХ" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ std :: bind, lambda рдлрд╝рдВрдХреНрд╢рди рдЖрджрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рдЕрдкрдиреЗ рдХрд┐рд╕реА рднреА рдкрд░рд┐рд╡рд╣рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдкрдж рдХреЗ рднреАрддрд░ рдкрд░рд┐рд╡рд╣рди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЖрдк рдкреВрд░реНрдг рдЖрд░рдкреАрд╕реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рдЕрдВрдд рдореЗрдВ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЧреНрд░рд╛рд╣рдХ
рдиреАрдЪреЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЧреНрд░рд╛рд╣рдХ рдХреЛрдб рд╣реИред рдХреНрд▓рд╛рдЗрдВрдЯ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдЬрдирд░реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЪрдпрдирд┐рдд рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рд╕рд░реНрд╡рд░ рдкрд░ рднреЗрдЬрддрд╛ рд╣реИред рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдореЗрдВ, рд╕рднреА рдХреНрд▓рд╛рдЗрдВрдЯ рдЕрдиреБрд░реЛрдз рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ, рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд░реНрд╡рд░ рд╕реЗ рд╕реАрдзреЗ рд╕рдВрд╡рд╛рдж рдХрд░реЗрдЧрд╛ред
рдЧреНрд░рд╛рд╣рдХ namespace rpc { template <typename TPacker> class client final { private: class result; public: client(type::executor executor) : executor_{executor} { } template <typename ... TArgs> result call(std::string const &func_name, TArgs && ... args) { auto request = std::make_tuple(func_name, std::forward<TArgs>(args) ... ); auto pack = packer_.save(request); auto responce = executor_(std::move(pack)); return {responce}; } private: using packer_type = TPacker; packer_type packer_; type::executor executor_; class result final { public: result(type::buffer buffer) : buffer_{std::move(buffer)} { } template <typename T> auto as() const { std::tuple<std::decay_t<T>> tuple; packer_.load(buffer_, tuple); return std::move(std::get<0>(tuple)); } private: packer_type packer_; type::buffer buffer_; }; }; }
рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреНрд▓рд╛рд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдХреНрд▓рд╛рд╕ рдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдПрдХ рдореЗрдВ рдирд╣реАрдВ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдХрд┐ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред
рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдПрдХ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдареЗрдХреЗрджрд╛рд░ рдЦреБрдж рдХреЗ рддрд╣рдд рдкрд░рд┐рд╡рд╣рди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЫреБрдкрд╛рддрд╛ рд╣реИ, рдФрд░ рдХреЛрдб рдореЗрдВ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рдХреЗ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╕реЛрдЪрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд░рд┐рд╡рд╣рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрдВрд╕реЛрд▓ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред
auto executor = [] (rpc::type::buffer buffer) {
рдХрд╕реНрдЯрдо рдХреЛрдб рдиреЗ рдЕрднреА рддрдХ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡рд╣рд╛рдБ рдирд╣реАрдВ рд╣реИ рдЬрд╣рд╛рдВ рд╕реЗ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред
рдЧреНрд░рд╛рд╣рдХ рдХреЙрд▓ рд╡рд┐рдзрд┐:- рдХреНрд░рдорд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдмреБрд▓рд╛рдпрд╛ рд╡рд┐рдзрд┐ рдФрд░ рдЙрд╕рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдирд╛рдо рдкреИрдХ
- рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд░реНрд╡рд░ рдХреЛ рдПрдХ рдЕрдиреБрд░реЛрдз рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ
- рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдЙрддреНрддрд░ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ
рдореВрд▓ рдЧреНрд░рд╛рд╣рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддреИрдпрд╛рд░ рд╣реИред рдХреБрдЫ рдФрд░ рдмрдЪрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдж рдореЗрдВред
рд╕рд░реНрд╡рд░
рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд░реНрд╡рд░ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рдкреВрд░реНрдг рдЙрджрд╛рд╣рд░рдг рдкрд░ рдПрдХ рддреНрд╡рд░рд┐рдд, рд╡рд┐рдХрд░реНрдг рджреЗрдЦрдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред
рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдкреНрд░рджрд░реНрд╢рди рд╕рднреА рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╣реИрдВред рдкрд░рд┐рд╡рд╣рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рд▓рдВрдмреЛ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдПрдХ рдмрдлрд░ рдЧреБрдЬрд░рддрд╛ рд╣реИред
рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд░реНрд╡рд░ рдЗрдВрдЯрд░реИрдХреНрд╢рдиред рдЯреЗрд╕реНрдЯ рдХреЗрд╕ #include <cstdint> #include <cstdlib> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <sstream> #include <string> #include <tuple> #include <vector> #include <utility> namespace rpc::type { using buffer = std::vector<char>; using executor = std::function<buffer (buffer)>; } // namespace rpc::type namespace rpc::detail { template <typename> struct function_meta; template <typename TRes, typename ... TArgs> struct function_meta<std::function<TRes (TArgs ... )>> { using result_type = std::decay_t<TRes>; using args_type = std::tuple<std::decay_t<TArgs> ... >; using request_type = std::tuple<std::string, std::decay_t<TArgs> ... >; }; } // namespace rpc::detail namespace rpc::packer { class string_serializer final { public: template <typename ... T> type::buffer save(std::tuple<T ... > const const &tuple) const { auto str = to_string(tuple, std::make_index_sequence<sizeof ... (T)>{}); return {begin(str), end(str)}; } template <typename ... T> void load(type::buffer const &buffer, std::tuple<T ... > &tuple) const { std::string str{begin(buffer), end(buffer)}; from_string(std::move(str), tuple, std::make_index_sequence<sizeof ... (T)>{}); } private: template <typename T, std::size_t ... I> std::string to_string(T const &tuple, std::index_sequence<I ... >) const { std::stringstream stream; auto put_item = [&stream] (auto const &i) { if constexpr (std::is_same_v<std::decay_t<decltype(i)>, std::string>) stream << std::quoted(i) << ' '; else stream << i << ' '; }; (put_item(std::get<I>(tuple)), ... ); return std::move(stream.str()); } template <typename T, std::size_t ... I> void from_string(std::string str, T &tuple, std::index_sequence<I ... >) const { std::istringstream stream{std::move(str)}; auto get_item = [&stream] (auto &i) { if constexpr (std::is_same_v<std::decay_t<decltype(i)>, std::string>) stream >> std::quoted(i); else stream >> i; }; (get_item(std::get<I>(tuple)), ... ); } }; } // namespace rpc::packer namespace rpc { template <typename TPacker> class client final { private: class result; public: client(type::executor executor) : executor_{executor} { } template <typename ... TArgs> result call(std::string const &func_name, TArgs && ... args) { auto request = std::make_tuple(func_name, std::forward<TArgs>(args) ... ); auto pack = packer_.save(request); auto responce = executor_(std::move(pack)); return {responce}; } private: using packer_type = TPacker; packer_type packer_; type::executor executor_; class result final { public: result(type::buffer buffer) : buffer_{std::move(buffer)} { } template <typename T> auto as() const { std::tuple<std::decay_t<T>> tuple; packer_.load(buffer_, tuple); return std::move(std::get<0>(tuple)); } private: packer_type packer_; type::buffer buffer_; }; }; template <typename TPacker> class server final { public: template <typename ... THandler> server(std::pair<char const *, THandler> const & ... handlers) { auto make_executor = [&packer = packer_] (auto const &handler) { auto executor = [&packer, function = std::function{handler}] (type::buffer buffer) { using meta = detail::function_meta<std::decay_t<decltype(function)>>; typename meta::request_type request; packer.load(buffer, request); auto response = std::apply([&function] (std::string const &, auto && ... args) { return function(std::forward<decltype(args)>(args) ... ); }, std::move(request) ); return packer.save(std::make_tuple(std::move(response))); }; return executor; }; (handlers_.emplace(handlers.first, make_executor(handlers.second)), ... ); } type::buffer execute(type::buffer buffer) { std::tuple<std::string> pack; packer_.load(buffer, pack); auto func_name = std::move(std::get<0>(pack)); auto const iter = handlers_.find(func_name); if (iter == end(handlers_)) throw std::runtime_error{"Function \"" + func_name + "\" not found."}; return iter->second(std::move(buffer)); } private: using packer_type = TPacker; packer_type packer_; using handlers_type = std::map<std::string, type::executor>; handlers_type handlers_; }; } // namespace rpc int main() { try { using packer_type = rpc::packer::string_serializer; rpc::server<packer_type> server{ std::pair{"hello", [] (std::string const &s) { std::cout << "Func: \"hello\". Inpur string: " << s << std::endl; return "Hello " + s + "!"; }}, std::pair{"to_int", [] (std::string const &s) { std::cout << "Func: \"to_int\". Inpur string: " << s << std::endl; return std::stoi(s); }} }; auto executor = [&server] (rpc::type::buffer buffer) { return server.execute(std::move(buffer)); }; rpc::client<packer_type> client{std::move(executor)}; std::cout << client.call("hello", std::string{"world"}).as<std::string>() << std::endl; std::cout << "Convert to int: " << client.call("to_int", std::string{"100500"}).as<int>() << std::endl; } catch (std::exception const &e) { std::cerr << "Error: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
рд╕рд░реНрд╡рд░ рд╡рд░реНрдЧ рдХреЗ рдЙрдкрд░реЛрдХреНрдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рд╡рд┐рдзрд┐ рд╣реИред
рд╕рд░реНрд╡рд░ рд╡рд░реНрдЧ рдирд┐рд░реНрдорд╛рддрд╛ template <typename ... THandler> server(std::pair<char const *, THandler> const & ... handlers) { auto make_executor = [&packer = packer_] (auto const &handler) { auto executor = [&packer, function = std::function{handler}] (type::buffer buffer) { using meta = detail::function_meta<std::decay_t<decltype(function)>>; typename meta::request_type request; packer.load(buffer, request); auto response = std::apply([&function] (std::string const &, auto && ... args) { return function(std::forward<decltype(args)>(args) ... ); }, std::move(request) ); return packer.save(std::make_tuple(std::move(response))); }; return executor; }; (handlers_.emplace(handlers.first, make_executor(handlers.second)), ... ); }
рд╡рд░реНрдЧ рдХрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рд╣реИред рдпрд╣ рдЗрдирдкреБрдЯ рдкрд░ рдЬреЛрдбрд╝реЗ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдЬреЛрдбрд╝реА рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо рдФрд░ рдПрдХ рд╣реИрдВрдбрд▓рд░ рд╣реИред рдФрд░ рдЪреВрдВрдХрд┐ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдПрдХ рдЪрд░ рд╕рдВрдЦреНрдпрд╛ рдорд╛рдкрджрдВрдбреЛрдВ рд╡рд╛рд▓рд╛ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИ, рдЬрдм рд╕рд░реНрд╡рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕рд░реНрд╡рд░ рдкрд░ рдЙрдкрд▓рдмреНрдз рд╕рднреА рд╣реИрдВрдбрд▓рд░ рддреБрд░рдВрдд рдкрдВрдЬреАрдХреГрдд рд╣реЛрддреЗ рд╣реИрдВред рдпрд╣ рд╕рд░реНрд╡рд░ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдкрд░ рдмреБрд▓рд╛рдП рдЧрдП рдЕрддрд┐рд░рд┐рдХреНрдд рдкрдВрдЬреАрдХрд░рдг рддрд░реАрдХреЛрдВ рдХреЛ рдирд╣реАрдВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛ рджреЗрдЧрд╛ред рдФрд░, рдмрджрд▓реЗ рдореЗрдВ, рдХрд┐рд╕реА рдХреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рд╕реЗ рдореБрдХреНрдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╣реБ-рдереНрд░реЗрдбреЗрдб рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреНрдпрд╛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╕рд░реНрд╡рд░ рд╡рд░реНрдЧ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ template <typename ... THandler> server(std::pair<char const *, THandler> const & ... handlers) {
рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирдХреНрд╢реЗ рдореЗрдВ рдмрд╣реБрдд рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рд╡рд┐рд╖рдо рд╣реИрдВрдбрд▓рд░ рдбрд╛рд▓рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдХрдирд╡рд▓реНрд╢рди рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕реЗ std рдореЗрдВ рдбрд╛рд▓рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ :: рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рд╣реИрдВрдбрд▓рд░ рдХреЗ рдкреВрд░реЗ рд╕реЗрдЯ рдХреЛ рдмрд┐рдирд╛ рд▓реВрдк рдФрд░ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдореИрдк рдХрд░реЗрдВ
(handlers_.emplace(handlers.first, make_executor(handlers.second)), ... );
рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдСрдЯреЛ рдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрд╡рд░рдг рдХреЛ рд╣реИрдВрдбрд▓рд░ рдкрд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдкрд░ рдЙрдкрд▓рдмреНрдз рддрд░реАрдХреЛрдВ рдХреЗ рдирдХреНрд╢реЗ рдореЗрдВ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реИрдк рдкрдВрдЬреАрдХреГрдд рд╣реИрдВ (std :: map)ред рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп, рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдб рдкрд░ рдПрдХ рдЦреЛрдЬ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдПрдХ рд╣реА рд╣реИрдВрдбрд▓рд░ рдкреНрд░рд╛рдкреНрдд рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рднрд▓реЗ рд╣реА рдкреНрд░рд╛рдкреНрдд рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рд░рд┐рдЯрд░реНрди рдХрд┐рдП рдЧрдП рдкрд░рд┐рдгрд╛рдо рдХреА рдкрд░рд╡рд╛рд╣ рдХрд┐рдП рдмрд┐рдирд╛ред Std :: рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЙрд╕ рдкрд░ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдЯреНрдпреВрдкрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рд╕реЗ рдХрд╣рддрд╛ рд╣реИред Std :: apply рдлрдВрдХреНрд╢рди рдХреЛ C ++ 11 рдореЗрдВ рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдм рдпрд╣ "рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░" рдЙрдкрд▓рдмреНрдз рд╣реИ рдФрд░ рдЗрд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ type::buffer execute(type::buffer buffer) { std::tuple<std::string> pack; packer_.load(buffer, pack); auto func_name = std::move(std::get<0>(pack)); auto const iter = handlers_.find(func_name); if (iter == end(handlers_)) throw std::runtime_error{"Function \"" + func_name + "\" not found."}; return iter->second(std::move(buffer)); }
рдмреБрд▓рд╛рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдирд╛рдо рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдкрдВрдЬреАрдХреГрдд рд╣реИрдВрдбрд▓рд░ рдХреЗ рдирдХреНрд╢реЗ рдореЗрдВ рд╡рд┐рдзрд┐ рдХреА рдЦреЛрдЬ рдХрд░рддрд╛ рд╣реИ, рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рджреЗрддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдХреНрд▓рд╛рд╕ рдХреЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рд░реИрдкрд░ рдореЗрдВ рд╕рднреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИрдВред рдХрд┐рд╕реА рдиреЗ рдЕрдкрд╡рд╛рдж рдХреЛ рджреЗрдЦрд╛ рд╣реЛрдЧрд╛, рдФрд░ рд╢рд╛рдпрдж рдпрд╣ рд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рд╣реИ: "рдХреНрдпрд╛ рдЕрдкрд╡рд╛рдж рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╛рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ?" рд╣рд╛рдВ, рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдЬреЛ рдЕрдВрдд рдореЗрдВ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЕрдкрд╡рд╛рдж рдорд╛рд░реНрд╢рд▓рд┐рдВрдЧ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЧреНрд░рд╛рд╣рдХ рдФрд░ рд╕рд░реНрд╡рд░ рдХреЗ рдмреАрдЪ рдЕрдкрд╡рд╛рдж рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред
рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдПрдХ рдФрд░ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ
рдореБрдЦреНрдп int main() { try { using packer_type = rpc::packer::string_serializer; rpc::server<packer_type> server{ std::pair{"hello", [] (std::string const &s) { std::cout << "Func: \"hello\". Inpur string: " << s << std::endl; return "Hello " + s + "!"; }}, std::pair{"to_int", [] (std::string const &s) { std::cout << "Func: \"to_int\". Inpur string: " << s << std::endl; return std::stoi(s); }} }; auto executor = [&server] (rpc::type::buffer buffer) { return server.execute(std::move(buffer)); }; rpc::client<packer_type> client{std::move(executor)}; std::cout << client.call("hello", std::string{"world"}).as<std::string>() << std::endl; std::cout << "Convert to int: " << client.call("to_int", std::string{"100500"}).as<int>() << std::endl; } catch (std::exception const &e) { std::cerr << "Error: " << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
рдпрд╣ рдкреВрд░реЗ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд░реНрд╡рд░ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдирд┐рд╖реНрдкрд╛рджрдХ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЬрдЧрд╣, рдЖрдк рдЖрд╡рд╢реНрдпрдХ рдкрд░рд┐рд╡рд╣рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
C ++ 17 рдорд╛рдирдХ рдореЗрдВ, рдХрднреА-рдХрднреА рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рдкрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рди рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЙрдкрд░реЛрдХреНрдд рдореБрдЦреНрдп рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╕рд░реНрд╡рд░ рд╣реИрдВрдбрд▓рд░ (std :: pair рдмрд┐рдирд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░реНрд╕) рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рддреЗ рд╕рдордп рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдХреЛрдб рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИред
рдореВрд▓ RPC рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддреИрдпрд╛рд░ рд╣реИред рдпрд╣ рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рд╡рд╛рдкрд╕реА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рд╡рд╛рджрд╛ рдХреА рдЧрдИ рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИред
рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдПрдБ
рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реАрдорд╛ рдХреЗ рдкрд╛рд░ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдореЗрдВ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рдорд╛рдирдХ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рд╕рдм рдХреБрдЫ рдЖрдЙрдЯрдкреБрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдмрд╣реБрдд рдХреБрдЫ рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рд╕реНрд╡рдпрдВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдСрдкрд░реЗрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдХрднреА-рдХрднреА рдЖрдк рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реЙрд░реНрдЯ рдХрд░рдиреЗ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреБрдЫ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕рдореЗрдВ рдкрд░рд╛рд╡рд░реНрддрди рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдЕрднреА рддрдХ C ++ рдореЗрдВ рдирд╣реАрдВ рд╣реИред рдЖрдк рдХреЛрдб рдкреАрдврд╝реА рдФрд░ рдореИрдХреНрд░реЛрдЬрд╝ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЗ рдорд┐рд╢реНрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд┐рдЪрд╛рд░ рд╢реБрджреНрдз рд╕реА ++ рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдерд╛ред
C ++ рдореЗрдВ рдЕрднреА рддрдХ рдХреЛрдИ рдкреВрд░реНрдг рдкреНрд░рддрд┐рдмрд┐рдВрдм рдирд╣реАрдВ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдЫ рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕рдорд╛рдзрд╛рди рдирдП C ++ 17 "рд╕рдВрд░рдЪрд┐рдд рдмрд╛рдЗрдВрдбрд┐рдВрдЧ" рд╕реБрд╡рд┐рдзрд╛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдЕрдХреНрд╕рд░ рд╕рдВрд╡рд╛рджреЛрдВ рдореЗрдВ рдЖрдк рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╢рдмреНрджрдЬрд╛рд▓ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рд░реВрд╕реА рдореЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рдирд╛рдо рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рд╡рд┐рдХрд▓реНрдк рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ред
рдиреАрдЪреЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдЯреНрдпреВрдкрд▓ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
template <typename T> auto to_tuple(T &&value) { using type = std::decay_t<T>; if constexpr (is_braces_constructible_v<type, dummy_type, dummy_type, dummy_type>) { auto &&[f1, f2, f3] = value; return std::make_tuple(f1, f2, f3); } else if constexpr (is_braces_constructible_v<type, dummy_type, dummy_type>) { auto &&[f1, f2] = value; return std::make_tuple(f1, f2); } else if constexpr (is_braces_constructible_v<type, dummy_type>) { auto &&[f1] = value; return std::make_tuple(f1); } else { return std::make_tuple(); } }
рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рдЖрдк рдХрдИ рд╕рдорд╛рди рд╕рдорд╛рдзрд╛рди рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рдВрд░рдЪрд┐рдд рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдпрд╣рд╛рдБ рдЬреЛ рдХрд╣рд╛ рдЧрдпрд╛ рдерд╛, рдЙрд╕рдХрд╛ рдмрд╣реБрдд рдХреБрдЫ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред To_tuple рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдлрд╝реАрд▓реНрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рдВрд░рдЪрд┐рдд рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреА рдорджрдж рд╕реЗ рд╕рдВрд░рдЪрдирд╛ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ tuple рдореЗрдВ "рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд" рдХрд░рддрд╛ рд╣реИред рдФрд░ "рдЕрдЧрд░ рдмрд╛рдзрд╛" рдЖрдкрдХреЛ рд╡рд╛рдВрдЫрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╢рд╛рдЦрд╛ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЪреВрдВрдХрд┐ C ++ рдореЗрдВ рдХреЛрдИ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдЬреЛ рдХрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддрд╛ рд╣реИ, рдирд┐рд░реНрдорд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИрдВред рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ - рдкреНрд░рдХрд╛рд░ рдХрд╕реНрдЯрдо рдмрд┐рд▓реНрдбрд░реЛрдВ рдХреЗ рдмрд┐рдирд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
To_tuple is_braces_constructible_v рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдкреНрд░рдХрд╛рд░ рдЖрдкрдХреЛ рдШреБрдВрдШрд░рд╛рд▓реЗ рдмреНрд░реЗрд╕рд┐рдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЦреЗрддреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
is_braces_constructible_v struct dummy_type final { template <typename T> constexpr operator T () noexcept { return *static_cast<T const *>(nullptr); } }; template <typename T, typename ... TArgs> constexpr decltype(void(T{std::declval<TArgs>() ... }), std::declval<std::true_type>()) is_braces_constructible(std::size_t) noexcept; template <typename, typename ... > constexpr std::false_type is_braces_constructible(...) noexcept; template <typename T, typename ... TArgs> constexpr bool is_braces_constructible_v = std::decay_t<decltype(is_braces_constructible<T, TArgs ... >(0))>::value;
рдЙрдкрд░реЛрдХреНрдд to_tuple рдлрд╝рдВрдХреНрд╢рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ tuples рдореЗрдВ рддреАрди рд╕реЗ рдЕрдзрд┐рдХ рдлрд╝реАрд▓реНрдб рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред "рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд" рд╕рдВрд░рдЪрдирд╛ рдлрд╝реАрд▓реНрдб рдХреА рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдпрд╛ рддреЛ "рдХреЙрдиреНрд╕реНрдЯреИрдХреНрд╕рдкреНрд░" рд╢рд╛рдЦрд╛рдУрдВ рдХреЛ рдорди рдХреЗ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рд╕рдорд╛рд╡реЗрд╢ рдХреЗ рд╕рд╛рде рдХреЙрдкреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рд╕рд░рд▓рддрдо рдмреВрд╕реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдиреЗ рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдХреЛрдб рдХреЛ рдкрдврд╝рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред
рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд╕рд╛рде to_tuple рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ template <typename T> auto to_tuple(T &&value) { using type = std::decay_t<T>; #define NANORPC_TO_TUPLE_LIMIT_FIELDS 64
рдпрджрд┐ рдЖрдкрдиреЗ рдХрднреА C ++ 03 рдХреЗ рд▓рд┐рдП boost.bind рдЬреИрд╕рд╛ рдХреБрдЫ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ, рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рд╡рд┐рднрд┐рдиреНрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрдИ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд░рдиреЗ рдереЗ, рддреЛ to_tuple рдХрд╛ рдЙрдкрдпреЛрдЧ рдмреВрд╕реНрдЯрд░.рдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдЬреАрдм рдпрд╛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИред
рдФрд░ рдпрджрд┐ рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдореЗрдВ рдЯреНрдпреВрдкрд▓ рд╕рдорд░реНрдерди рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ to_tuple рдлрд╝рдВрдХреНрд╢рди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдХреНрд░рдорд╛рдВрдХрди рдХреЛ рд╕рдХреНрд╖рдо рдХрд░реЗрдЧрд╛ред рдФрд░ рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреЗ рдЖрд░рдкреАрд╕реА рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдзреЛрдЦрд╛ рджреЗрдирд╛ рдФрд░ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, C ++ рдореЗрдВ рдЕрдиреНрдп рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░ рд╣реИрдВ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдУрд╡рд░рд▓реЛрдб рдЖрдЙрдЯрдкреБрдЯ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХреЛрдб рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИ рдЬреЛ рдПрдХ рд╡рд┐рдзрд┐ рдХреЛ рдЕрдзрд┐рдХрд╛рдВрд╢ C ++ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ std :: list, std :: рд╡реЗрдХреНрдЯрд░, std :: mapред SFINAE рдФрд░ std :: enable_if_t рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреВрд▓рдХрд░ рднреА рдЖрдк рдзрд╛рд░рд╛рд╡рд╛рд╣рд┐рдХ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рд░реВрдк рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рдЬреИрд╕рд╛ рдХрд┐ is_braces_constructible_v рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдирд┐рд╖реНрдХрд░реНрд╖
рдкрдж рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░, рдЕрдкрд╡рд╛рдж рдорд╛рд░реНрд╢рд▓рд┐рдВрдЧ, рдкрд░рд┐рд╡рд╣рди, рдПрд╕рдЯреАрдПрд▓ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдХреНрд░рдорд╛рдВрдХрди рдФрд░ рдмрд╣реБрдд рдХреБрдЫ рдмрдирд╛ рд░рд╣рд╛ред
рдкреЛрд╕реНрдЯ рдХреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЗрд╡рд▓ рд╕рд╛рдорд╛рдиреНрдп рд╕рд┐рджреНрдзрд╛рдВрдд рджрд┐рдП рдЧрдП рдереЗ, рдЬрд┐рди рдкрд░ рдореИрдВ рдЕрдкрдиреА RPC рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдФрд░ рдЕрдкрдиреЗ рд▓рд┐рдП рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдореВрд▓ рдХрд╛рд░реНрдп рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ - рдирдИ C ++ 14/17 рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдЖрдЬрд╝рдорд╛рдиреЗ рдХреЗ рд▓рд┐рдПред рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдкрдХреЛ рд╡реНрдпрд╛рдкрдХ HTTP / HTTPS рдФрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреВрд░рд╕реНрде рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рдХрд╛рдлреА рд╡рд┐рд╕реНрддреГрдд рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред GitHub рдкрд░ NanoRPCрдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛрдб редрдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!