OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkTFitsIn_DEFINED | 8 #ifndef SkTFitsIn_DEFINED |
9 #define SkTFitsIn_DEFINED | 9 #define SkTFitsIn_DEFINED |
10 | 10 |
11 #include "SkTypes.h" | 11 #include "SkTypes.h" |
12 #include "SkTLogic.h" | 12 #include "SkTLogic.h" |
13 #include <limits> | 13 #include <limits> |
| 14 #include <type_traits> |
14 | 15 |
15 namespace sktfitsin { | 16 namespace sktfitsin { |
16 namespace Private { | 17 namespace Private { |
17 | 18 |
18 /** SkTMux::type = (a && b) ? Both : (a) ? A : (b) ? B : Neither; */ | 19 /** SkTMux::type = (a && b) ? Both : (a) ? A : (b) ? B : Neither; */ |
19 template <bool a, bool b, typename Both, typename A, typename B, typename Neithe
r> | 20 template <bool a, bool b, typename Both, typename A, typename B, typename Neithe
r> |
20 struct SkTMux { | 21 struct SkTMux { |
21 using type = skstd::conditional_t<a, skstd::conditional_t<b, Both, A>, | 22 using type = skstd::conditional_t<a, skstd::conditional_t<b, Both, A>, |
22 skstd::conditional_t<b, B, Neither>>; | 23 skstd::conditional_t<b, B, Neither>>; |
23 }; | 24 }; |
24 | 25 |
25 /** SkTHasMoreDigits = (digits(A) >= digits(B)) ? true_type : false_type. */ | 26 /** SkTHasMoreDigits = (digits(A) >= digits(B)) ? true_type : false_type. */ |
26 template<typename A, typename B> struct SkTHasMoreDigits | 27 template<typename A, typename B> struct SkTHasMoreDigits |
27 : skstd::bool_constant<std::numeric_limits<A>::digits >= std::numeric_limits
<B>::digits> | 28 : skstd::bool_constant<std::numeric_limits<A>::digits >= std::numeric_limits
<B>::digits> |
28 { }; | 29 { }; |
29 | 30 |
30 /** A high or low side predicate which is used when it is statically known | 31 /** A high or low side predicate which is used when it is statically known |
31 * that source values are in the range of the Destination. | 32 * that source values are in the range of the Destination. |
32 */ | 33 */ |
33 template <typename S> struct SkTOutOfRange_False { | 34 template <typename S> struct SkTOutOfRange_False { |
34 typedef skstd::false_type can_be_true; | 35 typedef std::false_type can_be_true; |
35 typedef S source_type; | 36 typedef S source_type; |
36 static bool apply(S s) { | 37 static bool apply(S s) { |
37 return false; | 38 return false; |
38 } | 39 } |
39 }; | 40 }; |
40 | 41 |
41 /** A low side predicate which tests if the source value < Min(D). | 42 /** A low side predicate which tests if the source value < Min(D). |
42 * Assumes that Min(S) <= Min(D). | 43 * Assumes that Min(S) <= Min(D). |
43 */ | 44 */ |
44 template <typename D, typename S> struct SkTOutOfRange_LT_MinD { | 45 template <typename D, typename S> struct SkTOutOfRange_LT_MinD { |
45 typedef skstd::true_type can_be_true; | 46 typedef std::true_type can_be_true; |
46 typedef S source_type; | 47 typedef S source_type; |
47 static bool apply(S s) { | 48 static bool apply(S s) { |
48 typedef SkTHasMoreDigits<S, D> precondition; | 49 typedef SkTHasMoreDigits<S, D> precondition; |
49 static_assert(precondition::value, "SkTOutOfRange_LT_MinD__minS_gt_minD"
); | 50 static_assert(precondition::value, "SkTOutOfRange_LT_MinD__minS_gt_minD"
); |
50 | 51 |
51 return s < static_cast<S>((std::numeric_limits<D>::min)()); | 52 return s < static_cast<S>((std::numeric_limits<D>::min)()); |
52 } | 53 } |
53 }; | 54 }; |
54 | 55 |
55 /** A low side predicate which tests if the source value is less than 0. */ | 56 /** A low side predicate which tests if the source value is less than 0. */ |
56 template <typename D, typename S> struct SkTOutOfRange_LT_Zero { | 57 template <typename D, typename S> struct SkTOutOfRange_LT_Zero { |
57 typedef skstd::true_type can_be_true; | 58 typedef std::true_type can_be_true; |
58 typedef S source_type; | 59 typedef S source_type; |
59 static bool apply(S s) { | 60 static bool apply(S s) { |
60 return s < static_cast<S>(0); | 61 return s < static_cast<S>(0); |
61 } | 62 } |
62 }; | 63 }; |
63 | 64 |
64 /** A high side predicate which tests if the source value > Max(D). | 65 /** A high side predicate which tests if the source value > Max(D). |
65 * Assumes that Max(S) >= Max(D). | 66 * Assumes that Max(S) >= Max(D). |
66 */ | 67 */ |
67 template <typename D, typename S> struct SkTOutOfRange_GT_MaxD { | 68 template <typename D, typename S> struct SkTOutOfRange_GT_MaxD { |
68 typedef skstd::true_type can_be_true; | 69 typedef std::true_type can_be_true; |
69 typedef S source_type; | 70 typedef S source_type; |
70 static bool apply(S s) { | 71 static bool apply(S s) { |
71 typedef SkTHasMoreDigits<S, D> precondition; | 72 typedef SkTHasMoreDigits<S, D> precondition; |
72 static_assert(precondition::value, "SkTOutOfRange_GT_MaxD__maxS_lt_maxD"
); | 73 static_assert(precondition::value, "SkTOutOfRange_GT_MaxD__maxS_lt_maxD"
); |
73 | 74 |
74 return s > static_cast<S>((std::numeric_limits<D>::max)()); | 75 return s > static_cast<S>((std::numeric_limits<D>::max)()); |
75 } | 76 } |
76 }; | 77 }; |
77 | 78 |
78 /** Composes two SkTOutOfRange predicates. | 79 /** Composes two SkTOutOfRange predicates. |
79 * First checks OutOfRange_Low then, if in range, OutOfRange_High. | 80 * First checks OutOfRange_Low then, if in range, OutOfRange_High. |
80 */ | 81 */ |
81 template<class OutOfRange_Low, class OutOfRange_High> struct SkTOutOfRange_Eithe
r { | 82 template<class OutOfRange_Low, class OutOfRange_High> struct SkTOutOfRange_Eithe
r { |
82 typedef skstd::true_type can_be_true; | 83 typedef std::true_type can_be_true; |
83 typedef typename OutOfRange_Low::source_type source_type; | 84 typedef typename OutOfRange_Low::source_type source_type; |
84 static bool apply(source_type s) { | 85 static bool apply(source_type s) { |
85 bool outOfRange = OutOfRange_Low::apply(s); | 86 bool outOfRange = OutOfRange_Low::apply(s); |
86 if (!outOfRange) { | 87 if (!outOfRange) { |
87 outOfRange = OutOfRange_High::apply(s); | 88 outOfRange = OutOfRange_High::apply(s); |
88 } | 89 } |
89 return outOfRange; | 90 return outOfRange; |
90 } | 91 } |
91 }; | 92 }; |
92 | 93 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 209 |
209 /** Returns true if the integer source value 's' will fit in the integer destina
tion type 'D'. */ | 210 /** Returns true if the integer source value 's' will fit in the integer destina
tion type 'D'. */ |
210 template <typename D, typename S> inline bool SkTFitsIn(S s) { | 211 template <typename D, typename S> inline bool SkTFitsIn(S s) { |
211 static_assert(std::numeric_limits<S>::is_integer, "SkTFitsIn_source_must_be_
integer"); | 212 static_assert(std::numeric_limits<S>::is_integer, "SkTFitsIn_source_must_be_
integer"); |
212 static_assert(std::numeric_limits<D>::is_integer, "SkTFitsIn_destination_mus
t_be_integer"); | 213 static_assert(std::numeric_limits<D>::is_integer, "SkTFitsIn_destination_mus
t_be_integer"); |
213 | 214 |
214 return !sktfitsin::Private::SkTFitsIn<D, S>::type::OutOfRange(s); | 215 return !sktfitsin::Private::SkTFitsIn<D, S>::type::OutOfRange(s); |
215 } | 216 } |
216 | 217 |
217 #endif | 218 #endif |
OLD | NEW |