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 16 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 17 # pragma GCC system_header 18 #endif 19 20 _LIBCPP_BEGIN_NAMESPACE_STD 21 22 struct __uninitialized_tag {}; 23 24 // This class stores an object of type _Tp but never destroys it. 25 // 26 // This is akin to using __attribute__((no_destroy)), except that it is possible 27 // to control the lifetime of the object with more flexibility by deciding e.g. 28 // whether to initialize the object at construction or to defer to a later 29 // initialization using __emplace. 30 template <class _Tp> 31 struct __no_destroy { 32 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI explicit __no_destroy(__uninitialized_tag) : __dummy_() { 33 if (__libcpp_is_constant_evaluated()) { 34 __dummy_ = char(); 35 } 36 } 37 _LIBCPP_HIDE_FROM_ABI ~__no_destroy() { 38 // nothing 39 } 40 41 template <class... _Args> 42 _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI explicit __no_destroy(_Args&&... __args) 43 : __obj_(std::forward<_Args>(__args)...) {} 44 45 template <class... _Args> 46 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp& __emplace(_Args&&... __args) { 47 new (&__obj_) _Tp(std::forward<_Args>(__args)...); 48 return __obj_; 49 } 50 51 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp& __get() { return __obj_; } 52 _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _Tp const& __get() const { return __obj_; } 53 54 private: 55 union { 56 _Tp __obj_; 57 char __dummy_; // so we can initialize a member even with __uninitialized_tag for constexpr-friendliness 58 }; 59 }; 60 61 _LIBCPP_END_NAMESPACE_STD 62 63 #endif // _LIBCPP___UTILITY_NO_DESTROY_H 64