esp_attr: add flag_attr to support enums used as flags

This commit is contained in:
Michael (XIAO Xufeng) 2019-08-08 17:49:12 +08:00
parent 264ffbeb14
commit d850a0bd1c
3 changed files with 53 additions and 1 deletions

View file

@ -319,3 +319,31 @@ TEST_CASE("can call std::function and bind", "[cxx]")
#endif
/* Tests below are done in the compile time, don't actually get run. */
/* Check whether a enumerator flag can be used in C++ */
template<typename T> __attribute__((unused)) static void test_binary_operators()
{
T flag1 = (T)0;
T flag2 = (T)0;
flag1 = ~flag1;
flag1 = flag1 | flag2;
flag1 = flag1 & flag2;
flag1 = flag1 ^ flag2;
flag1 = flag1 >> 2;
flag1 = flag1 << 2;
flag1 |= flag2;
flag1 &= flag2;
flag1 ^= flag2;
flag1 >>= 2;
flag1 <<= 2;
}
//Add more types here. If any flags cannot pass the build, use FLAG_ATTR in esp_attr.h
#include "hal/timer_types.h"
template void test_binary_operators<timer_intr_t>();

View file

@ -76,6 +76,30 @@
// Forces to not inline function
#define NOINLINE_ATTR __attribute__((noinline))
// This allows using enum as flags in C++
// Format: FLAG_ATTR(flag_enum_t)
#ifdef __cplusplus
#define FLAG_ATTR_IMPL(TYPE, INT_TYPE) \
constexpr TYPE operator~ (TYPE a) { return (TYPE)~(INT_TYPE)a; } \
constexpr TYPE operator| (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a | (INT_TYPE)b); } \
constexpr TYPE operator& (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a & (INT_TYPE)b); } \
constexpr TYPE operator^ (TYPE a, TYPE b) { return (TYPE)((INT_TYPE)a ^ (INT_TYPE)b); } \
constexpr TYPE operator>> (TYPE a, int b) { return (TYPE)((INT_TYPE)a >> b); } \
constexpr TYPE operator<< (TYPE a, int b) { return (TYPE)((INT_TYPE)a << b); } \
TYPE& operator|=(TYPE& a, TYPE b) { a = a | b; return a; } \
TYPE& operator&=(TYPE& a, TYPE b) { a = a & b; return a; } \
TYPE& operator^=(TYPE& a, TYPE b) { a = a ^ b; return a; } \
TYPE& operator>>=(TYPE& a, int b) { a >>= b; return a; } \
TYPE& operator<<=(TYPE& a, int b) { a <<= b; return a; }
#define FLAG_ATTR_U32(TYPE) FLAG_ATTR_IMPL(TYPE, uint32_t)
#define FLAG_ATTR FLAG_ATTR_U32
#else
#define FLAG_ATTR(TYPE)
#endif
// Implementation for a unique custom section
//
// This prevents gcc producing "x causes a section type conflict with y"

View file

@ -40,7 +40,6 @@ typedef enum {
TIMER_START = 1, /*!<Start timer counter*/
} timer_start_t;
/**
* @brief Interrupt types of the timer.
*/
@ -50,6 +49,7 @@ typedef enum {
TIMER_INTR_T1 = BIT(1), /*!< interrupt of timer 1 */
TIMER_INTR_WDT = BIT(2), /*!< interrupt of watchdog */
} timer_intr_t;
FLAG_ATTR(timer_intr_t)
/**
* @brief Behavior of the watchdog if a stage times out.