From 6ce7132b1b05d2b61fedd782b8271b1118789ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= Date: Fri, 6 Mar 2026 09:21:07 +0100 Subject: [PATCH] ipa: libipa: quantized: Enable `constexpr` operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is nothing inherently non-constexpr in the `Quantized` type. Whether it can work in `constexpr` contexts depends on the traits type. There is no reason to explicitly disallow `constexpr` operation. So mark all eligible methods `constexpr`. In addition, add some `static_assert()`s to the "quantized" test to check constexpr operation. For example, `FixedPointQTraits<...>::toFloat()` is `constexpr`, so this enables the construction of `{U,}Q<...>` from the underlying quantized value in `constexpr` contexts, which can be useful for example for storing default values in e.g. `static constexpr` variables. Signed-off-by: Barnabás Pőcze Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/ipa/libipa/quantized.h | 32 +++++++++++++++++++------------- test/ipa/libipa/quantized.cpp | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/ipa/libipa/quantized.h b/src/ipa/libipa/quantized.h index 6bd196c7..8d7b06a2 100644 --- a/src/ipa/libipa/quantized.h +++ b/src/ipa/libipa/quantized.h @@ -24,34 +24,40 @@ struct Quantized { static_assert(std::is_arithmetic_v, "Quantized: QuantizedType must be arithmetic"); - Quantized() + constexpr Quantized() : Quantized(0.0f) {} - Quantized(float x) { *this = x; } - Quantized(QuantizedType x) { *this = x; } - Quantized &operator=(float x) + constexpr Quantized(float x) + : Quantized(Traits::fromFloat(x)) { - quantized_ = Traits::fromFloat(x); - value_ = Traits::toFloat(quantized_); + } + + constexpr Quantized(QuantizedType x) + : quantized_(x), value_(Traits::toFloat(x)) + { + } + + constexpr Quantized &operator=(float x) + { + *this = Quantized(x); return *this; } - Quantized &operator=(QuantizedType x) + constexpr Quantized &operator=(QuantizedType x) { - value_ = Traits::toFloat(x); - quantized_ = x; + *this = Quantized(x); return *this; } - float value() const { return value_; } - QuantizedType quantized() const { return quantized_; } + constexpr float value() const { return value_; } + constexpr QuantizedType quantized() const { return quantized_; } - bool operator==(const Quantized &other) const + constexpr bool operator==(const Quantized &other) const { return quantized_ == other.quantized_; } - bool operator!=(const Quantized &other) const + constexpr bool operator!=(const Quantized &other) const { return !(*this == other); } diff --git a/test/ipa/libipa/quantized.cpp b/test/ipa/libipa/quantized.cpp index f138597f..18655dac 100644 --- a/test/ipa/libipa/quantized.cpp +++ b/test/ipa/libipa/quantized.cpp @@ -25,7 +25,7 @@ struct BrightnessHueTraits { int quantized = std::lround(v * 128.0f); return std::clamp(quantized, -128, 127); } - static float toFloat(QuantizedType v) + static constexpr float toFloat(QuantizedType v) { return static_cast(v) / 128.0f; } @@ -40,7 +40,7 @@ struct ContrastSaturationTraits { int quantized = std::lround(v * 128.0f); return std::clamp(quantized, 0, 255); } - static float toFloat(QuantizedType v) + static constexpr float toFloat(QuantizedType v) { return static_cast(v) / 128.0f; } @@ -138,6 +138,17 @@ protected: return TestFail; } + /* Test constexpr operation */ + { + constexpr BrightnessQ b1(uint8_t(1)); + constexpr BrightnessQ b2(uint8_t(2)); + + static_assert(b1.quantized() == 1); + static_assert(b2.quantized() == 2); + static_assert(b1 != b2); + static_assert(!(b1 == b2)); + } + return TestPass; } };