Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Class template unlimited_storage

boost::histogram::unlimited_storage — Memory-efficient storage for integral counters which cannot overflow.

Synopsis

// In header: <boost/histogram/unlimited_storage.hpp>

template<typename Allocator> 
class unlimited_storage {
public:
  // types
  typedef Allocator                                                          allocator_type; 
  typedef double                                                             value_type;     
  typedef unspecified                                                        mp_int;         
  typedef reference_t< const buffer_type >                                   const_reference;
  typedef iterator_t< const value_type, const_reference, const buffer_type > const_iterator; 
  typedef iterator_t< value_type, reference, buffer_type >                   iterator;       

  // member classes/structs/unions

  struct adder {

    // public member functions
    template<typename Buffer, typename U> 
      void operator()(double *, Buffer &, std::size_t, const U &);
    template<typename T, typename Buffer, typename U> 
      void operator()(T *, Buffer &, std::size_t, const U &);
    template<typename T, typename Buffer, typename U> 
      void U_is_integral(std::false_type, T *, Buffer &, std::size_t, 
                         const U &);
    template<typename T, typename Buffer, typename U> 
      void U_is_integral(std::true_type, T *, Buffer &, std::size_t, 
                         const U &);
    template<typename T, typename Buffer, typename U> 
      void U_is_unsigned_integral(std::false_type, T *, Buffer &, std::size_t, 
                                  const U &);
    template<typename Buffer, typename U> 
      void U_is_unsigned_integral(std::true_type, mp_int *, Buffer &, 
                                  std::size_t, const U &);
    template<typename T, typename Buffer, typename U> 
      void U_is_unsigned_integral(std::true_type, T *, Buffer &, std::size_t, 
                                  const U &);
  };

  struct buffer_type {
    // construct/copy/destruct
    buffer_type(allocator_type = {});
    buffer_type(buffer_type &&) noexcept;
    buffer_type(const buffer_type &);
    buffer_type & operator=(buffer_type &&) noexcept;
    buffer_type & operator=(const buffer_type &);
    ~buffer_type();

    // public member functions
    template<typename F, class... Ts> 
      decltype(auto) apply(F &&, Ts &&...) const;
    void destroy() noexcept;
    template<typename T> void make(std::size_t);
    template<typename T, typename U> void make(std::size_t, U);

    // public data members
    allocator_type alloc;
    std::size_t size;
    char type;
    void * ptr;
  };

  struct incrementor {

    // public member functions
    template<typename T, typename Buffer> 
      void operator()(T *, Buffer &, std::size_t);
    template<typename Buffer> void operator()(mp_int *, Buffer &, std::size_t);
    template<typename Buffer> void operator()(double *, Buffer &, std::size_t);
  };
  template<typename Value, typename Reference, typename Buffer> 
  class iterator_t : public boost::iterator_adaptor< iterator_t< Value, Reference, Buffer >, std::size_t, Value, std::random_access_iterator_tag, Reference, std::ptrdiff_t >
  {
  public:
    // construct/copy/destruct
    iterator_t() = default;
    template<typename V, typename R, typename B> 
      iterator_t(const iterator_t< V, R, B > &);
    iterator_t(Buffer *, std::size_t) noexcept;

    // protected member functions
    template<typename V, typename R, typename B> 
      bool equal(const iterator_t< V, R, B > &) const noexcept;
    Reference dereference() const;
  };

  struct multiplier {

    // public member functions
    template<typename T, typename Buffer> 
      void operator()(T *, Buffer &, const double);
    template<typename Buffer> 
      void operator()(double *, Buffer &, const double);
    template<typename T, typename Buffer, typename U> 
      void operator()(T *, Buffer &, std::size_t, const U &);
    template<typename Buffer, typename U> 
      void operator()(double *, Buffer &, std::size_t, const U &);
  };

  class reference :
    public boost::histogram::unlimited_storage< buffer_type >::reference_t
  {
  public:
    // construct/copy/destruct
    reference operator=(reference);
    reference operator=(const_reference);
    template<typename U> reference operator=(const U &);

    // public member functions
    template<typename U> reference operator+=(const U &);
    template<typename U> reference operator *=(const U &);
    template<typename U> reference operator-=(const U &);
    template<typename U> reference operator/=(const U &);
    reference operator++();
    bool operator<(reference) const;
    bool operator>(reference) const;
    bool operator==(reference) const;
  };
  template<typename Buffer> 
  class reference_t {
  public:
    // construct/copy/destruct
    reference_t(Buffer *, std::size_t);
    reference_t(const reference_t &) = default;
    reference_t & operator=(const reference_t &) = delete;
    reference_t & operator=(reference_t &&) = delete;

    // public member functions
    bool operator<(reference_t) const;
    bool operator>(reference_t) const;
    bool operator==(reference_t) const;
    template<typename U> bool operator<(const U &) const;
    template<typename U> bool operator>(const U &) const;
    template<typename U> bool operator==(const U &) const;
    operator double() const;

    // protected member functions
    template<typename Binary, typename U> 
      bool op(const reference_t< U > &) const;
    template<typename Binary, typename U> bool op(const U &) const;
  };

  // construct/copy/destruct
  explicit unlimited_storage(allocator_type = {});
  unlimited_storage(const unlimited_storage &) = default;
  unlimited_storage(unlimited_storage &&) = default;
  template<typename T> unlimited_storage(const storage_adaptor< T > &);
  template<typename T> 
    unlimited_storage(std::size_t, const T *, allocator_type = {});
  unlimited_storage & operator=(const unlimited_storage &) = default;
  unlimited_storage & operator=(unlimited_storage &&) = default;
  template<typename Iterable, 
           typename  = detail::requires_iterable<Iterable> > 
    unlimited_storage & operator=(const Iterable &);

  // private static functions
  template<typename T> static constexpr char type_index() noexcept;

  // public member functions
  allocator_type get_allocator() const;
  void reset(std::size_t);
  std::size_t size() const noexcept;
  reference operator[](std::size_t) noexcept;
  const_reference operator[](std::size_t) const noexcept;
  bool operator==(const unlimited_storage &) const noexcept;
  template<typename T> bool operator==(const T &) const;
  unlimited_storage & operator *=(const double);
  iterator begin() noexcept;
  iterator end() noexcept;
  const_iterator begin() const noexcept;
  const_iterator end() const noexcept;
  template<typename Archive> void serialize(Archive &, unsigned);
};

Description

This storage provides a no-overflow-guarantee if it is filled with integral weights only. This storage implementation keeps a contiguous array of elemental counters, one for each cell. If an operation is requested, which would overflow a counter, the whole array is replaced with another of a wider integral type, then the operation is executed. The storage uses integers of 8, 16, 32, 64 bits, and then switches to a multiprecision integral type, similar to those in Boost.Multiprecision.

A scaling operation or adding a floating point number turns the elements into doubles, which voids the no-overflow-guarantee.

unlimited_storage public construct/copy/destruct

  1. explicit unlimited_storage(allocator_type a = {});
  2. unlimited_storage(const unlimited_storage &) = default;
  3. unlimited_storage(unlimited_storage &&) = default;
  4. template<typename T> unlimited_storage(const storage_adaptor< T > & s);
  5. template<typename T> 
      unlimited_storage(std::size_t s, const T * p, allocator_type a = {});
    used by unit tests, not part of generic storage interface
  6. unlimited_storage & operator=(const unlimited_storage &) = default;
  7. unlimited_storage & operator=(unlimited_storage &&) = default;
  8. template<typename Iterable, typename  = detail::requires_iterable<Iterable> > 
      unlimited_storage & operator=(const Iterable & s);

unlimited_storage private static functions

  1. template<typename T> static constexpr char type_index() noexcept;

unlimited_storage public member functions

  1. allocator_type get_allocator() const;
  2. void reset(std::size_t s);
  3. std::size_t size() const noexcept;
  4. reference operator[](std::size_t i) noexcept;
  5. const_reference operator[](std::size_t i) const noexcept;
  6. bool operator==(const unlimited_storage & o) const noexcept;
  7. template<typename T> bool operator==(const T & o) const;
  8. unlimited_storage & operator *=(const double x);
  9. iterator begin() noexcept;
  10. iterator end() noexcept;
  11. const_iterator begin() const noexcept;
  12. const_iterator end() const noexcept;
  13. template<typename Archive> void serialize(Archive &, unsigned);

PrevUpHomeNext