Skip to content

Commit faedda1

Browse files
committed
Implement '~' operator
1 parent 3a593f5 commit faedda1

File tree

5 files changed

+47
-60
lines changed

5 files changed

+47
-60
lines changed

src/expression_evaluator.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,25 @@ InternalValue BinaryExpression::Evaluate(RenderContext& context)
9292
break;
9393
}
9494
case jinja2::BinaryExpression::StringConcat:
95+
{
96+
auto leftStr = context.GetRendererCallback()->GetAsTargetString(leftVal);
97+
auto rightStr = context.GetRendererCallback()->GetAsTargetString(rightVal);
98+
TargetString resultStr;
99+
std::string* nleftStr = boost::get<std::string>(&leftStr);
100+
if (nleftStr != nullptr)
101+
{
102+
auto* nrightStr = boost::get<std::string>(&rightStr);
103+
resultStr = *nleftStr + *nrightStr;
104+
}
105+
else
106+
{
107+
auto* wleftStr = boost::get<std::wstring>(&leftStr);
108+
auto* wrightStr = boost::get<std::wstring>(&rightStr);
109+
resultStr = *wleftStr + *wrightStr;
110+
}
111+
result = InternalValue(std::move(resultStr));
112+
break;
113+
}
95114
default:
96115
break;
97116
}

src/render_context.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@
77

88
namespace jinja2
99
{
10+
struct IRendererCallback
11+
{
12+
virtual TargetString GetAsTargetString(const InternalValue& val) = 0;
13+
};
14+
1015
class RenderContext
1116
{
1217
public:
13-
RenderContext(const InternalValueMap& extValues)
18+
RenderContext(const InternalValueMap& extValues, IRendererCallback* rendererCallback)
19+
: m_rendererCallback(rendererCallback)
1420
{
1521
m_externalScope = &extValues;
1622
EnterScope();
@@ -63,10 +69,15 @@ class RenderContext
6369
{
6470
return *m_currentScope;
6571
}
72+
auto GetRendererCallback()
73+
{
74+
return m_rendererCallback;
75+
}
6676
private:
6777
InternalValueMap* m_currentScope;
6878
const InternalValueMap* m_externalScope;
6979
std::list<InternalValueMap> m_scopes;
80+
IRendererCallback* m_rendererCallback;
7081

7182
};
7283
} // jinja2

src/template_impl.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class TemplateImpl : public ITemplateImpl
5555
else
5656
intParams[ip.first] = newParam.get();
5757
}
58-
RenderContext context(intParams);
58+
RendererCallback<CharT> callback;
59+
RenderContext context(intParams, &callback);
5960
OutStream outStream(
6061
[this, &os](size_t offset, size_t length) {
6162
os.write(m_template.data() + offset, length);
@@ -68,6 +69,18 @@ class TemplateImpl : public ITemplateImpl
6869
}
6970
}
7071

72+
template<typename CharT>
73+
class RendererCallback : public IRendererCallback
74+
{
75+
public:
76+
TargetString GetAsTargetString(const InternalValue& val) override
77+
{
78+
std::basic_ostringstream<CharT> os;
79+
Apply<visitors::ValueRenderer<CharT>>(val, os);
80+
return TargetString(os.str());
81+
}
82+
};
83+
7184
private:
7285

7386
std::basic_string<CharT> m_template;

src/value_visitors.h

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -96,64 +96,6 @@ struct BaseVisitor : public boost::static_visitor<R>
9696
{
9797
return R();
9898
}
99-
#if 0
100-
template<typename U>
101-
R operator() (const GenericMap&, U&&) const
102-
{
103-
assert(false);
104-
return R();
105-
}
106-
107-
template<typename U>
108-
R operator() (const GenericList&, U&&) const
109-
{
110-
assert(false);
111-
return R();
112-
}
113-
114-
template<typename U>
115-
R operator() (const ValueRef&, U&&) const
116-
{
117-
assert(false);
118-
return R();
119-
}
120-
121-
template<typename U>
122-
R operator() (const TargetString&, U&&) const
123-
{
124-
assert(false);
125-
return R();
126-
}
127-
128-
template<typename T>
129-
R operator() (T&&, const GenericMap&) const
130-
{
131-
assert(false);
132-
return R();
133-
}
134-
135-
template<typename T>
136-
R operator() (T&&, const GenericList&) const
137-
{
138-
assert(false);
139-
return R();
140-
}
141-
142-
template<typename T>
143-
R operator() (T&&, const ValueRef&) const
144-
{
145-
assert(false);
146-
return R();
147-
}
148-
149-
template<typename T>
150-
R operator() (T&&, const TargetString&) const
151-
{
152-
assert(false);
153-
return R();
154-
}
155-
#endif
156-
15799
};
158100

159101

test/expressions_test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TEST(ExpressionsTest, BinaryMathOperations)
2323
{{ 10 ** -2 }}
2424
{{ 10/10 + 2*5 }}
2525
{{ 'Hello' + " " + 'World ' + stringValue }}
26+
{{ 'Hello' ~ " " ~ 123 ~ ' ' ~ 1.234 ~ " " ~ true ~ " " ~ intValue ~ " " ~ false ~ ' ' ~ 'World ' ~ stringValue }}
2627
)";
2728

2829
Template tpl;
@@ -51,6 +52,7 @@ TEST(ExpressionsTest, BinaryMathOperations)
5152
0.01
5253
11
5354
Hello World rain
55+
Hello 123 1.234 true 3 false World rain
5456
)";
5557

5658
EXPECT_STREQ(expectedResult.c_str(), result.c_str());

0 commit comments

Comments
 (0)