Last active
December 15, 2015 06:49
-
-
Save lichray/5219299 to your computer and use it in GitHub Desktop.
Modified from N3588, make_unique; a syntax enthusiast's work.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <type_traits> | |
#include <iostream> | |
#include <memory> | |
struct default_init_t {}; | |
default_init_t default_init; | |
template <typename T, typename = void> | |
struct make_unique; | |
template <typename T> | |
struct make_unique<T, typename std::enable_if< | |
not std::is_array<T>::value>::type> : std::unique_ptr<T> { | |
template <typename... Args> | |
make_unique(Args&&... args) : | |
std::unique_ptr<T>(new T(std::forward<Args>(args)...)) {} | |
make_unique(default_init_t) : | |
std::unique_ptr<T>(new T) {} | |
operator std::unique_ptr<T>() && { | |
return this; | |
} | |
}; | |
template <typename T> | |
struct make_unique<T, typename std::enable_if< | |
std::is_array<T>::value>::type> { | |
make_unique() : braced_(true) {} | |
make_unique(size_t n) : braced_(false), sz_(n) {} | |
make_unique(make_unique&&) = delete; | |
make_unique& operator=(make_unique&&) = delete; | |
template <typename... Args> | |
auto operator()(Args&&... args) && -> std::unique_ptr<T> { | |
typedef typename std::remove_extent<T>::type U; | |
return std::unique_ptr<T>(braced_ ? | |
new U[sizeof...(Args)]{ std::forward<Args>(args)... } : | |
new U[sz_]{ std::forward<Args>(args)... }); | |
} | |
auto operator()(default_init_t) && -> std::unique_ptr<T> { | |
typedef typename std::remove_extent<T>::type U; | |
return std::unique_ptr<T>(new U[sz_]); | |
} | |
private: | |
bool braced_; | |
size_t sz_; | |
}; | |
// STL's tests | |
using namespace std; | |
void print(const unique_ptr<int[]>& up) { | |
for (int i = 0; i < 5; ++i) { | |
cout << up[i] << " "; | |
} | |
cout << endl; | |
} | |
void f(unique_ptr<int>) {} | |
int main() { | |
cout << *make_unique<int>() << endl; | |
cout << *make_unique<int>(1729) << endl; | |
cout << "\"" << *make_unique<string>() << "\"" << endl; | |
cout << "\"" << *make_unique<string>("meow") << "\"" << endl; | |
cout << "\"" << *make_unique<string>(6, 'z') << "\"" << endl; | |
cout << *make_unique<int>(default_init) << endl; | |
cout << "\"" << *make_unique<string>(default_init) << "\"" << endl; | |
print(make_unique<int[]>{5}()); | |
print(make_unique<int[]>{5}(default_init)); | |
print(make_unique<int[]>{5}(100, 200, 300)); | |
print(make_unique<int[]>{}(111, 222, 333, 444, 555)); | |
f(make_unique<int>(3)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment