Skip to content

Instantly share code, notes, and snippets.

@lholden
Last active December 18, 2015 01:29
Show Gist options
  • Save lholden/5704040 to your computer and use it in GitHub Desktop.
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)
#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