<commit_before>/**
 * @file
 */
#pragma once

#include "libbirch/external.hpp"
#include "libbirch/thread.hpp"

namespace libbirch {
/**
 * Buffer for storing the contents of an array. Buffer objects are shared
 * between arrays with copy-on-write semantics, and overallocated to contain
 * bookkeeping variables, as well as the contents of the buffer itself, in
 * the one allocation. They do not inherit from Countable, as their reference
 * counting semantics are simpler.
 *
 * @ingroup libbirch
 */
template<class T>
class Buffer {
public:
  /**
   * Constructor.
   */
  Buffer();

  /**
   * Copy constructor.
   */
  Buffer(const Buffer<T>& o) = delete;

  /**
   * Assignment operator.
   */
  Buffer<T>& operator=(const Buffer<T>&) = delete;

  /**
   * Increment the usage count.
   */
  void incUsage();

  /**
   * Decrement the usage count.
   *
   * @return Use count.
   */
  unsigned decUsage();

  /**
   * Usage count.
   */
  unsigned numUsage() const;

  /**
   * Get the start of the buffer.
   */
  T* buf();

  /**
   * Get the start of the buffer.
   */
  const T* buf() const;

  /**
   * Compute the number of bytes that should be allocated for a buffer of
   * this type with @p n elements.
   */
  static int64_t size(const int64_t n);

  /**
   * Id of the thread that allocated the buffer.
   */
  unsigned tid;

private:
  /**
   * Use count (the number of arrays sharing this buffer).
   */
  std::atomic<unsigned> useCount;

  /**
   * First element in the buffer. Taking the address of this gives a pointer
   * to the start of the overallocated buffer.
   */
  alignas(T) char first;
};
}

template<class T>
libbirch::Buffer<T>::Buffer() :
    tid(libbirch::tid),
    useCount(0) {
  //
}

template<class T>
void libbirch::Buffer<T>::incUsage() {
  useCount.fetch_add(1u, std::memory_order_relaxed);
}

template<class T>
unsigned libbirch::Buffer<T>::decUsage() {
  assert(useCount > 0);
  return useCount.fetch_sub(1u, std::memory_order_relaxed) - 1u;
}

template<class T>
unsigned libbirch::Buffer<T>::numUsage() const {
  return useCount.load();<commit_msg>Updated Buffer to use new Atomic class in place of std::atomic.<commit_after>/**
 * @file
 */
#pragma once

#include "libbirch/external.hpp"
#include "libbirch/thread.hpp"
#include "libbirch/Atomic.hpp"

namespace libbirch {
/**
 * Buffer for storing the contents of an array. Buffer objects are shared
 * between arrays with copy-on-write semantics, and overallocated to contain
 * bookkeeping variables, as well as the contents of the buffer itself, in
 * the one allocation. They do not inherit from Countable, as their reference
 * counting semantics are simpler.
 *
 * @ingroup libbirch
 */
template<class T>
class Buffer {
public:
  /**
   * Constructor.
   */
  Buffer();

  /**
   * Copy constructor.
   */
  Buffer(const Buffer<T>& o) = delete;

  /**
   * Assignment operator.
   */
  Buffer<T>& operator=(const Buffer<T>&) = delete;

  /**
   * Increment the usage count.
   */
  void incUsage();

  /**
   * Decrement the usage count.
   *
   * @return Use count.
   */
  unsigned decUsage();

  /**
   * Usage count.
   */
  unsigned numUsage() const;

  /**
   * Get the start of the buffer.
   */
  T* buf();

  /**
   * Get the start of the buffer.
   */
  const T* buf() const;

  /**
   * Compute the number of bytes that should be allocated for a buffer of
   * this type with @p n elements.
   */
  static int64_t size(const int64_t n);

  /**
   * Id of the thread that allocated the buffer.
   */
  unsigned tid;

private:
  /**
   * Use count (the number of arrays sharing this buffer).
   */
  Atomic<unsigned> useCount;

  /**
   * First element in the buffer. Taking the address of this gives a pointer
   * to the start of the overallocated buffer.
   */
  alignas(T) char first;
};
}

template<class T>
libbirch::Buffer<T>::Buffer() :
    tid(libbirch::tid),
    useCount(0) {
  //
}

template<class T>
void libbirch::Buffer<T>::incUsage() {
  ++useCount;
}

template<class T>
unsigned libbirch::Buffer<T>::decUsage() {
  assert(useCount.load() > 0);
  return --useCount;
}

template<class T>
unsigned libbirch::Buffer<T>::numUsage() const {
  return useCount.load();
{'fraction_non_alphanumeric': 0.13174224343675417, 'fraction_numerical': 0.003579952267303103, 'mean_word_length': 3.014367816091954, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2598616', 'n_tokens_mistral': 1409, 'n_tokens_neox': 1358, 'n_words': 438}