Qucs-core  0.0.19
states.cpp
Go to the documentation of this file.
00001 /*
00002  * states.cpp - save-state variable template class implementation
00003  *
00004  * Copyright (C) 2004 Stefan Jahn <stefan@lkcc.org>
00005  *
00006  * This is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2, or (at your option)
00009  * any later version.
00010  *
00011  * This software is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this package; see the file COPYING.  If not, write to
00018  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  * $Id$
00022  *
00023  */
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 #include "states.h"
00030 
00031 // Some definitions for the save-state variables.
00032 #define STATE_SHIFT 3
00033 #define STATE_NUM   8
00034 #define STATE_MASK  7
00035 
00036 namespace qucs {
00037 
00038 // Constructor creates an unnamed instance of the states class.
00039 template <class state_type_t>
00040 states<state_type_t>::states ()
00041 {
00042     nstates = 0;
00043     currentstate = 0;
00044     stateval = NULL;
00045 }
00046 
00047 /* The copy constructor creates a new instance based on the given
00048    states object. */
00049 template <class state_type_t>
00050 states<state_type_t>::states (const states & c)
00051 {
00052     nstates = c.nstates;
00053     currentstate = c.currentstate;
00054 
00055     // copy state variables if necessary
00056     if (nstates && c.stateval)
00057     {
00058         int size = nstates * sizeof (state_type_t) * STATE_NUM;
00059         stateval = (state_type_t *) malloc (size);
00060         memcpy (stateval, c.stateval, size);
00061     }
00062     else stateval = NULL;
00063 }
00064 
00065 // Destructor deletes a states object.
00066 template <class state_type_t>
00067 states<state_type_t>::~states ()
00068 {
00069     free (stateval);
00070 }
00071 
00072 /* The function allocates and initializes memory for the save-state
00073    variables. */
00074 template <class state_type_t>
00075 void states<state_type_t>::initStates (void)
00076 {
00077     free (stateval);
00078     if (nstates)
00079     {
00080         stateval = (state_type_t *)
00081                    calloc (nstates, sizeof (state_type_t) * STATE_NUM);
00082     }
00083     currentstate = 0;
00084 }
00085 
00086 // Clears the save-state variables.
00087 template <class state_type_t>
00088 void states<state_type_t>::clearStates (void)
00089 {
00090     if (nstates && stateval)
00091         memset (stateval, 0, nstates * sizeof (state_type_t) * STATE_NUM);
00092     currentstate = 0;
00093 }
00094 
00095 /* The function returns a save-state variable at the given position.
00096    Higher positions mean earlier states.  By default the function
00097    returns the current state of the save-state variable. */
00098 template <class state_type_t>
00099 state_type_t states<state_type_t>::getState (int state, int n)
00100 {
00101     int i = (n + currentstate) & STATE_MASK;
00102     return stateval[(state << STATE_SHIFT) + i];
00103 }
00104 
00105 /* This function applies the given value to a save-state variable.
00106    Higher positions mean earlier states.  By default the function sets
00107    the current state of the save-state variable. */
00108 template <class state_type_t>
00109 void states<state_type_t>::setState (int state, state_type_t val, int n)
00110 {
00111     int i = (n + currentstate) & STATE_MASK;
00112     stateval[(state << STATE_SHIFT) + i] = val;
00113 }
00114 
00115 // Shifts one state forward.
00116 template <class state_type_t>
00117 void states<state_type_t>::nextState (void)
00118 {
00119     if (--currentstate < 0) currentstate = STATE_NUM - 1;
00120 }
00121 
00122 // Shifts one state backward.
00123 template <class state_type_t>
00124 void states<state_type_t>::prevState (void)
00125 {
00126     currentstate = (currentstate + 1) & STATE_MASK;
00127 }
00128 
00129 /* This function applies the given value to a save-state variable through
00130    all history values. */
00131 template <class state_type_t>
00132 void states<state_type_t>::fillState (int state, state_type_t val)
00133 {
00134     // get a pointer to the start of the state array
00135     state_type_t * p = &stateval[state << STATE_SHIFT];
00136     // fill each array member with the supplied value
00137     for (int i = 0; i < STATE_NUM; i++)
00138     {
00139         *p++ = val;
00140     }
00141 }
00142 
00143 /* This function stores the values of the given state into the given
00144    pointer location. */
00145 template <class state_type_t>
00146 void states<state_type_t>::saveState (int state, state_type_t * values)
00147 {
00148     // loop through the list of states copying them into the
00149     // supplied input array
00150     for (int i = 0; i < STATE_NUM; i++)
00151     {
00152         values[i] = getState (state, i);
00153     }
00154 }
00155 
00156 /* This function stores the values in the given pointer location
00157    into the state. */
00158 template <class state_type_t>
00159 void states<state_type_t>::inputState (int state, state_type_t * values)
00160 {
00161     // loop through the list of states copying them into the
00162     // supplied input array
00163     for (int i = 0; i < STATE_NUM; i++)
00164     {
00165         setState (state, values[i], i);
00166     }
00167 }
00168 
00169 } // namespace qucs