Created
January 8, 2014 22:43
-
-
Save reuk/8325948 to your computer and use it in GitHub Desktop.
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
// | |
// main.cpp | |
// functional | |
// | |
// Created by Reuben Thomas on 08/01/2014. | |
// Copyright (c) 2014 Reuben Thomas. All rights reserved. | |
// | |
#include <iostream> | |
#include <vector> | |
#include <functional> | |
#include <algorithm> | |
#include <numeric> | |
// basic functional patterns | |
template <typename T, typename U, typename FuncType> | |
T map (const U & u, const FuncType & f) | |
{ | |
T ret (u.size()); | |
std::transform (u.begin(), u.end(), ret.begin(), f); | |
return ret; | |
} | |
template <typename U, typename FuncType> | |
U filter (const U & u, const FuncType & f) | |
{ | |
U ret; | |
std::remove_copy_if | |
( u.begin() | |
, u.end() | |
, std::back_inserter (ret) | |
, std::not1 (f) | |
); | |
return ret; | |
} | |
template <typename T, typename U, typename FuncType> | |
T reduce (const U & u, const T & t, const FuncType & f) | |
{ | |
return std::accumulate (u.begin(), u.end(), t, f); | |
} | |
// functors for working with std::pairs | |
template <typename T, typename U> | |
struct getFirst: public std::unary_function<std::pair<T, U>, T> | |
{ | |
T operator() (const std::pair<T, U> & p) const {return p.first;} | |
}; | |
template <typename T, typename U> | |
struct getSecond: public std::unary_function<std::pair<T, U>, U> | |
{ | |
U operator() (const std::pair<T, U> & p) const {return p.second;} | |
}; | |
// function composition! | |
template <typename T, typename U> | |
struct composer: public std::unary_function<typename T::argument_type, typename U::result_type> | |
{ | |
protected: | |
T t; | |
U u; | |
public: | |
explicit composer (const T & t, const U & u): t (t), u (u) {} | |
typename U::result_type operator() (const typename T::argument_type & arg) const | |
{ | |
return u (t (arg)); | |
} | |
}; | |
template <typename T, typename U> | |
composer<T, U> compose (const T & t, const U & u) | |
{ | |
return composer<T, U> (t, u); | |
} | |
// output functor | |
template <typename T> | |
struct printer: public std::unary_function<T, void> | |
{ | |
void operator() (const T & t) const {std::cout << t << " ";} | |
}; | |
// let's try it all out... | |
int main(int argc, const char * argv[]) | |
{ | |
std::vector<std::pair<double, double> > v; | |
v.push_back (std::pair<double, double> (0.1, 7)); | |
v.push_back (std::pair<double, double> (-2, 5.29)); | |
v.push_back (std::pair<double, double> (1, 0)); | |
v.push_back (std::pair<double, double> (500, -7.1)); | |
std::vector<double> l = map<std::vector<double> > | |
( v | |
, compose (getFirst<double, double>(), std::bind1st (std::plus<double>(), 2.0)) | |
); | |
std::for_each (l.begin(), l.end(), printer<double>()); | |
std::cout << std::endl; | |
std::vector<std::pair<double, double> > d = filter | |
( v | |
, compose (getFirst<double, double>(), std::bind2nd (std::greater_equal<double>(), 0.0)) | |
); | |
std::for_each (d.begin(), d.end(), compose (getFirst<double, double>(), printer<double>())); | |
std::cout << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment