@@ -14,19 +14,27 @@ namespace jinja2
1414struct EmptyValue {};
1515class Value ;
1616
17- class ReflectedMap
17+ struct ListItemAccessor
1818{
19- public:
20- struct ItemAccessor
21- {
22- virtual ~ItemAccessor () {}
23- virtual bool HasValue (const std::string& name) const = 0;
24- virtual Value GetValue (const std::string& name) const = 0;
25- virtual std::string ToString () const = 0;
26- };
19+ virtual ~ListItemAccessor () {}
2720
28- ReflectedMap () = default ;
29- ReflectedMap (std::function<const ItemAccessor* ()> accessor)
21+ virtual size_t GetSize () const = 0;
22+ virtual Value GetValueByIndex (int64_t idx) const = 0;
23+ };
24+
25+ struct MapItemAccessor : public ListItemAccessor
26+ {
27+ virtual ~MapItemAccessor () {}
28+ virtual bool HasValue (const std::string& name) const = 0;
29+ virtual Value GetValueByName (const std::string& name) const = 0;
30+ virtual std::vector<std::string> GetKeys () const = 0;
31+ };
32+
33+ class GenericMap
34+ {
35+ public:
36+ GenericMap () = default ;
37+ GenericMap (std::function<const MapItemAccessor* ()> accessor)
3038 : m_accessor(std::move(accessor))
3139 {
3240 }
@@ -36,28 +44,21 @@ class ReflectedMap
3644 return m_accessor ()->HasValue (name);
3745 }
3846
39- Value GetValue (const std::string& name) const ;
40-
41- std::string ToString () const
47+ Value GetValueByName (const std::string& name) const ;
48+ size_t GetSize () const
4249 {
43- return m_accessor ()->ToString ();
50+ return m_accessor ()->GetSize ();
4451 }
52+ Value GetValueByIndex (int64_t index) const ;
4553
46- std::function<const ItemAccessor * ()> m_accessor;
54+ std::function<const MapItemAccessor * ()> m_accessor;
4755};
4856
49- class ReflectedList
57+ class GenericList
5058{
5159public:
52- struct ItemAccessor
53- {
54- virtual ~ItemAccessor () {}
55- virtual size_t GetSize () const = 0;
56- virtual Value GetValue (size_t idx) const = 0;
57- };
58-
59- ReflectedList () = default ;
60- ReflectedList (std::function<const ItemAccessor* ()> accessor)
60+ GenericList () = default ;
61+ GenericList (std::function<const ListItemAccessor* ()> accessor)
6162 : m_accessor(std::move(accessor))
6263 {
6364 }
@@ -67,15 +68,14 @@ class ReflectedList
6768 return m_accessor ()->GetSize ();
6869 }
6970
70- Value GetValue ( int idx) const ;
71+ Value GetValueByIndex ( int64_t idx) const ;
7172
72- std::function<const ItemAccessor * ()> m_accessor;
73+ std::function<const ListItemAccessor * ()> m_accessor;
7374};
7475
7576using ValuesList = std::vector<Value>;
7677using ValuesMap = std::unordered_map<std::string, Value>;
77- class ReflectedMap ;
78- using ValueData = boost::variant<EmptyValue, bool , std::string, std::wstring, int64_t , double , boost::recursive_wrapper<ValuesList>, boost::recursive_wrapper<ValuesMap>, ReflectedMap>;
78+ using ValueData = boost::variant<EmptyValue, bool , std::string, std::wstring, int64_t , double , boost::recursive_wrapper<ValuesList>, boost::recursive_wrapper<ValuesMap>, GenericList, GenericMap>;
7979
8080class Value {
8181public:
@@ -116,7 +116,7 @@ class Value {
116116
117117 bool isList () const
118118 {
119- return boost::get<ValuesList>(&m_data) != nullptr ;
119+ return boost::get<ValuesList>(&m_data) != nullptr || boost::get<GenericList>(&m_data) != nullptr ;
120120 }
121121 auto & asList ()
122122 {
@@ -128,7 +128,7 @@ class Value {
128128 }
129129 bool isMap () const
130130 {
131- return boost::get<ValuesMap>(&m_data) != nullptr || boost::get<ReflectedMap >(&m_data) != nullptr ;
131+ return boost::get<ValuesMap>(&m_data) != nullptr || boost::get<GenericMap >(&m_data) != nullptr ;
132132 }
133133 auto & asMap ()
134134 {
@@ -149,58 +149,19 @@ class Value {
149149 ValueData m_data;
150150};
151151
152- inline Value ReflectedMap::GetValue (const std::string& name) const
152+ inline Value GenericMap::GetValueByName (const std::string& name) const
153153{
154- return m_accessor ()->GetValue (name);
154+ return m_accessor ()->GetValueByName (name);
155155}
156156
157-
158- template <typename Derived>
159- class ReflectedMapImplBase : public ReflectedMap ::ItemAccessor
160- {
161- public:
162- bool HasValue (const std::string& name) const override
163- {
164- return Derived::GetAccessors ().count (name) != 0 ;
165- }
166- Value GetValue (const std::string& name) const override
167- {
168- auto & accessors = Derived::GetAccessors ();
169- auto p = accessors.find (name);
170- if (p == accessors.end ())
171- throw std::runtime_error (" Invalid field access" );
172-
173- return static_cast <const Derived*>(this )->GetField (p->second );
174- }
175- };
176-
177- template <typename T>
178- class ReflectedMapImpl : public ReflectedMapImplBase <ReflectedMapImpl<T>>
157+ inline Value GenericMap::GetValueByIndex (int64_t index) const
179158{
180- public:
181- ReflectedMapImpl (T val) : m_value(val) {}
182- using FieldAccessor = std::function<Value (const T& value)>;
183-
184- static auto & GetAccessors ();
185- static std::string ToString (const T& value);
186- template <typename Fn>
187- Value GetField (Fn&& accessor) const
188- {
189- return accessor (m_value);
190- }
191-
192- std::string ToString () const override
193- {
194- return ToString (m_value);
195- }
196- private:
197- T m_value;
198- };
159+ return m_accessor ()->GetValueByIndex (index);
160+ }
199161
200- template <typename T>
201- Value AsReflectedMap (T&& val)
162+ inline Value GenericList::GetValueByIndex (int64_t index) const
202163{
203- return Value ( ReflectedMap ([accessor = ReflectedMapImpl<T>(std::forward<T>(val))]() -> const ReflectedMap::ItemAccessor* { return &accessor;}) );
164+ return m_accessor ()-> GetValueByIndex (index );
204165}
205166
206167} // jinja2
0 commit comments