Skip to content

Instantly share code, notes, and snippets.

@plonk
Created May 16, 2013 22:09
Show Gist options
  • Select an option

  • Save plonk/5595517 to your computer and use it in GitHub Desktop.

Select an option

Save plonk/5595517 to your computer and use it in GitHub Desktop.
C++でRubyみたいに書きたい病。print文の出来には満足している
#include <sstream>
#include <iostream>
#include <cctype>
#include <list>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
// vector や list で Ruby の Array みたいなことをするクラス
template <typename Container>
class Array {
public:
Array() : data_() { }
template <typename Iterator>
Array(Iterator first, Iterator last) : data_() {
std::copy(first, last, back_inserter(data_));
}
template <typename Functor>
Array map(Functor function) const {
Array<Container> tmp;
std::transform(data_.begin(), data_.end(), back_inserter(tmp.data_), function);
return tmp;
}
template <typename Functor>
Array each(Functor function) const {
std::for_each(data_.begin(), data_.end(), function);
return *this;
}
template <typename Functor>
typename Container::value_type inject(Functor binary_function, typename Container::value_type initial_value) {
return accumulate(data_.begin(), data_.end(), initial_value, binary_function);
}
template <typename Functor>
typename Container::value_type inject(Functor binary_function) {
typename Container::value_type initial_value = data_.front();
auto begin = ++data_.begin();
return accumulate(begin, data_.end(), initial_value, binary_function);
}
string join(const string &separator) {
string buf;
int i = 0;
each([&buf, &i](typename Container::value_type val) {
ostringstream os;
if (i++ != 0) buf += ' ';
os << val;
buf += os.str();
});
return buf;
}
const Container& data() const { return data_; }
private:
Container data_;
};
string upcase(const string &src)
{
string ret(src);
int (*f)(int) = toupper; // to resolve function overload
transform(ret.begin(), ret.end(), ret.begin(), f);
return ret;
}
// 活目せよ。コンマ演算子!
template <typename T>
ostream& operator,(ostream& out, T val)
{
return out << val;
}
#define print cout ,
#define do(x) ([](x) {
#define end })
int main()
{
int _ai[3] = {1, 2, 3};
string _as[2] = {"hello", "world"};
Array<vector<int>> a (&_ai[0], &_ai[3]);
Array<list<string>> a2 (&_as[0], &_as[2]);
auto b = a.map do (int n)
return n*n*n;
end; // 個々の要素を3乗
b.each do (int n)
print n, '\n';
end; // 3乗した要素を表示
int sum = b.inject(plus<int>()); // 計
int product = b.inject(multiplies<int>()); // 積
print "sum = ", sum, '\n';
print "product = ", product, '\n';
print a2.map do (string s)
return upcase(s);
end.join(" ") + '\n'; // 単語を大文字に
print a2.inject(plus<string>(), ">>>") + '\n'; // ">>>" + "hello" + "world"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment