Coverage Report

Created: 2025-06-13 06:30

/src/wxwidgets/include/wx/longlong.h
Line
Count
Source (jump to first uncovered line)
1
/////////////////////////////////////////////////////////////////////////////
2
// Name:        wx/longlong.h
3
// Purpose:     Legacy support for 64-bit integers predating universal long
4
//              long availability
5
// Author:      Jeffrey C. Ollie <jeff@ollie.clive.ia.us>, Vadim Zeitlin
6
// Created:     10.02.99
7
// Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8
// Licence:     wxWindows licence
9
/////////////////////////////////////////////////////////////////////////////
10
11
#ifndef _WX_LONGLONG_H
12
#define _WX_LONGLONG_H
13
14
#include "wx/defs.h"
15
#include "wx/iosfwrap.h"
16
#include "wx/string.h"
17
18
#include <limits.h>     // for LONG_MAX
19
20
#if wxUSE_STREAMS
21
class WXDLLIMPEXP_FWD_BASE wxTextOutputStream;
22
class WXDLLIMPEXP_FWD_BASE wxTextInputStream;
23
#endif
24
25
class WXDLLIMPEXP_FWD_BASE wxULongLong;
26
27
class WXDLLIMPEXP_BASE wxWARN_UNUSED wxLongLong
28
{
29
public:
30
    // ctors
31
        // default ctor initializes to 0
32
8.28k
    wxLongLong() : m_ll(0) { }
33
        // from long long
34
27.1k
    wxLongLong(wxLongLong_t ll) : m_ll(ll) { }
35
        // from 2 longs
36
    wxLongLong(wxInt32 hi, wxUint32 lo)
37
0
    {
38
        // cast first to avoid precision loss and use unsigned shift to avoid
39
        // undefined behaviour if the high part is negative (and then cast
40
        // again to avoid warning about the possible sign change)
41
0
        m_ll = (wxLongLong_t)(((wxULongLong_t) hi) << 32);
42
0
        m_ll |= (wxLongLong_t) lo;
43
0
    }
44
45
    // default copy ctor is ok
46
47
    // no dtor
48
49
    // assignment operators
50
        // from native 64 bit integer
51
#ifndef wxLongLongIsLong
52
    wxLongLong& operator=(wxLongLong_t ll)
53
0
        { m_ll = ll; return *this; }
54
    wxLongLong& operator=(wxULongLong_t ll)
55
0
        { m_ll = ll; return *this; }
56
#endif // !wxLongLong
57
    wxLongLong& operator=(const wxULongLong &ll);
58
    wxLongLong& operator=(int l)
59
0
        { m_ll = l; return *this; }
60
    wxLongLong& operator=(long l)
61
35.3k
        { m_ll = l; return *this; }
62
    wxLongLong& operator=(unsigned int l)
63
0
        { m_ll = l; return *this; }
64
    wxLongLong& operator=(unsigned long l)
65
0
        { m_ll = l; return *this; }
66
67
68
        // from double: this one has an explicit name because otherwise we
69
        // would have ambiguity with "ll = int" and also because we don't want
70
        // to have implicit conversions between doubles and wxLongLongs
71
    wxLongLong& Assign(double d)
72
0
        { m_ll = (wxLongLong_t)d; return *this; }
73
74
    // assignment operators from wxLongLong is ok
75
76
    // accessors
77
        // get high part
78
    wxInt32 GetHi() const
79
0
        { return wx_truncate_cast(wxInt32, m_ll >> 32); }
80
        // get low part
81
    wxUint32 GetLo() const
82
0
        { return wx_truncate_cast(wxUint32, m_ll); }
83
84
        // get absolute value
85
0
    wxLongLong Abs() const { return wxLongLong(*this).Abs(); }
86
0
    wxLongLong& Abs() { if ( m_ll < 0 ) m_ll = -m_ll; return *this; }
87
88
        // convert to native long long
89
0
    wxLongLong_t GetValue() const { return m_ll; }
90
91
        // convert to long with range checking in debug mode (only!)
92
    long ToLong() const
93
0
    {
94
        // This assert is useless if long long is the same as long (which is
95
        // the case under the standard Unix LP64 model).
96
0
#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG
97
0
        wxASSERT_MSG( (m_ll >= LONG_MIN) && (m_ll <= LONG_MAX),
98
0
                      wxT("wxLongLong to long conversion loss of precision") );
99
0
#endif
100
101
0
        return wx_truncate_cast(long, m_ll);
102
0
    }
103
104
        // convert to double
105
0
    double ToDouble() const { return wx_truncate_cast(double, m_ll); }
106
107
    // don't provide implicit conversion to wxLongLong_t or we will have an
108
    // ambiguity for all arithmetic operations
109
    //operator wxLongLong_t() const { return m_ll; }
110
111
    // operations
112
        // addition
113
    wxLongLong operator+(const wxLongLong& ll) const
114
0
        { return wxLongLong(m_ll + ll.m_ll); }
115
    wxLongLong& operator+=(const wxLongLong& ll)
116
30
        { m_ll += ll.m_ll; return *this; }
117
    friend wxLongLong operator+(long l, const wxLongLong& ll)
118
0
        { return ll + l; }
119
120
    wxLongLong operator+(const wxLongLong_t ll) const
121
0
        { return wxLongLong(m_ll + ll); }
122
    wxLongLong& operator+=(const wxLongLong_t ll)
123
10
        { m_ll += ll; return *this; }
124
125
        // pre increment
126
    wxLongLong& operator++()
127
0
        { m_ll++; return *this; }
128
129
        // post increment
130
    wxLongLong operator++(int)
131
0
        { wxLongLong value(*this); m_ll++; return value; }
132
133
        // negation operator
134
    wxLongLong operator-() const
135
0
        { return wxLongLong(-m_ll); }
136
0
    wxLongLong& Negate() { m_ll = -m_ll; return *this; }
137
138
        // subtraction
139
    wxLongLong operator-(const wxLongLong& ll) const
140
0
        { return wxLongLong(m_ll - ll.m_ll); }
141
    wxLongLong& operator-=(const wxLongLong& ll)
142
0
        { m_ll -= ll.m_ll; return *this; }
143
    friend wxLongLong operator-(long l, const wxLongLong& ll)
144
0
    {
145
0
        return wxLongLong(l) - ll;
146
0
    }
147
148
    wxLongLong operator-(const wxLongLong_t ll) const
149
0
        { return wxLongLong(m_ll - ll); }
150
    wxLongLong& operator-=(const wxLongLong_t ll)
151
10
        { m_ll -= ll; return *this; }
152
153
        // pre decrement
154
    wxLongLong& operator--()
155
0
        { m_ll--; return *this; }
156
157
        // post decrement
158
    wxLongLong operator--(int)
159
0
        { wxLongLong value(*this); m_ll--; return value; }
160
161
    // shifts
162
        // left shift
163
    wxLongLong operator<<(int shift) const
164
0
        { return wxLongLong(m_ll << shift); }
165
    wxLongLong& operator<<=(int shift)
166
0
        { m_ll <<= shift; return *this; }
167
168
        // right shift
169
    wxLongLong operator>>(int shift) const
170
0
        { return wxLongLong(m_ll >> shift); }
171
    wxLongLong& operator>>=(int shift)
172
0
        { m_ll >>= shift; return *this; }
173
174
    // bitwise operators
175
    wxLongLong operator&(const wxLongLong& ll) const
176
0
        { return wxLongLong(m_ll & ll.m_ll); }
177
    wxLongLong& operator&=(const wxLongLong& ll)
178
0
        { m_ll &= ll.m_ll; return *this; }
179
180
    wxLongLong operator|(const wxLongLong& ll) const
181
0
        { return wxLongLong(m_ll | ll.m_ll); }
182
    wxLongLong& operator|=(const wxLongLong& ll)
183
0
        { m_ll |= ll.m_ll; return *this; }
184
185
    wxLongLong operator^(const wxLongLong& ll) const
186
0
        { return wxLongLong(m_ll ^ ll.m_ll); }
187
    wxLongLong& operator^=(const wxLongLong& ll)
188
0
        { m_ll ^= ll.m_ll; return *this; }
189
190
    // multiplication/division
191
    wxLongLong operator*(const wxLongLong& ll) const
192
0
        { return wxLongLong(m_ll * ll.m_ll); }
193
    wxLongLong operator*(long l) const
194
0
        { return wxLongLong(m_ll * l); }
195
    wxLongLong& operator*=(const wxLongLong& ll)
196
0
        { m_ll *= ll.m_ll; return *this; }
197
    wxLongLong& operator*=(long l)
198
35.4k
        { m_ll *= l; return *this; }
199
200
    wxLongLong operator/(const wxLongLong& ll) const
201
0
        { return wxLongLong(m_ll / ll.m_ll); }
202
    wxLongLong operator/(long l) const
203
0
        { return wxLongLong(m_ll / l); }
204
    wxLongLong& operator/=(const wxLongLong& ll)
205
0
        { m_ll /= ll.m_ll; return *this; }
206
    wxLongLong& operator/=(long l)
207
0
        { m_ll /= l; return *this; }
208
209
    wxLongLong operator%(const wxLongLong& ll) const
210
0
        { return wxLongLong(m_ll % ll.m_ll); }
211
    wxLongLong operator%(long l) const
212
0
        { return wxLongLong(m_ll % l); }
213
214
    // comparison
215
    bool operator==(const wxLongLong& ll) const
216
0
        { return m_ll == ll.m_ll; }
217
    bool operator==(long l) const
218
0
        { return m_ll == l; }
219
    bool operator!=(const wxLongLong& ll) const
220
10
        { return m_ll != ll.m_ll; }
221
    bool operator!=(long l) const
222
0
        { return m_ll != l; }
223
    bool operator<(const wxLongLong& ll) const
224
0
        { return m_ll < ll.m_ll; }
225
    bool operator<(long l) const
226
0
        { return m_ll < l; }
227
    bool operator>(const wxLongLong& ll) const
228
0
        { return m_ll > ll.m_ll; }
229
    bool operator>(long l) const
230
0
        { return m_ll > l; }
231
    bool operator<=(const wxLongLong& ll) const
232
0
        { return m_ll <= ll.m_ll; }
233
    bool operator<=(long l) const
234
0
        { return m_ll <= l; }
235
    bool operator>=(const wxLongLong& ll) const
236
0
        { return m_ll >= ll.m_ll; }
237
    bool operator>=(long l) const
238
0
        { return m_ll >= l; }
239
240
0
    friend bool operator<(long l, const wxLongLong& ll) { return ll > l; }
241
0
    friend bool operator>(long l, const wxLongLong& ll) { return ll < l; }
242
0
    friend bool operator<=(long l, const wxLongLong& ll) { return ll >= l; }
243
0
    friend bool operator>=(long l, const wxLongLong& ll) { return ll <= l; }
244
0
    friend bool operator==(long l, const wxLongLong& ll) { return ll == l; }
245
0
    friend bool operator!=(long l, const wxLongLong& ll) { return ll != l; }
246
247
    // miscellaneous
248
249
        // return the string representation of this number
250
    wxString ToString() const
251
0
    {
252
0
        return wxString::Format(wxASCII_STR("%" wxLongLongFmtSpec "d"), m_ll);
253
0
    }
254
255
        // conversion to byte array: returns a pointer to static buffer!
256
    void *asArray() const;
257
258
#if wxUSE_STD_IOSTREAM
259
        // input/output
260
    friend WXDLLIMPEXP_BASE
261
    std::ostream& operator<<(std::ostream&, const wxLongLong&);
262
#endif
263
264
    friend WXDLLIMPEXP_BASE
265
    wxString& operator<<(wxString&, const wxLongLong&);
266
267
#if wxUSE_STREAMS
268
    friend WXDLLIMPEXP_BASE
269
    class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLong&);
270
    friend WXDLLIMPEXP_BASE
271
    class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLong&);
272
#endif
273
274
private:
275
    wxLongLong_t  m_ll;
276
};
277
278
class WXDLLIMPEXP_BASE wxWARN_UNUSED wxULongLong
279
{
280
public:
281
    // ctors
282
        // default ctor initializes to 0
283
0
    wxULongLong() : m_ll(0) { }
284
        // from long long
285
2
    wxULongLong(wxULongLong_t ll) : m_ll(ll) { }
286
        // from 2 longs
287
0
    wxULongLong(wxUint32 hi, wxUint32 lo) : m_ll(0)
288
0
    {
289
        // cast to wxLongLong_t first to avoid precision loss!
290
0
        m_ll = ((wxULongLong_t) hi) << 32;
291
0
        m_ll |= (wxULongLong_t) lo;
292
0
    }
293
294
    // default copy ctor is ok
295
296
    // no dtor
297
298
    // assignment operators
299
        // from native 64 bit integer
300
#ifndef wxLongLongIsLong
301
    wxULongLong& operator=(wxULongLong_t ll)
302
0
        { m_ll = ll; return *this; }
303
    wxULongLong& operator=(wxLongLong_t ll)
304
0
        { m_ll = ll; return *this; }
305
#endif // !wxLongLong
306
    wxULongLong& operator=(int l)
307
0
        { m_ll = l; return *this; }
308
    wxULongLong& operator=(long l)
309
0
        { m_ll = l; return *this; }
310
    wxULongLong& operator=(unsigned int l)
311
0
        { m_ll = l; return *this; }
312
    wxULongLong& operator=(unsigned long l)
313
0
        { m_ll = l; return *this; }
314
    wxULongLong& operator=(const wxLongLong &ll)
315
0
        { m_ll = ll.GetValue(); return *this; }
316
317
    // assignment operators from wxULongLong is ok
318
319
    // accessors
320
        // get high part
321
    wxUint32 GetHi() const
322
0
        { return wx_truncate_cast(wxUint32, m_ll >> 32); }
323
        // get low part
324
    wxUint32 GetLo() const
325
0
        { return wx_truncate_cast(wxUint32, m_ll); }
326
327
        // convert to native ulong long
328
0
    wxULongLong_t GetValue() const { return m_ll; }
329
330
        // convert to ulong with range checking in debug mode (only!)
331
    unsigned long ToULong() const
332
0
    {
333
0
        wxASSERT_MSG( m_ll <= ULONG_MAX,
334
0
                      wxT("wxULongLong to long conversion loss of precision") );
335
336
0
        return wx_truncate_cast(unsigned long, m_ll);
337
0
    }
338
339
        // convert to double
340
0
    double ToDouble() const { return wx_truncate_cast(double, m_ll); }
341
342
    // operations
343
        // addition
344
    wxULongLong operator+(const wxULongLong& ll) const
345
0
        { return wxULongLong(m_ll + ll.m_ll); }
346
    wxULongLong& operator+=(const wxULongLong& ll)
347
0
        { m_ll += ll.m_ll; return *this; }
348
    friend wxULongLong operator+(unsigned long l, const wxULongLong& ull)
349
0
        { return ull + l; }
350
351
    wxULongLong operator+(const wxULongLong_t ll) const
352
0
        { return wxULongLong(m_ll + ll); }
353
    wxULongLong& operator+=(const wxULongLong_t ll)
354
0
        { m_ll += ll; return *this; }
355
356
        // pre increment
357
    wxULongLong& operator++()
358
0
        { m_ll++; return *this; }
359
360
        // post increment
361
    wxULongLong operator++(int)
362
0
        { wxULongLong value(*this); m_ll++; return value; }
363
364
        // subtraction
365
    wxULongLong operator-(const wxULongLong& ll) const
366
0
        { return wxULongLong(m_ll - ll.m_ll); }
367
    wxULongLong& operator-=(const wxULongLong& ll)
368
0
        { m_ll -= ll.m_ll; return *this; }
369
    friend wxULongLong operator-(unsigned long l, const wxULongLong& ull)
370
0
    {
371
0
        return wxULongLong(l - ull.m_ll);
372
0
    }
373
374
    wxULongLong operator-(const wxULongLong_t ll) const
375
0
        { return wxULongLong(m_ll - ll); }
376
    wxULongLong& operator-=(const wxULongLong_t ll)
377
0
        { m_ll -= ll; return *this; }
378
379
        // pre decrement
380
    wxULongLong& operator--()
381
0
        { m_ll--; return *this; }
382
383
        // post decrement
384
    wxULongLong operator--(int)
385
0
        { wxULongLong value(*this); m_ll--; return value; }
386
387
    // shifts
388
        // left shift
389
    wxULongLong operator<<(int shift) const
390
0
        { return wxULongLong(m_ll << shift); }
391
    wxULongLong& operator<<=(int shift)
392
0
        { m_ll <<= shift; return *this; }
393
394
        // right shift
395
    wxULongLong operator>>(int shift) const
396
0
        { return wxULongLong(m_ll >> shift); }
397
    wxULongLong& operator>>=(int shift)
398
0
        { m_ll >>= shift; return *this; }
399
400
    // bitwise operators
401
    wxULongLong operator&(const wxULongLong& ll) const
402
0
        { return wxULongLong(m_ll & ll.m_ll); }
403
    wxULongLong& operator&=(const wxULongLong& ll)
404
0
        { m_ll &= ll.m_ll; return *this; }
405
406
    wxULongLong operator|(const wxULongLong& ll) const
407
0
        { return wxULongLong(m_ll | ll.m_ll); }
408
    wxULongLong& operator|=(const wxULongLong& ll)
409
0
        { m_ll |= ll.m_ll; return *this; }
410
411
    wxULongLong operator^(const wxULongLong& ll) const
412
0
        { return wxULongLong(m_ll ^ ll.m_ll); }
413
    wxULongLong& operator^=(const wxULongLong& ll)
414
0
        { m_ll ^= ll.m_ll; return *this; }
415
416
    // multiplication/division
417
    wxULongLong operator*(const wxULongLong& ll) const
418
0
        { return wxULongLong(m_ll * ll.m_ll); }
419
    wxULongLong operator*(unsigned long l) const
420
0
        { return wxULongLong(m_ll * l); }
421
    wxULongLong& operator*=(const wxULongLong& ll)
422
0
        { m_ll *= ll.m_ll; return *this; }
423
    wxULongLong& operator*=(unsigned long l)
424
0
        { m_ll *= l; return *this; }
425
426
    wxULongLong operator/(const wxULongLong& ll) const
427
0
        { return wxULongLong(m_ll / ll.m_ll); }
428
    wxULongLong operator/(unsigned long l) const
429
0
        { return wxULongLong(m_ll / l); }
430
    wxULongLong& operator/=(const wxULongLong& ll)
431
0
        { m_ll /= ll.m_ll; return *this; }
432
    wxULongLong& operator/=(unsigned long l)
433
0
        { m_ll /= l; return *this; }
434
435
    wxULongLong operator%(const wxULongLong& ll) const
436
0
        { return wxULongLong(m_ll % ll.m_ll); }
437
    wxULongLong operator%(unsigned long l) const
438
0
        { return wxULongLong(m_ll % l); }
439
440
    // comparison
441
    bool operator==(const wxULongLong& ll) const
442
0
        { return m_ll == ll.m_ll; }
443
    bool operator==(unsigned long l) const
444
0
        { return m_ll == l; }
445
    bool operator!=(const wxULongLong& ll) const
446
0
        { return m_ll != ll.m_ll; }
447
    bool operator!=(unsigned long l) const
448
0
        { return m_ll != l; }
449
    bool operator<(const wxULongLong& ll) const
450
0
        { return m_ll < ll.m_ll; }
451
    bool operator<(unsigned long l) const
452
0
        { return m_ll < l; }
453
    bool operator>(const wxULongLong& ll) const
454
0
        { return m_ll > ll.m_ll; }
455
    bool operator>(unsigned long l) const
456
0
        { return m_ll > l; }
457
    bool operator<=(const wxULongLong& ll) const
458
0
        { return m_ll <= ll.m_ll; }
459
    bool operator<=(unsigned long l) const
460
0
        { return m_ll <= l; }
461
    bool operator>=(const wxULongLong& ll) const
462
0
        { return m_ll >= ll.m_ll; }
463
    bool operator>=(unsigned long l) const
464
0
        { return m_ll >= l; }
465
466
0
    friend bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; }
467
0
    friend bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; }
468
0
    friend bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; }
469
0
    friend bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; }
470
0
    friend bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; }
471
0
    friend bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; }
472
473
    // miscellaneous
474
475
        // return the string representation of this number
476
    wxString ToString() const
477
0
    {
478
0
        return wxString::Format(wxASCII_STR("%" wxLongLongFmtSpec "u"), m_ll);
479
0
    }
480
481
        // conversion to byte array: returns a pointer to static buffer!
482
    void *asArray() const;
483
484
#if wxUSE_STD_IOSTREAM
485
        // input/output
486
    friend WXDLLIMPEXP_BASE
487
    std::ostream& operator<<(std::ostream&, const wxULongLong&);
488
#endif
489
490
    friend WXDLLIMPEXP_BASE
491
    wxString& operator<<(wxString&, const wxULongLong&);
492
493
#if wxUSE_STREAMS
494
    friend WXDLLIMPEXP_BASE
495
    class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLong&);
496
    friend WXDLLIMPEXP_BASE
497
    class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLong&);
498
#endif
499
500
private:
501
    wxULongLong_t  m_ll;
502
};
503
504
inline
505
wxLongLong& wxLongLong::operator=(const wxULongLong &ll)
506
0
{
507
0
    m_ll = ll.GetValue();
508
0
    return *this;
509
0
}
510
511
// ----------------------------------------------------------------------------
512
// Specialize numeric_limits<> for our long long wrapper classes.
513
// ----------------------------------------------------------------------------
514
515
#include <limits>
516
517
namespace std
518
{
519
520
template<> struct numeric_limits<wxLongLong>  : numeric_limits<wxLongLong_t> {};
521
template<> struct numeric_limits<wxULongLong> : numeric_limits<wxULongLong_t> {};
522
523
} // namespace std
524
525
// ----------------------------------------------------------------------------
526
// Specialize wxArgNormalizer to allow using wxLongLong directly with wx pseudo
527
// vararg functions.
528
// ----------------------------------------------------------------------------
529
530
// Notice that this must be done here and not in wx/strvararg.h itself because
531
// we can't include wx/longlong.h from there as this header itself includes
532
// wx/string.h which includes wx/strvararg.h too, so to avoid the circular
533
// dependencies we can only do it here (or add another header just for this but
534
// it doesn't seem necessary).
535
#include "wx/strvararg.h"
536
537
template<>
538
struct wxFormatStringSpecifier<wxLongLong>
539
{
540
    enum { value = wxFormatString::Arg_LongLongInt };
541
};
542
543
template<>
544
struct WXDLLIMPEXP_BASE wxArgNormalizer<wxLongLong>
545
{
546
     wxArgNormalizer(wxLongLong value,
547
                     const wxFormatString *fmt, unsigned index)
548
         : m_value(value)
549
0
     {
550
0
         wxASSERT_ARG_TYPE( fmt, index, wxFormatString::Arg_LongLongInt );
551
0
     }
552
553
0
     wxLongLong_t get() const { return m_value.GetValue(); }
554
555
     wxLongLong m_value;
556
};
557
558
// Compatibility typedefs: these types were never supposed to be used outside
559
// of wx itself but nevertheless appear in the existing code, so define them to
560
// let it continue to build.
561
using wxLongLongNative = wxLongLong;
562
using wxULongLongNative = wxULongLong;
563
564
#endif // _WX_LONGLONG_H