1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___UTILITY_NO_DESTROY_H 10 #define _LIBCPP___UTILITY_NO_DESTROY_H 11 12 #include <__config> 13 #include <__type_traits/is_constant_evaluated.h> 14 #include <__utility/forward.h> 15 #include <new> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 # pragma GCC system_header 19 #endif 20 21 _LIBCPP_BEGIN_NAMESPACE_STD 22 23 struct __uninitialized_tag {}; 24 25 // This class stores an object of type _Tp but never destroys it. 26 // 27 // This is akin to using __attribute__((no_destroy)), except that it is possible 28 // to control the lifetime of the object with more flexibility by deciding e.g. 29 // whether to initialize the object at construction or to defer to a later 30 // initialization using __emplace. 31 template <class _Tp> 32 struct __no_destroy { 33 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __no_destroy(__uninitialized_tag) : __obj_() {} 34 35 template <class... _Args> 36 _LIBCPP_HIDE_FROM_ABI explicit __no_destroy(_Args&&... __args) { 37 ::new ((void*)__obj_) _Tp(std::forward<_Args>(__args)...); 38 } 39 40 template <class... _Args> 41 _LIBCPP_HIDE_FROM_ABI _Tp& __emplace(_Args&&... __args) { 42 return *(::new ((void*)__obj_) _Tp(std::forward<_Args>(__args)...)); 43 } 44 45 _LIBCPP_HIDE_FROM_ABI _Tp& __get() { return *reinterpret_cast<_Tp*>(__obj_); } 46 _LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return *reinterpret_cast<const _Tp*>(__obj_); } 47 48 private: 49 _ALIGNAS_TYPE(_Tp) char __obj_[sizeof(_Tp)]; 50 }; 51 52 _LIBCPP_END_NAMESPACE_STD 53 54 #endif // _LIBCPP___UTILITY_NO_DESTROY_H 55