Default values for range access adaptors?
Rangeの先頭要素にアクセスするアダプターで、アクセスできなかった場合にデフォルト値を指定させてほしい、というリクエストがありました。
Ovenから移植し、Boost.Rangeの拡張として開発しているOvenToBoostのfront
アクセッサーは参照を返すので、値(not 参照)であるデフォルト値を許可するのは難しいです。なので、optional
を返すoptional_front
を実装しました。
#include <iostream> #include <vector> #include <boost/assign/list_of.hpp> #include <boost/range/adaptor/filtered.hpp> #include <boost/range/access/front.hpp> bool is_even(int x) { return x % 2 == 0; } int main() { using namespace boost::adaptors; using namespace boost::range::access; std::vector<int> v = boost::assign::list_of(1)(2)(3); if (boost::optional<int&> x = v | filtered(is_even) | optional_front) { std::cout << x.get() << std::endl; } else { std::cout << "not found" << std::endl; } }
2
同様に、最後尾要素にアクセスするoptional_back
、ランダムアクセスするoptional_at
も実装してあります。
Michel Morinさんから、他のアダプターとの一貫性のために、front
はsingle rangeを返すべきじゃないか、というフィードバックをもらいました。たしかに、optional
の代わりにrangeを返す方法もありだと思います。
for (T x : r | front) {
std::cout << x << std::endl;
}
この設計にすれば、要素にアクセスできたらその要素がfor
文で1回だけ取得され、アクセスできなかったら空のrangeが返されます。
設計的にはこの選択肢もありだと思いますが、既存の設計のfront
とoptional_range
も便利だと思うので、これらに加えてfront_range
を追加しようと考えています。
なお、OvenToBoostプロジェクトは間もなくBoost.Rangeにマージされる予定になっています。
Time to merge Oven-to-Boost Extensions?
今月中にはマージしてくれるそうです。優先度の高いものから順次入れていくそうなので、私の方も引き続き追加機能の実装を進めていくつもりです。