5.19 15点 更新 (2.030 翻译完成,格式已调整)
5.12 22:30 更新(最后面蓝色部分为 2.030)
5.1 16点 更新(2.029 完成)
4.30 0 点 更新
4.29 19点 更新
4.28 19点 更新
4.27 12点 更新
4.26 12点 更新
4.25 9点 更新
昨天努力的翻译了两小时,结果昏头昏脑刷新了一下,全丢了。。。。。
重来
Jump to: isInputRange isOutputRange isForwardRange isBidirectionalRange isRandomAccessRange ElementType hasSwappableElements hasAssignableElements hasLength isInfinite hasSlicing walkLength Retro retro opSlice empty popFront popBack front back opIndex length Stride stride Chain chain Radial radial Take take advance retreatN Repeat repeat replicate Cycle cycle Topology fixed flexible SListRange sameHead cons Zip zip Proxy at hasAt StoppingPolicy shortest longest requireSameLength Recurrence recurrence Sequence sequence iota
===========================================================================
Range 的种类:InputRange;OutputRange;ForwardRange;RandomAccessRange; bidirectional(双向) 或者 infinite(无穷的range)
Elements的种类:AssignableElements(可分配的);SwappableElements(可交换的)
自己归纳的,不一定对
===========================================================================
This module defines a few useful range incarnations. Credit for ideas in building this module go to bearophile.
这个模块定义了一些有用的 range ,构建这个模块的思想归功于[color=red]去 bearophile[/color]
Author:
Andrei Alexandrescu
template isInputRange(R)
Returns true if R is an input range. An input range must define the primitives empty, popFront, and front. The following code should compile for any input range.
如果 R 是 一个 input 的 range,返回 true 。 一个 input 的 range 必须定义基元 空(primitives empty) 、 popFront 和 front 。 下面的代码应编译任何input range。
R r; // can define a range object 定义一个 range 对象
if (r.empty) {} // can test for empty 判断是否为 空
r.popFront; // can invoke next 调用下一步
auto h = r.front; // can get the front of the range 得到range的front([color=red]range的第一个元素?[/color])
The semantics of an input range (not checkable during compilation) are assumed to be the following (r is an object of type R):
input range 的语义作如下假定 (编译期不检查, 且 r 是一个类型为 R 的对象):
* r.empty returns false iff there is more data available in the range.
r.empty 返回 false , 说明 range 中有数据。
* r.front returns the current element in the range. It may return by value or by reference. Calling r.front is allowed only if calling r.empty has, or would have, returned false.
r.front 在 range 中返回当前的元素。 它可能返回的是“值”或者是“引用”。 [color=red]如果调用 r.empty 已经或将返回 false,只允许调用 r.front
(如果调用 r.empty 返回 false,才允许调用 r.front)[/color]
* r.popFront advances to the popFront element in the range. Calling r.popFront is allowed only if calling r.empty has, or would have, returned false.
r.popFront 在 range 中前移 popFront 元素。 如果调用 r.empty 返回 false,才允许调用 r.popFront 。
template isOutputRange(R,E)
Returns true if R is an output range. An output range must define the primitive put that accepts an object of type E. The following code should compile for any output range.
如果 R 是一个 output range,返回 true 。 一个output range(类型E)必须定义为 对象类型 。 下面的代码应该编译。
R r; // can define a range object 定义一个 range 对象
E e;
r.put(e); // can write an element to the range 将一个元素写入 range
The semantics of an output range (not checkable during compilation) are assumed to be the following (r is an object of type R):
output range 的语义作如下假定 (编译期不检查,且 r 是一个类型为 R 的对象):
* r.put(e) puts e in the range (in a range-dependent manner) and advances to the popFront position in the range. Successive calls to r.put add elements to the range. put may throw to signal failure.
将 e 放入 range 中(按一个连续的依赖方式)并且前进到 range 中的popFront位置。对于连续的调用 r.put(把元素添加到 range )。put 可能抛出异常。 (多少次会出异常??)
put in 加入
template isForwardRange(R)
Returns true if R is a forward range. A forward range is an input range that can save "checkpoints" by simply copying it to another value of the same type. Notable examples of input ranges that are not forward ranges are file/socket ranges; copying such a range will not save the position in the stream, and they most likely reuse an internal buffer as the entire stream does not sit in memory. Subsequently, advancing either the original or the copy will advance the stream, so the copies are not independent. The following code should compile for any forward range.
如果 R 是一个向前(移动)的 range ,返回 true 。一个向前(移动)的 range 是能通过简单地复制它为另一个能保存“检查点”的相同类型的副本。input ranges 不能向前移动的例子是 file/socket range ; 在流(stream)中复制这样一个副本将不会保存位置(position)信息,并且当整个的流(stream)没放置在内存中时,他们很有可能再利用一个内部的缓冲区。其后,推进原始或者副本(range)都将推进流(stream),因此副本不是独立的。下列的代码应该可以编译任何向前(移动)的 range 。
=============================================================
The semantics of a forward range (not checkable during compilation) are the same as for an input range, with the additional requirement that backtracking must be possible by saving a copy of the range object.
forward range 语意上等同于 input range(编译期不检查),另外的要求是,回溯(backtracking)必须要保存一份Range对象副本 。
template isBidirectionalRange(R)
Returns true if R is a bidirectional range. A bidirectional range is a forward range that also offers the primitives back and popBack. The following code should compile for any bidirectional range.
假如 R 是一个bidirectional range(双向 range),返回 true ,bidirectional range 是一个forward range,他也提供了 back 和popBack (方法)。下面的bidirectional range 代码应该可以编译:
R r;
static assert(isForwardRange!(R)); // range is an input range 是一个input range
r.popBack; // can invoke retreat 调用后退
auto t = r.back; // can get the back of the range 可以得到后面的range
The semantics of a bidirectional range (not checkable during compilation) are assumed to be the following (r is an object of type R):
Bidirectional(双向) range 语意上作如下假定(编译期不检查,且 r 是 R类型的对象):
* r.back returns (possibly a reference to) the last element in the range. Calling r.back is allowed only if calling r.empty has, or would have, returned false.
r.back 返回 range 中最后一个元素(也可能是个引用),只有当 r.empty 返回 false 时(r 不为空),才能调用 r.back
template isRandomAccessRange(R)
Returns true if R is a random-access range. A random-access range is a forward range that also offers the primitive opIndex, OR an infinite input range that offers opIndex. The following code should compile for any random-access range.
假如R 是 一个 random-access range ,返回 true ,random-access range 是一个forward range,他也提供了 opIndex (方法),或者是提供了 opIndex(方法)的一种无穷的(infinite)input range。
R r;
static assert(isForwardRange!(R)); // range 是 forward(range)
static assert(isBidirectionalRange!(R) || isInfinite!(R));
// range 是 bidirectional(双向) 或者 infinite(无穷的range)
auto e = r[1]; // can index 可以索引
The semantics of a random-access range (not checkable during compilation) are assumed to be the following (r is an object of type R):
随机访问range(RandomAccessRange)语意上做如下假定(编译期不检查,且 r 是 R类型的对象):
* r.opIndex(n) returns a reference to the nth element in the range.
r.opIndex(n) 操作返回 range中第n 个元素的引用
template ElementType(R)
The element type of R. R does not have to be a range. The element type is determined as the type yielded by r.front for an object r or type R. For example, ElementType!(T[]) is T.
R 不必是个 range ,元素类型是由 r.front 操作产生的对象类型 或 R 类型。例如 ElementType !(T[]) is T.
template hasSwappableElements(R)
Returns true if R is a forward range and has swappable elements. The following code should compile for any random-access range.
假如 R 是一个 forward range并且含有swappable元素,下面的随机访问 range 可以被编译:
R r;
static assert(isForwardRange!(R)); // range is forward
swap(r.front, r.front); // can swap elements of the range 可以交换元素的 range
template hasAssignableElements(R)
Returns true if R is a forward range and has mutable elements. The following code should compile for any random-access range.
如果R 是一个 forward range,并且有不定(量)的元素,则返回 true ,下面(关于)随机访问 range 的代码可以编译:
R r;
static assert(isForwardRange!(R)); // range is forward
auto e = r.front;
r.front = e; // can assign elements of the range 可分配元素的 range 。
template hasLength(R)
Returns true if R has a length member that returns an integral type. R does not have to be a range. Note that length is an optional primitive as no range must implement it. Some ranges do not store their length explicitly, some cannot compute it without actually exhausting the range (e.g. socket streams), and some other ranges may be infinite.
假如 R 是有一个 整数类型的长度成员,则返回 true ,R 不必是个 range ,注意,长度是一个可选的,range不必一定实现它。一些 range 并不存储长度。(因为)有些 range 实际上是没有穷尽的( 例如 socket 流(streams)),,也可能是无限的,因此它可能是无法计算的。
===============================================================================
4.25 上午又翻译了一点
template isInfinite(Range)
Returns true if Range is an infinite input range. An infinite input range is an input range that has a statically-defined member that is always false, for example:
假如 Range 是一个 infinite(无穷的) input range ,返回 true,infinite input range 是一个 ,input range,其静态成员的值永远是 false ,例如:
struct InfiniteRange
{
enum bool empty = false;
...
}
template hasSlicing(Range)
Returns true if Range offers a slicing operator with integral boundaries, that in turn returns an input range type. The following code should compile for hasSlicing to be true:
如果 range 为切片操作提供了一个整数值的边界,返回 true ,反过来(切片操作)他又会返回一个 input range 类型 。下面的代码可以编译出 hasSlicing(操作)为 true
Range r;
auto s = r[1 .. 2];
static assert(isInputRange!(typeof(s)));
size_t walkLength(Range)(Range range, size_t upTo = size_t.max);
This is a best-effort implementation of length for any kind of range.
这是尽最大努力实现长度为任何种类的 range 。
If hasLength!(Range), simply returns range.length without checking upTo.
如果hasLength!(Range), 它简单的返回 range.length (未检查 [color=red]upTo[/color] :arrow: )
Otherwise, walks the range through its length and returns the number of elements seen. Performes [color=red]Ο(n)[/color] evaluations of range.empty and range.popFront, where n is the effective length of range. The upTo parameter is useful to "cut the losses" in case the interest is in seeing whether the range has at least some number of elements. If the parameter [color=red]upTo[/color] is specified, stops if upTo steps have been taken and returns upTo.
当 n 是一个有效的长度,Ο(n) 操作执行range.empty 和 range.popFront 的赋值,否则,遍历 range 返回它的元素总数。如果高兴的看到upTo 参数能够有效的“减少损失”
是否 range 至少有若干的元素。假如 upTo 参数是指定的
[color=red]上面这段翻不好[/color]
===================================================================
4.25 下午
struct Retro(R) if (isBidirectionalRange!(R));
Retro!(R) retro(R)(R input);
Iterates a bidirectional range backwards. 向后迭代一个双向 range
Example: 示例:
int[] a = [ 1, 2, 3, 4, 5 ];
assert(equal(retro(a) == [ 5, 4, 3, 2, 1 ][]));
Retro opSlice();
Returns this. 返回 this。
bool empty();
Forwards to input.empty. 将转发到input.empty (调用)
void popFront();
Forwards to input.popBack. 将转发到input. popBack.
void popBack();
Forwards to input.popFront. 将转发到input.popFront
ElementType!(R) front();
Forwards to input.back. 将转发到input.back.
ElementType!(R) back();
Forwards to input.front. 将转发到input.front.
ElementType!(R) opIndex(uint n);
Forwards to input[input.length - n + 1]. Defined only if R is a random access range and if R defines R.length. 。
将转发到input[input.length - n + 1]。如果 R 定义了 R.length,同时,被定义R 为一个随机访问 range 。
size_t length();
Range primitive operation that returns the length of the range. Forwards to input.length and is defined only if hasLength!(R).
返回 range 的长度( range 的基本操作)。将转发到 input.length ,同时,被定义hasLength!(R) (为真?)。
struct Stride(R) if (isInputRange!(R));
Stride!(R) stride(R)(R input, size_t n);
Iterates range r with stride n. If the range is a random-access range, moves by indexing into the range; otehrwise, moves by successive calls to popFront.
用步长 n 迭代 range ,如果range 是一个随机访问 range ,range 的索引会移动,并且会连续的调用 popFront (操作)
Example:示例:
int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
assert(equal(stride(a, 3) == [ 1, 4, 7, 10 ][]));
this(R input, size_t n);
Initializes the stride. 初始化 步长
Stride opSlice();
Returns this. 返回 this
bool empty();
Forwards to input.empty. 转发到 input.empty (调用)
void popFront();
@@@
void popBack();
Forwards to input.popFront. 转发到 input.popFront.
ElementType!(R) front();
Forwards to input.front. 转发到 input.front.
ElementType!(R) back();
Forwards to input.back after getting rid of any slack items.
转发到 input.back 后将摆脱任何 slack items 。
ElementType!(R) opIndex(uint n);
Forwards to input[input.length - n + 1]. Defined only if R is a random access range and if R defines R.length.
转发到input[input.length - n + 1],如果 R 定义了 R.length,同时被定义R 为一个随机访问 range 。
size_t length();
Range primitive operation that returns the length of the range. Forwards to input.length and is defined only if hasLength!(R).
返回 range 的长度( range 的基本操作)。将转发到 input.length ,同时,被定义仅当hasLength!(R) (为真?)。
========================================================================
4.26 12点 更新
template Chain(R...) if (allSatisfy!(isInputRange,R))
Chain!(R) chain(R...)(R input);
Spans multiple ranges in sequence. The function chain takes any number of ranges and returns a Chain!(R1, R2,...) object. The ranges may be different, but they must have the same element type. The result is a range that offers the front, popFront, and empty primitives. If all input ranges offer random access and length, Chain offers them as well.
顺序跨越多个 range ,函数 chain 需要任意数量的 range ,并返回 Chain!(R1, R2,...) 对象。Range 可能会有所不同,但它们必须具有相同的元素类型。它都提供了 front , popFront , and empty 原始操作。如果所有的 input range 都提供了随机存取和长度,Chain (函数) 也都提供。
If only one range is offered to Chain or chain, the Chain type exits the picture by aliasing itself directly to that range's type.
如果只有一个 range 提供了 Chain 或 chain 函数,Chain 类型通过别名直接回到 range 类型。(picture 何解 ?)
Example:示例:
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
int[] arr3 = [ 7 ];
auto s = chain(arr1, arr2, arr3);
assert(s.length == 7);
assert(s[5] == 6);
assert(equal(s, [1, 2, 3, 4, 5, 6, 7][]));
struct Radial(R) if (isRandomAccessRange!(R) && hasLength!(R));
Radial!(R) radial(R)(R r);
Radial!(R) radial(R)(R r, size_t startingIndex);
Iterates a random-access range starting from a given point and progressively extending left and right from that point. If no initial point is given, iteration starts from the middle of the range. Iteration spans the entire range.
由给定的某一点从左到右遍历 随机存取 range 。如果没有给出初始点,迭代就从 range 的中间点开始,反复迭代整个 range 。(顺序是怎样的?)
=============================================================================
4.27 12点 更新
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
assert(equal(radial(a) == [ 3, 2, 4, 1, 5 ][]));
a = [ 1, 2, 3, 4 ];
assert(equal(radial(a) == [ 2, 3, 1, 4 ][]));
this(R input);
Takes a range and starts iterating from its median point. Ranges with an even length start iterating from the element to the left of the median. The second iterated element, if any, is the one to the right of the first iterated element. A convenient way to use this constructor is by calling the helper function radial(input).
得到一个 range 并且从中间点开始迭代。用一个相等步长从元素中间的左边开始迭代,第二次迭代从(中间点)右边第一个元素开始迭代,使用此构造函数的方便方法是调用helper 函数 radial(input)
this(R input, size_t startingPoint);
Takes a range and starts iterating from input[mid]. The second iterated element, if any, is the one to the right of the first iterated element. If there is no element to the right of input[mid], iteration continues downwards with input[mid - 1] etc. A convenient way to use this constructor is by calling the helper function radial(input, startingPoint).
得到一个 range 并且从 input[mid] 点开始迭代。第二次迭代从( input[mid] 点)右边第一个元素开始迭代,假如 input[mid] 点 右边没有元素,迭代就从input[mid - 1] 继续向下迭代。使用此构造函数的方便方法是调用helper 函数 radial( input, startingPoint ),
Radial opSlice();
Returns this. 返回 this
bool empty();
Range primitive operation that returns true iff there are no more elements to be iterated.
返回 true ,range 为空,没有元素需要迭代
void popFront();
Range primitive operation that advances the range to its next element.
前进到 range 的下一个元素
ElementType!(R) front();
Range primitive operation that returns the currently iterated element. Throws if the range is empty.
返回当前迭代(指向)的元素,如果 range 为空,抛出异常
struct Take(R) if (isInputRange!(R));
Take!(R) take(R)(size_t n, R input);
Lazily takes only up to n elements of a range. This is particulary useful when using with infinite ranges. If the range offers random access and length, Take offers them as well.
只需要取到 range 的 n 个元素,(这个功能在)当使用infinite ranges(无穷 range)时尤为有用。假如 range 提供了随机存取和长度,也会提供它们(上述函数)
Example:
int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
auto s = take(5, arr1);
assert(s.length == 5);
assert(s[4] == 5);
assert(equal(s, [ 1, 2, 3, 4, 5 ][]));
翻到这里开始有点清晰了
=================================================================
4.28 19点 更新
size_t advance(Range)(ref Range r, size_t n);
Eagerly advances r itself (not a copy) n times (by calling r.popFront n times). The pass of r into drop is by reference, so the original range is affected. Completes in Ο(1) steps for ranges that support slicing, and in Ο(n) time for all other ranges.
r 步进(而不是副本) n 次(调用 r.popFront n 次),如果 r 通过引用去删除(调用advances ?),原始的 range 将受到影响,所有的 range 都支持Ο(1) 到 Ο(n) 的切片
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
a.advance(2); // 从最左边往右删除 2 个元素(译注)
assert(a == [ 3, 4, 5 ]);
size_t retreatN(Range)(ref Range r, size_t n);
Eagerly retreats r itself (not a copy) n times (by calling r.popBack n times). The pass of r into advanceRight is by reference, so the original range is affected. Completes in Ο(1) steps for ranges that support slicing, and in Ο(n) time for all other ranges.
r 步退(而不是副本)n 次(调用 r.popBack n 次),如果 r 通过引用调用advanceRight(右进?),原始的 range 将受到影响,所有的 range 都支持Ο(1) 到 Ο(n) 的切片
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
a.advanceRight(2); // 删掉了 4,5,从最右边往左删除 2 个(译注)
assert(a == [ 1, 2, 3 ]);
struct Repeat(T);
Repeat!(T) repeat(T)(T value);
Repeats one value forever. //不断的重复一个值
Example:
enforce(equal(take(4, repeat(5)), [ 5, 5, 5, 5 ][]));
T front();
T back();
bool empty;
void popFront();
T opIndex(uint);
Range primitive implementations. Range 的原始实现
Take!(Repeat!(T)) replicate(T)(size_t n, T value);
Replicates value exactly n times. Equivalent to take(n, repeat(value)).
重复一个值 n 次,等价于take(n, repeat(value)) 。
struct Cycle(R) if (isForwardRange!(R));
struct Cycle(R) if (isStaticArray!(R));
Cycle!(R) cycle(R)(R input);
Cycle!(R) cycle(R)(R input, size_t index);
Repeats the given forward range ad infinitum. If the original range is infinite (fact that would make Cycle the identity application), Cycle detects that and aliases itself to the range type itself. If the original range has random access, Cycle offers random access and also offers a constructor taking an initial position index. Cycle is specialized for statically-sized arrays, mostly for performance reasons.
无限的重复forward range 。假如原始 range 是一个 infinite (range),(实际上是一致性循环) ,循环将检查 别名类型 和 range 类型,假如这个原始 range 有随机存取能力(函数或方法),循环提供随机存取,并且还提供一个构造器去取得 初始位置索引 。为了提高性能,循环是一个特定的静态尺寸的数组
Example:
assert(equal(take(5, cycle([1, 2][])), [ 1, 2, 1, 2, 1 ][]));
Tip: 提示:
This is a great way to implement simple circular buffers.
这是实现简单循环缓冲器的一个很好的方式。
=========================================================================
4.30 0点 更新
enum Topology; 枚举 拓扑
Policy that controls whether or not a range (e.g. std.range.SListRange) iterating a container can modify its topology. By topology of a container we understand the layout of the container's slots and the links between them, regardless of the actual content of the container's elements. For example, a singly-linked list with three elements has the topology of three cells linked by pointers. The topology is not concerned with the content of the nodes, only with the shape of the three connected cells.
控制器策略是否是一 range (例如std.range.SListRange )遍历一个容器可以修改其拓扑。由容器拓扑我们理解容器连接点的布局和它们之间的联系,而不关心容器元素的实际内容。 例如,一个有三个元素的单链表通过指针与三个单元相连接的拓扑。拓扑不关心节点内容,只关心三个连接单元的形成。
Fixed 固定的
The range cannot change the container's topology (whereas it can change its content). This is useful if e.g. the container must control creation and destruction of its slots.
Range 不能改变容器的拓扑(但能改变它的内容),这是非常有用的,例如容器必须管理它的连接点的创建和销毁。
Flexible 灵活性
The range can change the underlying container's structure. This is useful if the range is free-floating and is not owned by any container.
Range 可以改变下面的容器的结构。这是非常有用的,如果 range 是自由浮动,并且不属于任何容器。
struct SListRange(T,Topology topology = Topology.flexible);
Defines a simple and efficient singly-linked list. The list implements the forward range concept. By default the list has flexible topology, e.g. appending to it is possible.
定义了一个简单而有效的单链表。这个单链表实现了forward range。默认情况下,单链表具有灵活的拓扑,例如向其追加。
Example:
SListRange!(int, Topology.flexible) lst(2, 3);
lst = cons(1, lst);
assert(equal(lst, [1, 2, 3][]));
this(T[] values...);
Constructor taking an array of values. 构造器得到一个数组值。
Example:
auto lst = SListRange!(int)(1, 2, 3, 4, 5);
assert(equal(lst, [1, 2, 3, 4, 5][]));
SListRange opSlice();
Returns this. 返回 this 。
const bool empty(); [color=red] iff =if and only if 【逻】在...,而且只有在...[/color]
Range primitive operation that returns true iff there are no more elements to be iterated.
range 的基元操作,返回 true ,没有元素要迭代
void popFront();
Range primitive operation that advances the range to its next element. Forwards to input.popBack.
步进到下一个元素(Range 的原始操作),步退用input.popBack 。(好像是要配套使用)
T front();
Range primitive operation that returns the currently iterated element. Forwards to input.back.
返回当前迭代元素,步退用input.popBack 。(好像是要配套使用)
const bool sameHead(in SListRange!(T,topology) rhs);
Returns true iff this list and rhs have the same front.
如果 list 和 rhs 有相同的前端(第一个元素相同?),返回 true
SListRange!(T,t) cons(T, Topology t)(T front, SListRange!(T,t) tail);
Prepends value to the root of the list. 从开始处添加值(root 根部)
BUG:
This function may fail to compile due to bug 2676.
这个函数也许会编译失败
4.30
struct Zip(R...) if (R.length && allSatisfy!(isInputRange,R));
Zip!(R) zip(R...)(R ranges);
Zip!(R) zip(R...)(StoppingPolicy sp, R ranges);
Iterate several ranges in lockstep. The element type is a proxy tuple that allows accessing the current element in the nth range by using e.at!(n).
在同步(lockstep)中重复几个 range 。元素类型是代理元组,使用 e.at!(n) 允许访问第 n 个 range 中的当前元素, ,
Example:
int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "b", "c" ];
// prints 1:a 2:b 3:c
foreach (e; zip(a, b))
{
write(e.at!(0), ':', e.at!(1), ' ');
}
Zip offers the lowest range facilities of all components, e.g. it offers random access iff all ranges offer random access, and also offers mutation and swapping if all ranges offer it. Due to this, Zip is extremely powerful because it allows manipulating several ranges in lockstep. For example, the following code sorts two arrays in parallel:
Zip 提供最小 range 的所有组件,例如,它提供了随机存取,同时还提供了转换(mutation) and 交换(swapping)。因此,zip 是极其强大的,它允许同步操作多个 range。例如,下面的代码并行索引两个数组:
int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "b", "c" ];
sort!("a.at!(0) > b.at!(0)")(zip(a, b));
assert(a == [ 3, 2, 1 ]);
assert(b == [ "c", "b", "a" ]);
this(R rs, StoppingPolicy s = StoppingPolicy.shortest);
Builds an object. Usually this is invoked indirectly by using the std.range.zip function.
构建一个对象。使用 std.range.zip 函数间接调用。
bool empty();
Returns true if the range is at end. The test depends on the stopping policy.
假如 range 是在末尾,返回 true 。测试取决于stopping 策略。
Proxy front();
Returns a proxy for the current iterated element.
返回当前迭代元素的代理
Proxy back();
Returns a proxy for the rightmost element.
返回最右边元素的代理
void popFront();
Advances to the popFront element in all controlled ranges.
(在所有受控制的 range 里) 步进到 popFront 元素
void popBack();
Calls popBack for all controlled ranges.
调用 popBack( )
size_t length();
Returns the length of this range. Defined only if all ranges define length.
返回 range 的 length(长度)。所有的 range 都定义了 length 。
===================================================================
5.1 16点 更新 (完)
struct Recurrence(alias fun,StateType,size_t stateSize);
Recurrence!(fun,CommonType!(State),State.length) recurrence(alias fun, State...)(State initial);
Creates a mathematical sequence given the initial values and a recurrence function that computes the popFront value from the existing values. The sequence comes in the form of an infinite forward range. The type Recurrence itself is seldom used directly; most often, recurrences are obtained by calling the function recurrence.
从现有的值中创建一个数学序列,用给出的初始值和recurrence 函数 计算 popFront 值。Sequence 是 infinite forward range 的形式,这个类型很少被重复,经常被重复是由于调用 recurrence 函数
When calling recurrence, the function that computes the next value is specified as a template argument, and the initial values in the recurrence are passed as regular arguments. For example, in a Fibonacci sequence, there are two initial values (and therefore a state size of 2) because computing the popFront Fibonacci value needs the past two values.
当重复调用,该函数计算下一个 值 ,通过指定为一个模板参数和初始值 再次被作为定期参数传递。 例如在一个 斐波那契序列,有两个初始值 (,因此一 状态的大小是2) 因为计算 popFront 斐波那契值需要两个值。
If the function is passed in string form, the state has name "a" and the zero-based index in the recurrence has name "n". The given string must return the desired value for a[n] given a[n - 1], a[n - 2], a[n - 3],..., a[n - stateSize]. The state size is dictated by the number of arguments passed to the call to recurrence. The Recurrence class itself takes care of managing the recurrence's state and shifting it appropriately.
该函数是以传递字符串形式,状态名称 "a" 和在 recurrence中从零开始的索引名称 "n"。 给定字符串必须返回所需的值a[n] 给 a[n -1], a[n-2] , a[n-3] ,..., a[n-stateSize] 。 状态的大小是要传递给调用 recurrence 的参数的数量 。 在Recurrence类自己 管理 recurrence 的状态和适当地移动它。
Example:
// a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n]
auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
// print the first 10 Fibonacci numbers
foreach (e; take(10, fib)) { writeln(e); }
// print the first 10 factorials
foreach (e; take(10, recurrence!("a[n-1] * n")(1))) { writeln(e); }
struct Sequence(alias fun,State);
Sequence!(fun,Tuple!(State)) sequence(alias fun, State...)(State args);
Sequence is similar to Recurrence except that iteration is presented in the so-called closed form. This means that the nth element in the series is computable directly from the initial values and n itself. This implies that the interface offered by Sequence is a random-access range, as opposed to the regular Recurrence, which only offers forward iteration.
序列是不重复的,迭代是以封闭的形式进行。这意味着,从初始值 到 N 的第 n 个元素是可计算的。这意味着,sequence 提供的接口是一个 random-access range ,不是反复重复
,而只是提供向前迭代。
The state of the sequence is stored as a Tuple so it can be heterogeneous.
序列的狀態被儲存為一元組,這樣它能是不同種類的。
Example:
// a[0] = 1, a[1] = 2, a[n] = a[0] + n * a[1]
auto odds = sequence!("a[0] + n * a[1]")(1, 2);
Take!(Sequence!("a.field[0] + n * a.field[1]",Tuple!(CommonType!(B,E),S))) iota(B, E, S)(B begin, E end, S step);
[color=blue]Take!(Sequence!("a.field[0] + n * a.field[1]",Tuple!(CommonType!(B,E),uint))) iota(B, E)(B begin, E end); [/color]
Returns a range that goes through the numbers begin, begin + step, begin + 2 * step, ..., up to and excluding end. The range offered is a random access range.[color=blue]The two-arguments version has step = 1。[/color]
通过一个数字返回 range ,执行 begin + step, begin + 2 * step, ... 并且排除尾端。这个 range 提供 random access range 。步长为1。
Example:
auto r = iota(0, 10, 1);
assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));
r = iota(0, 11, 3);
assert(equal(r, [0, 3, 6, 9][]));
assert(r[2] == 6);
[color=blue]enum TransverseOptions; 枚举 横截选项
Options for the FrontTransversal and Transversal ranges (below).
FrontTransversal 和 横截 range 选项如下:
assumeJagged 锯齿断言
When transversed, the elements of a range of ranges are assumed to have different lengths (e.g. a jagged array).
当transversed ,一系列 range 的元素被假定有不同的长度(如不规则阵列,或锯齿数组) 。
enforceNotJagged 强制无锯齿
The transversal enforces that the elements of a range of ranges have all the same length (e.g. an array of arrays, all having the same length). Checking is done once upon construction of the transversal range.
横向执行的一系列 range 的元素都有相同的长度(例如一个数组的数组,全都具有相同的长度)。
做一次检查后,构建 横截 range 。
assumeNotJagged 断言非锯齿
The transversal assumes, without verifying, that the elements of a range of ranges have all the same length. This option is useful if checking was already done from the outside of the range.
横向假设(断言),未经核实,一系列 range 的元素都一样长(range.length)。这个选项是有用的,如果是已经完成检查的 range 除外。
struct FrontTransversal(RangeOfRanges,TransverseOptions opt = TransverseOptions.assumeJagged);
FrontTransversal!(RangeOfRanges,opt) frontTransversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr);
Given a range of ranges, iterate transversally through the first elements of each of the enclosed ranges.
给定一系列 range,在每个封闭的 range 里,通过第一个元素 迭代横向(横向迭代?)(transversally)。
Example:
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = frontTransversal(x);
assert(equals(ror, [ 1, 3 ][]));
this(RangeOfRanges input);
Construction from an input.
通过 一个 input(RangeOfRanges 一种 range 类型) 构造。
bool empty();
ElementType front();
void popFront();
Forward range primitives.
Forward range 的基元(都有的函数)。
ElementType back();
void popBack();
Bidirectional primitives. They are offered if isBidirectionalRange!RangeOfRanges.
双向 基元 (双向 range 都有),如果他们提供isBidirectionalRange!RangeOfRanges (方法)。
ElementType opIndex(size_t n);
Random-access primitive. It is offered if isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).
随机存取基元,如果他们都提供 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).(方法)
struct Transversal(RangeOfRanges,TransverseOptions opt = TransverseOptions.assumeJagged);
Transversal!(RangeOfRanges,opt) transversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr, size_t n);
Given a range of ranges, iterate transversally through the the nth element of each of the enclosed ranges. All elements of the enclosing range must offer random access.
给定一系列 range ,在每个封闭的 range 里,通过第 n 个元素 迭代横向(横向迭代?)。所有 range 的元素必须提供随机存取。
Example:
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = transversal(x, 1);
assert(equals(ror, [ 2, 4 ][]));
this(RangeOfRanges input, size_t n);
Construction from an input and an index.
通过 一个 input(RangeOfRanges 一种 range 类型) 和 一个 index 构造
bool empty();
ElementType front();
void popFront();
Forward range primitives.
Forward range 的基元(都有的函数)。
ElementType back();
Bidirectional primitives. They are offered if isBidirectionalRange!RangeOfRanges.
双向 基元 (双向 range 都有),如果他们提供 isBidirectionalRange!RangeOfRanges (方法)。
ElementType opIndex(size_t n);
Random-access primitive. It is offered if isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).
随机存取基元 它如果提供 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged) (方法)。 [/color]
5.12 22:30 更新(最后面蓝色部分为 2.030)
5.1 16点 更新(2.029 完成)
4.30 0 点 更新
4.29 19点 更新
4.28 19点 更新
4.27 12点 更新
4.26 12点 更新
4.25 9点 更新
昨天努力的翻译了两小时,结果昏头昏脑刷新了一下,全丢了。。。。。
重来
Jump to: isInputRange isOutputRange isForwardRange isBidirectionalRange isRandomAccessRange ElementType hasSwappableElements hasAssignableElements hasLength isInfinite hasSlicing walkLength Retro retro opSlice empty popFront popBack front back opIndex length Stride stride Chain chain Radial radial Take take advance retreatN Repeat repeat replicate Cycle cycle Topology fixed flexible SListRange sameHead cons Zip zip Proxy at hasAt StoppingPolicy shortest longest requireSameLength Recurrence recurrence Sequence sequence iota
===========================================================================
Range 的种类:InputRange;OutputRange;ForwardRange;RandomAccessRange; bidirectional(双向) 或者 infinite(无穷的range)
Elements的种类:AssignableElements(可分配的);SwappableElements(可交换的)
自己归纳的,不一定对
===========================================================================
This module defines a few useful range incarnations. Credit for ideas in building this module go to bearophile.
这个模块定义了一些有用的 range ,构建这个模块的思想归功于[color=red]去 bearophile[/color]
Author:
Andrei Alexandrescu
template isInputRange(R)
Returns true if R is an input range. An input range must define the primitives empty, popFront, and front. The following code should compile for any input range.
如果 R 是 一个 input 的 range,返回 true 。 一个 input 的 range 必须定义基元 空(primitives empty) 、 popFront 和 front 。 下面的代码应编译任何input range。
R r; // can define a range object 定义一个 range 对象
if (r.empty) {} // can test for empty 判断是否为 空
r.popFront; // can invoke next 调用下一步
auto h = r.front; // can get the front of the range 得到range的front([color=red]range的第一个元素?[/color])
The semantics of an input range (not checkable during compilation) are assumed to be the following (r is an object of type R):
input range 的语义作如下假定 (编译期不检查, 且 r 是一个类型为 R 的对象):
* r.empty returns false iff there is more data available in the range.
r.empty 返回 false , 说明 range 中有数据。
* r.front returns the current element in the range. It may return by value or by reference. Calling r.front is allowed only if calling r.empty has, or would have, returned false.
r.front 在 range 中返回当前的元素。 它可能返回的是“值”或者是“引用”。 [color=red]如果调用 r.empty 已经或将返回 false,只允许调用 r.front
(如果调用 r.empty 返回 false,才允许调用 r.front)[/color]
* r.popFront advances to the popFront element in the range. Calling r.popFront is allowed only if calling r.empty has, or would have, returned false.
r.popFront 在 range 中前移 popFront 元素。 如果调用 r.empty 返回 false,才允许调用 r.popFront 。
template isOutputRange(R,E)
Returns true if R is an output range. An output range must define the primitive put that accepts an object of type E. The following code should compile for any output range.
如果 R 是一个 output range,返回 true 。 一个output range(类型E)必须定义为 对象类型 。 下面的代码应该编译。
R r; // can define a range object 定义一个 range 对象
E e;
r.put(e); // can write an element to the range 将一个元素写入 range
The semantics of an output range (not checkable during compilation) are assumed to be the following (r is an object of type R):
output range 的语义作如下假定 (编译期不检查,且 r 是一个类型为 R 的对象):
* r.put(e) puts e in the range (in a range-dependent manner) and advances to the popFront position in the range. Successive calls to r.put add elements to the range. put may throw to signal failure.
将 e 放入 range 中(按一个连续的依赖方式)并且前进到 range 中的popFront位置。对于连续的调用 r.put(把元素添加到 range )。put 可能抛出异常。 (多少次会出异常??)
put in 加入
template isForwardRange(R)
Returns true if R is a forward range. A forward range is an input range that can save "checkpoints" by simply copying it to another value of the same type. Notable examples of input ranges that are not forward ranges are file/socket ranges; copying such a range will not save the position in the stream, and they most likely reuse an internal buffer as the entire stream does not sit in memory. Subsequently, advancing either the original or the copy will advance the stream, so the copies are not independent. The following code should compile for any forward range.
如果 R 是一个向前(移动)的 range ,返回 true 。一个向前(移动)的 range 是能通过简单地复制它为另一个能保存“检查点”的相同类型的副本。input ranges 不能向前移动的例子是 file/socket range ; 在流(stream)中复制这样一个副本将不会保存位置(position)信息,并且当整个的流(stream)没放置在内存中时,他们很有可能再利用一个内部的缓冲区。其后,推进原始或者副本(range)都将推进流(stream),因此副本不是独立的。下列的代码应该可以编译任何向前(移动)的 range 。
=============================================================
The semantics of a forward range (not checkable during compilation) are the same as for an input range, with the additional requirement that backtracking must be possible by saving a copy of the range object.
forward range 语意上等同于 input range(编译期不检查),另外的要求是,回溯(backtracking)必须要保存一份Range对象副本 。
template isBidirectionalRange(R)
Returns true if R is a bidirectional range. A bidirectional range is a forward range that also offers the primitives back and popBack. The following code should compile for any bidirectional range.
假如 R 是一个bidirectional range(双向 range),返回 true ,bidirectional range 是一个forward range,他也提供了 back 和popBack (方法)。下面的bidirectional range 代码应该可以编译:
R r;
static assert(isForwardRange!(R)); // range is an input range 是一个input range
r.popBack; // can invoke retreat 调用后退
auto t = r.back; // can get the back of the range 可以得到后面的range
The semantics of a bidirectional range (not checkable during compilation) are assumed to be the following (r is an object of type R):
Bidirectional(双向) range 语意上作如下假定(编译期不检查,且 r 是 R类型的对象):
* r.back returns (possibly a reference to) the last element in the range. Calling r.back is allowed only if calling r.empty has, or would have, returned false.
r.back 返回 range 中最后一个元素(也可能是个引用),只有当 r.empty 返回 false 时(r 不为空),才能调用 r.back
template isRandomAccessRange(R)
Returns true if R is a random-access range. A random-access range is a forward range that also offers the primitive opIndex, OR an infinite input range that offers opIndex. The following code should compile for any random-access range.
假如R 是 一个 random-access range ,返回 true ,random-access range 是一个forward range,他也提供了 opIndex (方法),或者是提供了 opIndex(方法)的一种无穷的(infinite)input range。
R r;
static assert(isForwardRange!(R)); // range 是 forward(range)
static assert(isBidirectionalRange!(R) || isInfinite!(R));
// range 是 bidirectional(双向) 或者 infinite(无穷的range)
auto e = r[1]; // can index 可以索引
The semantics of a random-access range (not checkable during compilation) are assumed to be the following (r is an object of type R):
随机访问range(RandomAccessRange)语意上做如下假定(编译期不检查,且 r 是 R类型的对象):
* r.opIndex(n) returns a reference to the nth element in the range.
r.opIndex(n) 操作返回 range中第n 个元素的引用
template ElementType(R)
The element type of R. R does not have to be a range. The element type is determined as the type yielded by r.front for an object r or type R. For example, ElementType!(T[]) is T.
R 不必是个 range ,元素类型是由 r.front 操作产生的对象类型 或 R 类型。例如 ElementType !(T[]) is T.
template hasSwappableElements(R)
Returns true if R is a forward range and has swappable elements. The following code should compile for any random-access range.
假如 R 是一个 forward range并且含有swappable元素,下面的随机访问 range 可以被编译:
R r;
static assert(isForwardRange!(R)); // range is forward
swap(r.front, r.front); // can swap elements of the range 可以交换元素的 range
template hasAssignableElements(R)
Returns true if R is a forward range and has mutable elements. The following code should compile for any random-access range.
如果R 是一个 forward range,并且有不定(量)的元素,则返回 true ,下面(关于)随机访问 range 的代码可以编译:
R r;
static assert(isForwardRange!(R)); // range is forward
auto e = r.front;
r.front = e; // can assign elements of the range 可分配元素的 range 。
template hasLength(R)
Returns true if R has a length member that returns an integral type. R does not have to be a range. Note that length is an optional primitive as no range must implement it. Some ranges do not store their length explicitly, some cannot compute it without actually exhausting the range (e.g. socket streams), and some other ranges may be infinite.
假如 R 是有一个 整数类型的长度成员,则返回 true ,R 不必是个 range ,注意,长度是一个可选的,range不必一定实现它。一些 range 并不存储长度。(因为)有些 range 实际上是没有穷尽的( 例如 socket 流(streams)),,也可能是无限的,因此它可能是无法计算的。
===============================================================================
4.25 上午又翻译了一点
template isInfinite(Range)
Returns true if Range is an infinite input range. An infinite input range is an input range that has a statically-defined member that is always false, for example:
假如 Range 是一个 infinite(无穷的) input range ,返回 true,infinite input range 是一个 ,input range,其静态成员的值永远是 false ,例如:
struct InfiniteRange
{
enum bool empty = false;
...
}
template hasSlicing(Range)
Returns true if Range offers a slicing operator with integral boundaries, that in turn returns an input range type. The following code should compile for hasSlicing to be true:
如果 range 为切片操作提供了一个整数值的边界,返回 true ,反过来(切片操作)他又会返回一个 input range 类型 。下面的代码可以编译出 hasSlicing(操作)为 true
Range r;
auto s = r[1 .. 2];
static assert(isInputRange!(typeof(s)));
size_t walkLength(Range)(Range range, size_t upTo = size_t.max);
This is a best-effort implementation of length for any kind of range.
这是尽最大努力实现长度为任何种类的 range 。
If hasLength!(Range), simply returns range.length without checking upTo.
如果hasLength!(Range), 它简单的返回 range.length (未检查 [color=red]upTo[/color] :arrow: )
Otherwise, walks the range through its length and returns the number of elements seen. Performes [color=red]Ο(n)[/color] evaluations of range.empty and range.popFront, where n is the effective length of range. The upTo parameter is useful to "cut the losses" in case the interest is in seeing whether the range has at least some number of elements. If the parameter [color=red]upTo[/color] is specified, stops if upTo steps have been taken and returns upTo.
当 n 是一个有效的长度,Ο(n) 操作执行range.empty 和 range.popFront 的赋值,否则,遍历 range 返回它的元素总数。如果高兴的看到upTo 参数能够有效的“减少损失”
是否 range 至少有若干的元素。假如 upTo 参数是指定的
[color=red]上面这段翻不好[/color]
===================================================================
4.25 下午
struct Retro(R) if (isBidirectionalRange!(R));
Retro!(R) retro(R)(R input);
Iterates a bidirectional range backwards. 向后迭代一个双向 range
Example: 示例:
int[] a = [ 1, 2, 3, 4, 5 ];
assert(equal(retro(a) == [ 5, 4, 3, 2, 1 ][]));
Retro opSlice();
Returns this. 返回 this。
bool empty();
Forwards to input.empty. 将转发到input.empty (调用)
void popFront();
Forwards to input.popBack. 将转发到input. popBack.
void popBack();
Forwards to input.popFront. 将转发到input.popFront
ElementType!(R) front();
Forwards to input.back. 将转发到input.back.
ElementType!(R) back();
Forwards to input.front. 将转发到input.front.
ElementType!(R) opIndex(uint n);
Forwards to input[input.length - n + 1]. Defined only if R is a random access range and if R defines R.length. 。
将转发到input[input.length - n + 1]。如果 R 定义了 R.length,同时,被定义R 为一个随机访问 range 。
size_t length();
Range primitive operation that returns the length of the range. Forwards to input.length and is defined only if hasLength!(R).
返回 range 的长度( range 的基本操作)。将转发到 input.length ,同时,被定义hasLength!(R) (为真?)。
struct Stride(R) if (isInputRange!(R));
Stride!(R) stride(R)(R input, size_t n);
Iterates range r with stride n. If the range is a random-access range, moves by indexing into the range; otehrwise, moves by successive calls to popFront.
用步长 n 迭代 range ,如果range 是一个随机访问 range ,range 的索引会移动,并且会连续的调用 popFront (操作)
Example:示例:
int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
assert(equal(stride(a, 3) == [ 1, 4, 7, 10 ][]));
this(R input, size_t n);
Initializes the stride. 初始化 步长
Stride opSlice();
Returns this. 返回 this
bool empty();
Forwards to input.empty. 转发到 input.empty (调用)
void popFront();
@@@
void popBack();
Forwards to input.popFront. 转发到 input.popFront.
ElementType!(R) front();
Forwards to input.front. 转发到 input.front.
ElementType!(R) back();
Forwards to input.back after getting rid of any slack items.
转发到 input.back 后将摆脱任何 slack items 。
ElementType!(R) opIndex(uint n);
Forwards to input[input.length - n + 1]. Defined only if R is a random access range and if R defines R.length.
转发到input[input.length - n + 1],如果 R 定义了 R.length,同时被定义R 为一个随机访问 range 。
size_t length();
Range primitive operation that returns the length of the range. Forwards to input.length and is defined only if hasLength!(R).
返回 range 的长度( range 的基本操作)。将转发到 input.length ,同时,被定义仅当hasLength!(R) (为真?)。
========================================================================
4.26 12点 更新
template Chain(R...) if (allSatisfy!(isInputRange,R))
Chain!(R) chain(R...)(R input);
Spans multiple ranges in sequence. The function chain takes any number of ranges and returns a Chain!(R1, R2,...) object. The ranges may be different, but they must have the same element type. The result is a range that offers the front, popFront, and empty primitives. If all input ranges offer random access and length, Chain offers them as well.
顺序跨越多个 range ,函数 chain 需要任意数量的 range ,并返回 Chain!(R1, R2,...) 对象。Range 可能会有所不同,但它们必须具有相同的元素类型。它都提供了 front , popFront , and empty 原始操作。如果所有的 input range 都提供了随机存取和长度,Chain (函数) 也都提供。
If only one range is offered to Chain or chain, the Chain type exits the picture by aliasing itself directly to that range's type.
如果只有一个 range 提供了 Chain 或 chain 函数,Chain 类型通过别名直接回到 range 类型。(picture 何解 ?)
Example:示例:
int[] arr1 = [ 1, 2, 3, 4 ];
int[] arr2 = [ 5, 6 ];
int[] arr3 = [ 7 ];
auto s = chain(arr1, arr2, arr3);
assert(s.length == 7);
assert(s[5] == 6);
assert(equal(s, [1, 2, 3, 4, 5, 6, 7][]));
struct Radial(R) if (isRandomAccessRange!(R) && hasLength!(R));
Radial!(R) radial(R)(R r);
Radial!(R) radial(R)(R r, size_t startingIndex);
Iterates a random-access range starting from a given point and progressively extending left and right from that point. If no initial point is given, iteration starts from the middle of the range. Iteration spans the entire range.
由给定的某一点从左到右遍历 随机存取 range 。如果没有给出初始点,迭代就从 range 的中间点开始,反复迭代整个 range 。(顺序是怎样的?)
=============================================================================
4.27 12点 更新
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
assert(equal(radial(a) == [ 3, 2, 4, 1, 5 ][]));
a = [ 1, 2, 3, 4 ];
assert(equal(radial(a) == [ 2, 3, 1, 4 ][]));
this(R input);
Takes a range and starts iterating from its median point. Ranges with an even length start iterating from the element to the left of the median. The second iterated element, if any, is the one to the right of the first iterated element. A convenient way to use this constructor is by calling the helper function radial(input).
得到一个 range 并且从中间点开始迭代。用一个相等步长从元素中间的左边开始迭代,第二次迭代从(中间点)右边第一个元素开始迭代,使用此构造函数的方便方法是调用helper 函数 radial(input)
this(R input, size_t startingPoint);
Takes a range and starts iterating from input[mid]. The second iterated element, if any, is the one to the right of the first iterated element. If there is no element to the right of input[mid], iteration continues downwards with input[mid - 1] etc. A convenient way to use this constructor is by calling the helper function radial(input, startingPoint).
得到一个 range 并且从 input[mid] 点开始迭代。第二次迭代从( input[mid] 点)右边第一个元素开始迭代,假如 input[mid] 点 右边没有元素,迭代就从input[mid - 1] 继续向下迭代。使用此构造函数的方便方法是调用helper 函数 radial( input, startingPoint ),
Radial opSlice();
Returns this. 返回 this
bool empty();
Range primitive operation that returns true iff there are no more elements to be iterated.
返回 true ,range 为空,没有元素需要迭代
void popFront();
Range primitive operation that advances the range to its next element.
前进到 range 的下一个元素
ElementType!(R) front();
Range primitive operation that returns the currently iterated element. Throws if the range is empty.
返回当前迭代(指向)的元素,如果 range 为空,抛出异常
struct Take(R) if (isInputRange!(R));
Take!(R) take(R)(size_t n, R input);
Lazily takes only up to n elements of a range. This is particulary useful when using with infinite ranges. If the range offers random access and length, Take offers them as well.
只需要取到 range 的 n 个元素,(这个功能在)当使用infinite ranges(无穷 range)时尤为有用。假如 range 提供了随机存取和长度,也会提供它们(上述函数)
Example:
int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
auto s = take(5, arr1);
assert(s.length == 5);
assert(s[4] == 5);
assert(equal(s, [ 1, 2, 3, 4, 5 ][]));
翻到这里开始有点清晰了
=================================================================
4.28 19点 更新
size_t advance(Range)(ref Range r, size_t n);
Eagerly advances r itself (not a copy) n times (by calling r.popFront n times). The pass of r into drop is by reference, so the original range is affected. Completes in Ο(1) steps for ranges that support slicing, and in Ο(n) time for all other ranges.
r 步进(而不是副本) n 次(调用 r.popFront n 次),如果 r 通过引用去删除(调用advances ?),原始的 range 将受到影响,所有的 range 都支持Ο(1) 到 Ο(n) 的切片
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
a.advance(2); // 从最左边往右删除 2 个元素(译注)
assert(a == [ 3, 4, 5 ]);
size_t retreatN(Range)(ref Range r, size_t n);
Eagerly retreats r itself (not a copy) n times (by calling r.popBack n times). The pass of r into advanceRight is by reference, so the original range is affected. Completes in Ο(1) steps for ranges that support slicing, and in Ο(n) time for all other ranges.
r 步退(而不是副本)n 次(调用 r.popBack n 次),如果 r 通过引用调用advanceRight(右进?),原始的 range 将受到影响,所有的 range 都支持Ο(1) 到 Ο(n) 的切片
Example:
int[] a = [ 1, 2, 3, 4, 5 ];
a.advanceRight(2); // 删掉了 4,5,从最右边往左删除 2 个(译注)
assert(a == [ 1, 2, 3 ]);
struct Repeat(T);
Repeat!(T) repeat(T)(T value);
Repeats one value forever. //不断的重复一个值
Example:
enforce(equal(take(4, repeat(5)), [ 5, 5, 5, 5 ][]));
T front();
T back();
bool empty;
void popFront();
T opIndex(uint);
Range primitive implementations. Range 的原始实现
Take!(Repeat!(T)) replicate(T)(size_t n, T value);
Replicates value exactly n times. Equivalent to take(n, repeat(value)).
重复一个值 n 次,等价于take(n, repeat(value)) 。
struct Cycle(R) if (isForwardRange!(R));
struct Cycle(R) if (isStaticArray!(R));
Cycle!(R) cycle(R)(R input);
Cycle!(R) cycle(R)(R input, size_t index);
Repeats the given forward range ad infinitum. If the original range is infinite (fact that would make Cycle the identity application), Cycle detects that and aliases itself to the range type itself. If the original range has random access, Cycle offers random access and also offers a constructor taking an initial position index. Cycle is specialized for statically-sized arrays, mostly for performance reasons.
无限的重复forward range 。假如原始 range 是一个 infinite (range),(实际上是一致性循环) ,循环将检查 别名类型 和 range 类型,假如这个原始 range 有随机存取能力(函数或方法),循环提供随机存取,并且还提供一个构造器去取得 初始位置索引 。为了提高性能,循环是一个特定的静态尺寸的数组
Example:
assert(equal(take(5, cycle([1, 2][])), [ 1, 2, 1, 2, 1 ][]));
Tip: 提示:
This is a great way to implement simple circular buffers.
这是实现简单循环缓冲器的一个很好的方式。
=========================================================================
4.30 0点 更新
enum Topology; 枚举 拓扑
Policy that controls whether or not a range (e.g. std.range.SListRange) iterating a container can modify its topology. By topology of a container we understand the layout of the container's slots and the links between them, regardless of the actual content of the container's elements. For example, a singly-linked list with three elements has the topology of three cells linked by pointers. The topology is not concerned with the content of the nodes, only with the shape of the three connected cells.
控制器策略是否是一 range (例如std.range.SListRange )遍历一个容器可以修改其拓扑。由容器拓扑我们理解容器连接点的布局和它们之间的联系,而不关心容器元素的实际内容。 例如,一个有三个元素的单链表通过指针与三个单元相连接的拓扑。拓扑不关心节点内容,只关心三个连接单元的形成。
Fixed 固定的
The range cannot change the container's topology (whereas it can change its content). This is useful if e.g. the container must control creation and destruction of its slots.
Range 不能改变容器的拓扑(但能改变它的内容),这是非常有用的,例如容器必须管理它的连接点的创建和销毁。
Flexible 灵活性
The range can change the underlying container's structure. This is useful if the range is free-floating and is not owned by any container.
Range 可以改变下面的容器的结构。这是非常有用的,如果 range 是自由浮动,并且不属于任何容器。
struct SListRange(T,Topology topology = Topology.flexible);
Defines a simple and efficient singly-linked list. The list implements the forward range concept. By default the list has flexible topology, e.g. appending to it is possible.
定义了一个简单而有效的单链表。这个单链表实现了forward range。默认情况下,单链表具有灵活的拓扑,例如向其追加。
Example:
SListRange!(int, Topology.flexible) lst(2, 3);
lst = cons(1, lst);
assert(equal(lst, [1, 2, 3][]));
this(T[] values...);
Constructor taking an array of values. 构造器得到一个数组值。
Example:
auto lst = SListRange!(int)(1, 2, 3, 4, 5);
assert(equal(lst, [1, 2, 3, 4, 5][]));
SListRange opSlice();
Returns this. 返回 this 。
const bool empty(); [color=red] iff =if and only if 【逻】在...,而且只有在...[/color]
Range primitive operation that returns true iff there are no more elements to be iterated.
range 的基元操作,返回 true ,没有元素要迭代
void popFront();
Range primitive operation that advances the range to its next element. Forwards to input.popBack.
步进到下一个元素(Range 的原始操作),步退用input.popBack 。(好像是要配套使用)
T front();
Range primitive operation that returns the currently iterated element. Forwards to input.back.
返回当前迭代元素,步退用input.popBack 。(好像是要配套使用)
const bool sameHead(in SListRange!(T,topology) rhs);
Returns true iff this list and rhs have the same front.
如果 list 和 rhs 有相同的前端(第一个元素相同?),返回 true
SListRange!(T,t) cons(T, Topology t)(T front, SListRange!(T,t) tail);
Prepends value to the root of the list. 从开始处添加值(root 根部)
BUG:
This function may fail to compile due to bug 2676.
这个函数也许会编译失败
4.30
struct Zip(R...) if (R.length && allSatisfy!(isInputRange,R));
Zip!(R) zip(R...)(R ranges);
Zip!(R) zip(R...)(StoppingPolicy sp, R ranges);
Iterate several ranges in lockstep. The element type is a proxy tuple that allows accessing the current element in the nth range by using e.at!(n).
在同步(lockstep)中重复几个 range 。元素类型是代理元组,使用 e.at!(n) 允许访问第 n 个 range 中的当前元素, ,
Example:
int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "b", "c" ];
// prints 1:a 2:b 3:c
foreach (e; zip(a, b))
{
write(e.at!(0), ':', e.at!(1), ' ');
}
Zip offers the lowest range facilities of all components, e.g. it offers random access iff all ranges offer random access, and also offers mutation and swapping if all ranges offer it. Due to this, Zip is extremely powerful because it allows manipulating several ranges in lockstep. For example, the following code sorts two arrays in parallel:
Zip 提供最小 range 的所有组件,例如,它提供了随机存取,同时还提供了转换(mutation) and 交换(swapping)。因此,zip 是极其强大的,它允许同步操作多个 range。例如,下面的代码并行索引两个数组:
int[] a = [ 1, 2, 3 ];
string[] b = [ "a", "b", "c" ];
sort!("a.at!(0) > b.at!(0)")(zip(a, b));
assert(a == [ 3, 2, 1 ]);
assert(b == [ "c", "b", "a" ]);
this(R rs, StoppingPolicy s = StoppingPolicy.shortest);
Builds an object. Usually this is invoked indirectly by using the std.range.zip function.
构建一个对象。使用 std.range.zip 函数间接调用。
bool empty();
Returns true if the range is at end. The test depends on the stopping policy.
假如 range 是在末尾,返回 true 。测试取决于stopping 策略。
Proxy front();
Returns a proxy for the current iterated element.
返回当前迭代元素的代理
Proxy back();
Returns a proxy for the rightmost element.
返回最右边元素的代理
void popFront();
Advances to the popFront element in all controlled ranges.
(在所有受控制的 range 里) 步进到 popFront 元素
void popBack();
Calls popBack for all controlled ranges.
调用 popBack( )
size_t length();
Returns the length of this range. Defined only if all ranges define length.
返回 range 的 length(长度)。所有的 range 都定义了 length 。
===================================================================
5.1 16点 更新 (完)
struct Recurrence(alias fun,StateType,size_t stateSize);
Recurrence!(fun,CommonType!(State),State.length) recurrence(alias fun, State...)(State initial);
Creates a mathematical sequence given the initial values and a recurrence function that computes the popFront value from the existing values. The sequence comes in the form of an infinite forward range. The type Recurrence itself is seldom used directly; most often, recurrences are obtained by calling the function recurrence.
从现有的值中创建一个数学序列,用给出的初始值和recurrence 函数 计算 popFront 值。Sequence 是 infinite forward range 的形式,这个类型很少被重复,经常被重复是由于调用 recurrence 函数
When calling recurrence, the function that computes the next value is specified as a template argument, and the initial values in the recurrence are passed as regular arguments. For example, in a Fibonacci sequence, there are two initial values (and therefore a state size of 2) because computing the popFront Fibonacci value needs the past two values.
当重复调用,该函数计算下一个 值 ,通过指定为一个模板参数和初始值 再次被作为定期参数传递。 例如在一个 斐波那契序列,有两个初始值 (,因此一 状态的大小是2) 因为计算 popFront 斐波那契值需要两个值。
If the function is passed in string form, the state has name "a" and the zero-based index in the recurrence has name "n". The given string must return the desired value for a[n] given a[n - 1], a[n - 2], a[n - 3],..., a[n - stateSize]. The state size is dictated by the number of arguments passed to the call to recurrence. The Recurrence class itself takes care of managing the recurrence's state and shifting it appropriately.
该函数是以传递字符串形式,状态名称 "a" 和在 recurrence中从零开始的索引名称 "n"。 给定字符串必须返回所需的值a[n] 给 a[n -1], a[n-2] , a[n-3] ,..., a[n-stateSize] 。 状态的大小是要传递给调用 recurrence 的参数的数量 。 在Recurrence类自己 管理 recurrence 的状态和适当地移动它。
Example:
// a[0] = 1, a[1] = 1, and compute a[n+1] = a[n-1] + a[n]
auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
// print the first 10 Fibonacci numbers
foreach (e; take(10, fib)) { writeln(e); }
// print the first 10 factorials
foreach (e; take(10, recurrence!("a[n-1] * n")(1))) { writeln(e); }
struct Sequence(alias fun,State);
Sequence!(fun,Tuple!(State)) sequence(alias fun, State...)(State args);
Sequence is similar to Recurrence except that iteration is presented in the so-called closed form. This means that the nth element in the series is computable directly from the initial values and n itself. This implies that the interface offered by Sequence is a random-access range, as opposed to the regular Recurrence, which only offers forward iteration.
序列是不重复的,迭代是以封闭的形式进行。这意味着,从初始值 到 N 的第 n 个元素是可计算的。这意味着,sequence 提供的接口是一个 random-access range ,不是反复重复
,而只是提供向前迭代。
The state of the sequence is stored as a Tuple so it can be heterogeneous.
序列的狀態被儲存為一元組,這樣它能是不同種類的。
Example:
// a[0] = 1, a[1] = 2, a[n] = a[0] + n * a[1]
auto odds = sequence!("a[0] + n * a[1]")(1, 2);
Take!(Sequence!("a.field[0] + n * a.field[1]",Tuple!(CommonType!(B,E),S))) iota(B, E, S)(B begin, E end, S step);
[color=blue]Take!(Sequence!("a.field[0] + n * a.field[1]",Tuple!(CommonType!(B,E),uint))) iota(B, E)(B begin, E end); [/color]
Returns a range that goes through the numbers begin, begin + step, begin + 2 * step, ..., up to and excluding end. The range offered is a random access range.[color=blue]The two-arguments version has step = 1。[/color]
通过一个数字返回 range ,执行 begin + step, begin + 2 * step, ... 并且排除尾端。这个 range 提供 random access range 。步长为1。
Example:
auto r = iota(0, 10, 1);
assert(equal(r, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9][]));
r = iota(0, 11, 3);
assert(equal(r, [0, 3, 6, 9][]));
assert(r[2] == 6);
[color=blue]enum TransverseOptions; 枚举 横截选项
Options for the FrontTransversal and Transversal ranges (below).
FrontTransversal 和 横截 range 选项如下:
assumeJagged 锯齿断言
When transversed, the elements of a range of ranges are assumed to have different lengths (e.g. a jagged array).
当transversed ,一系列 range 的元素被假定有不同的长度(如不规则阵列,或锯齿数组) 。
enforceNotJagged 强制无锯齿
The transversal enforces that the elements of a range of ranges have all the same length (e.g. an array of arrays, all having the same length). Checking is done once upon construction of the transversal range.
横向执行的一系列 range 的元素都有相同的长度(例如一个数组的数组,全都具有相同的长度)。
做一次检查后,构建 横截 range 。
assumeNotJagged 断言非锯齿
The transversal assumes, without verifying, that the elements of a range of ranges have all the same length. This option is useful if checking was already done from the outside of the range.
横向假设(断言),未经核实,一系列 range 的元素都一样长(range.length)。这个选项是有用的,如果是已经完成检查的 range 除外。
struct FrontTransversal(RangeOfRanges,TransverseOptions opt = TransverseOptions.assumeJagged);
FrontTransversal!(RangeOfRanges,opt) frontTransversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr);
Given a range of ranges, iterate transversally through the first elements of each of the enclosed ranges.
给定一系列 range,在每个封闭的 range 里,通过第一个元素 迭代横向(横向迭代?)(transversally)。
Example:
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = frontTransversal(x);
assert(equals(ror, [ 1, 3 ][]));
this(RangeOfRanges input);
Construction from an input.
通过 一个 input(RangeOfRanges 一种 range 类型) 构造。
bool empty();
ElementType front();
void popFront();
Forward range primitives.
Forward range 的基元(都有的函数)。
ElementType back();
void popBack();
Bidirectional primitives. They are offered if isBidirectionalRange!RangeOfRanges.
双向 基元 (双向 range 都有),如果他们提供isBidirectionalRange!RangeOfRanges (方法)。
ElementType opIndex(size_t n);
Random-access primitive. It is offered if isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).
随机存取基元,如果他们都提供 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).(方法)
struct Transversal(RangeOfRanges,TransverseOptions opt = TransverseOptions.assumeJagged);
Transversal!(RangeOfRanges,opt) transversal(TransverseOptions opt = TransverseOptions.assumeJagged, RangeOfRanges)(RangeOfRanges rr, size_t n);
Given a range of ranges, iterate transversally through the the nth element of each of the enclosed ranges. All elements of the enclosing range must offer random access.
给定一系列 range ,在每个封闭的 range 里,通过第 n 个元素 迭代横向(横向迭代?)。所有 range 的元素必须提供随机存取。
Example:
int[][] x = new int[][2];
x[0] = [1, 2];
x[1] = [3, 4];
auto ror = transversal(x, 1);
assert(equals(ror, [ 2, 4 ][]));
this(RangeOfRanges input, size_t n);
Construction from an input and an index.
通过 一个 input(RangeOfRanges 一种 range 类型) 和 一个 index 构造
bool empty();
ElementType front();
void popFront();
Forward range primitives.
Forward range 的基元(都有的函数)。
ElementType back();
Bidirectional primitives. They are offered if isBidirectionalRange!RangeOfRanges.
双向 基元 (双向 range 都有),如果他们提供 isBidirectionalRange!RangeOfRanges (方法)。
ElementType opIndex(size_t n);
Random-access primitive. It is offered if isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged).
随机存取基元 它如果提供 isRandomAccessRange!RangeOfRanges && (opt == TransverseOptions.assumeNotJagged || opt == TransverseOptions.enforceNotJagged) (方法)。 [/color]