рдЬрд┐рдирдЬрд╛ 2 рд╕реА ++ рджреБрдирд┐рдпрд╛ рдореЗрдВ, рднрд╛рдЧ рджреЛред рдкреНрд░рддрд┐рдкрд╛рджрди

рдЬрд┐рдирдЬрд╛ 2 рд▓реЛрдЧреЛ рдпрд╣ рдЬрд┐рдиреНрдЬрд╛ 2 рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ C ++ рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрд╣рд╛рдиреА рдХрд╛ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╣реИред рдЖрдк рдпрд╣рд╛рдВ рдкрд╣рд▓реЗ рдПрдХ рдХреЛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ: рддреАрд╕рд░рд╛-рдСрд░реНрдбрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ, рдпрд╛ рдореИрдВрдиреЗ рдЬрд┐рдиреНрдЬрд╛ 2 рдХреЛ C ++ рдореЗрдВ рдХреИрд╕реЗ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ ред рдпрд╣ рдЯреЗрдВрдбрд░ рджреЗрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдЧрд╛ред рдпрд╛, рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдПрдХ рдЕрдЬрдЧрд░ рдХреА рддрд░рд╣ рднрд╛рд╖рд╛ рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред


рдЗрд╕ рддрд░рд╣ рдкреНрд░рддрд┐рдкрд╛рджрди


рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЯреЗрдореНрдкреНрд▓реЗрдЯ рддреАрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдбреНрд╕ рд╡рд╛рд▓реЗ рдкреЗрдбрд╝ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ: рд╕рд╛рджрд╛ рдкрд╛рда , рдЧрдгрдирд╛ рдХреА рдЧрдИ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпрд╛рдБ рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕рдВрд░рдЪрдирд╛рдПрдБ ред рддрджрдиреБрд╕рд╛рд░, рд░реЗрдВрдбрд░рд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди, рд╕рд╛рджрд╛ рдкрд╛рда рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдХрд┐рд╕реА рднреА рдмрджрд▓рд╛рд╡ рдХреЗ рдмрд┐рдирд╛ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдП, рдкрд╛рда рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХреА рдЬрд╛рдПрдЧреА, рдЬрд┐рд╕реЗ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдирд┐рдпрдВрддреНрд░рдг рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдкреНрд░рддрд┐рдкрд╛рджрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдерд╛: рдЖрдкрдХреЛ рдмрд╕ рдкреЗрдбрд╝ рдХреЗ рд╕рднреА рдиреЛрдбреНрд╕ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рд╕рдм рдХреБрдЫ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ, рд╕рдм рдХреБрдЫ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ рдФрд░ рдкрд╛рда рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВред рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрдм рддрдХ рджреЛ рд╢рд░реНрддреЗрдВ рдкреВрд░реА рд╣реЛрддреА рд╣реИрдВ: рдП) рд╕рднреА рдХрд╛рдо рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ (рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ wstring) рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ; b) рдХреЗрд╡рд▓ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рднрд╛рд╡ рдФрд░ рдореВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдРрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИ рдЬреЛ рдХрд┐ inja рдФрд░ Jinja2CppLight рд▓рд╛рдЧреВ рд╣реИрдВред рдореЗрд░реЗ рдЬрд┐рдВрдЬрд╛рдХреЛрдк рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ , рджреЛрдиреЛрдВ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреА рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рд╢реБрд░реВ рдореЗрдВ рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╛рд░рджрд░реНрд╢реА рд╕рдорд░реНрдерди рджрд┐рдпрд╛ред рджреВрд╕рд░реЗ, рдкреВрд░реЗ рд╡рд┐рдХрд╛рд╕ рдХреА рд╢реБрд░реБрдЖрдд рд╕рд┐рд░реНрдл рдЬрд┐рдиреНрдЬрд╛ 2 рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдХреЛ рд▓рдЧрднрдЧ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреА рдЧрдИ рдереА, рдФрд░ рдпрд╣, рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдПрдХ рдкреВрд░реНрдг рдкрдЯрдХрдерд╛ рд╡рд╛рд▓реА рднрд╛рд╖рд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдореБрдЭреЗ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд╕рд╛рде рдЧрд╣рд░реА рдЦреБрджрд╛рдИ рдХрд░рдиреА рдкрдбрд╝реАред


рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди


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


{% set param1=10 %} {{ param1 }} 

рдЗрд╕рдХреЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдкрд╛рда 10 рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛
рд╡рд┐рдХрд▓реНрдк рдереЛрдбрд╝рд╛ рдФрд░ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ:


 {% set param1=10 %} {{ param1 }} {% for param1 in range(10) %}-{{ param1 }}-{% endfor %} {{ param1 }} 

рд░реЗрдВрдбрд░ 10-0--1--2--3--4--5--6--7--8--9-10
рдЪрдХреНрд░ рдПрдХ рдирдпрд╛ рд╕реНрдХреЛрдк рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реНрдХреЛрдк рдХреЗ рдмрд╛рд╣рд░ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрдВрдЧреЗ, рдЬреИрд╕реЗ рдХрд┐ рд╡реЗ рдмрд╛рд╣рд░реА рдПрдХ рд╣реА рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдкреАрд╕реЗрдВрдЧреЗ рдирд╣реАрдВред рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде рдкреЗрдЪреАрджрд╛ / рдмреНрд▓реЙрдХ рдирд┐рд░реНрдорд╛рдг рднреА рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрд┐рдирдЬрд╛ 2 рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЧрдгрдирд╛ рдХрд╛ рд╕рдВрджрд░реНрдн рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИред рдпрд╛ рдмрд▓реНрдХрд┐, рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рдореЗрдВ рдкреНрд░рддрд┐рдкрд╛рджрди:


 class RenderContext { public: RenderContext(const InternalValueMap& extValues, IRendererCallback* rendererCallback); InternalValueMap& EnterScope(); void ExitScope(); auto FindValue(const std::string& val, bool& found) const { for (auto p = m_scopes.rbegin(); p != m_scopes.rend(); ++ p) { auto valP = p->find(val); if (valP != p->end()) { found = true; return valP; } } auto valP = m_externalScope->find(val); if (valP != m_externalScope->end()) { found = true; return valP; } found = false; return m_externalScope->end(); } auto& GetCurrentScope() const; auto& GetCurrentScope(); auto& GetGlobalScope(); auto GetRendererCallback(); RenderContext Clone(bool includeCurrentContext) const; private: InternalValueMap* m_currentScope; const InternalValueMap* m_externalScope; std::list<InternalValueMap> m_scopes; IRendererCallback* m_rendererCallback; }; 

рдпрд╣рд╛рдБ рд╕реЗ ред


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


рдЕрдм рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ред рдмрд╛рд╣рд░реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ (рдФрд░ рдЙрд╕рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ) рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ, Jinja2 рдорд╛рдиреНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реВрдЪреА рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:


  • рд╕рдВрдЦреНрдпрд╛ (рдЗрдВрдЯ, рдбрдмрд▓)
  • рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ (рд╕рдВрдХреАрд░реНрдг, рдЪреМрдбрд╝реА)
  • bool
  • рдРрд░реЗ (рдЕрдзрд┐рдХ рдЖрдпрд╛рдорд╣реАрди рдЯреНрдпреВрдкрд▓реНрд╕ рдХреА рддрд░рд╣)
  • рд╢рдмреНрджрдХреЛрд╢реЛрдВ
  • рдкреНрд░рддрд┐рдмрд┐рдВрдмрд┐рдд C ++ рд╕рдВрд░рдЪрдирд╛рдПрдВ

рдпрд╣ рд╕рдм рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдП рдЧрдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ :: рд╕рдВрд╕реНрдХрд░рдг:


 using ValueData = boost::variant<EmptyValue, bool, std::string, std::wstring, int64_t, double, boost::recursive_wrapper<ValuesList>, boost::recursive_wrapper<ValuesMap>, GenericList, GenericMap>; class Value { public: Value() = default; template<typename T> Value(T&& val, typename std::enable_if<!std::is_same<std::decay_t<T>, Value>::value>::type* = nullptr) : m_data(std::forward<T>(val)) { } Value(const char* val) : m_data(std::string(val)) { } template<size_t N> Value(char (&val)[N]) : m_data(std::string(val)) { } Value(int val) : m_data(static_cast<int64_t>(val)) { } const ValueData& data() const {return m_data;} ValueData& data() {return m_data;} private: ValueData m_data; }; 

рдпрд╣рд╛рдБ рд╕реЗ ред


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


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

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


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


 struct StringJoiner : BaseVisitor<> { using BaseVisitor::operator (); InternalValue operator() (EmptyValue, const std::string& str) const { return str; } InternalValue operator() (const std::string& left, const std::string& right) const { return left + right; } }; 

рдпрд╣рд╛рдБ рд╕реЗ ред


рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЖрдЧрдВрддреБрдХ рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓рддрд╛ рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ:


 InternalValue delimiter = m_args["d"]->Evaluate(context); for (const InternalValue& val : values) { if (isFirst) isFirst = false; else result = Apply2<visitors::StringJoiner>(result, delimiter); result = Apply2<visitors::StringJoiner>(result, val); } 

Apply2 рдпрд╣рд╛рдБ boost::apply_visitor рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рд╣реИ boost::apply_visitor , рдЬреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдиреЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдкрд╣рд▓реЗ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдХреБрдЫ рд░реВрдкрд╛рдВрддрд░рдг рдХрд░ рд░рд╣рд╛ рд╣реИред рдпрджрд┐ рд╡рд┐рдЬрд╝рд┐рдЯрд░ рдХреЗ рдбрд┐рдЬрд╝рд╛рдЗрдирд░ рдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рд╡реЗ рдЙрди рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмрд╛рдж рдкрд╛рд░рд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдЬрд┐рди рдкрд░ рдЖрдЧрдВрддреБрдХ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ:


 comparator = [](const KeyValuePair& left, const KeyValuePair& right) { return ConvertToBool(Apply2<visitors::BinaryMathOperation>(left.value, right.value, BinaryExpression::LogicalLt, BinaryExpression::CaseSensitive)); }; 

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


рдлрд┐рд▓реНрдЯрд░ рдФрд░ рдЯреЗрд╕реНрдЯ


рдЬрд┐рдиреНрдЬрд╛ 2 рдореЗрдВ "рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп" рдХреЛ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ "рдлрд┐рд▓реНрдЯрд░" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ '' | 'рд╕рд╛рдЗрди рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдХреЗ рдорд╛рди рдкрд░ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЬрдЯрд┐рд▓ рдСрдкрд░реЗрд╢рди рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рдирдпрд╛ рдореВрд▓реНрдп рд╣реЛрдЧрд╛ред рдкрд╛рдЗрдк рд▓рд╛рдЗрди рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдХреЗ рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдлрд┐рд▓реНрдЯрд░ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ:
{{ menuItems | selectattr('visible') | map(attribute='title') | map('upper') | join(' -> ') }}
рдпрд╣рд╛рдВ, рдХреЗрд╡рд▓ рдЙрди рддрддреНрд╡реЛрдВ рдХреЛ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП рджреГрд╢реНрдпрдорд╛рди рдореЗрдиреВ рдореЗрдиреВ рд╕реЗ рдЪреБрдиреЗ рдЬрд╛рдПрдВрдЧреЗ, рдлрд┐рд░ рд╢реАрд░реНрд╖рдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдЗрди рддрддреНрд╡реЛрдВ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдКрдкрд░реА рдорд╛рдорд▓реЗ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдкрд░рд┐рдгрд╛рдореА рд╕реВрдЪреА рдХреЛ рд╡рд┐рднрд╛рдЬрдХ рдХреЗ рд╕рд╛рде рдЪрд┐рдкрдХрд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ->> рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВред рдпрд╛, рдЬреАрд╡рди рд╕реЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╣реЗрдВ:


 {% macro MethodsDecl(class, access) %} {% for method in class.methods | rejectattr('isImplicit') | selectattr('accessType', 'in', access) %} {{ method.fullPrototype }}; {% endfor %} {% endmacro %} 

рдпрд╣рд╛рдБ рд╕реЗ ред


рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд┐рдХрд▓реНрдк
 {% macro MethodsDecl(class, access) %} {{ for method in class.methods | rejectattr('isImplicit') | selectattr('accessType', 'in', access) | map(attribute='fullPrototype') | join(';\n') }}; {% endmacro %} 

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


рджрд░рдЕрд╕рд▓, рд╕рдордп рдореЗрдВ рдореБрдЦреНрдп рдЪреВрдХ рд▓рдЧрднрдЧ рдЪрд╛рд▓реАрд╕ рдлрд┐рд▓реНрдЯрд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдЬреБрдбрд╝реА рдереА, рдЬрд┐рд╕реЗ рдореИрдВрдиреЗ рдореВрд▓ рд╕реЗрдЯ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдерд╛ред рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдореБрдЭреЗ рд▓рдЧрд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рдПрдХ рдпрд╛ рджреЛ рд╕рдкреНрддрд╛рд╣ рдореЗрдВ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реВрдВред рдпрд╣ рдмрд╣реБрдд рдЖрд╢рд╛рд╡рд╛рджреА рдерд╛ред рдФрд░ рд╣рд╛рд▓рд╛рдВрдХрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ: рдПрдХ рдореВрд▓реНрдп рд▓реЗрдВ рдФрд░ рдЗрд╕рдореЗрдВ рдХреБрдЫ рдлрд╝рдВрдХреНрдЯрд░ рд▓рдЧрд╛рдУ, рдЙрдирдореЗрдВ рд╕реЗ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдереЗ, рдФрд░ рдореБрдЭреЗ рдЯрд┐рдВрдХрд░ рдХрд░рдирд╛ рдкрдбрд╝рд╛ред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рджрд┐рд▓рдЪрд╕реНрдк рдХрд╛рд░реНрдп рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рддрд░реНрдХреЛрдВ рдХрд╛ рддрд░реНрдХ рдерд╛ред рдЬрд┐рдирдЬрд╛ 2 рдореЗрдВ, рдЕрдЬрдЧрд░ рдХреЗ рд░реВрдк рдореЗрдВ, рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рджрд┐рдП рдЧрдП рддрд░реНрдХ рдпрд╛ рддреЛ рдирд╛рдо рдпрд╛ рд╕реНрдерд┐рддрд┐рдЧрдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдШреЛрд╖рдгрд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╛ рддреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рдпрд╛ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, C ++ рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╡реИрдХрд▓реНрдкрд┐рдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд┐рдЬреНрдЮрд╛рдкрди рдореЗрдВ рдХрд╣реАрдВ рднреА рд╕реНрдерд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рднрд┐рдиреНрди рдорд╛рдорд▓реЛрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдЗрди рджреЛ рд╕реВрдЪрд┐рдпреЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ рд╕рд╛рде рдЖрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдпрд╣рд╛рдБ, рдорд╛рди рд▓реЗрдВ рдХрд┐, рдПрдХ рд░реЗрдВрдЬ рдлрдВрдХреНрд╢рди рд╣реИ: range([start, ]stop[, step]) ред рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЛрдВ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


 range(10) // -> range(start = 0, stop = 10, step = 1) range(1, 10) // -> range(start = 1, stop = 10, step = 1) range(1, 10, 3) // -> range(start = 1, stop = 10, step = 3) range(step=2, 10) // -> range(start = 0, stop = 10, step = 2) range(2, step=2, 10) // -> range(start = 2, stop = 10, step = 2) 

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


рдХреЛрдб рдХрд╛ рдмрдбрд╝рд╛ рдЯреБрдХрдбрд╝рд╛
 ParsedArguments ParseCallParams(const std::initializer_list<ArgumentInfo>& args, const CallParams& params, bool& isSucceeded) { struct ArgInfo { ArgState state = NotFound; int prevNotFound = -1; int nextNotFound = -1; const ArgumentInfo* info = nullptr; }; boost::container::small_vector<ArgInfo, 8> argsInfo(args.size()); boost::container::small_vector<ParamState, 8> posParamsInfo(params.posParams.size()); isSucceeded = true; ParsedArguments result; int argIdx = 0; int firstMandatoryIdx = -1; int prevNotFound = -1; int foundKwArgs = 0; // Find all provided keyword args for (auto& argInfo : args) { argsInfo[argIdx].info = &argInfo; auto p = params.kwParams.find(argInfo.name); if (p != params.kwParams.end()) { result.args[argInfo.name] = p->second; argsInfo[argIdx].state = Keyword; ++ foundKwArgs; } else { if (argInfo.mandatory) { argsInfo[argIdx].state = NotFoundMandatory; if (firstMandatoryIdx == -1) firstMandatoryIdx = argIdx; } else { argsInfo[argIdx].state = NotFound; } if (prevNotFound != -1) argsInfo[prevNotFound].nextNotFound = argIdx; argsInfo[argIdx].prevNotFound = prevNotFound; prevNotFound = argIdx; } ++ argIdx; } int startPosArg = firstMandatoryIdx == -1 ? 0 : firstMandatoryIdx; int curPosArg = startPosArg; int eatenPosArgs = 0; // Determine the range for positional arguments scanning bool isFirstTime = true; for (; eatenPosArgs < posParamsInfo.size(); ++ eatenPosArgs) { if (isFirstTime) { for (; startPosArg < args.size() && (argsInfo[startPosArg].state == Keyword || argsInfo[startPosArg].state == Positional); ++ startPosArg) ; isFirstTime = false; continue; } int prevNotFound = argsInfo[startPosArg].prevNotFound; if (prevNotFound != -1) { startPosArg = prevNotFound; } else if (curPosArg == args.size()) { break; } else { int nextPosArg = argsInfo[curPosArg].nextNotFound; if (nextPosArg == -1) break; curPosArg = nextPosArg; } } // Map positional params to the desired arguments int curArg = startPosArg; for (int idx = 0; idx < eatenPosArgs && curArg != -1; ++ idx, curArg = argsInfo[curArg].nextNotFound) { result.args[argsInfo[curArg].info->name] = params.posParams[idx]; argsInfo[curArg].state = Positional; } // Fill default arguments (if missing) and check for mandatory for (int idx = 0; idx < argsInfo.size(); ++ idx) { auto& argInfo = argsInfo[idx]; switch (argInfo.state) { case Positional: case Keyword: continue; case NotFound: { if (!IsEmpty(argInfo.info->defaultVal)) result.args[argInfo.info->name] = std::make_shared<ConstantExpression>(argInfo.info->defaultVal); break; } case NotFoundMandatory: isSucceeded = false; break; } } // Fill the extra positional and kw-args for (auto& kw : params.kwParams) { if (result.args.find(kw.first) != result.args.end()) continue; result.extraKwArgs[kw.first] = kw.second; } for (auto idx = eatenPosArgs; idx < params.posParams.size(); ++ idx) result.extraPosArgs.push_back(params.posParams[idx]); return result; } 

рдпрд╣рд╛рдБ рд╕реЗ ред


рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬреИрд╕реЗ, рдХрд╣рддреЗ рд╣реИрдВ, range ):


 bool isArgsParsed = true; auto args = helpers::ParseCallParams({{"start"}, {"stop", true}, {"step"}}, m_params, isArgsParsed); if (!isArgsParsed) return InternalValue(); 

рдФрд░ рдирд┐рдореНрди рд╕рдВрд░рдЪрдирд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ:


 struct ParsedArguments { std::unordered_map<std::string, ExpressionEvaluatorPtr<>> args; std::unordered_map<std::string, ExpressionEvaluatorPtr<>> extraKwArgs; std::vector<ExpressionEvaluatorPtr<>> extraPosArgs; ExpressionEvaluatorPtr<> operator[](std::string name) const { auto p = args.find(name); if (p == args.end()) return ExpressionEvaluatorPtr<>(); return p->second; } }; 

рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЗрд╕реЗ рдХреЗрд╡рд▓ рдЗрд╕рдХреЗ рдирд╛рдо рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:


 auto startExpr = args["start"]; auto stopExpr = args["stop"]; auto stepExpr = args["step"]; InternalValue startVal = startExpr ? startExpr->Evaluate(values) : InternalValue(); InternalValue stopVal = stopExpr ? stopExpr->Evaluate(values) : InternalValue(); InternalValue stepVal = stepExpr ? stepExpr->Evaluate(values) : InternalValue(); 

рдореИрдХреНрд░реЛрдЬрд╝ рдФрд░ рдкрд░реАрдХреНрд╖рдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдПрдХ рд╕рдорд╛рди рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдпрджреНрдпрдкрд┐ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХреЗ рддрд░реНрдХреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рднреА рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ (рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП), рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ "рдореВрд▓" рд╕реЗрдЯ, рдЬрд┐рд╕рдореЗрдВ рд▓рдЧрднрдЧ рдкрдЪрд╛рд╕ рдФрд░ рдЕрдиреНрдп рд╢рд╛рдорд┐рд▓ рдереЗ, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣рдж рддрдХ рд╕рд╣реА рдереЗред рдФрд░ рдпрд╣ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдореЗрдВ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреА рдореБрд╢реНрдХрд┐рд▓ рдЪреАрдЬреЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдереАрдВ, рдЬреИрд╕реЗ HTML (рдпрд╛ C ++) рдХреЗ рд▓рд┐рдП рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рдирд╛, xml рдпрд╛ json рдЬреИрд╕реЗ рдкреНрд░рд╛рд░реВрдкреЛрдВ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдорд╛рди, рдФрд░ рдЗрд╕реА рддрд░рд╣ред


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


рдкрд░рдВрдкрд░рд╛рдЧрдд рд░реВрдк рд╕реЗ, рд▓рд┐рдВрдХ:


рдЬрд┐рдирдЬрд╛ 2 рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛
Jinja2Cpp рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

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


All Articles