X-Git-Url: https://git.llucax.com/software/posixx.git/blobdiff_plain/5cc37d5e30b015c36f850c0d49a7da35c925c321..25e37c946dfa92e9a3676a022177afef06588a01:/src/basic_buffer.hpp?ds=inline diff --git a/src/basic_buffer.hpp b/src/basic_buffer.hpp index 494043f..14b880c 100644 --- a/src/basic_buffer.hpp +++ b/src/basic_buffer.hpp @@ -4,8 +4,10 @@ #include // std::bad_alloc, std::out_of_range #include // std::numeric_limits #include // std::tr1::is_integral, true_type, false_type +#include // std::realloc() #include // std::memcpy(), memset(), memcmp() #include // assert() +#include // 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& x, const basic_buffer & 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& x, const basic_buffer -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); }