Last active
December 18, 2015 01:29
-
-
Save lholden/5704040 to your computer and use it in GitHub Desktop.
A slightly more "functional" looking API around the c++11 algorithm library. (mostly just mucking around)
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 <iostream> | |
#include <algorithm> | |
#include <vector> | |
#include <cctype> | |
#include "optional.hpp" | |
// c++14 optional<T> for c++11. | |
// https://github.com/akrzemi1/Optional | |
namespace tr2 = std::experimental; | |
namespace loriholden { | |
namespace functional { | |
template <class C, typename F> | |
auto find(C& container, const F& function) -> tr2::optional<decltype(container[0])> const | |
{ | |
const auto& elem = std::find_if( | |
std::begin(container), | |
std::end(container), | |
function | |
); | |
tr2::optional<decltype(container[0])> result; | |
if (elem != std::end(container)) result.emplace(*elem); | |
return result; | |
}; | |
template <class C, typename F> | |
auto filter(C container, const F& function) -> C const | |
{ | |
using FWrap = std::function<bool(decltype(container[0]))>; | |
container.erase( | |
std::remove_if( | |
std::begin(container), | |
std::end(container), | |
std::not1(FWrap(function)) | |
), | |
std::end(container) | |
); | |
return container; | |
} | |
template <class C, typename I, typename F> | |
auto foldl(const C& container, const I& initial, const F& function) -> I const | |
{ | |
return std::accumulate( | |
std::begin(container), | |
std::end(container), | |
initial, | |
function | |
); | |
} | |
template <class C, typename I, typename F> | |
auto foldr(const C& container, const I& initial, const F& function) -> I const | |
{ | |
using It = decltype(std::begin(container)); | |
using ReverseIt = std::reverse_iterator<It>; | |
return std::accumulate( | |
ReverseIt(std::end(container)), | |
ReverseIt(std::begin(container)), | |
initial, | |
function | |
); | |
} | |
template <class C, typename F> | |
auto map(C container, const F& function) -> C const | |
{ | |
std::transform( | |
std::begin(container), | |
std::end(container), | |
std::begin(container), | |
function | |
); | |
return container; | |
} | |
/* | |
auto main() -> int { | |
namespace fun = loriholden::functional; | |
const std::vector<std::string> stuff{"one", "two", "three"}; | |
auto result1 = fun::find(stuff, [](const std::string& s) {return s == "two";}); | |
if (result1) { | |
std::cout << "my: " << result1.value() << std::endl; | |
} | |
else { | |
std::cout << "Did not find it" << std::endl; | |
} | |
// output: my: two | |
const std::vector<int> numbers{1, 2, 3, 4, 5, 6, 7, 8, 9}; | |
auto result2 = fun::filter(numbers, [](const int& i){return i < 6;}); | |
for (const auto& n: result2) std::cout << n << " "; | |
std::cout << " size: " << result2.size() << std::endl; | |
// output: 1 2 3 4 5 size: 5 | |
auto result3 = fun::foldl(numbers, 10, [](const int& a, const int& i){return a+i;}); | |
std::cout << "result: " << result3 << std::endl; | |
// output: result: 55 | |
auto result4 = fun::foldr(numbers, std::vector<int>{}, [](std::vector<int>& a, int i) { | |
a.push_back(i); | |
return std::move(a); | |
}); | |
for (const auto& n: result4) std::cout << n << " "; | |
std::cout << std::endl; | |
// output: 9 8 7 6 5 4 3 2 1 | |
const std::string hi{"Hello World"}; | |
auto result5 = fun::map(hi, std::ptr_fun<int, int>(std::toupper)); | |
std::cout << result5 << std::endl; | |
// output: HELLO WORLD | |
return 0; | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment