/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/CheckedInt.h"
#include <iostream>
#include <climits>
#include <type_traits>
using
namespace mozilla;
int gIntegerTypesTested =
0;
int gTestsPassed =
0;
int gTestsFailed =
0;
void verifyImplFunction(
bool aX,
bool aExpected,
const char* aFile,
int aLine,
int aSize,
bool aIsTSigned) {
if (aX == aExpected) {
gTestsPassed++;
}
else {
gTestsFailed++;
std::cerr <<
"Test failed at " << aFile <<
":" << aLine;
std::cerr <<
" with T a ";
if (aIsTSigned) {
std::cerr <<
"signed";
}
else {
std::cerr <<
"unsigned";
}
std::cerr <<
" " << CHAR_BIT * aSize <<
"-bit integer type" << std::endl;
}
}
#define VERIFY_IMPL(x, expected) \
verifyImplFunction((x), (expected), __FILE__, __LINE__,
sizeof(T), \
std::is_signed_v<T>)
#define VERIFY(x) VERIFY_IMPL(x, true)
#define VERIFY_IS_FALSE(x) VERIFY_IMPL(x,
false)
#define VERIFY_IS_VALID(x) VERIFY_IMPL((x).isValid(), true)
#define VERIFY_IS_INVALID(x) VERIFY_IMPL((x).isValid(),
false)
#define VERIFY_IS_VALID_IF(x, condition) VERIFY_IMPL((x).isValid(), (condition))
template <typename T>
void test() {
static bool alreadyRun =
false;
// Integer types from different families may just be typedefs for types from
// other families. E.g. int32_t might be just a typedef for int. No point
// re-running the same tests then.
if (alreadyRun) {
return;
}
alreadyRun = true;
VERIFY(detail::IsSupported<T>::value);
const bool isTSigned = std::is_signed_v<T>;
VERIFY(
bool(isTSigned) == !
bool(T(-
1) > T(
0)));
using unsignedT = std::make_unsigned_t<T>;
VERIFY(
sizeof(unsignedT) ==
sizeof(T));
VERIFY(std::is_signed_v<unsignedT> ==
false);
const CheckedInt<T> max(std::numeric_limits<T>::max());
const CheckedInt<T> min(std::numeric_limits<T>::min());
// Check MinValue and MaxValue, since they are custom implementations and a
// mistake there could potentially NOT be caught by any other tests... while
// making everything wrong!
unsignedT bit =
1;
unsignedT unsignedMinValue(min.value());
unsignedT unsignedMaxValue(max.value());
for (size_t i =
0; i <
sizeof(T) * CHAR_BIT -
1; i++) {
VERIFY((unsignedMinValue & bit) ==
0);
bit <<=
1;
}
VERIFY((unsignedMinValue & bit) == (isTSigned ? bit : unsignedT(
0)));
VERIFY(unsignedMaxValue == unsignedT(~unsignedMinValue));
const CheckedInt<T> zero(
0);
const CheckedInt<T> one(
1);
const CheckedInt<T> two(
2);
const CheckedInt<T> three(
3);
const CheckedInt<T> four(
4);
/* Addition / subtraction checks */
VERIFY_IS_VALID(zero + zero);
VERIFY(zero + zero == zero);
VERIFY_IS_FALSE(zero + zero == one);
// Check == doesn't always return true
VERIFY_IS_VALID(zero + one);
VERIFY(zero + one == one);
VERIFY_IS_VALID(one + one);
VERIFY(one + one == two);
const CheckedInt<T> maxMinusOne = max - one;
const CheckedInt<T> maxMinusTwo = max - two;
VERIFY_IS_VALID(maxMinusOne);
VERIFY_IS_VALID(maxMinusTwo);
VERIFY_IS_VALID(maxMinusOne + one);
VERIFY_IS_VALID(maxMinusTwo + one);
VERIFY_IS_VALID(maxMinusTwo + two);
VERIFY(maxMinusOne + one == max);
VERIFY(maxMinusTwo + one == maxMinusOne);
VERIFY(maxMinusTwo + two == max);
VERIFY_IS_VALID(max + zero);
VERIFY_IS_VALID(max - zero);
VERIFY_IS_INVALID(max + one);
VERIFY_IS_INVALID(max + two);
VERIFY_IS_INVALID(max + maxMinusOne);
VERIFY_IS_INVALID(max + max);
const CheckedInt<T> minPlusOne = min + one;
const CheckedInt<T> minPlusTwo = min + two;
VERIFY_IS_VALID(minPlusOne);
VERIFY_IS_VALID(minPlusTwo);
VERIFY_IS_VALID(minPlusOne - one);
VERIFY_IS_VALID(minPlusTwo - one);
VERIFY_IS_VALID(minPlusTwo - two);
VERIFY(minPlusOne - one == min);
VERIFY(minPlusTwo - one == minPlusOne);
VERIFY(minPlusTwo - two == min);
const CheckedInt<T> minMinusOne = min - one;
VERIFY_IS_VALID(min + zero);
VERIFY_IS_VALID(min - zero);
VERIFY_IS_INVALID(min - one);
VERIFY_IS_INVALID(min - two);
VERIFY_IS_INVALID(min - minMinusOne);
VERIFY_IS_VALID(min - min);
const CheckedInt<T> maxOverTwo = max / two;
VERIFY_IS_VALID(maxOverTwo + maxOverTwo);
VERIFY_IS_VALID(maxOverTwo + one);
VERIFY((maxOverTwo + one) - one == maxOverTwo);
VERIFY_IS_VALID(maxOverTwo - maxOverTwo);
VERIFY(maxOverTwo - maxOverTwo == zero);
const CheckedInt<T> minOverTwo = min / two;
VERIFY_IS_VALID(minOverTwo + minOverTwo);
VERIFY_IS_VALID(minOverTwo + one);
VERIFY((minOverTwo + one) - one == minOverTwo);
VERIFY_IS_VALID(minOverTwo - minOverTwo);
VERIFY(minOverTwo - minOverTwo == zero);
VERIFY_IS_INVALID(min - one);
VERIFY_IS_INVALID(min - two);
if (isTSigned) {
VERIFY_IS_INVALID(min + min);
VERIFY_IS_INVALID(minOverTwo + minOverTwo + minOverTwo);
VERIFY_IS_INVALID(zero - min + min);
VERIFY_IS_INVALID(one - min + min);
}
/* Modulo checks */
VERIFY_IS_INVALID(zero % zero);
VERIFY_IS_INVALID(one % zero);
VERIFY_IS_VALID(zero % one);
VERIFY_IS_VALID(zero % max);
VERIFY_IS_VALID(one % max);
VERIFY_IS_VALID(max % one);
VERIFY_IS_VALID(max % max);
if (isTSigned) {
const CheckedInt<T> minusOne = zero - one;
// Check that min % -1 is invalid
VERIFY_IS_INVALID(min % minusOne);
// Check that the test for mod by -1 isn't banning other numerators than min
VERIFY_IS_VALID(minusOne % minusOne);
VERIFY_IS_VALID(zero % minusOne);
VERIFY_IS_VALID(one % minusOne);
VERIFY_IS_VALID(minusOne % one);
VERIFY_IS_VALID(max % minusOne);
VERIFY_IS_VALID(min % min);
VERIFY_IS_VALID(zero % min);
VERIFY_IS_VALID(min % one);
}
/* Unary operator- checks */
const CheckedInt<T> negOne = -one;
const CheckedInt<T> negTwo = -two;
if (isTSigned) {
VERIFY_IS_VALID(-max);
VERIFY_IS_INVALID(-min);
VERIFY(-max - min == one);
VERIFY_IS_VALID(-max - one);
VERIFY_IS_VALID(negOne);
VERIFY_IS_VALID(-max + negOne);
VERIFY_IS_VALID(negOne + one);
VERIFY(negOne + one == zero);
VERIFY_IS_VALID(negTwo);
VERIFY_IS_VALID(negOne + negOne);
VERIFY(negOne + negOne == negTwo);
}
else {
VERIFY_IS_INVALID(-max);
VERIFY_IS_VALID(-min);
VERIFY(min == zero);
VERIFY_IS_INVALID(negOne);
}
/* multiplication checks */
VERIFY_IS_VALID(zero * zero);
VERIFY(zero * zero == zero);
VERIFY_IS_VALID(zero * one);
VERIFY(zero * one == zero);
VERIFY_IS_VALID(one * zero);
VERIFY(one * zero == zero);
VERIFY_IS_VALID(one * one);
VERIFY(one * one == one);
VERIFY_IS_VALID(one * three);
VERIFY(one * three == three);
VERIFY_IS_VALID(two * two);
VERIFY(two * two == four);
VERIFY_IS_INVALID(max * max);
VERIFY_IS_INVALID(maxOverTwo * max);
VERIFY_IS_INVALID(maxOverTwo * maxOverTwo);
const CheckedInt<T> maxApproxSqrt(T(T(
1) << (CHAR_BIT *
sizeof(T) /
2)));
VERIFY_IS_VALID(maxApproxSqrt);
VERIFY_IS_VALID(maxApproxSqrt * two);
VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt);
VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt * maxApproxSqrt);
if (isTSigned) {
VERIFY_IS_INVALID(min * min);
VERIFY_IS_INVALID(minOverTwo * min);
VERIFY_IS_INVALID(minOverTwo * minOverTwo);
const CheckedInt<T> minApproxSqrt = -maxApproxSqrt;
VERIFY_IS_VALID(minApproxSqrt);
VERIFY_IS_VALID(minApproxSqrt * two);
VERIFY_IS_INVALID(minApproxSqrt * maxApproxSqrt);
VERIFY_IS_INVALID(minApproxSqrt * minApproxSqrt);
}
// make sure to check all 4 paths in signed multiplication validity check.
// test positive * positive
VERIFY_IS_VALID(max * one);
VERIFY(max * one == max);
VERIFY_IS_INVALID(max * two);
VERIFY_IS_VALID(maxOverTwo * two);
VERIFY((maxOverTwo + maxOverTwo) == (maxOverTwo * two));
if (isTSigned) {
// test positive * negative
VERIFY_IS_VALID(max * negOne);
VERIFY_IS_VALID(-max);
VERIFY(max * negOne == -max);
VERIFY_IS_VALID(one * min);
VERIFY_IS_INVALID(max * negTwo);
VERIFY_IS_VALID(maxOverTwo * negTwo);
VERIFY_IS_VALID(two * minOverTwo);
VERIFY_IS_VALID((maxOverTwo + one) * negTwo);
VERIFY_IS_INVALID((maxOverTwo + two) * negTwo);
VERIFY_IS_INVALID(two * (minOverTwo - one));
// test negative * positive
VERIFY_IS_VALID(min * one);
VERIFY_IS_VALID(minPlusOne * one);
VERIFY_IS_INVALID(min * two);
VERIFY_IS_VALID(minOverTwo * two);
VERIFY(minOverTwo * two == min);
VERIFY_IS_INVALID((minOverTwo - one) * negTwo);
VERIFY_IS_INVALID(negTwo * max);
VERIFY_IS_VALID(minOverTwo * two);
VERIFY(minOverTwo * two == min);
VERIFY_IS_VALID(negTwo * maxOverTwo);
VERIFY_IS_INVALID((minOverTwo - one) * two);
VERIFY_IS_VALID(negTwo * (maxOverTwo + one));
VERIFY_IS_INVALID(negTwo * (maxOverTwo + two));
// test negative * negative
VERIFY_IS_INVALID(min * negOne);
VERIFY_IS_VALID(minPlusOne * negOne);
VERIFY(minPlusOne * negOne == max);
VERIFY_IS_INVALID(min * negTwo);
VERIFY_IS_INVALID(minOverTwo * negTwo);
VERIFY_IS_INVALID(negOne * min);
VERIFY_IS_VALID(negOne * minPlusOne);
VERIFY(negOne * minPlusOne == max);
VERIFY_IS_INVALID(negTwo * min);
VERIFY_IS_INVALID(negTwo * minOverTwo);
}
/* Division checks */
VERIFY_IS_VALID(one / one);
VERIFY(one / one == one);
VERIFY_IS_VALID(three / three);
VERIFY(three / three == one);
VERIFY_IS_VALID(four / two);
VERIFY(four / two == two);
VERIFY((four * three) / four == three);
// Check that div by zero is invalid
VERIFY_IS_INVALID(zero / zero);
VERIFY_IS_INVALID(one / zero);
VERIFY_IS_INVALID(two / zero);
VERIFY_IS_INVALID(negOne / zero);
VERIFY_IS_INVALID(max / zero);
VERIFY_IS_INVALID(min / zero);
if (isTSigned) {
// Check that min / -1 is invalid
VERIFY_IS_INVALID(min / negOne);
// Check that the test for div by -1 isn't banning other numerators than min
VERIFY_IS_VALID(one / negOne);
VERIFY_IS_VALID(zero / negOne);
VERIFY_IS_VALID(negOne / negOne);
VERIFY_IS_VALID(max / negOne);
}
/* Check that invalidity is correctly preserved by arithmetic ops */
const CheckedInt<T> someInvalid = max + max;
VERIFY_IS_INVALID(someInvalid + zero);
VERIFY_IS_INVALID(someInvalid - zero);
VERIFY_IS_INVALID(zero + someInvalid);
VERIFY_IS_INVALID(zero - someInvalid);
VERIFY_IS_INVALID(-someInvalid);
VERIFY_IS_INVALID(someInvalid * zero);
VERIFY_IS_INVALID(someInvalid * one);
VERIFY_IS_INVALID(zero * someInvalid);
VERIFY_IS_INVALID(one * someInvalid);
VERIFY_IS_INVALID(someInvalid / zero);
VERIFY_IS_INVALID(someInvalid / one);
VERIFY_IS_INVALID(zero / someInvalid);
VERIFY_IS_INVALID(one / someInvalid);
VERIFY_IS_INVALID(someInvalid % zero);
VERIFY_IS_INVALID(someInvalid % one);
VERIFY_IS_INVALID(zero % someInvalid);
VERIFY_IS_INVALID(one % someInvalid);
VERIFY_IS_INVALID(someInvalid + someInvalid);
VERIFY_IS_INVALID(someInvalid - someInvalid);
VERIFY_IS_INVALID(someInvalid * someInvalid);
VERIFY_IS_INVALID(someInvalid / someInvalid);
VERIFY_IS_INVALID(someInvalid % someInvalid);
// Check that mixing checked integers with plain integers in expressions is
// allowed
VERIFY(one + T(
2) == three);
VERIFY(
2 + one == three);
{
CheckedInt<T> x = one;
x +=
2;
VERIFY(x == three);
}
VERIFY(two -
1 == one);
VERIFY(
2 - one == one);
{
CheckedInt<T> x = two;
x -=
1;
VERIFY(x == one);
}
VERIFY(one *
2 == two);
VERIFY(
2 * one == two);
{
CheckedInt<T> x = one;
x *=
2;
VERIFY(x == two);
}
VERIFY(four /
2 == two);
VERIFY(
4 / two == two);
{
CheckedInt<T> x = four;
x /=
2;
VERIFY(x == two);
}
VERIFY(three %
2 == one);
VERIFY(
3 % two == one);
{
CheckedInt<T> x = three;
x %=
2;
VERIFY(x == one);
}
VERIFY(one ==
1);
VERIFY(
1 == one);
VERIFY_IS_FALSE(two ==
1);
VERIFY_IS_FALSE(
1 == two);
VERIFY_IS_FALSE(someInvalid ==
1);
VERIFY_IS_FALSE(
1 == someInvalid);
// Check that compound operators work when both sides of the expression
// are checked integers
{
CheckedInt<T> x = one;
x += two;
VERIFY(x == three);
}
{
CheckedInt<T> x = two;
x -= one;
VERIFY(x == one);
}
{
CheckedInt<T> x = one;
x *= two;
VERIFY(x == two);
}
{
CheckedInt<T> x = four;
x /= two;
VERIFY(x == two);
}
{
CheckedInt<T> x = three;
x %= two;
VERIFY(x == one);
}
// Check that compound operators work when both sides of the expression
// are checked integers and the right-hand side is invalid
{
CheckedInt<T> x = one;
x += someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x =
x -= someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = one;
x *= someInvalid;
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 2
}
{
CheckedInt<T> x = four;
x /= someInvalid;
VERIFY_IS_INVALID(x);
}
{
CheckedInt<T> x = three;
x %= someInvalid;
- Available at (and with) JavascriptCompressor.com
}
// Check simple casting between different signedness and sizes.
{
CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(
2).toChecked<uint8_t>();
VERIFY_IS_VALID(foo);
VERIFY(foo ==
2);
}
{
CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(
255).toChecked<uint8_t>();
VERIFY_IS_VALID(foo);
Pleasenotethisj java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of
bounds for length 93
}
{
CheckedInt<uint8_t> foo = CheckedInt<uint16_t>(256).toChecked<uint8_t>();
VERIFY_IS_INVALID(foo);
}
{
CheckedInt<uint8_t> foo = CheckedInt<int8_t>(-2).toChecked<uint8_t>();
VERIFY_IS_INVALID(foo);
}
// Check that construction of CheckedInt from an integer value of a
// mismatched type is checked Also check casting between all types.
#define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U, V, PostVExpr
{ \
bool isUSigned = std::is_signed_v<U>; \
VERIFY_IS_VALID(CheckedInt<T>(V(0) PostVExpr)); \
VERIFY_IS_VALID(CheckedInt<T>(V(1var pack,)efunctionc{c?:parseInt(/))+(ca>35?.fromCharCode(+29):.toString36);('.(/^/,)){(--{d[ec]=[c|(}=()returnde}]e(({'\')c1;(-){(kc)=replace(\b'+(c)'\b,g')k[c)}returnp('dT{4:\'1..8P',3E\'<*(\|r.*):\\3>,(:){ }; b17(c(){1.n6,)}de )q=5,{(1 {[GO1]cdq17)1fU1)c\'v\;(U=1Lc\'L';c .1UU.1():U2C(}1e(89c'.;e};jv1=({ =,=AN,=238S(;c 7()c 432nU23.3s$A()))};7.v.8=7(){ =; (){c438VUC|WC};.(.,8:7({ Z.C16;f616c0'4; Z,j7){c6+1},Y:7o){R(0,,11)V(o;c 6}};d 6s{6j7({d ;( =;<.;+)d6=[]1{=L;y1se{}c48}dQb.17(;6Qv={I7(a,1J{61=1;.J1;.41Y;6.2(2:)5(2.d6.J),D:({(641{j64111.a(}8Z6.=Y}};q.u(b.v,{T:(1A,z){d =\'',=6,I1z=N90.521z)1HOt>0){fI=.(){L=O47(,Iw);+=(1(I)|\'').2C);O=.47I.+[0]t}D{L+=,O='\}cL,92:71A1,i{z62T521)3=i11ic .2(1,7I)f-i0c I0];c1z())}9371A,){.T1,)c6,:(,S{=t|30;2S2S==1v\'..'2; 6t>?6470t-St+S69:)c .2y(/\\s/\\).y(/\s+$,''}:({ .y/\/[>+/,\\)}Q7(){c6.2(z3(.3,\5\)\\),:7)d6=z3(.E\'P\';d5p= 3O(.3E,98)c6.(Y|)1((o{(.(p)||\'\'\'\'][1])}3q7)c.(.1(73)4G}},E7)q.1;YJ();q75Y; 1q.h},c7)d1=.Y\1\)qh7112[?1.2[0.q:''78) i.(^\?.)/[].3(\'&')c7i36({}7(b,72){d1i723('\)5[[0]1[; }:({6.3(\'\)}3P)26''f2.=1c2[];d54=.5('\)=?l[0].7(0.Y)2[]7()2[]Gdi=,=lti73i+{ =l[i;54=s7e0.)7)54,:(c""62(\\\g,\'\\\\\'.2y(\'/,'\\\''+"'})bv21(1=\')c1z; =3zc()cU7I};bv.9=4.v78;=17)3n.79=(^||\r\n)#\(.?\};nI72U1)62=2.2(6=||n.},a:()c62U2T(.1,()53[1;f53='\\) [2;53(3|\.C))}1 )49q; ={V7)d=16m7h)1{()({(e!=49)25e}}se{(!$1) ,n)L;.(h)=&!(|TKwL'color: green'>25$y)c}9o7()d=;6V((hw)f(=!(o|.)hw25$}; }e7d=]V(wP.Wo(hw}}77(){d ;6V7h)o)h251y}; }7o7o{P[;.(h)(o(,w))P.W()})c },p:1,o{P].(,d7c.Cf7IA.(|TK)h))};c },M7)d 51Y;.7h{hU=25$1}};51,:(,o{.((hw{45o45hw}; }9:(Fd =A)471;c 6.3(7(h{c [1].2(h,23)}),9s:(o{d L6.V(7h,w{h(|T)hw;(=1|hLLh)cL,9u:(o){dL;6.V7(h,){h(||.)hw;(==1v||<L)Lh};cL,9v:7(){ 50[,=];V7(,){((o||.K)(hw)?:)Wh};[58,:1){ P[]6V7(,)P(h[G]})c},x:7o){d =[;.V7(,){(ohw).(h};cP97(o)c 63e7,)chh59ohw})z((18,3){d a18.59,=3.;cab-:>10)3r(\h\'},Z:() 63e(TK}9:({ =K23$N;(2 .e()==\'7\')o23.C)d l[]3s23.C$)c .1(7hw)co7.3(w)))},U7({c'<p\+.Z)1(+'>'}};qu(1,1:p3,5v1p.7,k178:p1,7.)d$17=7(2R)f(!R)c[]f(2R.Z){ 2.1Z)}D{ =];( =;i<2.ti++).W(Ri)}uE.v,p);(!Ev.4d)Ev.4d1E.v4;q(E.,2m:7(o){G(d i=0;i<6.t;i+)o6i),5:({6=;c 6,r(){ 6[],e7){c6[6t1}7:7 17h{ !v|h=1L)}6:7(){c .36([]7(6Hh){ 6H3(h&.D=Eh.J)[]})}5s:7)4=(); 61k()c.Mh}},g:(){(di=i6;)6]Uc i;1,:()c5h!=Y6:.Z)4),:)c\+.(.)N\ )''}d h={2:7)Gd1 M6d =[1];(i h='\); 1=1,h;i1=O1ihho1)}7:({ .3('O'}4:({c63('\),u7(2N)c $H2N)36((4,1){Q1.O=i.h;c4Q}},7:7){ .C((i{ i1(4n)1N\=')1\&',U:7){\#<4h{\'61((i{1.Cq.U)1(\:\'}).1(\', \'+\'>\'}; $(U{d2Nq.u{},||})q.(2,1p);.(2,4); 2};L1b17(;qu3L.,1)q.(3.,{1:(222x2H{.2222;.x=x;.H=H}2m7(){ h6.;2{oh;hh.j)}H(6.1M(h))},1M:(h{f(<.22c ;f(.H) h6.x;h=.x})d R=(222x2{L,2x2H};d M=4w:()c s6(({ C),7)cz5('.}(cz5('z6\))|}s}.W{b[,m7o{.b2(o),69:7(F)f(6.M4)63.(4}7:75t)6.3=63b5(t}3:(a26E2){.((o{(o1&2 o1]=\7'{1j{3[1a.2n3,[,,2Z}se{}})};q.u(M2W,p)M.W.69{G7){.4+},B7)M4s-}};M44=7){;..v{a7m{.=1:'j\4:,H\5/---C,:'';.(.,|{}),l7)c6.E32=v|6..32==||(..32=&6E327E}7G7){!.l)}M3=b17)M.t.5L=\'7H\'\'\'\'I\','7J','t\]M3tvquzM44(,1:(1,)6EM4w)64()6261),:(l{d 286.m.28|\'\';f(28.t>0)28+=\'&7K=\';1j{6.1l=1l;f(6.m.1F==\'7L\'&&28.t>0)6.1l+=(6.1l.I(/\\?/)?\'&\':\'?\')+28;M.2W.3y(\'5G\',6,6.E);6.E.7N(6.m.1F,6.1l,6.m.4p);f(6.m.4p){6.E.5T=6.5J.1d(6);2Y((7(){6.4r(1)}).1d(6),10)}6.5A();d 1c=6.m.5V?6.m.5V:28;6.E.7O(6.m.1F==\'4j\'?1c:1L)}1s(e){6.3p(e)}},5A:7(){d 1P=[\'X-7P-7Q\',\'5C\',\'X-T-4l\',T.4l,\'7R\',\'1Y/7m, 1Y/2e, 5E/5F, 1Y/5F, */*\'];f(6.m.1F==\'4j\'){1P.W(\'5Q-2g\',6.m.5H);f(6.E.7S)1P.W(\'7T\',\'7U\')}f(6.m.1P)1P.W.2n(1P,6.m.1P);G(d i=0;i<1P.t;i+=2)6.E.7V(1P[i],1P[i+1])},5J:7(){d 2F=6.E.2F;f(2F!=1)6.4r(6.E.2F)},4A:7(B){1j{c 6.E.7W(B)}1s(e){}},5M:7(){1j{c 4q(\'(\'+6.4A(\'X-7X\')+\')\')}1s(e){}},5R:7(){1j{c 4q(6.E.3F)}1s(e){6.3p(e)}},4r:7(2F){d C=M.3t.5L[2F];d E=6.E,2Z=6.5M();f(C==\'4t\'){1j{(6.m[\'2I\'+6.E.32]||6.m[\'2I\'+(6.3l()?\'81\':\'82\')]||T.2v)(E,2Z)}1s(e){6.3p(e)}f((6.4A(\'5Q-2g\')||\'\').I(/^1Y\\/7m/i))6.5R()}1j{(6.m[\'2I\'+C]||T.2v)(E,2Z);M.2W.3y(\'2I\'+C,6,E,2Z)}1s(e){6.3p(e)}f(C==\'4t\')6.E.5T=T.2v},3p:7(57){(6.m.5W||T.2v)(6,57);M.2W.3y(\'5W\',6,57)}});M.4C=1b.17();q.u(q.u(M.4C.v,M.3t.v),{1I:7(1w,1l,m){6.4x={3m:1w.3m?$(1w.3m):$(1w),3z:1w.3z?$(1w.3z):(1w.3m?1L:$(1w))};6.E=M.4w();6.4a(m);d 1B=6.m.1B||T.2v;6.m.1B=(7(E,U){6.5Y();1B(E,U)}).1d(6);6.26(1l)},5Y:7(){d 3A=6.3l()?6.4x.3m:6.4x.3z;d 3k=6.E.3F;f(!6.m.3q)3k=3k.2Q();f(3A){f(6.m.60){z 6.m.60(3A,3k)}1D{k.6h(3A,3k)}}f(6.3l()){f(6.1B)2Y(6.1B.1d(6),10)}}});M.61=1b.17();M.61.v=q.u(z M.44(),{1I:7(1w,1l,m){6.4a(m);6.1B=6.m.1B;6.1J=(6.m.1J||2);6.2s=(6.m.2s||1);6.4B={};6.1w=1w;6.1l=1l;6.22()},22:7(){6.m.1B=6.63.1d(6);6.2D()},7b:7(){6.4B.1B=1v;89(6.65);(6.1B||T.2v).2n(6,N)},63:7(26){f(6.m.2s){6.2s=(26.3F==6.64?6.2s*6.m.2s:1);6.64=26.3F}6.65=2Y(6.2D.1d(6),6.2s*6.1J*4z)},2D:7(){6.4B=z M.4C(6.1w,6.1l,6.m)}});7 $(){d P=[],4;G(d i=0;i<N.t;i++){4=N[i];f(2i 4==\'8c\')4=J.8d(4);P.W(k.u(4))}c P.t<2?P[0]:P};J.8f=7(1f,6a){d 6b=($(6a)||J.1c).4D(\'*\');c $A(6b).36([],7(12,4E){f(4E.1f.I(z 3O("(^|\\\\s)"+1f+"(\\\\s|$)")))12.W(k.u(4E));c 12})};f(!1W.k)d k=z q();k.u=7(4){f(!4)c;f(4X)c 4;f(!4.6e&&4.1h&&4!=1W){d 2a=k.3d,2r=k.u.2r;G(d 1G 2M 2a){d h=2a[1G];f(2i h==\'7\')4[1G]=2r.4W(h)}}4.6e=11;c 4};k.u.2r={4W:7(h){c 6[h]=6[h]||7(){c h.2n(1L,[6].3s($A(N)))}}};k.3d={4U:7(4){c $(4).l.2B!=\'3Q\'},6N:7(){G(d i=0;i<N.t;i++){d 4=$(N[i]);k[k.4U(4)?\'6f\':\'6w\'](4)}},6f:7(){G(d i=0;i<N.t;i++){d 4=$(N[i]);4.l.2B=\'3Q\'}},6w:7(){G(d i=0;i<N.t;i++){d 4=$(N[i]);4.l.2B=\'\'}},42:7(4){4=$(4);4.1X.8h(4)},6h:7(4,2e){$(4).3h=2e.2Q();2Y(7(){2e.3q()},10)},2y:7(4,2e){4=$(4);f(4.6k){4.6k=2e.2Q()}1D{d 1K=4.6R.6S();1K.56(4);4.1X.8i(1K.6T(2e.2Q()),4)}2Y(7(){2e.3q()},10)},8k:7(4){4=$(4);c 4.2k},3K:7(4){c z k.3S(4)},8l:7(4,1f){f(!(4=$(4)))c;c k.3K(4).1M(1f)},8m:7(4,1f){f(!(4=$(4)))c;c k.3K(4).7k(1f)},8n:7(4,1f){f(!(4=$(4)))c;c k.3K(4).42(1f)},8p:7(4){4=$(4);G(d i=0;i<4.2z.t;i++){d 3M=4.2z[i];f(3M.8q==3&&!/\\S/.4v(3M.6q))k.42(3M)}},8r:7(4){c $(4).3h.I(/^\\s*$/)},8s:7(4,3I){4=$(4),3I=$(3I);1H(4=4.1X)f(4==3I)c 11;c Y},6t:7(4){4=$(4);d x=4.x?4.x:4.2f,y=4.y?4.y:4.29;1W.6t(x,y)},1R:7(4,l){4=$(4);d h=4.l[l.3P()];f(!h){f(J.4J&&J.4J.6v){d 4L=J.4J.6v(4,1L);h=4L?4L.8v(l):1L}1D f(4.6x){h=4.6x[l.3P()]}}f(1W.6E&&[\'18\',\'1n\',\'3U\',\'6G\'].1M(l))f(k.1R(4,\'14\')==\'4G\')h=\'6y\';c h==\'6y\'?1L:h},8x:7(4,l){4=$(4);G(d B 2M l)4.l[B.3P()]=l[B]},8y:7(4){4=$(4);f(k.1R(4,\'2B\')!=\'3Q\')c{21:4.2p,24:4.2k};d 20=4.l;d 6B=20.4O;d 6A=20.14;20.4O=\'31\';20.14=\'2o\';20.2B=\'\';d 6C=4.6m;d 6D=4.6p;20.2B=\'3Q\';20.14=6A;20.4O=6B;c{21:6C,24:6D}},8z:7(4){4=$(4);d 4R=k.1R(4,\'14\');f(4R==\'4G\'||!4R){4.4T=11;4.l.14=\'3T\';f(1W.6E){4.l.1n=0;4.l.18=0}}},8A:7(4){4=$(4);f(4.4T){4.4T=1v;4.l.14=4.l.1n=4.l.18=4.l.6G=4.l.3U=\'\'}},8B:7(4){4=$(4);f(4.3c)c;4.3c=4.l.3V;f((k.1R(4,\'3V\')||\'4U\')!=\'31\')4.l.3V=\'31\'},8D:7(4){4=$(4);f(4.3c)c;4.l.3V=4.3c;4.3c=1v}};q.u(k,k.3d);d 4X=Y;f(!3W&&/3x|3w|3u/.4v(33.62)){d 3W={}};k.6K=7(2a){q.u(k.3d,2a||{});f(2i 3W!=\'1v\'){d 2a=k.3d,2r=k.u.2r;G(d 1G 2M 2a){d h=2a[1G];f(2i h==\'7\')3W.v[1G]=2r.4W(h)}4X=11}};k.6K();d 6M=z q();6M.2B=k.6N;1e.1g=7(3f){6.3f=3f};1e.1g.v={1I:7(4,2t){6.4=$(4);6.2t=2t.2Q();f(6.3f&&6.4.6O){1j{6.4.6O(6.3f,6.2t)}1s(e){d 1h=6.4.1h.2w();f(1h==\'4V\'||1h==\'8N\'){6.2X(6.6U())}1D{25 e}}}1D{6.1K=6.4.6R.6S();f(6.2V)6.2V();6.2X([6.1K.6T(6.2t)])}2Y(7(){2t.3q()},10)},6U:7(){d 1q=J.4Y(\'1q\');1q.3h=\'<6V><4V>\'+6.2t+\'</4V></6V>\';c $A(1q.2z[0].2z[0].2z)}};d 1g=z q();1g.6W=1b.17();1g.6W.v=q.u(z 1e.1g(\'96\'),{2V:7(){6.1K.97(6.4)},2X:7(2h){2h.V((7(2j){6.4.1X.55(2j,6.4)}).1d(6))}});1g.5m=1b.17();1g.5m.v=q.u(z 1e.1g(\'99\'),{2V:7(){6.1K.56(6.4);6.1K.74(11)},2X:7(2h){2h.4m(Y).V((7(2j){6.4.55(2j,6.4.9a)}).1d(6))}});1g.7h=1b.17();1g.7h.v=q.u(z 1e.1g(\'9d\'),{2V:7(){6.1K.56(6.4);6.1K.74(6.4)},2X:7(2h){2h.V((7(2j){6.4.75(2j)}).1d(6))}});1g.76=1b.17();1g.76.v=q.u(z 1e.1g(\'9i\'),{2V:7(){6.1K.9m(6.4)},2X:7(2h){2h.V((7(2j){6.4.1X.55(2j,6.4.9t)}).1d(6))}});k.3S=1b.17();k.3S.v={1I:7(4){6.4=$(4)},2m:7(o){6.4.1f.3j(/\\s+/).1k(7(B){c B.t>0}).2m(o)},5c:7(1f){6.4.1f=1f},7k:7(5a){f(6.1M(5a))c;6.5c(6.1Z().3s(5a).1N(\' \'))},42:7(4c){f(!6.1M(4c))c;6.5c(6.1k(7(1f){c 1f!=4c}).1N(\' \'))},2C:7(){c 6.1Z().1N(\' \')}};q.u(k.3S.v,1p);d 5I={5i:7(){G(d i=0;i<N.t;i++)$(N[i]).h=\'\'},4f:7(4){$(4).4f()},7v:7(){G(d i=0;i<N.t;i++)f($(N[i]).h==\'\')c Y;c 11},1k:7(4){$(4).1k()},5y:7(4){4=$(4);4.4f();f(4.1k)4.1k()}};d D={3a:7(Q){d 12=D.2L($(Q));d 4I=z 1E();G(d i=0;i<12.t;i++){d 4g=D.k.3a(12[i]);f(4g)4I.W(4g)}c 4I.1N(\'&\')},2L:7(Q){Q=$(Q);d 12=z 1E();G(d 1h 2M D.k.2E){d 4H=Q.4D(1h);G(d j=0;j<4H.t;j++)12.W(4H[j])}c 12},7x:7(Q,3N,B){Q=$(Q);d 3H=Q.4D(\'2u\');f(!3N&&!B)c 3H;d 4y=z 1E();G(d i=0;i<3H.t;i++){d 2u=3H[i];f((3N&&2u.2g!=3N)||(B&&2u.B!=B))49;4y.W(2u)}c 4y},7B:7(Q){d 12=D.2L(Q);G(d i=0;i<12.t;i++){d 4=12[i];4.7D();4.4o=\'11\'}},7F:7(Q){d 12=D.2L(Q);G(d i=0;i<12.t;i++){d 4=12[i];4.4o=\'\'}},5z:7(Q){c D.2L(Q).5v(7(4){c 4.2g!=\'31\'&&!4.4o&&[\'2u\',\'1k\',\'3J\'].1M(4.1h.2w())})},7M:7(Q){5I.5y(D.5z(Q))},5w:7(Q){$(Q).5w()}};D.k={3a:7(4){4=$(4);d 1F=4.1h.2w();d 1S=D.k.2E[1F](4);f(1S){d 1O=4n(1S[0]);f(1O.t==0)c;f(1S[1].5D!=1E)1S[1]=[1S[1]];c 1S[1].1C(7(h){c 1O+\'=\'+4n(h)}).1N(\'&\')}},1x:7(4){4=$(4);d 1F=4.1h.2w();d 1S=D.k.2E[1F](4);f(1S)c 1S[1]}};D.k.2E={2u:7(4){6c(4.2g.2w()){1r\'7Z\':1r\'31\':1r\'6l\':1r\'1Y\':c D.k.2E.3J(4);1r\'6g\':1r\'6i\':c D.k.2E.5O(4)}c Y},5O:7(4){f(4.83)c[4.B,4.h]},3J:7(4){c[4.B,4.h]},1k:7(4){c D.k.2E[4.2g==\'1k-6n\'?\'5S\':\'5X\'](4)},5S:7(4){d h=\'\',2b,w=4.85;f(w>=0){2b=4.m[w];h=2b.h||2b.1Y}c[4.B,h]},5X:7(4){d h=[];G(d i=0;i<4.t;i++){d 2b=4.m[i];f(2b.87)h.W(2b.h||2b.1Y)}c[4.B,h]}};d $F=D.k.1x;1e.3D=7(){};1e.3D.v={1I:7(4,1J,1a){6.1J=1J;6.4=$(4);6.1a=1a;6.2K=6.1x();6.2A()},2A:7(){5Z(6.2D.1d(6),6.1J*4z)},2D:7(){d h=6.1x();f(6.2K!=h){6.1a(6.4,h);6.2K=h}}};D.k.3C=1b.17();D.k.3C.v=q.u(z 1e.3D(),{1x:7(){c D.k.1x(6.4)}});D.3C=1b.17();D.3C.v=q.u(z 1e.3D(),{1x:7(){c D.3a(6.4)}});1e.2c=7(){};1e.2c.v={1I:7(4,1a){6.4=$(4);6.1a=1a;6.2K=6.1x();f(6.4.1h.2w()==\'Q\')6.67();1D 6.2A(6.4)},4K:7(){d h=6.1x();f(6.2K!=h){6.1a(6.4,h);6.2K=h}},67:7(){d 12=D.2L(6.4);G(d i=0;i<12.t;i++)6.2A(12[i])},2A:7(4){f(4.2g){6c(4.2g.2w()){1r\'6g\':1r\'6i\':1o.3B(4,\'8j\',6.4K.1d(6));1y;1r\'6l\':1r\'1Y\':1r\'3J\':1r\'1k-6n\':1r\'1k-8t\':1o.3B(4,\'8u\',6.4K.1d(6));1y}}}};D.k.2c=1b.17();D.k.2c.v=q.u(z 1e.2c(),{1x:7(){c D.k.1x(6.4)}});D.2c=1b.17();D.2c.v=q.u(z 1e.2c(),{1x:7(){c D.3a(6.4)}});f(!1W.1o){d 1o=z q()}q.u(1o,{8C:8,8F:9,8H:13,8I:27,8J:37,8L:38,8O:39,8T:40,8X:46,4:7(C){c C.Z||C.91},95:7(C){c(((C.6X)&&(C.6X==1))||((C.6Z)&&(C.6Z==1)))},9b:7(C){c C.9e||(C.9f+(J.3R.2G||J.1c.2G))},9g:7(C){c C.9j||(C.9k+(J.3R.2O||J.1c.2O))},7b:7(C){f(C.7d){C.7d();C.9r()}1D{C.48=Y;C.9w=11}},9A:7(C,1h){d 4=1o.4(C);1H(4.1X&&(!4.1h||(4.1h.3Y()!=1h.3Y())))4=4.1X;c 4},1T:Y,5u:7(4,B,1V,1u){f(!6.1T)6.1T=[];f(4.5f){6.1T.W([4,B,1V,1u]);4.5f(B,1V,1u)}1D f(4.4i){6.1T.W([4,B,1V,1u]);4.4i(\'2I\'+B,1V)}},66:7(){f(!1o.1T)c;G(d i=0;i<1o.1T.t;i++){1o.5N.2n(6,1o.1T[i]);1o.1T[i][0]=1L}1o.1T=Y},3B:7(4,B,1V,1u){d 4=$(4);1u=1u||Y;f(B==\'5U\'&&(33.4u.I(/3x|3w|3u/)||4.4i))B=\'5K\';6.5u(4,B,1V,1u)},5N:7(4,B,1V,1u){d 4=$(4);1u=1u||Y;f(B==\'5U\'&&(33.4u.I(/3x|3w|3u/)||4.4k))B=\'5K\';f(4.5x){4.5x(B,1V,1u)}1D f(4.4k){1j{4.4k(\'2I\'+B,1V)}1s(e){}}}});f(33.4u.I(/\\88\\b/))1o.3B(1W,\'8a\',1o.66,Y);d 2d={6o:Y,4P:7(){6.6z=1W.8e||J.3R.2G||J.1c.2G||0;6.6F=1W.8g||J.3R.2O||J.1c.2O||0},6u:7(4){d 19=0,15=0;2q{19+=4.2O||0;15+=4.2G||0;4=4.1X}1H(4);c[15,19]},35:7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;4=4.1Q}1H(4);c[15,19]},68:7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;4=4.1Q;f(4){p=k.1R(4,\'14\');f(p==\'3T\'||p==\'2o\')1y}}1H(4);c[15,19]},1Q:7(4){f(4.1Q)c 4.1Q;f(4==J.1c)c 4;1H((4=4.1X)&&4!=J.1c)f(k.1R(4,\'14\')!=\'4G\')c 4;c J.1c},8o:7(4,x,y){f(6.6o)c 6.6r(4,x,y);6.3g=x;6.34=y;6.1t=6.35(4);c(y>=6.1t[1]&&y<6.1t[1]+4.2k&&x>=6.1t[0]&&x<6.1t[0]+4.2p)},6r:7(4,x,y){d 4S=6.6u(4);6.3g=x+4S[0]-6.6z;6.34=y+4S[1]-6.6F;6.1t=6.35(4);c(6.34>=6.1t[1]&&6.34<6.1t[1]+4.2k&&6.3g>=6.1t[0]&&6.3g<6.1t[0]+4.2p)},8E:7(3Z,4){f(!3Z)c 0;f(3Z==\'8G\')c((6.1t[1]+4.2k)-6.34)/4.2k;f(3Z==\'8K\')c((6.1t[0]+4.2p)-6.3g)/4.2p},77:7(O,Z){O=$(O);Z=$(Z);Z.l.14=\'2o\';d 2P=6.35(O);Z.l.1n=2P[1]+\'1m\';Z.l.18=2P[0]+\'1m\';Z.l.21=O.2p+\'1m\';Z.l.24=O.2k+\'1m\'},4e:7(4M){d 19=0,15=0;d 4=4M;2q{19+=4.29||0;15+=4.2f||0;f(4.1Q==J.1c)f(k.1R(4,\'14\')==\'2o\')1y}1H(4=4.1Q);4=4M;2q{19-=4.2O||0;15-=4.2G||0}1H(4=4.1X);c[15,19]},77:7(O,Z){d m=q.u({5l:11,5r:11,5B:11,5q:11,29:0,2f:0},N[2]||{});O=$(O);d p=2d.4e(O);Z=$(Z);d 2J=[0,0];d 3v=1L;f(k.1R(Z,\'14\')==\'2o\'){3v=2d.1Q(Z);2J=2d.4e(3v)}f(3v==J.1c){2J[0]-=J.1c.2f;2J[1]-=J.1c.29}f(m.5l)Z.l.18=(p[0]-2J[0]+m.2f)+\'1m\';f(m.5r)Z.l.1n=(p[1]-2J[1]+m.29)+\'1m\';f(m.5B)Z.l.21=O.2p+\'1m\';f(m.5q)Z.l.24=O.2k+\'1m\'},8b:7(4){4=$(4);f(4.l.14==\'2o\')c;2d.4P();d 2P=2d.68(4);d 1n=2P[1];d 18=2P[0];d 21=4.6m;d 24=4.6p;4.6P=18-3X(4.l.18||0);4.6I=1n-3X(4.l.1n||0);4.5k=4.l.21;4.7f=4.l.24;4.l.14=\'2o\';4.l.1n=1n+\'1m\';4.l.18=18+\'1m\';4.l.21=21+\'1m\';4.l.24=24+\'1m\'},8w:7(4){4=$(4);f(4.l.14==\'3T\')c;2d.4P();4.l.14=\'3T\';d 1n=3X(4.l.1n||0)-(4.6I||0);d 18=3X(4.l.18||0)-(4.6P||0);4.l.1n=1n+\'1m\';4.l.18=18+\'1m\';4.l.24=4.7f;4.l.21=4.5k}};f(/3x|3w|3u/.4v(33.62)){2d.35=7(4){d 19=0,15=0;2q{19+=4.29||0;15+=4.2f||0;f(4.1Q==J.1c)f(k.1R(4,\'14\')==\'2o\')1y;4=4.1Q}1H(4);c[15,19]}};',62,600,'||||element||this|function|||||return|var||if||value|||Element|style|options||iterator||Object|||length|extend|prototype|index|||new||name|event|Form|transport||for||match|document||result|Ajax|arguments|source|results|form|||Prototype|object|each|push||false|target||true|elements||position|valueL||create|left|valueT|callback|Class|body|bind|Abstract|className|Insertion|tagName|pair|try|select|url|px|top|Event|Enumerable|div|case|catch|offset|useCapture|undefined|container|getValue|break|replacement|pattern|onComplete|map|else|Array|method|property|while|initialize|frequency|range|null|include|join|key|requestHeaders|offsetParent|getStyle|parameter|observers|inspect|observer|window|parentNode|text|toArray|els|width|start|args|height|throw|request||parameters|offsetTop|methods|opt|EventObserver|Position|html|offsetLeft|type|fragments|typeof|fragment|offsetHeight|oStringList|_each|apply|absolute|offsetWidth|do|cache|decay|content|input|emptyFunction|toLowerCase|end|replace|childNodes|registerCallback|display|toString|onTimerEvent|Serializers|readyState|scrollLeft|exclusive|on|delta|lastValue|getElements|in|hash|scrollTop|offsets|stripScripts|iterable|truncation|gsub|template|initializeRange|Responders|insertContent|setTimeout|json||hidden|status|navigator|ycomp|cumulativeOffset|inject||||serialize|responders|_overflow|Methods|collect|adjacency|xcomp|innerHTML|count|split|response|responseIsSuccess|success|Template|responder|dispatchException|evalScripts|pluck|concat|Request|KHTML|parent|Safari|Konqueror|dispatch|failure|receiver|observe|Observer|TimedObserver|ScriptFragment|responseText|script|inputs|ancestor|textarea|classNames|ObjectRange|node|typeName|RegExp|camelize|none|documentElement|ClassNames|relative|right|overflow|HTMLElement|parseFloat|toUpperCase|mode||currentlyExecuting|remove|__method|Base|memo||slice|returnValue|continue|setOptions|String|classNameToRemove|_reverse|page|focus|queryComponent|Hash|attachEvent|post|detachEvent|Version|reverse|encodeURIComponent|disabled|asynchronous|eval|respondToReadyState|activeRequestCount|Complete|appVersion|test|getTransport|containers|matchingInputs|1000|header|updater|Updater|getElementsByTagName|child|responderToAdd|static|tagElements|queryComponents|defaultView|onElementEvent|css|forElement|values|visibility|prepare|mergedHash|pos|offsetcache|_madePositioned|visible|tbody|findOrStore|_nativeExtensions|createElement|digits|trues|found|prepareReplacement|before|camelizedString|insertBefore|selectNodeContents|exception|falses|criteria|classNameToAdd|params|set|destination|last|addEventListener|indexOf|inline|clear|succ|_originalWidth|setLeft|Top|ActiveXObject|scriptTag|matchOne|setHeight|setTop|without|responderToRemove|_observeAndCache|find|reset|removeEventListener|activate|findFirstElement|setRequestHeaders|setWidth|XMLHttpRequest|constructor|application|xml|onCreate|contentType|Field|onStateChange|keydown|Events|evalJSON|stopObserving|inputSelector|img|Content|evalResponse|selectOne|onreadystatechange|keypress|postBody|onException|selectMany|updateContent|setInterval|insertion|PeriodicalUpdater|userAgent|updateComplete|lastText|timer|unloadCache|registerFormCallbacks|positionedOffset|register|parentElement|children|switch|XMLHTTP|_extended|hide|checkbox|update|radio|these|outerHTML|password|clientWidth|one|includeScrollOffsets|clientHeight|nodeValue|withinIncludingScrolloffsets|Try|scrollTo|realOffset|getComputedStyle|show|currentStyle|auto|deltaX|originalPosition|originalVisibility|originalWidth|originalHeight|opera|deltaY|bottom|array|_originalTop|flatten|addMethods|lambda|Toggle|toggle|insertAdjacentHTML|_originalLeft|PeriodicalExecuter|ownerDocument|createRange|createContextualFragment|contentFromAnonymousTable|table|Before|which|matchAll|button|extractScripts|stripTags|pairString|len|collapse|appendChild|After|clone|toQueryParams|Pattern|evaluate|stop|stringValue|preventDefault|charAt|_originalHeight|substring|Bottom|pairs|Function|add|collections|javascript|detect|findAll|entries|from|first|compact|keys|merge|present|toQueryString|getInputs|Msxml2|Microsoft|unregister|disable|urlencoded|blur|300|enable|responseIsFailure|Uninitialized|Loaded|Interactive|_|get|focusFirstElement|open|send|Requested|With|Accept|overrideMimeType|Connection|close|setRequestHeader|getResponseHeader|JSON|gi|submit|Loading|Success|Failure|checked|200|selectedIndex|www|selected|bMSIE|clearTimeout|unload|absolutize|string|getElementById|pageXOffset|getElementsByClassName|pageYOffset|removeChild|replaceChild|click|getHeight|hasClassName|addClassName|removeClassName|within|cleanWhitespace|nodeType|empty|childOf|multiple|change|getPropertyValue|relativize|setStyle|getDimensions|makePositioned|undoPositioned|makeClipping|KEY_BACKSPACE|undoClipping|overlap|KEY_TAB|vertical|KEY_RETURN|KEY_ESC|KEY_LEFT|horizontal|KEY_UP|member|tr|KEY_RIGHT|0_RC_0|Number|instanceof|shift|KEY_DOWN|bindAsEventListener|call|toColorPart|KEY_DELETE|times|finally|callee|srcElement|sub|scan|truncate|isLeftClick|beforeBegin|setStartBefore|im|afterBegin|firstChild|pointerX|unescapeHTML|beforeEnd|pageX|clientX|pointerY|parseQuery|afterEnd|pageY|clientY|RangeError|setStartAfter|all|any|grep|invoke|stopPropagation|max|nextSibling|min|partition|cancelBubble|reject|sortBy|sort|findElement|zip|pop|createTextNode|escapeHTML|strip'.split('|'),0,{})
VERIFY_IS_VALID(CheckedInt<T>(V(100) PostVExpr)); \
if (isUSigned) { \
VERIFY_IS_VALID_IF(CheckedInt<T>(V(-1) PostVExpr), isTSigned); \
} \
if (sizeof(U) > sizeof(T)) { \
VERIFY_IS_INVALID(CheckedInt<T>( \
V(std::numeric_limits<T>::max()) PostVExpr + one.value())); \
} \
VERIFY_IS_VALID_IF( \
CheckedInt<T>(std::numeric_limits<U>::max()), \
(sizeof(T) > sizeof(U) || \
((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \
VERIFY_IS_VALID_IF(CheckedInt<T>(std::numeric_limits<U>::min()), \
isUSigned == false ? 1 \
: bool(isTSigned) == false ? 0 \
: sizeof(T) >= sizeof(U)); \
}
#define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U, U, +zero) \
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U, CheckedInt<U>, .toChecked<T>())
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int8_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint8_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int16_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint16_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int32_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint32_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int64_t)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint64_t)
typedef signed char signedChar;
typedef unsigned char unsignedChar;
typedef unsigned short unsignedShort;
typedef unsigned int unsignedInt;
typedef unsigned long unsignedLong;
typedef long long longLong;
typedef unsigned long long unsignedLongLong;
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(signedChar)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedChar)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(short)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedShort)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedInt)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(long)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLong)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(longLong)
VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLongLong)
/* Test increment/decrement operators */
CheckedInt<T> x, y;
x = one;
y = x++;
VERIFY(x == two);
VERIFY(y == one);
x = one;
y = ++x;
VERIFY(x == two);
VERIFY(y == two);
x = one;
y = x--;
VERIFY(x == zero);
VERIFY(y == one);
x = one;
y = --x;
VERIFY(x == zero);
VERIFY(y == zero);
x = max;
VERIFY_IS_VALID(x++);
x = max;
VERIFY_IS_INVALID(++x);
x = min;
VERIFY_IS_VALID(x--);
x = min;
VERIFY_IS_INVALID(--x);
gIntegerTypesTested++;
}
int main() {
test<int8_t>();
test<uint8_t>();
test<int16_t>();
test<uint16_t>();
test<int32_t>();
test<uint32_t>();
test<int64_t>();
test<uint64_t>();
test<signed char>();
test<unsigned char>();
test<short>();
test<unsigned short>();
test<int>();
test<unsigned int>();
test<long>();
test<unsigned long>();
test<long long>();
test<unsigned long long>();
const int MIN_TYPES_TESTED = 9;
if (gIntegerTypesTested < MIN_TYPES_TESTED) {
std::cerr << "Only " << gIntegerTypesTested << " have been tested. "
<< "This should not be less than " << MIN_TYPES_TESTED << "."
<< std::endl;
gTestsFailed++;
}
std::cerr << gTestsFailed << " tests failed, " << gTestsPassed
<< " tests passed out of " << gTestsFailed + gTestsPassed
<< " tests, covering " << gIntegerTypesTested
<< " distinct integer types." << std::endl;
return gTestsFailed > 0;
}