mirror of
				https://github.com/red0124/ssp.git
				synced 2025-10-31 05:06:46 +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   | multiple definition errors. The function returns **true** if the conversion was   | ||||||
| a success, and **false** otherwise. The function uses **const char*** begin and end   | a success, and **false** otherwise. The function uses **const char*** begin and end   | ||||||
| for performance reasons. | 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
 |         // same as or_else, but saves the result into a 'U' object
 | ||||||
|         // instead of a tuple
 |         // instead of a tuple
 | ||||||
|         template <typename U, typename... Us, typename Fun = none> |         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; |             std::optional<U> value; | ||||||
|             try_convert_and_invoke<U, Us...>(value, fun); |             try_convert_and_invoke<U, Us...>(value, fun); | ||||||
|             return composite_with(std::move(value)); |             return composite_with(std::move(value)); | ||||||
| @ -306,7 +306,7 @@ private: | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void set_error_file_not_open() { |     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; |         bool_error_ = true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -223,7 +223,7 @@ TEST_CASE("testing composite conversion") { | |||||||
|                  CHECK(std::tie(i1, i2, d) == expectedData); |                  CHECK(std::tie(i1, i2, d) == expectedData); | ||||||
|              }) |              }) | ||||||
|                 .on_error(fail) |                 .on_error(fail) | ||||||
|                 .or_else_object<test_struct, int, double, char>(fail) |                 .or_object<test_struct, int, double, char>(fail) | ||||||
|                 .on_error(fail) |                 .on_error(fail) | ||||||
|                 .or_else<test_tuple>(fail) |                 .or_else<test_tuple>(fail) | ||||||
|                 .on_error(fail) |                 .on_error(fail) | ||||||
| @ -291,7 +291,7 @@ TEST_CASE("testing composite conversion") { | |||||||
| 
 | 
 | ||||||
|         auto [d1, d2, d3, d4, d5] = |         auto [d1, d2, d3, d4, d5] = | ||||||
|             p.try_next<int, int, double>(fail) |             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_struct>(expect_test_struct) | ||||||
|                 .or_else<test_tuple>(fail) |                 .or_else<test_tuple>(fail) | ||||||
|                 .or_else<std::tuple<int, double>>(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, my_string, my_string, my_string>([](auto&&) {}) | ||||||
|         .or_else<my_string>([](auto&) {}) |         .or_else<my_string>([](auto&) {}) | ||||||
|         .or_else<xyz>([](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>>( |         .or_else<std::tuple<my_string, my_string, my_string>>( | ||||||
|             [](auto&, auto&, auto&) {}); |             [](auto&, auto&, auto&) {}); | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user