std::unique_ptrをboost::optionalで改良する

`std::unique_ptr`、ちゃんと使っていますか？　ただ必要に応じてdeleteするだけでなく、デリータを自作することでscoped guardを実現することもできる素晴らしいクラスですが、scoped guardの思想を体現するには惜しい部分があります。
それは管理する型`pointer`に対して必要以上の要求を課すこと、すなわち[nullable pointer](http://en.cppreference.com/w/cpp/concept/NullablePointer)を要求することです。
これのせいで、何かリソースやハンドルなどポインタで定義されないものを`std::unique_ptr`で管理することはできません。せっかくカスタマイズできるのに。
nullable pointerは以下を満たす必要があります。
・EqualityComparable
・DefaultConstructible
・CopyConstructible
・CopyAssignable
・Destructible
加えて、`bool`型に変換可能で、全ての動作が例外を投げる可能性がない必要があります。また、`std::nullptr_t`型での初期化、`std::nullptr_t`型を代入すること、`std::nullptr_t`型との等価比較が可能でなければなりません。

しかし、完全なscoped guardクラスを実現するには、以下の条件だけで十分なはずです。
・CopyConstructible
・CopyAssignable
・NothrowDestructible

例外を投げないムーブがあるならコピーはできなくても大丈夫。
前置きが長くなりましたが、この記事ではこの不満を解消すべく、`std::unique_ptr`型を改良したより汎用的な`scoped_guard` クラスを作成したいと思います。
と言っても、`std::unique_ptr`のnullable pointer型の部分を別の自作型で置き換えればいいだけなのでそんな大層な仕事はしません。ここではそのnullable型に`boost::optional`を使うことにしました。

実装のコードの前に使い方のコードを示したいと思います。
型`resource`がよくあるリソースクラスです。リソースは決まった手順で取得して、決まった手順で解放しなければなりません。
`scoped_guard`にはテンプレート引数に管理する型と解放処理をする[Callable型](http://en.cppreference.com/w/cpp/concept/Callable)を必要とします。デリータはこのCallable型に変換可能でなければなりません。他はほとんど`std::unique_ptr`と同じように使えます。ただし、`get`や`reset`のオーバーロードの一部、比較演算子など不要になったメンバ関数が用意されていませんので注意してください。


```cpp
#include <utility>

// リソース
struct resource ;
resource get_resource() ;
void release_res(resource res) ;
void res_dosomething(resource res) ;


int main()
{
  using resource_type = scoped_guard< resource, void(*)(res) >;
  resource_type r(get_res(), &release_res); // 生成と解放

  if (r) { res_dosomething(*r); } // res_dosomethingが実行される。
  // auto r2 = r; // コピーは認められない
  auto r2 = std::move(r);         // 所有権が移譲される。
  if (r) { res_dosomething(*r); } // res_dosomethingは実行されない。

// res_dosomething(*r); // undefined behavior! 
}

```

以下が実装のコードです。実際に使う場合は名前空間をちゃんとつけてあげなければなりませんね。
せっかくboostを使っているのに`noncopyable`を自作しているのは、`boost::noncopyable`が色々と残念な仕様だからです。こちらで作った`noncopyable`はテンプレート引数に自分の型を突っ込んであげなければなりません。

```cpp
#include <utility>

#include <boost/optional.hpp>
#include <boost/operators.hpp>

// helpers
template< class T >
struct do_nothing { void operator()(const T&) noexcept {} };
template< class T >
class noncopyable
{
protected:
  noncopyable() = default;
  noncopyable(const noncopyable&) = delete;
  noncopyable& operator=(const noncopyable&) = delete;
  noncopyable(noncopyable&&) = default;
  noncopyable& operator=(noncopyable&&) = default;
  ~noncopyable() = default;
};

// forward declaration
template< class T, class D = do_nothing< T > >
class scoped_guard ;

// implement
template< class T, class D >
class scoped_guard
  : noncopyable< scoped_guard< T, D > >,
    public boost::dereferenceable< scoped_guard< T, D >, T* >
{
  boost::optional< T > element;
  D deleter;

  void release_element() noexcept { if (element) { deleter(*element); } }

public:
  using value_type = T;
  using reference = value_type&;
  using const_reference = const value_type&;
  using pointer = value_type*;
  using const_pointer = const value_type*;
  using optional_type = boost::optional< value_type >;
  using deleter_type = D;

  // ctors and dtor
  scoped_guard() = default;
  scoped_guard(const_reference value, deleter_type d = deleter_type())
    : element(value), deleter(d) {}
  scoped_guard(value_type&& value, deleter_type d = deleter_type())
    noexcept : element(std::move(value)), deleter(d) {}
  scoped_guard(scoped_guard&& rhs) noexcept
    : element(std::move(rhs.element)), deleter(std::move(rhs.deleter))
    { rhs.element = boost::none; }
  scoped_guard& operator=(scoped_guard&& rhs) noexcept
  {
    element = std::move(rhs.element);
    deleter = std::move(rhs.deleter);
    rhs.element = boost::none;
    return (*this);
  }
  ~scoped_guard() noexcept { release_element(); }

  // modifiers
  optional_type release() noexcept
  {
    auto temp = std::move(element);
    element = boost::none;
    return temp;
  }
  void reset(const_reference value)
  {
    release_element();
    element = value;
  }
  void reset(value_type&& value) noexcept
  {
    release_element();
    element = std::move(value);
  }
  void swap(scoped_guard& other) noexcept
  {
    auto temp = std::move(*this);
    *this = std::move(other);
    other = std::move(temp);
  }

  // observers
  deleter_type get_deleter() noexcept { return deleter; }
  explicit operator bool() const noexcept
    { return static_cast< bool >(element); }
  reference operator*() const noexcept
    { return *(const_cast< scoped_guard* >(this)->element); }
};

```


間違いや改善点などご指摘がございましたらコメントをお願いいたします。