Since lambdas are objects, just return them via a function that takes col as a parameter. If you want it to be compile time, use metaprogramming with templates. Not sure if constexpr works in this case, but I may be wrong.
namespace date { struct day_point { int value; }; }
# include <functional>
template <typename T>
using predicate = std::function<bool(T const&)>;
# include <boost/fusion/algorithm/query/find.hpp>
# include <boost/fusion/include/find.hpp>
# include <boost/fusion/include/map.hpp>
# include <boost/fusion/include/pair.hpp>
# include <boost/fusion/include/sequence.hpp>
# include <boost/fusion/include/vector.hpp>
namespace fsn = boost::fusion;
# include <algorithm>
# include <random>
# include <vector>
class ProcessingObject {
public:
template <typename FilterBy>
void filter_out() {
auto lambda = filter_at<FilterBy>();
auto& column = get_column<FilterBy>();
column.erase(std::remove_if
(column.begin(), column.end(), lambda),
column.end());
}
template <typename T>
std::vector<T>& get_column() {
auto res = fsn::find<std::vector<T>>(columns);
if (res == fsn::end(columns)) {
/* No matching column */
}
return *fsn::find<std::vector<T>>(columns);
}
template <typename FilterBy>
auto& filter_at() {
return fsn::at_key<FilterBy>(filter_map);
}
private:
fsn::map<fsn::pair<date::day_point, predicate<date::day_point>>,
fsn::pair<std::string, predicate<std::string>>>
filter_map {};
fsn::vector<std::vector<date::day_point>,
std::vector<std::string>> columns;
};
# include <iostream>
# include <random>
int main (int, char **) {
auto obj = ProcessingObject{};
/* Fill some columns. */
auto &strings = obj.get_column<std::string>();
auto &days = obj.get_column<date::day_point>();
strings.emplace_back("whatever");
strings.emplace_back("blah");
strings.emplace_back("foobar");
for (auto i = 0; i < 10; ++i)
days.emplace_back(date::day_point{i});
/* Set up some filter functions for each associated column */
auto day_point_filter = [](auto day){ return day.value < 7; };
auto str_filter = [](auto str){ return str.size() > 4; };
obj.filter_at <std::string>() = str_filter;
obj.filter_at <date::day_point>() = day_point_filter;
/* Display the contents of some columns */
for (auto elt: obj.get_column<std::string>())
std::cout << elt << "\n";
for (auto elt: obj.get_column<date::day_point>())
std::cout << elt.value << "\n";
std::cout << "Filtering out things according to our lambdas" << "\n";
/* Filter according to the lambda associated with each type. */
obj.filter_out<std::string>();
obj.filter_out<date::day_point>();
for (auto elt: obj.get_column<std::string>())
std::cout << elt << "\n";
for (auto elt: obj.get_column<date::day_point>())
std::cout << elt.value << "\n";
}