148

I just want to flip a boolean based on what it already is. If it's true - make it false. If it's false - make it true.

Here is my code excerpt:

switch(wParam) {

case VK_F11:
  if (flipVal == true) {
     flipVal = false;
  } else {
    flipVal = true;
  }
break;

case VK_F12:
  if (otherVal == true) {
     otherValVal = false;
  } else {
    otherVal = true;
  }
break;

default:
break;
}
sharptooth
  • 167,383
  • 100
  • 513
  • 979
John T
  • 23,735
  • 11
  • 56
  • 82

13 Answers13

409

You can flip a value like so:

myVal = !myVal;

so your code would shorten down to:

switch(wParam) {
    case VK_F11:
    flipVal = !flipVal;
    break;

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}
Dana
  • 32,083
  • 17
  • 62
  • 73
John T
  • 23,735
  • 11
  • 56
  • 82
98

Clearly you need a factory pattern!

KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();


class VK_F11 extends KeyObj {
   boolean val;
   public void doStuff() {
      val = !val;
   }
}

class VK_F12 extends KeyObj {
   boolean val;
   public void doStuff() {
      val = !val;
   }
}

class KeyFactory {
   public KeyObj getKeyObj(int param) {
      switch(param) {
         case VK_F11:
            return new VK_F11();
         case VK_F12:
            return new VK_F12();
      }
      throw new KeyNotFoundException("Key " + param + " was not found!");
   }
}

:D

</sarcasm>
Drew
  • 15,158
  • 17
  • 68
  • 77
  • 16
    We could probably add in the singleton pattern for the factory too. – Drew Mar 04 '09 at 21:56
  • 1
    @Orm Cause you are an _ORM_? :) – mlvljr Mar 19 '10 at 16:37
  • 7
    Note the subtle recommendation to switch to Java! – Mechanical snail Dec 19 '12 at 16:38
  • 1
    Well ... i think we need another major release of C++ for this one, may be C++/51 – 0x6900 Sep 15 '15 at 12:40
  • Hey guys! I think your approach is not reentrant. You need atomic_bool at least, better a mutex or an event queue. Further, we need an observer-pattern to monitor the state of val. – Marco Freudenberger Oct 20 '17 at 09:14
  • 3
    I'm not sure if this is amazing or horrible... Probably amazing. A note to beginners: Drew is, in fact, being sarcastic. You should go for a solution that is as simple as possible (but no simpler)... although the factory pattern is very powerful, and you should learn it. – Casey May 03 '20 at 19:27
54

Easiest solution that I found:

x ^= true;
xamid
  • 440
  • 11
  • 25
  • 29
    `x = !x;` is not only shorter, but also more legible. – Rodrigo Oct 04 '17 at 00:00
  • 32
    Note that e.g. `longVariableName ^= true;` is clearly shorter than `longVariableName = !longVariableName;` And every programmer should know XOR. – xamid Oct 05 '17 at 16:15
  • `a ^= b` means `a = a ^ b`, where `^` means XOR. The notation `a °= b` for `a = a ° b` for any operator `°` is very common amongst C/C++/C# syntax. – xamid Oct 06 '17 at 17:49
  • Yes, I know that. It's just that I'm using R for so long that I was thinking about ^ as power function. So ^= would need to have an entirely new meaning... Lol – Rodrigo Oct 06 '17 at 18:04
  • 8
    Anecdotal, but I recently came across the line `gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;` Of course, the cleanest thing to do is to expand it to multiple lines and use temporary variables to store the objects, but `gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1` is much more readable, less error prone, and fewer characters than the original code. – Vortico Oct 31 '17 at 10:40
  • 3
    Additionally, less duplication means less chance for forgetting to update BOTH sides of the equation during rapid development changes / long days/nights of coding. – Katastic Voyage Nov 14 '17 at 01:06
  • 1
    @Vortico, anedoctal but it was precisely to avoid a line like that I came here today. I suppose you can say that there is also obfuscation by verbosity. – migle Apr 29 '20 at 23:08
  • IMMO this solution is preferable to `x = !x` also because it prevents copy-paste errors, you do not take any risk of involving another variable by mispelling the right operand (imagine 2 similar name variables, both have a function flipping it, the second function is made copy-pasting the first, and you only remember to change the left operand) – Antonio Sep 14 '21 at 10:28
46

If you know the values are 0 or 1, you could do flipval ^= 1.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • 1
    Why use a bitwise operator for a logical operation? Smells of needless obfuscation to me. – Mark Pim Mar 04 '09 at 17:18
  • 6
    @Mark: Sorry. Guess I'm old-fashioned. But it does help if your L-value expression is really long, so you don't have to repeat it. Also, you could say flipval ^= TRUE. Is that better? – Mike Dunlavey Mar 04 '09 at 17:52
  • @Mark - see my posting - because sometimes your logical values are stored in bits. Not everyone wants to waste a whole 8 bits (or more) just for a boolean. – Alnitak Mar 06 '09 at 09:17
  • 6
    @Alnitak: You're right in some circumstances. I have seen some people pack bits together to "save space" and act as if the instructions to access them didn't take any space. – Mike Dunlavey Mar 06 '09 at 12:39
  • I'm confused as to how this would work... If my value is 0 (false) and I say `myVal ^= 1` wouldn't that be `myVal = 0^1` which is still `0` and if my value is 1 (true) and I say `myVal ^= 1` wouldn't that be `myVal = 1^1` which is still `1`? How does this flip the BOOL value? – Albert Renshaw Nov 11 '13 at 19:53
  • 2
    @Albert: `^` is the _exclusive-or_ operator. `0^1` is `1`, and `1^1` is `0`. It's the same as adding if you ignore the carry bit. Or you can think of it as - if either bit is 1, the result is the inverse of the other bit. Or you can think of it as asking the question: Are these two bits different? – Mike Dunlavey Nov 12 '13 at 01:33
  • @MikeDunlavey that last way of thinking of it made sense! Are 0 and 1 different? "1" (yes), they are! are 1 and 1 different? "0" (no), the aren't! – Albert Renshaw Nov 12 '13 at 03:40
  • 1
    @MikeDunlavey if you're on a device with 4M of Flash for code space, and 3K of SRAM for data space then that is a justified way of acting! – M.M Dec 16 '14 at 04:39
  • I vote for this one. Right now, I'm writing a test case, I need to flip a bool and sometimes expressions are really long. Obfuscation is bad, true, but the amount of text on the screen can also be obfuscating, math is easier. – migle Apr 29 '20 at 23:06
  • Also, on embedded systems, 5 lines of comments to explain a line of black magic is sometimes worth it. :) – Stuggi Mar 30 '21 at 20:38
17

Just for information - if instead of an integer your required field is a single bit within a larger type, use the 'xor' operator instead:

int flags;

int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;

/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;

/* I want to set 'flag_b' */
flags |= flag_b;

/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;

/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;
Boiethios
  • 38,438
  • 19
  • 134
  • 183
Alnitak
  • 334,560
  • 70
  • 407
  • 495
12

Just because my favorite odd ball way to toggle a bool is not listed...

bool x = true;
x = x == false;

works too. :)

(yes the x = !x; is clearer and easier to read)

Rozwel
  • 1,990
  • 2
  • 20
  • 30
10

This seems to be a free-for-all ... Heh. Here's another varation, which I guess is more in the category "clever" than something I'd recommend for production code:

flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);

I guess it's advantages are:

  • Very terse
  • Does not require branching

And a just as obvious disadvantage is

  • Very terse

This is close to @korona's solution using ?: but taken one (small) step further.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 3
    By order of operations, I think you can omit the parenthesis for even more terse. :O – Drew Sep 29 '11 at 14:50
9

The codegolf'ish solution would be more like:

flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
korona
  • 2,308
  • 1
  • 22
  • 37
3
flipVal ^= 1;

same goes for

otherVal
evandrix
  • 6,041
  • 4
  • 27
  • 38
2

I prefer John T's solution, but if you want to go all code-golfy, your statement logically reduces to this:

//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;

//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;
JosephStyons
  • 57,317
  • 63
  • 160
  • 234
1

Clearly you need a flexible solution that can support types masquerading as boolean. The following allows for that:

template<typename T>    bool Flip(const T& t);

You can then specialize this for different types that might pretend to be boolean. For example:

template<>  bool Flip<bool>(const bool& b)  { return !b; }
template<>  bool Flip<int>(const int& i)    { return !(i == 0); }

An example of using this construct:

if(Flip(false))  { printf("flipped false\n"); }
if(!Flip(true))  { printf("flipped true\n"); }

if(Flip(0))  { printf("flipped 0\n"); }
if(!Flip(1)) { printf("flipped 1\n"); }

No, I'm not serious.

dma
  • 1,758
  • 10
  • 25
0

For integers with values of 0 and 1 you can try:

value = abs(value - 1);

MWE in C:

#include <stdio.h>
#include <stdlib.h>
int main()
{
        printf("Hello, World!\n");
        int value = 0;
        int i;
        for (i=0; i<10; i++)
        {
                value = abs(value -1);
                printf("%d\n", value);
        }
        return 0;
}
Artur
  • 407
  • 2
  • 8
0

Just because I like to question code. I propose that you can also make use of the ternary by doing something like this:

Example:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
Jon
  • 2,456
  • 21
  • 28