multithread in C++ with Windows

Windowsのスレッド関係のAPIのラッパクラスを書いてみた。こんなことしなくてもpthreadやboost::threadあたり使えばいいんだけど、勉強のために。

#include <windows.h>
#include <cassert>
#include <process.h>

namespace multithread
{
  typedef unsigned (__stdcall * thread_func_t)(void *);

  // thread ----------------------------------------------------------------
  class thread
  {
    HANDLE m_handle;
    unsigned m_id;
    unsigned m_stack_size;

  public:
    // stack_sizeが0==1MB(Windowsの規定)
    thread(unsigned stack_size = 0)
      : m_handle(0),
        m_id(0),
        m_stack_size(stack_size)
    {}

    ~thread()
    {
      if(!!m_handle) CloseHandle(m_handle);
    }

    // 上手く実行できた場合、
    // または既に実行/生成している場合true
    bool start(thread_func_t thread_func, void * thread_arg)
    {
      if(!m_handle)
      {
        m_handle = 
          reinterpret_cast<HANDLE>
          (
            _beginthreadex(
              NULL,
              m_stack_size,
              thread_func,
              thread_arg,
              0,
              &m_id
            )
          );

        if(m_handle==0) return false;
      }

      return true;
    }

    // 上手く生成できた場合、
    // または既に実行/生成している場合true
    bool materialize(thread_func_t thread_func, void * thread_arg)
    {
      if(!m_handle)
      {
        m_handle = 
          reinterpret_cast<HANDLE>
          (
            _beginthreadex(
              NULL,
              m_stack_size,
              thread_func,
              thread_arg,
              CREATE_SUSPENDED,
              &m_id
            )
          );

        if(m_handle==0) return false;
      }

      return true;
    }

    // 情報取得
    // スレッドが生成済み/走っている場合true
    operator bool()
    {
      unsigned long result;
      return !!m_handle
          && (GetExitCodeThread(m_handle, &result)!=0)
          && (result==STILL_ACTIVE);
    }

    const unsigned id()
    {
      return m_id;
    }

    const int exitcode() const
    {
      unsigned long result;
      if(GetExitCodeThread(m_handle, &result)!=0) return result;
    }

    void priority(int new_priority) const
    {
      assert(-7 <= new_priority && new_priority < 7);

      SetThreadPriority(m_handle, new_priority);
    }
    const int priority() const
    {
      return GetThreadPriority(m_handle);
    }

    // 操作
    const unsigned suspend() const
    {
      return SuspendThread(m_handle);
    }
    const unsigned resume() const
    {
      return ResumeThread(m_handle);
    }

    void wait(const unsigned long time = INFINITE) const
    {
      WaitForSingleObject(m_handle, time);
    }

  private:
    thread(const thread &);
    const thread & operator=(const thread &);
  };
}

っていうか_beginthreadと_beginthreadexでインターフェイスやハンドルの後始末の方法とかが違うし、_MTマクロを定義(もしくはプロジェクト->設定でいじる)しないと使えないしでCreateThreadが恋しくなるんだけどなぁ…。VCのCRTライブラリ関係は腐っている、と解釈していいんだろうか?

critical sectionに関してはこれで。