単純増加のループ処理
C++03
for (int i = 0; i < 5; i++) {
// ...
}
を範囲forにしたとき
C++11
for (auto i : range<int>(5)) {
// ...
}
みたいな実行効率を考えた range クラス相当は既にあるだろうと思ったのですが、軽く検索すると int[] や vec などに [a] = a を代入してから使用しているものしか見つけられませんでした。真面目に探せば実行効率を考えたものは必ず出てくると思いますが、ざっくりと書いてみた。(コンパイラの最適化をかなり当てにしています)
sample.cpp
#include <iostream>
template <typename T>
struct range {
struct iterator {
T value;
iterator(T n) : value(n) {}
T operator *() { return value; }
void operator ++() { ++value; }
bool operator !=(iterator &rhs) { return value != rhs.value; }
};
T _start, _end;
range(T count) : _start(0), _end(count) {}
range(T start, T end) : _start(start), _end(end) {}
iterator begin() { return iterator(_start); }
iterator end() { return iterator(_end); }
};
int main()
{
std::cout << "range(5):";
for (const auto i : range<int>(5))
std::cout << " " << i;
std::cout << std::endl;
std::cout << "range(2, 7):";
for (const auto i : range<size_t>(2, 7))
std::cout << " " << i;
std::cout << std::endl;
}
実行結果
range(5): 0 1 2 3 4
range(2, 7): 2 3 4 5 6
Apple clang version 15.0.0 (clang-1500.3.9.4)[x86_64] を使い
$ clang++ -std=c++11 sample.cpp -O -S
で出力したアセンブラの一部を抜粋
range(5)のループ部
xorl %r14d, %r14d
leaq L_.str.1(%rip), %r15
.p2align 4, 0x90
LBB0_1: ## =>This Inner Loop Header: Depth=1
movl $1, %edx
movq %rbx, %rdi
movq %r15, %rsi
callq __ZNSt3__124__put_character_sequenceB8ue170006IcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
movq %rax, %rdi
movl %r14d, %esi
callq __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEi
incl %r14d
cmpl $5, %r14d
jne LBB0_1
変数 i は r14d レジスタで完結しています。