X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FMemory.h;h=374f1e0ec377a532c4b3c699c2c476567260f95e;hb=c1ab48e4f588c0b6429cf741436cb7a794c92539;hp=6270cfab8194db5312873bf3c4789816b7976b9d;hpb=ce64f0f685111ac24c7a321ea56d0c3524621df1;p=folly.git diff --git a/folly/Memory.h b/folly/Memory.h index 6270cfab..374f1e0e 100644 --- a/folly/Memory.h +++ b/folly/Memory.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,25 +37,82 @@ namespace folly { * @author Xu Ning (xning@fb.com) */ -template, typename... Args> -typename std::enable_if::value, std::unique_ptr>::type +#if __cplusplus >= 201402L || \ + defined __cpp_lib_make_unique && __cpp_lib_make_unique >= 201304L + +/* using override */ using std::make_unique; + +#else + +template +typename std::enable_if::value, std::unique_ptr>::type make_unique(Args&&... args) { - return std::unique_ptr(new T(std::forward(args)...)); + return std::unique_ptr(new T(std::forward(args)...)); } // Allows 'make_unique(10)'. (N3690 s20.9.1.4 p3-4) -template> -typename std::enable_if::value, std::unique_ptr>::type +template +typename std::enable_if::value, std::unique_ptr>::type make_unique(const size_t n) { - return std::unique_ptr(new typename std::remove_extent::type[n]()); + return std::unique_ptr(new typename std::remove_extent::type[n]()); } // Disallows 'make_unique()'. (N3690 s20.9.1.4 p5) -template, typename... Args> +template typename std::enable_if< - std::extent::value != 0, std::unique_ptr>::type + std::extent::value != 0, std::unique_ptr>::type make_unique(Args&&...) = delete; +#endif + +/** + * static_function_deleter + * + * So you can write this: + * + * using RSA_deleter = folly::static_function_deleter; + * auto rsa = std::unique_ptr(RSA_new()); + * RSA_generate_key_ex(rsa.get(), bits, exponent, nullptr); + * rsa = nullptr; // calls RSA_free(rsa.get()) + * + * This would be sweet as well for BIO, but unfortunately BIO_free has signature + * int(BIO*) while we require signature void(BIO*). So you would need to make a + * wrapper for it: + * + * inline void BIO_free_fb(BIO* bio) { CHECK_EQ(1, BIO_free(bio)); } + * using BIO_deleter = folly::static_function_deleter; + * auto buf = std::unique_ptr(BIO_new(BIO_s_mem())); + * buf = nullptr; // calls BIO_free(buf.get()) + */ + +template +struct static_function_deleter { + void operator()(T* t) { f(t); } +}; + +/** + * to_shared_ptr + * + * Convert unique_ptr to shared_ptr without specifying the template type + * parameter and letting the compiler deduce it. + * + * So you can write this: + * + * auto sptr = to_shared_ptr(getSomethingUnique()); + * + * Instead of this: + * + * auto sptr = shared_ptr(getSomethingUnique()); + * + * Useful when `T` is long, such as: + * + * using T = foobar::cpp2::FooBarServiceAsyncClient; + */ +template +std::shared_ptr to_shared_ptr(std::unique_ptr&& ptr) { + return std::shared_ptr(std::move(ptr)); +} + /** * A SimpleAllocator must provide two methods: *