OOP.hh 4.77 KB
Newer Older
1
/******************************************************************************
balaskoa's avatar
balaskoa committed
2
 * Copyright (c) 2000-2020 Ericsson Telecom AB
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Baranyi, Botond
 *
 ******************************************************************************/

#ifndef OOP_HH
#define OOP_HH

#include "Universal_charstring.hh"
17
#include "Logger.hh"
18
19
20
21
22

// OBJECT
// ------

class OBJECT {
23
24
25
26
27
28
private:
  size_t ref_count;
  
  OBJECT(const OBJECT&); // copy disabled
  OBJECT operator=(const OBJECT&); // assignment disabled
  boolean operator==(const OBJECT&); // equality operator disabled
29
public:
30
31
32
33
34
35
36
37
38
39
40
  OBJECT(): ref_count(0) {}
  virtual ~OBJECT() {
    if (ref_count != 0) {
      TTCN_error("Internal error: deleting an object with %lu reference(s) left.", ref_count);
    }
  }
  void add_ref() { ++ref_count; }
  boolean remove_ref() {
    --ref_count;
    return ref_count == 0;
  }
41
  virtual void log() const {
42
    TTCN_Logger::log_event_str("object: { }");
43
  }
44
45
46
  virtual UNIVERSAL_CHARSTRING toString() {
    return UNIVERSAL_CHARSTRING("Object");
  }
47
48
49
50
51
52
53
};

// OBJECT_REF
// ----------

template <typename T>
class OBJECT_REF {
54
55
56
57
  template <typename T2>
  friend boolean operator==(null_type, const OBJECT_REF<T2>& right_val);
  template <typename T2>
  friend boolean operator!=(null_type, const OBJECT_REF<T2>& right_val);
58
private:
59
  T* ptr; // NULL if it's a null reference
60
61
  
public:
62
63
64
  OBJECT_REF(): ptr(NULL) {} // constructor with no parameters

  OBJECT_REF(null_type): ptr(NULL) {} // constructor for null reference
65
  
66
67
  OBJECT_REF(T* p_ptr): ptr(p_ptr) { // constructor for new value (.create)
    ptr->add_ref();
68
69
  }
  
70
71
72
  OBJECT_REF(const OBJECT_REF<T>& p_other): ptr(p_other.ptr) { // copy constructor
    if (ptr != NULL) {
      ptr->add_ref();
73
74
75
    }
  }
  
76
77
78
79
80
81
82
83
84
  void clean_up() {
    if (ptr != NULL) {
      if (ptr->remove_ref()) {
        delete ptr;
      }
      ptr = NULL;
    }
  }
  
85
86
87
88
89
90
  ~OBJECT_REF() {
    clean_up();
  }
  
  OBJECT_REF& operator=(null_type) { // assignment operator for null reference
    clean_up();
91
    return *this;
92
93
94
95
  }
  
  OBJECT_REF& operator=(const OBJECT_REF<T>& p_other) { // assignment operator for actual reference
    clean_up();
96
97
98
    if (p_other.ptr != NULL) {
      ptr = p_other.ptr;
      ptr->add_ref();
99
100
101
102
    }
    return *this;
  }
  
103
104
  boolean operator==(null_type) const { // equality operator (with null reference)
    return ptr == NULL;
105
106
  }
  
107
108
109
110
111
112
113
114
115
116
  boolean operator!=(null_type) const { // inequality operator (with null reference)
    return ptr != NULL;
  }
  
  boolean operator==(const OBJECT_REF<T>& p_other) const { // equality operator (with actual reference)
    return ptr == p_other.ptr;
  }
  
  boolean operator!=(const OBJECT_REF<T>& p_other) const { // inequality operator (with actual reference)
    return ptr != p_other.ptr;
117
118
119
  }
  
  T* operator*() { // de-referencing operator
120
121
    if (ptr != NULL) {
      return ptr;
122
123
124
125
126
    }
    TTCN_error("Accessing a null reference.");
  }
  
  T* operator->() { // de-referencing operator (for methods)
127
128
    if (ptr != NULL) {
      return ptr;
129
130
131
132
133
    }
    TTCN_error("Accessing a null reference.");
  }
  
  const T* operator->() const { // de-referencing operator (for constant methods)
134
135
    if (ptr != NULL) {
      return ptr;
136
137
138
    }
    TTCN_error("Accessing a null reference.");
  }
139
140
141
142
143
144
145
146
147
  
  void log() const {
    if (ptr == NULL) {
      TTCN_Logger::log_event_str("null");
    }
    else {
      ptr->log();
    }
  }
148
149
150
151
152
153
154
155
156
157
158
159
  
  boolean is_bound() const {
    return ptr != NULL;
  }
  
  boolean is_value() const {
    return ptr != NULL;
  }
  
  boolean is_present() const {
    return ptr != NULL;
  }
160
161
};

162
163
164
165
166
167
168
169
170
171
template<typename T>
boolean operator==(null_type, const OBJECT_REF<T>& right_val) { // equality operator (with null reference, inverted)
  return right_val.ptr == NULL;
}

template<typename T>
boolean operator!=(null_type, const OBJECT_REF<T>& right_val) { // inequality operator (with null reference, inverted)
  return right_val.ptr != NULL;
}

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// EXCEPTION
// ---------

template<typename T, int type_id>
class EXCEPTION {
public:
  struct exception_struct {
    T* val_ptr;
    size_t ref_count;
  };
private:
  exception_struct* ex_ptr;
  EXCEPTION operator=(const EXCEPTION&); // assignment disabled
public:
  EXCEPTION(T* p_value): ex_ptr(new exception_struct) {
    ex_ptr->val_ptr = p_value;
    ex_ptr->ref_count = 1;
  }
  EXCEPTION(const EXCEPTION& p): ex_ptr(p.ex_ptr) {
    ++ex_ptr->ref_count;
  }
  ~EXCEPTION() {
    --ex_ptr->ref_count;
    if (ex_ptr->ref_count == 0) {
      delete ex_ptr->val_ptr;
      delete ex_ptr;
    }
  }
  T& operator()() { return *ex_ptr->val_ptr; }
};

#endif /* OOP_HH */