Skip to content

Instantly share code, notes, and snippets.

@splinterofchaos
Created February 17, 2015 18:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save splinterofchaos/e867c65e3ed5fe1b41da to your computer and use it in GitHub Desktop.
Save splinterofchaos/e867c65e3ed5fe1b41da to your computer and use it in GitHub Desktop.
Projection
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <vector>
#include <fu/fu.h>
struct Person {
std::string name;
std::string birth_place;
int year_of_birth;
int year_of_death;
int age() const { return year_of_death - year_of_birth; }
};
int main() {
using namespace fu;
std::vector<Person> people =
{ {"Frédéric Chopin", "Poland", 1810, 1849}
, {"Wolfgang Amadeus Mozart", "Austria", 1756, 1791}
, {"Ludwig van Beethoven", "Germany", 1770, 1827}
, {"Franz Liszt", "Hungary", 1811, 1886}
};
std::sort(std::begin(people), std::end(people),
[](auto& a, auto& b) {
return a.year_of_birth < b.year_of_birth;
});
assert(people.front().year_of_birth == 1756);
std::sort(std::begin(people), std::end(people),
fu::proj_less(&Person::year_of_birth));
assert(people.front().year_of_birth == 1756 && "did not change");
using namespace std::placeholders;
std::sort(std::begin(people), std::end(people),
std::bind(std::less<>{},
std::bind(&Person::year_of_birth, _1),
std::bind(&Person::year_of_birth, _2)));
assert(people.front().year_of_birth == 1756 && "did not change");
auto acc = [](int accum, const Person& p) { return accum + p.age(); };
int sum =
std::accumulate(std::begin(people), std::end(people),
0, fu::rproj(std::plus<>{}, &Person::age));
float ave = float(sum) / people.size();
std::cout << "Average age: " << ave << std::endl;
bool ok =
std::equal(std::begin(people), std::end(people),
std::begin(people),
[](Person& a, Person& b) {
return a.year_of_birth < b.year_of_death;
});
assert(ok);
ok =
std::equal(std::begin(people), std::end(people),
std::begin(people),
fu::join(std::less<>{}, &Person::year_of_birth,
&Person::year_of_death));
assert(ok);
ok = std::all_of(std::begin(people), std::end(people),
fu::split(std::less<>{}, &Person::year_of_birth,
&Person::year_of_death));
assert(ok);
std::vector<Person> germans;
std::copy_if(std::begin(people), std::end(people),
std::back_inserter(germans),
[](auto& p) { return p.birth_place == "Germany"; });
assert(germans.size() == 1);
germans.clear();
std::copy_if(std::begin(people), std::end(people),
std::back_inserter(germans),
proj(eq("Germany"), &Person::birth_place));
assert(germans.size() == 1);
size_t size = std::accumulate(std::begin(people), std::end(people),
0,
[](size_t sum, const Person& p) {
return sum + p.name.size();
});
std::string names;
names.reserve(size + people.size() * 2);
std::for_each(std::begin(people), std::end(people),
[&](const Person& p) { names.append(p.name);
names.append(", "); });
auto name_len = proj(&std::string::size, &Person::name);
size_t sizE = std::accumulate(std::begin(people), std::end(people),
0,
rproj(std::plus<>{}, name_len));
std::string names2;
names2.reserve(sizE + people.size() * 2);
auto append = [&](const std::string& n) { names2.append(n);
names2.append(", "); };
std::for_each(std::begin(people), std::end(people),
proj(append, &Person::name));
std::cout << "All names: " << names << std::endl;
assert(names == names2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment