DirectInputデバイスの列挙

PNGを表示できたので次は移動です。
ゲームパッドで操作できるようにしようと思い、DirectInputのラッパーを書き始めました。
とりあえず、Hamigaki.Coroutineを使ってデバイスの列挙をしてみました。

// 反復子の要素型
typedef ::DIDEVICEINSTANCEA device_info;

// デバイス列挙用反復子
typedef hamigaki::coroutines::generator<
    device_info
> device_info_iterator;

class direct_input2 : private boost::noncopyable
{
public:
    explicit direct_input2(::HINSTANCE hInstance);
    ~direct_input2();

    // 反復子取得関数
    std::pair<device_info_iterator,device_info_iterator>
    device_info_range(unsigned long type, unsigned long flags)
    {
        return std::pair<device_info_iterator,device_info_iterator>(
            device_info_iterator(
                boost::bind(
                    &direct_input2::enum_devices, this, _1, type, flags
                )
            ),
            device_info_iterator()
        );
    }

private:
    ::IDirectInput2A* pimpl_;

    // EnumDevices()のコールバック関数
    static int __stdcall enum_devices_callback(
        const device_info* lpddi, void* pvRef)
    {
        try
        {
            device_info_iterator::self& self =
                *reinterpret_cast<device_info_iterator::self*>(pvRef);

            self.yield(*lpddi);

            return TRUE;
        }
        catch (...)
        {
        }

        return FALSE;
    }

    // コルーチンのエントリ関数
    device_info enum_devices(
        device_info_iterator::self& self,
        unsigned long type, unsigned long flags
    )
    {
        ::HRESULT res =
            pimpl_->EnumDevices(type, &enum_devices_callback, &self, flags);
        if (FAILED(res))
            throw directx9_error(res, "IDirectInput2A::EnumDevices()");

        self.exit();
        HAMIGAKI_COROUTINE_UNREACHABLE_RETURN(device_info())
    }
};

DirectSoundの時とほぼ同じです。
列挙用の関数がメンバ関数であることと、引数があることが違うぐらいです。
最新のDirectInput8を使いたかったのですが、Cygwin/MinGW用のヘッダがDirectX5相当のもので、仕方なくDirectInput2を使っています。
使い方はこうなります。

// DirectInputオブジェクトを作成
direct_input::direct_input2 di(hInstance);

// device_info_iteratorの対を取得
typedef direct_input::device_info_iterator iter_type;
iter_type beg, end;
boost::tie(beg,end) =
    di.device_info_range(DIDEVTYPE_JOYSTICK, DIEDFL_ALLDEVICES);

// インスタンス名を出力してみる
for (; beg != end; ++beg)
    std::cout << beg->tszInstanceName << std::endl;

ごく普通の反復子です。