1//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines and implements the OwningPtr class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_OWNINGPTR_H
15#define LLVM_ADT_OWNINGPTR_H
16
17#include "llvm/Support/Compiler.h"
18#include <cassert>
19#include <cstddef>
20
21namespace llvm {
22
23/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
24/// guarantees deletion of the object pointed to, either on destruction of the
25/// OwningPtr or via an explicit reset().  Once created, ownership of the
26/// pointee object can be taken away from OwningPtr by using the take method.
27template<class T>
28class OwningPtr {
29  OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
30  OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
31  T *Ptr;
32public:
33  explicit OwningPtr(T *P = 0) : Ptr(P) {}
34
35#if LLVM_HAS_RVALUE_REFERENCES
36  OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
37
38  OwningPtr &operator=(OwningPtr &&Other) {
39    reset(Other.take());
40    return *this;
41  }
42#endif
43
44  ~OwningPtr() {
45    delete Ptr;
46  }
47
48  /// reset - Change the current pointee to the specified pointer.  Note that
49  /// calling this with any pointer (including a null pointer) deletes the
50  /// current pointer.
51  void reset(T *P = 0) {
52    if (P == Ptr) return;
53    T *Tmp = Ptr;
54    Ptr = P;
55    delete Tmp;
56  }
57
58  /// take - Reset the owning pointer to null and return its pointer.  This does
59  /// not delete the pointer before returning it.
60  T *take() {
61    T *Tmp = Ptr;
62    Ptr = 0;
63    return Tmp;
64  }
65
66  T &operator*() const {
67    assert(Ptr && "Cannot dereference null pointer");
68    return *Ptr;
69  }
70
71  T *operator->() const { return Ptr; }
72  T *get() const { return Ptr; }
73  LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
74  bool operator!() const { return Ptr == 0; }
75  bool isValid() const { return Ptr != 0; }
76
77  void swap(OwningPtr &RHS) {
78    T *Tmp = RHS.Ptr;
79    RHS.Ptr = Ptr;
80    Ptr = Tmp;
81  }
82};
83
84template<class T>
85inline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
86  a.swap(b);
87}
88
89/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
90///  functionality as OwningPtr, except that it works for array types.
91template<class T>
92class OwningArrayPtr {
93  OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
94  OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
95  T *Ptr;
96public:
97  explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
98
99#if LLVM_HAS_RVALUE_REFERENCES
100  OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
101
102  OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
103    reset(Other.take());
104    return *this;
105  }
106#endif
107
108  ~OwningArrayPtr() {
109    delete [] Ptr;
110  }
111
112  /// reset - Change the current pointee to the specified pointer.  Note that
113  /// calling this with any pointer (including a null pointer) deletes the
114  /// current pointer.
115  void reset(T *P = 0) {
116    if (P == Ptr) return;
117    T *Tmp = Ptr;
118    Ptr = P;
119    delete [] Tmp;
120  }
121
122  /// take - Reset the owning pointer to null and return its pointer.  This does
123  /// not delete the pointer before returning it.
124  T *take() {
125    T *Tmp = Ptr;
126    Ptr = 0;
127    return Tmp;
128  }
129
130  T &operator[](std::ptrdiff_t i) const {
131    assert(Ptr && "Cannot dereference null pointer");
132    return Ptr[i];
133  }
134
135  T *get() const { return Ptr; }
136  LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
137  bool operator!() const { return Ptr == 0; }
138
139  void swap(OwningArrayPtr &RHS) {
140    T *Tmp = RHS.Ptr;
141    RHS.Ptr = Ptr;
142    Ptr = Tmp;
143  }
144};
145
146template<class T>
147inline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
148  a.swap(b);
149}
150
151} // end namespace llvm
152
153#endif
154