CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
structured_data.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Classes for representing generic structured data
4
5Author: Thomas Kiley
6
7\*******************************************************************/
8
9#include "structured_data.h"
10#include "range.h"
11#include "string_utils.h"
12#include <algorithm>
13
14labelt::labelt(std::vector<std::string> components) : components(components)
15{
16 PRECONDITION(!components.empty());
17 PRECONDITION(std::all_of(
18 components.begin(), components.end(), [](const std::string &component) {
19 return !component.empty() &&
20 std::none_of(component.begin(), component.end(), ::isupper);
21 }));
22}
23
24std::string labelt::camel_case() const
25{
26 std::ostringstream output;
27 output << *components.begin();
29 output, std::next(components.begin()), components.end(), "", capitalize);
30 return output.str();
31}
32
33std::string labelt::snake_case() const
34{
35 std::ostringstream output;
36 join_strings(output, components.begin(), components.end(), '_');
37 return output.str();
38}
39
40std::string labelt::kebab_case() const
41{
42 std::ostringstream output;
43 join_strings(output, components.begin(), components.end(), '-');
44 return output.str();
45}
46
47std::string labelt::pretty() const
48{
49 std::ostringstream output;
50 const auto range =
51 make_range(components.begin(), std::next(components.begin()))
52 .map(capitalize)
53 .concat(make_range(std::next(components.begin()), components.end()));
54
55 join_strings(output, range.begin(), range.end(), ' ');
56 return output.str();
57}
58
59bool labelt::operator<(const labelt &other) const
60{
61 return components < other.components;
62}
63
65{
66 // Structured data (e.g. arrays and objects) should use an entry
69}
70
72structured_data_entryt::entry(std::map<labelt, structured_data_entryt> children)
73{
74 return structured_data_entryt(std::move(children));
75}
76
78 : data(std::move(data))
79{
80}
81
83 std::map<labelt, structured_data_entryt> children)
84 : _children(std::move(children))
85{
86}
87
89{
90 return _children.empty();
91}
92
94{
95 return data.value;
96}
97const std::map<labelt, structured_data_entryt> &
99{
100 return _children;
101}
102
104{
105 return data;
106}
107
109 std::map<labelt, structured_data_entryt> data)
110 : _data(std::move(data))
111{
112}
113
114std::vector<std::string>
115pretty_node(const std::pair<labelt, structured_data_entryt> &entry)
116{
117 const labelt &label = entry.first;
118 const structured_data_entryt &data = entry.second;
119 if(data.is_leaf())
120 {
121 std::ostringstream line;
122 line << label.pretty() << ": " << data.leaf_data();
123 return {line.str()};
124 }
125 else
126 {
127 const auto indent = [](const std::string &line) { return "\t" + line; };
128
129 const auto &children = data.children();
130 std::vector<std::vector<std::string>> lines =
131 make_range(children)
132 .map(pretty_node)
133 .map([&](std::vector<std::string> sub_lines) {
134 return make_range(sub_lines)
135 .map(indent)
136 .collect<std::vector<std::string>>();
137 })
138 .collect<std::vector<std::vector<std::string>>>();
139
140 std::vector<std::string> result;
141 for(const auto &sub_lines : lines)
142 {
143 result.insert(result.end(), sub_lines.begin(), sub_lines.end());
144 }
145 return result;
146 }
147}
148
149std::string to_pretty(const structured_datat &data)
150{
151 if(data.data().empty())
152 return "";
153
154 std::vector<std::vector<std::string>> lines =
155 make_range(data.data())
156 .map(pretty_node)
157 .collect<std::vector<std::vector<std::string>>>();
158 std::vector<std::string> flattened_lines;
159 for(const auto &line_section : lines)
160 {
161 flattened_lines.insert(
162 flattened_lines.end(), line_section.begin(), line_section.end());
163 }
164 std::ostringstream output;
165 join_strings(output, flattened_lines.begin(), flattened_lines.end(), "\n");
166 return output.str();
167}
168
169const std::map<labelt, structured_data_entryt> &structured_datat::data() const
170{
171 return _data;
172}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Definition json.h:27
bool is_array() const
Definition json.h:61
std::string value
Definition json.h:132
bool is_object() const
Definition json.h:56
A way of representing nested key/value data.
const std::map< labelt, structured_data_entryt > & data() const
structured_datat(std::map< labelt, structured_data_entryt > data)
std::map< labelt, structured_data_entryt > _data
STL namespace.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< iteratort > make_range(iteratort begin, iteratort end)
Definition range.h:522
#define PRECONDITION(CONDITION)
Definition invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:97
std::string capitalize(const std::string &str)
Stream & join_strings(Stream &&os, const It b, const It e, const Delimiter &delimiter, TransformFunc &&transform_func)
Prints items to an stream, separated by a constant delimiter.
std::string camel_case() const
labelt(std::vector< std::string > components)
std::string kebab_case() const
std::vector< std::string > components
std::string snake_case() const
std::string pretty() const
bool operator<(const labelt &other) const
static structured_data_entryt data_node(const jsont &data)
std::string leaf_data() const
std::map< labelt, structured_data_entryt > _children
const std::map< labelt, structured_data_entryt > & children() const
static structured_data_entryt entry(std::map< labelt, structured_data_entryt > children)
std::vector< std::string > pretty_node(const std::pair< labelt, structured_data_entryt > &entry)
std::string to_pretty(const structured_datat &data)
Convert the structured_data into plain text.