|
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