Skip to content

Instantly share code, notes, and snippets.

@piyo7
Created March 11, 2015 11:14
Show Gist options
  • Save piyo7/1711868c7e57c151e174 to your computer and use it in GitHub Desktop.
Save piyo7/1711868c7e57c151e174 to your computer and use it in GitHub Desktop.
Boost.Rangeをパイプライン記法のままコンテナに変換 ref: http://qiita.com/piyo7/items/94e022dd9a0b57bd704b
val vec = (1 to 10).
filter(i => i % 2 != 0).
map(i => i * i).
toVector
print(vec.mkString(",")) // 1,9,25,49,81
auto range = boost::irange(1, 10)
| boost::adaptors::filtered([](int i){ return i % 2 != 0; })
| boost::adaptors::transformed([](int i){ return i * i; })
for (int i : range) std::cout << i << ","; // 1,9,25,49,81,
std::vector<int> vec(std::begin(range), std::end(range));
std::vector<int> vec;
boost::copy(range, std::back_inserter(vec));
std::vector<int> vec = boost::irange(1, 10)
| boost::adaptors::filtered([](int i){ return i % 2 != 0; })
| boost::adaptors::transformed([](int i){ return i * i; })
| boost::as_container; // !?
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/irange.hpp>
#include <iterator>
#include <vector>
// 自前のoperator|をオーバーロードで呼びだすためのタグ
struct ToVector {};
ToVector to_vec = ToVector();
template<
typename Range, // 制約:value_typeが定義されていること、std::beginとstd::end呼べること
typename T = typename Range::value_type
>
std::vector<T> operator | (
const Range& range,
ToVector // タグ
) {
return std::vector<T>(std::begin(range), std::end(range));
}
int main() {
std::vector<int> vec = boost::irange(1, 10)
| boost::adaptors::filtered([](int n){ return n % 2 != 0; })
| boost::adaptors::transformed([](int n){ return n * n; })
| to_vec; // できた!
return 0;
}
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/irange.hpp>
#include <iterator>
#include <vector>
// 暗黙の型変換クラス
template <typename Range>
class RangeConverter {
const Range& range_;
public:
RangeConverter(const Range& range): range_(range) {}
// 暗黙の型変換関数
template <
typename Target // 制約:先頭と末尾のイテレーターによるコンスラクタがあること
>
operator Target() const {
return Target(std::begin(range_), std::end(range_));
}
};
struct ToContainer {};
ToContainer to_cont = ToContainer();
template<
typename Range,
typename T = typename Range::value_type
>
RangeConverter<Range> operator | (
const Range& range,
ToContainer
) {
return RangeConverter<Range>(range); // 具体的なコンテナへの変換はRangeConverterに委ねる
}
int main() {
std::vector<int> vec = boost::irange(1, 10)
| boost::adaptors::filtered([](int n){ return n % 2 != 0; })
| boost::adaptors::transformed([](int n){ return n * n; })
| to_cont; // できた……!
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment