Last active
February 11, 2019 19:53
-
-
Save fbaeuerlein/f3c32f1345a6ed16c8a95a826fdc5d72 to your computer and use it in GitHub Desktop.
adding sprintf to exprTK for number to string conversion and formatting
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <cassert> | |
#include <iostream> | |
#include "exprtk/exprtk.hpp" | |
/** | |
* @brief class containig a generic funtion for formatting numbers with snprintf | |
* | |
* Uses the igeneric_function overload for strings | |
* | |
* @tparam T parser scalar value type | |
* @tparam T type of conversion for snprintf | |
*/ | |
template <typename T, typename ConversionType = T> | |
struct formatter : public exprtk::igeneric_function<T> | |
{ | |
typedef typename exprtk::igeneric_function<T>::parameter_list_t | |
parameter_list_t; | |
typedef typename exprtk::igeneric_function<T> igenfunct_t; | |
formatter() | |
// function should take a string as first parameter and a scalar as a second one | |
: exprtk::igeneric_function<T>("ST",igenfunct_t::e_rtrn_string) | |
{ | |
} | |
inline T operator()(std::string & result, parameter_list_t parameters) | |
{ | |
typedef typename exprtk::igeneric_function<T>::generic_type generic_type; | |
typedef typename generic_type::scalar_view scalar_t; | |
typedef typename generic_type::string_view string_t; | |
assert(parameters.size() == 2); | |
// extract formatting string and value from parameters | |
string_t string(parameters[0]); | |
scalar_t scalar(parameters[1]); | |
char buffer[64]; | |
if ( snprintf(buffer, sizeof(buffer), &string[0], static_cast<ConversionType>(scalar())) < 0 ) | |
{ | |
// AN error occurred!; | |
} | |
result = buffer; // "return" string | |
return T(0); | |
} | |
}; | |
int main() | |
{ | |
typedef double T; | |
typedef exprtk::symbol_table<T> symbol_table_t; | |
typedef exprtk::expression<T> expression_t; | |
typedef exprtk::parser<T> parser_t; | |
// expression to build a string containing concatenated three numbers (padded with zeros) | |
std::string expression_string = | |
"return [fmt('%04i',x) + fmt('%04i',y) + fmt('%04i',z), 'abcd', 3];"; | |
// variable definition | |
T x = 123, y = 89, z = 3; | |
formatter<T, int> fmt; // instantiate formater with conversion of T to int | |
symbol_table_t symbol_table; | |
symbol_table.add_variable("x", x); | |
symbol_table.add_variable("y", y); | |
symbol_table.add_variable("z", z); | |
symbol_table.add_function("fmt", fmt); | |
expression_t expression; | |
expression.register_symbol_table(symbol_table); | |
// parse the expression | |
parser_t parser; | |
if (!parser.compile(expression_string,expression)) | |
{ | |
printf("Error: %s\n", parser.error().c_str()); | |
return -1; | |
} | |
// print results | |
if (expression.results().count() > 0) | |
{ | |
std::cout << "Expression return count: " << expression.results().count() << std::endl; | |
typedef exprtk::results_context<T> results_context_t; | |
typedef typename results_context_t::type_store_t type_t; | |
typedef typename type_t::scalar_view scalar_t; | |
typedef typename type_t::vector_view vector_t; | |
typedef typename type_t::string_view string_t; | |
const results_context_t &results = expression.results(); | |
for (std::size_t i = 0; i < results.count(); ++i) | |
{ | |
type_t t = results[i]; | |
// determine the right type of return values | |
switch (t.type) | |
{ | |
case type_t::e_scalar: | |
{ | |
scalar_t scalar(t); | |
std::cout << "Scalar result: " << i << " " << scalar() << std::endl; | |
} | |
break; | |
case type_t::e_vector: | |
break; | |
case type_t::e_string: | |
{ | |
string_t string(t); | |
std::cout << "String result: " << i << " " << std::string(string.begin(), string.end()) << std::endl; | |
} | |
break; | |
default: | |
std::cout << "No result there!" << std::endl; | |
break; | |
} | |
} | |
} | |
std::cout << "Finished ..." << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment