]> git.llucax.com Git - software/posixx.git/blobdiff - src/basic_buffer.hpp
Generalize basic_buffer's value_type
[software/posixx.git] / src / basic_buffer.hpp
index 494043fa86e33b0fadfa77e66e4d2c95b87b79ae..14b880cbb00d3ab5cf40ee3351e87ed41636a4be 100644 (file)
@@ -4,8 +4,10 @@
 #include <stdexcept> // std::bad_alloc, std::out_of_range
 #include <limits> // std::numeric_limits
 #include <tr1/type_traits> // std::tr1::is_integral, true_type, false_type
+#include <cstdlib> // std::realloc()
 #include <cstring> // std::memcpy(), memset(), memcmp()
 #include <cassert> // assert()
+#include <cstddef> // std::size_t, ptrdiff_t
 
 namespace posixx {
 
@@ -13,20 +15,20 @@ namespace posixx {
  * A low-level buffer.
  *
  * This is pretty much like using a plain C-style array using dynamic memory,
- * with a STL-ish interface.
+ * with a STL-ish interface. Only POD should be stored, since no constructors
+ * or destructors are called.
  *
  * The buffer will use Allocator (which should be a function with realloc(3)
  * semantics) for all storage management.
  */
-template< void* (*Allocator)(void*, size_t) >
+template< typename T, void* (*Allocator)(void*, size_t) = &std::realloc >
 struct basic_buffer {
 
        // Types
        //////////////////////////////////////////////////////////////////////
 
        ///
-       typedef unsigned char value_type; // TODO: use char to be more
-                                         //       std::string-friendly?
+       typedef T value_type;
 
        ///
        typedef value_type& reference;
@@ -35,16 +37,16 @@ struct basic_buffer {
        typedef const value_type& const_reference;
 
        ///
-       typedef value_type* iterator; // TODO: make a real iterator
+       typedef value_type* iterator;
 
        ///
        typedef const value_type* const_iterator;
 
        ///
-       typedef size_t size_type;
+       typedef std::size_t size_type;
 
        ///
-       typedef ptrdiff_t difference_type;
+       typedef std::ptrdiff_t difference_type;
 
        ///
        typedef value_type* pointer;
@@ -53,12 +55,10 @@ struct basic_buffer {
        typedef const pointer const_pointer;
 
        ///
-       // TODO: reverse iterator
-       //typedef typename std::reverse_iterator< iterator > reverse_iterator;
+       typedef std::reverse_iterator< iterator > reverse_iterator;
 
        ///
-       //typedef typename std::reverse_iterator< const iterator >
-       //              const_reverse_iterator;
+       typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
 
 
        // Construct/Copy/Destroy
@@ -96,7 +96,7 @@ struct basic_buffer {
         *
         * @throw std::bad_alloc
         */
-       basic_buffer(const basic_buffer< Allocator >& x):
+       basic_buffer(const basic_buffer< T, Allocator >& x):
                        _data(_allocate(NULL, x.size() * sizeof(value_type))),
                        _size(x.size())
        {
@@ -127,8 +127,8 @@ struct basic_buffer {
         *
         * @throw std::bad_alloc
         */
-       basic_buffer< Allocator >& operator = (
-                       const basic_buffer< Allocator >& x)
+       basic_buffer< T, Allocator >& operator = (
+                       const basic_buffer< T, Allocator >& x)
        {
                if (this != &x) {
                        resize(x.size());
@@ -178,29 +178,29 @@ struct basic_buffer {
         * Returns a random access reverse_iterator that points to the
         * past-the-end value.
         */
-       //reverse_iterator rbegin()
-       //{ return std::reverse_iterator< iterator >(end()); }
+       reverse_iterator rbegin()
+       { return reverse_iterator(end()); }
 
        /**
         * Returns a random access const_reverse_iterator that points to the
         * past-the-end value.
         */
-       //const_reverse_iterator rbegin() const
-       //{ return std::reverse_iterator< const iterator >(end()); }
+       const_reverse_iterator rbegin() const
+       { return const_reverse_iterator(end()); }
 
        /**
         * Returns a random access reverse_iterator that points to the first
         * element.
         */
-       //reverse_iterator rend()
-       //{ return std::reverse_iterator< iterator >(begin()); }
+       reverse_iterator rend()
+       { return reverse_iterator(begin()); }
 
        /**
         * Returns a random access const_reverse_iterator that points to the
         * first element.
         */
-       //const_reverse_iterator rend() const
-       //{ return std::reverse_iterator< const iterator >(begin()); }
+       const_reverse_iterator rend() const
+       { return const_reverse_iterator(begin()); }
 
 
        // Capacity
@@ -403,11 +403,11 @@ struct basic_buffer {
        }
 
        /**
-        * Efficiently swaps the contents of x and y.
+        * Efficiently swaps the contents of x and y.
         *
         * Invalidates all references and iterators.
         */
-       void swap(basic_buffer< Allocator >& x)
+       void swap(basic_buffer< T, Allocator >& x)
        {
                pointer tmp_data = x._data;
                size_type tmp_size = x._size;
@@ -434,10 +434,10 @@ protected:
        pointer _data;
 
        // Size in number of items
-       size_t _size;
+       std::size_t _size;
 
        // Allocator wrapper for automatic casting
-       static pointer _allocate(void* ptr, size_t sz)
+       static pointer _allocate(void* ptr, std::size_t sz)
        {
                if (ptr == NULL && sz == 0)
                        return NULL;
@@ -485,8 +485,9 @@ protected:
 /**
  * Returns true if x hass the same contents as y.
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator == (const basic_buffer< Allocator >& x, const basic_buffer < Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator == (const basic_buffer< T, Allocator >& x,
+               const basic_buffer < T, Allocator >& y)
 {
        if (&x == &y)
                return true;
@@ -506,8 +507,9 @@ bool operator == (const basic_buffer< Allocator >& x, const basic_buffer < Alloc
 /**
  * Returns !(x==y).
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator != (const basic_buffer<Allocator>& x, const basic_buffer <Allocator>& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator != (const basic_buffer< T, Allocator >& x,
+               const basic_buffer < T, Allocator >& y)
 {
        return !(x == y);
 }
@@ -516,8 +518,9 @@ bool operator != (const basic_buffer<Allocator>& x, const basic_buffer <Allocato
  * Returns true if the elements contained in x are lexicographically less than
  * the elements contained in y.
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator < (const basic_buffer< Allocator >& x, const basic_buffer< Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator < (const basic_buffer< T, Allocator >& x,
+               const basic_buffer< T, Allocator >& y)
 {
        if (&x == &y)
                return false;
@@ -537,8 +540,9 @@ bool operator < (const basic_buffer< Allocator >& x, const basic_buffer< Allocat
 /**
  * Returns y < x.
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator > (const basic_buffer< Allocator >& x, const basic_buffer< Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator > (const basic_buffer< T, Allocator >& x,
+               const basic_buffer< T, Allocator >& y)
 {
        return y < x;
 }
@@ -546,8 +550,9 @@ bool operator > (const basic_buffer< Allocator >& x, const basic_buffer< Allocat
 /**
  * Returns !(y < x).
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator <= (const basic_buffer< Allocator >& x, const basic_buffer< Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator <= (const basic_buffer< T, Allocator >& x,
+               const basic_buffer< T, Allocator >& y)
 {
        return !(y < x);
 }
@@ -555,8 +560,9 @@ bool operator <= (const basic_buffer< Allocator >& x, const basic_buffer< Alloca
 /**
  * Returns !(x < y).
  */
-template < void* (*Allocator)(void*, size_t) >
-bool operator >= (const basic_buffer< Allocator >& x, const basic_buffer< Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+bool operator >= (const basic_buffer< T, Allocator >& x,
+               const basic_buffer< T, Allocator >& y)
 {
        return !(x < y);
 }
@@ -570,8 +576,8 @@ bool operator >= (const basic_buffer< Allocator >& x, const basic_buffer< Alloca
  *
  * Invalidates all references and iterators.
  */
-template < void* (*Allocator)(void*, size_t) >
-void swap(basic_buffer< Allocator >& x, basic_buffer< Allocator >& y)
+template < typename T, void* (*Allocator)(void*, std::size_t) >
+void swap(basic_buffer< T, Allocator >& x, basic_buffer< T, Allocator >& y)
 {
        x.swap(y);
 }