Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / CheckedInt.h
blob940399302faa2e67ba2fc0031df6100bc25e80c7
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* Provides checked integers, detecting integer overflow and divide-by-0. */
8 // Necessary modifications are made to the original CheckedInt.h file when
9 // incorporating it into WebKit:
10 // 1) Comment out #define MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
11 // 2) Comment out #include "mozilla/StandardInteger.h"
12 // 3) Define MOZ_DELETE
13 // 4) Change namespace mozilla to namespace blink
15 #ifndef mozilla_CheckedInt_h_
16 #define mozilla_CheckedInt_h_
19 * Build options. Comment out these #defines to disable the corresponding
20 * optional feature. Disabling features may be useful for code using
21 * CheckedInt outside of Mozilla (e.g. WebKit)
24 // Enable usage of MOZ_STATIC_ASSERT to check for unsupported types.
25 // If disabled, static asserts are replaced by regular assert().
26 // #define MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
29 * End of build options
32 #ifdef MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
33 # include "mozilla/Assertions.h"
34 #else
35 # ifndef MOZ_STATIC_ASSERT
36 # include <cassert>
37 # define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason)
38 # define MOZ_ASSERT(cond, reason) assert((cond) && reason)
39 # endif
40 #endif
42 // #include "mozilla/StandardInteger.h"
44 #ifndef MOZ_DELETE
45 #define MOZ_DELETE
46 #endif
48 #include <climits>
50 namespace blink {
52 namespace detail {
55 * Step 1: manually record supported types
57 * What's nontrivial here is that there are different families of integer
58 * types: basic integer types and stdint types. It is merrily undefined which
59 * types from one family may be just typedefs for a type from another family.
61 * For example, on GCC 4.6, aside from the basic integer types, the only other
62 * type that isn't just a typedef for some of them, is int8_t.
65 struct UnsupportedType {};
67 template<typename IntegerType>
68 struct IsSupportedPass2
70 static const bool value = false;
73 template<typename IntegerType>
74 struct IsSupported
76 static const bool value = IsSupportedPass2<IntegerType>::value;
79 template<>
80 struct IsSupported<int8_t>
81 { static const bool value = true; };
83 template<>
84 struct IsSupported<uint8_t>
85 { static const bool value = true; };
87 template<>
88 struct IsSupported<int16_t>
89 { static const bool value = true; };
91 template<>
92 struct IsSupported<uint16_t>
93 { static const bool value = true; };
95 template<>
96 struct IsSupported<int32_t>
97 { static const bool value = true; };
99 template<>
100 struct IsSupported<uint32_t>
101 { static const bool value = true; };
103 template<>
104 struct IsSupported<int64_t>
105 { static const bool value = true; };
107 template<>
108 struct IsSupported<uint64_t>
109 { static const bool value = true; };
112 template<>
113 struct IsSupportedPass2<char>
114 { static const bool value = true; };
116 template<>
117 struct IsSupportedPass2<unsigned char>
118 { static const bool value = true; };
120 template<>
121 struct IsSupportedPass2<short>
122 { static const bool value = true; };
124 template<>
125 struct IsSupportedPass2<unsigned short>
126 { static const bool value = true; };
128 template<>
129 struct IsSupportedPass2<int>
130 { static const bool value = true; };
132 template<>
133 struct IsSupportedPass2<unsigned>
134 { static const bool value = true; };
136 template<>
137 struct IsSupportedPass2<long>
138 { static const bool value = true; };
140 template<>
141 struct IsSupportedPass2<unsigned long>
142 { static const bool value = true; };
146 * Step 2: some integer-traits kind of stuff.
149 template<size_t Size, bool Signedness>
150 struct StdintTypeForSizeAndSignedness
153 template<>
154 struct StdintTypeForSizeAndSignedness<1, true>
155 { typedef int8_t Type; };
157 template<>
158 struct StdintTypeForSizeAndSignedness<1, false>
159 { typedef uint8_t Type; };
161 template<>
162 struct StdintTypeForSizeAndSignedness<2, true>
163 { typedef int16_t Type; };
165 template<>
166 struct StdintTypeForSizeAndSignedness<2, false>
167 { typedef uint16_t Type; };
169 template<>
170 struct StdintTypeForSizeAndSignedness<4, true>
171 { typedef int32_t Type; };
173 template<>
174 struct StdintTypeForSizeAndSignedness<4, false>
175 { typedef uint32_t Type; };
177 template<>
178 struct StdintTypeForSizeAndSignedness<8, true>
179 { typedef int64_t Type; };
181 template<>
182 struct StdintTypeForSizeAndSignedness<8, false>
183 { typedef uint64_t Type; };
185 template<typename IntegerType>
186 struct UnsignedType
188 typedef typename StdintTypeForSizeAndSignedness<sizeof(IntegerType),
189 false>::Type Type;
192 template<typename IntegerType>
193 struct IsSigned
195 static const bool value = IntegerType(-1) <= IntegerType(0);
198 template<typename IntegerType, size_t Size = sizeof(IntegerType)>
199 struct TwiceBiggerType
201 typedef typename StdintTypeForSizeAndSignedness<
202 sizeof(IntegerType) * 2,
203 IsSigned<IntegerType>::value
204 >::Type Type;
207 template<typename IntegerType>
208 struct TwiceBiggerType<IntegerType, 8>
210 typedef UnsupportedType Type;
213 template<typename IntegerType>
214 struct PositionOfSignBit
216 static const size_t value = CHAR_BIT * sizeof(IntegerType) - 1;
219 template<typename IntegerType>
220 struct MinValue
222 private:
223 typedef typename UnsignedType<IntegerType>::Type UnsignedIntegerType;
224 static const size_t PosOfSignBit = PositionOfSignBit<IntegerType>::value;
226 public:
227 // Bitwise ops may return a larger type, that's why we cast explicitly.
228 // In C++, left bit shifts on signed values is undefined by the standard
229 // unless the shifted value is representable.
230 // Notice that signed-to-unsigned conversions are always well-defined in
231 // the standard as the value congruent to 2**n, as expected. By contrast,
232 // unsigned-to-signed is only well-defined if the value is representable.
233 static const IntegerType value =
234 IsSigned<IntegerType>::value
235 ? IntegerType(UnsignedIntegerType(1) << PosOfSignBit)
236 : IntegerType(0);
239 template<typename IntegerType>
240 struct MaxValue
242 // Tricksy, but covered by the unit test.
243 // Relies heavily on the type of MinValue<IntegerType>::value
244 // being IntegerType.
245 static const IntegerType value = ~MinValue<IntegerType>::value;
249 * Step 3: Implement the actual validity checks.
251 * Ideas taken from IntegerLib, code different.
254 template<typename T>
255 inline bool
256 HasSignBit(T x)
258 // In C++, right bit shifts on negative values is undefined by the standard.
259 // Notice that signed-to-unsigned conversions are always well-defined in the
260 // standard, as the value congruent modulo 2**n as expected. By contrast,
261 // unsigned-to-signed is only well-defined if the value is representable.
262 return bool(typename UnsignedType<T>::Type(x)
263 >> PositionOfSignBit<T>::value);
266 // Bitwise ops may return a larger type, so it's good to use this inline
267 // helper guaranteeing that the result is really of type T.
268 template<typename T>
269 inline T
270 BinaryComplement(T x)
272 return ~x;
275 template<typename T,
276 typename U,
277 bool IsTSigned = IsSigned<T>::value,
278 bool IsUSigned = IsSigned<U>::value>
279 struct DoesRangeContainRange
283 template<typename T, typename U, bool Signedness>
284 struct DoesRangeContainRange<T, U, Signedness, Signedness>
286 static const bool value = sizeof(T) >= sizeof(U);
289 template<typename T, typename U>
290 struct DoesRangeContainRange<T, U, true, false>
292 static const bool value = sizeof(T) > sizeof(U);
295 template<typename T, typename U>
296 struct DoesRangeContainRange<T, U, false, true>
298 static const bool value = false;
301 template<typename T,
302 typename U,
303 bool IsTSigned = IsSigned<T>::value,
304 bool IsUSigned = IsSigned<U>::value,
305 bool DoesTRangeContainURange = DoesRangeContainRange<T, U>::value>
306 struct IsInRangeImpl {};
308 template<typename T, typename U, bool IsTSigned, bool IsUSigned>
309 struct IsInRangeImpl<T, U, IsTSigned, IsUSigned, true>
311 static bool run(U)
313 return true;
317 template<typename T, typename U>
318 struct IsInRangeImpl<T, U, true, true, false>
320 static bool run(U x)
322 return x <= MaxValue<T>::value && x >= MinValue<T>::value;
326 template<typename T, typename U>
327 struct IsInRangeImpl<T, U, false, false, false>
329 static bool run(U x)
331 return x <= MaxValue<T>::value;
335 template<typename T, typename U>
336 struct IsInRangeImpl<T, U, true, false, false>
338 static bool run(U x)
340 return sizeof(T) > sizeof(U) || x <= U(MaxValue<T>::value);
344 template<typename T, typename U>
345 struct IsInRangeImpl<T, U, false, true, false>
347 static bool run(U x)
349 return sizeof(T) >= sizeof(U)
350 ? x >= 0
351 : x >= 0 && x <= U(MaxValue<T>::value);
355 template<typename T, typename U>
356 inline bool
357 IsInRange(U x)
359 return IsInRangeImpl<T, U>::run(x);
362 template<typename T>
363 inline bool
364 IsAddValid(T x, T y)
366 // Addition is valid if the sign of x+y is equal to either that of x or that
367 // of y. Since the value of x+y is undefined if we have a signed type, we
368 // compute it using the unsigned type of the same size.
369 // Beware! These bitwise operations can return a larger integer type,
370 // if T was a small type like int8_t, so we explicitly cast to T.
372 typename UnsignedType<T>::Type ux = x;
373 typename UnsignedType<T>::Type uy = y;
374 typename UnsignedType<T>::Type result = ux + uy;
375 return IsSigned<T>::value
376 ? HasSignBit(BinaryComplement(T((result ^ x) & (result ^ y))))
377 : BinaryComplement(x) >= y;
380 template<typename T>
381 inline bool
382 IsSubValid(T x, T y)
384 // Subtraction is valid if either x and y have same sign, or x-y and x have
385 // same sign. Since the value of x-y is undefined if we have a signed type,
386 // we compute it using the unsigned type of the same size.
387 typename UnsignedType<T>::Type ux = x;
388 typename UnsignedType<T>::Type uy = y;
389 typename UnsignedType<T>::Type result = ux - uy;
391 return IsSigned<T>::value
392 ? HasSignBit(BinaryComplement(T((result ^ x) & (x ^ y))))
393 : x >= y;
396 template<typename T,
397 bool IsSigned = IsSigned<T>::value,
398 bool TwiceBiggerTypeIsSupported =
399 IsSupported<typename TwiceBiggerType<T>::Type>::value>
400 struct IsMulValidImpl {};
402 template<typename T, bool IsSigned>
403 struct IsMulValidImpl<T, IsSigned, true>
405 static bool run(T x, T y)
407 typedef typename TwiceBiggerType<T>::Type TwiceBiggerType;
408 TwiceBiggerType product = TwiceBiggerType(x) * TwiceBiggerType(y);
409 return IsInRange<T>(product);
413 template<typename T>
414 struct IsMulValidImpl<T, true, false>
416 static bool run(T x, T y)
418 const T max = MaxValue<T>::value;
419 const T min = MinValue<T>::value;
421 if (x == 0 || y == 0)
422 return true;
424 if (x > 0) {
425 return y > 0
426 ? x <= max / y
427 : y >= min / x;
430 // If we reach this point, we know that x < 0.
431 return y > 0
432 ? x >= min / y
433 : y >= max / x;
437 template<typename T>
438 struct IsMulValidImpl<T, false, false>
440 static bool run(T x, T y)
442 return y == 0 || x <= MaxValue<T>::value / y;
446 template<typename T>
447 inline bool
448 IsMulValid(T x, T y)
450 return IsMulValidImpl<T>::run(x, y);
453 template<typename T>
454 inline bool
455 IsDivValid(T x, T y)
457 // Keep in mind that in the signed case, min/-1 is invalid because abs(min)>max.
458 return y != 0 &&
459 !(IsSigned<T>::value && x == MinValue<T>::value && y == T(-1));
462 // This is just to shut up msvc warnings about negating unsigned ints.
463 template<typename T, bool IsSigned = IsSigned<T>::value>
464 struct OppositeIfSignedImpl
466 static T run(T x) { return -x; }
468 template<typename T>
469 struct OppositeIfSignedImpl<T, false>
471 static T run(T x) { return x; }
473 template<typename T>
474 inline T
475 OppositeIfSigned(T x)
477 return OppositeIfSignedImpl<T>::run(x);
480 } // namespace detail
484 * Step 4: Now define the CheckedInt class.
488 * @class CheckedInt
489 * @brief Integer wrapper class checking for integer overflow and other errors
490 * @param T the integer type to wrap. Can be any type among the following:
491 * - any basic integer type such as |int|
492 * - any stdint type such as |int8_t|
494 * This class implements guarded integer arithmetic. Do a computation, check
495 * that isValid() returns true, you then have a guarantee that no problem, such
496 * as integer overflow, happened during this computation, and you can call
497 * value() to get the plain integer value.
499 * The arithmetic operators in this class are guaranteed not to raise a signal
500 * (e.g. in case of a division by zero).
502 * For example, suppose that you want to implement a function that computes
503 * (x+y)/z, that doesn't crash if z==0, and that reports on error (divide by
504 * zero or integer overflow). You could code it as follows:
505 @code
506 bool computeXPlusYOverZ(int x, int y, int z, int *result)
508 CheckedInt<int> checkedResult = (CheckedInt<int>(x) + y) / z;
509 if (checkedResult.isValid()) {
510 *result = checkedResult.value();
511 return true;
512 } else {
513 return false;
516 @endcode
518 * Implicit conversion from plain integers to checked integers is allowed. The
519 * plain integer is checked to be in range before being casted to the
520 * destination type. This means that the following lines all compile, and the
521 * resulting CheckedInts are correctly detected as valid or invalid:
522 * @code
523 // 1 is of type int, is found to be in range for uint8_t, x is valid
524 CheckedInt<uint8_t> x(1);
525 // -1 is of type int, is found not to be in range for uint8_t, x is invalid
526 CheckedInt<uint8_t> x(-1);
527 // -1 is of type int, is found to be in range for int8_t, x is valid
528 CheckedInt<int8_t> x(-1);
529 // 1000 is of type int16_t, is found not to be in range for int8_t,
530 // x is invalid
531 CheckedInt<int8_t> x(int16_t(1000));
532 // 3123456789 is of type uint32_t, is found not to be in range for int32_t,
533 // x is invalid
534 CheckedInt<int32_t> x(uint32_t(3123456789));
535 * @endcode
536 * Implicit conversion from
537 * checked integers to plain integers is not allowed. As shown in the
538 * above example, to get the value of a checked integer as a normal integer,
539 * call value().
541 * Arithmetic operations between checked and plain integers is allowed; the
542 * result type is the type of the checked integer.
544 * Checked integers of different types cannot be used in the same arithmetic
545 * expression.
547 * There are convenience typedefs for all stdint types, of the following form
548 * (these are just 2 examples):
549 @code
550 typedef CheckedInt<int32_t> CheckedInt32;
551 typedef CheckedInt<uint16_t> CheckedUint16;
552 @endcode
554 template<typename T>
555 class CheckedInt
557 protected:
558 T mValue;
559 bool mIsValid;
561 template<typename U>
562 CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid)
564 MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
565 "This type is not supported by CheckedInt");
568 public:
570 * Constructs a checked integer with given @a value. The checked integer is
571 * initialized as valid or invalid depending on whether the @a value
572 * is in range.
574 * This constructor is not explicit. Instead, the type of its argument is a
575 * separate template parameter, ensuring that no conversion is performed
576 * before this constructor is actually called. As explained in the above
577 * documentation for class CheckedInt, this constructor checks that its
578 * argument is valid.
580 template<typename U>
581 CheckedInt(U value)
582 : mValue(T(value)),
583 mIsValid(detail::IsInRange<T>(value))
585 MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
586 "This type is not supported by CheckedInt");
589 /** Constructs a valid checked integer with initial value 0 */
590 CheckedInt() : mValue(0), mIsValid(true)
592 MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
593 "This type is not supported by CheckedInt");
596 /** @returns the actual value */
597 T value() const
599 MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)");
600 return mValue;
604 * @returns true if the checked integer is valid, i.e. is not the result
605 * of an invalid operation or of an operation involving an invalid checked
606 * integer
608 bool isValid() const
610 return mIsValid;
613 template<typename U>
614 friend CheckedInt<U> operator +(const CheckedInt<U>& lhs,
615 const CheckedInt<U>& rhs);
616 template<typename U>
617 CheckedInt& operator +=(U rhs);
618 template<typename U>
619 friend CheckedInt<U> operator -(const CheckedInt<U>& lhs,
620 const CheckedInt<U> &rhs);
621 template<typename U>
622 CheckedInt& operator -=(U rhs);
623 template<typename U>
624 friend CheckedInt<U> operator *(const CheckedInt<U>& lhs,
625 const CheckedInt<U> &rhs);
626 template<typename U>
627 CheckedInt& operator *=(U rhs);
628 template<typename U>
629 friend CheckedInt<U> operator /(const CheckedInt<U>& lhs,
630 const CheckedInt<U> &rhs);
631 template<typename U>
632 CheckedInt& operator /=(U rhs);
634 CheckedInt operator -() const
636 // Circumvent msvc warning about - applied to unsigned int.
637 // if we're unsigned, the only valid case anyway is 0
638 // in which case - is a no-op.
639 T result = detail::OppositeIfSigned(mValue);
640 /* Help the compiler perform RVO (return value optimization). */
641 return CheckedInt(result,
642 mIsValid && detail::IsSubValid(T(0),
643 mValue));
647 * @returns true if the left and right hand sides are valid
648 * and have the same value.
650 * Note that these semantics are the reason why we don't offer
651 * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b)
652 * but that would mean that whenever a or b is invalid, a!=b
653 * is always true, which would be very confusing.
655 * For similar reasons, operators <, >, <=, >= would be very tricky to
656 * specify, so we just avoid offering them.
658 * Notice that these == semantics are made more reasonable by these facts:
659 * 1. a==b implies equality at the raw data level
660 * (the converse is false, as a==b is never true among invalids)
661 * 2. This is similar to the behavior of IEEE floats, where a==b
662 * means that a and b have the same value *and* neither is NaN.
664 bool operator ==(const CheckedInt& other) const
666 return mIsValid && other.mIsValid && mValue == other.mValue;
669 /** prefix ++ */
670 CheckedInt& operator++()
672 *this += 1;
673 return *this;
676 /** postfix ++ */
677 CheckedInt operator++(int)
679 CheckedInt tmp = *this;
680 *this += 1;
681 return tmp;
684 /** prefix -- */
685 CheckedInt& operator--()
687 *this -= 1;
688 return *this;
691 /** postfix -- */
692 CheckedInt operator--(int)
694 CheckedInt tmp = *this;
695 *this -= 1;
696 return tmp;
699 private:
701 * The !=, <, <=, >, >= operators are disabled:
702 * see the comment on operator==.
704 template<typename U>
705 bool operator !=(U other) const MOZ_DELETE;
706 template<typename U>
707 bool operator <(U other) const MOZ_DELETE;
708 template<typename U>
709 bool operator <=(U other) const MOZ_DELETE;
710 template<typename U>
711 bool operator >(U other) const MOZ_DELETE;
712 template<typename U>
713 bool operator >=(U other) const MOZ_DELETE;
716 #define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP) \
717 template<typename T> \
718 inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, \
719 const CheckedInt<T> &rhs) \
721 if (!detail::Is##NAME##Valid(lhs.mValue, rhs.mValue)) \
722 return CheckedInt<T>(0, false); \
724 return CheckedInt<T>(lhs.mValue OP rhs.mValue, \
725 lhs.mIsValid && rhs.mIsValid); \
728 MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +)
729 MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -)
730 MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *)
731 MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Div, /)
733 #undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR
735 // Implement castToCheckedInt<T>(x), making sure that
736 // - it allows x to be either a CheckedInt<T> or any integer type
737 // that can be casted to T
738 // - if x is already a CheckedInt<T>, we just return a reference to it,
739 // instead of copying it (optimization)
741 namespace detail {
743 template<typename T, typename U>
744 struct CastToCheckedIntImpl
746 typedef CheckedInt<T> ReturnType;
747 static CheckedInt<T> run(U u) { return u; }
750 template<typename T>
751 struct CastToCheckedIntImpl<T, CheckedInt<T>>
753 typedef const CheckedInt<T>& ReturnType;
754 static const CheckedInt<T>& run(const CheckedInt<T>& u) { return u; }
757 } // namespace detail
759 template<typename T, typename U>
760 inline typename detail::CastToCheckedIntImpl<T, U>::ReturnType
761 castToCheckedInt(U u)
763 return detail::CastToCheckedIntImpl<T, U>::run(u);
766 #define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
767 template<typename T> \
768 template<typename U> \
769 CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(U rhs) \
771 *this = *this OP castToCheckedInt<T>(rhs); \
772 return *this; \
774 template<typename T, typename U> \
775 inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, U rhs) \
777 return lhs OP castToCheckedInt<T>(rhs); \
779 template<typename T, typename U> \
780 inline CheckedInt<T> operator OP(U lhs, const CheckedInt<T> &rhs) \
782 return castToCheckedInt<T>(lhs) OP rhs; \
785 MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
786 MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
787 MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
788 MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
790 #undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS
792 template<typename T, typename U>
793 inline bool
794 operator ==(const CheckedInt<T> &lhs, U rhs)
796 return lhs == castToCheckedInt<T>(rhs);
799 template<typename T, typename U>
800 inline bool
801 operator ==(U lhs, const CheckedInt<T> &rhs)
803 return castToCheckedInt<T>(lhs) == rhs;
806 // Convenience typedefs.
807 typedef CheckedInt<int8_t> CheckedInt8;
808 typedef CheckedInt<uint8_t> CheckedUint8;
809 typedef CheckedInt<int16_t> CheckedInt16;
810 typedef CheckedInt<uint16_t> CheckedUint16;
811 typedef CheckedInt<int32_t> CheckedInt32;
812 typedef CheckedInt<uint32_t> CheckedUint32;
813 typedef CheckedInt<int64_t> CheckedInt64;
814 typedef CheckedInt<uint64_t> CheckedUint64;
816 } // namespace blink
818 #endif /* mozilla_CheckedInt_h_ */