1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <fbl/ref_ptr.h>
8 #include <fbl/unique_ptr.h>
9 #include <fbl/type_support.h>
10 #include <memory>
11 #include <stdint.h>
12 #include <zircon/compiler.h>
13 
14 namespace fbl {
15 namespace internal {
16 
17 // Declaration of the base type which will be used to control what type of
18 // pointers are permitted to be in containers.
19 template <typename T> struct ContainerPtrTraits;
20 
21 // Traits for managing raw pointers.
22 template <typename T>
23 struct ContainerPtrTraits<T*> {
24     using ValueType       = T;
25     using RefType         = T&;
26     using ConstRefType    = const T&;
27     using PtrType         = T*;
28     using ConstPtrType    = const T*;
29     using RawPtrType      = T*;
30     using ConstRawPtrType = const T*;
31 
32     static constexpr bool IsManaged = false;
33     static constexpr bool CanCopy = true;
34 
35     static inline T* GetRaw(const PtrType& ptr) { return ptr; }
36     static inline T* Copy(const RawPtrType& ptr) { return ptr; }
37 
38     static inline RawPtrType Leak(PtrType& ptr) __WARN_UNUSED_RESULT {
39         return ptr;
40     }
41 
42     static inline PtrType Reclaim(RawPtrType ptr) {
43         return ptr;
44     }
45 };
46 
47 // Traits for managing unique pointers.
48 template <typename T>
49 struct ContainerPtrTraits<::fbl::unique_ptr<T>> {
50     using ValueType       = T;
51     using RefType         = T&;
52     using ConstRefType    = const T&;
53     using PtrType         = ::fbl::unique_ptr<T>;
54     using ConstPtrType    = ::fbl::unique_ptr<const T>;
55     using RawPtrType      = T*;
56     using ConstRawPtrType = const T*;
57 
58     static constexpr bool IsManaged = true;
59     static constexpr bool CanCopy = false;
60 
61     static inline T* GetRaw(const PtrType& ptr) { return ptr.get(); }
62 
63     static inline RawPtrType Leak(PtrType& ptr) __WARN_UNUSED_RESULT {
64         return ptr.release();
65     }
66 
67     static inline PtrType Reclaim(RawPtrType ptr) {
68         return PtrType(ptr);
69     }
70 };
71 
72 // Traits for managing std::unique_ptrs to objects (arrays of objects are not supported)
73 template <typename T, typename Deleter>
74 struct ContainerPtrTraits<::std::unique_ptr<T, Deleter>> {
75     using ValueType       = T;
76     using RefType         = T&;
77     using ConstRefType    = const T&;
78     using PtrType         = ::std::unique_ptr<T, Deleter>;
79     using ConstPtrType    = ::std::unique_ptr<const T, Deleter>;
80     using RawPtrType      = T*;
81     using ConstRawPtrType = const T*;
82 
83     static constexpr bool IsManaged = true;
84     static constexpr bool CanCopy = false;
85 
86     static inline T* GetRaw(const PtrType& ptr) { return ptr.get(); }
87 
88     static inline RawPtrType Leak(PtrType& ptr) __WARN_UNUSED_RESULT {
89         return ptr.release();
90     }
91 
92     static inline PtrType Reclaim(RawPtrType ptr) {
93         return PtrType(ptr);
94     }
95 };
96 
97 // Traits for managing ref_counted pointers.
98 template <typename T>
99 struct ContainerPtrTraits<::fbl::RefPtr<T>> {
100     using ValueType       = T;
101     using RefType         = T&;
102     using ConstRefType    = const T&;
103     using PtrType         = ::fbl::RefPtr<T>;
104     using ConstPtrType    = ::fbl::RefPtr<const T>;
105     using RawPtrType      = T*;
106     using ConstRawPtrType = const T*;
107 
108     static constexpr bool IsManaged = true;
109     static constexpr bool CanCopy = true;
110 
111     static inline T*       GetRaw(const PtrType& ptr)      { return ptr.get(); }
112     static inline PtrType  Copy(const RawPtrType& ptr)     { return PtrType(ptr); }
113 
114     static inline RawPtrType Leak(PtrType& ptr) __WARN_UNUSED_RESULT {
115         return ptr.leak_ref();
116     }
117 
118     static inline PtrType Reclaim(RawPtrType ptr) {
119         return ::fbl::internal::MakeRefPtrNoAdopt(ptr);
120     }
121 };
122 
123 }  // namespace internal
124 }  // namespace fbl
125