Skip to content

Instantly share code, notes, and snippets.

@insooth
Created January 10, 2020 13:05
Show Gist options
  • Save insooth/bb79352aed5686878787194b7e77db4f to your computer and use it in GitHub Desktop.
Save insooth/bb79352aed5686878787194b7e77db4f to your computer and use it in GitHub Desktop.
Parsing and converting a string by tokens, a generic approach
// see LICENSE on insooth.github.io
// This code is a proposal to fix the issues found by me in code review.
//
// Generic approach to the following algorithm:
// given string 's', a list of tokens inside that string,
// and a way to convert data around that tokens taken from
// that string 's', execute an conversion algorithm for
// multiple tokens.
#include <iostream>
#include <tuple> // make_tuple, tuple
#include <utility> // forward, make_pair, pair
// delay expression u(static_cast<T>(x)) where x is an arg to expression (runs it)
template<class T, class U>
constexpr auto place_as(U&& u)
{
return [u = std::forward<U>(u)] (auto&& x)
{
u(static_cast<T>(std::forward<decltype(x)>(x)));
};
}
// tuple<t1, t2, ...> -> (t1, t2, ...)
template<class F, class... Ts>
constexpr bool run(F&& f, std::tuple<Ts...>&& ts)
{
return run(std::forward<F>(f), std::get<Ts>(std::forward<std::tuple<Ts...>>(ts))...);
}
template<class F, class... Ts>
constexpr bool run(F&& f, Ts&&... ts)
{
return (f(std::forward<Ts>(ts).first, std::forward<Ts>(ts).second) && ...);
}
struct A
{
int i;
char c;
};
int main()
{
const char* s = "INT CHAR BOOL"; // input
A a = { 123, 'a' }; // output: converted data
auto f = [s](const char* const h, auto f)
{
// find h in s, process rest of the string, save result as x
int x = 0; // for exposition only
f(x);
std::cout << "conversion done\n";
return true;
};
const bool r = run(f, std::make_tuple
(
std::make_pair("INT", place_as<int> ([&a](int x) { a.i = x; }))
, std::make_pair("CHAR", place_as<char>([&a](char x) { a.c = x; }))
));
std::cout << std::boolalpha << (r ? "\nsuccess" : "\nfailure" ) << '\n';
return 0;
}
/*
http://coliru.stacked-crooked.com/a/9558e397385073e4
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
conversion done
conversion done
success
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment