Click here to Skip to main content
Click here to Skip to main content

Tagged as

Simple Bit Switches to Indicate Function States

, 13 May 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
A simple bit switch implementation to indicate/maintain function/scope states

Introduction

This simple article, primarily intended for beginners, explains the concept of using switches for state maintenance in functions.

The term 'switch', within the context of this article, refers to a simple object whose primary function is to set and unset attributes that describe the state of an execution scope.

Background

Let's take a look at some sample code:

class my_class
{
   public:

   void function_a()
   {
      run = true;

      if( condition1 ... )
      {
          run=false;
          return;
      }

      if( condition2... )
      {
          run=false;
          return;
      }

      switch( condition 3 )
      {
         case a:
         break;

         case b:
         break;

         default:
         run=false;
         return;
      }

      run = false;
   }

   bool is_running() const
   {
      return run;
   }

   protected:

   bool run;
}

Notice the object above. The object uses a boolean variable 'run' to indicate the state of 'function_a'. The nature of the function is such that it has too many exit points which implies the state variable needs to be reset before hitting each one of these exit points. To minimize the trouble, you can either re-organize the function to have a single exit point, in which case you'd still have to reset the state variable at the end or you can use a switch to accomplish the same task.

The following sample code shows a simple boolean switch. Our actual code will make use of std::bitset (see usage section).

class boolean_switch
{
    boolean_switch(){}

    bool* mpval;

    public:

    boolean_switch( bool* pval, bool initial_state )
    {
         if(pval)
         {
           mpval = pval;
           *mpval = initial_state;
         }
    }

    ~boolean_switch()
    {
        if(mpval)
        {
          *mpval = !(*mpval);
        }
    }
}

class my_class
{
   public:

   void function_a()
   {
      boolean_switch run_switch(&run, true);

      if( condition1 ... )
      {
          return;
      }

      if( condition2... )
      {
          return;
      }

      switch( condition 3 )
      {
         case a:
         break;

         case b:
         break;

         default:
         return;
      }
   }

   bool is_running() const
   {
      return run;
   }

   protected:

   bool run;
}

So now you get the basic idea, using the inherent nature of objects (construction & destruction) and scopes to maintain states. The usage section shows a different implementation using std::bitset for more extensibility, the idea remains the same.

Using the Code

Step 1: Define possible states for your function and enumerate them as shown below:

namespace states
{
    enum{status_running=0, status_scope1, status_scope2}
}

Step 2: Include a std::bitset object in your class as a member object. This serves the purpose of a bit mask.

namespace states
{
    enum{status_running=0, status_scope1, status_scope2}
}

const UINT MASK_SIZE 8;

class my_object
{
public:

    void function_a();

protected:
    std::bitset<mask_size> bmask;
}

Step 3: Use the switch object to indicate function scopes. Like any electrical switch, there's an 'On' and 'Off' position for the switch. Normally you'd set a switch to the 'On' position to indicate a state, but if a reverse logic is required, you may set the switch to the 'Off' position. The 'On' and 'Off' are contained in an enum within the 'switches' namespace. For the function below, we'll set the 'running' state to 'On' within the scope of the function.

void my_object::function_a()
{
    //
    // indicates the function is running now.
    //

    switches::bit_switch<mask_size> current_state(&bmask, states::status_running);

    while(//some condition)
    {
        //
        // indicates the function is within scope 1 now
        //
        switches::bit_switch<mask_size> current_state(&bmask, states::status_scope1);
        .
        .
        .

    }
}

Step 4: Add accessor functions for state checking.

namespace states
{
    enum{status_running=0, status_scope1, status_scope2}
}

const UINT MASK_SIZE 8;

class my_object
{
public:

    void function_a();

    bool is_running(){  return bmask[states::status_running];   }
    bool is_within_scope1(){    return bmask[states::status_scope1];    }
    bool is_within_scope2(){    return bmask[states::status_scope2];    }

protected:
    std::bitset<mask_size> bmask;
}

The switch is turned on when the function enters scope and turned off when it leaves its scope.

History

  • 5/12/2011 - Revision 1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Vinith B Raj

United States United States
No Biography provided

Comments and Discussions

 
GeneralLacks simplicity PinmemberMukit, Ataul16-May-11 1:51 
GeneralRe: Lacks simplicity PinmemberMukit, Ataul17-May-11 19:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 13 May 2011
Article Copyright 2011 by Vinith B Raj
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid