C++11 の make_shared を拡張する

# 概要
`std::make_shared<T>` は `std::shared_ptr<T>` を生成するヘルパ関数です。
ユーザーオブジェクトと参照カウンタをまとめて生成するので、より効率的にメモリ確保してくれます。

しかし、全てこれで生成すればいいというわけではありません。
いくつか落とし穴や制限があります。

* 型 T のコンストラクタが公開されていないと、コンパイルエラーになる。
* カスタムデリータ、カスタムアロケータが指定できない。

勿論それぞれ回避策はありますが、いちいち書くのも面倒ですので、それらを回避する関数を作りましょう。
ついでに、C++11 に無い `make_unique` も実装してしまいましょう。

# 仕様
## `template <class T, typename... Args> std::shared_ptr<T> make_shared(Args&&... args)`
`std::make_shared<T>` とほぼ同じ働きをします。
唯一違うのは、型 T のコンストラクタが公開されていなくても、コンパイルエラーにならないことです。
ファクトリの実装が捗りますね。

### `template <class T, class Deleter, typename... Args> std::shared_ptr<T> make_shared(custom_deleter, Deleter d, Args&&... args)`
タグディスパッチによる、カスタムデリータ指定版です。
残念ながら、内部的には単に new してカスタムデリータを渡しているだけなので、本来の `std::make_shared<T>` の恩恵は受けられません。

### `template <class T, class Deleter, class Alloc, typename... Args> std::shared_ptr<T> make_shared(custom_full, Deleter d, Alloc a, Args&&... args)`
同じく、タグディスパッチによる、カスタムデリータとアロケータ指定版です。
注意点も同じです。

## `template <class T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args)`
`std::make_shared<T>` の `std::unique_ptr<T>` 版です。
C++14 での `std::make_unique<T>` とインターフェイスは同じですが、内部的には単に new しているだけです。
故に効率的なメモリ確保の恩恵は受けられませんが、書式を統一しておけば後々いくらでも調整できるでしょう。

### `template <class T, class Deleter, typename... Args> std::unique_ptr<T> make_unique(custom_deleter, Deleter d, Args&&... args)`
タグディスパッチによる、カスタムデリータ指定版です。
ベースになっている `make_unique<T>` と実装はほぼ同じなので、特に注意点はありません。


# 実装
名前空間 sub 内に各種関数を実装します。

```cpp:sub_memory.hpp
#ifndef SUB_MEMORY_HPP_
#define SUB_MEOMRY_HPP_

#include <memory>

namespace sub {

namespace {

// ctor を public にするためだけの継承クラス
template <class T>
struct _derived : public T {
    template <typename... Args>
    _derived(Args&&... args) : T(std::forward<Args>(args)...) {}
};

} // namespace

// カスタムデリータ使用タグ
struct custom_deleter {};

// カスタムデリータ、アロケータ使用タグ
struct custom_full {};

// make_shared 拡張版 カスタムデリータ指定
template <class T, class Deleter, typename... Args>
std::shared_ptr<T> make_shared(custom_deleter, Deleter d, Args&&... args) {
    return std::move(std::shared_ptr<T>(new _derived<T>(std::forward<Args>(args)...), d));
}

// make_shared 拡張版 カスタムデリータ、アロケータ指定
template <class T, class Deleter, class Alloc, typename... Args>
std::shared_ptr<T> make_shared(custom_full, Deleter d, Alloc a, Args&&... args) {
    return std::move(std::shared_ptr<T>(new _derived<T>(std::forward<Args>(args)...), d, a));
}

// make_shared 拡張版
template <class T, typename... Args>
std::shared_ptr<T> make_shared(Args&&... args) {
    return std::move(std::make_shared<_derived<T>>(std::forward<Args>(args)...));
}

// make_unique(C++14) 拡張版 カスタム
template <class T, class Deleter, typename... Args>
std::unique_ptr<T> make_unique(custom_deleter, Deleter d, Args&&... args) {
    return std::move(std::unique_ptr<T>(new _derived<T>(std::forward<Args>(args)...), d));
}

// make_unique(C++14) 拡張版
template <class T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::move(std::unique_ptr<T>(new _derived<T>(std::forward<Args>(args)...)));
}

} // namespace sub

#endif // SUB_MEMORY_HPP_
```

# テスト
コンストラクタを公開しないクラスを定義し、実装した関数に渡してみましょう。

## ソース
```cpp:sub_memory-test.cpp
#include <stdio.h>
#include <string>
#include "sub_memory.hpp"

// ctor が公開されていない適当なクラス
class foo {
public:
    ~foo() { printf("~foo()\n"); }
    void f() { printf("f() "); }
    
protected:
    foo() { printf("foo() "); }
    foo(int i) { printf("foo(%d) ", i); }
    foo(std::string &str) {
        printf("foo(%s) ", str.empty() ? "*empty*" : str.c_str());
    }
};

int main() {
    // ctor が公開されていないので直接インスタンス化はできない
#if 0
    foo a;
    foo *p = new foo();
#endif
    
    // make_shared + 引数なし
    printf("0: ");
    if (auto it = sub::make_shared<foo>()) {
        printf("shared ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    // make_shared + 引数あり
    printf("1: ");
    if (auto it = sub::make_shared<foo>(1234)) {
        printf("shared ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    // make_shared + 引数あり + カスタムデリータ
    printf("2: ");
    if (auto it = sub::make_shared<foo>(sub::custom_deleter(), std::default_delete<foo>(), 456)) {
        printf("shared custom_deleter ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    // make_shared + 引数あり + カスタムデリータ + カスタムアロケータ
    printf("3: ");
    if (auto it = sub::make_shared<foo>(sub::custom_full(), std::default_delete<foo>(), std::allocator<void>(), 789)) {
        printf("shared custom_full ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    // make_unique + 引数なし
    printf("4: ");
    if (auto it = sub::make_unique<foo>()) {
        printf("unique ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }

    // make_unique + 引数あり（参照）
    printf("5: ");
    std::string str("bar");
    if (auto it = sub::make_unique<foo>(str)) {
        printf("unique ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    // make_unique + 引数あり（コピー）
    printf("6: ");
#if 0
    // コピー渡し ctor が用意されていないのでコンパイルエラー
    if (auto it = sub::make_unique<foo>(std::string("baz"))) {
        printf("unique ");
        it->f();
#else
    if (false) {
#endif
    } else {
        printf("*** error ***\n");
    }
    
    // make_unique + 引数あり + カスタムデリータ
    printf("7: ");
    if (auto it = sub::make_unique<foo>(sub::custom_deleter(), std::default_delete<foo>(), 42)) {
        printf("unique custom_deleter ");
        it->f();
        
    } else {
        printf("*** error ***\n");
    }
    
    return 0;
}
```

## 出力
以下のように出力されます。

```
0: foo() shared f() ~foo()
1: foo(1234) shared f() ~foo()
2: foo(456) shared custom_deleter f() ~foo()
3: foo(789) shared custom_full f() ~foo()
4: foo() unique f() ~foo()
5: foo(bar) unique f() ~foo()
6: *** error ***
7: foo(42) unique custom_deleter f() ~foo()
```

# 課題
## カスタムデリータやアロケータの指定をもっとスマートに出来ないか
現在タグディスパッチを使っていますが、関数の名前を変えるだけでもよかったかもしれません。
よりよい実装方法があれば教えて頂けると助かります。

## 名前空間をもっとかっこよく
とりあえず sub にしましたが、あまりクールではありません。
物凄くどうでもいいですし、組み込む際に各々が変えればいいですが、もっといい名前があれば教えてください。

## その他
実装やテストで気が付いたことがあればご意見頂けると幸いです。