1193323Sed//===- llvm/ADT/OwningPtr.h - Smart ptr that owns the pointee ---*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines and implements the OwningPtr class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14249423Sdim#ifndef LLVM_ADT_OWNINGPTR_H
15249423Sdim#define LLVM_ADT_OWNINGPTR_H
16193323Sed
17243830Sdim#include "llvm/Support/Compiler.h"
18193323Sed#include <cassert>
19193323Sed#include <cstddef>
20193323Sed
21193323Sednamespace llvm {
22193323Sed
23193323Sed/// OwningPtr smart pointer - OwningPtr mimics a built-in pointer except that it
24193323Sed/// guarantees deletion of the object pointed to, either on destruction of the
25193323Sed/// OwningPtr or via an explicit reset().  Once created, ownership of the
26193323Sed/// pointee object can be taken away from OwningPtr by using the take method.
27193323Sedtemplate<class T>
28193323Sedclass OwningPtr {
29243830Sdim  OwningPtr(OwningPtr const &) LLVM_DELETED_FUNCTION;
30243830Sdim  OwningPtr &operator=(OwningPtr const &) LLVM_DELETED_FUNCTION;
31193323Sed  T *Ptr;
32193323Sedpublic:
33193323Sed  explicit OwningPtr(T *P = 0) : Ptr(P) {}
34193323Sed
35249423Sdim#if LLVM_HAS_RVALUE_REFERENCES
36243830Sdim  OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
37243830Sdim
38243830Sdim  OwningPtr &operator=(OwningPtr &&Other) {
39243830Sdim    reset(Other.take());
40243830Sdim    return *this;
41243830Sdim  }
42243830Sdim#endif
43243830Sdim
44193323Sed  ~OwningPtr() {
45193323Sed    delete Ptr;
46193323Sed  }
47193323Sed
48193323Sed  /// reset - Change the current pointee to the specified pointer.  Note that
49193323Sed  /// calling this with any pointer (including a null pointer) deletes the
50193323Sed  /// current pointer.
51193323Sed  void reset(T *P = 0) {
52193323Sed    if (P == Ptr) return;
53193323Sed    T *Tmp = Ptr;
54193323Sed    Ptr = P;
55193323Sed    delete Tmp;
56193323Sed  }
57193323Sed
58193323Sed  /// take - Reset the owning pointer to null and return its pointer.  This does
59193323Sed  /// not delete the pointer before returning it.
60193323Sed  T *take() {
61193323Sed    T *Tmp = Ptr;
62193323Sed    Ptr = 0;
63193323Sed    return Tmp;
64193323Sed  }
65193323Sed
66193323Sed  T &operator*() const {
67193323Sed    assert(Ptr && "Cannot dereference null pointer");
68193323Sed    return *Ptr;
69193323Sed  }
70193323Sed
71193323Sed  T *operator->() const { return Ptr; }
72193323Sed  T *get() const { return Ptr; }
73193323Sed  operator bool() const { return Ptr != 0; }
74193323Sed  bool operator!() const { return Ptr == 0; }
75193323Sed
76193323Sed  void swap(OwningPtr &RHS) {
77193323Sed    T *Tmp = RHS.Ptr;
78193323Sed    RHS.Ptr = Ptr;
79193323Sed    Ptr = Tmp;
80193323Sed  }
81193323Sed};
82193323Sed
83193323Sedtemplate<class T>
84193323Sedinline void swap(OwningPtr<T> &a, OwningPtr<T> &b) {
85193323Sed  a.swap(b);
86193323Sed}
87193323Sed
88193323Sed/// OwningArrayPtr smart pointer - OwningArrayPtr provides the same
89193323Sed///  functionality as OwningPtr, except that it works for array types.
90193323Sedtemplate<class T>
91193323Sedclass OwningArrayPtr {
92243830Sdim  OwningArrayPtr(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
93243830Sdim  OwningArrayPtr &operator=(OwningArrayPtr const &) LLVM_DELETED_FUNCTION;
94193323Sed  T *Ptr;
95193323Sedpublic:
96193323Sed  explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
97193323Sed
98249423Sdim#if LLVM_HAS_RVALUE_REFERENCES
99243830Sdim  OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
100243830Sdim
101243830Sdim  OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
102243830Sdim    reset(Other.take());
103243830Sdim    return *this;
104243830Sdim  }
105243830Sdim#endif
106243830Sdim
107193323Sed  ~OwningArrayPtr() {
108193323Sed    delete [] Ptr;
109193323Sed  }
110193323Sed
111193323Sed  /// reset - Change the current pointee to the specified pointer.  Note that
112193323Sed  /// calling this with any pointer (including a null pointer) deletes the
113193323Sed  /// current pointer.
114193323Sed  void reset(T *P = 0) {
115193323Sed    if (P == Ptr) return;
116193323Sed    T *Tmp = Ptr;
117193323Sed    Ptr = P;
118193323Sed    delete [] Tmp;
119193323Sed  }
120193323Sed
121193323Sed  /// take - Reset the owning pointer to null and return its pointer.  This does
122193323Sed  /// not delete the pointer before returning it.
123193323Sed  T *take() {
124193323Sed    T *Tmp = Ptr;
125193323Sed    Ptr = 0;
126193323Sed    return Tmp;
127193323Sed  }
128193323Sed
129193323Sed  T &operator[](std::ptrdiff_t i) const {
130193323Sed    assert(Ptr && "Cannot dereference null pointer");
131193323Sed    return Ptr[i];
132193323Sed  }
133193323Sed
134193323Sed  T *get() const { return Ptr; }
135193323Sed  operator bool() const { return Ptr != 0; }
136193323Sed  bool operator!() const { return Ptr == 0; }
137193323Sed
138193323Sed  void swap(OwningArrayPtr &RHS) {
139193323Sed    T *Tmp = RHS.Ptr;
140193323Sed    RHS.Ptr = Ptr;
141193323Sed    Ptr = Tmp;
142193323Sed  }
143193323Sed};
144193323Sed
145193323Sedtemplate<class T>
146193323Sedinline void swap(OwningArrayPtr<T> &a, OwningArrayPtr<T> &b) {
147193323Sed  a.swap(b);
148193323Sed}
149193323Sed
150193323Sed} // end namespace llvm
151193323Sed
152193323Sed#endif
153