get_message_iterator

なんとなくWindowsのメッセージループを反復子にするアイデアを思いついたので書いてみました。
役に立つかは不明です。
以下、コード。

#include <boost/iterator/iterator_facade.hpp>
#include <stdexcept>
#include <windows.h>

// A/W切り分け用
template<class CharT>
struct window_message_traits;

template<>
struct window_message_traits<char>
{
    static ::BOOL get_message(
        ::MSG& msg, ::HWND hwnd, ::UINT min_msg, ::UINT max_msg)
    {
        return ::GetMessageA(&msg, hwnd, min_msg, max_msg);
    }

    static ::LRESULT dispatch_message(const ::MSG& msg)
    {
        return ::DispatchMessageA(&msg);
    }
};

template<>
struct window_message_traits<wchar_t>
{
    static ::BOOL get_message(
        ::MSG& msg, ::HWND hwnd, ::UINT min_msg, ::UINT max_msg)
    {
        return ::GetMessageW(&msg, hwnd, min_msg, max_msg);
    }

    static ::LRESULT dispatch_message(const ::MSG& msg)
    {
        return ::DispatchMessageW(&msg);
    }
};

// GetMessage()する反復子
template<class CharT=char>
class get_message_iterator
    : public boost::iterator_facade<
        get_message_iterator<CharT>,
        const ::MSG,
        boost::single_pass_traversal_tag
    >
{
    friend class boost::iterator_core_access;

public:
    get_message_iterator() : hwnd_(0), min_(0), max_(0)
    {
        msg_.message = WM_QUIT;
    }

    explicit get_message_iterator(::HWND hwnd)
        : hwnd_(hwnd), min_(0), max_(0)
    {
        increment();
    }

    get_message_iterator(::HWND hwnd, ::UINT min_msg, ::UINT max_msg)
        : hwnd_(hwnd), min_(min_msg), max_(max_msg)
    {
        increment();
    }

private:
    ::MSG msg_;
    ::HWND hwnd_;
    ::UINT min_;
    ::UINT max_;

    const ::MSG& dereference() const
    {
        return msg_;
    }

    void increment()
    {
        typedef window_message_traits<CharT> traits;
        ::BOOL res = traits::get_message(msg_, hwnd_, min_, max_);
        if (res == -1)
            throw std::runtime_error("GetMessage() failed");
    }

    bool equal(const get_message_iterator& rhs) const
    {
        return msg_.message == rhs.msg_.message;
    }
};

// DispatchMessage()する反復子
template <class CharT=char>
struct dispatch_message_iterator
    : public std::iterator<std::output_iterator_tag,void,void,void,void>
{
    dispatch_message_iterator()
    {
    }

    dispatch_message_iterator& operator=(const ::MSG& msg)
    {
        typedef window_message_traits<CharT> traits;
        traits::dispatch_message(msg);
        return *this;
    }

    dispatch_message_iterator& operator*()
    {
        return *this;
    }

    dispatch_message_iterator& operator++()
    {
        return *this;
    }

    dispatch_message_iterator& operator++(int)
    {
        return *this;
    }
};

// TranslateMessage()して、素通しするファンクタ
struct translate_message
{
    ::MSG operator()(const ::MSG& msg) const
    {
        ::TranslateMessage(&msg);
        return msg;
    }
};

// お試し
#include <algorithm>
#include <iostream>

int main()
{
    try
    {
        ::PostQuitMessage(0);

        std::transform(
            get_message_iterator<>(0),
            get_message_iterator<>(),
            dispatch_message_iterator<>(),
            translate_message()
        );
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}