Boost logo

Boost :

From: jsiek_at_[hidden]
Date: 2000-01-08 01:36:39


There is a close relative to the array class that is also very
usefull: an array based on just a pointer to some memory "borrowed"
from somewhere else, an array_ref class.

Here's an implementation of both array and array_ref. As you'll
see I had some fun with helper classes.

Cheers,

Jeremy Siek

#ifndef BOOST_ARRAY_HPP
#define BOOST_ARRAY_HPP

#include <iterator>
#include <algorithm>
#include <boost/operators.hpp>

namespace boost {

  // A helper for creating reversible containers
  template <class C, class Iter, class const_Iter>
  struct reversible_container
  {
    // associated types
    typedef std::reverse_iterator<Iter> reverse_iterator;
    typedef std::reverse_iterator<const_Iter> const_reverse_iterator;

    // reverse iterator support
    reverse_iterator rbegin()
    {
      return reverse_iterator(static_cast<C&>(*this).end());
    }
    reverse_iterator rend()
    {
      return reverse_iterator(static_cast<C&>(*this).begin());
    }
    const_reverse_iterator rbegin() const
    {
      return const_reverse_iterator(static_cast<C&>(*this).end());
    }
    const_reverse_iterator rend() const
    {
      return const_reverse_iterator(static_cast<C&>(*this).begin());
    }
  };

  // A helper class for providing the Container interface based on an
  // underlying type C that provides data() and size() functions
  template <class C, class T>
  struct ptr_container_helper
    : public reversible_container< ptr_container_helper<C,T>, T*, const T*>,
      equality_comparable< ptr_container_helper<C,T> >,
      less_than_comparable< ptr_container_helper<C,T> >
  {
    typedef ptr_container_helper self;
  public:
    // associated types
    typedef T value_type;
    typedef T* pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;

    // iterator support
    iterator begin()
    {
      return static_cast<C&>(*this).data();
    }
    iterator end()
    {
      return static_cast<C&>(*this).data() + static_cast<C&>(*this).size();
    }
    const_iterator begin() const
    {
      return static_cast<const C&>(*this).data();
    }
    const_iterator end() const
    {
      return static_cast<const C&>(*this).data()
        + static_cast<const C&>(*this).size();
    }
    // direct element access
    reference operator[](size_type n)
    {
      return static_cast<C&>(*this).data()[n];
    }
    const_reference operator[](size_type n) const
    {
      return static_cast<const C&>(*this).data()[n];
    }
  };

  template <class C, class T>
  bool operator==(const ptr_container_helper<C,T>& x,
                  const ptr_container_helper<C,T>& y)
  {
    return std::equal(x.begin(), x.end(), y.begin());
  }

  template <class C, class T>
  bool operator<(const ptr_container_helper<C,T>& x,
                 const ptr_container_helper<C,T>& y)
  {
    return std::lexicographical_compare(x.begin(), x.end(),
                                        y.begin(), y.end());
  }

  // An array class wrapper for "borrowed" memory
  template <class T>
  class array_ref
    : public ptr_container_helper< array_ref<T>, T>
  {
    typedef array_ref self;
  public:
    array_ref() : _data(0), _size(0) { }
    array_ref(T* data_, size_t n)
      : _data(data_), _size(n) { }
    array_ref(const self& x)
      : _data(x._data), _size(x._size) { }
    ~array_ref() { }
    
    size_t size() const { return _size; }
    
    T* data() { return _data; }
    const T* data() const { return _data; }
    
  protected:
    T* _data;
    int _size;
  };

  // A heap-allocated fixed-size array class
  template <class T, size_t N>
  struct array
    : public ptr_container_helper< array<T,N>, T>
  {
    size_t size() const { return N; }

    T* data() { return _data; }
    const T* data() const { return _data; }
    
    T _data[N];
  };

} /* namespace boost */

#endif // BOOST_ARRAY_HPP


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk