#ifndef FUNCTIONAL_H #define FUNCTIONAL_H #include #include #include /* * Composition of functions through operator* * * Immediate evaluation of * */ template auto composition_h(F&& f, G&& g, std::true_type) { #if DEBUG==1 std::cout << " * -> " << std::endl; // DEBLURG #endif return [f, g](auto&& t){ return f( g( std::forward(t) ) ); }; } template auto composition_h(F&& f, G&& g, std::false_type) { #if DEBUG==1 std::cout << " * T -> T" << std::endl; // DEBLURG #endif return f( g ); } template auto operator*(F&& f, G&& g) { #if DEBUG==1 std::cout << "f * g -> "; #endif return composition_h(f, g, std::is_lvalue_reference()); } /* * Following templates handle mapping of transforming function * onto vector types */ template auto operator*(Transform&& transform, std::vector const& vec) { #if DEBUG==1 std::cout << " * vec -> vec \t[const]" << std::endl; // DEBLURG #endif std::vector transformed_vec; transformed_vec.reserve( vec.size() ); for (auto const& v : vec) { transformed_vec.push_back( transform(v) ); } return transformed_vec; } template auto operator*(Transform&& transform, std::vector&& vec) { #if DEBUG==1 std::cout << " * vec -> vec \t[rvalue]" << std::endl; // DEBLURG #endif std::vector transformed_vec; transformed_vec.reserve( vec.size() ); for (auto const& v : vec) { transformed_vec.push_back( transform(v) ); } return transformed_vec; } template auto operator*(Transform&& transform, std::vector& vec) { #if DEBUG==1 std::cout << " * vec -> vec \t[non-const]" << std::endl; #endif std::vector transformed_vec; transformed_vec.reserve( vec.size() ); for (auto const& v : vec) { transformed_vec.push_back( transform(v) ); } return transformed_vec; } auto const id = [](auto&& t) -> decltype(t)&& { return std::forward(t); }; /* * Maps a transform function onto each element in vector * * Obsolete */ template auto map = [](F&& transform) { return [transform](std::vector const& vec) { std::vector transformed_vec; transformed_vec.reserve( vec.size() ); for (auto const& v : vec) { transformed_vec.push_back( transform(v) ); } return transformed_vec; }; }; #endif