CMS 3D CMS Logo

Sequence.h

Go to the documentation of this file.
00001 #ifndef CLASSLIB_SEQUENCE_H
00002 # define CLASSLIB_SEQUENCE_H
00003 
00004 //<<<<<< INCLUDES                                                       >>>>>>
00005 
00006 # include "classlib/utils/Range.h"
00007 # include "classlib/utils/IntTraits.h"
00008 # include "classlib/utils/DebugAids.h"
00009 # include "classlib/utils/Log.h"
00010 # include <stdexcept>
00011 # include <typeinfo>
00012 
00013 namespace lat {
00014 //<<<<<< PUBLIC DEFINES                                                 >>>>>>
00015 //<<<<<< PUBLIC CONSTANTS                                               >>>>>>
00016 //<<<<<< PUBLIC TYPES                                                   >>>>>>
00017 
00018 template <class T> class Sequence;
00019 
00020 //<<<<<< PUBLIC VARIABLES                                               >>>>>>
00021 //<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
00022 
00023 template <class T>
00024 logstream &operator<< (logstream &log, const Sequence<T> &s);
00025 
00026 //<<<<<< CLASS DECLARATIONS                                             >>>>>>
00027 
00034 template <class T>
00035 class Sequence
00036 {
00037 public:
00038     Sequence (bool wraps = false);
00039     Sequence (T low, T high, bool wraps = false);
00040     Sequence (const Range<T> &limits, bool wraps = false);
00041     // Implicit copy constructor.
00042     // Implicit destructor.
00043     // Implicit assignment operator.
00044 
00045     Range<T>            limits (void) const;
00046     void                limits (const Range<T> &value);
00047 
00048     bool                wraps (void) const;
00049     void                wraps (bool value);
00050     bool                wrapped (void);
00051     
00052     T                   next (void);
00053     T                   current (void) const;
00054     void                reset (void);
00055 
00056     friend logstream &  operator<< <> (logstream &log, const Sequence &s);
00057 
00058 private:
00059     Range<T>            m_limits;  /*< The range of possible values. */
00060     T                   m_current; /*< The current sequence value. */
00061     bool                m_wraps;   /*< Flag indicating the wrapping mode. */
00062     bool                m_wrapped; /*< Flag indicating if wrapping has
00063                                        happened.  Reading the flag
00064                                        clears it. */
00065 };
00066 
00067 //<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
00068 
00069 template <class T>
00070 inline logstream &
00071 operator<< (logstream &log, const Sequence<T> &s)
00072 {
00073 #ifndef NLOG
00074     ASSERT (s.m_limits.low () < s.m_limits.high ());
00075     ASSERT (s.m_current >= s.m_limits.low ());
00076     ASSERT (s.m_current <= s.m_limits.high ());
00077 
00078     return log
00079         << "Sequence<" << typeid(T).name () << "> @ " << &s << " {\n" << indent
00080         << "limits  [" << s.m_limits.low ()
00081         << ", " << s.m_limits.high () << "]\n"
00082         << "current " << s.m_current << endl
00083         << "wraps   " << s.m_wraps << endl
00084         << "wrapped " << s.m_wrapped << endl
00085         << undent << "}";
00086 #endif // !NLOG
00087 }
00088 
00089 //<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
00090 
00103 template <class T>
00104 inline
00105 Sequence<T>::Sequence (bool wraps /* = false */)
00106     : m_limits (IntTraits<T>::Min, IntTraits<T>::Max),
00107       m_current (IntTraits<T>::Min),
00108       m_wraps (wraps),
00109       m_wrapped (false)
00110 {
00111     ASSERT (m_limits.low () < m_limits.high ());
00112     ASSERT (m_current >= m_limits.low ());
00113     ASSERT (m_current <= m_limits.high ());
00114 }
00115 
00117 template <class T>
00118 inline
00119 Sequence<T>::Sequence (T low, T high, bool wraps /* = false */)
00120     : m_limits (low, high),
00121       m_current (low),
00122       m_wraps (wraps),
00123       m_wrapped (false)
00124 {
00125     ASSERT (m_limits.low () < m_limits.high ());
00126     ASSERT (m_current >= m_limits.low ());
00127     ASSERT (m_current <= m_limits.high ());
00128 }
00129 
00131 template <class T>
00132 inline
00133 Sequence<T>::Sequence (const Range<T> &limits, bool wraps /* = false */)
00134     : m_limits (limits),
00135       m_current (limits.low ()),
00136       m_wraps (wraps),
00137       m_wrapped (false)
00138 {
00139     ASSERT (m_limits.low () < m_limits.high ());
00140     ASSERT (m_current >= m_limits.low ());
00141     ASSERT (m_current <= m_limits.high ());
00142 }
00143 
00145 template <class T>
00146 inline Range<T>
00147 Sequence<T>::limits (void) const
00148 { return m_limits; }
00149 
00155 template <class T>
00156 inline void
00157 Sequence<T>::limits (const Range<T> &value)
00158 {
00159     ASSERT (m_limits.low () < m_limits.high ());
00160     ASSERT (m_current >= m_limits.low ());
00161     ASSERT (m_current <= m_limits.high ());
00162     ASSERT (value.low () < value.high ());
00163 
00164     m_limits = limits;
00165     if (m_current < m_limits.low ())
00166     {
00167         m_wrapped = true;
00168         m_current = m_limits.low ();
00169     }
00170     else if (m_current > m_limits.high ())
00171     {
00172         m_wrapped = true;
00173         m_current = m_limits.high ();
00174     }
00175 }
00176 
00179 template <class T>
00180 inline bool
00181 Sequence<T>::wraps (void) const
00182 { return m_wraps; }
00183 
00186 template <class T>
00187 inline void Sequence<T>::wraps (bool value)
00188 { m_wraps = value; }
00189 
00192 template <class T>
00193 inline bool
00194 Sequence<T>::wrapped (void)
00195 { bool wrapped = m_wrapped; m_wrapped = false; return wrapped; }
00196 
00205 template <class T>
00206 inline T
00207 Sequence<T>::next (void)
00208 {
00209     ASSERT (m_limits.low () < m_limits.high ());
00210     ASSERT (m_current >= m_limits.low ());
00211     ASSERT (m_current <= m_limits.high ());
00212 
00213     if (m_current == m_limits.high ())
00214         if (m_wraps)
00215         {
00216             m_wrapped = true;
00217             m_current = m_limits.low ();
00218         }
00219         else
00220             throw std::range_error ("Sequence upper limit reached");
00221     else
00222         ++m_current;
00223 
00224     ASSERT (m_current >= m_limits.low ());
00225     ASSERT (m_current <= m_limits.high ());
00226     return m_current;
00227 }
00228 
00230 template <class T>
00231 inline T
00232 Sequence<T>::current (void) const
00233 {
00234     ASSERT (m_limits.low () < m_limits.high ());
00235     ASSERT (m_current >= m_limits.low ());
00236     ASSERT (m_current <= m_limits.high ());
00237     return m_current;
00238 }
00239 
00242 template <class T>
00243 inline void
00244 Sequence<T>::reset (void)
00245 {
00246     ASSERT (m_limits.low () < m_limits.high ());
00247     ASSERT (m_current >= m_limits.low ());
00248     ASSERT (m_current <= m_limits.high ());
00249 
00250     m_current = m_limits.low ();
00251     m_wrapped = false;
00252 
00253     ASSERT (m_limits.low () < m_limits.high ());
00254     ASSERT (m_current >= m_limits.low ());
00255     ASSERT (m_current <= m_limits.high ());
00256 }
00257 
00258 } // namespace lat
00259 #endif // CLASSLIB_SEQUENCE_H

Generated on Tue Jun 9 17:38:55 2009 for CMSSW by  doxygen 1.5.4