Having 2 strange warnings during auto generation enum + string items...
EnumItems.h (2 times included header to build enum and string array + possibility to have multiple enums and single boilerplate)
#ifdef ENUM_ONCE_INCLUDED
#undef ENUM_NUMBERED
#undef ENUM_ITEM
#define ENUM_NUMBERED(i, n) *(new TemporaryItem( #i, n ))
#define ENUM_ITEM(i) *(new TemporaryItem( #i ))
#undef ENUM_ONCE_INCLUDED
#else
#define ENUM_NUMBERED(i, n) i = n
#define ENUM_ITEM(i) i
#define ENUM_ONCE_INCLUDED
#endif // ENUM_ONCE_INCLUDED
#ifndef ENUM_ITEMS
#error Undefined ENUM_ITEMS # !
#elif ENUM_ITEMS == 1
{
ENUM_NUMBERED(E_LOREM, 0),
ENUM_NUMBERED(E_IPSUM, 1),
ENUM_ITEM(E_DOLOR),
ENUM_NUMBERED(E_SIT, 20)
}
#endif // ENUM_ITEMS
#ifdef ENUM_ONCE_INCLUDED
;
#if defined(__ICCARM__) && defined(DEBUG)
#pragma diag_suppress=Pa105
#endif
#else
,_once = TemporaryItem::PostProcess(states, sizeof(states));static_cast<void>(_once);
#if defined(__ICCARM__) && defined(DEBUG)
#pragma diag_default=Pa105
#endif
#endif // ENUM_ONCE_INCLUDED
*.cpp(s)
#define ENUM_ITEMS 1
namespace
{
enum second_t
#include "EnumItems.h" // standard enum items - 1st include
// F12 jumps to particular item in header
}
static const char *states[21] =
#include "EnumItems.h" // struct TemporaryItem* - 2nd include
Sigle expected a declaration
with additional brackets in EnumItems.h (for multiple enums)
- or lot of this declaration has no storage
without in Visual Studio Error List only
and Remark[Pa105]: this directive is inside an active namespace scope ## in IAR, but this is true in most cases unfortunately.
Is it possible to remove them somehow (except supress in IAR) ?
Or is there any similar and better way how to write enum + string counterparts without need to compare and synchronize their separate instances again and again ?
Mind final target is old-fashioned IAR EC++ compiler.
It is also unlikely impossible to use names for ENUM_ITEMS definitions without hard to read breakneck tricks.
Polymorphic struct/class used to check & store preprocessor generated definitions and rewrite them by string arrays.
struct TemporaryItem {
const char *name; int pos;
TemporaryItem(const char *n) { name = n; pos = INT_MIN; /* auto-generated */ }
TemporaryItem(const char *n, int p) { name = n; pos = p; }
static char PostProcess(const char **process, size_t size) {
size /= sizeof(char *); // array size
TemporaryItem **source = new TemporaryItem*[size];
memcpy(source, process, sizeof(TemporaryItem*) * size); // copy definitions
memset(process, 0, sizeof(TemporaryItem *) * size); // reset final range
int stLogicNumber = source[0]->pos;
if (stLogicNumber == INT_MIN) stLogicNumber = 0; // no logic shift
int finalPos = 0; // default item destination
for (size_t i = 0; i < size; i++) {
TemporaryItem *current = source[i];
if (current == NULL) break; // no more defined
int defPos = current->pos;
if (defPos == INT_MIN) defPos = finalPos; // auto-generated
else if (stLogicNumber < 0)
defPos -= stLogicNumber; // move forward by 1st logic value
if (defPos >= finalPos && static_cast<unsigned>(defPos) < size)
finalPos = defPos; // set valid destination
else __debugbreak(); // block backward && out of bounds
process[finalPos] = current->name;
delete current; // remove processed definition
finalPos++;
}
delete[] source; // remove temp array
return 0;
}
operator const char *() // collect TemporaryItem-s definitions in destination array
{ return reinterpret_cast<const char *>(this); }
};
1st version having nice get/set operators also here easily map c++ enums to strings, but enum items are useless mixed by preprocessor to single line there.