Skip to content

Instantly share code, notes, and snippets.

@leopoldcambier
Created April 3, 2020 18:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leopoldcambier/31fdb4308c22dd18775f64a740ac35ba to your computer and use it in GitHub Desktop.
Save leopoldcambier/31fdb4308c22dd18775f64a740ac35ba to your computer and use it in GitHub Desktop.
Chaining functions using C++ template
#include<tuple>
#include<iostream>
#include<string>
template<typename Tin, typename Tout>
struct transformer {
Tout transform(Tin tin) {
std::cout << "Hi!\n";
return tin + 1;
}
using Tin_type = Tin;
using Tout_type = Tout;
};
// Returns the Tin of the first element
template<typename... Trs>
struct Tin_list
{
using type = typename std::tuple_element<0, std::tuple<Trs...>>::type::Tin_type;
};
// Returns the Tout of the last element
template<typename... Trs>
struct Tout_list
{
using type = typename std::tuple_element<sizeof...(Trs)-1, std::tuple<Trs...>>::type::Tout_type;
};
// Base case; only one transformator
template<typename Tr>
typename Tr::Tout_type chain_transform(typename Tr::Tin_type tin, Tr transformer)
{
return transformer.transform(tin);
}
// Recursive case
// enable_if will enable this function if Trs... has only one element. Otherwise it will call the above base case
template<typename Tr, typename... Trs>
typename std::enable_if<(sizeof...(Trs) > 0), typename Tout_list<Tr,Trs...>::type>::type
chain_transform(typename Tin_list<Tr,Trs...>::type tin, Tr transformer, Trs... transformers)
{
auto out = transformer.transform(tin);
return chain_transform(out, transformers...);
}
struct transformer_0 {
std::string transform(int i) {
return "coucou" + std::to_string(i);
}
using Tin_type = int;
using Tout_type = std::string;
};
struct transformer_1 {
double transform(std::string s) {
return (double) s.size();
}
using Tin_type = std::string;
using Tout_type = double;
};
struct transformer_2 {
size_t transform(double v) {
return (size_t)v + 123;
}
using Tin_type = double;
using Tout_type = size_t;
};
int main() {
auto t0 = transformer_0();
auto t1 = transformer_1();
auto t2 = transformer_2();
std::cout << chain_transform(145, t0, t1, t2) << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment