gfx/skia/trunk/src/utils/SkTFitsIn.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2013 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef SkTFitsIn_DEFINED
michael@0 9 #define SkTFitsIn_DEFINED
michael@0 10
michael@0 11 #include "SkTypes.h"
michael@0 12 #include "SkTLogic.h"
michael@0 13 #include <limits>
michael@0 14
michael@0 15 namespace sktfitsin {
michael@0 16 namespace Private {
michael@0 17
michael@0 18 /** SkTHasMoreDigits::type = (digits(A) >= digits(B)) ? SkTrue : SkFalse. */
michael@0 19 template<typename A, typename B> struct SkTHasMoreDigits {
michael@0 20 typedef SkTBool<std::numeric_limits<A>::digits >= std::numeric_limits<B>::digits> type;
michael@0 21 };
michael@0 22
michael@0 23 /** A high or low side predicate which is used when it is statically known
michael@0 24 * that source values are in the range of the Destination.
michael@0 25 */
michael@0 26 template <typename S> struct SkTOutOfRange_False {
michael@0 27 typedef SkFalse can_be_true;
michael@0 28 typedef S source_type;
michael@0 29 static bool apply(S s) {
michael@0 30 return false;
michael@0 31 }
michael@0 32 };
michael@0 33
michael@0 34 /** A low side predicate which tests if the source value < Min(D).
michael@0 35 * Assumes that Min(S) <= Min(D).
michael@0 36 */
michael@0 37 template <typename D, typename S> struct SkTOutOfRange_LT_MinD {
michael@0 38 typedef SkTrue can_be_true;
michael@0 39 typedef S source_type;
michael@0 40 static bool apply(S s) {
michael@0 41 typedef typename SkTHasMoreDigits<S, D>::type precondition;
michael@0 42 SK_COMPILE_ASSERT(precondition::value, SkTOutOfRange_LT_MinD__minS_gt_minD);
michael@0 43
michael@0 44 return s < static_cast<S>((std::numeric_limits<D>::min)());
michael@0 45 }
michael@0 46 };
michael@0 47
michael@0 48 /** A low side predicate which tests if the source value is less than 0. */
michael@0 49 template <typename D, typename S> struct SkTOutOfRange_LT_Zero {
michael@0 50 typedef SkTrue can_be_true;
michael@0 51 typedef S source_type;
michael@0 52 static bool apply(S s) {
michael@0 53 return s < static_cast<S>(0);
michael@0 54 }
michael@0 55 };
michael@0 56
michael@0 57 /** A high side predicate which tests if the source value > Max(D).
michael@0 58 * Assumes that Max(S) >= Max(D).
michael@0 59 */
michael@0 60 template <typename D, typename S> struct SkTOutOfRange_GT_MaxD {
michael@0 61 typedef SkTrue can_be_true;
michael@0 62 typedef S source_type;
michael@0 63 static bool apply(S s) {
michael@0 64 typedef typename SkTHasMoreDigits<S, D>::type precondition;
michael@0 65 SK_COMPILE_ASSERT(precondition::value, SkTOutOfRange_GT_MaxD__maxS_lt_maxD);
michael@0 66
michael@0 67 return s > static_cast<S>((std::numeric_limits<D>::max)());
michael@0 68 }
michael@0 69 };
michael@0 70
michael@0 71 /** Composes two SkTOutOfRange predicates.
michael@0 72 * First checks OutOfRange_Low then, if in range, OutOfRange_High.
michael@0 73 */
michael@0 74 template<class OutOfRange_Low, class OutOfRange_High> struct SkTOutOfRange_Either {
michael@0 75 typedef SkTrue can_be_true;
michael@0 76 typedef typename OutOfRange_Low::source_type source_type;
michael@0 77 static bool apply(source_type s) {
michael@0 78 bool outOfRange = OutOfRange_Low::apply(s);
michael@0 79 if (!outOfRange) {
michael@0 80 outOfRange = OutOfRange_High::apply(s);
michael@0 81 }
michael@0 82 return outOfRange;
michael@0 83 }
michael@0 84 };
michael@0 85
michael@0 86 /** SkTCombineOutOfRange::type is an SkTOutOfRange_XXX type which is the
michael@0 87 * optimal combination of OutOfRange_Low and OutOfRange_High.
michael@0 88 */
michael@0 89 template<class OutOfRange_Low, class OutOfRange_High> struct SkTCombineOutOfRange {
michael@0 90 typedef SkTOutOfRange_Either<OutOfRange_Low, OutOfRange_High> Both;
michael@0 91 typedef SkTOutOfRange_False<typename OutOfRange_Low::source_type> Neither;
michael@0 92
michael@0 93 typedef typename OutOfRange_Low::can_be_true apply_low;
michael@0 94 typedef typename OutOfRange_High::can_be_true apply_high;
michael@0 95
michael@0 96 typedef typename SkTMux<apply_low, apply_high,
michael@0 97 Both, OutOfRange_Low, OutOfRange_High, Neither>::type type;
michael@0 98 };
michael@0 99
michael@0 100 template<typename D, typename S, class OutOfRange_Low, class OutOfRange_High>
michael@0 101 struct SkTRangeChecker {
michael@0 102 /** This is the method which is called at runtime to do the range check. */
michael@0 103 static bool OutOfRange(S s) {
michael@0 104 typedef typename SkTCombineOutOfRange<OutOfRange_Low, OutOfRange_High>::type Combined;
michael@0 105 return Combined::apply(s);
michael@0 106 }
michael@0 107 };
michael@0 108
michael@0 109 /** SkTFitsIn_Unsigned2Unsiged::type is an SkTRangeChecker with an OutOfRange(S s) method
michael@0 110 * the implementation of which is tailored for the source and destination types.
michael@0 111 * Assumes that S and D are unsigned integer types.
michael@0 112 */
michael@0 113 template<typename D, typename S> struct SkTFitsIn_Unsigned2Unsiged {
michael@0 114 typedef SkTOutOfRange_False<S> OutOfRange_Low;
michael@0 115 typedef SkTOutOfRange_GT_MaxD<D, S> OutOfRange_High;
michael@0 116
michael@0 117 typedef SkTRangeChecker<D, S, OutOfRange_Low, OutOfRange_High> HighSideOnlyCheck;
michael@0 118 typedef SkTRangeChecker<D, S, SkTOutOfRange_False<S>, SkTOutOfRange_False<S> > NoCheck;
michael@0 119
michael@0 120 // If std::numeric_limits<D>::digits >= std::numeric_limits<S>::digits, nothing to check.
michael@0 121 // This also protects the precondition of SkTOutOfRange_GT_MaxD.
michael@0 122 typedef typename SkTHasMoreDigits<D, S>::type sourceFitsInDesitination;
michael@0 123 typedef typename SkTIf<sourceFitsInDesitination, NoCheck, HighSideOnlyCheck>::type type;
michael@0 124 };
michael@0 125
michael@0 126 /** SkTFitsIn_Signed2Signed::type is an SkTRangeChecker with an OutOfRange(S s) method
michael@0 127 * the implementation of which is tailored for the source and destination types.
michael@0 128 * Assumes that S and D are signed integer types.
michael@0 129 */
michael@0 130 template<typename D, typename S> struct SkTFitsIn_Signed2Signed {
michael@0 131 typedef SkTOutOfRange_LT_MinD<D, S> OutOfRange_Low;
michael@0 132 typedef SkTOutOfRange_GT_MaxD<D, S> OutOfRange_High;
michael@0 133
michael@0 134 typedef SkTRangeChecker<D, S, OutOfRange_Low, OutOfRange_High> FullCheck;
michael@0 135 typedef SkTRangeChecker<D, S, SkTOutOfRange_False<S>, SkTOutOfRange_False<S> > NoCheck;
michael@0 136
michael@0 137 // If std::numeric_limits<D>::digits >= std::numeric_limits<S>::digits, nothing to check.
michael@0 138 // This also protects the precondition of SkTOutOfRange_LT_MinD and SkTOutOfRange_GT_MaxD.
michael@0 139 typedef typename SkTHasMoreDigits<D, S>::type sourceFitsInDesitination;
michael@0 140 typedef typename SkTIf<sourceFitsInDesitination, NoCheck, FullCheck>::type type;
michael@0 141 };
michael@0 142
michael@0 143 /** SkTFitsIn_Signed2Unsigned::type is an SkTRangeChecker with an OutOfRange(S s) method
michael@0 144 * the implementation of which is tailored for the source and destination types.
michael@0 145 * Assumes that S is a signed integer type and D is an unsigned integer type.
michael@0 146 */
michael@0 147 template<typename D, typename S> struct SkTFitsIn_Signed2Unsigned {
michael@0 148 typedef SkTOutOfRange_LT_Zero<D, S> OutOfRange_Low;
michael@0 149 typedef SkTOutOfRange_GT_MaxD<D, S> OutOfRange_High;
michael@0 150
michael@0 151 typedef SkTRangeChecker<D, S, OutOfRange_Low, OutOfRange_High> FullCheck;
michael@0 152 typedef SkTRangeChecker<D, S, OutOfRange_Low, SkTOutOfRange_False<S> > LowSideOnlyCheck;
michael@0 153
michael@0 154 // If std::numeric_limits<D>::max() >= std::numeric_limits<S>::max(),
michael@0 155 // no need to check the high side. (Until C++11, assume more digits means greater max.)
michael@0 156 // This also protects the precondition of SkTOutOfRange_GT_MaxD.
michael@0 157 typedef typename SkTHasMoreDigits<D, S>::type sourceCannotExceedDesitination;
michael@0 158 typedef typename SkTIf<sourceCannotExceedDesitination, LowSideOnlyCheck, FullCheck>::type type;
michael@0 159 };
michael@0 160
michael@0 161 /** SkTFitsIn_Unsigned2Signed::type is an SkTRangeChecker with an OutOfRange(S s) method
michael@0 162 * the implementation of which is tailored for the source and destination types.
michael@0 163 * Assumes that S is an usigned integer type and D is a signed integer type.
michael@0 164 */
michael@0 165 template<typename D, typename S> struct SkTFitsIn_Unsigned2Signed {
michael@0 166 typedef SkTOutOfRange_False<S> OutOfRange_Low;
michael@0 167 typedef SkTOutOfRange_GT_MaxD<D, S> OutOfRange_High;
michael@0 168
michael@0 169 typedef SkTRangeChecker<D, S, OutOfRange_Low, OutOfRange_High> HighSideOnlyCheck;
michael@0 170 typedef SkTRangeChecker<D, S, SkTOutOfRange_False<S>, SkTOutOfRange_False<S> > NoCheck;
michael@0 171
michael@0 172 // If std::numeric_limits<D>::max() >= std::numeric_limits<S>::max(), nothing to check.
michael@0 173 // (Until C++11, assume more digits means greater max.)
michael@0 174 // This also protects the precondition of SkTOutOfRange_GT_MaxD.
michael@0 175 typedef typename SkTHasMoreDigits<D, S>::type sourceCannotExceedDesitination;
michael@0 176 typedef typename SkTIf<sourceCannotExceedDesitination, NoCheck, HighSideOnlyCheck>::type type;
michael@0 177 };
michael@0 178
michael@0 179 /** SkTFitsIn::type is an SkTRangeChecker with an OutOfRange(S s) method
michael@0 180 * the implementation of which is tailored for the source and destination types.
michael@0 181 * Assumes that S and D are integer types.
michael@0 182 */
michael@0 183 template<typename D, typename S> struct SkTFitsIn {
michael@0 184 // One of the following will be the 'selector' type.
michael@0 185 typedef SkTFitsIn_Signed2Signed<D, S> S2S;
michael@0 186 typedef SkTFitsIn_Signed2Unsigned<D, S> S2U;
michael@0 187 typedef SkTFitsIn_Unsigned2Signed<D, S> U2S;
michael@0 188 typedef SkTFitsIn_Unsigned2Unsiged<D, S> U2U;
michael@0 189
michael@0 190 typedef SkTBool<std::numeric_limits<S>::is_signed> S_is_signed;
michael@0 191 typedef SkTBool<std::numeric_limits<D>::is_signed> D_is_signed;
michael@0 192
michael@0 193 typedef typename SkTMux<S_is_signed, D_is_signed, S2S, S2U, U2S, U2U>::type selector;
michael@0 194 // This type is an SkTRangeChecker.
michael@0 195 typedef typename selector::type type;
michael@0 196 };
michael@0 197
michael@0 198 } // namespace Private
michael@0 199 } // namespace sktfitsin
michael@0 200
michael@0 201 /** Returns true if the integer source value 's' will fit in the integer destination type 'D'. */
michael@0 202 template <typename D, typename S> inline bool SkTFitsIn(S s) {
michael@0 203 SK_COMPILE_ASSERT(std::numeric_limits<S>::is_integer, SkTFitsIn_source_must_be_integer);
michael@0 204 SK_COMPILE_ASSERT(std::numeric_limits<D>::is_integer, SkTFitsIn_destination_must_be_integer);
michael@0 205
michael@0 206 return !sktfitsin::Private::SkTFitsIn<D, S>::type::OutOfRange(s);
michael@0 207 }
michael@0 208
michael@0 209 #endif

mercurial