Enum系関数とiterator
iteratorの作り方を覚えると、列挙できるものは何でもiteratorにしたくなります。特に、Boost.Iteratorを使うとiteratorの作成が劇的に簡単になるため、なおさらです。しかし、DirectXで採用されているEnum系の関数(Enum〜、〜Enumerate)はiteratorモデルにマッチしません。
例えば、DirectSoundEnumerate()は次のような関数です。
HRESULT WINAPI DirectSoundEnumerate( LPDSENUMCALLBACK lpDSEnumCallback, LPVOID lpContext );
ここで、lpDSEnumCallbackはDirectSoundEnumerate()からコールバックされる関数で、デバイスの数だけ繰り返し呼ばれます。(途中で中断することもできます。)
この列挙には、
- どんな順序で列挙されるか分からない
- 列挙の順序は一方向
- 読み出し専用
といった特徴があります。
この制約の中で利用できそうなアルゴリズムは、
- for_each()
- find()
- count()
- copy()
- transform()
- replace_copy()
- remove_copy()
- accumulate()
- inner_product()
ぐらいかと思います。動きはしますが、count()やinner_product()なんかは、あまり役には立たないでしょう。実際の利用状況を考えると、
ができれば十分だと思います。となると、copy()とfind()に相当する操作を提供するだけで事足りるのです。
もちろん、一旦全てのデバイス情報をコピーすれば、iteratorを提供するのは簡単ですし、スレッドを駆使すれば無理やり実装することも可能でしょうが、得られるものは少ないかと思います。