xref: /xnu-10063.121.3/libkern/libkern/c++/OSPtr.h (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1 //
2 // Copyright (c) 2019 Apple, Inc. All rights reserved.
3 //
4 // @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 //
6 // This file contains Original Code and/or Modifications of Original Code
7 // as defined in and that are subject to the Apple Public Source License
8 // Version 2.0 (the 'License'). You may not use this file except in
9 // compliance with the License. The rights granted to you under the License
10 // may not be used to create, or enable the creation or redistribution of,
11 // unlawful or unlicensed copies of an Apple operating system, or to
12 // circumvent, violate, or enable the circumvention or violation of, any
13 // terms of an Apple operating system software license agreement.
14 //
15 // Please obtain a copy of the License at
16 // http://www.opensource.apple.com/apsl/ and read it before using this file.
17 //
18 // The Original Code and all software distributed under the License are
19 // distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 // EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 // INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 // Please see the License for the specific language governing rights and
24 // limitations under the License.
25 //
26 // @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 //
28 
29 #ifndef XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
30 #define XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
31 
32 //
33 // The declarations in this file are a transition tool from raw pointers to
34 // the new OSSharedPtr class.
35 //
36 // Basically, code in headers that wants to be able to vend both a raw pointer
37 // and a shared pointer interface should use `OSPtr<T>` instead of `T*`.
38 // Then, users that want to opt into using `OSSharedPtr` can define the
39 // `IOKIT_ENABLE_SHARED_PTR` macro in their translation unit (.cpp file),
40 // and `OSPtr<T>` will suddenly be `OSSharedPtr<T>`.
41 //
42 // When the `IOKIT_ENABLE_SHARED_PTR` macro is not enabled, however, `OSPtr<T>`
43 // will simply be `T*`, so that clients that do not wish to migrate to smart
44 // pointers don't need to.
45 //
46 // Note that defining `IOKIT_ENABLE_SHARED_PTR` requires C++17, because the
47 // implementation of `OSSharedPtr` requires that.
48 //
49 
50 #if !defined(PRIVATE) // only ask to opt-in explicitly for third-party developers
51 #   if defined(IOKIT_ENABLE_SHARED_PTR)
52 #       if !defined(IOKIT_ENABLE_EXPERIMENTAL_SHARED_PTR_IN_API)
53 #           error It seems that you have defined IOKIT_ENABLE_SHARED_PTR to \
54         ask IOKit to return shared pointers from many of its API \
55         functions. This is great! However, please note that we may \
56         transition more IOKit APIs to shared pointers in the future, \
57         so if you enable IOKIT_ENABLE_SHARED_PTR right now, your \
58         code may fail to compile with future versions of IOKit \
59         (which would return shared pointers where you expect raw \
60         pointers). If you are OK with that, please define the \
61         IOKIT_ENABLE_EXPERIMENTAL_SHARED_PTR_IN_API macro to \
62         silence this error. If that is not acceptable, please hold \
63         off on enabling shared pointers in IOKit APIs until we have \
64         committed to API stability for it.
65 #       endif
66 #   endif
67 #endif
68 
69 #if defined(IOKIT_ENABLE_SHARED_PTR)
70 
71 #define __returns_nonnull_osptr
72 
73 #if __cplusplus < 201703L
74 #error "Your code must compile with C++17 or later to adopt shared pointers. Use Xcode's 'C++ Language Dialect' setting, or on clang's command-line use -std=gnu++17"
75 #endif
76 
77 #include <libkern/c++/OSSharedPtr.h>
78 
79 template <typename T>
80 using OSPtr = OSSharedPtr<T>;
81 
82 class OSCollection; // Forward declare only because OSCollection.h needs OSPtr.h
83 
84 template <typename T>
85 using OSTaggedPtr = OSTaggedSharedPtr<T, OSCollection>;
86 
87 #else
88 
89 #if __has_attribute(returns_nonnull)
90 #define __returns_nonnull_osptr __attribute__((returns_nonnull))
91 #else
92 #define __returns_nonnull_osptr
93 #endif
94 
95 template <typename T>
96 class __attribute__((trivial_abi)) OSSharedPtr;
97 
98 template <typename T, typename Tag>
99 class __attribute__((trivial_abi)) OSTaggedSharedPtr;
100 
101 // We're not necessarily in C++11 mode, so we need to disable warnings
102 // for C++11 extensions
103 #pragma clang diagnostic push
104 #pragma clang diagnostic ignored "-Wc++11-extensions"
105 
106 template <typename T>
107 using OSPtr = T *;
108 
109 template <typename T>
110 using OSTaggedPtr = T *;
111 
112 #pragma clang diagnostic pop
113 
114 #endif
115 
116 // Allow C++98 code to use nullptr.
117 //
118 // This isn't the right place to put this, however the old OSPtr.h header
119 // had it and some code has now started relying on nullptr being defined.
120 #if !__has_feature(cxx_nullptr) && !defined(nullptr)
121 # define nullptr NULL
122 #endif
123 
124 #endif // !XNU_LIBKERN_LIBKERN_CXX_OS_PTR_H
125