рдкреЗрдбрд╝ рдкрд░ рдХреИрд╕реЗ рдЪрдврд╝реЗрдВрдЧреЗ

рдЪрд┐рддреНрд░ 2

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

рдкрд╣рд▓реА рдЪреАрдЬреЗрдВ рдкрд╣рд▓реЗ


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

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

рдПрдХ рдкреЗрдбрд╝ рдХреЗ рд╕рд╛рде PVS-Studio рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдореЗрдВ, рдХрдИ рдЪреАрдЬреЗрдВ рд╣реЛрддреА рд╣реИрдВ:

  • . , , , using typedef, . , . ;
  • . , ;
  • , , , ;
  • . ( ). . , nullptr , , . ;
  • . , . , .

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

рд╣рдо рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЗ рдЕрдВрджрд░ рдкреЗрдбрд╝ рдХрд╛ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдХреИрд╕реЗ рджрд┐рдЦрддрд╛ рд╣реИред рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдкрд░рд┐рдЪрдп рдХреЗ рд╕рд╛рде, рдЗрд╕ рдорд╛рдорд▓реЗ рдХреА рддрд╣ рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИред

рдЪрд┐рддреНрд░ 1

рдпрд╣ рдХрд╛рдо рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ


рдРрддрд┐рд╣рд╛рд╕рд┐рдХ рд░реВрдк рд╕реЗ, рдкреАрд╡реАрдПрд╕-рд╕реНрдЯреВрдбрд┐рдпреЛ рдХреЛрдб рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдкреЗрдбрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреНрд▓рд╛рд╕рд┐рдХ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рд╕рднреА рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдЪрд┐рдд рд╣реИ - рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдиреЛрдб рд╣реИ рдЬреЛ рдЖрдо рддреМрд░ рдкрд░ рджреЛ рдмрдЪреНрдЪреЛрдВ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред рдиреЛрдбреНрд╕ рдЬрд┐рдиреНрд╣реЗрдВ рд╡рдВрд╢рдЬ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдореИрдВ рдЯрд░реНрдорд┐рдирд▓реЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░реВрдВрдЧрд╛, рдЕрдиреНрдп рд╕рднреА - рдЧреИрд░-рдЯрд░реНрдорд┐рдирд▓ред рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдПрдХ рдиреЙрдирдЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдмрдЪреНрдЪреЗ рдХреЗ рдиреЛрдбреНрд╕ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЯрд░реНрдорд┐рдирд▓ рд╕реЗ рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рд╡рдВрд╢рдЬреЛрдВ рдХреЛ рдореМрд▓рд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреА рдЬрд╛рддреА рд╣реИред рдЯрд░реНрдорд┐рдирд▓ рдиреЛрдбреНрд╕ (рдпрд╛ рдкрддреНрддреЗ) рдореЗрдВ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдЪреАрдЬрд╝ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХрд╛ рдЕрднрд╛рд╡ рд╣реЛрддрд╛ рд╣реИред

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

рд╕рдВрдХрд▓рдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рдорд╛рдирдХ рд╣реИ, рдореИрдВ рд╣рд░ рдХрд┐рд╕реА рдХреЛ рд╢реИрд▓реА рдХреЗ рдХреНрд▓рд╛рд╕рд┐рдХреНрд╕ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ - рдж рдбреНрд░реИрдЧрди рдмреБрдХ ред

рд╣рдо рдЖрдЧреЗ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВред рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдХреЛрдб рдЙрджрд╛рд╣рд░рдг рджреЗрдЦреЗрдВ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдЗрд╕реЗ рдХреИрд╕реЗ рджреЗрдЦрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╣рдорд╛рд░реЗ рдЖрдВрддрд░рд┐рдХ рд╡реГрдХреНрд╖ рджреГрд╢реНрдп рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╕реЗ рдХрдИ рдЪрд┐рддреНрд░ рд╣реЛрдВрдЧреЗред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рдЙрджрд╛рд╣рд░рдг:

int f(int a, int b)
{
  return a + b;
}

рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмрд╛рдж рдпрд╣ рд╕рд░рд▓ рдХрд╛рд░реНрдп рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛ (рдЧреИрд░-рдЯрд░реНрдорд┐рдирд▓ рдиреЛрдбреНрд╕ рдкреАрд▓реЗ рд░рдВрдЧ рдореЗрдВ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВ):

рдЪрд┐рддреНрд░ 6

рдЗрд╕ рджреГрд╢реНрдп рдХреЗ рдЕрдкрдиреЗ рдкрдХреНрд╖ рдФрд░ рд╡рд┐рдкрдХреНрд╖ рд╣реИрдВ, рдФрд░ рдмрд╛рдж рдореЗрдВ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдереЛрдбрд╝рд╛ рдФрд░ред рд▓реЗрдХрд┐рди рдЪрд▓реЛ рдкреЗрдбрд╝ рдХреЛ рджреЗрдЦреЛред рддреБрд░рдВрдд рдПрдХ рдЖрд░рдХреНрд╖рдг рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдХреБрдЫ рд╣рдж рддрдХ рдмреЗрдорд╛рдиреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рд╡рд┐рд░рд╛рдо рдЪрд┐рд╣реНрди рдФрд░ рдХреЛрд╖реНрдардХ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд╕рдВрдХрд▓рди рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ, рдпрд╣ рд╢рд╛рдирджрд╛рд░ рдХрдЪрд░рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдиреИрджрд╛рдирд┐рдХ тАЛтАЛрдирд┐рдпрдореЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рддрд░рд╣ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХрднреА-рдХрднреА рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддреА рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╕рд╛рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА (рдПрдПрд╕рдЯреА) рдХреЗ рд╕рд╛рде рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд╛рд░реНрд╕ рдЯреНрд░реА (рдбреАрдЯреА) рдХреЗ рд╕рд╛рдеред

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

рдЬрдмрдХрд┐ рд╣рдореЗрдВ рдкреЗрдбрд╝ рдХреЗ рдмрд╛рдПрдВ рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реЛрдЧреАред рдпрд╣рд╛рдБ рдпрд╣ рдПрдХ рдмрдбрд╝реЗ рдХреНрд▓реЛрдЬрдЕрдк рдореЗрдВ рд╣реИ:

рдЪрд┐рддреНрд░ резреж

рдпрд╣ рд╡рд┐рдЬреНрдЮрд╛рдкрди рд╕реБрд╡рд┐рдзрд╛рдПрдБред PtreeDeclarator рдореВрд▓ рдиреЛрдб рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдЙрд╕рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рде рдиреЛрдбреНрд╕ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдкреНрд░рдХрд╛рд░ рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рдПрдиреНрдХреЛрдбреЗрдб рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рднреА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЪрд┐рддреНрд░ рдмрд╣реБрдд рд╣реА рд╕реБрдВрджрд░ рд╣реИ, рдФрд░ рдХреЛрдб рдХреЗ рд╕рд╛рде рдкреЗрдбрд╝ рдХреЗ рддрддреНрд╡реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред

рдЖрд╕рд╛рди рд▓рдЧрддрд╛ рд╣реИ, рд╣реИ рдирд╛?

рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд▓реЗрддреЗ рд╣реИрдВред рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЛрдб рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ f :

f(42, 23);

рдкреЗрдбрд╝ рдореЗрдВ рдПрдХ рд╕рдорд╛рд░реЛрд╣ рдХреЙрд▓ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

рдЪрд┐рддреНрд░ 12

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

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

рд╣рдо рдпрд╣ рдХреИрд╕реЗ рдХрд░реЗрдВрдЧреЗ? рдкрдврд╝рддреЗ рд░рд╣рд┐рдпреЗред

рд╕рд╛рдЗрдХрд┐рд▓ рдХрд╛ рдХрд╛рд░рдЦрд╛рдирд╛


рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреЗрдбрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░рдирд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдЖрдкрдХреЛ рдмрд╕ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдРрд╕рд╛ рдХрд░реЗрдЧрд╛, рдФрд░ рд╣рд░ рдЬрдЧрд╣ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛ред рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕реЗ рд▓рдВрдмреЛрджрд╛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕рд╛ рд╣реЛрдЧрд╛, рдЕрдЧрд░ рдПрдХ-рджреЛ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред

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

рджреВрд╕рд░реЗ, рдХрднреА-рдХрднреА рдЖрдкрдХреЛ рд╡рд░реНрддрдорд╛рди рддрддреНрд╡ рдХреЗ рд╕реВрдЪрдХрд╛рдВрдХ рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рджреЛ рддрд░реНрдХреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рдФрд░ рд░реЛрдХрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рддреАрд╕рд░рд╛, рдЖрдЗрдП рдлрд╝рдВрдХреНрд╢рди рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкрдЪрд╛ рд▓реЗрддреЗ рд╣реИрдВред рдХрд╣реЛ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдХреЛрдб рд╣реИ:

int f(int a, int b)
{
  int c = a + b;
  c *= 2;
  if (c < 42) return c;
  return 42;
}

рдпрд╣ рдХреЛрдб рдЧреВрдВрдЧрд╛ рд╣реИ, рдореБрдЭреЗ рдкрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдЗрдП рдЕрдм рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдкреЗрдбрд╝ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИред рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛ рджреЗрдЦреА рд╣реИ, рдпрд╣рд╛рдБ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд╢рд░реАрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

рдЪрд┐рддреНрд░ 4

рдпрд╣ рдорд╛рдорд▓рд╛ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреА рддрд░рд╣ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рдХреБрдЫ рдЕрдВрддрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рд╕реЗ рдЪрд┐рддреНрд░ рдкрд░ рдПрдХ рдФрд░ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред

рдЖрдкрдиреЗ рдзреНрдпрд╛рди рджрд┐рдпрд╛?

рдпрд╣ рд╕рд╣реА рд╣реИ, рдЗрд╕ рд╕реВрдЪреА рдореЗрдВ рдХреЛрдИ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рдирд╣реАрдВ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕реЗ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд┐рднрд╛рдЬрдХ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрдо рд╕реЗ рдХрдо рджреЛ рдорд╛рдорд▓реЗ рд╣реИрдВ:

  • рдЕрд▓рдЧ рд╕реВрдЪреАред
  • рдкреВрд░реА рд╕реВрдЪреАред

рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЛрдб рдореЗрдВ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рд╣реЛрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдпрд╣ рдЕрдиреБрд╡рд╛рджрдХ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рдПрдХ рд╕рд░рд▓реАрдХреГрдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИред

void ProcessArguments(Ptree* arglist)
{
  if (!arglist) return;

  Ptree* args = Second(arglist);
  while (args)
  {
    Ptree* p = args->Car();
    if (!Eq(p, ','))
    {
      ProcessArg(p);
    }

    args = args->Cdr();
  }
}

рдЕрдЧрд░ рдореБрдЭреЗ рд╣рд░ рдмрд╛рд░ рдПрдХ рд╕рдорд╛рди рдХреЛрдб рдХрд╛ рднреБрдЧрддрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдореИрдВ рдкрд╣рд▓реЗ рд╣реА рдЕрдореАрд░ рд╣реЛ рдЬрд╛рдКрдВрдЧрд╛ред

рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред рдореБрдЭреЗ рддреБрд░рдВрдд рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдкреБрд░рд╛рдирд╛ рдХреЛрдб рд╣реИ рдЬреЛ C ++ 11 рд╕реЗ рднреА рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЕрдзрд┐рдХ рдЖрдзреБрдирд┐рдХ рдорд╛рдирдХреЛрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рд╣реИред рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВрдиреЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдЪреАрди рд╕рднреНрдпрддрд╛рдУрдВ рдХреЗ рд╕рдордп рдХреЗ рдПрдХ рдЯреБрдХрдбрд╝реЗ рдХреЗ рд▓рд┐рдП рджреЗрдЦрд╛ рдерд╛ред

рддреЛ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрд╖реНрдардХ рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ:

(42, 23) рдХреЛрд╖реНрдардХ рдХреА рд╕рд╛рдордЧреНрд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░рд╛

рдХрд╛рд░реНрдп рдпрд╣рд╛рдБ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╣ рд╕рдм рдХрд░рддреА рд╣реИ рдПрдХ рдмрд╛рд░ рджрд╛рдИрдВ рдУрд░ рдФрд░ рдлрд┐рд░ рдПрдХ рдмрд╛рд░ рдмрд╛рдЗрдирд░реА рдЯреНрд░реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд╛рдИрдВ рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИред рдЕрдЧрд▓рд╛, рд▓реВрдк рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рддрддреНрд╡реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ: 42, рдлрд┐рд░ рдПрдХ рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо, рдлрд┐рд░ 23, рдФрд░ рдЕрдЧрд▓реЗ рдЪрд░рдг рдореЗрдВ рдЖрд░реНрдЧреНрд╕ рдкреЙрдЗрдВрдЯрд░рд╢реВрдиреНрдп рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╢рд╛рдЦрд╛ рдХреЗ рдЕрдВрдд рдореЗрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддреЗ рд╣реИрдВред рд▓реВрдк, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдирд┐рд░реНрдмрд╛рдз рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдореЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред

рдереЛрдбрд╝реЗ рдмрджрд▓реЗ рд╣реБрдП рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдЗрд╕реА рддрд░рд╣ рдХреЗ рдХрд╛рд░реНрдп рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдкреБрд░рд╛рдиреЗ рдХреЛрдб рдореЗрдВред

рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдгред рдореБрдЭреЗ рдХреИрд╕реЗ рдкрддрд╛ рдЪрд▓реЗрдЧрд╛ рдХрд┐ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреЛрдб рдмреНрд▓реЙрдХ рдореЗрдВ рдХрд┐рд╕реА рдирд┐рд╢реНрдЪрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рд╣реИ? рдЙрд╕рдХреЗ рдЬреИрд╕рд╛:

bool IsFunctionCalled(const Ptree* body, std::string_view name)
{
  if (!arglist) return;

  const Ptree* statements = body;
  while (statements)
  {
    const Ptree* cur = statements->Car();
    if (IsA(cur, ntExprStatement) && IsA(cur->Car(), ntFuncallExpr))
    {
      const Ptree* funcName = First(cur->Car());
      if (Eq(funcName, name))
        return true;
    }

    statements = statements->Cdr();
  }
  return false;
}

рдзреНрдпрд╛рди рджреЗрдВред рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдиреЛрдЯрд┐рд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЙрд╕рдХреА рдХреНрдпрд╛ рдЙрдореНрд░ рд╣реИ? рд╡рд╣рд╛рдБ std :: string_view рдЪрд┐рдкрдХ рдЬрд╛рддреА рд╣реИред рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдмрд╕реЗ рдкреБрд░рд╛рдирд╛ рдХреЛрдб рднреА рдзреАрд░реЗ-рдзреАрд░реЗ рдкрд░рд┐рд▓рдХреНрд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдзреАрд░реЗ-рдзреАрд░реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рд░рд╣реЗрдЧрд╛ред

рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЖрдк рдпрд╣рд╛рдБ рдХреБрдЫ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдкреНрд░рдпреЛрдЧ рдХрд░реЗрдВ? рдЦреИрд░, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╛рдирдХ find_if рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо ред рд╡рд╣рд╛рдБ рдХреНрдпрд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╢реНрд░реЗрдгреА-рдЖрдзрд╛рд░рд┐рдд рдХреЗ рд▓рд┐рдП рдкрдардиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рд╣реЛрдЧрд╛ рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреЗ рд╕рдорд░реНрдерди рдХреА рд╕реБрд╡рд┐рдзрд╛ рд╣реЛрдЧреАред

рдЖрдЗрдП рдЗрд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред

рдкреЗрдбрд╝ рдХреЛ рдмреЙрдХреНрд╕ рдореЗрдВ рд░рдЦреЛ


рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдкреЗрдбрд╝ рдХреЛ рдПрд╕рдЯреАрдПрд▓ рдХрдВрдЯреЗрдирд░ рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд╕реВрдЪрд┐рдпреЛрдВ рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдХреА рдкрд░рд╡рд╛рд╣ рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рд╣рдо рдиреЛрдбреНрд╕ рдкрд░ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬреИрд╕реЗ:

void DoSomethingWithTree(const Ptree* tree)
{
  ....
  for (auto cur : someTreeContainer)
  {
    ....
  }
}

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЗрдХрд╛рдИ рд╣реИ рдЬрд┐рд╕реЗ someTreeContainer рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдо рдЕрднреА рддрдХ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдХреЗ рддрд░реАрдХреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рдмрд╛рдд рдХрд░рддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЗрдВ рднреА рдорд╛рдирдХ рд▓реЛрдЧреЛрдВ рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪрд▓реЛ рдЙрдирдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрдЯреНрд░реЗрдЯрд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

template <typename Node_t,
          std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int>>
class PtreeIterator
{
public:
  using value_type = Node_t;
  using dereference_type = value_type;
  using reference = std::add_lvalue_reference_t<value_type>;
  using pointer   = std::add_pointer_t<value_type>;
  using difference_type =
    decltype(std::declval<pointer>() - std::declval<pointer>());
  using iterator_category = std::forward_iterator_tag;

public:
  PtreeIterator(Node_t* node) noexcept : m_node{ node } {}
  ....

  PtreeIterator& operator++() noexcept
  {
    m_node = Rest(m_node);
    return *this;
  }
  dereference_type operator*() const noexcept
  {
    return static_cast<dereference_type>(First(m_node));
  }

private:
  Node_t* m_node = nullptr;
};

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

рдЕрдм рд╣рдо рдХрдВрдЯреЗрдирд░ рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬрд┐рд╕рдореЗрдВ рд╣рдо рдЯреНрд░реА рдиреЛрдб рд░рдЦреЗрдВрдЧреЗред рдпрд╣рд╛рдБ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╡рд┐рдХрд▓реНрдк рд╣реИ:

template <typename Node_t>
class PtreeContainer
{
public:
  using Iterator = PtreeIterator<Node_t>;
  using value_type = typename Iterator::dereference_type;
  using size_type  = size_t;
  using difference_type =
        typename Iterator::difference_type;

public:
  PtreeContainer(Node_t* nodes) :
    m_nodes{ nodes }
  {
    if (IsLeaf(m_nodes))
    {
      m_nodes = nullptr;
    }
  }

  ....

  Iterator begin() const noexcept
  { 
    return m_nodes;
  }
  Iterator end() const noexcept
  { 
    return nullptr; 
  }
  bool empty() const noexcept
  {
    return begin() == end();
  }

private:
  Node_t* m_nodes = nullptr;
};

рд╣рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд╣рдо рдлреИрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

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

рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рд╣рдо рд╕рд┐рд░реНрдл рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЖрдЗрдП рдмрддрд╛рддреЗ рд╣реИрдВ рдРрд╕реЗ:

enum class PtreeIteratorTag : uint8_t
{
  Statement,
  List
};

template <typename Node_t, PtreeIteratorTag tag,
  std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int> = 0>
class PtreeIterator { .... };

рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рдХреИрд╕реЗ рдорджрдж рдорд┐рд▓реЗрдЧреА? рдкреНрд░рд╛рдердорд┐рдХред рд╣рдо рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рдореЗрдВ рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдВрдЧреЗред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, C ++ 17 рдореЗрдВ рд╣рдо рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдЪрд░рдг рдореЗрдВ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрдХреНрд╕ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ :

PtreeIterator& operator++() noexcept
{
  if constexpr (tag == PtreeIteratorTag::Statement)
  {
    m_node = Rest(m_node);
  }
  else
  {
    m_node = RestRest(m_node);
  }
  return *this;
}

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

template <typename Node_t, PtreeIteratorTag tag>
class PtreeContainer
{
public:
  using Iterator = PtreeIterator<Node_t, tag>;
  ....
};

рдЕрдм, рд╣рдо рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд░ рд░рд╣реЗ рд╣реИрдВ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВред

рд▓реЗрдХрд┐рди рд╡рд╣ рд╕рдм рдирд╣реАрдВ рд╣реИ


рдЖрдЗрдП рдЗрд╕ рдХреЛрдб рдХреЛ рджреЗрдЦреЗрдВ:

void ProcessEnum(Ptree* argList, Ptree* enumPtree)
{
  const ptrdiff_t argListLen = Length(argList);
  if (argListLen < 0) return;

  for (ptrdiff_t i = 0; i < argListLen; ++i)
  {
    std::string name;
    Ptree* elem;

    const EGetEnumElement r = GetEnumElementInfo(enumPtree, i, elem, name);
    ....
  }
}

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдХреЛрдб рдореЗрдВ рдмрд╣реБрдд рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ, рдХрд╛рдЙрдВрдЯрд░ рд╕реЗ рд▓реВрдк рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕ рддрдереНрдп рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ GetEnumElementInfo рдлрд╝рдВрдХреНрд╢рди рдмрд╣реБрдд рд╕рдВрджрд┐рдЧреНрдз рджрд┐рдЦрддрд╛ рд╣реИред рдЕрдм рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рдмреНрд▓реИрдХ рдмреЙрдХреНрд╕ рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдпрд╣ рдорд╛рди рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЗрдВрдбреЗрдХреНрд╕ рджреНрд╡рд╛рд░рд╛ рдПрдирдо рддрддреНрд╡ рдХреЛ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рддрд╛ рд╣реИ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреЗрдбрд╝ рдореЗрдВ рдЕрдкрдирд╛ рдирд╛рдо рдФрд░ рдиреЛрдб рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд╡рд╛рдкрд╕реА рдХрд╛ рдореВрд▓реНрдп рднреА рдереЛрдбрд╝рд╛ рдЕрдЬреАрдм рд╣реИред рдЖрдЗрдП рдЗрд╕рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдВ - рд╣рдорд╛рд░реА рд╕реВрдЪреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрджрд░реНрд╢ рдиреМрдХрд░реА:

void ProcessEnum(const Ptree* argList)
{
  for (auto elem : PtreeContainer<const Ptree, PtreeIteratorTag::List>(argList))
  {
    auto name = PtreeToString(elem);
    ....
  }
}

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

рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд╕реБрдВрджрд░ рдХреЛрдб рдХреЛ рдЧрдбрд╝рдмрдбрд╝ рдХрд░рддреЗ рд╣реИрдВ:

void ProcessEnum(const Ptree* argList)
{
  size_t i = 0;
  for (auto elem : PtreeContainer<const Ptree, PtreeIteratorTag::List>(argList))
  {
    auto name = PtreeToString(elem);
    ....
    UseIndexSomehow(i++);
  }
}

рдЕрднреА рднреА рдПрдХ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реВрдВ:

рдЪрд┐рддреНрд░ 7

рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рд╣рдореЗрдВ рдХреБрдЫ рдРрд╕рд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рддрддреНрд╡реЛрдВ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рдЧрд┐рди рд╕рдХреЗред рдПрдХ рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЬреЛрдбрд╝реЗрдВред рдореИрдВрдиреЗ рдлрд┐рд░ рд╕реЗ рд╕рдВрдХреНрд╖рд┐рдкреНрддрддрд╛ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рд╡рд░рдг рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛:

template <typename Node_t, PtreeIteratorTag tag,
  std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int>>
class PtreeCountingIterator
{
public:
  using size_type = size_t;
  using value_type = Node_t;
  using dereference_type = std::pair<value_type, size_type>;
  using reference = std::add_lvalue_reference_t<value_type>;
  using pointer = std::add_pointer_t<value_type>;
  using difference_type =
        decltype(std::declval<pointer>() - std::declval<pointer>());
  using iterator_category = std::forward_iterator_tag;

public:
  PtreeCountingIterator(Node_t* node) noexcept : m_node{ node } {}
  ....

  PtreeCountingIterator& operator++() noexcept
  {
    if constexpr (tag == PtreeIteratorTag::Statement)
    {
      m_node = Rest(m_node);
    }
    else
    {
      m_node = RestRest(m_node);
    }

    ++m_counter;
    return *this;
  }

  dereference_type operator*() const noexcept
  {
    return { static_cast<value_type>(First(m_node)), counter() };
  }

private:
  Node_t* m_node = nullptr;
  size_type m_counter = 0;
};

рдЕрдм рд╣рдо рдРрд╕реЗ рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣реИ рдирд╛?

void ProcessEnum(const Ptree* argList)
{
  for (auto [elem, i] :
            PtreeCountedContainer<const Ptree, PtreeIteratorTag::List>(argList))
  {
    auto name = PtreeToString(elem);
    ....
    UseIndexSomehow(i);
  }
}

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

рд╣рдореЗрдВ рдХрдВрдЯреЗрдирд░ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдмрд╛рдж рдореЗрдВ рдЙрд╕ рдкрд░ рдЕрдзрд┐рдХред

рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рдХреЗ рдкреНрд░рдХрд╛рд░


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

рдЗрд╕ рдХреЛрдб рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:

int a, b, c = 0, d;

рд╣рдо рдкреЗрдбрд╝ рдореЗрдВ рдХреНрдпрд╛ рджреЗрдЦрддреЗ рд╣реИрдВ:

рдЪрд┐рддреНрд░ 13

рдЪрд▓реЛ рдЕрдм рдШреЛрд╖рдгрд╛рдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рдкрд░ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ рдореИрдВ рдЖрдкрдХреЛ рдкреЗрдбрд╝ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдФрд░ рдмрддрд╛рдКрдВрдЧрд╛ред рдЙрд╕рд╕реЗ рдкрд╣рд▓реЗ рд╣рд░ рд╕рдордп, рд╣рдо рдПрдХ рд╕реВрдЪрдХ рдХреЗ рд╕рд╛рде Ptree рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рдереЗ ред рдпрд╣ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЕрдиреНрдп рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдбреНрд╕ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗ рд╣реИрдВред рдЙрдирдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рддрд╕реНрд╡реАрд░ рдореЗрдВ рд╕рдмрд╕реЗ рдКрдкрд░реА рдиреЛрдб, рдлрд╝рд░реНрд╕реНрдЯ рдФрд░ рд╕реЗрдХреЗрдВрдб рдЬреИрд╕реЗ рдпреВрдЯрд┐рд▓рд┐рдЯреА рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛, рдШреЛрд╖рдгрд╛рдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд╡рд╛рдкрд╕ рдЖ рд╕рдХрддрд╛ рд╣реИ ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рддрд░реАрдХреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд╛рд░ рдФрд░ рд╕реАрдбреАрдЖрд░ (рд▓рд┐рд╕реНрдк рднрд╛рд╖рд╛ рдХреЗ рдкреНрд░рд╢рдВрд╕рдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИрд▓реЛ)ред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдирд┐рджрд╛рди рдореЗрдВ рд╣рдо рдкреЗрдбрд╝ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЙрдкреЗрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рд░ рдХреЛрдИ рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рд╕рд╛рд░ рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реИрдВред

рд╕рднреА рдШреЛрд╖рдгрд╛рдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдмрд╛рдИрдкрд╛рд╕ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

void ProcessDecl(const PtreeDeclarator* decl) { .... }

void ProcessDeclarators(const PtreeDeclaration* declaration)
{
  for (auto decl : declaration->GetDeclarators())
  {
    ProcessDecl(static_cast<const PtreeDeclarator*>(decl));
  }
}

GetDeclarators рд╡рд┐рдзрд┐ рдПрдХ рдкреБрди : рдкреНрд░рдпреЛрдЬреНрдп рдХрдВрдЯреЗрдирд░ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕рдХрд╛ рдкреНрд░рдХрд╛рд░ PtreeContainer <const Ptree, PtreeIteratorTag :: List> рд╣реИ ред

рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде, рдХрд▓рд╛рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рддреЛ рд╕рдм рдХреБрдЫ рдареАрдХ рд░рд╣реЗрдЧрд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ ProcessDecl рдлрд╝рдВрдХреНрд╢рди Ptree рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдЪрд╛рд╣рддрд╛ рд╣реИ , рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдкрддрд╛ рд╣реИред рдореИрдВ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкреБрди: рдЗрдЯреНрд░реЗрдЯрд░ рдХреЛ рдмрджрд▓рдиреЗ рдФрд░ рдХрд╛рд╕реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

template <typename Node_t, typename Deref_t, PtreeIteratorTag tag,
  std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int>>
class PtreeIterator
{
public:
  using value_type = Deref_t;
  using dereference_type = value_type;
  using reference = std::add_lvalue_reference_t<value_type>;
  using pointer = std::add_pointer_t<value_type>;
  using difference_type =
        decltype(std::declval<pointer>() - std::declval<pointer>());
  using iterator_category = std::forward_iterator_tag;
  ....
}

рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рд░ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЗрди рд╕рднреА рддрд░реНрдХреЛрдВ рдХреЛ рди рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рднреА рдЕрд╡рд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЙрдкрдирд╛рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementIterator =
PtreeIterator<Node_t, Deref_t, PtreeIteratorTag::Statement>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeListIterator =
PtreeIterator<Node_t, Deref_t, PtreeIteratorTag::List>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementCountingIterator =
PtreeCountingIterator<Node_t, Deref_t, PtreeIteratorTag::Statement>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeListCountingIterator =
PtreeCountingIterator<Node_t, Deref_t, PtreeIteratorTag::List>;

рд╡рд╣ рдмреЗрд╣рддрд░ рд╣реИред рдЕрдм, рдпрджрд┐ рд╣рдореЗрдВ рдЬрд╛рддрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рддрд░реНрдХ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╣рдо рдЯреИрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рди рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рд╕рд┐рд░ рдХреЛ рд░реЛрдХ рднреА рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВ ред

рд▓реЗрдХрд┐рди рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рд╕рд╛рде рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╡рд░реНрдЧ рд░рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рднреА рдкреБрдирд░рд╛рд╡реГрддреНрдд рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реЛред рдЕрдм рдпрд╣ рдЕрд╢реЛрднрдиреАрдп рд░реВрдк рд╕реЗ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рд╕рд╛рджрдЧреА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

рдЪрд┐рддреНрд░ 39

рдпрд╣реА рд╣реИ, рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рдПрдХрд▓ рдХрдВрдЯреЗрдирд░ рд╡рд░реНрдЧ рд╣рдорд╛рд░реЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдпрд╣ рдмрддрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рдХрд┐ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрд░реАрдлреЗрд░рд┐рдВрдЧ рдХреЗ рд╕рдордп рд╡рд╛рдкрд╕ рд▓реМрдЯрдирд╛ рд╣реИред рдлрд┐рд░, рдХреЛрдб рдореЗрдВ, рд╣рдо рдмрд╕ рдЙрд╕ рдХрдВрдЯреЗрдирд░ рдХреЛ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд┐рдирд╛ рд╕реЛрдЪреЗ-рд╕рдордЭреЗ рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрддреЗ рд╣реИрдВред

рд╣рдо рдЗрд╕ рдкреНрд░рд╢реНрди рдХреА рдЬрд╛рдБрдЪ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рдХрд░реЗрдВрдЧреЗред

рдкреИрдЯрд░реНрди рдХрд╛ рдЬрд╛рджреВ


рддреЛ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдЬрд░реВрд░рдд рд╣реИ:

  • рдПрдХ рдХрдВрдЯреЗрдирд░ рдЬреЛ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд░реВрдк рд╕реЗ рдХрд┐рд╕реА рднреА рдкреБрдирд░рд╛рд╡реГрддреНрдд рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред
  • рдиреЛрдбрд░реНрд╕ рдХреА рд╕реВрдЪреА рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдХрд░реНрддрд╛, рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдФрд░ рдПрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреЛрдиреЛрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред
  • рдПрдХ рд╣реА рдкреБрдирд░рд╛рд╡реГрддреНрдд, рд▓реЗрдХрд┐рди рдПрдХ рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд╕рд╛рдеред
  • рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рджреЛрдиреЛрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдбреЗрд░реЗрдлрд╝рд░рд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп рдХрд╛рд╕реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдВрдЯреЗрдирд░ рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреБрдирд░рд╛рд╡реГрддреНрдд рдкреНрд░рдХрд╛рд░ рд╕реЗ рдмрд╛рдВрдзрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реБрдЖ:

template <template <typename, typename> typename FwdIt,
          typename Node_t,
          typename Deref_t = std::add_pointer_t<Node_t>>
class PtreeContainer
{
public:
  using Iterator = FwdIt<Node_t, Deref_t>;
  using value_type = typename Iterator::dereference_type;
  using size_type  = size_t;
  using difference_type = typename Iterator::difference_type;

public:
  PtreeContainer(Node_t* nodes) :
    m_nodes{ nodes }
  {
    if (IsLeaf(m_nodes))
    {
      m_nodes = nullptr;
    }
  }

  ....
  Iterator begin() const noexcept
  { 
    return m_nodes;
  }
  Iterator end() const noexcept
  { 
    return nullptr; 
  }
  bool empty() const noexcept
  {
    return begin() == end();
  }
  ....

private:
  Node_t* m_nodes = nullptr;
};

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

difference_type count() const noexcept
{
  return std::distance(begin(), end());
}

рдпрд╛ рдпрд╣рд╛рдБ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рд╕рдВрдЪрд╛рд▓рдХ рд╣реИ:

value_type operator[](size_type index) const noexcept
{
  size_type i = 0;
  for (auto it = begin(); it != end(); ++it)
  {
    if (i++ == index)
    {
      return *it;
    }
  }

  return value_type{};
}

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЙрдирдХреА рд░реИрдЦрд┐рдХ рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдХрд╛рд░рдг рдРрд╕реЗ рддрд░реАрдХреЛрдВ рдХреЛ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рд╡реЗ рдЙрдкрдпреЛрдЧреА рд╣реЛрддреЗ рд╣реИрдВред

рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рдЙрдкрдирд╛рдо рдЬреЛрдбрд╝реЗрдВ:

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementList =
PtreeContainer<PtreeStatementIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeItemList =
PtreeContainer<PtreeListIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeCountedStatementList =
PtreeContainer<PtreeStatementCountingIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeCountedItemList =
PtreeContainer<PtreeListCountingIterator, Node_t, Deref_t>;

рдЕрдм рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдХрдВрдЯреЗрдирд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдХрд╣рддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдП рдЧрдП PtreeDeclaration рд╡рд░реНрдЧ рдореЗрдВ , рд╣рдо GetDeclarators рд╡рд┐рдзрд┐ рд╕реЗ рдПрдХ рдХрдВрдЯреЗрдирд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ , рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рд╡рд┐рднрд╛рдЬрдХ рдХреЛ рдЫреЛрдбрд╝рддрд╛ рд╣реИ , рдЬрдмрдХрд┐ рдЗрд╕рдореЗрдВ рдХреЛрдИ рдХрд╛рдЙрдВрдЯрд░ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдЬрдм dereferenced рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ PtreeDeclarator рдкреНрд░рдХрд╛рд░ рдХрд╛ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ ред рдпрд╣рд╛рдБ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдХрдВрдЯреЗрдирд░ рдХреА рдШреЛрд╖рдгрд╛ рдХреА рдЧрдИ рд╣реИ:

using DeclList =
      Iterators::PtreeItemList<Ptree, PtreeDeclarator*>;
using ConstDeclList =
      Iterators::PtreeItemList<const Ptree, const PtreeDeclarator*>;
             :
void ProcessDecl(const PtreeDeclarator* decl) { .... }

void ProcessDeclarators(const PtreeDeclaration* declaration)
{
  for (auto decl : declaration->GetDeclarators())
  {
    ProcessDecl(decl);
  }
}

рдФрд░ рдЕрдВрдд рдореЗрдВ, рдЪреВрдВрдХрд┐ рдПрд▓рд┐рдпрд╛рд╕реЗрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЕрдиреБрдорд╛рди рдХреЗрд╡рд▓ C ++ 20 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдХреЛрдб рдореЗрдВ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рдХрдВрдЯреЗрдирд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рд╛:

template <typename Node_t>
PtreeStatementList<Node_t> MakeStatementList(Node_t* node)
{
  return { node };
}

template <typename Node_t>
PtreeItemList<Node_t> MakeItemList(Node_t* node)
{
  return { node };
}

template <typename Node_t>
PtreeCountedStatementList<Node_t> MakeCountedStatementList(Node_t* node)
{
  return { node };
}

template <typename Node_t>
PtreeCountedItemList<Node_t> MakeCountedItemList(Node_t* node)
{
  return { node };
}

рдЙрд╕ рдХрд╛рд░реНрдп рдХреЛ рдпрд╛рдж рдХрд░реЗрдВ рдЬреЛ рдПрдирдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рдерд╛ ред рдЕрдм рд╣рдо рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

void ProcessEnum(const Ptree* argList)
{
  for (auto [elem, i] : MakeCountedItemList(argList))
  {
    auto name = PtreeToString(elem);
    ....
    UseIndexSomehow(i);
  }
}

рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛, рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рдмреЗрд╣рддрд░ рд╣реЛ рдЧрдпрд╛ рд╣реИ:

void ProcessEnum(Ptree* argList, Ptree* enumPtree)
{
  const ptrdiff_t argListLen = Length(argList);
  if (argListLen < 0) return;

  for (ptrdiff_t i = 0; i < argListLen; ++i)
  {
    std::string name;
    Ptree* elem;

    const EGetEnumElement r = GetEnumElementInfo(enumPtree, i, elem, name);
    ....
    UseIndexSomehow(i);
  }
}

рдмрд╕ рдЖрдЬ рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рд╣реА


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

рд▓реЗрдЦ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдРрд╕рд╛ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рд╣рдорд╛рд░реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЗ рдХреЛрдб рдХреЛ рдбрд╛рдВрдЯ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдХрд╣рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд╡рд╣рд╛рдВ рд╕рдм рдХреБрдЫ рдЦрд░рд╛рдм рд╣реИред рдпрд╣ рд╕рдЪ рдирд╣реАрдВ рд╣реИред рдЗрддрд┐рд╣рд╛рд╕ рд╡рд╛рд▓реА рдХрд┐рд╕реА рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рддрд░рд╣, рд╣рдорд╛рд░рд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рднреВрд╡реИрдЬреНрдЮрд╛рдирд┐рдХ рдЬрдорд╛рдУрдВ рд╕реЗ рднрд░рд╛ рд╣реИ рдЬреЛ рдкрд┐рдЫрд▓реЗ рдпреБрдЧреЛрдВ рд╕реЗ рдмрдиреЗ рд╣реБрдП рд╣реИрдВред рдЧреМрд░ рдХреАрдЬрд┐рдП рдХрд┐ рд╣рдордиреЗ рдкреНрд░рд╛рдЪреАрди рд╕рднреНрдпрддрд╛ рд╕реЗ рдЬрд╝рдореАрди рдХреЗ рдиреАрдЪреЗ рд╕реЗ рдЦреБрджрд╛рдИ, рдХрд▓рд╛рдХреГрддрд┐рдпреЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓рд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╢реЗрд▓реНрдл рдкрд░ рдЕрдЪреНрдЫрд╛ рджрд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдХреА рд╣реИред

рдкреА.рдПрд╕


рдпрд╣рд╛рдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХреЛрдб рд╣реЛрдВрдЧреЗред рдореБрдЭреЗ рд╕рдВрджреЗрд╣ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдФрд░ рдЕрдВрдд рдореЗрдВ рдореИрдВрдиреЗ рдЗрд╕реЗ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рддрд╛рдХрд┐ рдкрд░реНрджреЗ рдХреЗ рдкреАрдЫреЗ рдХреБрдЫ рднреА рди рдЫреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХреЗред рдЕрдЧрд░ рдЖрдкрдХреЛ рдХреЛрдб рдкрдврд╝рдиреЗ рдореЗрдВ рдХреЛрдИ рджрд┐рд▓рдЪрд╕реНрдкреА рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣рд╛рдВ рдореИрдВ рдЖрдкрдХреЛ рдЕрд▓рд╡рд┐рджрд╛ рдХрд╣реВрдВрдЧрд╛ред рдмрд╛рдХреА рдореИрдВ рдЖрдкрдХреЛ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рд╕реБрдЦрдж рд╕рдордп рдХреА рдХрд╛рдордирд╛ рдХрд░рддрд╛ рд╣реВрдВред

рдХреЛрдб

рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдЪрд▓рдиреЗрд╡рд╛рд▓рд╛


template <typename Node_t, typename Deref_t, PtreeIteratorTag tag,
std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int> = 0>
class PtreeIterator
{
public:
  using value_type = Deref_t;
  using dereference_type = value_type;
  using reference = std::add_lvalue_reference_t<value_type>;
  using pointer = std::add_pointer_t<value_type>;
  using difference_type =
        decltype(std::declval<pointer>() - std::declval<pointer>());
  using iterator_category = std::forward_iterator_tag;

public:
  PtreeIterator(Node_t* node) noexcept : m_node{ node } {}
  PtreeIterator() = delete;
  PtreeIterator(const PtreeIterator&) = default;
  PtreeIterator& operator=(const PtreeIterator&) = default;
  PtreeIterator(PtreeIterator&&) = default;
  PtreeIterator& operator=(PtreeIterator&&) = default;

  bool operator==(const PtreeIterator & other) const noexcept
  {
    return m_node == other.m_node;
  }
  bool operator!=(const PtreeIterator & other) const noexcept
  {
    return !(*this == other);
  }
  PtreeIterator& operator++() noexcept
  {
    if constexpr (tag == PtreeIteratorTag::Statement)
    {
      m_node = Rest(m_node);
    }
    else
    {
      m_node = RestRest(m_node);
    }
    return *this;
  }
  PtreeIterator operator++(int) noexcept
  {
    auto tmp = *this;
    ++(*this);
    return tmp;
  }
  dereference_type operator*() const noexcept
  {
    return static_cast<dereference_type>(First(m_node));
  }
  pointer operator->() const noexcept
  {
    return &(**this);
  }

  Node_t* get() const noexcept
  {
    return m_node;
  }

private:
  Node_t* m_node = nullptr;
};

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementIterator =
PtreeIterator<Node_t, Deref_t, PtreeIteratorTag::Statement>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeListIterator =
PtreeIterator<Node_t, Deref_t, PtreeIteratorTag::List>;

рдХрд╛рдЙрдВрдЯрд░ рдХреЗ рд╕рд╛рде Iterator


template <typename Node_t, typename Deref_t, PtreeIteratorTag tag,
std::enable_if_t<std::is_base_of_v<Node_t, Ptree>, int> = 0>
class PtreeCountingIterator
{
public:
  using size_type = size_t;
  using value_type = Deref_t;
  using dereference_type = std::pair<value_type, size_type>;
  using reference = std::add_lvalue_reference_t<value_type>;
  using pointer = std::add_pointer_t<value_type>;
  using difference_type =
        decltype(std::declval<pointer>() - std::declval<pointer>());
  using iterator_category = std::forward_iterator_tag;

 public:
  PtreeCountingIterator(Node_t* node) noexcept : m_node{ node } {}
  PtreeCountingIterator() = delete;
  PtreeCountingIterator(const PtreeCountingIterator&) = default;
  PtreeCountingIterator& operator=(const PtreeCountingIterator&) = default;
  PtreeCountingIterator(PtreeCountingIterator&&) = default;
  PtreeCountingIterator& operator=(PtreeCountingIterator&&) = default;

  bool operator==(const PtreeCountingIterator& other) const noexcept
  {
    return m_node == other.m_node;
  }
  bool operator!=(const PtreeCountingIterator& other) const noexcept
  {
    return !(*this == other);
  }
  PtreeCountingIterator& operator++() noexcept
  {
    if constexpr (tag == PtreeIteratorTag::Statement)
    {
      m_node = Rest(m_node);
    }
    else
    {
      m_node = RestRest(m_node);
    }

    ++m_counter;
    return *this;
  }
  PtreeCountingIterator operator++(int) noexcept
  {
    auto tmp = *this;
    ++(*this);
    return tmp;
  }
  dereference_type operator*() const noexcept
  {
    return { static_cast<value_type>(First(m_node)), counter() };
  }
  value_type operator->() const noexcept
  {
    return (**this).first;
  }

  size_type counter() const noexcept
  {
    return m_counter;
  }
  Node_t* get() const noexcept
  {
    return m_node;
  }

private:
  Node_t* m_node = nullptr;
  size_type m_counter = 0;
};

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementCountingIterator =
PtreeCountingIterator<Node_t, Deref_t, PtreeIteratorTag::Statement>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeListCountingIterator =
PtreeCountingIterator<Node_t, Deref_t, PtreeIteratorTag::List>;

рдЬреЗрдиреЗрд░рд┐рдХ рдХрдВрдЯреЗрдирд░


template <template <typename, typename> typename FwdIt,
          typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
class PtreeContainer
{
public:
  using Iterator = FwdIt<Node_t, Deref_t>;
  using value_type = typename Iterator::dereference_type;
  using size_type  = size_t;
  using difference_type = typename Iterator::difference_type;

public:
  PtreeContainer(Node_t* nodes) :
    m_nodes{ nodes }
  {
    if (IsLeaf(m_nodes))
    {
      m_nodes = nullptr;
    }
  }

  PtreeContainer() = default;
  PtreeContainer(const PtreeContainer&) = default;
  PtreeContainer& operator=(const PtreeContainer&) = default;
  PtreeContainer(PtreeContainer&&) = default;
  PtreeContainer& operator=(PtreeContainer&&) = default;

  bool operator==(std::nullptr_t) const noexcept
  {
    return empty();
  }
  bool operator!=(std::nullptr_t) const noexcept
  {
    return !(*this == nullptr);
  }
  bool operator==(Node_t* node) const noexcept
  {
    return get() == node;
  }
  bool operator!=(Node_t* node) const noexcept
  {
    return !(*this == node);
  }
  bool operator==(PtreeContainer other) const noexcept
  {
    return get() == other.get();
  }
  bool operator!=(PtreeContainer other) const noexcept
  {
    return !(*this == other);
  }
  value_type operator[](size_type index) const noexcept
  {
    size_type i = 0;
    for (auto it = begin(); it != end(); ++it)
    {
      if (i++ == index)
      {
        return *it;
      }
    }

    return value_type{};
  }

  Iterator begin() const noexcept
  { 
    return m_nodes;
  }
  Iterator end() const noexcept
  { 
    return nullptr; 
  }
  bool empty() const noexcept
  {
    return begin() == end();
  }

  value_type front() const noexcept
  {
    return (*this)[0];
  }
  value_type back() const noexcept
  {
    value_type last{};
    for (auto cur : *this)
    {
      last = cur;
    }

    return last;
  }
  Node_t* get() const noexcept
  {
    return m_nodes;
  }

  difference_type count() const noexcept
  {
    return std::distance(begin(), end());
  }
  bool has_at_least(size_type n) const noexcept
  {
    size_type counter = 0;
    for (auto it = begin(); it != end(); ++it)
    {
      if (++counter == n)
      {
        return true;
      }
    }
    return false;
  }

private:
  Node_t* m_nodes = nullptr;
};

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeStatementList =
PtreeContainer<PtreeStatementIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeItemList =
PtreeContainer<PtreeListIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeCountedStatementList =
PtreeContainer<PtreeStatementCountingIterator, Node_t, Deref_t>;

template <typename Node_t, typename Deref_t = std::add_pointer_t<Node_t>>
using PtreeCountedItemList =
PtreeContainer<PtreeListCountingIterator, Node_t, Deref_t>;



рдпрджрд┐ рдЖрдк рдЗрд╕ рд▓реЗрдЦ рдХреЛ рдЕрдВрдЧреНрд░реЗрдЬреА рдмреЛрд▓рдиреЗ рд╡рд╛рд▓реЗ рджрд░реНрд╢рдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдХреГрдкрдпрд╛ рдЕрдиреБрд╡рд╛рдж рдХреЗ рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: рдпреВрд░реА рдорд┐рдирд╛рдПрд╡ред рдХреИрд╕реЗ рдПрдХ рдкреЗрдбрд╝ рдкрд░ рдЪрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП ред

All Articles