/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */ #ifndef MPT_BASE_ALGORITHM_HPP #define MPT_BASE_ALGORITHM_HPP #include "mpt/base/detect_compiler.hpp" #include "mpt/base/namespace.hpp" #include "mpt/base/saturate_cast.hpp" #include #include namespace mpt { inline namespace MPT_INLINE_NS { // Grows x with an exponential factor suitable for increasing buffer sizes. // Clamps the result at limit. // And avoids integer overflows while doing its business. // The growth factor is 1.5, rounding down, execpt for the initial x==1 case. template inline T exponential_grow(const T & x, const Tlimit & limit) { if (x <= 1) { return 2; } T add = std::min(x >> 1, std::numeric_limits::max() - x); return std::min(x + add, mpt::saturate_cast(limit)); } template inline T exponential_grow(const T & x) { return mpt::exponential_grow(x, std::numeric_limits::max()); } // Check if val is in [lo,hi] without causing compiler warnings // if theses checks are always true due to the domain of T. // GCC does not warn if the type is templated. template constexpr bool is_in_range(const T & val, const C & lo, const C & hi) { return lo <= val && val <= hi; } template MPT_CONSTEXPR20_FUN bool contains(const Tcontainer & container, const Tval & value) noexcept(noexcept(std::find(std::begin(container), std::end(container), value))) { return std::find(std::begin(container), std::end(container), value) != std::end(container); } } // namespace MPT_INLINE_NS } // namespace mpt #endif // MPT_BASE_ALGORITHM_HPP