Move overflow protected add helpers to math.

This commit is contained in:
Thomas Geymayer 2014-07-22 00:36:17 +02:00
parent 23413b4781
commit f25abad9d7
7 changed files with 66 additions and 20 deletions

View File

@ -305,9 +305,9 @@ namespace canvas
} }
// Add sizes of all children in layout direction // Add sizes of all children in layout direction
safeAdd(min_size.x(), item_data.min_size); SGMisc<int>::addClipOverflowInplace(min_size.x(), item_data.min_size);
safeAdd(max_size.x(), item_data.max_size); SGMisc<int>::addClipOverflowInplace(max_size.x(), item_data.max_size);
safeAdd(size_hint.x(), item_data.size_hint); SGMisc<int>::addClipOverflowInplace(size_hint.x(), item_data.size_hint);
// Take maximum in fixed (non-layouted) direction // Take maximum in fixed (non-layouted) direction
min_size.y() = std::max( min_size.y(), min_size.y() = std::max( min_size.y(),
@ -320,9 +320,9 @@ namespace canvas
_layout_data.has_hfw = _layout_data.has_hfw || item.hasHeightForWidth(); _layout_data.has_hfw = _layout_data.has_hfw || item.hasHeightForWidth();
} }
safeAdd(min_size.x(), _layout_data.padding); SGMisc<int>::addClipOverflowInplace(min_size.x(), _layout_data.padding);
safeAdd(max_size.x(), _layout_data.padding); SGMisc<int>::addClipOverflowInplace(max_size.x(), _layout_data.padding);
safeAdd(size_hint.x(), _layout_data.padding); SGMisc<int>::addClipOverflowInplace(size_hint.x(), _layout_data.padding);
_layout_data.min_size = min_size.x(); _layout_data.min_size = min_size.x();
_layout_data.max_size = max_size.x(); _layout_data.max_size = max_size.x();

View File

@ -108,15 +108,6 @@ namespace canvas
return layout_item->minimumSize().y(); return layout_item->minimumSize().y();
} }
//----------------------------------------------------------------------------
void Layout::safeAdd(int& a, int b)
{
if( SGLimits<int>::max() - b < a )
a = SGLimits<int>::max();
else
a += b;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Layout::distribute(std::vector<ItemData>& items, const ItemData& space) void Layout::distribute(std::vector<ItemData>& items, const ItemData& space)
{ {

View File

@ -104,11 +104,6 @@ namespace canvas
*/ */
virtual void doLayout(const SGRecti& geom) = 0; virtual void doLayout(const SGRecti& geom) = 0;
/**
* Add two integers taking care of overflow (limit to INT_MAX)
*/
static void safeAdd(int& a, int b);
/** /**
* Distribute the available @a space to all @a items * Distribute the available @a space to all @a items
*/ */

View File

@ -41,6 +41,30 @@ public:
static T clip(const T& a, const T& _min, const T& _max) static T clip(const T& a, const T& _min, const T& _max)
{ return max(_min, min(_max, a)); } { return max(_min, min(_max, a)); }
/// Add two (integer) values taking care of overflows.
static T addClipOverflow(T a, T b)
{
if( b > 0 )
{
if( SGLimits<T>::max() - b < a )
return SGLimits<T>::max();
}
else
{
if( SGLimits<T>::min() - b > a )
return SGLimits<T>::min();
}
return a + b;
}
/// Add two (integer) values in place, taking care of overflows.
static T& addClipOverflowInplace(T& a, T b)
{
return a = addClipOverflow(a, b);
}
/** /**
* Seek a variable towards a target value with given rate and timestep * Seek a variable towards a target value with given rate and timestep
* *

View File

@ -196,6 +196,17 @@ SGVec2<T>
max(S s, const SGVec2<T>& v) max(S s, const SGVec2<T>& v)
{ return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); } { return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
/// Add two vectors taking care of (integer) overflows. The values are limited
/// to the respective minimum and maximum values.
template<class T>
SGVec2<T> addClipOverflow(SGVec2<T> const& lhs, SGVec2<T> const& rhs)
{
return SGVec2<T>(
SGMisc<T>::addClipOverflow(lhs.x(), rhs.x()),
SGMisc<T>::addClipOverflow(lhs.y(), rhs.y())
);
}
/// Scalar dot product /// Scalar dot product
template<typename T> template<typename T>
inline inline

View File

@ -288,6 +288,18 @@ max(S s, const SGVec3<T>& v)
SGMisc<T>::max(s, v(2))); SGMisc<T>::max(s, v(2)));
} }
/// Add two vectors taking care of (integer) overflows. The values are limited
/// to the respective minimum and maximum values.
template<class T>
SGVec3<T> addClipOverflow(SGVec3<T> const& lhs, SGVec3<T> const& rhs)
{
return SGVec3<T>(
SGMisc<T>::addClipOverflow(lhs.x(), rhs.x()),
SGMisc<T>::addClipOverflow(lhs.y(), rhs.y()),
SGMisc<T>::addClipOverflow(lhs.z(), rhs.z())
);
}
/// Scalar dot product /// Scalar dot product
template<typename T> template<typename T>
inline inline

View File

@ -244,6 +244,19 @@ max(S s, const SGVec4<T>& v)
SGMisc<T>::max(s, v(3))); SGMisc<T>::max(s, v(3)));
} }
/// Add two vectors taking care of (integer) overflows. The values are limited
/// to the respective minimum and maximum values.
template<class T>
SGVec4<T> addClipOverflow(SGVec4<T> const& lhs, SGVec4<T> const& rhs)
{
return SGVec4<T>(
SGMisc<T>::addClipOverflow(lhs.x(), rhs.x()),
SGMisc<T>::addClipOverflow(lhs.y(), rhs.y()),
SGMisc<T>::addClipOverflow(lhs.z(), rhs.z()),
SGMisc<T>::addClipOverflow(lhs.w(), rhs.w())
);
}
/// Scalar dot product /// Scalar dot product
template<typename T> template<typename T>
inline inline