рдпрд╣ рдЖрд▓реЗрдЦ C ++ рдореЗрдВ рдХреНрд░рдорд╛рдВрдХрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реЛрдЧрд╛ред рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдЙрди рдмреБрдирд┐рдпрд╛рджреА рддрдВрддреНрд░реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдкрдврд╝рдирд╛ / рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЖрджрд┐рдо рд▓рд┐рдмрдХреНрд▓рд╛рдВрдЧ-рдЖрдзрд╛рд░рд┐рдд рдХреЛрдб рдЬрдирд░реЗрд╢рди рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдбреЗрдореЛ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░ рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред
RuSO рдореЗрдВ, C ++ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдордп-рд╕рдордп рдкрд░ рд╕рд╡рд╛рд▓ рдЙрдарддреЗ рд╣реИрдВ, рдХрднреА-рдХрднреА рдпреЗ рдкреНрд░рд╢реНрди рдкреНрд░рдХреГрддрд┐ рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрддреЗ рд╣реИрдВ, рдЬрдм рдЯреАрд╕реА рдореВрд▓ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХрд╣рд╛рдВ рд╕реЗ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реИ, рдХрднреА-рдХрднреА рдпреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рд╕реА ++ рдореЗрдВ рдХреНрд░рдордмрджреНрдзрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЪрд░рдгреЛрдВ рд╕реЗ рдХреБрдЫ рддрд╛рд░реНрдХрд┐рдХ рдирд┐рд╖реНрдХрд░реНрд╖ рддрдХ рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдЬрдм рдпрд╣ рдкреНрд░рдгрд╛рд▓реА рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрднреНрдпрд╛рд╕ рдореЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред
1. рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА
рдпрд╣ рдЖрд▓реЗрдЦ рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдбреЗрдЯрд╛ рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреНрд░рдордмрджреНрдз рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рддреГрддреАрдп-рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдорд╛рдирдХ C ++ рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдЙрдкрдХрд░рдгреЛрдВ рддрдХ рд╣реА рд╕реАрдорд┐рдд рдХрд░рддрд╛ рд╣реИред
рдЪреВрдВрдХрд┐ рдХреНрд░рдорд╛рдВрдХрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрд╛рдЗрдЯреНрд╕ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИ, рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрд┐рдд рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд╛рде рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рд╡рд┐рд╡рд░рдгреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╕рдордп рд╢рдмреНрдж "рдХреНрд░рдорд╛рдВрдХрди" рдХреЗ рдмрдЬрд╛рдп рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕реА рддрд░рд╣ рдкрдврд╝рдиреЗ / deserialize рдХреЗ рд▓рд┐рдПред
рд▓реЗрдЦ рдХреА рдорд╛рддреНрд░рд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХреЗрд╡рд▓ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рдЙрджрд╛рд╣рд░рдг рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗ (рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдЬрд╣рд╛рдВ deserialization рдореЗрдВ рдХреБрдЫ рд╡рд┐рд╡рд░рдг рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИрдВ)ред рдЙрдкрд░реЛрдХреНрдд рднрдВрдбрд╛рд░ рдореЗрдВ рдкреВрд░реНрдг рдХреЛрдб рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
2. рд╕рдорд░реНрдерд┐рдд рдкреНрд░рдХрд╛рд░
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рддреЗ рд╣реИрдВ - рдпрд╣ рд╕реАрдзреЗ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╡рд┐рдХрд▓реНрдк рд╕реА ++ рдХреЗ рдореВрд▓рднреВрдд рдкреНрд░рдХрд╛рд░реЛрдВ рддрдХ рд╕реАрдорд┐рдд рд╣реИ, рддреЛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдореНрдкрд▓реЗрдЯ (рдЬреЛ рдкреВрд░реНрдгрд╛рдВрдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдПрдХ рдкрд░рд┐рд╡рд╛рд░ рд╣реИ) рдФрд░ рдЗрд╕рдХреА рд╕реНрдкрд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдЧреАред рдкреНрд░рд╛рдердорд┐рдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ (рдкреНрд░рдХрд╛рд░ std :: int32_t, std :: uint16_t, рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдкреНрд░рдпреБрдХреНрдд):
template<typename T> auto write(std::ostream& os, T value) -> std::size_t { const auto pos = os.tellp(); os.write(reinterpret_cast<const char*>(&value), sizeof(value)); return static_cast<std::size_t>(os.tellp() - pos); }
рдиреЛрдЯ : рдпрджрд┐ рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рджреМрд░рд╛рди рдкреНрд░рд╛рдкреНрдд рдбреЗрдЯрд╛ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд╛рдЗрдЯ рдСрд░реНрдбрд░ рдХреЗ рд╕рд╛рде рдорд╢реАрдиреЛрдВ рдХреЗ рдмреАрдЪ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИ, рддреЛ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реНрдерд╛рдиреАрдп рдмрд╛рдЗрдЯ рдСрд░реНрдбрд░ рд╕реЗ рдПрдХ рдиреЗрдЯрд╡рд░реНрдХ рдмрд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рдореВрд▓реНрдп рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдлрд┐рд░ рд░рд┐рдореЛрдЯ рдорд╢реАрди рдкрд░ рд░рд┐рд╡рд░реНрд╕ рдСрдкрд░реЗрд╢рди рдХрд░реЗрдВ, рдЗрд╕рд▓рд┐рдП рд▓реЗрдЦрди рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрди рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛, рдФрд░ рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рдкрдврд╝рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдПред
рдмреВрд▓ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛:
constexpr auto t_value = static_cast<std::uint8_t>('T'); constexpr auto f_value = static_cast<std::uint8_t>('F'); template<> auto write(std::ostream& os, bool value) -> std::size_t { const auto pos = os.tellp(); const auto tmp = (value) ? t_value : f_value; os.write(reinterpret_cast<const char*>(&tmp), sizeof(tmp)); return static_cast<std::size_t>(os.tellp() - pos); }
рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рдпрдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ: рдпрджрд┐ рдЯрд╛рдЗрдк рдЯреА рдХреЗ рдорд╛рди рдХреЛ рд▓рдВрдмрд╛рдИ рдХреЗ рдЖрдХрд╛рд░ рдХреЗ рдмрд╛рдЗрдЯреНрд╕ (рдЯреА) рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд░реВрдк рдореЗрдВ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдердорд┐рдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛, рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рдЯрд╛рдЗрдк рдЯреА рдХреА рдПрдХ рд╡рд╕реНрддреБ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреА рд╕реБрд╡рд┐рдзрд╛рдУрдВ рд╕реЗ рддрдп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХрдВрдЯреЗрдирд░ std :: string рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ: рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╣рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдкрддрд╛ рдирд╣реАрдВ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдПрдХ рд╕реВрдЪрдХ рдХреЛ рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд╛рд▓реЗрдВ рдФрд░ рдЗрд╕реЗ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдкрд░ рд▓рд┐рдЦреЗрдВ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдореЗрдВ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
template<> auto write(std::ostream& os, const std::string& value) -> std::size_t { const auto pos = os.tellp(); const auto len = static_cast<std::uint32_t>(value.size()); os.write(reinterpret_cast<const char*>(&len), sizeof(len)); if (len > 0) os.write(value.data(), len); return static_cast<std::size_t>(os.tellp() - pos); }
рдпрд╣рд╛рдБ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБ:
- рди рдХреЗрд╡рд▓ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд╕рд╛рдордЧреНрд░реА рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдкрд░ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИ, рдмрд▓реНрдХрд┐ рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ рднреАред
- Cast std :: string :: size_type to std :: uint32_t рдЯрд╛рдЗрдк рдХрд░реЗрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рд▓рдХреНрд╖реНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдХрд╛рд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрдереНрдп рд╕реЗ рдХрд┐ рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд▓рдВрдмрд╛рдИ рдХрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рдХрдореА рдорд╛рдорд▓реЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧреА, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЕрдЧрд░ рдбреЗрдЯрд╛ рдХреЛ рдорд╢реАрди рдХреЗ рдмреАрдЪ рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдорд╢реАрди рд╢рдмреНрдж рдЖрдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдореВрд▓ рдкреНрд░рдХрд╛рд░ рдХреЗ (рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ std :: string) рдХрд╛ рдорд╛рди рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ
рд░рд╛рдЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЕрдм рдЪрд▓реЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдЙрди рдмрджрд▓рд╛рд╡реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдпрджрд┐ рд╣рдо рд╕рдорд░реНрдерд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ - рдЯреА рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдВрдЯреЗрдирд░ рддрддреНрд╡реЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░реЗрдВред рдФрд░ рдЕрдЧрд░ std :: рд╡реЗрдХреНрдЯрд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХрд╛рдо рдХрд░реЗрдЧрд╛:
template<typename T> auto write(std::ostream& os, const std::vector<T>& value) -> std::size_t { const auto pos = os.tellp(); const auto len = static_cast<std::uint16_t>(value.size()); os.write(reinterpret_cast<const char*>(&len), sizeof(len)); auto size = static_cast<std::size_t>(os.tellp() - pos); if (len > 0) { std::for_each(value.cbegin(), value.cend(), [&](const auto& e) { size += ::write(os, e); }); } return size; }
, рддрдм std рдХреЗ рд╕рд╛рде: рдорд╛рдирдЪрд┐рддреНрд░ - рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ std :: рдорд╛рдирдЪрд┐рддреНрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдХрдо рд╕реЗ рдХрдо рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ - рдХреБрдВрдЬреА рдкреНрд░рдХрд╛рд░ рдФрд░ рдорд╛рди рдкреНрд░рдХрд╛рд░ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рд╣рдореЗрдВ рдЕрдзрд┐рдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╕рдорд╛рдзрд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ рдХрд┐ рдХрдВрдЯреЗрдирд░ рд╕рдорд░реНрдерди рдХреИрд╕реЗ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдП, рдЖрдЗрдП рдпрд╛рдж рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА рдХрд╕реНрдЯрдо рдХрдХреНрд╖рд╛рдПрдВ рд╣реИрдВред рдЬрд╛рд╣рд┐рд░ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП
рд▓реЗрдЦрди рдХрд╛рд░реНрдп рдХреЛ рдЕрдзрд┐рднрд╛рд░ рджреЗрдирд╛ рдмреБрджреНрдзрд┐рдорд╛рдиреА рдирд╣реАрдВ рд╣реЛрдЧреА, рдЬрд┐рд╕реЗ рдХреНрд░рдордмрджреНрдзрддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╕рд░реНрд╡реЛрддреНрддрдо рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ
рд▓реЗрдЦрди рдкреИрдЯрд░реНрди рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рдХрдХреНрд╖рд╛рдПрдВ рдХреНрд░рдорд╢рдГ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдХреНрд░рдорд╛рдВрдХрди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд░рдЦрддреА рд╣реИрдВ, рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЗрд╕ рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдирд┐рдХрд▓рддрд╛ рд╣реИ, рдпрд╣ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╕реНрдЯрдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп
рд▓рд┐рдЦрдиреЗ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ "рд╕рд╛рдорд╛рдиреНрдп рднрд╛рдЬрдХ" рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рдЗрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
class ISerializable { protected: ~ISerializable() = default; public: virtual auto serialize(std::ostream& os) const -> std::size_t = 0; virtual auto deserialize(std::istream& is) -> std::size_t = 0; virtual auto serialized_size() const noexcept -> std::size_t = 0; };
ISerializable рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдХреЛрдИ рднреА рд╡рд░реНрдЧ рдЗрд╕рд╕реЗ рд╕рд╣рдордд рд╣реИ:
- рдУрд╡рд░рд░рд╛рдЗрдб рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░реЗрдВ - рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рд╕реНрдЯреЗрдЯ (рдбреЗрдЯрд╛ рд╕рджрд╕реНрдп) рд▓рд┐рдЦреЗрдВред
- рдУрд╡рд░рд░рд╛рдЗрдб рдбрд┐рд╕реНрдХреНрд░рд╛рдЗрдмрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВ - рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рд╕реНрдЯреЗрдЯ (рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдХрд╛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди) рдкрдврд╝реЗрдВред
- рдУрд╡рд░рд░рд╛рдЗрдб serialized_size - рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдХреНрд░рдордмрджреНрдз рдбреЗрдЯрд╛ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
рддреЛ,
рд░рд╛рдЗрдЯ рдЯреВ рдлрдВрдХреНрд╢рди рдЯреЗрдореНрдкрд▓реЗрдЯ: рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╣рдо
ISerializable class рдХреЗ рд▓рд┐рдП рд╕реНрдкреЗрд╢рд▓рд╛рдЗрдЬреЗрд╢рди рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:
template<> auto write(std::ostream& os, const ISerializable& value) -> std::size_t { return value.serialize(os); }
рд╣рд░ рдмрд╛рд░, рд╣рдореЗрдВ рдЗрд╕ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд╛рд░рд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ
ISerializable рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╣рдо рдЗрд╕реЗ рдХреНрд░рдордмрджреНрдзрддрд╛ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреЛрдб рд▓реЗрдЦрди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд▓рдХреНрд╖реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЗрд╕реЗ рдЬрдЯрд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рд╣рдорд╛рд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдкреНрд░рдХрд╛рд░ рдореВрд▓рднреВрдд рдкреНрд░рдХрд╛рд░реЛрдВ рддрдХ рд╕реАрдорд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рджреВрд╕рд░реЗ рд╕рдорд╛рдзрд╛рди рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
3. рд╕реНрдЯреНрд░реАрдо_рд▓реЗрдЦрдХ
рдПрдХ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдбреЗрдЯрд╛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдерд╛ред рдЕрдЧрд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ рдХреНрд▓рд╛рд╕ рдЯреЗрдореНрдкрд▓реЗрдЯред рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╕рдорд╛рди рдХрд╛рд░реНрдпрдкреНрд░рдгрд╛рд▓реА рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВрдЧреЗ - рдкреНрд░рд╛рдердорд┐рдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛рдУрдВ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рдХреЛ
ISerializable рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП - рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╣рдо type_traits рдХрд╛ рд╕рд╣рд╛рд░рд╛ рд▓рд┐рдП рдмрд┐рдирд╛ рдХрдИ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ: C ++ 11 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, std :: enable_ifit рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛, рдЬреЛ рдЖрдкрдХреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдХреБрдЫ рд╢рд░реНрддреЗрдВ - рдФрд░ рдпрд╣ рд╡рд╣реА рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рд▓рд╛рдн рдЙрдард╛рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред
рд╕реНрдЯреНрд░реАрдо_рд▓реЗрдЦрдХ рд╡рд░реНрдЧ
рдЯреЗрдореНрдкрд▓реЗрдЯ :
template<typename T, typename U = void> class stream_writer { public: static auto write(std::ostream& os, const T& value) -> std::size_t; };
рд▓рд┐рдЦрдиреЗ рдХреА рд╡рд┐рдзрд┐ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛:
template<typename T, typename U> auto stream_writer<T, U>::write(std::ostream& os, const T& value) -> std::size_t { const auto pos = os.tellp(); os.write(reinterpret_cast<const char*>(&value), sizeof(value)); return static_cast<std::size_t>(os.tellp() - pos); }
ISerializable рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧреА:
template<typename T> class stream_writer<T, only_if_serializable<T>> : public stream_io<T> { public: static auto write(std::ostream& os, const T& value) -> std::size_t; };
рдЬрд╣рд╛рдБ only_if_serializable рдПрдХ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ:
template<typename T> using only_if_serializable = std::enable_if_t<std::is_base_of_v<ISerializable, T>>;
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрджрд┐ рдЯрд╛рдЗрдк T рдПрдХ рд╢реНрд░реЗрдгреА рд╣реИ рдЬреЛ
ISerializable рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреНрд░рдорд╢рдГ рдкреНрд░рддреНрдпрд╛рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдореНрдореАрджрд╡рд╛рд░ рдорд╛рдиреА рдЬрд╛рдПрдЧреА, рдпрджрд┐ рдЯрд╛рдЗрдк T
ISerializable рдХреЗ рд╕рдорд╛рди рд╢реНрд░реЗрдгреА рдкрджрд╛рдиреБрдХреНрд░рдо рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕реЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рд╕реЗ рдмрд╛рд╣рд░ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрд╣рд╛рдБ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╢реНрди рдкреВрдЫрдирд╛ рдЙрдЪрд┐рдд рд╣реЛрдЧрд╛: рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛? рдЖрдЦрд┐рд░рдХрд╛рд░, рдкреНрд░рд╛рдердорд┐рдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рдорд╛рди рдорд╛рди рд╣реЛрдВрдЧреЗ рдЬреИрд╕реЗ рдХрд┐ рдЗрд╕рдХреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ - <рдЯреА, рд╢реВрдиреНрдп>ред рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рд╡рд░реАрдпрддрд╛ рдХреНрдпреЛрдВ рджреА рдЬрд╛рдПрдЧреА, рдФрд░ рдХреНрдпрд╛ рдпрд╣ рд╣реЛрдЧрд╛? рдЙрддреНрддрд░: рдХреНрдпреЛрдВрдХрд┐ рдРрд╕рд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рдорд╛рдирдХ (
рд╕реНрд░реЛрдд ) рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
(рез.рез) рдпрджрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдорд┐рд▓рд╛рди рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдкрд╛рдИ рдЬрд╛рддреА рд╣реИ, рддреЛ рдЙрд╕ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕реЗ рддрд╛рддреНрдХрд╛рд▓рд┐рдХрддрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ
рдПрд╕рдЯреАрдбреА рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ :: рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
template<typename T> class stream_writer<T, only_if_string<T>> { public: static auto write(std::ostream& os, const T& value) -> std::size_t; }; template<typename T> auto stream_writer<T, only_if_string<T>>::write(std::ostream& os, const T& value) -> std::size_t { const auto pos = os.tellp(); const auto len = static_cast<std::uint32_t>(value.size()); os.write(reinterpret_cast<const char*>(&len), sizeof(len)); if (len > 0) os.write(value.data(), len); return static_cast<std::size_t>(os.tellp() - pos); }
рдЬрд╣рд╛рдБ only_if_string рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
template<typename T> using only_if_string = std::enable_if_t<std::is_same_v<T, std::string>>;
рдпрд╣ рдХрдВрдЯреЗрдирд░реЛрдВ рдореЗрдВ рд▓реМрдЯрдиреЗ рдХрд╛ рд╕рдордп рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдХреБрдЫ рдкреНрд░рдХрд╛рд░ U, рдпрд╛ <U, V> рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХрдВрдЯреЗрдирд░ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ std :: map рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реАрдзреЗ
stream_writer рд╡рд░реНрдЧ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ T рдХреЗ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ - рдпрд╣ рд╡рд╣реА рд╣реИ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рд╣рдордиреЗ рд▓рдХреНрд╖реНрдп рдХрд┐рдпрд╛ рдерд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рд╡рд╛рд▓ рдпрд╣ рдЙрдарддрд╛ рд╣реИ рдХрд┐
рд╕реНрдЯреНрд░реАрдо_рд▓реЗрдЦрдХ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рджреВрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рддрд╛рдХрд┐ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░реЗ? рдпрд╣ рдЕрдЧрд▓реЗ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рд╣реИред
4. рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ
рдкрд╣рд▓реЗ, рдореИрдВ рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рджреВрдВрдЧрд╛, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рдореИрдВ рдЕрджреНрдпрддрди рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред
template<typename T> concept String = std::is_same_v<T, std::string>;
рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдЗрд╕ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдзреЛрдЦрд╛рдзрдбрд╝реА рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕реЗ рд╣рдо рдЕрдЧрд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗ:
template<typename T> concept Container = !String<T> && requires (T a) { typename T::value_type; typename T::reference; typename T::const_reference; typename T::iterator; typename T::const_iterator; typename T::size_type; { a.begin() } -> typename T::iterator; { a.end() } -> typename T::iterator; { a.cbegin() } -> typename T::const_iterator; { a.cend() } -> typename T::const_iterator; { a.clear() } -> void; };
рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╡реЗ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реЛрддреА рд╣реИрдВ рдЬреЛ рд╣рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХрдВрдЯреЗрдирд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ
stream_writer рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдорд╛рдирдХ рдореЗрдВ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдВ рд╣реИрдВред
template<typename T> concept SequenceContainer = Container<T> && requires (T a, typename T::size_type count) { { a.resize(count) } -> void; };
рдЕрдиреБрдХреНрд░рдорд┐рдХ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрд╡рдзрд╛рд░рдгрд╛: рдПрд╕рдЯреАрдбреА :: рд╡реЗрдХреНрдЯрд░, рдПрд╕рдЯреАрдбреА :: рд╕реВрдЪреА, рдЖрджрд┐ред
template<typename T> concept AssociativeContainer = Container<T> && requires (T a) { typename T::key_type; };
рд╕рд╣рдпреЛрдЧреА рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓реНрдкрдирд╛: std :: map, std :: set, std :: unordered_map, рдЖрджрд┐ред
рдЕрдм, рдирд┐рд░рдВрддрд░ рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрд╖ рд╣реИ рд╡рд╣ рдкреНрд░рдХрд╛рд░ рдЯреА рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддрд╛ рд╣реИ:
template<typename T> requires SequenceContainer<T> class stream_writer<T, void> { public: static auto write(std::ostream& os, const T& value) -> std::size_t; }; template<typename T> requires SequenceContainer<T> auto stream_writer<T, void>::write(std::ostream& os, const T& value) -> std::size_t { const auto pos = os.tellp();
рд╕рдорд░реНрдерд┐рдд рдХрдВрдЯреЗрдирд░:
- рдПрд╕рдЯреАрдбреА :: рд╡реЗрдХреНрдЯрд░
- std :: deque
- рдПрд╕рдЯреАрдбреА :: рд╕реВрдЪреА
- std :: рдлреЙрд░рд╡рд░реНрдб_рд▓рд┐рд╕реНрдЯ
рдЗрд╕реА рддрд░рд╣ рд╕рд╣рдпреЛрдЧреА рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП:
template<typename T> requires AssociativeContainer<T> class stream_writer<T, void> : public stream_io<T> { public: static auto write(std::ostream& os, const T& value) -> std::size_t; }; template<typename T> requires AssociativeContainer<T> auto stream_writer<T, void>::write(std::ostream& os, const T& value) -> std::size_t { const auto pos = os.tellp(); const auto len = static_cast<typename stream_writer::size_type>(value.size()); os.write(reinterpret_cast<const char*>(&len), sizeof(len)); auto size = static_cast<std::size_t>(os.tellp() - pos); if (len > 0) { using value_t = typename stream_writer::value_type; std::for_each(value.cbegin(), value.cend(), [&](const auto& item) { size += stream_writer<value_t>::write(os, item); }); } return size; }
рд╕рдорд░реНрдерд┐рдд рдХрдВрдЯреЗрдирд░:
- рдПрд╕рдЯреАрдбреА :: рдирдХреНрд╢рд╛
- std :: unordered_map
- рдПрд╕рдЯреАрдбреА :: рд╕реЗрдЯ
- std :: unordered_set
рдирдХреНрд╢реЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдПрдХ рдЫреЛрдЯреА рд╕реА рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рд╣реИ, рдпрд╣
stream_reader рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЪрд┐рдВрддрд╛ рдХрд░рддрд╛ рд╣реИред Std :: map <K, T> рдХреЗ рд▓рд┐рдП value_type рдХреНрд░рдорд╢рдГ st рд╣реИ :: pair <const K, T>, рдХреНрд░рдорд╢рдГ, рдЬрдм рд╣рдо рдЗрдирдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рд░реАрдбрд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп рдПрдХ рд╕реВрдЪрдХ рдХреЛ const K рдХреЛ рдкреЙрдЗрдВрдЯрд░ рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИред рд╣рдо рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рд╛рд╣рдЪрд░реНрдп рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП value_type рдпрд╛ рддреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ K рдпрд╛ std :: pair <const K, V> рд╣реИ, рдлрд┐рд░ рд╣рдо рдЫреЛрдЯреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рд╣рд╛рдпрдХ рд╡рд░реНрдЧ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рдиреНрд╣реЗрдВ value_type рдФрд░ рдЕрдВрджрд░ рд╕реЗ рдорд╛рдирдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░реЗрдВ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
рдПрд╕рдЯреАрдбреА :: рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП, рд╕рдм рдХреБрдЫ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣рддрд╛ рд╣реИ:
template<typename U, typename V = void> struct converter { using type = U; };
Std :: map рдХреЗ рд▓рд┐рдП - рдХрд╛рд╕реНрдЯ рдирд┐рдХрд╛рд▓реЗрдВ:
template<typename U> struct converter<U, only_if_pair<U>> { using type = std::pair<std::remove_const_t<typename U::first_type>, typename U::second_type>; };
рд╕рд╛рд╣рдЪрд░реНрдп рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд▓рд┐рдП
рдкрдврд╝рдиреЗ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛:
template<typename T> requires AssociativeContainer<T> auto stream_reader<T, void>::read(std::istream& is, T& value) -> std::size_t { const auto pos = is.tellg(); typename stream_reader::size_type len = 0; is.read(reinterpret_cast<char*>(&len), sizeof(len)); auto size = static_cast<std::size_t>(is.tellg() - pos); if (len > 0) { for (auto i = 0U; i < len; ++i) { using value_t = typename converter<typename stream_reader::value_type>::type; value_t v {}; size += stream_reader<value_t>::read(is, v); value.insert(std::move(v)); } } return size; }
5. рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ:
class User : public ISerializable { public: User(std::string_view username, std::string_view password) : m_username(username) , m_password(password) {} SERIALIZABLE_INTERFACE protected: std::string m_username {}; std::string m_password {}; };
рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдХреНрд░рдордмрджреНрдз рд╡рд┐рдзрд┐ (std :: ostream &) рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрдиреА рдЪрд╛рд╣рд┐рдП:
auto User::serialize(std::ostream& os) const -> std::size_t { auto size = 0U; size += stream_writer<std::string>::write(os, m_username); size += stream_writer<std::string>::write(os, m_password); return size; }
рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЖрдкрдХреЛ рдпрд╣ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рд░ рдмрд╛рд░ рдпрд╣ рд╕рдВрдХреЗрдд рдХрд░рдирд╛ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ рдХрд┐ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред рд╣рдо рдПрдХ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ T рдЯрд╛рдЗрдк рдХрд░реЗрдЧрд╛ред
template<typename T> auto write(std::ostream& os, const T& value) -> std::size_t { return stream_writer<T>::write(os, value); }
рдЕрдм рдкрд░рд┐рднрд╛рд╖рд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
auto User::serialize(std::ostream& os) const -> std::size_t { auto size = 0U; size += ::write(os, m_username); size += ::write(os, m_password); return size; }
рдЕрдВрддрд┐рдо рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдХреБрдЫ рдФрд░ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА:
template<typename T> auto write_recursive(std::ostream& os, const T& value) -> std::size_t { return ::write(os, value); } template<typename T, typename... Ts> auto write_recursive(std::ostream& os, const T& value, const Ts&... values) { auto size = write_recursive(os, value); return size + write_recursive(os, values...); } template<typename... Ts> auto write_all(std::ostream& os, const Ts&... values) -> std::size_t { return write_recursive(os, values...); }
Write_all рдлрд╝рдВрдХреНрд╢рди
рдЖрдкрдХреЛ рд╕рднреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдПрдХ рд╕рд╛рде рдХреНрд░рдордмрджреНрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрдмрдХрд┐
write_recursive рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдкрд░ рд▓рд┐рдЦрдиреЗ рдХрд╛ рд╕рд╣реА рдХреНрд░рдо рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЧрдгрдирд╛ рдХрд╛ рдХреНрд░рдо
рдЧреБрдирд╛-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ (рдмрд╢рд░реНрддреЗ рдХрд┐ рд╣рдо рдмрд╛рдЗрдирд░реА + рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ), рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди
size_of_all рдореЗрдВ (рдЗрд╕рдХрд╛ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрд░рдордмрджреНрдз рдбреЗрдЯрд╛ рдХреЗ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдпрд╣ рдЧреБрдирд╛-рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╣реИ рдЬреЛ рдЗрдирдкреБрдЯ-рдЖрдЙрдЯрдкреБрдЯ рд╕рдВрдЪрд╛рд▓рди рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рдХрд╛рд░рдг рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
6. рдХреЛрдб рдЬрдирд░реЗрд╢рди
рд▓рд┐рдмрдХреНрд▓реИрдВрдЧ - рд╕реА рдПрдкреАрдЖрдИ рдлреЙрд░ рдХреНрд▓реЗрдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рд╣рдореЗрдВ рдкреБрди: рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ, рдФрд░ рдпрджрд┐ рдХреЛрдИ рд╣реИ, рддреЛ рдЙрд╕реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВ рдФрд░ рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рдирд╛рдореЛрдВ рд╕реЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВред рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рд╕реЗ рд╕реВрдЪреАрдмрджреНрдзред рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рдХрд░рдирд╛ рдмрд╛рдХреА рд╣реИ, рд╡рд╣
ISERIALizable class (рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ) рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВред
рдПрдХ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдХреЛрдб рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:
class __attribute__((annotate("serializable"))) User : public ISerializable { public: User(std::string_view username, std::string_view password) : m_username(username) , m_password(password) {} User() = default; virtual ~User() = default; SERIALIZABLE_INTERFACE protected: __attribute__((annotate("serializable"))) std::string m_username {}; __attribute__((annotate("serializable"))) std::string m_password {}; };
рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ GNU рд╢реИрд▓реА рдореЗрдВ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ libclang C ++ 20 рд╕реЗ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкреНрд░рд╛рд░реВрдк рдХреЛ рдкрд╣рдЪрд╛рдирдиреЗ рд╕реЗ рдЗрдВрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЧреИрд░-рдПрдиреЛрдЯреЗрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рднреА рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд╕реНрд░реЛрдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдЯреНрд░реИрд╡рд░реНрд╕рд▓:
for (const auto& file : fs::recursive_directory_iterator(argv[1])) { if (file.is_regular_file() && file.path().extension() == ".hpp") { processTranslationUnit(file, dst); } }
ProcessTranslationUnit рдлрд╝рдВрдХреНрд╢рди рдХреА рдкрд░рд┐рднрд╛рд╖рд╛:
auto processTranslationUnit(const fs::path& path, const fs::path& targetDir) -> void { const auto pathname = path.string(); arg::Context context { false, false }; auto translationUnit = arg::TranslationUnit::parse(context, pathname.c_str(), CXTranslationUnit_None); arg::ClassExtractor extractor; extractor.extract(translationUnit.cursor()); const auto& classes = extractor.classes(); for (const auto& [name, c] : classes) { SerializableDefGenerator::processClass(c, path, targetDir.string()); } }
рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдХреЗрд╡рд▓
ClassExtractor рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмреНрдпрд╛рдЬ рдХреА рд╣реИ - рдПрдПрд╕рдЯреА рдХреЗ рдЧрдарди рдХреЗ рд▓рд┐рдП рдмрд╛рдХреА рд╕рдм рдХреБрдЫ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдЕрд░реНрдХ рд╕рдорд╛рд░реЛрд╣ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:
void ClassExtractor::extract(const CXCursor& cursor) { clang_visitChildren(cursor, [](CXCursor c, CXCursor, CXClientData data) { if (clang_getCursorKind(c) == CXCursorKind::CXCursor_ClassDecl) { } return CXChildVisit_Continue; } , this); }
рдпрд╣рд╛рдВ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреНрд▓реИрдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реАрдзреЗ рд╕реА рдПрдкреАрдЖрдИ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВред рд╣рдордиреЗ рдЬрд╛рдирдмреВрдЭрдХрд░ рдХреЗрд╡рд▓ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреЛрдб рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдХрд┐ libclang рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрд░реНрджреЗ рдХреЗ рдкреАрдЫреЗ рдЬреЛ рдХреБрдЫ рднреА рд░рд╣рддрд╛ рд╣реИ рдЙрд╕рдореЗрдВ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ - рдпрд╣ рд╕рд┐рд░реНрдл рдХрдХреНрд╖рд╛ рдХреЗ рдирд╛рдо, рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдЖрджрд┐ рдХрд╛ рдкрдВрдЬреАрдХрд░рдг рд╣реИред рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рдХреЛрдб рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдФрд░ рдЕрдВрдд рдореЗрдВ,
processClass рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рдП рдЧрдП рд╡рд░реНрдЧ рдХреЗ рдХреНрд░рдорд╛рдВрдХрди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдпрджрд┐ рдХреЛрдИ рд╣реИ, рддреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИред рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ: рдЬрд╣рд╛рдВ рдирд╛рдо рд╕реНрдерд╛рди рдХрд╛ рдирд╛рдо / рдирд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ (рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рд╕реАрдзреЗ
рдХрдХреНрд╖рд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рддреА рд╣реИ) рдФрд░ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдкрдеред
рдЙрдкрд░реНрдпреБрдХреНрдд рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП, рдЕрд░реНрдЬреЗрдВрдЯреАрдирд╛ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореИрдВ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рдирд╣реАрдВ рджреЗрддрд╛ - рдореИрдВрдиреЗ рдЗрд╕реЗ рдЕрдиреНрдп рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдмрд╕ рдЙрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА рдЬрд┐рд╕реЗ рд╡рд╣рд╛рдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдореИрдВ рдЖрд▓рд╕реА рдерд╛ред рдореИрдВрдиреЗ рдХреЛрдб рдХреЛ рдлрд┐рд░ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдЦрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╕ рдЗрд╕реЗ рдмрд┐рдВрдЯреНрд░реЗ рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдХреЙрдирди рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕реЗ рд╕реАрдПрдордХреЗ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдЬреЛрдбрд╝рд╛ рд╣реИред рдпрд╣ рд╕рднреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреНрд▓рд╛рд╕реЗрд╕ рдФрд░ рдбреЗрдЯрд╛ рд╕рджрд╕реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреНрд▓реЗрдВрдЧ рд╕реА рдПрдкреАрдЖрдИ рдкрд░ рд╕рд░рд▓ рдЖрд╡рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИредрдФрд░ рдПрдХ рдФрд░ рдЫреЛрдЯреА рдЯрд┐рдкреНрдкрдгреА - рдореИрдВ рдПрдХ рддреИрдпрд╛рд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ, рдореИрдВ рдХреЗрд╡рд▓ рдпрд╣ рдмрддрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реИред
UPD0 : рд▓рд┐рдмрд╛рд╕реИрдВрдЧ рдХреЗ
рдмрдЬрд╛рдп cppast рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрдкрд▓рдмреНрдз рдХрд░рд╛рдИ рдЧрдИ рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП
рдорд╛рд╕реНрдЯрд░реНрд╕рдкрд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
1.
github.com/isnullxbh/dsl2.
github.com/isnullxbh/Agenta