1 // Copyright 2009-2020 Intel Corporation 2 // SPDX-License-Identifier: Apache-2.0 3 4 #pragma once 5 6 // stl 7 #include <algorithm> 8 // common 9 #include "constants.h" 10 #include "vec.h" 11 12 namespace rkcommon { 13 namespace math { 14 15 using std::max; 16 using std::min; 17 18 /*! default implementatoin of 'anyLessThan' for scalar types, so we 19 can make a range<float>s etc. Vec-types will overwrite that and 20 test if _any_ dimension is less */ 21 template <typename TA, typename TB> anyLessThan(const TA & a,const TB & b)22 inline bool anyLessThan(const TA &a, const TB &b) 23 { 24 return a < b; 25 } 26 27 template <typename T> 28 struct range_t 29 { range_trange_t30 range_t() : lower(pos_inf), upper(neg_inf) {} range_trange_t31 range_t(const EmptyTy &) : lower(pos_inf), upper(neg_inf) {} range_trange_t32 range_t(const ZeroTy &) : lower(zero), upper(zero) {} range_trange_t33 range_t(const OneTy &) : lower(zero), upper(one) {} range_trange_t34 range_t(const T &t) : lower(t), upper(t) {} range_trange_t35 range_t(const T &_lower, const T &_upper) : lower(_lower), upper(_upper) 36 { 37 } range_trange_t38 range_t(const T *v) : lower(v[0]), upper(v[1]) {} 39 40 template <typename other_t> range_trange_t41 explicit range_t(const range_t<other_t> &other) 42 : lower(T(other.lower)), upper(T(other.upper)) 43 { 44 } 45 sizerange_t46 inline T size() const 47 { 48 return upper - lower; 49 } 50 centerrange_t51 inline T center() const 52 { 53 return .5f * (lower + upper); 54 } 55 extendrange_t56 inline void extend(const T &t) 57 { 58 lower = min(lower, t); 59 upper = max(upper, t); 60 } 61 extendrange_t62 inline void extend(const range_t<T> &t) 63 { 64 lower = min(lower, t.lower); 65 upper = max(upper, t.upper); 66 } 67 68 /*! take given value t, and 'clamp' it to 'this->'range; ie, if it 69 already is inside the range return as is, otherwise move it to 70 either lower or upper of this range. Warning: the value 71 returned by this can be 'upper', which is NOT strictly part of 72 the range! */ clamprange_t73 inline T clamp(const T &t) const 74 { 75 return max(lower, min(t, upper)); 76 } 77 78 /*! Try to parse given string into a range; and return if 79 successful. if not, return defaultvalue */ 80 static range_t<T> fromString( 81 const std::string &string, 82 const range_t<T> &defaultValue = rkcommon::math::empty); 83 toVec2range_t84 inline vec_t<T, 2> toVec2() const 85 { 86 return vec_t<T, 2>(lower, upper); 87 } 88 emptyrange_t89 inline bool empty() const 90 { 91 return anyLessThan(upper, lower); 92 } 93 containsrange_t94 inline bool contains(const T &vec) const 95 { 96 return !anyLessThan(vec, lower) && !anyLessThan(upper, vec); 97 } 98 99 inline operator T*() 100 { 101 return static_cast<T*>(&lower); 102 } 103 104 inline operator const T*() const 105 { 106 return static_cast<const T*>(&lower); 107 } 108 109 T lower, upper; 110 }; 111 112 template <typename T> 113 inline std::ostream &operator<<(std::ostream &o, const range_t<T> &r) 114 { 115 o << "[" << r.lower << "," << r.upper << "]"; 116 return o; 117 } 118 119 /*! scale range, per dimension */ 120 template <typename T> 121 inline range_t<T> operator*(const range_t<T> &range, const T &scale) 122 { 123 return range_t<T>(range.lower * scale, range.upper * scale); 124 } 125 126 /*! scale range, per dimension */ 127 template <typename T> 128 inline range_t<T> operator*(const T &scale, const range_t<T> &range) 129 { 130 return range_t<T>(range.lower * scale, range.upper * scale); 131 } 132 133 /*! translate a range, per dimension */ 134 template <typename T> 135 inline range_t<T> operator+(const range_t<T> &range, const T &translation) 136 { 137 return range_t<T>(range.lower + translation, range.upper + translation); 138 } 139 140 /*! translate a range, per dimension */ 141 template <typename T> 142 inline range_t<T> operator+(const T &translation, const range_t<T> &range) 143 { 144 return range_t<T>(range.lower + translation, range.upper + translation); 145 } 146 147 // range_t aliases //////////////////////////////////////////////////////// 148 149 using range1f = range_t<float>; 150 using range2f = range_t<vec2f>; 151 using range3f = range_t<vec3f>; 152 using range4f = range_t<vec4f>; 153 using range1i = range_t<int>; 154 using range2i = range_t<vec2i>; 155 using range3i = range_t<vec3i>; 156 using range4i = range_t<vec4i>; 157 158 } // namespace math 159 } // namespace rkcommon 160