fix a multiline comment warning
[folly.git] / folly / Memory.h
1 /*
2  * Copyright 2013-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <cassert>
20 #include <cerrno>
21 #include <cstddef>
22 #include <cstdlib>
23 #include <exception>
24 #include <limits>
25 #include <memory>
26 #include <stdexcept>
27 #include <type_traits>
28 #include <utility>
29
30 #include <folly/Traits.h>
31 #include <folly/functional/Invoke.h>
32 #include <folly/portability/Config.h>
33 #include <folly/portability/Malloc.h>
34
35 namespace folly {
36
37 #if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || \
38     (defined(__ANDROID__) && (__ANDROID_API__ > 15)) ||   \
39     (defined(__APPLE__) &&                                \
40      (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_6 ||    \
41       __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_3_0))
42
43 inline void* aligned_malloc(size_t size, size_t align) {
44   // use posix_memalign, but mimic the behaviour of memalign
45   void* ptr = nullptr;
46   int rc = posix_memalign(&ptr, align, size);
47   return rc == 0 ? (errno = 0, ptr) : (errno = rc, nullptr);
48 }
49
50 inline void aligned_free(void* aligned_ptr) {
51   free(aligned_ptr);
52 }
53
54 #elif defined(_WIN32)
55
56 inline void* aligned_malloc(size_t size, size_t align) {
57   return _aligned_malloc(size, align);
58 }
59
60 inline void aligned_free(void* aligned_ptr) {
61   _aligned_free(aligned_ptr);
62 }
63
64 #else
65
66 inline void* aligned_malloc(size_t size, size_t align) {
67   return memalign(align, size);
68 }
69
70 inline void aligned_free(void* aligned_ptr) {
71   free(aligned_ptr);
72 }
73
74 #endif
75
76 /**
77  * For exception safety and consistency with make_shared. Erase me when
78  * we have std::make_unique().
79  *
80  * @author Louis Brandy (ldbrandy@fb.com)
81  * @author Xu Ning (xning@fb.com)
82  */
83
84 #if __cplusplus >= 201402L || __cpp_lib_make_unique >= 201304L || \
85     (__ANDROID__ && __cplusplus >= 201300L) || _MSC_VER >= 1900
86
87 /* using override */ using std::make_unique;
88
89 #else
90
91 template <typename T, typename... Args>
92 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
93 make_unique(Args&&... args) {
94   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
95 }
96
97 // Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
98 template <typename T>
99 typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
100 make_unique(const size_t n) {
101   return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
102 }
103
104 // Disallows 'make_unique<T[10]>()'. (N3690 s20.9.1.4 p5)
105 template <typename T, typename... Args>
106 typename std::enable_if<
107   std::extent<T>::value != 0, std::unique_ptr<T>>::type
108 make_unique(Args&&...) = delete;
109
110 #endif
111
112 /**
113  * static_function_deleter
114  *
115  * So you can write this:
116  *
117  *      using RSA_deleter = folly::static_function_deleter<RSA, &RSA_free>;
118  *      auto rsa = std::unique_ptr<RSA, RSA_deleter>(RSA_new());
119  *      RSA_generate_key_ex(rsa.get(), bits, exponent, nullptr);
120  *      rsa = nullptr;  // calls RSA_free(rsa.get())
121  *
122  * This would be sweet as well for BIO, but unfortunately BIO_free has signature
123  * int(BIO*) while we require signature void(BIO*). So you would need to make a
124  * wrapper for it:
125  *
126  *      inline void BIO_free_fb(BIO* bio) { CHECK_EQ(1, BIO_free(bio)); }
127  *      using BIO_deleter = folly::static_function_deleter<BIO, &BIO_free_fb>;
128  *      auto buf = std::unique_ptr<BIO, BIO_deleter>(BIO_new(BIO_s_mem()));
129  *      buf = nullptr;  // calls BIO_free(buf.get())
130  */
131
132 template <typename T, void(*f)(T*)>
133 struct static_function_deleter {
134   void operator()(T* t) const {
135     f(t);
136   }
137 };
138
139 /**
140  *  to_shared_ptr
141  *
142  *  Convert unique_ptr to shared_ptr without specifying the template type
143  *  parameter and letting the compiler deduce it.
144  *
145  *  So you can write this:
146  *
147  *      auto sptr = to_shared_ptr(getSomethingUnique<T>());
148  *
149  *  Instead of this:
150  *
151  *      auto sptr = shared_ptr<T>(getSomethingUnique<T>());
152  *
153  *  Useful when `T` is long, such as:
154  *
155  *      using T = foobar::FooBarAsyncClient;
156  */
157 template <typename T, typename D>
158 std::shared_ptr<T> to_shared_ptr(std::unique_ptr<T, D>&& ptr) {
159   return std::shared_ptr<T>(std::move(ptr));
160 }
161
162 /**
163  *  to_weak_ptr
164  *
165  *  Make a weak_ptr and return it from a shared_ptr without specifying the
166  *  template type parameter and letting the compiler deduce it.
167  *
168  *  So you can write this:
169  *
170  *      auto wptr = to_weak_ptr(getSomethingShared<T>());
171  *
172  *  Instead of this:
173  *
174  *      auto wptr = weak_ptr<T>(getSomethingShared<T>());
175  *
176  *  Useful when `T` is long, such as:
177  *
178  *      using T = foobar::FooBarAsyncClient;
179  */
180 template <typename T>
181 std::weak_ptr<T> to_weak_ptr(const std::shared_ptr<T>& ptr) {
182   return std::weak_ptr<T>(ptr);
183 }
184
185 struct SysBufferDeleter {
186   void operator()(void* p) const {
187     ::free(p);
188   }
189 };
190
191 using SysBufferUniquePtr = std::unique_ptr<void, SysBufferDeleter>;
192 inline SysBufferUniquePtr allocate_sys_buffer(size_t size) {
193   return SysBufferUniquePtr(::malloc(size));
194 }
195
196 /**
197  * A SimpleAllocator must provide two methods:
198  *
199  *    void* allocate(size_t size);
200  *    void deallocate(void* ptr);
201  *
202  * which, respectively, allocate a block of size bytes (aligned to the
203  * maximum alignment required on your system), throwing std::bad_alloc
204  * if the allocation can't be satisfied, and free a previously
205  * allocated block.
206  *
207  * SysAlloc resembles the standard allocator.
208  */
209 class SysAlloc {
210  public:
211   void* allocate(size_t size) {
212     void* p = ::malloc(size);
213     if (!p) {
214       throw std::bad_alloc();
215     }
216     return p;
217   }
218   void deallocate(void* p) {
219     ::free(p);
220   }
221 };
222
223 /**
224  * StlAllocator wraps a SimpleAllocator into a STL-compliant
225  * allocator, maintaining an instance pointer to the simple allocator
226  * object.  The underlying SimpleAllocator object must outlive all
227  * instances of StlAllocator using it.
228  *
229  * But note that if you pass StlAllocator<MallocAllocator,...> to a
230  * standard container it will be larger due to the contained state
231  * pointer.
232  *
233  * @author: Tudor Bosman <tudorb@fb.com>
234  */
235
236 // This would be so much simpler with std::allocator_traits, but gcc 4.6.2
237 // doesn't support it.
238 template <class Alloc, class T> class StlAllocator;
239
240 template <class Alloc> class StlAllocator<Alloc, void> {
241  public:
242   typedef void value_type;
243   typedef void* pointer;
244   typedef const void* const_pointer;
245
246   StlAllocator() : alloc_(nullptr) { }
247   explicit StlAllocator(Alloc* a) : alloc_(a) { }
248
249   Alloc* alloc() const {
250     return alloc_;
251   }
252
253   template <class U> struct rebind {
254     typedef StlAllocator<Alloc, U> other;
255   };
256
257   bool operator!=(const StlAllocator<Alloc, void>& other) const {
258     return alloc_ != other.alloc_;
259   }
260
261   bool operator==(const StlAllocator<Alloc, void>& other) const {
262     return alloc_ == other.alloc_;
263   }
264
265  private:
266   Alloc* alloc_;
267 };
268
269 template <class Alloc, class T>
270 class StlAllocator {
271  public:
272   typedef T value_type;
273   typedef T* pointer;
274   typedef const T* const_pointer;
275   typedef T& reference;
276   typedef const T& const_reference;
277
278   typedef ptrdiff_t difference_type;
279   typedef size_t size_type;
280
281   StlAllocator() : alloc_(nullptr) { }
282   explicit StlAllocator(Alloc* a) : alloc_(a) { }
283
284   template <class U> StlAllocator(const StlAllocator<Alloc, U>& other)
285     : alloc_(other.alloc()) { }
286
287   T* allocate(size_t n, const void* /* hint */ = nullptr) {
288     return static_cast<T*>(alloc_->allocate(n * sizeof(T)));
289   }
290
291   void deallocate(T* p, size_t /* n */) { alloc_->deallocate(p); }
292
293   size_t max_size() const {
294     return std::numeric_limits<size_t>::max();
295   }
296
297   T* address(T& x) const {
298     return std::addressof(x);
299   }
300
301   const T* address(const T& x) const {
302     return std::addressof(x);
303   }
304
305   template <class... Args>
306   void construct(T* p, Args&&... args) {
307     new (p) T(std::forward<Args>(args)...);
308   }
309
310   void destroy(T* p) {
311     p->~T();
312   }
313
314   Alloc* alloc() const {
315     return alloc_;
316   }
317
318   template <class U> struct rebind {
319     typedef StlAllocator<Alloc, U> other;
320   };
321
322   bool operator!=(const StlAllocator<Alloc, T>& other) const {
323     return alloc_ != other.alloc_;
324   }
325
326   bool operator==(const StlAllocator<Alloc, T>& other) const {
327     return alloc_ == other.alloc_;
328   }
329
330  private:
331   Alloc* alloc_;
332 };
333
334 /**
335  * Helper function to obtain rebound allocators
336  *
337  * @author: Marcelo Juchem <marcelo@fb.com>
338  */
339 template <typename T, typename Allocator>
340 typename Allocator::template rebind<T>::other rebind_allocator(
341   Allocator const& allocator
342 ) {
343   return typename Allocator::template rebind<T>::other(allocator);
344 }
345
346 /*
347  * Helper classes/functions for creating a unique_ptr using a custom
348  * allocator.
349  *
350  * @author: Marcelo Juchem <marcelo@fb.com>
351  */
352
353 // Derives from the allocator to take advantage of the empty base
354 // optimization when possible.
355 template <typename Allocator>
356 class allocator_delete
357   : private std::remove_reference<Allocator>::type
358 {
359   typedef typename std::remove_reference<Allocator>::type allocator_type;
360
361  public:
362   typedef typename Allocator::pointer pointer;
363
364   allocator_delete() = default;
365
366   explicit allocator_delete(const allocator_type& allocator)
367     : allocator_type(allocator)
368   {}
369
370   explicit allocator_delete(allocator_type&& allocator)
371     : allocator_type(std::move(allocator))
372   {}
373
374   template <typename U>
375   allocator_delete(const allocator_delete<U>& other)
376     : allocator_type(other.get_allocator())
377   {}
378
379   allocator_type& get_allocator() const {
380     return *const_cast<allocator_delete*>(this);
381   }
382
383   void operator()(pointer p) const {
384     if (!p) {
385       return;
386     }
387     const_cast<allocator_delete*>(this)->destroy(p);
388     const_cast<allocator_delete*>(this)->deallocate(p, 1);
389   }
390 };
391
392 namespace detail {
393
394 FOLLY_CREATE_MEMBER_INVOKE_TRAITS(destroy_invoke_traits, destroy);
395
396 } // namespace detail
397
398 template <typename Allocator, typename Value>
399 using is_simple_allocator =
400     Negation<detail::destroy_invoke_traits::is_invocable<Allocator, Value*>>;
401
402 template <typename T, typename Allocator>
403 struct as_stl_allocator {
404   typedef typename std::conditional<
405     is_simple_allocator<
406       typename std::remove_reference<Allocator>::type,
407       typename std::remove_reference<T>::type
408     >::value,
409     folly::StlAllocator<
410       typename std::remove_reference<Allocator>::type,
411       typename std::remove_reference<T>::type
412     >,
413     typename std::remove_reference<Allocator>::type
414   >::type type;
415 };
416
417 template <typename T, typename Allocator>
418 typename std::enable_if<
419   is_simple_allocator<
420     typename std::remove_reference<Allocator>::type,
421     typename std::remove_reference<T>::type
422   >::value,
423   folly::StlAllocator<
424     typename std::remove_reference<Allocator>::type,
425     typename std::remove_reference<T>::type
426   >
427 >::type make_stl_allocator(Allocator&& allocator) {
428   return folly::StlAllocator<
429     typename std::remove_reference<Allocator>::type,
430     typename std::remove_reference<T>::type
431   >(&allocator);
432 }
433
434 template <typename T, typename Allocator>
435 typename std::enable_if<
436   !is_simple_allocator<
437     typename std::remove_reference<Allocator>::type,
438     typename std::remove_reference<T>::type
439   >::value,
440   typename std::remove_reference<Allocator>::type
441 >::type make_stl_allocator(Allocator&& allocator) {
442   return std::move(allocator);
443 }
444
445 /**
446  * AllocatorUniquePtr: a unique_ptr that supports both STL-style
447  * allocators and SimpleAllocator
448  *
449  * @author: Marcelo Juchem <marcelo@fb.com>
450  */
451
452 template <typename T, typename Allocator>
453 struct AllocatorUniquePtr {
454   typedef std::unique_ptr<T,
455     folly::allocator_delete<
456       typename std::conditional<
457         is_simple_allocator<
458           typename std::remove_reference<Allocator>::type,
459           typename std::remove_reference<T>::type
460         >::value,
461         folly::StlAllocator<typename std::remove_reference<Allocator>::type, T>,
462         typename std::remove_reference<Allocator>::type
463       >::type
464     >
465   > type;
466 };
467
468 /**
469  * Functions to allocate a unique_ptr / shared_ptr, supporting both
470  * STL-style allocators and SimpleAllocator, analog to std::allocate_shared
471  *
472  * @author: Marcelo Juchem <marcelo@fb.com>
473  */
474
475 template <typename T, typename Allocator, typename ...Args>
476 typename AllocatorUniquePtr<T, Allocator>::type allocate_unique(
477   Allocator&& allocator, Args&&... args
478 ) {
479   auto stlAllocator = folly::make_stl_allocator<T>(
480     std::forward<Allocator>(allocator)
481   );
482   auto p = stlAllocator.allocate(1);
483
484   try {
485     stlAllocator.construct(p, std::forward<Args>(args)...);
486
487     return {p,
488       folly::allocator_delete<decltype(stlAllocator)>(std::move(stlAllocator))
489     };
490   } catch (...) {
491     stlAllocator.deallocate(p, 1);
492     throw;
493   }
494 }
495
496 template <typename T, typename Allocator, typename ...Args>
497 std::shared_ptr<T> allocate_shared(Allocator&& allocator, Args&&... args) {
498   return std::allocate_shared<T>(
499     folly::make_stl_allocator<T>(std::forward<Allocator>(allocator)),
500     std::forward<Args>(args)...
501   );
502 }
503
504 /**
505  * IsArenaAllocator<T>::value describes whether SimpleAllocator has
506  * no-op deallocate().
507  */
508 template <class T> struct IsArenaAllocator : std::false_type { };
509
510 /*
511  * folly::enable_shared_from_this
512  *
513  * To be removed once C++17 becomes a minimum requirement for folly.
514  */
515 #if __cplusplus >= 201700L || \
516     __cpp_lib_enable_shared_from_this >= 201603L
517
518 // Guaranteed to have std::enable_shared_from_this::weak_from_this(). Prefer
519 // type alias over our own class.
520 /* using override */ using std::enable_shared_from_this;
521
522 #else
523
524 /**
525  * Extends std::enabled_shared_from_this. Offers weak_from_this() to pre-C++17
526  * code. Use as drop-in replacement for std::enable_shared_from_this.
527  *
528  * C++14 has no direct means of creating a std::weak_ptr, one must always
529  * create a (temporary) std::shared_ptr first. C++17 adds weak_from_this() to
530  * std::enable_shared_from_this to avoid that overhead. Alas code that must
531  * compile under different language versions cannot call
532  * std::enable_shared_from_this::weak_from_this() directly. Hence this class.
533  *
534  * @example
535  *   class MyClass : public folly::enable_shared_from_this<MyClass> {};
536  *
537  *   int main() {
538  *     std::shared_ptr<MyClass> sp = std::make_shared<MyClass>();
539  *     std::weak_ptr<MyClass> wp = sp->weak_from_this();
540  *   }
541  */
542 template <typename T>
543 class enable_shared_from_this : public std::enable_shared_from_this<T> {
544  public:
545   constexpr enable_shared_from_this() noexcept = default;
546
547   std::weak_ptr<T> weak_from_this() noexcept {
548     return weak_from_this_<T>(this);
549   }
550
551   std::weak_ptr<T const> weak_from_this() const noexcept {
552     return weak_from_this_<T>(this);
553   }
554
555  private:
556   // Uses SFINAE to detect and call
557   // std::enable_shared_from_this<T>::weak_from_this() if available. Falls
558   // back to std::enable_shared_from_this<T>::shared_from_this() otherwise.
559   template <typename U>
560   auto weak_from_this_(std::enable_shared_from_this<U>* base_ptr)
561   noexcept -> decltype(base_ptr->weak_from_this()) {
562     return base_ptr->weak_from_this();
563   }
564
565   template <typename U>
566   auto weak_from_this_(std::enable_shared_from_this<U> const* base_ptr)
567   const noexcept -> decltype(base_ptr->weak_from_this()) {
568     return base_ptr->weak_from_this();
569   }
570
571   template <typename U>
572   std::weak_ptr<U> weak_from_this_(...) noexcept {
573     try {
574       return this->shared_from_this();
575     } catch (std::bad_weak_ptr const&) {
576       // C++17 requires that weak_from_this() on an object not owned by a
577       // shared_ptr returns an empty weak_ptr. Sadly, in C++14,
578       // shared_from_this() on such an object is undefined behavior, and there
579       // is nothing we can do to detect and handle the situation in a portable
580       // manner. But in case a compiler is nice enough to implement C++17
581       // semantics of shared_from_this() and throws a bad_weak_ptr, we catch it
582       // and return an empty weak_ptr.
583       return std::weak_ptr<U>{};
584     }
585   }
586
587   template <typename U>
588   std::weak_ptr<U const> weak_from_this_(...) const noexcept {
589     try {
590       return this->shared_from_this();
591     } catch (std::bad_weak_ptr const&) {
592       return std::weak_ptr<U const>{};
593     }
594   }
595 };
596
597 #endif
598
599 } // namespace folly