ReactOS 0.4.16-dev-1025-gd3456f5
safeint.h
Go to the documentation of this file.
1/***
2*safeint.h - SafeInt class and free-standing functions used to prevent arithmetic overflows
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7*
8* The SafeInt class is designed to have as low an overhead as possible
9* while still ensuring that all integer operations are conducted safely.
10* Nearly every operator has been overloaded, with a very few exceptions.
11*
12* A usability-safety trade-off has been made to help ensure safety. This
13* requires that every operation return either a SafeInt or a bool. If we
14* allowed an operator to return a base integer type T, then the following
15* can happen:
16*
17* char i = SafeInt<char>(32) * 2 + SafeInt<char>(16) * 4;
18*
19* The * operators take precedence, get overloaded, return a char, and then
20* you have:
21*
22* char i = (char)64 + (char)64; //overflow!
23*
24* This situation would mean that safety would depend on usage, which isn't
25* acceptable.
26*
27* One key operator that is missing is an implicit cast to type T. The reason for
28* this is that if there is an implicit cast operator, then we end up with
29* an ambiguous compile-time precedence. Because of this amiguity, there
30* are two methods that are provided:
31*
32* Casting operators for every native integer type
33*
34* SafeInt::Ptr() - returns the address of the internal integer
35*
36* The SafeInt class should be used in any circumstances where ensuring
37* integrity of the calculations is more important than performance. See Performance
38* Notes below for additional information.
39*
40* Many of the conditionals will optimize out or be inlined for a release
41* build (especially with /Ox), but it does have significantly more overhead,
42* especially for signed numbers. If you do not _require_ negative numbers, use
43* unsigned integer types - certain types of problems cannot occur, and this class
44* performs most efficiently.
45*
46* Here's an example of when the class should ideally be used -
47*
48* void* AllocateMemForStructs(int StructSize, int HowMany)
49* {
50* SafeInt<unsigned long> s(StructSize);
51*
52* s *= HowMany;
53*
54* return malloc(s);
55*
56* }
57*
58* Here's when it should NOT be used:
59*
60* void foo()
61* {
62* int i;
63*
64* for(i = 0; i < 0xffff; i++)
65* ....
66* }
67*
68* Error handling - a SafeInt class will throw exceptions if something
69* objectionable happens. The exceptions are SafeIntException classes,
70* which contain an enum as a code.
71*
72* Typical usage might be:
73*
74* bool foo()
75* {
76* SafeInt<unsigned long> s; //note that s == 0 unless set
77*
78* try{
79* s *= 23;
80* ....
81* }
82* catch(SafeIntException err)
83* {
84* //handle errors here
85* }
86* }
87*
88* SafeInt accepts an error policy as an optional template parameter.
89* We provide two error policy along with SafeInt: SafeIntErrorPolicy_SafeIntException, which
90* throws SafeIntException in case of error, and SafeIntErrorPolicy_InvalidParameter, which
91* calls _invalid_parameter to terminate the program.
92*
93* You can replace the error policy class with any class you like. This is accomplished by:
94* 1) Create a class that has the following interface:
95*
96* struct YourSafeIntErrorPolicy
97* {
98* static __declspec(noreturn) void __stdcall SafeIntOnOverflow()
99* {
100* throw YourException( YourSafeIntArithmeticOverflowError );
101* // or do something else which will terminate the program
102* }
103*
104* static __declspec(noreturn) void __stdcall SafeIntOnDivZero()
105* {
106* throw YourException( YourSafeIntDivideByZeroError );
107* // or do something else which will terminate the program
108* }
109* };
110*
111* Note that you don't have to throw C++ exceptions, you can throw Win32 exceptions, or do
112* anything you like, just don't return from the call back into the code.
113*
114* 2) Either explicitly declare SafeInts like so:
115* SafeInt< int, YourSafeIntErrorPolicy > si;
116* or, before including SafeInt:
117* #define _SAFEINT_DEFAULT_ERROR_POLICY ::YourSafeIntErrorPolicy
118*
119* Performance:
120*
121* Due to the highly nested nature of this class, you can expect relatively poor
122* performance in unoptimized code. In tests of optimized code vs. correct inline checks
123* in native code, this class has been found to take approximately 8% more CPU time (this varies),
124* most of which is due to exception handling.
125*
126* Binary Operators:
127*
128* All of the binary operators have certain assumptions built into the class design.
129* This is to ensure correctness. Notes on each class of operator follow:
130*
131* Arithmetic Operators (*,/,+,-,%)
132* There are three possible variants:
133* SafeInt< T, E > op SafeInt< T, E >
134* SafeInt< T, E > op U
135* U op SafeInt< T, E >
136*
137* The SafeInt< T, E > op SafeInt< U, E > variant is explicitly not supported, and if you try to do
138* this the compiler with throw the following error:
139*
140* error C2593: 'operator *' is ambiguous
141*
142* This is because the arithmetic operators are required to return a SafeInt of some type.
143* The compiler cannot know whether you'd prefer to get a type T or a type U returned. If
144* you need to do this, you need to extract the value contained within one of the two using
145* the casting operator. For example:
146*
147* SafeInt< T, E > t, result;
148* SafeInt< U, E > u;
149*
150* result = t * (U)u;
151*
152* Comparison Operators:
153*
154* Because each of these operators return type bool, mixing SafeInts of differing types is
155* allowed.
156*
157* Shift Operators:
158*
159* Shift operators always return the type on the left hand side of the operator. Mixed type
160* operations are allowed because the return type is always known.
161*
162* Boolean Operators:
163*
164* Like comparison operators, these overloads always return type bool, and mixed-type SafeInts
165* are allowed. Additionally, specific overloads exist for type bool on both sides of the
166* operator.
167*
168* Binary Operators:
169*
170* Mixed-type operations are discouraged, however some provision has been made in order to
171* enable things like:
172*
173* SafeInt<char> c = 2;
174*
175* if(c & 0x02)
176* ...
177*
178* The "0x02" is actually an int, and it needs to work.
179* In the case of binary operations on integers smaller than 32-bit, or of mixed type, corner
180* cases do exist where you could get unexpected results. In any case where SafeInt returns a different
181* result than the underlying operator, it will call _ASSERTE(). You should examine your code and cast things
182* properly so that you are not programming with side effects.
183*
184* Comparison Operators and ANSI Conversions:
185*
186* The comparison operator behavior in this class varies from the ANSI definition.
187* As an example, consider the following:
188*
189* unsigned int l = 0xffffffff;
190* char c = -1;
191*
192* if(c == l)
193* printf("Why is -1 equal to 4 billion???\n");
194*
195* The problem here is that c gets cast to an int, now has a value of 0xffffffff, and then gets
196* cast again to an unsigned int, losing the true value. This behavior is despite the fact that
197* an __int64 exists, and the following code will yield a different (and intuitively correct)
198* answer:
199*
200* if((__int64)c == (__int64)l))
201* printf("Why is -1 equal to 4 billion???\n");
202* else
203* printf("Why doesn't the compiler upcast to 64-bits when needed?\n");
204*
205* Note that combinations with smaller integers won't display the problem - if you
206* changed "unsigned int" above to "unsigned short", you'd get the right answer.
207*
208* If you prefer to retain the ANSI standard behavior insert, before including safeint.h:
209*
210* #define _SAFEINT_ANSI_CONVERSIONS 1
211*
212* into your source. Behavior differences occur in the following cases:
213* 8, 16, and 32-bit signed int, unsigned 32-bit int
214* any signed int, unsigned 64-bit int
215* Note - the signed int must be negative to show the problem
216*
217****/
218
219#pragma once
220
221#if !defined(RC_INVOKED)
222
223#include <corecrt.h>
224#include <crtdbg.h>
225
226// Disable warnings hit under /Wall:
227// C4514: unreferenced inline function has been removed (/Wall)
228// C4710: function not inlined (/Wall)
229#pragma warning(push)
230#pragma warning(disable: 4514)
231#pragma warning(disable: 4710)
232
233#if !defined (_SAFEINT_DEFAULT_ERROR_POLICY)
234#define _SAFEINT_DEFAULT_ERROR_POLICY SafeIntErrorPolicy_SafeIntException
235#endif /* !defined (_SAFEINT_DEFAULT_ERROR_POLICY) */
236
237#if !defined (_SAFEINT_SHIFT_ASSERT)
238#define _SAFEINT_SHIFT_ASSERT(x) _ASSERTE(x)
239#endif /* !defined (_SAFEINT_SHIFT_ASSERT) */
240
241#if !defined (_SAFEINT_BINARY_ASSERT)
242#define _SAFEINT_BINARY_ASSERT(x) _ASSERTE(x)
243#endif /* !defined (_SAFEINT_BINARY_ASSERT) */
244
245#if !defined (_SAFEINT_EXCEPTION_ASSERT)
246#define _SAFEINT_EXCEPTION_ASSERT()
247#endif /* !defined (_SAFEINT_EXCEPTION_ASSERT) */
248
249// by default, SafeInt will accept negation of an unsigned int;
250// if you wish to disable it or assert, you can define the following
251// macro to be a static assert or a runtime assert
252#if !defined (_SAFEINT_UNSIGNED_NEGATION_BEHAVIOR)
253#define _SAFEINT_UNSIGNED_NEGATION_BEHAVIOR()
254#endif /* !defined (_SAFEINT_UNSIGNED_NEGATION_BEHAVIOR) */
255
256// See above "Comparison Operators and ANSI Conversions" for an explanation
257// of _SAFEINT_USE_ANSI_CONVERSIONS
258#if !defined (_SAFEINT_USE_ANSI_CONVERSIONS)
259#define _SAFEINT_USE_ANSI_CONVERSIONS 0
260#endif /* !defined (_SAFEINT_USE_ANSI_CONVERSIONS) */
261
262#pragma pack(push, _CRT_PACKING)
263
264namespace msl
265{
266
267namespace utilities
268{
269
271{
276
277} // namespace utilities
278
279} // namespace msl
280
281#include "safeint_internal.h"
282
283namespace msl
284{
285
286namespace utilities
287{
288
290{
291public:
294 {
295 m_code = code;
296 }
298};
299
301{
302 static __declspec(noreturn) void SafeIntOnOverflow()
303 {
306 }
307
308 static __declspec(noreturn) void SafeIntOnDivZero()
309 {
312 }
313};
314
316{
317 static __declspec(noreturn) void SafeIntOnOverflow()
318 {
320 _CRT_SECURE_INVALID_PARAMETER("SafeInt Arithmetic Overflow");
321 }
322
323 static __declspec(noreturn) void SafeIntOnDivZero()
324 {
326 _CRT_SECURE_INVALID_PARAMETER("SafeInt Divide By Zero");
327 }
328};
329
330// Free-standing functions that can be used where you only need to check one operation
331// non-class helper function so that you can check for a cast's validity
332// and handle errors how you like
333
334template < typename T, typename U >
335inline bool SafeCast( const T From, U& To ) throw()
336{
337 return (details::SafeCastHelper< U, T,
339}
340
341template < typename T, typename U >
342inline bool SafeEquals( const T t, const U u ) throw()
343{
345}
346
347template < typename T, typename U >
348inline bool SafeNotEquals( const T t, const U u ) throw()
349{
351}
352
353template < typename T, typename U >
354inline bool SafeGreaterThan( const T t, const U u ) throw()
355{
357}
358
359template < typename T, typename U >
360inline bool SafeGreaterThanEquals( const T t, const U u ) throw()
361{
363}
364
365template < typename T, typename U >
366inline bool SafeLessThan( const T t, const U u ) throw()
367{
369}
370
371template < typename T, typename U >
372inline bool SafeLessThanEquals( const T t, const U u ) throw()
373{
375}
376
377template < typename T, typename U >
378inline bool SafeModulus( const T& t, const U& u, T& result ) throw()
379{
381}
382
383template < typename T, typename U >
384inline bool SafeMultiply( T t, U u, T& result ) throw()
385{
388}
389
390template < typename T, typename U >
391inline bool SafeDivide( T t, U u, T& result ) throw()
392{
393 return ( details::DivisionHelper< T, U,
395}
396
397template < typename T, typename U >
398inline bool SafeAdd( T t, U u, T& result ) throw()
399{
400 return ( details::AdditionHelper< T, U,
402}
403
404template < typename T, typename U >
405inline bool SafeSubtract( T t, U u, T& result ) throw()
406{
407 return ( details::SubtractionHelper< T, U,
409}
410
411// SafeInt class
412template < typename T, typename E = _SAFEINT_DEFAULT_ERROR_POLICY >
414{
415public:
417 {
418 static_assert( details::NumericType< T >::isInt , "SafeInt<T>: T needs to be an integer type" );
419 m_int = 0;
420 }
421
422 // Having a constructor for every type of int
423 // avoids having the compiler evade our checks when doing implicit casts -
424 // e.g., SafeInt<char> s = 0x7fffffff;
425 SafeInt( const T& i ) throw()
426 {
427 static_assert( details::NumericType< T >::isInt , "SafeInt<T>: T needs to be an integer type" );
428 //always safe
429 m_int = i;
430 }
431
432 // provide explicit boolean converter
433 SafeInt( bool b ) throw()
434 {
435 static_assert( details::NumericType< T >::isInt , "SafeInt<T>: T needs to be an integer type" );
436 m_int = b ? 1 : 0;
437 }
438
439 template < typename U >
441 {
442 static_assert( details::NumericType< T >::isInt , "SafeInt<T>: T needs to be an integer type" );
443 *this = SafeInt< T, E >( (U)u );
444 }
445
446 template < typename U >
447 SafeInt( const U& i )
448 {
449 static_assert( details::NumericType< T >::isInt , "SafeInt<T>: T needs to be an integer type" );
450 // SafeCast will throw exceptions if i won't fit in type T
452 }
453
454 // now start overloading operators
455 // assignment operator
456 // constructors exist for all int types and will ensure safety
457
458 template < typename U >
460 {
461 // use constructor to test size
462 // constructor is optimized to do minimal checking based
463 // on whether T can contain U
464 // note - do not change this
465 *this = SafeInt< T, E >( rhs );
466 return *this;
467 }
468
469 SafeInt< T, E >& operator =( const T& rhs ) throw()
470 {
471 m_int = rhs;
472 return *this;
473 }
474
475 template < typename U >
477 {
479 return *this;
480 }
481
483 {
484 m_int = rhs.m_int;
485 return *this;
486 }
487
488 // Casting operators
489
490 operator bool() const throw()
491 {
492 return !!m_int;
493 }
494
495 operator char() const
496 {
497 char val;
499 return val;
500 }
501
502 operator signed char() const
503 {
504 signed char val;
506 return val;
507 }
508
509 operator unsigned char() const
510 {
511 unsigned char val;
513 return val;
514 }
515
516 operator __int16() const
517 {
518 __int16 val;
520 return val;
521 }
522
523 operator unsigned __int16() const
524 {
525 unsigned __int16 val;
527 return val;
528 }
529
530 operator __int32() const
531 {
532 __int32 val;
534 return val;
535 }
536
537 operator unsigned __int32() const
538 {
539 unsigned __int32 val;
541 return val;
542 }
543
544 // The compiler knows that int == __int32
545 // but not that long == __int32
546 operator long() const
547 {
548 long val;
550 return val;
551 }
552
553 operator unsigned long() const
554 {
555 unsigned long val;
557 return val;
558 }
559
560 operator __int64() const
561 {
562 __int64 val;
564 return val;
565 }
566
567 operator unsigned __int64() const
568 {
569 unsigned __int64 val;
571 return val;
572 }
573
574#ifdef _NATIVE_WCHAR_T_DEFINED
575 operator wchar_t() const
576 {
577 unsigned __int16 val;
579 return val;
580 }
581#endif /* _NATIVE_WCHAR_T_DEFINED */
582
583 // If you need a pointer to the data
584 // this could be dangerous, but allows you to correctly pass
585 // instances of this class to APIs that take a pointer to an integer
586 // also see overloaded address-of operator below
587 T* Ptr() throw() { return &m_int; }
588 const T* Ptr() const throw() { return &m_int; }
589 const T& Ref() const throw() { return m_int; }
590
591 // Unary operators
592 bool operator !() const throw() { return (!m_int) ? true : false; }
593
594 // operator + (unary)
595 // note - normally, the '+' and '-' operators will upcast to a signed int
596 // for T < 32 bits. This class changes behavior to preserve type
597 const SafeInt< T, E >& operator +() const throw() { return *this; };
598
599 //unary -
601 {
602 // Note - unsigned still performs the bitwise manipulation
603 // will warn at level 2 or higher if the value is 32-bit or larger
604 T tmp;
606 return SafeInt< T, E >( tmp );
607 }
608
609 // prefix increment operator
611 {
613 {
614 ++m_int;
615 return *this;
616 }
617 E::SafeIntOnOverflow();
618 }
619
620 // prefix decrement operator
622 {
624 {
625 --m_int;
626 return *this;
627 }
628 E::SafeIntOnOverflow();
629 }
630
631 // note that postfix operators have inherently worse perf
632 // characteristics
633
634 // postfix increment operator
635 SafeInt< T, E > operator ++( int ) // dummy arg to comply with spec
636 {
638 {
639 SafeInt< T, E > tmp( m_int );
640
641 m_int++;
642 return tmp;
643 }
644 E::SafeIntOnOverflow();
645 }
646
647 // postfix decrement operator
648 SafeInt< T, E > operator --( int ) // dummy arg to comply with spec
649 {
651 {
652 SafeInt< T, E > tmp( m_int );
653 m_int--;
654 return tmp;
655 }
656 E::SafeIntOnOverflow();
657 }
658
659 // One's complement
660 // Note - this operator will normally change size to an int
661 // cast in return improves perf and maintains type
663
664 // Binary operators
665 //
666 // arithmetic binary operators
667 // % modulus
668 // * multiplication
669 // / division
670 // + addition
671 // - subtraction
672 //
673 // For each of the arithmetic operators, you will need to
674 // use them as follows:
675 //
676 // SafeInt<char> c = 2;
677 // SafeInt<int> i = 3;
678 //
679 // SafeInt<int> i2 = i op (char)c;
680 // OR
681 // SafeInt<char> i2 = (int)i op c;
682 //
683 // The base problem is that if the lhs and rhs inputs are different SafeInt types
684 // it is not possible in this implementation to determine what type of SafeInt
685 // should be returned. You have to let the class know which of the two inputs
686 // need to be the return type by forcing the other value to the base integer type.
687 //
688 // Note - as per feedback from Scott Meyers, I'm exploring how to get around this.
689 // 3.0 update - I'm still thinking about this. It can be done with template metaprogramming,
690 // but it is tricky, and there's a perf vs. correctness tradeoff where the right answer
691 // is situational.
692 //
693 // The case of:
694 //
695 // SafeInt< T, E > i, j, k;
696 // i = j op k;
697 //
698 // works just fine and no unboxing is needed because the return type is not ambiguous.
699
700 // Modulus
701 // Modulus has some convenient properties -
702 // first, the magnitude of the return can never be
703 // larger than the lhs operand, and it must be the same sign
704 // as well. It does, however, suffer from the same promotion
705 // problems as comparisons, division and other operations
706 template < typename U >
708 {
709 T result;
711 return SafeInt< T, E >( result );
712 }
713
715 {
716 T result;
718 return SafeInt< T, E >( result );
719 }
720
721 // Modulus assignment
722 template < typename U >
724 {
726 return *this;
727 }
728
729 template < typename U >
731 {
733 return *this;
734 }
735
736 // Multiplication
737 template < typename U >
739 {
740 T ret( 0 );
742 return SafeInt< T, E >( ret );
743 }
744
746 {
747 T ret( 0 );
749 return SafeInt< T, E >( ret );
750 }
751
752 // Multiplication assignment
754 {
756 return *this;
757 }
758
759 template < typename U >
761 {
763 return *this;
764 }
765
766 template < typename U >
768 {
770 return *this;
771 }
772
773 // Division
774 template < typename U >
776 {
777 T ret( 0 );
779 return SafeInt< T, E >( ret );
780 }
781
783 {
784 T ret( 0 );
786 return SafeInt< T, E >( ret );
787 }
788
789 // Division assignment
791 {
793 return *this;
794 }
795
796 template < typename U > SafeInt< T, E >& operator /=( U i )
797 {
799 return *this;
800 }
801
802 template < typename U > SafeInt< T, E >& operator /=( SafeInt< U, E > i )
803 {
805 return *this;
806 }
807
808 // For addition and subtraction
809
810 // Addition
812 {
813 T ret( 0 );
815 return SafeInt< T, E >( ret );
816 }
817
818 template < typename U >
820 {
821 T ret( 0 );
823 return SafeInt< T, E >( ret );
824 }
825
826 //addition assignment
828 {
830 return *this;
831 }
832
833 template < typename U >
835 {
837 return *this;
838 }
839
840 template < typename U >
842 {
844 return *this;
845 }
846
847 // Subtraction
848 template < typename U >
850 {
851 T ret( 0 );
853 return SafeInt< T, E >( ret );
854 }
855
857 {
858 T ret( 0 );
860 return SafeInt< T, E >( ret );
861 }
862
863 // Subtraction assignment
865 {
867 return *this;
868 }
869
870 template < typename U >
872 {
874 return *this;
875 }
876
877 template < typename U >
879 {
881 return *this;
882 }
883
884 // Comparison operators
885 // Additional overloads defined outside the class
886 // to allow for cases where the SafeInt is the rhs value
887
888 // Less than
889 template < typename U >
890 bool operator <( U rhs ) const throw()
891 {
893 }
894
895 bool operator <( SafeInt< T, E > rhs ) const throw()
896 {
897 return m_int < (T)rhs;
898 }
899
900 // Greater than or eq.
901 template < typename U >
902 bool operator >=( U rhs ) const throw()
903 {
905 }
906
907 bool operator >=( SafeInt< T, E > rhs ) const throw()
908 {
909 return m_int >= (T)rhs;
910 }
911
912 // Greater than
913 template < typename U >
914 bool operator >( U rhs ) const throw()
915 {
917 }
918
919 bool operator >( SafeInt< T, E > rhs ) const throw()
920 {
921 return m_int > (T)rhs;
922 }
923
924 // Less than or eq.
925 template < typename U >
926 bool operator <=( U rhs ) const throw()
927 {
929 }
930
931 bool operator <=( SafeInt< T, E > rhs ) const throw()
932 {
933 return m_int <= (T)rhs;
934 }
935
936 // Equality
937 template < typename U >
938 bool operator ==( U rhs ) const throw()
939 {
941 }
942
943 // Need an explicit override for type bool
944 bool operator ==( bool rhs ) const throw()
945 {
946 return ( m_int == 0 ? false : true ) == rhs;
947 }
948
949 bool operator ==( SafeInt< T, E > rhs ) const throw() { return m_int == (T)rhs; }
950
951 // != operators
952 template < typename U >
953 bool operator !=( U rhs ) const throw()
954 {
956 }
957
958 bool operator !=( bool b ) const throw()
959 {
960 return ( m_int == 0 ? false : true ) != b;
961 }
962
963 bool operator !=( SafeInt< T, E > rhs ) const throw() { return m_int != (T)rhs; }
964
965 // Shift operators
966 // Note - shift operators ALWAYS return the same type as the lhs
967 // specific version for SafeInt< T, E > not needed -
968 // code path is exactly the same as for SafeInt< U, E > as rhs
969
970 // Left shift
971 // Also, shifting > bitcount is undefined - trap in debug (check _SAFEINT_SHIFT_ASSERT)
972
973 template < typename U >
974 SafeInt< T, E > operator <<( U bits ) const throw()
975 {
978
979 return SafeInt< T, E >( (T)( m_int << bits ) );
980 }
981
982 template < typename U >
983 SafeInt< T, E > operator <<( SafeInt< U, E > bits ) const throw()
984 {
987
988 return SafeInt< T, E >( (T)( m_int << (U)bits ) );
989 }
990
991 // Left shift assignment
992
993 template < typename U >
994 SafeInt< T, E >& operator <<=( U bits ) throw()
995 {
998
999 m_int <<= bits;
1000 return *this;
1001 }
1002
1003 template < typename U >
1004 SafeInt< T, E >& operator <<=( SafeInt< U, E > bits ) throw()
1005 {
1008
1009 m_int <<= (U)bits;
1010 return *this;
1011 }
1012
1013 // Right shift
1014 template < typename U >
1016 {
1019
1020 return SafeInt< T, E >( (T)( m_int >> bits ) );
1021 }
1022
1023 template < typename U >
1025 {
1028
1029 return SafeInt< T, E >( (T)(m_int >> (U)bits) );
1030 }
1031
1032 // Right shift assignment
1033 template < typename U >
1035 {
1038
1039 m_int >>= bits;
1040 return *this;
1041 }
1042
1043 template < typename U >
1045 {
1048
1049 m_int >>= (U)bits;
1050 return *this;
1051 }
1052
1053 // Bitwise operators
1054 // This only makes sense if we're dealing with the same type and size
1055 // demand a type T, or something that fits into a type T
1056
1057 // Bitwise &
1059 {
1060 return SafeInt< T, E >( m_int & (T)rhs );
1061 }
1062
1063 template < typename U >
1064 SafeInt< T, E > operator &( U rhs ) const throw()
1065 {
1066 // we want to avoid setting bits by surprise
1067 // consider the case of lhs = int, value = 0xffffffff
1068 // rhs = char, value = 0xff
1069 //
1070 // programmer intent is to get only the lower 8 bits
1071 // normal behavior is to upcast both sides to an int
1072 // which then sign extends rhs, setting all the bits
1073
1074 // If you land in the assert, this is because the bitwise operator
1075 // was causing unexpected behavior. Fix is to properly cast your inputs
1076 // so that it works like you meant, not unexpectedly
1077
1079 }
1080
1081 // Bitwise & assignment
1083 {
1084 m_int &= (T)rhs;
1085 return *this;
1086 }
1087
1088 template < typename U >
1090 {
1092 return *this;
1093 }
1094
1095 template < typename U >
1097 {
1099 return *this;
1100 }
1101
1102 // XOR
1104 {
1105 return SafeInt< T, E >( (T)( m_int ^ (T)rhs ) );
1106 }
1107
1108 template < typename U >
1109 SafeInt< T, E > operator ^( U rhs ) const throw()
1110 {
1111 // If you land in the assert, this is because the bitwise operator
1112 // was causing unexpected behavior. Fix is to properly cast your inputs
1113 // so that it works like you meant, not unexpectedly
1114
1116 }
1117
1118 // XOR assignment
1120 {
1121 m_int ^= (T)rhs;
1122 return *this;
1123 }
1124
1125 template < typename U >
1127 {
1129 return *this;
1130 }
1131
1132 template < typename U >
1134 {
1136 return *this;
1137 }
1138
1139 // bitwise OR
1141 {
1142 return SafeInt< T, E >( (T)( m_int | (T)rhs ) );
1143 }
1144
1145 template < typename U >
1146 SafeInt< T, E > operator |( U rhs ) const throw()
1147 {
1149 }
1150
1151 // bitwise OR assignment
1153 {
1154 m_int |= (T)rhs;
1155 return *this;
1156 }
1157
1158 template < typename U >
1160 {
1162 return *this;
1163 }
1164
1165 template < typename U >
1167 {
1169 return *this;
1170 }
1171
1172 // Miscellaneous helper functions
1174 {
1175 T tmp = test < m_int ? test : m_int;
1176 return tmp < floor ? floor : tmp;
1177 }
1178
1180 {
1181 T tmp = test > m_int ? test : m_int;
1182 return tmp > upper ? upper : tmp;
1183 }
1184
1185 void Swap( SafeInt< T, E >& with ) throw()
1186 {
1187 T temp( m_int );
1188 m_int = with.m_int;
1189 with.m_int = temp;
1190 }
1191
1192 template < int bits >
1194 {
1195 // Zero is always aligned
1196 if( m_int == 0 )
1197 return *this;
1198
1199 // We don't support aligning negative numbers at this time
1200 // Can't align unsigned numbers on bitCount (e.g., 8 bits = 256, unsigned char max = 255)
1201 // or signed numbers on bitCount-1 (e.g., 7 bits = 128, signed char max = 127).
1202 // Also makes no sense to try to align on negative or no bits.
1203
1206 bits >= 0 && ( !details::IntTraits<T>::isSigned || m_int > 0 ) );
1207
1208 const T AlignValue = ( (T)1 << bits ) - 1;
1209
1210 m_int = ( m_int + AlignValue ) & ~AlignValue;
1211
1212 if( m_int <= 0 )
1213 E::SafeIntOnOverflow();
1214
1215 return *this;
1216 }
1217
1218 // Commonly needed alignments:
1219 const SafeInt< T, E >& Align2() { return Align< 1 >(); }
1220 const SafeInt< T, E >& Align4() { return Align< 2 >(); }
1221 const SafeInt< T, E >& Align8() { return Align< 3 >(); }
1222 const SafeInt< T, E >& Align16() { return Align< 4 >(); }
1223 const SafeInt< T, E >& Align32() { return Align< 5 >(); }
1224 const SafeInt< T, E >& Align64() { return Align< 6 >(); }
1225
1226private:
1228};
1229
1230// Externally defined functions for the case of U op SafeInt< T, E >
1231template < typename T, typename U, typename E >
1232bool operator <( U lhs, SafeInt< T, E > rhs ) throw()
1233{
1235}
1236
1237template < typename T, typename U, typename E >
1239{
1241}
1242
1243// Greater than
1244template < typename T, typename U, typename E >
1245bool operator >( U lhs, SafeInt< T, E > rhs ) throw()
1246{
1248}
1249
1250template < typename T, typename U, typename E >
1252{
1254}
1255
1256// Greater than or equal
1257template < typename T, typename U, typename E >
1258bool operator >=( U lhs, SafeInt< T, E > rhs ) throw()
1259{
1261}
1262
1263template < typename T, typename U, typename E >
1265{
1267}
1268
1269// Less than or equal
1270template < typename T, typename U, typename E >
1271bool operator <=( U lhs, SafeInt< T, E > rhs ) throw()
1272{
1274}
1275
1276template < typename T, typename U, typename E >
1278{
1280}
1281
1282// equality
1283// explicit overload for bool
1284template < typename T, typename E >
1285bool operator ==( bool lhs, SafeInt< T, E > rhs ) throw()
1286{
1287 return lhs == ( (T)rhs == 0 ? false : true );
1288}
1289
1290template < typename T, typename U, typename E >
1291bool operator ==( U lhs, SafeInt< T, E > rhs ) throw()
1292{
1294}
1295
1296template < typename T, typename U, typename E >
1298{
1299 return details::EqualityTest< T, U >::IsEquals( (T)lhs, (U)rhs );
1300}
1301
1302//not equals
1303template < typename T, typename U, typename E >
1304bool operator !=( U lhs, SafeInt< T, E > rhs ) throw()
1305{
1306 return !details::EqualityTest< T, U >::IsEquals( rhs, lhs );
1307}
1308
1309template < typename T, typename E >
1310bool operator !=( bool lhs, SafeInt< T, E > rhs ) throw()
1311{
1312 return ( (T)rhs == 0 ? false : true ) != lhs;
1313}
1314
1315template < typename T, typename U, typename E >
1317{
1318 return !details::EqualityTest< T, U >::IsEquals( lhs, rhs );
1319}
1320
1321// Modulus
1322template < typename T, typename U, typename E >
1324{
1325 // Value of return depends on sign of lhs
1326 // This one may not be safe - bounds check in constructor
1327 // if lhs is negative and rhs is unsigned, this will throw an exception.
1328
1329 // Fast-track the simple case
1330 // same size and same sign
1331#pragma warning(suppress:4127 6326)
1333 {
1334 if( rhs != 0 )
1335 {
1336 if( details::IntTraits< T >::isSigned && (T)rhs == -1 )
1337 return 0;
1338
1339 return SafeInt< T, E >( (T)( lhs % (T)rhs ) );
1340 }
1341
1342 E::SafeIntOnDivZero();
1343 }
1344
1345 return SafeInt< T, E >( ( SafeInt< U, E >( lhs ) % (T)rhs ) );
1346}
1347
1348// Multiplication
1349template < typename T, typename U, typename E >
1351{
1352 T ret( 0 );
1354 return SafeInt< T, E >(ret);
1355}
1356
1357// Division
1358template < typename T, typename U, typename E > SafeInt< T, E > operator /( U lhs, SafeInt< T, E > rhs )
1359{
1360#pragma warning(push)
1361#pragma warning(disable: 4127 4146 4307 4310 6326)
1362 // Corner case - has to be handled separately
1364 {
1365 if( (T)rhs > 0 )
1366 return SafeInt< T, E >( lhs/(T)rhs );
1367
1368 // Now rhs is either negative, or zero
1369 if( (T)rhs != 0 )
1370 {
1371 if( sizeof( U ) >= 4 && sizeof( T ) <= sizeof( U ) )
1372 {
1373 // Problem case - normal casting behavior changes meaning
1374 // flip rhs to positive
1375 // any operator casts now do the right thing
1376 U tmp;
1377 if( sizeof(T) == 4 )
1378 tmp = lhs/(U)(unsigned __int32)( -(T)rhs );
1379 else
1380 tmp = lhs/(U)( -(T)rhs );
1381
1383 return SafeInt< T, E >( -( (T)tmp ) );
1384
1385 // Corner case
1386 // Note - this warning happens because we're not using partial
1387 // template specialization in this case. For any real cases where
1388 // this block isn't optimized out, the warning won't be present.
1389 if( tmp == (U)details::IntTraits< T >::maxInt + 1 )
1391
1392 E::SafeIntOnOverflow();
1393 }
1394
1395 return SafeInt< T, E >(lhs/(T)rhs);
1396 }
1397
1398 E::SafeIntOnDivZero();
1399 } // method == DivisionState_UnsignedSigned
1400
1402 {
1403 if( lhs == details::IntTraits< U >::minInt && (T)rhs == -1 )
1404 {
1405 // corner case of a corner case - lhs = min int, rhs = -1,
1406 // but rhs is the return type, so in essence, we can return -lhs
1407 // if rhs is a larger type than lhs
1408 if( sizeof( U ) < sizeof( T ) )
1409 {
1411 }
1412
1413 // If rhs is smaller or the same size int, then -minInt won't work
1414 E::SafeIntOnOverflow();
1415 }
1416 }
1417
1418 // Otherwise normal logic works with addition of bounds check when casting from U->T
1419 U ret;
1421 return SafeInt< T, E >( ret );
1422#pragma warning(pop)
1423}
1424
1425// Addition
1426template < typename T, typename U, typename E >
1428{
1429 T ret( 0 );
1431 return SafeInt< T, E >( ret );
1432}
1433
1434// Subtraction
1435template < typename T, typename U, typename E >
1437{
1438 T ret( 0 );
1440
1441 return SafeInt< T, E >( ret );
1442}
1443
1444// Overrides designed to deal with cases where a SafeInt is assigned out
1445// to a normal int - this at least makes the last operation safe
1446// +=
1447template < typename T, typename U, typename E >
1449{
1450 T ret( 0 );
1452 lhs = ret;
1453 return lhs;
1454}
1455
1456template < typename T, typename U, typename E >
1458{
1459 T ret( 0 );
1461 lhs = ret;
1462 return lhs;
1463}
1464
1465template < typename T, typename U, typename E >
1467{
1468 T ret( 0 );
1470 lhs = ret;
1471 return lhs;
1472}
1473
1474template < typename T, typename U, typename E >
1476{
1477 T ret( 0 );
1479 lhs = ret;
1480 return lhs;
1481}
1482
1483template < typename T, typename U, typename E >
1485{
1486 T ret( 0 );
1488 lhs = ret;
1489 return lhs;
1490}
1491
1492template < typename T, typename U, typename E >
1493T& operator &=( T& lhs, SafeInt< U, E > rhs ) throw()
1494{
1495 lhs = details::BinaryAndHelper< T, U >::And( lhs, (U)rhs );
1496 return lhs;
1497}
1498
1499template < typename T, typename U, typename E >
1500T& operator ^=( T& lhs, SafeInt< U, E > rhs ) throw()
1501{
1502 lhs = details::BinaryXorHelper< T, U >::Xor( lhs, (U)rhs );
1503 return lhs;
1504}
1505
1506template < typename T, typename U, typename E >
1507T& operator |=( T& lhs, SafeInt< U, E > rhs ) throw()
1508{
1509 lhs = details::BinaryOrHelper< T, U >::Or( lhs, (U)rhs );
1510 return lhs;
1511}
1512
1513template < typename T, typename U, typename E >
1514T& operator <<=( T& lhs, SafeInt< U, E > rhs ) throw()
1515{
1516 lhs = (T)( SafeInt< T, E >( lhs ) << (U)rhs );
1517 return lhs;
1518}
1519
1520template < typename T, typename U, typename E >
1521T& operator >>=( T& lhs, SafeInt< U, E > rhs ) throw()
1522{
1523 lhs = (T)( SafeInt< T, E >( lhs ) >> (U)rhs );
1524 return lhs;
1525}
1526
1527// Specific pointer overrides
1528// Note - this function makes no attempt to ensure
1529// that the resulting pointer is still in the buffer, only
1530// that no int overflows happened on the way to getting the new pointer
1531template < typename T, typename U, typename E >
1533{
1534 // Cast the pointer to a number so we can do arithmetic
1535 SafeInt< uintptr_t, E > ptr_val = reinterpret_cast< uintptr_t >( lhs );
1536 // Check first that rhs is valid for the type of ptrdiff_t
1537 // and that multiplying by sizeof( T ) doesn't overflow a ptrdiff_t
1538 // Next, we need to add 2 SafeInts of different types, so unbox the ptr_diff
1539 // Finally, cast the number back to a pointer of the correct type
1540 lhs = reinterpret_cast< T* >( (uintptr_t)( ptr_val + (ptrdiff_t)( SafeInt< ptrdiff_t, E >( rhs ) * sizeof( T ) ) ) );
1541 return lhs;
1542}
1543
1544template < typename T, typename U, typename E >
1546{
1547 // Cast the pointer to a number so we can do arithmetic
1548 SafeInt< size_t, E > ptr_val = reinterpret_cast< uintptr_t >( lhs );
1549 // See above for comments
1550 lhs = reinterpret_cast< T* >( (uintptr_t)( ptr_val - (ptrdiff_t)( SafeInt< ptrdiff_t, E >( rhs ) * sizeof( T ) ) ) );
1551 return lhs;
1552}
1553
1554template < typename T, typename U, typename E >
1556{
1557 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1558 return lhs;
1559}
1560
1561template < typename T, typename U, typename E >
1563{
1564 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1565 return lhs;
1566}
1567
1568template < typename T, typename U, typename E >
1570{
1571 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1572 return lhs;
1573}
1574
1575template < typename T, typename U, typename E >
1577{
1578 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1579 return lhs;
1580}
1581
1582template < typename T, typename U, typename E >
1584{
1585 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1586 return lhs;
1587}
1588
1589template < typename T, typename U, typename E >
1591{
1592 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1593 return lhs;
1594}
1595
1596template < typename T, typename U, typename E >
1598{
1599 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1600 return lhs;
1601}
1602
1603template < typename T, typename U, typename E >
1605{
1606 static_assert( details::DependentFalse< T >::value, "SafeInt<T>: This operator explicitly not supported" );
1607 return lhs;
1608}
1609
1610// Shift operators
1611// NOTE - shift operators always return the type of the lhs argument
1612
1613// Left shift
1614template < typename T, typename U, typename E >
1615SafeInt< U, E > operator <<( U lhs, SafeInt< T, E > bits ) throw()
1616{
1619
1620 return SafeInt< U, E >( (U)( lhs << (T)bits ) );
1621}
1622
1623// Right shift
1624template < typename T, typename U, typename E >
1626{
1629
1630 return SafeInt< U, E >( (U)( lhs >> (T)bits ) );
1631}
1632
1633// Bitwise operators
1634// This only makes sense if we're dealing with the same type and size
1635// demand a type T, or something that fits into a type T.
1636
1637// Bitwise &
1638template < typename T, typename U, typename E >
1640{
1642}
1643
1644// Bitwise XOR
1645template < typename T, typename U, typename E >
1647{
1649}
1650
1651// Bitwise OR
1652template < typename T, typename U, typename E >
1654{
1656}
1657
1658} // namespace utilities
1659
1660} // namespace msl
1661
1662#pragma pack(pop)
1663
1664#pragma warning(pop) // Disable /Wall warnings
1665#endif // RC_INVOKED
#define U(x)
Definition: wordpad.c:45
#define __int16
Definition: basetyps.h:22
#define __int64
Definition: basetyps.h:16
#define __int32
Definition: basetyps.h:19
SafeIntException(SafeIntError code)
Definition: safeint.h:293
SafeInt< T, E > Max(SafeInt< T, E > test, SafeInt< T, E > upper=SafeInt< T, E >(details::IntTraits< T >::maxInt)) const
Definition: safeint.h:1179
const T * Ptr() const
Definition: safeint.h:588
SafeInt< T, E > operator|(SafeInt< T, E > rhs) const
Definition: safeint.h:1140
SafeInt< T, E > operator&(SafeInt< T, E > rhs) const
Definition: safeint.h:1058
SafeInt< T, E > operator<<(U bits) const
Definition: safeint.h:974
bool operator>(U rhs) const
Definition: safeint.h:914
SafeInt< T, E > operator^(SafeInt< T, E > rhs) const
Definition: safeint.h:1103
bool operator>=(U rhs) const
Definition: safeint.h:902
SafeInt< T, E > operator>>(U bits) const
Definition: safeint.h:1015
SafeInt< T, E > & operator&=(SafeInt< T, E > rhs)
Definition: safeint.h:1082
SafeInt< T, E > operator~() const
Definition: safeint.h:662
SafeInt< T, E > & operator|=(SafeInt< T, E > rhs)
Definition: safeint.h:1152
SafeInt< T, E > & operator*=(SafeInt< T, E > rhs)
Definition: safeint.h:753
SafeInt< T, E > & operator+=(SafeInt< T, E > rhs)
Definition: safeint.h:827
SafeInt< T, E > & operator<<=(U bits)
Definition: safeint.h:994
SafeInt< T, E > & operator-=(SafeInt< T, E > rhs)
Definition: safeint.h:864
SafeInt< T, E > operator*(U rhs) const
Definition: safeint.h:738
const SafeInt< T, E > & Align32()
Definition: safeint.h:1223
const SafeInt< T, E > & Align4()
Definition: safeint.h:1220
bool operator!=(U rhs) const
Definition: safeint.h:953
const SafeInt< T, E > & operator+() const
Definition: safeint.h:597
const SafeInt< T, E > & Align64()
Definition: safeint.h:1224
void Swap(SafeInt< T, E > &with)
Definition: safeint.h:1185
SafeInt< T, E > & operator%=(U rhs)
Definition: safeint.h:723
SafeInt< T, E > & operator=(const U &rhs)
Definition: safeint.h:459
SafeInt< T, E > & operator++()
Definition: safeint.h:610
SafeInt< T, E > & operator/=(SafeInt< T, E > i)
Definition: safeint.h:790
SafeInt(const T &i)
Definition: safeint.h:425
bool operator<(U rhs) const
Definition: safeint.h:890
SafeInt< T, E > & operator>>=(U bits)
Definition: safeint.h:1034
const SafeInt< T, E > & Align2()
Definition: safeint.h:1219
SafeInt(const U &i)
Definition: safeint.h:447
bool operator!() const
Definition: safeint.h:592
const SafeInt< T, E > & Align()
Definition: safeint.h:1193
SafeInt< T, E > & operator--()
Definition: safeint.h:621
SafeInt< T, E > operator-() const
Definition: safeint.h:600
SafeInt< T, E > operator/(U rhs) const
Definition: safeint.h:775
SafeInt< T, E > Min(SafeInt< T, E > test, SafeInt< T, E > floor=SafeInt< T, E >(details::IntTraits< T >::minInt)) const
Definition: safeint.h:1173
bool operator==(U rhs) const
Definition: safeint.h:938
SafeInt< T, E > & operator^=(SafeInt< T, E > rhs)
Definition: safeint.h:1119
const SafeInt< T, E > & Align8()
Definition: safeint.h:1221
const T & Ref() const
Definition: safeint.h:589
bool operator<=(U rhs) const
Definition: safeint.h:926
SafeInt< T, E > operator%(U rhs) const
Definition: safeint.h:707
const SafeInt< T, E > & Align16()
Definition: safeint.h:1222
SafeInt(const SafeInt< U, E > &u)
Definition: safeint.h:440
result_buffer_count char *const _In_ int const _In_ bool const _In_ unsigned const _In_ STRFLT const _In_ bool const _Inout_ __crt_cached_ptd_host &ptd throw()
Definition: cvt.cpp:119
unsigned char
Definition: typeof.h:29
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
GLdouble GLdouble t
Definition: gl.h:2047
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
#define bits
Definition: infblock.c:15
#define b
Definition: ke_i.h:79
#define T
Definition: mbstring.h:31
unsigned int uintptr_t
Definition: intrin.h:47
@ SafeIntDivideByZero
Definition: safeint.h:274
@ SafeIntArithmeticOverflow
Definition: safeint.h:273
SafeInt< U, E > operator>>(U lhs, SafeInt< T, E > bits)
Definition: safeint.h:1625
bool SafeDivide(T t, U u, T &result)
Definition: safeint.h:391
T & operator<<=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1514
bool SafeModulus(const T &t, const U &u, T &result)
Definition: safeint.h:378
SafeInt< T, E > operator+(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1427
bool SafeSubtract(T t, U u, T &result)
Definition: safeint.h:405
bool operator==(bool lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1285
bool SafeGreaterThanEquals(const T t, const U u)
Definition: safeint.h:360
bool SafeMultiply(T t, U u, T &result)
Definition: safeint.h:384
SafeInt< T, E > operator|(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1653
bool operator<(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1232
SafeInt< T, E > operator-(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1436
bool SafeAdd(T t, U u, T &result)
Definition: safeint.h:398
T & operator>>=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1521
bool SafeEquals(const T t, const U u)
Definition: safeint.h:342
T & operator^=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1500
SafeInt< U, E > operator<<(U lhs, SafeInt< T, E > bits)
Definition: safeint.h:1615
SafeInt< T, E > operator%(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1323
SafeInt< T, E > operator^(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1646
T & operator|=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1507
bool SafeNotEquals(const T t, const U u)
Definition: safeint.h:348
bool SafeGreaterThan(const T t, const U u)
Definition: safeint.h:354
T & operator-=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1457
bool SafeCast(const T From, U &To)
Definition: safeint.h:335
T & operator&=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1493
T & operator/=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1475
bool SafeLessThanEquals(const T t, const U u)
Definition: safeint.h:372
bool operator!=(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1304
SafeInt< T, E > operator*(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1350
T & operator%=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1484
T & operator+=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1448
SafeInt< T, E > operator/(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1358
bool operator<=(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1271
bool SafeLessThan(const T t, const U u)
Definition: safeint.h:366
T & operator*=(T &lhs, SafeInt< U, E > rhs)
Definition: safeint.h:1466
bool operator>=(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1258
SafeInt< T, E > operator&(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1639
bool operator>(U lhs, SafeInt< T, E > rhs)
Definition: safeint.h:1245
Definition: safeint.h:265
#define bool
Definition: nsiface.idl:72
#define long
Definition: qsort.c:33
#define test
Definition: rosglue.h:37
static calc_node_t temp
Definition: rpn_ieee.c:38
#define _SAFEINT_EXCEPTION_ASSERT()
Definition: safeint.h:246
#define _SAFEINT_SHIFT_ASSERT(x)
Definition: safeint.h:238
#define true
Definition: stdbool.h:36
Definition: inflate.c:139
static __declspec(noreturn) void SafeIntOnDivZero()
Definition: safeint.h:323
static __declspec(noreturn) void SafeIntOnOverflow()
Definition: safeint.h:317
static __declspec(noreturn) void SafeIntOnDivZero()
Definition: safeint.h:308
static __declspec(noreturn) void SafeIntOnOverflow()
Definition: safeint.h:302
#define wchar_t
Definition: wchar.h:102
#define _CRT_SECURE_INVALID_PARAMETER(expr)
Definition: corecrt.h:409
int ret