Skip to content

Commit

Permalink
動的配列とRange両対応の関数定義をメインにした。
Browse files Browse the repository at this point in the history
  • Loading branch information
outlandkarasu committed Feb 19, 2022
1 parent 03aa208 commit 2e2a859
Showing 1 changed file with 33 additions and 32 deletions.
65 changes: 33 additions & 32 deletions source/range_example.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -282,8 +311,8 @@ unittest
values.popBack;
}));

// 動的配列に対してRangeのメンバーを利用するには
// std.rangeの関数をimportする必要があります
// std.rangeから各メンバーをimportすることで
// 動的配列をRangeとして扱えるようになります
{
import std.range : empty, front, popFront, save, back, popBack;

Expand All @@ -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));
}

0 comments on commit 2e2a859

Please sign in to comment.