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 | |