klee
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Ref.h
Go to the documentation of this file.
1 //===-- Ref.h ---------------------------------------------------*- C++ -*-===//
2 //
3 // The KLEE Symbolic Virtual Machine
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef KLEE_REF_H
11 #define KLEE_REF_H
12 
13 #include "llvm/Support/Casting.h"
14 using llvm::isa;
15 using llvm::cast;
16 using llvm::cast_or_null;
17 using llvm::dyn_cast;
18 using llvm::dyn_cast_or_null;
19 
20 #include <assert.h>
21 #include <iosfwd> // FIXME: Remove this!!!
22 
23 namespace llvm {
24  class raw_ostream;
25 }
26 
27 namespace klee {
28 
29 template<class T>
30 class ref {
31  T *ptr;
32 
33 public:
34  // default constructor: create a NULL reference
35  ref() : ptr(0) { }
36  ~ref () { dec (); }
37 
38 private:
39  void inc() const {
40  if (ptr)
41  ++ptr->refCount;
42  }
43 
44  void dec() const {
45  if (ptr && --ptr->refCount == 0)
46  delete ptr;
47  }
48 
49 public:
50  template<class U> friend class ref;
51 
52  // constructor from pointer
53  ref(T *p) : ptr(p) {
54  inc();
55  }
56 
57  // normal copy constructor
58  ref(const ref<T> &r) : ptr(r.ptr) {
59  inc();
60  }
61 
62  // conversion constructor
63  template<class U>
64  ref (const ref<U> &r) : ptr(r.ptr) {
65  inc();
66  }
67 
68  // pointer operations
69  T *get () const {
70  return ptr;
71  }
72 
73  /* The copy assignment operator must also explicitly be defined,
74  * despite a redundant template. */
75  ref<T> &operator= (const ref<T> &r) {
76  r.inc();
77  dec();
78  ptr = r.ptr;
79 
80  return *this;
81  }
82 
83  template<class U> ref<T> &operator= (const ref<U> &r) {
84  r.inc();
85  dec();
86  ptr = r.ptr;
87 
88  return *this;
89  }
90 
91  T& operator*() const {
92  return *ptr;
93  }
94 
95  T* operator->() const {
96  return ptr;
97  }
98 
99  bool isNull() const { return ptr == 0; }
100 
101  // assumes non-null arguments
102  int compare(const ref &rhs) const {
103  assert(!isNull() && !rhs.isNull() && "Invalid call to compare()");
104  return get()->compare(*rhs.get());
105  }
106 
107  // assumes non-null arguments
108  bool operator<(const ref &rhs) const { return compare(rhs)<0; }
109  bool operator==(const ref &rhs) const { return compare(rhs)==0; }
110  bool operator!=(const ref &rhs) const { return compare(rhs)!=0; }
111 };
112 
113 template<class T>
114 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const ref<T> &e) {
115  os << *e;
116  return os;
117 }
118 
119 template<class T>
120 inline std::stringstream &operator<<(std::stringstream &os, const ref<T> &e) {
121  os << *e;
122  return os;
123 }
124 
125 } // end namespace klee
126 
127 namespace llvm {
128  // simplify_type implementation for ref<>, which allows dyn_cast from on a
129  // ref<> to apply to the wrapper type. Conceptually the result of such a
130  // dyn_cast should probably be a ref of the casted type, but that breaks the
131  // idiom of initializing a variable to the result of a dyn_cast inside an if
132  // condition, or we would have to implement operator(bool) for ref<> with
133  // isNull semantics, which doesn't seem like a good idea.
134 template<typename T>
135 struct simplify_type<const ::klee::ref<T> > {
136  typedef T* SimpleType;
137  static SimpleType getSimplifiedValue(const ::klee::ref<T> &Ref) {
138  return Ref.get();
139  }
140 };
141 
142 template<typename T>
143 struct simplify_type< ::klee::ref<T> >
144  : public simplify_type<const ::klee::ref<T> > {};
145 }
146 
147 #endif /* KLEE_REF_H */
int compare(const ref &rhs) const
Definition: Ref.h:102
bool operator!=(const ref &rhs) const
Definition: Ref.h:110
void dec() const
Definition: Ref.h:44
ref(T *p)
Definition: Ref.h:53
T & operator*() const
Definition: Ref.h:91
bool operator<(const ref &rhs) const
Definition: Ref.h:108
bool operator==(const ref &rhs) const
Definition: Ref.h:109
ref< T > & operator=(const ref< T > &r)
Definition: Ref.h:75
void inc() const
Definition: Ref.h:39
T * operator->() const
Definition: Ref.h:95
bool isNull() const
Definition: Ref.h:99
~ref()
Definition: Ref.h:36
ref()
Definition: Ref.h:35
ref(const ref< U > &r)
Definition: Ref.h:64
T * ptr
Definition: Ref.h:31
ref(const ref< T > &r)
Definition: Ref.h:58
static SimpleType getSimplifiedValue(const ::klee::ref< T > &Ref)
Definition: Ref.h:137