Differentiate between two equally valued, differently named enum values - c++

Short description:
I have an enum with the same value for 2 different enum constants:
namespace MOTOR
{
using AXES = enum : int
{
X,
Y,
SPECIAL = 0X01,
};
}
so that SPECIAL has the same value as Y (both are 0x01).
I also have a function that does the following:
ErrType CMotorBase::ConvertAxis(MOTOR::AXES& Axis)
{
switch(Axis)
{
case MOTOR::AXES::X: Axis = MOTOR::AXES::SPECIAL;
break;
}
return NO_ERROR;
}
when I try to use the function like this:
MOTOR::AXES Axis = MOTOR::AXES::X;
ErrType Err = ConvertAxis(Axis);
...
other code
...
I expect that when I hit breakpoint on "other code", the value of Axis will be
MOTOR::AXES::SPECIAL on visual studio debugger.
but I get that Axis = MOTOR::AXES::Y; (same value, different constant name)
they both have the same value of course so the "logic" is ok, but another programmer will think something went wrong while debugging.
Any idea how to solve it? I want that both value and name will be correct when returning from the function.

Both MOTOR::AXES::Y and MOTOR::AXES::SPECIAL have the same value, so the compiler (or anybody, for that matter) cannot distinguish them everywhere.
You might want to give MOTOR::AXES::SPECIAL a different value, but give it the same treatment as MOTOR::AXES::Y where applicable. This might add some complexity to your program, but that is the cost for the extra "intelligence" you want.
Edit:
Alternatively (based on your comment), you might want to separate your "normal" (internal) and "special" (external) enums into two separate enums, so they can be distinguished by type. Something like this:
enum AXIS {
X.
Y
};
enum SPECIAL_AXIS {
SPECIAL_X = AXIS::Y,
SPECIAL_Y = /* a value */
};

Related

Using template meta programming (TMP) to make homogeneously storable templated configurants

Sorry for the atrocious title.
The scenario is that I have a configuration system in my program, that needs to able to hold values of all types. These values (configurants) need to be held in a homogenous container.
For example: (this is pseudo-code, I'm not sure how this would actually look)
configurant i(64);
configurant b(true);
configurant f(128.f);
configurant custom(Color(255, 255, 255));
vector<configurant> confs;
confs.emplace_back(i);
confs.emplace_back(b);
confs.emplace_back(f);
confs.emplace_back(custom);
// some form of accessing the vector with proper configurant type here:
// casting?
Like I said, I don't know how this system would look in practice. I know that a statement like
auto color = confs.at(3).rgb();
is generally not possible in C++, but is there something I could do with templated metaprogramming to try and get as close as possible to this solution?
(perhaps the configurants could be mapped with their type? but this would not be a compile time operation)
I'm looking to create a system that is storable homogeneously, immediately accessible (not stored on the heap) and that evaluates the validity of operations at compile time.
Open to any suggestions.
And before the comments come in, I've experimented with std::any/std::any_cast, std::variant, the visitor pattern, and other things of that nature. I'm not looking to use any of those systems.
EDIT To avoid confusion, there are N configurants: it is not a statically sized group of configurants. More configurants would be added by the user of this interface.
EDIT 2 Additional example of desired usage
class foo {
configurant enabled;
configurant bar;
public:
foo() {
this->enabled = configurant(true);
this->bar = configurant(5);
}
void body() {
if(this->enabled) {
std::cout << (this->bar < 100) << "\n";
}
}
// It also needs to be kept in mind that these configurant classes
// cannot be templated (directly, at least), since they need to be stored in
// a homogeneous container.
};
Because of this requirement
"that evaluates the validity of operations at compile time.",
this means that your example
auto color = confs.at(3).rgb();
will only work with the index 3 known at compile time
(why not 2 or 4?).
This index is not very relevant/useful in this situation.
May be should you simply consider a structure providing
the required data with a proper name instead of a
compile-time index?
struct Confs
{
configurant<int> i;
configurant<bool> b;
configurant<float> f;
configurant<Color> custom;
};
...
Confs confs{64, true, 128.f, Color(255, 255, 255)};
auto color = confs.custom.rgb();
Something like this could rely on a compile-time index
but I don't really see the benefit over a named member.
auto confs=std::make_tuple(64, true, 128.0f, Color{255, 255, 255});
auto color = std::get<3>(confs).rgb();

Passing an enum string (not value) to a macro

So I had this query wherein say I have an enum and a struct that look like these,
enum fields {
field_1,
field_2
};
struct my_struct {
int field_1;
int field_2;
};
My specific need is, given the enum with the names of the structure members (field_1, field_2 etc) I should be able to generate a macro which can set the structure member to a given value.
#define my_macro (__a, __field) \
__a.__field = 1;
So is there a way to call my_macro like this:
struct my_struct b;
/* extract members of enum as string literals */
my_macro(b, /*field name from the enum */);
Few other posts detailing usage of boost macros helps me extract the enum members as strings ( How to convert an enum type variable to a string?). Issue is with passing it in the appropriate manner to the macro.
It should work the way it is. Macros are processed before compilation, while the code is still code, and they result in code generation.
Your macro #define my_macro(__a, __field) __a.__field = 1; will cause any entry like my_macro(x, y) to be transformed into x.y = 1;, literally, before its handed to the compiler.
If you do something like my_macro(1+1, "test"), it will generate the code 1+1."test" = 1; and will create a compile error. Thats how simple macros are.
Thats why macro parameters are often enclosed by () to make sure it will work the way it was intented, if you don't do that things like this can happen:
#define div_by_100(a) a / 100
printf("%d\n", div_by_100(1000)); // will print 10
printf("%d\n", div_by_100(500 + 500)); // will print 505
This happens because order of operations is resolved at compile time, after the macros have been resolved.
Notice that, because macros are resolved before compilation, they are not a runtime solution. If this enum value is not explict in the code, macros won't help you at all. You will have to write a routing function that will assign a value to each member of this class/struct depending on what enum value was given. Example:
void route(struct farm* s, enum animals e)
{
switch (e)
{
case cow:
s->cow = 1;
break;
case duck:
s->duck = 1;
break;
case horse:
s->horse = 1;
break;
case goat:
s->goat = 1;
break;
}
}
It depends on the way your mechanism of turning an enum to a string works. Your macro should work as long as that mechanism is still a macro that gets replaced by the preprocessor. That's the issue. Your macro should otherwise work properly.

How to select an action depending on the value of a pair of enums?

I'm implementing a model of a protocol in C++ (cache coherency protocol to be particular, but it does not matter for this question)
The protocol takes two values : a previous_state and a message_type. Both are enums. The protocol should select a unique action for each combination of the two inputs. Some combinations are invalid (an error should be displayed), and a few combinations are to be stalled.
What is a good way to code the above scenario in C++? I can think of : Two nested switch blocks to select an input combination, and call a particular action implemented as a function.
Is there some more elegant and flexible way to code the above scenario? It should ideally be easy to add/remove input combinations from the protocol.
Thanks for any advice. (I'm new to design patterns, and don't know any that fits here)
Let's assume the two enums are 32-bit values. I'd do something like this:
void doit(E1 previous_state, E2 message_type) {
# define COMBINE(_x_, _y_) (static_cast<int64_t>(previous_state) << 32 | message_type)
switch (COMBINE(previous_state, message_type) {
case COMBINE(e1value1, e2value1):
// ...
break;
case COMBINE(e1value4, e2value3):
// ...
break;
// ... more cases ...
default:
// report error
}
}
Don't assume this will generate faster code though--switch statements are often optimized into jump tables, but tricks like this may defeat that. If you're mostly interested in the best possible performance, you'll have to experiment and find out which is best on your system (noting that changing the int64_t to a smaller type and minimizing the shifts in my example may have some effect).
Why not use simple 2 dimensional array? For example
enum Previous_state
{
state_1 = 0,
state_2,
...,
state_n,
PreviousLastValue
}
enum Message_type
{
type_1 = 0,
type_2,
...,
type_n,
TypeLastValue
}
...
Action actions[PreviousLastValue][TypeLastValue] = {NULL};
void SetAction(Previous_state state, Message_type type, Action action)
{
actions[state][type] = action;
}
void RemoveAction(Previous_state state, Message_type type)
{
actions[state][type] = 0;
}
void GetAction(Previous_state state, Message_type type)
{
if(actions[state][type] == 0)
{
//display error
}
return actions[state][type];
}

Visual Studio Compiler is highlighting Static variables differently?

I'm programming in C++ and have a method which uses a static variable. The method isn't working as I think it should; upon investigation, I found that my static variable is being highlighted in red in two places and blue in other places. Below is the code:
int GameModeState::changeJob(int number)
{
static int job = 1; //red
if (number == 1)
{
job = (job+1); //First one is red, second one is blue
return job; //blue
} else {
return job; //blue
}
}
I'm calling this method with other methods, one shown for example:
int GameModeState::getJob()
{
int currentJob = (changeJob(2));
return currentJob;
}
I want a method like getJob() to simply return the current value of job, while another method, when calling changeJob(number) is changeJob(1), to increment job's value by one. (Hence the if/else statement in changeJob(number)).
Since the job variables are highlighted differently, I'm thinking the compiler is saying that it views the two separately somehow? I'm getting stuck with job being some even value.
EDIT I also have Awesomium... I believe that is the only addition to the compiler, but I'm not completely sure.
MOAR EDIT In another class, I have a method which should determine the current job's number and do something based on if the number is even or odd (since right now there are only two jobs)
void ZoneMovementState::_changeZone(const String& message, const Awesomium::JSValue& input, Awesomium::JSValue& output)
{
//Awesomium::JSValue::Object object = input.getObject();
//String zoneFilename = Convert::toString(object[L"zoneFilename"].toString());
// If the number from getJob is even, the player is currently a geologist
if (GameModeState::getJob()%2 == 0)
{
ZoneParser::getSingleton().load("../media/zones/geology_zone.xml", false);
} else {
ZoneParser::getSingleton().load("../media/zones/farm_zone.xml", false);
}
transitionHandler->go();
}
Ignore the two commented out lines; they deal with JS, which I'm not working on for now.
In the program, I can access the farm_zone until I increment job's value using the below method in GameModeState:
void GameModeState::_openNotebook(const String& message, const Awesomium::JSValue& input, Awesomium::JSValue& output)
{
mNotebookTransition->go();
static int currentJob = changeJob(1);
}
.... So I figured out my problem. While going through the code to show you guys, I realized that the static for currentJob was probably unneeded... once I removed it, my code works as it should now.
Thanks for the help guys!
Part of the problem here is you're using a static local for what very likely should just be a member variable. A static local maintains it's value across all calls to a function in all threads in a process. It's much more likely that you want it to persist for all calls to changeJob in a particular GameModeState instance (else why make it a member functon to begin with?).
To do this you'll need to define a member variable on GameModeState initialize it in the constructor and then access it in the method. For example
class GameModeState {
int job;
GameModeState() : job(1) {}
int changeJob(int number);
};
int GameModeState::changeJob(int number) {
if (number == 1) {
job = (job+1);
return job;
} else {
return job;
}
}
Note: I'm not entirely sure why you're seeing the color's your are seeing. Visual Studio by default won't color member variables a particular color in C++ so it's very likely another add-in you are using.
Nah, highlighting doesn't mean anything. That is, the editor doesn't call the compiler before deciding how/what/when to highlight. So that is not your problem. Sorry 'bout that :-)
You can prove this to yourself by going to Tools->Options->TextEditor and noticing that you can change the highlighting by choosing a different text-editing model.

Defining names in place of "true" and "false" for bool type

I am wanting to use a bool to switch back and forth between loading X and loading Y from a file. I don't want to use "true" and "false", because it doesn't make the code clear. I would rather use something like LOAD_X or LOAD_Y... Is the following code the way to do it? Or is there a better way?
#define LOAD_X true
#define LOAD_Y false
Edit: Okay, so it seems an enum is the way to go... but what should the naming scheme be? Like all caps, or lower case for the first word, uppercase for following words, etc.
You can use an enum:
enum LoadType {
LoadY,
LoadX
};
Or, you might prefer to constrain the scope of the enumerators by using a namespace:
namespace LoadType {
enum Type {
LoadY,
LoadX
};
};
The advantage of using an enum is that if your function takes a LoadType (or a LoadType::Type in the second example), you can't pass it any arbitrary integer or bool; you can only pass it one of the enumerators (or something explicitly cast to the enumeration type, which is really easy to spot in a code review).
I would use an enum instead. Just because there are two choices, doesn't mean the type should be bool
enum load_type { loadX, loadY };
I guess that works, if you'll only ever have two options. I'd be tempted to go for an enum:
enum LOADMODE {
LOAD_X,
LOAD_Y
};
At the very least, prefer constants over macros:
const bool LOAD_X = true;
const bool LOAD_Y = false;
They will abide by scope rules and won't silently break stuff without you realising when names conflict.
i think Load X IS LOAD.
Lowercase font look more friendly, you can choose bright colors.
enum LoadType {
LoadY,
LoadX
it is all right.