summaryrefslogtreecommitdiff
path: root/chromium/components/zucchini/algorithm.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/zucchini/algorithm.h')
-rw-r--r--chromium/components/zucchini/algorithm.h50
1 files changed, 49 insertions, 1 deletions
diff --git a/chromium/components/zucchini/algorithm.h b/chromium/components/zucchini/algorithm.h
index 7143a953626..463aca3840d 100644
--- a/chromium/components/zucchini/algorithm.h
+++ b/chromium/components/zucchini/algorithm.h
@@ -48,7 +48,7 @@ T InclusiveClamp(T value, T lo, T hi) {
// Returns the minimum multiple of |m| that's no less than |x|. Assumes |m > 0|
// and |x| is sufficiently small so that no overflow occurs.
template <class T>
-constexpr T ceil(T x, T m) {
+constexpr T AlignCeil(T x, T m) {
static_assert(std::is_unsigned<T>::value, "Value type must be unsigned.");
return T((x + m - 1) / m) * m;
}
@@ -62,6 +62,47 @@ void SortAndUniquify(std::vector<T>* container) {
container->shrink_to_fit();
}
+// Extracts a single bit at |pos| from integer |v|.
+template <int pos, typename T>
+constexpr T GetBit(T v) {
+ return (v >> pos) & 1;
+}
+
+// Extracts bits in inclusive range [|lo|, |hi|] from integer |v|, and returns
+// the sign-extend result. For example, let the (MSB-first) bits in a 32-bit int
+// |v| be:
+// xxxxxxxx xxxxxSii iiiiiiii iyyyyyyy,
+// hi^ lo^ => lo = 7, hi = 18
+// To extract "Sii iiiiiiii i", calling
+// GetSignedBits<7, 18>(v);
+// produces the sign-extended result:
+// SSSSSSSS SSSSSSSS SSSSSiii iiiiiiii.
+template <int lo, int hi, typename T>
+constexpr typename std::make_signed<T>::type GetSignedBits(T v) {
+ constexpr int kNumBits = sizeof(T) * 8;
+ using SignedType = typename std::make_signed<T>::type;
+ // Assumes 0 <= |lo| <= |hi| < |kNumBits|.
+ // How this works:
+ // (1) Shift-left by |kNumBits - 1 - hi| to clear "left" bits.
+ // (2) Shift-right by |kNumBits - 1 - hi + lo| to clear "right" bits. The
+ // input is casted to a signed type to perform sign-extension.
+ return static_cast<SignedType>(v << (kNumBits - 1 - hi)) >>
+ (kNumBits - 1 - hi + lo);
+}
+
+// Similar to GetSignedBits(), but returns the zero-extended result. For the
+// above example, calling
+// GetUnsignedBits<7, 18>(v);
+// results in:
+// 00000000 00000000 0000Siii iiiiiiii.
+template <int lo, int hi, typename T>
+constexpr typename std::make_unsigned<T>::type GetUnsignedBits(T v) {
+ constexpr int kNumBits = sizeof(T) * 8;
+ using UnsignedType = typename std::make_unsigned<T>::type;
+ return static_cast<UnsignedType>(v << (kNumBits - 1 - hi)) >>
+ (kNumBits - 1 - hi + lo);
+}
+
// Copies bits at |pos| in |v| to all higher bits, and returns the result as the
// same int type as |v|.
template <typename T>
@@ -79,6 +120,13 @@ constexpr T SignExtend(T v) {
return static_cast<typename std::make_signed<T>::type>(v << kShift) >> kShift;
}
+// Determines whether |v|, if interpreted as a signed integer, is representable
+// using |digs| bits. |1 <= digs <= sizeof(T)| is assumed.
+template <int digs, typename T>
+constexpr bool SignedFit(T v) {
+ return v == SignExtend<digs - 1, T>(v);
+}
+
} // namespace zucchini
#endif // COMPONENTS_ZUCCHINI_ALGORITHM_H_