diff --git a/src/unittest/harness.hpp b/src/unittest/harness.hpp index 94feea70a..c8a58ca6d 100644 --- a/src/unittest/harness.hpp +++ b/src/unittest/harness.hpp @@ -262,7 +262,7 @@ namespace unittest } #define TEST_ASSERT_TRUE(expr) \ - TEST_RETURN__(::unittest::checkExpression((expr), __LINE__)) + TEST_RETURN__(::unittest::checkExpression(static_cast(expr), __LINE__)) #define TEST_ASSERT_FALSE(expr) \ TEST_RETURN__(::unittest::checkExpression(!static_cast(expr), __LINE__)) diff --git a/src/xpcc/architecture/interface/register.hpp b/src/xpcc/architecture/interface/register.hpp index f6def56be..ec1eb28ce 100644 --- a/src/xpcc/architecture/interface/register.hpp +++ b/src/xpcc/architecture/interface/register.hpp @@ -229,13 +229,16 @@ struct Register : value(0) {} /// @{ - // The safe-bool idiom is not required here, since we are not - // dealing with complex objects, but with one integral value. - // So there is not need for it. - /* explicit */ - - /// Returns `true` if `value` is non-zero - constexpr operator bool() const + /** + * Returns `true` if `value` is non-zero + * + * The compiler will allow implicit conversions to bool in the following contexts: + * - conditions of if, while, for, do-while statements + * - logical operators (&&, ||) + * - negation (operator !) + * - static_assert + */ + explicit constexpr operator bool() const { return bool(value); } /// Returns `true` if `value` is zero @@ -252,28 +255,6 @@ struct Register /// This class is meant to be subclassed constexpr Register(UnderlyingType value) : value(value) {} - -#ifndef __DOXYGEN__ -public: - // do NOT cast to anything else - /// all other conversion operators are deleted and must be explicitly implemented - constexpr operator char16_t() const = delete; - constexpr operator char32_t() const = delete; - constexpr operator wchar_t() const = delete; - constexpr operator signed char() const = delete; - constexpr operator unsigned char() const = delete; - constexpr operator signed short int() const = delete; - constexpr operator unsigned short int() const = delete; - constexpr operator signed int() const = delete; - constexpr operator unsigned int() const = delete; - constexpr operator signed long int() const = delete; - constexpr operator unsigned long int() const = delete; - constexpr operator signed long long int() const = delete; - constexpr operator unsigned long long int() const = delete; - constexpr operator float() const = delete; - constexpr operator double() const = delete; - constexpr operator long double() const = delete; -#endif }; /// @ingroup register @@ -547,10 +528,10 @@ struct Flags : public ::xpcc::FlagsOperators /// Returns `true` if bit is set constexpr bool all(Enum const &flag) const - { return (*this & flag); } + { return bool(*this & flag); } /// Returns `true` if bit is set constexpr bool any(Enum const &flag) const - { return (*this & flag); } + { return bool(*this & flag); } /// Returns `true` if bit is **not** set constexpr bool none(Enum const &flag) const { return !(*this & flag); } @@ -563,7 +544,7 @@ struct Flags : public ::xpcc::FlagsOperators { return (*this & o) == o; } /// Returns `true` if **any** of the passed bits are set constexpr bool any(Flags const &o) const - { return *this & o; } + { return bool(*this & o); } /// Returns `true` if **none** of the passed bits are set constexpr bool none(Flags const &o) const { return (*this & o).value == 0; } @@ -598,9 +579,10 @@ struct FlagsGroup : public FlagsGroup // enum class constexpr FlagsGroup(typename T::EnumType value) : FlagsGroup(typename T::UnderlyingType(value)) {} - // Flags class - constexpr FlagsGroup(T value) + /// Flags operators and Flags constructor + constexpr FlagsGroup(::xpcc::FlagsOperators value) : FlagsGroup(value.value) {} + } xpcc_packed; /// @endcond @@ -656,9 +638,10 @@ struct FlagsGroup : public Register /// enum type constructor constexpr FlagsGroup(typename T::EnumType value) : Register(typename T::UnderlyingType(value)) {} - /// Flags type constructor - constexpr FlagsGroup(T value) + /// Flags operators and Flags constructor + constexpr FlagsGroup(::xpcc::FlagsOperators value) : Register(value.value) {} + } xpcc_packed; /** diff --git a/src/xpcc/architecture/interface/test/register_test.cpp b/src/xpcc/architecture/interface/test/register_test.cpp index 283ad7206..c28959e2c 100644 --- a/src/xpcc/architecture/interface/test/register_test.cpp +++ b/src/xpcc/architecture/interface/test/register_test.cpp @@ -49,6 +49,11 @@ RegisterTest::testAssignments() a0 = translateCommonArgument(c3); TEST_ASSERT_EQUALS(a0, 0x42); + // flags operators to common struct + v0 = Test::A; + c0 = v0 | Test::C; + TEST_ASSERT_EQUALS(c0.value, 0b101); + // to register // these are not possible! diff --git a/src/xpcc/architecture/platform/driver/adc/stm32f3/adc_impl.hpp.in b/src/xpcc/architecture/platform/driver/adc/stm32f3/adc_impl.hpp.in index f9d274edc..42954bea3 100644 --- a/src/xpcc/architecture/platform/driver/adc/stm32f3/adc_impl.hpp.in +++ b/src/xpcc/architecture/platform/driver/adc/stm32f3/adc_impl.hpp.in @@ -87,7 +87,7 @@ xpcc::stm32::Adc{{ id }}::setPrescaler(const Prescaler pre) bool xpcc::stm32::Adc{{ id }}::isReady() { - return (getInterruptFlags() & InterruptFlag::Ready); + return static_cast(getInterruptFlags() & InterruptFlag::Ready); } void @@ -162,7 +162,7 @@ xpcc::stm32::Adc{{ id }}::startConversion(void) bool xpcc::stm32::Adc{{ id }}::isConversionFinished(void) { - return (getInterruptFlags() & InterruptFlag::EndOfSampling); + return static_cast(getInterruptFlags() & InterruptFlag::EndOfSampling); } // ---------------------------------------------------------------------------- diff --git a/src/xpcc/architecture/platform/driver/spi/stm32/spi_hal_impl.hpp.in b/src/xpcc/architecture/platform/driver/spi/stm32/spi_hal_impl.hpp.in index a7619f675..6f9a2af89 100644 --- a/src/xpcc/architecture/platform/driver/spi/stm32/spi_hal_impl.hpp.in +++ b/src/xpcc/architecture/platform/driver/spi/stm32/spi_hal_impl.hpp.in @@ -111,13 +111,13 @@ xpcc::stm32::SpiHal{{ id }}::setMasterSelection(MasterSelection masterSelection) inline bool xpcc::stm32::SpiHal{{ id }}::isReceiveRegisterNotEmpty() { - return getInterruptFlags() & InterruptFlag::RxBufferNotEmpty; + return static_cast(getInterruptFlags() & InterruptFlag::RxBufferNotEmpty); } inline bool xpcc::stm32::SpiHal{{ id }}::isTransmitRegisterEmpty() { - return getInterruptFlags() & InterruptFlag::TxBufferEmpty; + return static_cast(getInterruptFlags() & InterruptFlag::TxBufferEmpty); } void inline diff --git a/src/xpcc/driver/temperature/tmp102_impl.hpp b/src/xpcc/driver/temperature/tmp102_impl.hpp index 6015c32ca..12a0e25a6 100644 --- a/src/xpcc/driver/temperature/tmp102_impl.hpp +++ b/src/xpcc/driver/temperature/tmp102_impl.hpp @@ -141,7 +141,7 @@ xpcc::Tmp102::readComparatorMode(bool &result) if (RF_CALL( this->runTransaction() )) { reinterpret_cast(this->config_msb) = Config1_t(this->buffer[0]) & ~Resolution_t::mask(); - result = Config2_t(this->buffer[1]) & Config2::Alert; + result = static_cast(Config2_t(this->buffer[1]) & Config2::Alert); config_lsb = Config2_t(this->buffer[1]) & ~Config2::Alert; RF_RETURN(true); }