diff --git a/source/range_example.d b/source/range_example.d index f91d476..bdff212 100644 --- a/source/range_example.d +++ b/source/range_example.d @@ -262,16 +262,45 @@ unittest } /++ -配列をRangeとして扱う場合の例です。 +動的配列とRangeのどちらにも使用できる関数を定義する例です。 +/ unittest { import std.range : isInputRange, isRandomAccessRange, only; + // 配列向けの関数をimportしておくことで、 + // 動的配列とRangeのどちらにも使用できる関数が定義できます。 + // ただし、パフォーマンスが重要になる場合は、 + // 動的配列向けに最適化した実装を別途用意することも検討してください。 + bool myAny(InputRange, Element)(InputRange range, Element needle) + if (isInputRange!InputRange) + { + import std.range : empty, front, popFront; + for (; !range.empty; range.popFront()) + { + if (range.front == needle) + { + return true; + } + } + + return false; + } + + // 自作関数を動的配列に対して使用 + values = [1, 2, 3]; + assert(myAny(values, 1)); + assert(!myAny(values, 100)); + + // 動的配列ではないRangeに対しても利用可能 + assert(myAny(only(1), 1)); + assert(!myAny(only(1), 100)); + // 動的配列はstd.rangeやstd.algorithmの内部ではRangeと見なされます。 static assert(isRandomAccessRange!(int[])); - // ただし、そのままではRangeに備わっているメンバーを利用できません。 + // しかし、動的配列用のRangeのメンバーをstd.rangeからimportしないと、 + // 動的配列の各メンバーを利用することはできません。 int[] values = [1, 2, 3, 4]; static assert(!__traits(compiles, { values.empty; @@ -282,8 +311,8 @@ unittest values.popBack; })); - // 動的配列に対してRangeのメンバーを利用するには - // std.rangeの関数をimportする必要があります。 + // std.rangeから各メンバーをimportすることで + // 動的配列をRangeとして扱えるようになります。 { import std.range : empty, front, popFront, save, back, popBack; @@ -300,33 +329,5 @@ unittest assert(saved == [1, 2, 3, 4]); } - - // 配列向けの関数をimportしておくことで、 - // 動的配列とRangeのどちらにも使用できる関数が定義できます。 - // ただし、パフォーマンスが重要になる場合は、 - // 動的配列向けに最適化した実装を別途用意することも検討してください。 - bool myAny(InputRange, Element)(InputRange range, Element needle) - if (isInputRange!InputRange) - { - import std.range : empty, front, popFront; - for (; !range.empty; range.popFront()) - { - if (range.front == needle) - { - return true; - } - } - - return false; - } - - // 自作関数を動的配列に対して使用 - values = [1, 2, 3]; - assert(myAny(values, 1)); - assert(!myAny(values, 100)); - - // 動的配列ではないRangeに対しても利用可能 - assert(myAny(only(1), 1)); - assert(!myAny(only(1), 100)); }