Skip to content

Instantly share code, notes, and snippets.

@cjameshuff
Last active November 14, 2015 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjameshuff/01a4472e5504bcba49a3 to your computer and use it in GitHub Desktop.
Save cjameshuff/01a4472e5504bcba49a3 to your computer and use it in GitHub Desktop.
Fun with lambdas
#include <cstdlib>
#include <iostream>
#include "boost/format.hpp"
using boost::format;
namespace iter {
template<typename T, int increment = 1>
class integer {
public:
using value_type = T;
private:
value_type val;
public:
integer(value_type v = 0): val{v} {}
integer(const integer & rhs) = default;
auto operator++() -> integer & {val += increment; return *this;}
auto operator*() const -> value_type {return val;}
auto operator==(const integer & rhs) const -> bool {return val == rhs.val;}
auto operator!=(const integer & rhs) const -> bool {return val != rhs.val;}
};
template<typename T>
class indexed {
public:
struct value_type {
decltype(*(T())) value;
int index;
};
private:
T val;
int idx;
public:
indexed() {}
indexed(T v, int i = 0): val{v}, idx{i} {}
indexed(const indexed & rhs) = default;
auto operator++() -> indexed & {++val; ++idx; return *this;}
auto operator*() const -> value_type {return {*val, idx};}
auto operator==(const indexed & rhs) const -> bool {return val == rhs.val;}
auto operator!=(const indexed & rhs) const -> bool {return val != rhs.val;}
};
template<typename T, typename FnT, typename RetT>
class mapping {
public:
using value_type = RetT;
private:
T val;
FnT fn;
public:
mapping() {}
mapping(T v, FnT f): val{v}, fn{f} {}
mapping(const mapping & rhs) = default;
auto operator++() -> mapping & {++val; return *this;}
auto operator*() const -> value_type {return fn(*val);}
auto operator==(const mapping & rhs) const -> bool {return val == rhs.val;}
auto operator!=(const mapping & rhs) const -> bool {return val != rhs.val;}
};
}// namespace iter
// Little more than a wrapper for a begin/end pair.
// Ranges can be created from any entity that supports the begin()/end() interface.
template<typename T>
class range {
public:
using iterator = T;
using value_type = decltype(*(T()));
private:
iterator begin_val;
iterator end_val;
public:
range(iterator b, iterator e): begin_val{b}, end_val{e} {}
range(const range & rhs) = default;
auto begin() const -> iterator {return begin_val;}
auto end() const -> iterator {return end_val;}
template<typename FnT>
auto map(FnT fn) const ->
range<iter::mapping<iterator, FnT, decltype(fn(*begin_val))>>
{
return {{begin_val, fn}, {end_val, fn}};
}
auto indexed() const -> range<iter::indexed<iterator>> {
return {{begin_val, 0}, {end_val, 0}};
}
};
template<typename T>
auto gen_range(const T & cont) -> range<typename T::const_iterator> {
using std::begin;
using std::end;
return {begin(cont), end(cont)};
}
using irange = range<iter::integer<int, 1>>;
using rev_irange = range<iter::integer<int, -1>>;
int main()
{
printf("Hello World\n");
auto strings = std::array<std::string, 5>{"foo", "bar", "glib", "glob", "gnop"};
for(auto x: strings)
std::cout << x << std::endl;
for(auto x: gen_range(strings))
std::cout << x << std::endl;
for(auto x: gen_range(strings).indexed())
std::cout << x.index << ": " << x.value << std::endl;
// for(auto x: irange{0, 10})
for(auto x: irange{0, 10}.map([](int x)-> std::string {return str(format("x*x: %d")%(x*x));}))
std::cout << x << std::endl;
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment