}
// Add sizes of all children in layout direction
- safeAdd(min_size.x(), item_data.min_size);
- safeAdd(max_size.x(), item_data.max_size);
- safeAdd(size_hint.x(), item_data.size_hint);
+ SGMisc<int>::addClipOverflowInplace(min_size.x(), item_data.min_size);
+ SGMisc<int>::addClipOverflowInplace(max_size.x(), item_data.max_size);
+ SGMisc<int>::addClipOverflowInplace(size_hint.x(), item_data.size_hint);
// Take maximum in fixed (non-layouted) direction
min_size.y() = std::max( min_size.y(),
_layout_data.has_hfw = _layout_data.has_hfw || item.hasHeightForWidth();
}
- safeAdd(min_size.x(), _layout_data.padding);
- safeAdd(max_size.x(), _layout_data.padding);
- safeAdd(size_hint.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(min_size.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(max_size.x(), _layout_data.padding);
+ SGMisc<int>::addClipOverflowInplace(size_hint.x(), _layout_data.padding);
_layout_data.min_size = min_size.x();
_layout_data.max_size = max_size.x();
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)
{
*/
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
*/
static T clip(const T& a, const T& _min, const T& _max)
{ 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
*
max(S s, const SGVec2<T>& v)
{ 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
template<typename T>
inline
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
template<typename T>
inline
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
template<typename T>
inline