File tree Expand file tree Collapse file tree 2 files changed +37
-12
lines changed
lib/inc/sys_string/impl/util Expand file tree Collapse file tree 2 files changed +37
-12
lines changed Original file line number Diff line number Diff line change @@ -183,25 +183,28 @@ namespace sysstr::util
183183 }
184184
185185 private:
186+
186187
187188 void grow ()
188189 {
189190 if (this ->m_size < this ->capacity ())
190191 return ;
191-
192+
192193 size_type desired;
193-
194- if (this ->capacity () == 0 )
194+ if (this ->capacity () < growth_increment) {
195195 desired = growth_increment;
196- else if (this ->capacity () / growth_div_factor < this ->max_size () / growth_mul_factor)
197- desired = (this ->capacity () * growth_mul_factor) / growth_div_factor;
198- else if (this ->capacity () < this ->max_size () - growth_increment)
199- desired = this ->capacity () + growth_increment;
200- else if (this ->capacity () == this ->max_size ())
201- throw std::bad_alloc ();
202- else
203- desired = this ->max_size ();
204-
196+ } else {
197+ desired = util::saturated_mul_div (this ->capacity (), growth_mul_factor, growth_div_factor);
198+ if (desired == this ->capacity () || desired >= this ->max_size ()) {
199+ if (this ->capacity () < this ->max_size () - growth_increment)
200+ desired = this ->capacity () + growth_increment;
201+ else if (this ->capacity () == this ->max_size ())
202+ throw std::bad_alloc ();
203+ else
204+ desired = this ->max_size ();
205+ }
206+ }
207+
205208 this ->m_storage .reallocate (desired, this ->m_size );
206209 }
207210
Original file line number Diff line number Diff line change @@ -108,6 +108,28 @@ namespace sysstr::util
108108
109109 #endif
110110
111+ template <std::unsigned_integral T>
112+ constexpr T saturated_mul_div (T val, std::convertible_to<T> auto numerator, std::convertible_to<T> auto denominator) {
113+ T num = T (numerator);
114+ T denom = T (denominator);
115+ T whole = num / denom;
116+ num = num % denom;
117+
118+ T quot = val / denom;
119+ T rem = val % denom;
120+ T increment = quot * num;
121+
122+ T extra = rem * num;
123+ quot = extra / denom;
124+ rem = extra % denom;
125+ increment += quot;
126+ increment += (2 * rem >= denom);
127+
128+ if (whole && (std::numeric_limits<T>::max () - increment) / whole < val)
129+ return std::numeric_limits<T>::max ();
130+ return val * whole + increment;
131+ }
132+
111133}
112134
113135#endif
You can’t perform that action at this time.
0 commit comments