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

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial