AwesomeBoolean

The long awaited AwesomeBoolean ( http://uncyclopedia.wikia.com/wiki/Workaround_Oriented_Programming ) has finally been implemented in C++! Get your copy now, free to use for personal and commercial purposes!
(This is the result of me having nothing to do.)

boo.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#ifndef _BOO_H // Read: BOO HA (ha, ha, ha.. etc)
#define _BOO_H

#include <iostream>

enum aBool {FALSE = 0, TRUE = 1, MAYBE = 2, NO_IDEA = 3};

class boo
{
    aBool state;
public:
    boo(aBool);
    boo(int);
    boo(bool);

    friend bool operator==(const boo&, const boo&);             // Equal
    friend bool operator!=(const boo&, const boo&);             // Inequal
    friend boo operator&&(const boo&, const boo&);              // And
    friend boo operator||(const boo&, const boo&);              // Or
    friend boo operator!(const boo&);                           // Not
    friend boo operator&(const boo&, const boo&);                  // Alt-and
    friend boo operator|(const boo&, const boo&);                  // Alt-or
    friend boo operator~(const boo&);                               // Alt-not
    friend boo operator^(const boo&, const boo&);               // Exclusive or
    boo& operator=(const boo&);                                 // Set
    friend boo& operator&=(boo&, const boo&);                   // And-set
    friend boo& operator|=(boo&, const boo&);                   // Or-set
    friend std::ostream& operator<<(std::ostream&,const boo&);  // Printing
    operator int();                                             // Conversion
};

#endif 


boo.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "boo.h"

boo::boo(aBool b = NO_IDEA) : state(b) {}
boo::boo(int i) {state = static_cast<aBool>(i);}
boo::boo(bool b) {state = static_cast<aBool>(b);}

bool operator==(const boo& a, const boo& b)
{
    return (a.state == b.state);
}
bool operator!=(const boo& a, const boo& b)
{
    return (a.state != b.state);
}

boo operator&&(const boo& a, const boo& b)
{
    if ((a.state == 0) || (b.state == 0)) return FALSE;
    if (a.state == TRUE) return b;
    if (b.state == TRUE) return a;
    if (a.state == NO_IDEA) return b;
    if (b.state == NO_IDEA) return a;
    return MAYBE;
}

boo operator||(const boo& a, const boo& b)
{
    if (a.state == FALSE) return b;
    if (b.state == FALSE) return a;
    if ((a.state == TRUE) || (b.state == TRUE)) return TRUE;
    if ((a.state == MAYBE) || (b.state == MAYBE)) return MAYBE;
    return NO_IDEA;
}

boo operator!(const boo& a)
{
    if (a.state < MAYBE) return !a.state;
    return a.state;
}

boo operator&(const boo& a, const boo& b) {return (a && b);}

boo operator|(const boo& a, const boo& b) {return (a || b);}

boo operator~(const boo& a) {return (!a);}

boo operator^(const boo& a, const boo& b)
{
    if ((a.state == NO_IDEA) || (b.state == NO_IDEA)) return NO_IDEA;
    if ((a.state == MAYBE) || (b.state == MAYBE)) return MAYBE;
    return (a ^ b);
}

boo& boo::operator=(const boo& b)
{
    state = b.state;
    return *this;
}

boo& operator&=(boo& a, const boo& b)
{
    a = a || b;
    return a;
}

boo& operator|=(boo& a, const boo& b)
{
    a = a && b;
    return a;
}

std::ostream& operator<<(std::ostream& os, const boo& b)
{
    if (b.state == FALSE) os << "false";
    else if (b.state == TRUE) os << "true";
    else if (b.state == MAYBE) os << "maybe";
    else os << "no idea";
    return os;
}

boo::operator int()
{
    return state;
}


PS: I have never really done any libraries and due to the current state of circumstances, I was unable to check whether the boo.h and boo.cpp work in this state. They were however tested in a single file, if I did anything wrong, please tell.

Definitions (as a set of rules, not as a truth table. The first rule takes precedence over the rest, the second over the third and after, etc.)
And
If a or b equals false: false.
If a or b equals true: other operand.
If a or b equals no_idea: other operand.
Else: maybe.
Or
If a or b equals false: other operand.
If a or b equals true: true.
If a or b equals maybe: maybe.
Else: no_idea.
Xor
If a or b equals no_idea: no_idea.
If a or b equals maybe: maybe.
Else: a ^ b.
Not
If a is true or false: !a.
Else: a.


EDIT:
Added header guards.

EDIT:
Added int-conversion and made state private. Also updated a wrong implementation on AND.
Last edited on
It's about damn time someone addressed this issue, lets hope AwesomeBoolean appears in c++ 0x
Exactly my thoughts! I was sick and tired of the lack of extended boolean operations. I should add to-boolean conversions with positive and negative case assumptions, if you convert it to boolean with ++ no_idea and maybe turn true, if you convert it to boolean with -- no_idea and maybe turn false.
Come on guys, you can't forget BOTH. Honestly, it's like you don't know boolean!
I actually implemented quantum-bits (qbits) one time, it worked, but the same way wouldn't work for an int, so I scrapped the entire project after noticing that. It would be a pain to implement in here, but possible. (Not going to do it, though. :P)

EDIT:
As a side note, both is more or less implemented as no_idea.
Last edited on
Edited the code to work like it should. Added a set of rules that define the operators. Conversion to an int is now possible, too (with either int(), (int) or ..._cast<int>). For this conversion: FALSE == 0. TRUE == 1. MAYBE == 2. NO_IDEA == 3.
While fun, here is some useful, real-world stuff:

Boost tribool http://www.boost.org/doc/libs/1_45_0/doc/html/tribool.html

Maybe http://www.google.com/search?q=c%2B%2B+maybe+monad
Another random thing I created when bored ( I got this idea when "solving" a different topic: http://www.cplusplus.com/forum/general/33632/ ):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* Wrap Around Number Oriented Paradigm/Programming
**
** Include list:
**   - iostream
**   - string
**   - vector
**
** Global variable names:
**   std::string num;
**      Contains the original string.
**
**   std::vector<unsigned> wraparoundnumber;
**      Contains the string when converted to a vector of unsigned integers.
**
**   std::vector<void(*)(void)> functions;
**      Contains the function pointers of the functions that correspond to indices in wraparoundnumber.
**
**   unsigned in;
**      The index value of the function that is currently being executed.
**
**   bool go;
**      A boolean value that determines whether the program should terminate after the current function. (FALSE = stop, TRUE = continue)
*/

#ifndef WANOP_H_INCLUDED
#define WANOP_H_INCLUDED

#include <iostream>
#include <string>
#include <vector>

#define START_ADD_FUNCTIONS void function_add(void){

#define END_ADD_FUNCTIONS \
    }\
    int main()\
    {\
        function_add();\
        if(!stringToInt(num,wraparoundnumber)){std::cout<<"Input string does not convert to an int.\n";return 1;}\
        if(!isValidWrapper(wraparoundnumber)) {std::cout<<"Number is not a wraparound number.\n";return 1;}\
        if(functions.size()!=wraparoundnumber.size()){std::cout<<"Function amount does not equal number amount.\n";return 1;}\
        executeWrapperFunctions(functions,wraparoundnumber);\
        std::cout << "Press ENTER to continue...";\
        std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );\
        return 0;\
    }\
    \
    bool stringToInt(const std::string& s, std::vector<unsigned>& v)\
    {\
        if(!s.size())return false;\
        for(unsigned u=0;u<s.size();u++)if(s[u]<'0'||s[u]>'9')return false;\
        for(unsigned u=0;u<s.size();u++)v.push_back(s[u]-'0');return true;\
    }\
    \
    bool isValidWrapper(std::vector<unsigned> a)\
    {\
        unsigned i(0);\
        unsigned u(a.size());\
        while(u>0)\
        {\
            if(a[i]==-1)return false;\
            unsigned b(a[i]);\
            a[i]=-1;\
            i+=b;\
            i%=a.size();\
            u--;\
        }\
        return(i==0);\
    }\
    \
    void executeWrapperFunctions(const std::vector<void(*)(void)>& v, const std::vector<unsigned>& u)\
    {\
        while(go)\
        {\
            (*v[in])();\
            in+=u[in];\
            in%=u.size();\
        }\
    }

#define PROGRAM(x)\
    unsigned in(0);\
    std::string num(x);\
    bool go(true);\
    std::vector<void(*)(void)> functions;\
    std::vector<unsigned> wraparoundnumber;\
    bool stringToInt(const std::string&,std::vector<unsigned>&);\
    bool isValidWrapper(std::vector<unsigned>);\
    void executeWrapperFunctions(const std::vector<void(*)(void)>&,const std::vector<unsigned>&)

#define ADD(x) functions.push_back(x)

#endif // WANOP_H_INCLUDED 


WANOP stands for Wrap-Around Number Oriented Programming / Paradigm.

You feed the program a potential wrap around number and some functions (amount of functions equals the "length" of the number). Now the program will execute functions based on the current index (position in the number) from the given list of functions. A very simplistic example of a WANOP-C++ program would be:

1
2
3
4
5
6
7
8
9
10
11
12
#include "WANOP.h"

PROGRAM("3126");

void bla(void) {std::cout << in << " : "<< wraparoundnumber[in] << std::endl;}

START_ADD_FUNCTIONS
ADD(bla);
ADD(bla);
ADD(bla);
ADD(bla);
END_ADD_FUNCTIONS


Which would add bla four times (binding it to every single digit of the wrap around number) and execute it every time (because they are bound to all digits).

Another WANOP program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "WANOP.h"

PROGRAM("3126");

signed a(0);
signed b(0);

void first(void) {std::cin >> a;}
void second(void) {std::cout << "----\n";}
void third(void) {std::cout << (a+b) << "\n\n";}
void fourth(void) {std::cin >> b;}

START_ADD_FUNCTIONS
ADD(first);
ADD(second);
ADD(third);
ADD(fourth);
END_ADD_FUNCTIONS

Which would make you input two integers and count them together, printing the outcome.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "WANOP.h"

PROGRAM("24133625115");

std::string message("");

void h() {message="H";}
void e() {message+="e";}
void l() {message+="l";}
void o() {message+="o";}
void _() {message+=" ";}
void w() {message+="w";}
void r() {message+="r";}
void d() {message+="ld\n\n";}
void a() {std::cout << message; go = 0;}

START_ADD_FUNCTIONS
ADD(h);ADD(d);ADD(e);ADD(l);ADD(o);ADD(a);ADD(l);ADD(r);ADD(o);ADD(_);ADD(w);
END_ADD_FUNCTIONS

Hello world.

EDIT:
Bohohoho, programming hell, here we come.
Last edited on
I made a new WANOP version, WANOP2. It allows for a cleaner syntax:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "WANOPV2.h"
Program("522");
case 0:
cout << "5";
break;

case 1:
cout << "2" << endl;
go=false;
break;

case 2:
cout << "2";
break;

End;


Here is the full header file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/* Wrap Around Number Oriented Paradigm/Programming
**
** Include list:
**   - iostream
**   - string
**   - vector
**
** Global variable names:
**   const std::string num;
**      Contains the original string.
**
**   std::vector<unsigned> wraparoundnumber;
**      Contains the string when converted to a vector of unsigned integers.
**
**   unsigned in;
**      The index value of the function that is currently being executed.
**
**   bool go;
**      A boolean value that determines whether the program should terminate after the current function. (FALSE = stop, TRUE = continue)
*/
#ifndef WANOPV2_H_INCLUDED
#define WANOPV2_H_INCLUDED

#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define Program(x) \
unsigned in(0);const string num(x);bool go(true);vector<unsigned> wraparoundnumber;\
bool stringToInt(const string& s,vector<unsigned>& v){if(!s.size())return false;for(unsigned u=0;u<s.size();u++)if(s[u]<'0'||s[u]>'9')return false;for(unsigned u=0;u<s.size();u++)v.push_back(s[u]-'0');return true;}\
bool isValidWrapper(vector<unsigned> a){unsigned i(0);unsigned u(a.size());while(u>0){if(a[i]==-1)return false;unsigned b(a[i]);a[i]=-1;i+=b;i%=a.size();u--;}return(i==0);}\
void executeWrapperFunctions(const vector<unsigned>& u){while(go){switch(in){0

#define End\
}in+=u[in];in%=u.size();}}\
int main(){\
if(!stringToInt(num,wraparoundnumber)){cout<<"Input string does not convert to an int.\n";return 1;}\
if(!isValidWrapper(wraparoundnumber)){cout<<"Number is not a wraparound number.\n";return 1;}\
executeWrapperFunctions(wraparoundnumber);cout<<"\nPress ENTER to continue...";\
cin.ignore(numeric_limits<streamsize>::max(),'\n');return 0;}using namespace std

#endif 


More example codes (previous post codes in v2):
1
2
3
4
5
6
7
8
9
10
11
#include "WANOPV2.h"

signed a(0);
signed b(0);

Program("3126");
case 0:cin>>a;break;
case 1:cout<<"----\n";break;
case 2:cout<<(a+b);break;
case 3:cin>>b;break;
End;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "WANOPV2.h"

Program("24133625115");
case 0: cout << "H";break;
case 1: cout << "l";break;
case 2: cout << "e";break;
case 3: cout << "l";break;
case 4: cout << "o";break;
case 5: cout << "d";go = false;break;
case 6: cout << "l";break;
case 7: cout << "r";break;
case 8: cout << "o";break;
case 9: cout << " ";break;
case 10: cout << "w";break;
End;
Last edited on
I don't think you need a dependency list when the dependencies are part of the standard libary; you can assume the C++ standard library exists if someone's compiling your code.
Misnamed it a bit, you are correct. Gonna change it right away. :P
Topic archived. No new replies allowed.