RMI рдХрд╛ рдЕрд░реНрде рд╣реИ C ++ рдФрд░ boost.preprocessor

рдЗрд╕ рд╕рдВрд╕рд╛рдзрди рдкрд░ рдпрд╣ рдореЗрд░рд╛ рдкрд╣рд▓рд╛ рдкреНрд░рдХрд╛рд╢рди рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдЖрдкрд╕реЗ рдЕрдкрдиреА рдЧрд▓рддрд┐рдпреЛрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд▓рд╛рдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реВрдВред

рдЖрд░рдПрдордЖрдИ рдЖрддреНрдордирд┐рд░реАрдХреНрд╖рдг рд╕рдХреНрд╖рдо рдкреАрдПрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╣реА рддреБрдЪреНрдЫ рдХрд╛рд░реНрдп рд╣реИред рд▓реЗрдХрд┐рди, рд╕реА ++, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЙрди рдкрд░ рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдЗрд╕ рдкреНрд░рдХрд╛рд╢рди рдореЗрдВ, рдореИрдВ C ++ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреЛрдЧреА рдЖрд░рдПрдордЖрдИ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди


1. рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЧрд▓рддреА рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛред
2. рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдкрд╣рдЪрд╛рди (рд▓рд┐рдВрдХрд┐рдВрдЧ) рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реЗ рдЫрд┐рдкрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рдЧрд▓рддреА рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛред
3. рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ C ++ рдкреНрд░рдХрд╛рд░реЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рдирд╣реАрдВ рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
4. рд╕рдВрд╕реНрдХрд░рдгрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рддрд╛рдХрд┐ рдореМрдЬреВрджрд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рдЯреВрдЯ рди рдЬрд╛рдПред

рдЪреМрдереЗ рдмрд┐рдВрджреБ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ:
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рджреЛ рдРрдб / div рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдПрдХ рд╕рдВрд╕реНрдХрд░рдгред рд╣рдо рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рд╕рд┐рд░реНрдл рдПрдХ рдФрд░ рд╕рдВрд╕реНрдХрд░рдг рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрдИрдбреА рдЬреЛ рдХреНрд▓рд╛рдЗрдВрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкрд╣рд▓реЗ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреИрд░ рдЬрд╛рдПрдЧреАред

рдЙрдкрдХрд░рдг рдЪрдпрди


рдХреНрдпреЛрдВрдХрд┐ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо C ++ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдореБрдЭреЗ рддреАрди рд╡рд┐рдХрд▓реНрдк рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ:


рдореИрдВ рдХреНрд░рдорд╢рдГ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмреЛрд▓реВрдВрдЧрд╛:


рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рдкрд╣рд▓реЗ, рджреВрд╕рд░реЗ рдФрд░ рддреАрд╕рд░реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ - рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рд╕рдВрд╕реНрдХрд░рдг рдЙрдкрдпреБрдХреНрдд рд╣реИред

рддреЛ, рдЪреБрдирд╛рд╡ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╣рдо рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рд╣рд╛рдВ, рдЬрд░реВрд░ рдмрдврд╝рд╛рдПрдВредрдкреНрд░реЛрд╕реЗрд╕рд░ ред

рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛


C ++ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░:

рдкреНрд░рдХрд╛рд░, рдЬреИрд╕рд╛ рдХрд┐ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдкрд░реНрдпрд╛рдкреНрдд рд╕реЗ рдЕрдзрд┐рдХ рд╣реИрдВред
рдереЛрдбрд╝рд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдФрд░ рд╕реАрдорд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рдирд╛, рдФрд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рд╡рд╛рдВрдЫрд┐рдд рд╕рд╛рджрдЧреА рдФрд░ рдЧрд▓рддреА рдХрд░рдиреЗ рдХреА рдЕрдХреНрд╖рдорддрд╛ рдХреЛ рднреА рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ - рдЪреБрдирд╛рд╡ рдЕрдиреБрдХреНрд░рдореЛрдВ рдФрд░ рдЯреНрдпреВрдкрд▓реНрд╕ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред

рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред
(a)(b)(c) - рдЕрдиреБрдХреНрд░рдо рдпрд╣рд╛рдБ, рд╣рдордиреЗ рддреАрди рддрддреНрд╡реЛрдВ рд╕реЗ рдорд┐рд▓рдХрд░ рдПрдХ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ред
(a) рднреА рдПрдХ рдЕрдиреБрдХреНрд░рдо рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рддрддреНрд╡ рд╕реЗ рдорд┐рд▓рдХрд░ рдмрдирддрд╛ рд╣реИред (рд╕рд╛рд╡рдзрд╛рди!)
(a)(b, c)(d, e, f) - рдлрд┐рд░ рд╕реЗ рдПрдХ рдЕрдиреБрдХреНрд░рдо, рд▓реЗрдХрд┐рди рддреАрди tuples рд╕реЗ рдорд┐рд▓рдХрд░ред (рдкрд╣рд▓реЗ рддрддреНрд╡ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ - рдПрдХ рдЪрд╛рд▓, рд╣рд╛рд▓рд╛рдВрдХрд┐, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рддреБрдЪреНрдЫ рд╣реИ)
(a)(b, c)(d, (e, f)) - рдлрд┐рд░ рд╕реЗ рдПрдХ рдЕрдиреБрдХреНрд░рдо, рдФрд░ рддреАрди рдЯреНрдпреВрдкрд▓ рд╕реЗ рдорд┐рд▓рдХрд░ рднреАред рд▓реЗрдХрд┐рди! рдЕрдВрддрд┐рдо рдЯрдкрд▓ рдореЗрдВ рджреЛ рддрддреНрд╡ рд╣реЛрддреЗ рд╣реИрдВ: 1) рдХреЛрдИ рднреА рддрддреНрд╡, 2) рдЯрдкрд▓ред
рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг: (a)(b, c)(d, (e, (f)(g))) - рдпрд╣рд╛рдВ рдЖрдк рдЗрд╕реЗ рдЦреБрдж рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ;)
рдЬрд╛рд╣рд┐рд░ рд╣реИ, рд╕рдм рдХреБрдЫ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдиреБрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд░рд▓ рд╣реИред

рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╕рд┐рдВрдЯреИрдХреНрд╕


рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рдХреЗ рдмрд╛рдж, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЙрднрд░рддрд╛ рд╣реИ:
 (proc_name0, //   (signature_arg0, signature_arg1, signature_argN) //    (signature_arg0) //    ) (proc_name1, //   (signature_arg0, signature_arg1) //     ) (proc_name2, //   () //     ( ) ) 

рдЦреИрд░ ... рд╣рд╛рд▓рд╛рдВрдХрд┐, рдмрд╣реБрдд рдкрд╣рд▓реЗ рд╕реЗ рд╣реАред

рдХреБрдЫ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг


рдХреНрдпреЛрдВрдХрд┐ рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдореМрдЬреВрджрд╛ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рдирд╣реАрдВ рдЯреВрдЯрддреА рд╣реИ - рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рджреЛ рдЖрдИрдбреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред рдкрд╣рд▓рд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЖрдИрдбреА рд╣реИ, рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЖрдИрдбреА рд╣реИред

рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рд╕рдордЭрд╛рдКрдВрдЧрд╛ред
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдпрд╣ рд╣рдорд╛рд░реА рд╕реЗрд╡рд╛ рдХреЗ рдПрдкреАрдЖрдИ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЧреНрд░рд╛рд╣рдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИрдВред
 (proc_name0, // procID=0 (signature_arg0, signature_arg1) // sigID=0 ) (proc_name1, // procID=1 (signature_arg0, signature_arg1) // sigID=0 ) (proc_name2, // procID=2 () // sigID=0 ) 

рдЕрдм, proc_name0() рд╣рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдФрд░ рд╕рдВрд╕реНрдХрд░рдг рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред
 (proc_name0, // procID=0 (signature_arg0, signature_arg1) // sigID=0 (signature_arg0, signature_arg1, signature_arg2) // sigID=1 ) (proc_name1, // procID=1 (signature_arg0, signature_arg1) // sigID=0 ) (proc_name2, // procID=2 () // sigID=0 ) 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдПрдХ рдирдпрд╛ рдЖрдИрдбреА рд╕рдВрд╕реНрдХрд░рдг рд╣реИ, рдЬрдмрдХрд┐ рдкреВрд░реНрд╡ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рд░рд╣рд╛ред
рдпрд╣ рдерд╛: (0: 0), рдпрд╣ рдмрди рдЧрдпрд╛: (0: 0) (0: 1)
рдпрд╛рдиреА рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рд╣рдордиреЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдереАред рдкрд┐рдЫрд▓реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдиреЗ рджреЛрдиреЛрдВ (0: 0) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдФрд░ рдЗрди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рдЪрд┐рдВрддрд╛ рдХрд┐рдП рд░рд╣реЗрдВрдЧреЗ рдХрд┐ рдЗрди рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рджрд┐рдЦрд╛рдИ рджрд┐рдП рд╣реИрдВред
рд╣рдо рдпрд╣ рднреА рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рднреА рдирдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рдЕрдВрдд рддрдХ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдИрдбреА рд╕реЗрд╡рд╛ рдХреЗ рджреЛрдиреЛрдВ рдУрд░ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЪрд┐рдкрдХрд╛рдП рдЧрдП рд╣реИрдВред рдЖрд╕рд╛рдиреА рд╕реЗ! - рдмрд╕ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рдмрд╛рд░ рдПрдХ рд╣реА рд╡рд░реНрдгрд┐рдд рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!

рдпрд╣ рдХрд▓реНрдкрдирд╛ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ рдХрд┐ рд╣рдо рд▓рдВрдмреЗ рд╕рдордп рдореЗрдВ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
 MACRO( client_invoker, // name of the client invoker implementation class ((registration, // procedure name ((std::string, std::string)) // message : registration key )) ((activation, ((std::string)) // message )) ((login, ((std::string)) // message )) ((logout, ((std::string)) // message )) ((users_online, ((std::vector<std::string>)) // without args )) , server_invoker, // name of the server invoker implementation class ((registration, ((std::string)) // username )) ((activation, ((std::string, std::string, std::string)) // registration key : username : password )) ((login, ((std::string, std::string)) // username : password )) ((logout, (()) // without args )) ((users_online, (()) // without args ((std::string)) // substring )) ) 

рддрд╛рдХрд┐ рдХреЛрдИ рднреНрд░рдо рди рд╣реЛ рдХрд┐ рдХреМрди рдиреЗрддрд╛ рд╣реИ рдФрд░ рдХреМрди рдЧреБрд▓рд╛рдо рд╣реИ, рд╣рдо рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рдПрдХ рдкрдХреНрд╖ рдкрд░ рд╡рд░реНрдгрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ рдЬреЛ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рд╣реИрдВред рдпрд╣ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, client_invoker::registration(std::string, std::string) рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд░реНрд╡рд░ рдХреА рддрд░рдл рд╣реЛрдЧрд╛, рдЬрдмрдХрд┐ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕рд╛рдЗрдб рдореЗрдВ рд╣реЛрдЧрд╛ рдЧреНрд░рд╛рд╣рдХ, рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред
(рд╣рдо рдбрдмрд▓ рдХреЛрд╖реНрдардХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░, рдЬрдм рд╣рдорд╛рд░реЗ MACRO () рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдПрдкреАрдЖрдИ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рджреВрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ? ..

рдкрд░рд┐рдгрд╛рдо


рдКрдкрд░ рдореИрдХреНрд░реЛ рдХреЙрд▓ рд╕реЗ, рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рдиреАрдЪреЗ рдХрд╛ рдХреЛрдб рдЙрддреНрдкрдиреНрди рд╣реЛрдЧрд╛ред
рдХреЛрдб
 namespace yarmi { template<typename Impl, typename IO = Impl> struct client_invoker { client_invoker(Impl &impl, IO &io) :impl(impl) ,io(io) {} void yarmi_error(const std::uint8_t &arg0, const std::uint8_t &arg1, const std::string &arg2) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(0) & static_cast<std::uint8_t>(0) & arg0 & arg1 & arg2; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void registration(const std::string &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(1) & static_cast<std::uint8_t>(0) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void activation(const std::string &arg0, const std::string &arg1, const std::string &arg2) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(2) & static_cast<std::uint8_t>(0) & arg0 & arg1 & arg2; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void login(const std::string &arg0, const std::string &arg1) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(3) & static_cast<std::uint8_t>(0) & arg0 & arg1; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void logout() { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(4) & static_cast<std::uint8_t>(0); yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void users_online() { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(5) & static_cast<std::uint8_t>(0); yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void users_online(const std::string &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(5) & static_cast<std::uint8_t>(1) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void invoke(const char *ptr, std::size_t size) { std::uint8_t call_id, call_version; static const char* names[] = { "yarmi_error" ,"registration" ,"activation" ,"login" ,"logout" ,"users_online" }; static const std::uint8_t versions[] = { 0, 0, 0, 0, 0, 0 }; try { yas::binary_mem_iarchive ia(ptr, size, yas::no_header); ia & call_id & call_version; if ( call_id < 0 || call_id > 5 ) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"%s::%s(): bad call_id %d" ,"client_invoker" ,__FUNCTION__ ,static_cast<int>(call_id) ); throw std::runtime_error(errstr); } if ( call_version > versions[call_id] ) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"%s::%s(): bad call_version %d for call_id %d(%s::%s())" ,"client_invoker" ,__FUNCTION__ ,static_cast<int>(call_version) ,static_cast<int>(call_id) ,"client_invoker" ,names[call_id] ); throw std::runtime_error(errstr); } switch ( call_id ) { case 0: { std::uint8_t arg0; std::uint8_t arg1; std::string arg2; ia & arg0 & arg1 & arg2; impl.on_yarmi_error( arg0 , arg1 , arg2); }; break; case 1: { std::string arg0; std::string arg1; ia & arg0 & arg1; impl.on_registration(arg0, arg1); }; break; case 2: { std::string arg0; ia & arg0; impl.on_activation(arg0); }; break; case 3: { std::string arg0; ia & arg0; impl.on_login(arg0); }; break; case 4: { std::string arg0; ia & arg0; impl.on_logout(arg0); }; break; case 5: { std::vector<std::string> arg0; ia & arg0; impl.on_users_online(arg0); }; break; } } catch (const std::exception &ex) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"std::exception is thrown when %s::%s() is called: '%s'" ,"client_invoker" ,names[call_id] ,ex.what() ); yarmi_error(call_id, call_version, errstr); } catch (...) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"unknown exception is thrown when %s::%s() is called" ,"client_invoker" ,names[call_id] ); yarmi_error(call_id, call_version, errstr); } } private: Impl &impl; IO &io; }; // struct client_invoker template<typename Impl, typename IO = Impl> struct server_invoker { server_invoker(Impl &impl, IO &io) :impl(impl) ,io(io) {} void yarmi_error(const std::uint8_t &arg0, const std::uint8_t &arg1, const std::string &arg2) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(0) & static_cast<std::uint8_t>(0) & arg0 & arg1 & arg2; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void registration(const std::string &arg0, const std::string &arg1) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(1) & static_cast<std::uint8_t>(0) & arg0 & arg1; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void activation(const std::string &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(2) & static_cast<std::uint8_t>(0) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void login(const std::string &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(3) & static_cast<std::uint8_t>(0) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void logout(const std::string &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(4) & static_cast<std::uint8_t>(0) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void users_online(const std::vector<std::string> &arg0) { yas::binary_mem_oarchive oa(yas::no_header); oa & static_cast<std::uint8_t>(5) & static_cast<std::uint8_t>(0) & arg0; yas::binary_mem_oarchive pa; pa & oa.get_intrusive_buffer(); io.send(pa.get_shared_buffer()); } void invoke(const char *ptr, std::size_t size) { std::uint8_t call_id, call_version; static const char* names[] = { "yarmi_error" ,"registration" ,"activation" ,"login" ,"logout" ,"users_online" }; static const std::uint8_t versions[] = { 0, 0, 0, 0, 0, 1 }; try { yas::binary_mem_iarchive ia(ptr, size, yas::no_header); ia & call_id & call_version; if ( call_id < 0 || call_id > 5 ) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"%s::%s(): bad call_id %d" ,"server_invoker" ,__FUNCTION__ ,static_cast<int>(call_id) ); throw std::runtime_error(errstr); } if ( call_version > versions[call_id] ) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"%s::%s(): bad call_version %d for call_id %d(%s::%s())" ,"server_invoker" ,__FUNCTION__ ,static_cast<int>(call_version) ,static_cast<int>(call_id) ,"server_invoker" ,names[call_id] ); throw std::runtime_error(errstr); } switch ( call_id ) { case 0: { std::uint8_t arg0; std::uint8_t arg1; std::string arg2; ia & arg0 & arg1 & arg2; impl.on_yarmi_error(arg0, arg1, arg2); }; break; case 1: { std::string arg0; ia & arg0; impl.on_registration(arg0); }; break; case 2: { std::string arg0; std::string arg1; std::string arg2; ia & arg0 & arg1 & arg2; impl.on_activation(arg0, arg1, arg2); }; break; case 3: { std::string arg0; std::string arg1; ia & arg0 & arg1; impl.on_login(arg0, arg1); }; break; case 4: { impl.on_logout(); }; break; case 5: { switch ( call_version ) { case 0: { impl.on_users_online(); }; break; case 1: { std::string arg0; ia & arg0; impl.on_users_online(arg0); }; break; } }; break; } } catch (const std::exception &ex) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"std::exception is thrown when %s::%s() is called: '%s'" ,"server_invoker" ,names[call_id] ,ex.what() ); yarmi_error(call_id, call_version, errstr); } catch (...) { char errstr[1024] = {0}; std::snprintf( errstr ,sizeof(errstr) ,"unknown exception is thrown when %s::%s() is called" ,"server_invoker" ,names[call_id] ); yarmi_error(call_id, call_version, errstr); } } private: Impl &impl; IO &io; }; // struct server_invoker } // ns yarmi 


(рдореЗрд░реА рдЕрдиреНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛, YAS, рдХреНрд░рдорд╛рдВрдХрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИ)

рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, yarmi_error() рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ - рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рдкрд░реАрдд рдкрдХреНрд╖ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реБрдИред рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦреЗрдВ, client_invoker::invoke() , deserialization рдФрд░ рдордВрдЧрд▓рд╛рдЪрд░рдг рдХреЛ рдПрдХ try{}catch() рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ try{}catch() рдмреНрд▓реЙрдХ, рдФрд░ yarmi_error() catch() рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ catch() рдмреНрд▓реЙрдХред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрджрд┐ рдХрд┐рд╕реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдбрд┐рд╕реЗрд░реНрдмрд▓рд╛рдЗрдЬ рдпрд╛ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп рдХреЛрдИ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ catch() рдмреНрд▓реЙрдХ рд╕реЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрдХрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЕрдкрд╡рд╛рдж рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреЙрд▓рд┐рдВрдЧ рдкрд╛рд░реНрдЯреА рдХреЛ рднреЗрдЬреА рдЬрд╛рдПрдЧреАред рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рднреА рд╡рд╣реА рд╣реЛрдЧрд╛ред рдпрд╛рдиреА рдпрджрд┐ рд╕рд░реНрд╡рд░ рдиреЗ рдХреЙрд▓ рдХреЗ рджреМрд░рд╛рди рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╣рд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рд╣реБрдЖ - рдХреНрд▓рд╛рдЗрдВрдЯ рд╕рд░реНрд╡рд░ рдХреЛ рддреНрд░реБрдЯрд┐ рдХреА рдЬрд╛рдирдХрд╛рд░реА рднреЗрдЬреЗрдЧрд╛, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреЙрд▓ рдХреЗ рдЖрдИрдбреА рдФрд░ рд╕рдВрд╕реНрдХрд░рдг рдХреА рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рднреА рдХрд░реЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдЕрдкрд╡рд╛рдж рд╣реБрдЖред рд▓реЗрдХрд┐рди рдЖрдк рд╕реНрд╡рдпрдВ yarmi_error() рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдирд┐рд╖рд┐рджреНрдз рдирд╣реАрдВ рд╣реИред рдЙрджрд╛рд╣рд░рдг: yarmi_error(call_id, version_id, "message");

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рджреЗрдЦрд╛ рд╣реЛрдЧрд╛, рдЙрдкрд╕рд░реНрдЧ on_ рдЙрдирдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЗ рдирд╛рдореЛрдВ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ

server_invoker рдФрд░ server_invoker рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рдЙрдирдХрд╛ рдкрд╣рд▓рд╛ рддрд▓ рд╡рд╣ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреВрд╕рд░рд╛ рд╡рд╣ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ send(yas::shared_buffer buf) рд╡рд┐рдзрд┐ send(yas::shared_buffer buf) рд▓рд╛рдЧреВ рдХреА рдЬрд╛рддреА рд╣реИред
рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдХрдХреНрд╖рд╛ рдореЗрдВ рджреЛрдиреЛрдВ рднреВрдорд┐рдХрд╛рдПрдВ рд╣реИрдВ, рддреЛ рдЖрдк рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 struct client_session: yarmi::client_base<client_session>, yarmi::client_invoker<client_session> { client_session(boost::asio::io_service &ios) :yarmi::client_base<client_session>(ios, *this) ,yarmi::client_invoker<client_session>(*this, *this) // <<<<<<<<<<<<<<<<<<<<<<<<< {} }; 

рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
 struct client_session: yarmi::client_base<client_session>, yarmi::client_invoker<client_session> { client_session(boost::asio::io_service &ios) :yarmi::client_base<client_session>(ios, *this) ,yarmi::client_invoker<client_session>(*this, *this) {} void on_registration(const std::string &msg, const std::string ┬оkey) {} void on_activation(const std::string &msg) {} void on_login(const std::string &msg) {} void on_logout(const std::string &msg) {} void on_users_online(const std::vector<std::string> &users) {} }; 


рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ yarmi::client_invoker рдХреЗ рдкреВрд░реНрд╡рдЬреЛрдВ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ yarmi::client_invoker ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ client_session рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ client_session , рдЖрдк registration() рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 { registration("niXman"); } 

рд╣рдореЗрдВ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЙрддреНрддрд░ рдорд┐рд▓реЗрдЧрд╛ client_session::on_registration(std::string msg, std::string regkey)
рд╡рд╣ рд╕рдм рд╣реИ!

рдХрдорд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдирд╛рдореЛрдВ рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдЙрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рдирд╣реАрдВ рд╕рдордЭрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рддрдп рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдВрддрддрдГ, рдпрд╣ рд╕рдм YARMI рдирд╛рдордХ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╣реБрдЖ (рдлрд┐рд░ рднреА рдПрдХ рдФрд░ RMI)ред
рд╡рд░реНрдгрд┐рдд рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЗрдирдХреЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - yarmi.hpp ред рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдПрдХ рджрд┐рди рдХрд╛ рд╡реНрдпрд╡рд╕рд╛рдп рд╣реБрдЖред

рдЗрд╕ рдкреВрд░реА рдЪреАрдЬрд╝ рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдБ рдФрд░ рдпрд╣рд╛рдБ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред рдкрд╣рд▓рд╛ рдкрд░реАрдХреНрд╖рдг рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЕрднреА рднреА рдкреВрд░рд╛ рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗред

рд╡рд░реНрдгрд┐рдд рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкреГрд╖реНрда рдкрд░ рдЖрдкрдХреЛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмрд╣реБ-рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рд╕рд░реНрд╡рд░ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛрдб рдХреЗ рдХреЛрдб рдорд┐рд▓реЗрдВрдЧреЗред

рдПрдХ рдирд┐рд╖реНрдХрд░реНрд╖ рдХреЗ рдмрдЬрд╛рдп


рдпреЛрдЬрдирд╛рдУрдВ:
1. рдХрдИ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреА рдкреАрдврд╝реА
2. рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реЗрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХрд╣реАрдВ рдЕрдзрд┐рдХ рд╕рд░рд▓ рд╣реИ)
3. рдЕрдкрдиреЗ рд▓реЛрдХреЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛

рдореИрдВ рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рд╕реБрдЭрд╛рд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдЖрднрд╛рд░реА рд░рд╣реВрдВрдЧрд╛ред

рдкреБрдирд╢реНрдЪ
рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдорд╛рд░реА рдХрдИ рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ, рдЦреЗрд▓ рджреЗрд╡ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

Source: https://habr.com/ru/post/In199496/


All Articles