<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<HTML>
<HEAD>
  <meta name="Classification" content="Software Development">
  <meta name="KeyWords" content="C++,Quality,Code Generation,Codign Standard">
<TITLE>Listing 3</TITLE>
</HEAD>
<BODY>

<table CELLSPACING=0 CELLPADDING=6 WIDTH="100%" BGCOLOR="#009000">
  <tr><td>
    <table COLS=2 WIDTH="100%">
      <tr>
        <td COLSPAN="2">
          <font color="#FFFFFF" size=+4>Sven Rosvall</font>
        </td>
      </tr>
      <tr>
        <td>
          <i><font color="#FFFFFF"></font></i>
        </td>
        <td ALIGN=RIGHT>
          <font color="#FFFFFF">
          <a href="index.html"><font color="#FFFFFF">Home</font></a>
          -
          <a href="/Contact.html"><font color="#FFFFFF">Contact Info</font></a>
          </font>
        </td>
      </tr>
    </table>
  </td></tr>
</table>
<TABLE CELLSPACING=0 CELLPADDING=10>
<TR><TD VALIGN=TOP BGCOLOR="#CCFFFF">
·&nbsp;<A HREF="../index.html">Start</A><BR>
·&nbsp;<A HREF="../Sven-E.html">Sven&nbsp;Rosvall</A><BR>
&nbsp;&nbsp;·&nbsp;<A HREF="../Sven_CV.html">CV</A><BR>
&nbsp;&nbsp;·&nbsp;<A HREF="../Sven_Proj.html">Projects</A><BR>
&nbsp;&nbsp;·&nbsp;<A HREF="Articles.html">Articles</A><BR>
&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<A HREF="ArtStrings.html">Mixing&nbsp;Strings&nbsp;in&nbsp;C++</A><BR>
&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<A HREF="ArtSafeC.html">C++&nbsp;as&nbsp;a&nbsp;Safer&nbsp;C</A><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<A HREF="BoundedInt.h">Listing&nbsp;1</A><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<A HREF="BoundedIntTraits.h">Listing&nbsp;2</A><BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<B>Listing&nbsp;3</B><BR>
&nbsp;&nbsp;&nbsp;&nbsp;·&nbsp;<A HREF="CppLookup.html">C++&nbsp;Lookup&nbsp;Mysteries</A><BR>
·&nbsp;<A HREF="../Kari.html">Kari&nbsp;Rosvall</A><BR>
·&nbsp;<A HREF="../Sven_Kari.html">The&nbsp;Rosvalls</A><BR>
</TD><TD VALIGN=TOP>
<H2>Listing 3</H2>
<PRE>
// BoundedPointer.h
// Bounds checked pointer
//

#ifndef BoundedPointer_h
#define BoundedPointer_h

#include &lt;cstddef&gt;
#include &lt;cassert&gt;


template &lt;typename T&gt;
class BoundedPointer
{
public:
  // Default constructor
  BoundedPointer()
#ifndef NDEBUG
    : m_initialised(false)
#endif
    {}

  // Constructor from a pointer
  BoundedPointer(const T * value)
    : m_p(const_cast&lt;T *&gt;(value))
#ifndef NDEBUG
    , m_base(m_p)
    , m_size(1)
    , m_initialised(true)
#endif
    {}

  // Constructor from a built-in array
  template &lt;size_t Size&gt;
  BoundedPointer(T (&amp;arr)[Size])
    : m_p(arr)
#ifndef NDEBUG
    , m_base(m_p)
    , m_size(Size)
    , m_initialised(true)
#endif
    {}

  // Constructor from an user defined array type
  BoundedPointer(const T * base, size_t size)
    : m_p(const_cast&lt;T *&gt;(base))
#ifndef NDEBUG
    , m_base(m_p)
    , m_size(size)
    , m_initialised(true)
#endif
    {}

  // Dereference operators
  T &amp; operator*()
    {
      assert(m_initialised);
      assert(m_p != 0);
      return *m_p;
    }
  T * operator-&gt;()
    {
      assert(m_initialised);
      assert(m_p != 0);
      return m_p;
    }
  T &amp; operator[](size_t ix)
    {
      assert(m_initialised);
      assert(m_p != 0);
      assert(ix &lt; m_size - (m_p-m_base));
      return m_p[ix];
    }

  // Pointer arithmetic operations
  ptrdiff_t operator-(BoundedPointer const &amp; rhs)
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(rhs.m_initialised);
      assert(m_p != 0);
      assert(rhs.m_p != 0);

      // Make sure that both pointer point 
      // to the same array
      assert(m_base == rhs.m_base);
      return m_p - rhs.m_p;
    }
  BoundedPointer &amp; operator+=(ptrdiff_t rhs)
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(m_p != 0);

      m_p += rhs;
      assert(m_base &lt;= m_p &amp;&amp; m_p &lt; m_base + m_size);
      return *this;
    }
  BoundedPointer &amp; operator-=(int rhs)
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(m_p != 0);

      m_p -= rhs;
      assert(m_p &gt;= m_base);
      return *this;
    }
  BoundedPointer &amp; operator++()
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(m_p != 0);

      ++m_p;
      assert(m_p &lt; m_base + m_size);
      return *this;
    }
  BoundedPointer &amp; operator--()
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(m_p != 0);

      --m_p;
      assert(m_p &gt;= m_base);
      return *this;
    }

  // Comparison operators
  bool operator&lt;(BoundedPointer const &amp; rhs)
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(rhs.m_initialised);
      assert(m_p != 0);
      assert(rhs.m_p != 0);

      // Make sure that both pointer point 
      // to the same array
      assert(m_base == rhs.m_base);
      return m_p &lt; rhs.m_p;
    }
  bool operator==(BoundedPointer const &amp; rhs)
    {
      // Check validity of the pointers
      assert(m_initialised);
      assert(rhs.m_initialised);
      assert(m_p != 0);
      assert(rhs.m_p != 0);

      // Make sure that both pointer point 
      // to the same array
      assert(m_base == rhs.m_base);
      return m_p == rhs.m_p;
    }


private:
  T * m_p;
#ifndef NDEBUG
  T * m_base;
  size_t m_size;
  bool m_initialised;
#endif
};

// Binary arithmetic operators
template &lt;typename T&gt;
inline BoundedPointer&lt;T&gt; 
operator+(BoundedPointer&lt;T&gt; lhs, int rhs)
{
  return lhs.operator+=(rhs);
}
template &lt;typename T&gt;
inline BoundedPointer&lt;T&gt; 
operator+(int lhs, BoundedPointer&lt;T&gt; rhs)
{
  return rhs.operator+=(lhs);
}

template &lt;typename T&gt;
inline BoundedPointer&lt;T&gt; 
operator-(BoundedPointer&lt;T&gt; lhs, int rhs)
{
  return lhs.operator-=(rhs);
}
template &lt;typename T&gt;
inline BoundedPointer&lt;T&gt; 
operator-(int lhs, BoundedPointer&lt;T&gt; rhs)
{
  return rhs.operator-=(lhs);
}

#endif
</PRE>
<P><HR>
<FONT SIZE=-1> Copyright 2003-2010</FONT>
</TD></TR>
</TABLE>
</BODY></HTML>

