forked from JeffGarland/liaw2014
-
Notifications
You must be signed in to change notification settings - Fork 0
/
template_context.hpp
156 lines (127 loc) · 3.25 KB
/
template_context.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#ifndef _TEMPLATE_CONTEXT_HPP_
#define _TEMPLATE_CONTEXT_HPP_ 0x100
#include <list>
#include <map>
#include <string>
#include <vector>
#include "template_object_interface.hpp"
// Context is an example of how we could create a class that can be used by boostache
class Context;
class Context
{
// mapping of available variables
std::map<std::string, std::string> mVariables;
// mapping of available subcontext
std::map<std::string, std::vector<Context>> mSubContext;
public:
// overrides a context
void addVariable(std::string key, std::string value)
{
mVariables[key] = value;
}
void addSubContext(std::string key, std::vector<Context> value)
{
mSubContext[key] = value;
}
bool hasVariable(std::string key) const
{
return mVariables.find(key) != mVariables.end();
}
// NOTE! Should this just return ""?
std::string getVariable(std::string key) const
{
auto v = mVariables.find(key);
if (v == mVariables.end())
throw std::runtime_error("variable not found");
return v->second;
}
bool hasSubContext(std::string key) const
{
auto v = mSubContext.find(key);
return (v != mSubContext.end());
}
std::pair<std::vector<Context>::const_iterator, std::vector<Context>::const_iterator>
getSubContext(std::string key) const
{
auto v = mSubContext.find(key);
if (v == mSubContext.end())
throw std::runtime_error("variable not found");
return { v->second.begin(), v->second.end() };
}
};
struct Context_list_iterator_t;
struct Context_list_t
{
Context_list_t(const Context& c) { mData.push_front(c); }
std::list<Context> mData;
typedef Context_list_iterator_t Iterator;
};
struct Context_list_iterator_t
{
Context_list_iterator_t(std::vector<Context>::const_iterator i, const Context_list_t& p) : iter(i), parent_context(p) {}
bool operator==(const Context_list_iterator_t& rhs) const
{
return iter == rhs.iter;
}
bool operator!=(const Context_list_iterator_t& rhs) const
{
return iter != rhs.iter;
}
Context_list_iterator_t& operator++()
{
++iter;
return *this;
}
Context_list_t operator*() const
{
auto result = parent_context;
result.mData.push_front(*iter);
return result;
}
std::vector<Context>::const_iterator iter;
const Context_list_t& parent_context;
};
// NOTE! putting this in the other namespace?
namespace template_engine {
template<>
std::pair<Context_list_iterator_t, Context_list_iterator_t> GetRange<Context_list_t>(const Context_list_t& data, const std::string& key)
{
for (const auto& i : data.mData)
{
if (i.hasSubContext(key))
{
auto result = i.getSubContext(key);
typename Context_list_t::Iterator begin(result.first, data);
typename Context_list_t::Iterator end(result.second, data);
return { begin, end };
}
}
throw std::runtime_error("section not found");
}
template <>
void Render<Context_list_t>(const Context_list_t& data, std::ostream& os, const std::string& key)
{
for (const auto& i : data.mData)
{
if (i.hasVariable(key))
{
os<<i.getVariable(key);
return;
}
}
return ;
}
template <>
bool HasKey<Context_list_t>(const Context_list_t& data, const std::string& key)
{
for (const auto& i : data.mData)
{
if (i.hasVariable(key) || i.hasSubContext(key))
{
return true;
}
}
return false;
}
} // namespace template_engine
#endif // _TEMPLATE_CONTEXT_HPP_