Loki/test/SafeBits/SafeBitTest.cpp

326 lines
12 KiB
C++
Raw Normal View History

////////////////////////////////////////////////////////////////////////////////
//
// This is a test program for Safe-Bit-Fields in the Loki Library.
// Copyright (c) 2009 by Fedor Pikus & Rich Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
// The author makes no claims about the suitability of this software for any
// purpose. It is provided "as is" without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
// $Id$
#include <loki/SafeBits.h>
#include <iostream>
using namespace std;
using namespace Loki;
LOKI_BIT_FIELD( unsigned int ) Cat_state;
LOKI_BIT_CONST( Cat_state, CAT_NO_STATE, 0 ); // 0x0000 - no bit is set
LOKI_BIT_CONST( Cat_state, CAT_SLEEPING, 1 ); // 0x0001 - 1st bit is set
LOKI_BIT_CONST( Cat_state, CAT_PURRING, 2 ); // 0x0002 - 2nd bit is set
LOKI_BIT_CONST( Cat_state, CAT_PLAYING, 3 ); // 0x0004 - 3rd bit is set
LOKI_BIT_FIELD( unsigned int ) Dog_state;
LOKI_BIT_CONST( Dog_state, DOG_BARKING, 1 );
LOKI_BIT_CONST( Dog_state, DOG_CHEWING, 2 );
LOKI_BIT_CONST( Dog_state, DOG_DROOLING, 3 );
LOKI_BIT_CONST( Dog_state, DOG_SLEEPING, 4 );
LOKI_BIT_CONST( Dog_state, DOG_GROWLING, 5 );
LOKI_BIT_CONST( Dog_state, DOG_TIRED, 6 );
LOKI_BIT_CONST( Dog_state, DOG_DEAD, 7 );
LOKI_BIT_CONST( Dog_state, DOG_GROWING, 8 );
LOKI_BIT_CONST( Dog_state, DOG_THINKING, 9 );
LOKI_BIT_CONST( Dog_state, DOG_YELPING, 10 );
LOKI_BIT_CONST( Dog_state, DOG_QUIET, 11 );
LOKI_BIT_CONST( Dog_state, DOG_FETCHING, 12 );
LOKI_BIT_CONST( Dog_state, DOG_HOWLING, 13 );
LOKI_BIT_CONST( Dog_state, DOG_SICK, 14 );
LOKI_BIT_CONST( Dog_state, DOG_JUMPING, 15 );
LOKI_BIT_CONST( Dog_state, DOG_SWIMMING, 16 );
LOKI_BIT_CONST( Dog_state, DOG_BATHING, 17 );
LOKI_BIT_CONST( Dog_state, DOG_EATING, 18 );
LOKI_BIT_CONST( Dog_state, DOG_DRINKING, 19 );
LOKI_BIT_CONST( Dog_state, DOG_PLAYING, 20 );
LOKI_BIT_CONST( Dog_state, DOG_RUNNING, 21 );
LOKI_BIT_CONST( Dog_state, DOG_BITING, 22 );
LOKI_BIT_CONST( Dog_state, DOG_BEGGING, 23 );
LOKI_BIT_CONST( Dog_state, DOG_WHINING, 24 );
LOKI_BIT_CONST( Dog_state, DOG_WALKING, 25 );
LOKI_BIT_CONST( Dog_state, DOG_SINGING, 26 );
LOKI_BIT_CONST( Dog_state, DOG_FIGHTING, 27 );
LOKI_BIT_CONST( Dog_state, DOG_MATING, 28 );
LOKI_BIT_CONST( Dog_state, DOG_FEEDING, 29 );
LOKI_BIT_CONST( Dog_state, DOG_BIRTHING, 30 );
LOKI_BIT_CONST( Dog_state, DOG_SHEDDING, 31 );
LOKI_BIT_CONST( Dog_state, DOG_TALKING, 32 );
#ifdef ERROR0
LOKI_BIT_CONST( Dog_state, DOG_TALKING, 20 ); // Can't have two values with same name.
LOKI_BIT_CONST( Dog_state, DOG_BLOGGING, 33 ); // Can't set bit 33 in a 32 bit-sized object.
#endif
int main( void )
{
cout << "Running tests on Loki safe bit fields." << endl;
Cat_state cat_state = CAT_SLEEPING;
assert( cat_state );
Dog_state dog_now;
Dog_state dog_state = DOG_DROOLING;
assert( dog_state );
bool happy = cat_state & ( CAT_SLEEPING | CAT_PURRING ); // OK
assert( happy );
assert( CAT_SLEEPING < CAT_PURRING );
assert( CAT_SLEEPING <= CAT_SLEEPING );
assert( CAT_SLEEPING <= CAT_PURRING );
assert( CAT_SLEEPING != CAT_PURRING );
assert( CAT_SLEEPING == CAT_SLEEPING );
assert( CAT_PURRING >= CAT_SLEEPING );
assert( CAT_PURRING >= CAT_PURRING );
#ifdef ERROR1
assert( DOG_DROOLING != CAT_SLEEPING ); // Can't compare different types.
#endif
#ifdef ERROR2
if ( cat_state & DOG_BARKING ) {} // Wrong bit type
#endif
#ifdef ERROR3
if ( cat_state & CAT_SLEEPING == 0 ) {} // Operator precedence
#endif
#ifdef ERROR4
if ( dog_state && DOG_BARKING ) {} // Logical &&
#endif
if ( dog_state & DOG_BARKING ) {} // OK
#ifdef ERROR5
Cat_state state0 = 0; // Conversion from non-safe bits
#endif
Cat_state state = CAT_NO_STATE; // OK
assert( !state );
state = ~state;
assert( state );
assert( state != CAT_NO_STATE );
assert( state & CAT_SLEEPING );
assert( state & CAT_PURRING );
assert( state & CAT_PLAYING );
state = CAT_SLEEPING;
assert( state == cat_state );
assert( state.size() == ( 8 * sizeof(unsigned int) ) );
assert( sizeof(Cat_state) == sizeof(unsigned int) );
dog_now = dog_state = DOG_BARKING;
assert( dog_now == dog_state );
#ifdef ERROR6
if ( dog_state == cat_state ) {} // Don't allow comparison of different types.
#endif
/// @note All These assertions are inside #ifdef sections because they
/// compare either SafeBitField or SafeBitConst to literal integers.
/// If you compile any of these assertions they should generate errors.
/// These #ifdef sections exhaustively demonstrate that all possible
/// operations and comparisons with literal values are forbidden.
#ifdef ERROR7
assert( dog_state == 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR8
assert( dog_state != 2 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR9
assert( dog_state < 2 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR10
assert( dog_state > 0 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR11
assert( dog_state <= 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR12
assert( dog_state >= 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR13
assert( DOG_BARKING == 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR14
assert( DOG_BARKING != 2 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR15
assert( DOG_BARKING < 2 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR16
assert( DOG_BARKING > 0 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR17
assert( DOG_BARKING <= 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR18
assert( DOG_BARKING >= 1 ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR19
assert( ( dog_state | 1 ) != 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR20
assert( ( dog_state & 2 ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR21
assert( ( dog_state ^ 1 ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR22
assert( ( dog_state |= 2 ) == 3 ); // Don't allow operations with integers.
#endif
#ifdef ERROR23
assert( ( dog_state &= 3 ) == 2 ); // Don't allow operations with integers.
#endif
#ifdef ERROR24
assert( ( dog_state ^= 1 ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR25
assert( ( DOG_BARKING | 1 ) != 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR26
assert( ( DOG_BARKING & 2 ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR27
assert( ( DOG_BARKING ^ 1 ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR28
assert( ( DOG_BARKING |= 2 ) == 3 ); // Don't allow operations with integers.
#endif
#ifdef ERROR29
assert( ( DOG_BARKING &= 3 ) == 2 ); // Don't allow operations with integers.
#endif
#ifdef ERROR30
assert( ( DOG_BARKING ^= 1 ) == 0 ); // Don't allow operations with integers.
#endif
/// @note All These assertions are inside #ifdef sections because they
/// compare either SafeBitField or SafeBitConst to an int variable.
/// If you compile any of these assertions they should generate errors.
/// These #ifdef sections exhaustively demonstrate that all possible
/// operations and comparisons with integers are forbidden.
int value = 1;
(void)value;
#ifdef ERROR31
assert( dog_state == value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR32
value = 2;
assert( dog_state != value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR33
value = 2;
assert( dog_state < value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR34
value = 0;
assert( dog_state > value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR35
value = 1;
assert( dog_state <= value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR36
value = 1;
assert( dog_state >= value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR37
value = 1;
assert( DOG_BARKING == value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR38
value = 2;
assert( DOG_BARKING != value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR39
value = 2;
assert( DOG_BARKING < value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR40
value = 0;
assert( DOG_BARKING > value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR41
value = 1;
assert( DOG_BARKING <= value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR42
value = 1;
assert( DOG_BARKING >= value ); // Don't allow comparisons to integers.
#endif
#ifdef ERROR43
value = 1;
assert( ( dog_state | value ) != 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR44
value = 2;
assert( ( dog_state & value ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR45
value = 1;
assert( ( dog_state ^ value ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR46
value = 2;
assert( ( dog_state |= value ) == 3 ); // Don't allow operations with integers.
#endif
#ifdef ERROR47
value = 3;
assert( ( dog_state &= value ) == 2 ); // Don't allow operations with integers.
#endif
#ifdef ERROR48
value = 1;
assert( ( dog_state ^= value ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR49
value = 1;
assert( ( DOG_BARKING | value ) != 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR50
value = 2;
assert( ( DOG_BARKING & value ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR51
value = 1;
assert( ( DOG_BARKING ^ value ) == 0 ); // Don't allow operations with integers.
#endif
#ifdef ERROR52
value = 2;
assert( ( DOG_BARKING |= value ) == 3 ); // Don't allow operations with integers.
#endif
#ifdef ERROR53
value = 3;
assert( ( DOG_BARKING &= value ) == 2 ); // Don't allow operations with integers.
#endif
#ifdef ERROR54
value = 1;
assert( ( DOG_BARKING ^= value ) == 0 ); // Don't allow operations with integers.
#endif
dog_now = dog_state |= DOG_CHEWING;
assert( dog_state & ( DOG_CHEWING | DOG_BARKING ) );
assert( dog_now == dog_state );
dog_now = dog_state &= DOG_CHEWING;
assert( dog_state == DOG_CHEWING );
assert( dog_now == dog_state );
dog_state = ~dog_state;
assert( dog_state != DOG_CHEWING );
dog_state = ~dog_state;
assert( dog_state == DOG_CHEWING );
cout << "If nothing asserted, then all tests passed!" << endl;
return 0;
}