3#ifndef AWKWARD_GROWABLEBUFFER_H_ 
    4#define AWKWARD_GROWABLEBUFFER_H_ 
   21  template <
template <
class...> 
class TT, 
class... Args>
 
   23  template <
template <
class...> 
class TT>
 
   26  template <
template <
class...> 
class TT, 
class T>
 
   29  template <
typename PRIMITIVE>
 
   41        : ptr_(std::unique_ptr<PRIMITIVE[]>(new PRIMITIVE[
reserved])),
 
 
   52        : ptr_(std::move(ptr)),
 
 
   62      for (std::unique_ptr<Panel> current = std::move(next_);
 
   64           current = std::move(current->next_));
 
 
   68    PRIMITIVE& 
operator[](
size_t i) { 
return ptr_.get()[i]; }
 
   74      next_ = std::move(std::unique_ptr<Panel>(
new Panel(
reserved)));
 
 
   81      ptr_.get()[length_++] = datum;
 
 
   85    std::unique_ptr<Panel>&
 
  103    std::unique_ptr<PRIMITIVE[]>&
 
  116    append(PRIMITIVE* to_ptr, 
size_t offset, 
size_t from, int64_t length) 
const noexcept {
 
  117      memcpy(to_ptr + offset,
 
  118             reinterpret_cast<void*
>(ptr_.get() + from),
 
  119             length * 
sizeof(PRIMITIVE) - from);
 
 
  131      memcpy(to_ptr + offset,
 
  132             reinterpret_cast<void*
>(ptr_.get() + from),
 
  133             length_ * 
sizeof(PRIMITIVE) - from);
 
  135        next_->concatenate_to(to_ptr, offset + length_);
 
 
  147      memcpy(to_ptr + offset,
 
  148             reinterpret_cast<void*
>(ptr_.get()),
 
  149             length_ * 
sizeof(PRIMITIVE));
 
  151        next_->concatenate_to(to_ptr, offset + length_);
 
 
  159    template <
typename TO_PRIMITIVE>
 
  164    copy_as(TO_PRIMITIVE* to_ptr, 
size_t offset) {
 
  165      for (
size_t i = 0; i < length_; i++) {
 
  166        to_ptr[offset++] = 
static_cast<TO_PRIMITIVE
>(ptr_.get()[i]);
 
  169        next_->copy_as(to_ptr, offset);
 
 
  173    template <
typename TO_PRIMITIVE>
 
  174    typename std::enable_if<!awkward::is_tt<std::complex, TO_PRIMITIVE>::value &&
 
  176    copy_as(TO_PRIMITIVE* to_ptr, 
size_t offset) {
 
  177      for (
size_t i = 0; i < length_; i++) {
 
  178        to_ptr[offset++] = 
static_cast<TO_PRIMITIVE
>(ptr_.get()[i].real());
 
  179        to_ptr[offset++] = 
static_cast<TO_PRIMITIVE
>(ptr_.get()[i].imag());
 
  182        next_->copy_as(to_ptr, offset);
 
 
  191    template <
typename TO_PRIMITIVE>
 
  192    typename std::enable_if<awkward::is_tt<std::complex, TO_PRIMITIVE>::value &&
 
  194    copy_as(TO_PRIMITIVE* to_ptr, 
size_t offset) {
 
  195      for (
size_t i = 0; i < length_; i++) {
 
  196        double val = 
static_cast<double>(ptr_.get()[i]);
 
  197        to_ptr[offset++] = TO_PRIMITIVE(val);
 
  200        next_->copy_as(to_ptr, offset);
 
 
  206    std::unique_ptr<PRIMITIVE[]> ptr_;
 
  215    std::unique_ptr<Panel> next_;
 
 
  232  template <
typename PRIMITIVE>
 
  251      int64_t actual = 
options.initial();
 
  252      if (actual < minreserve) {
 
  257          std::unique_ptr<PRIMITIVE[]>(
new PRIMITIVE[(
size_t)actual]),
 
 
  272      int64_t actual = 
options.initial();
 
  276      auto ptr = std::unique_ptr<PRIMITIVE[]>(
new PRIMITIVE[(
size_t)actual]);
 
  277      PRIMITIVE* rawptr = ptr.get();
 
  278      for (int64_t i = 0; i < 
length; i++) {
 
 
  296      int64_t actual = 
options.initial();
 
  300      auto ptr = std::unique_ptr<PRIMITIVE[]>(
new PRIMITIVE[(
size_t)actual]);
 
  301      PRIMITIVE* rawptr = ptr.get();
 
  302      for (int64_t i = 0; i < 
length; i++) {
 
 
  319      int64_t actual = 
options.initial();
 
  323      auto ptr = std::unique_ptr<PRIMITIVE[]>(
new PRIMITIVE[(
size_t)actual]);
 
  324      PRIMITIVE* rawptr = ptr.get();
 
  325      for (int64_t i = 0; i < 
length; i++) {
 
  326        rawptr[i] = (PRIMITIVE)i;
 
 
  336    template <
typename TO_PRIMITIVE>
 
  339      int64_t len = (int64_t)other.
length();
 
  341          (len < other.options_.
initial()) ? other.options_.
initial() : len;
 
  350          std::unique_ptr<TO_PRIMITIVE[]>(
new TO_PRIMITIVE[(
size_t)actual]);
 
  351      TO_PRIMITIVE* rawptr = ptr.get();
 
  353      other.panel_->copy_as(rawptr, 0);
 
 
  373                   std::unique_ptr<PRIMITIVE[]> ptr,
 
  378          panel_(std::unique_ptr<
Panel<PRIMITIVE>>(new 
Panel<PRIMITIVE>(
 
  379              std::move(ptr), (size_t)
length, (size_t)reserved))),
 
  380          ptr_(panel_.get()) {}
 
 
  388                         std::unique_ptr<PRIMITIVE[]>(
 
  389                             new PRIMITIVE[(size_t)
options.initial()]),
 
 
  397        : options_(other.options_),
 
  398          length_(other.length_),
 
  399          panel_(std::move(other.panel_)),
 
 
  409      return length_ + ptr_->current_length();
 
 
  431      if (ptr_->current_length() == 0) {
 
  432        throw std::runtime_error(
"Buffer is empty");
 
  434        return (*ptr_)[ptr_->current_length() - 1];
 
 
  441      return length() * 
sizeof(PRIMITIVE);
 
 
  451      if (ptr_->current_length() == ptr_->reserved()) {
 
  452        add_panel((
size_t)ceil(options_.initial() * options_.resize()));
 
 
  464    extend(
const PRIMITIVE* ptr, 
size_t size) {
 
  465      size_t unfilled_items = ptr_->reserved() - ptr_->current_length();
 
  466      if (size > unfilled_items) {
 
  467        for (
size_t i = 0; i < unfilled_items; i++) {
 
  470        add_panel(size - unfilled_items > ptr_->reserved() ? size - unfilled_items
 
  472        for (
size_t i = unfilled_items; i < size; i++) {
 
  476        for (
size_t i = 0; i < size; i++) {
 
 
  486      return (*ptr_)[ptr_->current_length() - 1];
 
 
  493      if (external_pointer) {
 
  494        panel_->concatenate_to(external_pointer, 0);
 
 
  503      size_t next_offset = 0;
 
  505        memcpy(to_ptr + next_offset,
 
  506               reinterpret_cast<void*
>(panel_.get()->data().get()),
 
  507               panel_.get()->current_length() * 
sizeof(PRIMITIVE));
 
  508        next_offset += panel_.get()->current_length();
 
  509        panel_ = std::move(panel_.get()->next());
 
 
  518      if (external_pointer) {
 
  519        panel_->concatenate_to_from(external_pointer, to, from);
 
 
  525    append(PRIMITIVE* external_pointer, 
size_t offset, 
size_t from, int64_t 
length) 
const noexcept {
 
  526      if (external_pointer) {
 
  527        panel_->append(external_pointer, offset, from, 
length);
 
 
  534    fill_panel(PRIMITIVE datum) {
 
  535      ptr_->fill_panel(datum);
 
  541    add_panel(
size_t reserved) {
 
  542      length_ += ptr_->current_length();
 
  543      ptr_ = ptr_->append_panel(reserved);
 
  553    std::unique_ptr<Panel<PRIMITIVE>> panel_;
 
  558    Panel<PRIMITIVE>* ptr_;
 
 
Discontiguous, one-dimensional buffer (which consists of multiple contiguous, one-dimensional panels)...
Definition GrowableBuffer.h:233
 
static GrowableBuffer< PRIMITIVE > zeros(const BuilderOptions &options, int64_t length)
Creates a GrowableBuffer in which all elements are initialized to 0.
Definition GrowableBuffer.h:271
 
void extend(const PRIMITIVE *ptr, size_t size)
Inserts an entire array into the panel(s), possibly triggering allocation of a new panel.
Definition GrowableBuffer.h:464
 
static GrowableBuffer< TO_PRIMITIVE > copy_as(const GrowableBuffer< PRIMITIVE > &other)
Takes a (possibly multi-panels) GrowableBuffer<PRIMITIVE> and makes another (one panel) GrowableBuffe...
Definition GrowableBuffer.h:338
 
PRIMITIVE last() const
Last element in last panel.
Definition GrowableBuffer.h:430
 
void concatenate_from(PRIMITIVE *external_pointer, size_t to, size_t from) const noexcept
Copies and concatenates all accumulated data from multiple panels to one contiguously allocated exter...
Definition GrowableBuffer.h:517
 
size_t nbytes() const
Currently used number of bytes.
Definition GrowableBuffer.h:440
 
GrowableBuffer(GrowableBuffer &&other) noexcept
Move constructor.
Definition GrowableBuffer.h:396
 
static GrowableBuffer< PRIMITIVE > full(const BuilderOptions &options, PRIMITIVE value, int64_t length)
Creates a GrowableBuffer in which all elements are initialized to a given value.
Definition GrowableBuffer.h:295
 
const BuilderOptions & options() const
Return options of this GrowableBuffer.
Definition GrowableBuffer.h:414
 
void concatenate(PRIMITIVE *external_pointer) const noexcept
Copies and concatenates all accumulated data from multiple panels to one contiguously allocated exter...
Definition GrowableBuffer.h:492
 
PRIMITIVE & append_and_get_ref(PRIMITIVE datum)
Like append, but the type signature returns the reference to PRIMITIVE.
Definition GrowableBuffer.h:484
 
size_t length() const
Currently used number of elements.
Definition GrowableBuffer.h:408
 
static GrowableBuffer< PRIMITIVE > empty(const BuilderOptions &options, int64_t minreserve)
Creates an empty GrowableBuffer with a minimum reservation.
Definition GrowableBuffer.h:250
 
void append(PRIMITIVE datum)
Inserts one datum into the panel, possibly triggering allocation of a new panel.
Definition GrowableBuffer.h:450
 
static GrowableBuffer< PRIMITIVE > arange(const BuilderOptions &options, int64_t length)
Creates a GrowableBuffer in which the elements are initialized to numbers counting from 0 to length.
Definition GrowableBuffer.h:318
 
void append(PRIMITIVE *external_pointer, size_t offset, size_t from, int64_t length) const noexcept
Copies data from a panel to one contiguously allocated external_pointer.
Definition GrowableBuffer.h:525
 
GrowableBuffer(const BuilderOptions &options, std::unique_ptr< PRIMITIVE[]> ptr, int64_t length, int64_t reserved)
Creates a GrowableBuffer from a full set of parameters.
Definition GrowableBuffer.h:372
 
static GrowableBuffer< PRIMITIVE > empty(const BuilderOptions &options)
Creates an empty GrowableBuffer.
Definition GrowableBuffer.h:239
 
void clear()
Discards accumulated data, the #reserved returns to options.initial(), and a new #ptr is allocated.
Definition GrowableBuffer.h:421
 
void move_to(PRIMITIVE *to_ptr) noexcept
Moves all accumulated data from multiple panels to one contiguously allocated external_pointer....
Definition GrowableBuffer.h:502
 
GrowableBuffer(const BuilderOptions &options)
Creates a GrowableBuffer by allocating a new buffer, taking an options #reserved from options.
Definition GrowableBuffer.h:386
 
Definition GrowableBuffer.h:33
 
void fill_panel(PRIMITIVE datum)
Inserts one datum into the panel.
Definition GrowableBuffer.h:80
 
Panel * append_panel(size_t reserved)
Creates a new panel with slots equal to reserved and appends it after the current panel.
Definition GrowableBuffer.h:73
 
Panel(std::unique_ptr< PRIMITIVE[]> ptr, size_t length, size_t reserved)
Creates a Panel from a full set of parameters.
Definition GrowableBuffer.h:51
 
size_t current_length()
Currently used number of elements in the panel.
Definition GrowableBuffer.h:92
 
std::unique_ptr< Panel > & next()
Pointer to the next panel.
Definition GrowableBuffer.h:86
 
size_t reserved()
Currently allocated number of elements in the panel.
Definition GrowableBuffer.h:98
 
std::enable_if< awkward::is_tt< std::complex, TO_PRIMITIVE >::value &&!awkward::is_tt< std::complex, PRIMITIVE >::value >::type copy_as(TO_PRIMITIVE *to_ptr, size_t offset)
'copy_as' specialization of a 'std::complex' template type. Fills (one panel) GrowableBuffer<std::com...
Definition GrowableBuffer.h:194
 
void append(PRIMITIVE *to_ptr, size_t offset, size_t from, int64_t length) const noexcept
Copies the data from a panel to one contiguously allocated to_ptr.
Definition GrowableBuffer.h:116
 
~Panel()
Deletes a Panel.
Definition GrowableBuffer.h:61
 
std::unique_ptr< PRIMITIVE[]> & data()
Unique pointer to the panel data.
Definition GrowableBuffer.h:104
 
void concatenate_to_from(PRIMITIVE *to_ptr, size_t offset, size_t from) const noexcept
Copies and concatenates the accumulated data from multiple panels ptr_ to one contiguously allocated ...
Definition GrowableBuffer.h:130
 
std::enable_if<!awkward::is_tt< std::complex, TO_PRIMITIVE >::value &&awkward::is_tt< std::complex, PRIMITIVE >::value >::type copy_as(TO_PRIMITIVE *to_ptr, size_t offset)
Definition GrowableBuffer.h:176
 
Panel(size_t reserved)
Creates a Panel by allocating a new panel, taking a reserved number of slots.
Definition GrowableBuffer.h:40
 
std::enable_if<(!awkward::is_tt< std::complex, TO_PRIMITIVE >::value &&!awkward::is_tt< std::complex, PRIMITIVE >::value)||(awkward::is_tt< std::complex, TO_PRIMITIVE >::value &&awkward::is_tt< std::complex, PRIMITIVE >::value)>::type copy_as(TO_PRIMITIVE *to_ptr, size_t offset)
Fills (one panel) GrowableBuffer<TO_PRIMITIVE> with the elements of (possibly multi-panels) GrowableB...
Definition GrowableBuffer.h:164
 
PRIMITIVE & operator[](size_t i)
Overloads [] operator to access elements like an array.
Definition GrowableBuffer.h:68
 
void concatenate_to(PRIMITIVE *to_ptr, size_t offset) const noexcept
Copies and concatenates the accumulated data from multiple panels ptr_ to one contiguously allocated ...
Definition GrowableBuffer.h:146
 
Definition ArrayBuilder.h:14
 
std::true_type is_tt_impl(TT< Args... >)
 
Options< int64_t, double > BuilderOptions
Definition BuilderOptions.h:56
 
decltype(is_tt_impl< TT >(std::declval< typename std::decay< T >::type >())) is_tt
Definition GrowableBuffer.h:27
 
int64_t initial() const noexcept
The initial number of reserved entries for a GrowableBuffer.
Definition BuilderOptions.h:34
 
double resize() const noexcept
The factor with which a GrowableBuffer is resized when its length reaches its reserved.
Definition BuilderOptions.h:42