mirror of
https://github.com/red0124/ssp.git
synced 2025-01-23 04:55:20 +01:00
replace or_else_object with or_object inside the parser, update documentation
This commit is contained in:
parent
f39e1669f4
commit
60c8156fb7
66
README.md
66
README.md
@ -270,3 +270,69 @@ The shape enum will be in an example below. The **inline** is there just to prev
|
||||
multiple definition errors. The function returns **true** if the conversion was
|
||||
a success, and **false** otherwise. The function uses **const char*** begin and end
|
||||
for performance reasons.
|
||||
|
||||
## Substitute conversions
|
||||
|
||||
The parser can also be used to effectively parse files whose rows are not
|
||||
always in the same format (not a classical csv but still csv-like).
|
||||
An example would be the best way to demonstrate such a scenario.
|
||||
|
||||
Supposing we have a file containing different shapes in given formats:
|
||||
* circle radius
|
||||
* rectangle side_a side_b
|
||||
* triangle side_a side_b side_c
|
||||
|
||||
The delimiter is " ", and the number of columns varies depending on which
|
||||
shape it is. We are required to read the file and to store information
|
||||
(shape and area) of the shapes into a data structure in the same order
|
||||
as they are in the file.
|
||||
|
||||
```cpp
|
||||
ss::parser p{"shapes.txt", " "};
|
||||
if (!p.valid()) {
|
||||
std::cout << p.error_msg() << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
p.set_error_mode(ss::error_mode::error_string);
|
||||
std::vector<std::pair<shape, double>> shapes;
|
||||
|
||||
auto insert_circle = [&shapes](shape s, double r) {
|
||||
if (s != shape::circle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shapes.emplace_back(s, r * r * M_PI);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto insert_rectangle = [&shapes](shape s, double a, double b) {
|
||||
if (s != shape::rectangle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shapes.emplace_back(s, a * b);
|
||||
return true;
|
||||
};
|
||||
|
||||
auto insert_triangle = [&shapes](shape s, double a, double b, double c) {
|
||||
if (s != shape::triangle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double sh = (a + b + c) / 2;
|
||||
shapes.emplace_back(s, sqrt(sh * (sh - a) * (sh - b) * (sh - c)));
|
||||
return true;
|
||||
};
|
||||
|
||||
while (!p.eof()) {
|
||||
p.try_next<shape, double>(insert_circle)
|
||||
.or_else<shape, double, double>(insert_rectangle)
|
||||
.or_else<shape, double, double, double>(insert_triangle)
|
||||
.on_error([](const std::string& error) {
|
||||
std::cout << error << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
// do something with the stored data ...
|
||||
```
|
||||
|
@ -107,7 +107,7 @@ public:
|
||||
// same as or_else, but saves the result into a 'U' object
|
||||
// instead of a tuple
|
||||
template <typename U, typename... Us, typename Fun = none>
|
||||
composite<Ts..., std::optional<U>> or_else_object(Fun&& fun = none{}) {
|
||||
composite<Ts..., std::optional<U>> or_object(Fun&& fun = none{}) {
|
||||
std::optional<U> value;
|
||||
try_convert_and_invoke<U, Us...>(value, fun);
|
||||
return composite_with(std::move(value));
|
||||
@ -306,7 +306,7 @@ private:
|
||||
}
|
||||
|
||||
void set_error_file_not_open() {
|
||||
string_error_.append(file_name_).append(" could not be not open.");
|
||||
string_error_.append(file_name_).append(" could not be opened.");
|
||||
bool_error_ = true;
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ TEST_CASE("testing composite conversion") {
|
||||
CHECK(std::tie(i1, i2, d) == expectedData);
|
||||
})
|
||||
.on_error(fail)
|
||||
.or_else_object<test_struct, int, double, char>(fail)
|
||||
.or_object<test_struct, int, double, char>(fail)
|
||||
.on_error(fail)
|
||||
.or_else<test_tuple>(fail)
|
||||
.on_error(fail)
|
||||
@ -291,7 +291,7 @@ TEST_CASE("testing composite conversion") {
|
||||
|
||||
auto [d1, d2, d3, d4, d5] =
|
||||
p.try_next<int, int, double>(fail)
|
||||
.or_else_object<test_struct, int, double, char>()
|
||||
.or_object<test_struct, int, double, char>()
|
||||
.or_else<test_struct>(expect_test_struct)
|
||||
.or_else<test_tuple>(fail)
|
||||
.or_else<std::tuple<int, double>>(fail)
|
||||
@ -450,7 +450,7 @@ TEST_CASE("testing the moving of parsed composite values") {
|
||||
.or_else<my_string, my_string, my_string, my_string>([](auto&&) {})
|
||||
.or_else<my_string>([](auto&) {})
|
||||
.or_else<xyz>([](auto&&) {})
|
||||
.or_else_object<xyz, my_string, my_string, my_string>([](auto&&) {})
|
||||
.or_object<xyz, my_string, my_string, my_string>([](auto&&) {})
|
||||
.or_else<std::tuple<my_string, my_string, my_string>>(
|
||||
[](auto&, auto&, auto&) {});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user