LCOV - code coverage report
Current view: top level - lunchbox - buffer.h (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 13 15 86.7 %
Date: 2018-10-03 05:33:11 Functions: 6 7 85.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #ifndef LUNCHBOX_BUFFER_H
      20             : #define LUNCHBOX_BUFFER_H
      21             : 
      22             : #include <lunchbox/debug.h> // LBASSERT macro
      23             : #include <lunchbox/os.h>    // setZero used inline
      24             : #include <lunchbox/types.h>
      25             : 
      26             : #include <cstdlib> // for malloc
      27             : #include <cstring> // for memcpy
      28             : 
      29             : namespace lunchbox
      30             : {
      31             : /**
      32             :  * A simple memory buffer with some helper functions.
      33             :  *
      34             :  * std::vector does not implement optimizations for growing bitwise-movable
      35             :  * vectors, i.e., it copy-constructs each element on growth.
      36             :  *
      37             :  * This buffer just memcpy's elements, i.e., it should only be used for PODs
      38             :  * since the copy constructor or assignment operator is not called on the copied
      39             :  * elements. Primarily used for binary data, e.g., in eq::Image. The
      40             :  * implementation works like a pool, that is, data is only released when the
      41             :  * buffer is deleted or clear() is called.
      42             :  */
      43             : template <class T>
      44             : class Buffer
      45             : {
      46             : public:
      47             :     /** Construct a new, empty buffer. @version 1.0 */
      48           1 :     Buffer()
      49             :         : _data(nullptr)
      50             :         , _size(0)
      51           1 :         , _maxSize(0)
      52             :     {
      53           1 :     }
      54             : 
      55             :     /** Construct a new buffer of the given size. @version 1.0 */
      56             :     explicit Buffer(const uint64_t size)
      57             :         : _data(0)
      58             :         , _size(0)
      59             :         , _maxSize(0)
      60             :     {
      61             :         reset(size);
      62             :     }
      63             : 
      64             :     /** Copy constructor, copies data to new Buffer. @version 1.14 */
      65             :     Buffer(const Buffer& from);
      66             : 
      67             :     /** Move constructor, transfers data to new Buffer. @version 1.14 */
      68             :     Buffer(Buffer&& from);
      69             : 
      70             :     /** Destruct the buffer. @version 1.0 */
      71           2 :     ~Buffer() { clear(); }
      72             :     /** Flush the buffer, deleting all data. @version 1.0 */
      73           2 :     void clear()
      74             :     {
      75           2 :         if (_data)
      76           0 :             free(_data);
      77           2 :         _data = 0;
      78           2 :         _size = 0;
      79           2 :         _maxSize = 0;
      80           2 :     }
      81             : 
      82             :     /**
      83             :      * Tighten the allocated memory to the size of the buffer.
      84             :      * @return the new pointer to the first element.
      85             :      * @version 1.0
      86             :      */
      87             :     T* pack();
      88             : 
      89             :     /** Assignment operator, copies data from Buffer. @version 1.0 */
      90             :     Buffer& operator=(const Buffer& from);
      91             : 
      92             :     /** Move operator, transfers ownership. @version 1.14 */
      93             :     Buffer& operator=(Buffer&& from);
      94             : 
      95             :     /** Direct access to the element at the given index. @version 1.0 */
      96             :     T& operator[](const uint64_t position)
      97             :     {
      98             :         LBASSERT(_size > position);
      99             :         return _data[position];
     100             :     }
     101             : 
     102             :     /** Direct const access to an element. @version 1.0 */
     103             :     const T& operator[](const uint64_t position) const
     104             :     {
     105             :         LBASSERT(_size > position);
     106             :         return _data[position];
     107             :     }
     108             : 
     109             :     /**
     110             :      * Ensure that the buffer contains at least newSize elements.
     111             :      *
     112             :      * Existing data is retained. The size is set.
     113             :      * @return the new pointer to the first element.
     114             :      * @version 1.0
     115             :      */
     116             :     T* resize(const uint64_t newSize);
     117             : 
     118             :     /**
     119             :      * Ensure that the buffer contains at least newSize elements.
     120             :      *
     121             :      * Existing data is retained. The size is increased, if necessary.
     122             :      * @version 1.0
     123             :      */
     124             :     void grow(const uint64_t newSize);
     125             : 
     126             :     /**
     127             :      * Ensure that the buffer contains at least newSize elements.
     128             :      *
     129             :      * Existing data is preserved.
     130             :      * @return the new pointer to the first element.
     131             :      * @version 1.0
     132             :      */
     133             :     T* reserve(const uint64_t newSize);
     134             : 
     135             :     /**
     136             :      * Set the buffer size and malloc enough memory.
     137             :      *
     138             :      * Existing data may be deleted.
     139             :      * @return the new pointer to the first element.
     140             :      * @version 1.0
     141             :      */
     142             :     T* reset(const uint64_t newSize);
     143             : 
     144             :     /** Set the buffer content to 0. @version 1.9.1 */
     145             :     void setZero() { ::lunchbox::setZero(_data, _size); }
     146             :     /** Append elements to the buffer, increasing the size. @version 1.0 */
     147             :     void append(const T* data, const uint64_t size);
     148             : 
     149             :     /** Append one element to the buffer. @version 1.0 */
     150             :     void append(const T& element);
     151             : 
     152             :     /** Replace the existing data with new data. @version 1.0 */
     153             :     void replace(const void* data, const uint64_t size);
     154             : 
     155             :     /** Replace the existing data. @version 1.5.1 */
     156           0 :     void replace(const Buffer& from) { replace(from._data, from._size); }
     157             :     /** Swap the buffer contents with another Buffer. @version 1.0 */
     158             :     void swap(Buffer& buffer);
     159             : 
     160             :     /** @return a pointer to the data. @version 1.0 */
     161           2 :     T* getData() { return _data; }
     162             :     /** @return a const pointer to the data. @version 1.0 */
     163             :     const T* getData() const { return _data; }
     164             :     /**
     165             :      * Set the size of the buffer without changing its allocation.
     166             :      *
     167             :      * This method only modifies the size parameter. If the current
     168             :      * allocation of the buffer is too small, it asserts, returns false and
     169             :      * does not change the size.
     170             :      * @version 1.0
     171             :      */
     172             :     bool setSize(const uint64_t size);
     173             : 
     174             :     /** @return the current number of elements. @version 1.0 */
     175           2 :     uint64_t getSize() const { return _size; }
     176             :     /** @return the current storage size. @version 1.5.1 */
     177             :     uint64_t getNumBytes() const { return _size * sizeof(T); }
     178             :     /** @return true if the buffer is empty, false if not. @version 1.0 */
     179           1 :     bool isEmpty() const { return (_size == 0); }
     180             :     /** @return the maximum size of the buffer. @version 1.0 */
     181             :     uint64_t getMaxSize() const { return _maxSize; }
     182             : private:
     183             :     /** A pointer to the data. */
     184             :     T* _data;
     185             : 
     186             :     /** The number of valid items in _data. */
     187             :     uint64_t _size;
     188             : 
     189             :     /** The allocation _size of the buffer. */
     190             :     uint64_t _maxSize;
     191             : };
     192             : }
     193             : 
     194             : #include "buffer.ipp" // template implementation
     195             : 
     196             : #endif // LUNCHBOX_BUFFER_H

Generated by: LCOV version 1.11