summaryrefslogtreecommitdiff
path: root/ace/Basic_Types.h
blob: a4f312aa8f0ffad93c878fc207a333f59072d7bd (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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/* -*- C++ -*- */
// $Id$

// ============================================================================
//
// = LIBRARY
//    ace
//
// = FILENAME
//    Basic_Types.h
//
// = AUTHORS
//    David L. Levine
//
// = DESCRIPTION
//    #defines the list of preprocessor macros below.  The config.h file can
//    pre-define any of these to short-cut the definitions.  This is usually
//    only necessary if the preprocessor does all of its math using integers.
//
//    Sizes of built-in types:
//      ACE_SIZEOF_CHAR
//      ACE_SIZEOF_WCHAR
//      ACE_SIZEOF_SHORT
//      ACE_SIZEOF_INT
//      ACE_SIZEOF_LONG
//      ACE_SIZEOF_LONG_LONG
//      ACE_SIZEOF_VOID_P
//      ACE_SIZEOF_FLOAT
//      ACE_SIZEOF_DOUBLE
//      ACE_SIZEOF_LONG_DOUBLE
//
//    Wrappers for built-in types of specific sizes:
//      ACE_USHORT16 /* For backward compatibility.  Use ACE_UINT16 instead. */
//      ACE_INT16
//      ACE_UINT16
//      ACE_INT32
//      ACE_UINT32
//      ACE_UINT64
//    (Note: ACE_INT64 is not defined, because there is no ACE_LongLong for
//     platforms that don't have a native 8-byte integer type.)
//
//    Byte-order (endian-ness) determination:
//      ACE_BYTE_ORDER, to either ACE_BIG_ENDIAN or ACE_LITTLE_ENDIAN
//
// ============================================================================

#if !defined (ACE_BASIC_TYPES_H)
#define ACE_BASIC_TYPES_H

// A char always has 1 byte, by definition.
#define ACE_SIZEOF_CHAR 1

// Unfortunately, there isn't a portable way to determine the size of a wchar.
#if defined (ACE_HAS_WCHAR_TYPEDEFS_CHAR)
# define ACE_SIZEOF_WCHAR 1
#else
# define ACE_SIZEOF_WCHAR sizeof (wchar_t)
#endif /* ACE_HAS_WCHAR_TYPEDEFS_CHAR */

// The number of bytes in a short.
#if !defined (ACE_SIZEOF_SHORT)
#  if (USHRT_MAX) == 255U
#    define ACE_SIZEOF_SHORT 1
#  elif (USHRT_MAX) == 65535U
#    define ACE_SIZEOF_SHORT 2
#  elif (USHRT_MAX) == 4294967295U
#    define ACE_SIZEOF_SHORT 4
#  elif (USHRT_MAX) == 18446744073709551615U
#    define ACE_SIZEOF_SHORT 8
#  else
#    error: unsupported short size, must be updated for this platform!
#  endif /* USHRT_MAX */
#endif /* !defined (ACE_SIZEOF_SHORT) */

// The number of bytes in an int.
#if !defined (ACE_SIZEOF_INT)
#  if (UINT_MAX) == 65535U
#    define ACE_SIZEOF_INT 2
#  elif (UINT_MAX) == 4294967295U
#    define ACE_SIZEOF_INT 4
#  elif (UINT_MAX) == 18446744073709551615U
#    define ACE_SIZEOF_INT 8
#  else
#    error: unsupported int size, must be updated for this platform!
#  endif /* UINT_MAX */
#endif /* !defined (ACE_SIZEOF_INT) */

// The number of bytes in a long.
// NOTE - since preprocessors only need to do integer math, this is a likely
// place for a preprocessor to not properly support being able to figure out
// the proper size.  HP aC++ and GNU gcc have this difficulty so watch out.
#if !defined (ACE_SIZEOF_LONG)
#  if (ULONG_MAX) == 65535UL
#    define ACE_SIZEOF_LONG 2
#  elif ((ULONG_MAX) == 4294967295UL)
#    define ACE_SIZEOF_LONG 4
#  elif ((ULONG_MAX) == 18446744073709551615UL)
#    define ACE_SIZEOF_LONG 8
#  else
#    error: unsupported long size, must be updated for this platform!
#  endif /* ULONG_MAX */
#endif /* !defined (ACE_SIZEOF_LONG) */

// The number of bytes in a long long.
#if !defined (ACE_SIZEOF_LONG_LONG)
#  if defined (ACE_LACKS_LONGLONG_T)
#    define ACE_SIZEOF_LONG_LONG 8
#  else  /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
#    if ACE_SIZEOF_LONG == 8
#      define ACE_SIZEOF_LONG_LONG 8
       typedef unsigned long ACE_UINT64;
#    elif defined (ULLONG_MAX) && !defined (__GNUG__)
       // Some compilers use ULLONG_MAX and others, e.g. Irix, use
       // ULONGLONG_MAX.
#      if (ULLONG_MAX) == 18446744073709551615ULL
#        define ACE_SIZEOF_LONG_LONG 8
#      elif (ULLONG_MAX) == 4294967295ULL
#        define ACE_SIZEOF_LONG_LONG 4
#      else
#        error Unsupported long long size needs to be updated for this platform
#      endif
       typedef unsigned long long ACE_UINT64;
#    elif defined (ULONGLONG_MAX)
       // Irix 6.x, for example.
#      if (ULONGLONG_MAX) == 18446744073709551615ULL
#        define ACE_SIZEOF_LONG_LONG 8
#      elif (ULONGLONG_MAX) == 4294967295ULL
#        define ACE_SIZEOF_LONG_LONG 4
#      else
#        error Unsupported long long size needs to be updated for this platform
#      endif
       typedef unsigned long long ACE_UINT64;
#    else
       // ACE_SIZEOF_LONG_LONG is not yet known, but the platform doesn't
       // claim ACE_LACKS_LONGLONG_T, so assume it has 8-byte long longs.
#      define ACE_SIZEOF_LONG_LONG 8
#      if defined (sun) && !defined (ACE_LACKS_U_LONGLONG_T)
         // sun #defines u_longlong_t, maybe other platforms do also.
         // Use it, at least with g++, so that its -pedantic doesn't
         // complain about no ANSI C++ long long.
         typedef u_longlong_t ACE_UINT64;
#      else
         // LynxOS 2.5.0 and Linux don't have u_longlong_t.
         typedef unsigned long long ACE_UINT64;
#      endif /* sun */
#    endif /* ULLONG_MAX && !__GNUG__ */
#  endif /* ! ACE_WIN32 && ! ACE_LACKS_LONGLONG_T */
#endif /* !defined (ACE_SIZEOF_LONG_LONG) */


// The sizes of the commonly implemented types are now known.  Set up
// typedefs for whatever we can.  Some of these are needed for certain cases
// of ACE_UINT64, so do them before the 64-bit stuff.

#if ACE_SIZEOF_SHORT == 2
  typedef short ACE_INT16;
  typedef unsigned short ACE_UINT16;
#elif ACE_SIZEOF_INT == 2
  typedef int ACE_INT16;
  typedef unsigned short ACE_UINT16;
#else
# error Have to add to the ACE_UINT16 type setting
#endif

typedef ACE_UINT16 ACE_USHORT16;

#if ACE_SIZEOF_INT == 4
  typedef int ACE_INT32;
  typedef unsigned int ACE_UINT32;
#elif ACE_SIZEOF_LONG == 4
  typedef long ACE_INT32;
  typedef unsigned long ACE_UINT32;
#else
#  error Have to add to the ACE_UINT32 type setting
#endif

// If the platform lacks a long long, define one.
#if defined (ACE_LACKS_LONGLONG_T)
  class ACE_Export ACE_U_LongLong
  // = TITLE
  //     Unsigned long long for platforms that don't have one.
  //
  // = DESCRIPTION
  //     Provide our own unsigned long long.  This is intended to be
  //     use with ACE_High_Res_Timer, so the division operator assumes
  //     that the quotient fits into a u_long.
  //     Please note that the constructor takes (optionally) two values.
  //     The high one contributes 0x100000000 times its value.  So,
  //     for example, (0, 2) is _not_ 20000000000, but instead
  //     0x200000000.  To emphasize this, the default values are expressed
  //     in hex, and dump () outputs the value in hex.
  {
  public:
    // = Initialization and termination methods.
    ACE_U_LongLong (const ACE_UINT32 lo = 0x0, const ACE_UINT32 hi = 0x0);
    ACE_U_LongLong (const ACE_U_LongLong &);
    ACE_U_LongLong &operator= (const ACE_U_LongLong &);
    ~ACE_U_LongLong (void);

    // = Overloaded relation operators.
    int operator== (const ACE_U_LongLong &) const;
    int operator!= (const ACE_U_LongLong &) const;
    int operator< (const ACE_U_LongLong &) const;
    int operator<= (const ACE_U_LongLong &) const;
    int operator> (const ACE_U_LongLong &) const;
    int operator>= (const ACE_U_LongLong &) const;

    ACE_U_LongLong operator+ (const ACE_U_LongLong &) const;
    ACE_U_LongLong operator- (const ACE_U_LongLong &) const;
    ACE_U_LongLong operator* (const ACE_UINT32);
    ACE_U_LongLong &operator*= (const ACE_UINT32);

    ACE_U_LongLong operator<< (const u_int) const;
    ACE_U_LongLong &operator<<= (const u_int);
    ACE_U_LongLong operator>> (const u_int) const;
    ACE_U_LongLong &operator>>= (const u_int);

    double operator/ (const double) const;

    ACE_U_LongLong &operator+= (const ACE_U_LongLong &);
    ACE_U_LongLong &operator-= (const ACE_U_LongLong &);
    ACE_U_LongLong &operator++ ();
    ACE_U_LongLong &operator-- ();
    ACE_U_LongLong &operator|= (const ACE_U_LongLong);
    ACE_U_LongLong &operator&= (const ACE_U_LongLong);

    // Note that the following take ACE_UINT32 arguments.  These are
    // typical use cases, and easy to implement.  But, they limit the
    // return values to 32 bits as well.  There are no checks for
    // overflow.
    ACE_UINT32 operator/ (const ACE_UINT32) const;
    ACE_UINT32 operator% (const ACE_UINT32) const;

    // The following only operate on the lower 32 bits (they take only
    // 32 bit arguments).
    ACE_UINT32 operator| (const ACE_INT32) const;
    ACE_UINT32 operator& (const ACE_INT32) const;

    // The following operators convert their arguments to
    // ACE_UINT32.  So, there may be information loss if they are
    // used.
    ACE_U_LongLong operator* (const ACE_INT32);
    ACE_U_LongLong &operator*= (const ACE_INT32);
    ACE_UINT32 operator/ (const ACE_INT32) const;
#if ACE_SIZEOF_INT == 4
    ACE_UINT32 operator/ (const u_long) const;
    ACE_UINT32 operator/ (const long) const;
#else  /* ACE_SIZEOF_INT != 4 */
    ACE_UINT32 operator/ (const u_int) const;
    ACE_UINT32 operator/ (const int) const;
#endif /* ACE_SIZEOF_INT != 4 */

    // = Helper methods.
    void output (FILE * = stdout) const;
    // Outputs the value to the FILE, in hex.

    ACE_UINT32 hi (void) const;
    ACE_UINT32 lo (void) const;

    void hi (const ACE_UINT32 hi);
    void lo (const ACE_UINT32 lo);

    ACE_ALLOC_HOOK_DECLARE;

  private:
    ACE_UINT32 hi_;
    // High 32 bits.
    ACE_UINT32 lo_;
    // Low 32 bits.

    ACE_UINT32 ul_shift (ACE_UINT32 a, ACE_UINT32 c_in, ACE_UINT32 *c_out);
    ACE_U_LongLong ull_shift (ACE_U_LongLong a, ACE_UINT32 c_in,
                              ACE_UINT32 *c_out);
    ACE_U_LongLong ull_add (ACE_U_LongLong a, ACE_U_LongLong b,
                            ACE_UINT32 *carry);
    ACE_U_LongLong ull_mult (ACE_U_LongLong a, ACE_UINT32 b,
                             ACE_UINT32 *carry);
    // These functions are used to implement multiplication.
  };

  typedef ACE_U_LongLong ACE_UINT64;

#endif /* ACE_LACKS_LONGLONG_T */


// The number of bytes in a void *.
#ifndef ACE_SIZEOF_VOID_P
#define ACE_SIZEOF_VOID_P ACE_SIZEOF_LONG
#endif /* ACE_SIZEOF_VOID_P */

// The number of bytes in a float.
#ifndef ACE_SIZEOF_FLOAT
#  if FLT_MAX_EXP == 128
#    define ACE_SIZEOF_FLOAT 4
#  elif FLT_MAX_EXP == 1024
#    define ACE_SIZEOF_FLOAT 8
#  else
#    error: unsupported float size, must be updated for this platform!
#  endif /* FLT_MAX_EXP */
#endif /* ACE_SIZEOF_FLOAT */

// The number of bytes in a double.
#ifndef ACE_SIZEOF_DOUBLE
#  if DBL_MAX_EXP == 128
#    define ACE_SIZEOF_DOUBLE 4
#  elif DBL_MAX_EXP == 1024
#    define ACE_SIZEOF_DOUBLE 8
#  else
#    error: unsupported double size, must be updated for this platform!
#  endif /* DBL_MAX_EXP */
#endif /* ACE_SIZEOF_DOUBLE */

// The number of bytes in a long double.
#ifndef ACE_SIZEOF_LONG_DOUBLE
#  if LDBL_MAX_EXP == 128
#    define ACE_SIZEOF_LONG_DOUBLE 4
#  elif LDBL_MAX_EXP == 1024
#    define ACE_SIZEOF_LONG_DOUBLE 8
#  elif LDBL_MAX_EXP == 16384
#    define ACE_SIZEOF_LONG_DOUBLE 16
#  else
#    error: unsupported double size, must be updated for this platform!
#  endif /* LDBL_MAX_EXP */
#endif /* ACE_SIZEOF_LONG_DOUBLE */

// Byte-order (endian-ness) determination.
#if defined (BYTE_ORDER)
# if (BYTE_ORDER == LITTLE_ENDIAN)
#  define ACE_LITTLE_ENDIAN 0123X
#  define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
# elif (BYTE_ORDER == BIG_ENDIAN)
#  define ACE_BIG_ENDIAN 3210X
#  define ACE_BYTE_ORDER ACE_BIG_ENDIAN
# else
#  error: unknown BYTE_ORDER!
# endif /* BYTE_ORDER */
#elif defined (__BYTE_ORDER)
# if (__BYTE_ORDER == __LITTLE_ENDIAN)
#  define ACE_LITTLE_ENDIAN 0123X
#  define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
# elif (__BYTE_ORDER == __BIG_ENDIAN)
#  define ACE_BIG_ENDIAN 3210X
#  define ACE_BYTE_ORDER ACE_BIG_ENDIAN
# else
#  error: unknown __BYTE_ORDER!
# endif /* __BYTE_ORDER */
#else /* ! BYTE_ORDER && ! __BYTE_ORDER */
  // We weren't explicitly told, so we have to figure it out . . .
# if defined (i386) || defined (__i386__) || defined (_M_IX86) || \
     defined (vax) || defined (__alpha)
    // We know these are little endian.
#   define ACE_LITTLE_ENDIAN 0123X
#   define ACE_BYTE_ORDER ACE_LITTLE_ENDIAN
# else
    // Otherwise, we'll assume big endian.
#   define ACE_BIG_ENDIAN 3210X
#   define ACE_BYTE_ORDER ACE_BIG_ENDIAN
# endif
#endif /* ! BYTE_ORDER && ! __BYTE_ORDER */

#if defined (__ACE_INLINE__)
# include "ace/Basic_Types.i"
#endif /* __ACE_INLINE__ */

#endif /* ACE_BASIC_TYPES_H */