aboutsummaryrefslogtreecommitdiff
path: root/lout/object.hh
blob: 9cacff77604cad0db849517b0983eeb413793fb9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#ifndef __LOUT_OBJECT_HH__
#define __LOUT_OBJECT_HH__

#include <stdlib.h>
#include <string.h>

#include "misc.hh"

namespace lout {

/**
 * \brief Here, some common classes (or interfaces) are defined, to standardize
 *    the access to other classes.
 */
namespace object {

/**
 * \brief This is the base class for many other classes, which defines very
 *    common virtual methods.
 *
 * For convenience, none of them are abstract, but they
 * must be defined, when they are needed, especially for containers.
 */
class Object
{
public:
   virtual ~Object();
   virtual bool equals(Object *other);
   virtual int hashValue();
   virtual Object *clone();
   virtual void intoStringBuffer(misc::StringBuffer *sb);
   const char *toString();
   virtual size_t sizeOf();
};

/**
 * \brief Instances of a sub class of may be compared (less, greater).
 *
 * Used for sorting etc.
 */
class Comparable: public Object
{
public:
   /**
    * \brief Compare two objects, this and other.
    *
    * Return a value < 0, when this is less than other, a value > 0,
    * when this is greater than other, or 0, when this and other are
    * equal.
    *
    * If c1.equals(c2) (as defined in Object), c1.compareTo(c2) must
    * be 0, but, unlike you may expect, the reversed is not
    * necessarily true. This method returns 0, if, according to the
    * rules for sorting, there is no difference, but there may still
    * be differences (not relevant for sorting), which "equals" will
    * care about.
    */
   virtual int compareTo(Comparable *other) = 0;
};

/**
 * \brief Used for other orders as the one defined by Comparable.
 *
 * Compared objects must not necessarily be instances of Comparable.
 */
class Comparator: public Object
{
public:
   /**
    * \brief Compare two objects o1 and o2.
    *
    * Return a value < 0, when o1 is less than o2, a value > 0, when o1
    * is greater than o2, or 0, when o1 and o2 are equal.
    *
    * If o1.equals(o2) (as defined in Object), compare(o1, o2) must be
    * 0, but, unlike you may expect, the reversed is not necessarily
    * true. This method returns 0, if, according to the rules for
    * sorting, there is no difference, but there may still be
    * differences (not relevant for sorting), which "equals" will care
    * about.
    */
   virtual int compare(Object *o1, Object *o2) = 0;

   static Comparator *compareFunComparator;
   static int compareFun(const void *p1, const void *p2);
};

class StandardComparator: public Comparator
{
public:
   int compare(Object *o1, Object *o2);
};

extern StandardComparator standardComparator;

/**
 * \brief An object::Object wrapper for void pointers.
 */
class Pointer: public Object
{
private:
   void *value;

public:
   Pointer(void *value) { this->value = value; }
   bool equals(Object *other);
   int hashValue();
   void intoStringBuffer(misc::StringBuffer *sb);
   inline void *getValue() { return value; }
};

/**
 * \brief A typed version of object::Pointer.
 */
template <class T> class TypedPointer: public Pointer
{
public:
   inline TypedPointer(T *value) : Pointer ((void*)value) { }
   inline T *getTypedValue() { return (T*)getValue(); }
};


/**
 * \brief An object::Object wrapper for int's.
 */
class Integer: public Comparable
{
   int value;

public:
   Integer(int value) { this->value = value; }
   bool equals(Object *other);
   int hashValue();
   void intoStringBuffer(misc::StringBuffer *sb);
   int compareTo(Comparable *other);
   inline int getValue() { return value; }
};


/**
 * \brief An object::Object wrapper for bool's.
 */
class Boolean: public Comparable
{
   bool value;

public:
   Boolean(bool value) { this->value = value; }
   bool equals(Object *other);
   int hashValue();
   void intoStringBuffer(misc::StringBuffer *sb);
   int compareTo(Comparable *other);
   inline bool getValue() { return value; }
};


/**
 * \brief An object::Object wrapper for constant strings (char*).
 *
 * As opposed to object::String, the char array is not copied.
 */
class ConstString: public Comparable
{
protected:
   const char *str;

public:
   ConstString(const char *str) { this->str = str; }
   bool equals(Object *other);
   int hashValue();
   int compareTo(Comparable *other);
   void intoStringBuffer(misc::StringBuffer *sb);

   inline const char *chars() { return str; }

   static int hashValue(const char *str);
};


/**
 * \brief An object::Object wrapper for strings (char*).
 *
 * As opposed to object::ConstantString, the char array is copied.
 */
class String: public ConstString
{
public:
   String(const char *str);
   ~String();
};

/**
 * \todo Comment
 */
class PairBase: public Object
{
protected:
   Object *first, *second;

public:
   PairBase(Object *first, Object *second);
   ~PairBase();

   bool equals(Object *other);
   int hashValue();
   void intoStringBuffer(misc::StringBuffer *sb);
   size_t sizeOf();
};

/**
 * \todo Comment
 */
class Pair: public PairBase
{
public:
   Pair(Object *first, Object *second): PairBase (first, second) { }

   inline Object *getFirst () { return first; }
   inline Object *getSecond () { return second; }
};

/**
 * \todo Comment
 */
template <class F, class S> class TypedPair: public PairBase
{
public:
   TypedPair(F *first, S *second): PairBase (first, second) { }

   inline F *getFirst () { return first; }
   inline S *getSecond () { return second; }
};

} // namespace object

} // namespace lout

#endif // __LOUT_OBJECT_HH__