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