binary.h in Dで、 第二引数が含まれるiotaというか、そんな感じのRangeが欲しくなった。 つまり010が与えられたら[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]を返すようなやつである。

テンプレ

int min = 0, max = 10;

// auto closedIntegerInterval = ...;

import std.stdio : writeln;
writeln(typeof(closedIntegerInterval).stringof, closedIntegerInterval);

パターン1

import std.range : iota;
import std.algorithm : map;

auto closedIntegerInterval = iota(min - 1, max).map!(n => n + 1);
MapResult!(__lambda1, Result)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

パターン2

import std.range : iota;

auto closedIntegerInterval = iota(min, max + 1);
Result[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

パターン1、2ともにちゃんと動いてるっぽいが、パターン1の方はmin == int.minのときに、 パターン2の方はmax == int.maxの時にバグる。 例の記事では型のすべての値を列挙したかったので、これではいけない。

パターン3

import std.range : chain, iota, only;

auto closedIntegerInterval = iota(min, max).chain(only(max));
Result[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

採用した方法。 これならどんな値にも対応できる。 もっとシンプルでわかりやすい書き方はないものか?