| Home | Libraries | People | FAQ | More

## Concepts

Users can extend the library with various new types whose concepts are defined here.

### Axis

An Axis maps input values to indices. It holds state specific to that axis, like the number of bins and any metadata. Must be CopyConstructible, CopyAssignable, and nothrow MoveAssignable.

| Note
`Axis::index` cannot be templated or overloaded. This is by design, but also a limitation of the internal code used to detect generic user-defined axes. A workaround for making an axis that accepts multiple value types is described in the Guide.

##### Associated Types

- DiscreteAxis
- IntervalAxis

##### Required features

- `A` is a type meeting the requirements of Axis
- `a` is a value of type `A`
- `I` is an alias for `boost::histogram::axis::index_type`

Table 1.1. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`a.size()` | `I` | Const member function which returns the number of bins of the axis. All indices from `0` to `a.size() - 1` must be valid and address a bin of the axis.
`a.index(v)` | `I` | Const member function which maps a value `v` to an index. The mapping must be injective: each value must be uniquely mapped to one index. If the value is not covered by the axis, return either `-1` or `a.size()`. The value `-1` indicates that the value is lower than the lowest value covered by the axis. The value `a.size()` indicates that the value is above the uppermost value covered by the axis. By convention, NaN-values are mapped to `a.size()`.
`a.get_allocator()` | `Alloc` | Const member function which returns the allocator `Alloc` used by this axis. May be omitted if `A` does not use allocators. If this member function exists, also a special constructor must exists so that `A(a.get_allocator())` is a valid expression.

##### Optional features

- `A` is a type meeting the requirements of Axis
- `a` and `b` are values of type `A`
- `i` and `j` are indices of type `boost::histogram::axis::index_type`
- `n` is a value of type `unsigned`
- `M` is a metadata type that is DefaultConstructible, CopyConstructible and CopyAssignable. It it supports moves, it must be nothrow MoveAssignable.
- `ar` is a value of an archive with Boost.Serialization semantics

Table 1.2. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`a.update(v)` | `std::pair<I, I>` | Non-const member function which maps a value to an index (first argument of the returned pair) and offset (second argument of the returned pair). If the value is not covered by the axis, this method may grow the current axis size (`old_size`) by the number of bins needed to contain the value or more (`new_size`). If the value is below the lowest value covered by the axis, return index `0` and offset `new_size - old_size`. If the value is above the uppermost value covered by the axis, return index `new_size - 1` and a negative offset `old_size - new_size`. If the value is outside, but the axis is not enlarged, then return an index equivalent to `a.index(v)` and offset `0`.
`A(a, i, j, n)` |  | Special constructor used by the reduce algorithm. `a` is the original axis instance, `i` and `j` are the index range to keep in the reduced axis. If `n` is larger than 1, `n` adjacent bins are merged into one larger cell. If this constructor is not implemented, `boost::histogram::algorithm::reduce` throws an exception on an attempt to reduce this axis.
`a.options()` | `unsigned` | Static constexpr member function which returns the `axis options` for this axis.
`a.inclusive()` | `bool` | Static constexpr member function which returns true, if the axis has a bin for every possible input value, and false otherwise. Faster code can be generated if all axes types in a histogram are inclusive. An axis with underflow and overflow bins is always inclusive. An axis may be inclusive even if underflow or overflow bins are missing. For example, a category axis is inclusive if either it has an overflow bin or if it is growing.
`a.metadata()` | `M&` | Const and non-const member functions must exist, which both returns a mutable reference to the metadata associated with the axis (usually a string).
`a == b` | `bool` | Returns `true` if all state variables compare equal, including any metadata. Otherwise returns `false`. If `a == b` is implemented, also `a != b` must be implemented. If this binary operator is not implemented, the library considers the axes equal if their types are the same.
`a != b` | `bool` | Must be implemented if `a == b` is implemented and must be equal to `!(a == b)`.
`os << a` | `std::basic_ostream<CharT, Traits>&` | `os` is a value of type `std::basic_ostream<CharT, Traits>`. Streams a text representation of the axis. May not mutate `a`.
`a.serialize(ar, n)` |  | Saves to the archive or loads serialised state from the archive. The version number `n` is the stored version when the object is loaded or the current version when the object is saved.

##### Models

- `boost::histogram::axis::boolean`
- `boost::histogram::axis::category`
- `boost::histogram::axis::integer`
- `boost::histogram::axis::regular`
- `boost::histogram::axis::variable`

### DiscreteAxis

A DiscreteAxis is one of two optional refinements of the Axis concept, the other one is the IntervalAxis. This concept is for axes in which each bin represents a single value instead of an interval.

Discrete axes can be further divided into ordered and unordered. An axis is ordered, when bin indices i < j < k imply that value[i] < value[j] < value[k] or value[i] > value[j] > value[k] for all i, j, k. The `integer axis` is ordered and the `category axis` is unordered.

An unordered discrete axis cannot have an underflow bin. Since there is no order, one can have at most one extra bin that counts values not handled by the axis. By convention the overflow bin is used for that.

##### Associated Types

- Axis
- IntervalAxis

##### Optional features

- `A` is a type meeting the requirements of DiscreteAxis
- `a` is a value of type `A`
- `V` is the type accepted for conversion into an index
- `v` is a value of type `V`
- `i` is a value of type `boost::histogram::axis::index_type`
- `AxisIter` is an RandomAccessIterator over the bins of `A`
- `ReAxisIter` is a reverse RandomAccessIterator over the bins of `A`

Table 1.3. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`a.ordered()` | `bool` | Static constexpr member function which returns true if the axis is ordered and false otherwise. If this is absent, the library checks whether the value type is arithmetic instead, see `boost::histogram::axis::traits::ordered`.
`a.value(i)` | `V` | Const member function which maps an index to a value. The mapping must be injective: each index must be uniquely mapped to one value. The effect must be exactly the inverse of `a.index(v)`. The return value may be a const reference, if the lifetime of the referred object is equal to the lifetime of the axis.
`a.bin(i)` | `V` | Must have the same effect as `a.value(i)`.
`s.begin()` | `AxisIter` | Const member function which return an iterator to the bin with index `0`.
`s.end()` | `AxisIter` | Const member function which returns an iterator to the bin with index `s.size()`.
`s.rbegin()` | `ReAxisIter` | Const member function which return a reverse iterator to the bin with index `s.size()-1`.
`s.rend()` | `ReAxisIter` | Const member function which returns an iterator to the bin with index `-1`.

| Tip
The complete iterator interface can be added to a user-defined axis which implements `a.bin(i)` by inheriting from the `iterator_mixin`.

##### Models

- `boost::histogram::axis::category`
- `boost::histogram::axis::integer`, if first template parameter is `int`

### IntervalAxis

A IntervalAxis is one of two optional refinements of the Axis concept, the other one is the DiscreteAxis. It is for ordered values that form intervals with a well-defined lower and upper edge, and a center. Each bin represents an interval of values.

##### Associated Types

- Axis
- DiscreteAxis

##### Optional features

- `A` is a type meeting the requirements of IntervalAxis
- `a` is a value of type `A`
- `V` is the type accepted for conversion into an index
- `B` is the type that represents the bin interval
- `v` is a value of type `V`
- `i` is a value of type `boost::histogram::axis::index_type`
- `j` is a value of type `boost::histogram::axis::real_index_type`
- `AxisIter` is an RandomAccessIterator over the bins of `A`
- `ReAxisIter` is a reverse RandomAccessIterator over the bins of `A`

Table 1.4. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`a.value(i)` | `V` | Const member function which maps an index to a value. The mapping must be injective: each index must be uniquely mapped to one value. The result of `a.value(a.index(v))` should agree to very high precision with `v` (the mapping may not be exact due to the finite precision of floating point computations). The return value may be a const reference, if the lifetime of the referred object is equal to the lifetime of the axis. `a.value(j)` is expected to return the lower edge of the bin, `a.value(j+1)` the upper edge, and `a.value(j + 0.5)` the center.
`a.bin(i)` | `B` | Const member function which returns an instance that represents the current bin. Nothing about the type is required, but it is recommended that the type has the methods `B::lower()`, `B::upper()`, and `B::center()` similar to the types used by the builtin axis models. The return value may be a const reference, if the lifetime of the referred object is equal to the lifetime of the axis.
`s.begin()` | `AxisIter` | Const member function which return an iterator to the bin with index `0`.
`s.end()` | `AxisIter` | Const member function which returns an iterator to the bin with index `s.size()`.
`s.rbegin()` | `ReAxisIter` | Const member function which return a reverse iterator to the bin with index `s.size()-1`.
`s.rend()` | `ReAxisIter` | Const member function which returns an iterator to the bin with index `-1`.

| Tip
The complete iterator interface can be added to a user-defined axis which implements `a.bin(i)` by inheriting from the `iterator_mixin`.

##### Models

- `boost::histogram::axis::regular`
- `boost::histogram::axis::variable`
- `boost::histogram::axis::integer`, if first template parameter is a floating point type

### Transform

A Transform implements a monotonic mapping between two real-valued domains, external and internal. It is used to extend the `regular axis`. The bins in the internal domain are of equal width, while the bins in the external domain are non-equal width. Must be DefaultConstructible, CopyConstructible, and CopyAssignable.

##### Required features

- `T` is a type meeting the requirements of Transform
- `t` is a value of type `T`
- `X` is a type with the semantics of a floating-point type
- `x` is a value of type `X`
- `Y` is a floating-point type
- `y` is a value of type `Y`

Table 1.5. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`t.forward(x)` | `Y` | Const or static member function which maps the external value to the corresponding internal value. The return type `Y` may differ from `X`.
`t.inverse(y)` | `X` | Const or static member function which maps the internal value to the corresponding external value. The result of `t.inverse(t.forward(x))` must be approximately equal to `x` within floating-point precision.
`t == u` | `bool` | `u` is another value of type `T`. Returns `true` if both values have the same state. Otherwise returns `false`. May be omitted if `T` is stateless. If this binary operator is not implemented, the library considers the arguments equal, if and only if their types are the same.

##### Optional features

- `T` is a type meeting the requirements of Transform
- `t` is a value of type `T`
- `ar` is a value of an archive with Boost.Serialization semantics

Table 1.6. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`t.serialize(ar, n)` |  | `ar` is a value of an archive with Boost.Serialization semantics and `n` is an unsigned integral value. Saves to the archive or loads serialized state from the archive. The version number `n` is the stored version when the object is loaded or the current version when the object is saved.

##### Models

- `boost::histogram::axis::transform::id`
- `boost::histogram::axis::transform::log`
- `boost::histogram::axis::transform::sqrt`
- `boost::histogram::axis::transform::pow`

### Storage

A Storage handles memory for the bin counters and provides a uniform vector-like interface for accessing cell values for reading and writing. Must be DefaultConstructible, CopyConstructible, and CopyAssignable.

##### Required features

- `S` is a type meeting the requirements of Storage
- `s` is a value of types `S`
- `i` and `n` are values of type `std::size_t`
- `Alloc` is an allocator type for `S`

Table 1.7. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`S::value_type` |  | Cell element type, may be either an integral type, floating-point type, or a type meeting the requirements of Accumulator.
`S::reference` |  | `S::value_type&` or a proxy class which acts like a reference.
`S::const_reference` |  | `const S::value_type&` or a proxy class which acts like a const reference. Implicitly convertible to `S::value_type`.
`S::iterator` |  | Returns an STL-compliant iterator type which dereferences to `S::reference`.
`S::const_iterator` |  | Returns an STL-compliant iterator type which dereferences to `S::const_reference`.
`S::has_threading_support` | bool | Static constexpr member. True, if storage supports parallel read-write access to all cells. False, if such parallel access would either cause data corruption or require synchronization so that effectively only one cell can be accessed at a time, making cell-access single-threaded.
`s.size()` | `std::size_t` | Const member function which returns the current number of cells in the storage.
`s.reset(n)` |  | Non-const member function which discards current cell values, changes storage size to `n` and initializes all cells to the default-constructed state.
`s.begin()` | `S::iterator` | Non-const member function which returns the iterator to the first storage cell.
`s.begin()` | `S::const_iterator` | Likewise, but a const member function which returns the const_iterator.
`s.end()` | `S::iterator` | Member function which returns the iterator to the cell after the last valid storage cell.
`s.end()` | `S::const_iterator` | Likewise, but a const member function which returns the const_iterator.
`s[i]` | `S::reference` | Member function which returns a reference to the cell which is addressed by `i`. The index `i` must be valid: `i < s.size()`.
`s[i]` | `S::const_reference` | Likewise, but a const member function which returns a const reference.
`s == t` | `bool` | `t` is another value of a type which meets the requirements of Storage. Returns `true` if arguments have the same number of cells and all cells compare equal. Otherwise returns `false`.
`s.get_allocator()` | `Alloc` | Const member function which returns the allocator used by `S`. Must be omitted if `S` does not use allocators. If this member function exists, also a special constructor must exist so that `S(s.get_allocator())` is a valid expression.

##### Optional features

- `S` is a type meeting the requirements of Storage
- `s` is a value of types `S`
- `x` is convertible to `double`
- `ar` is a value of an archive with Boost.Serialization semantics

Table 1.8. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`s *= x` | `S&` | Scales all cell values by the factor `x` and returns a reference to self.
`s.serialize(ar, n)` |  | `ar` is a value of an archive with Boost.Serialization semantics and `n` is an unsigned integral value. Saves to the archive or loads serialized state from the archive. The version number `n` is the stored version when the object is loaded or the current version when the object is saved.

##### Models

- `boost::histogram::unlimited_storage`
- `boost::histogram::storage_adaptor`
- `boost::histogram::dense_storage`
- `boost::histogram::weight_storage`
- `boost::histogram::profile_storage`
- `boost::histogram::weighted_profile_storage`

### Accumulator

An Accumulator is a functor which consumes the argument to update some internal state. Must be DefaultConstructible, CopyConstructible, and CopyAssignable.

##### Required features

- `A` is a type meeting the requirements of Accumulator
- `a` and `b` are values of type `A`
- `ts...` is a pack of values of arbitrary types

Table 1.9. Valid expressions

Expression | Returns | Semantics, Pre/Post-conditions
--- | --- | ---
`a(ts...)` or `++a` |  | Either a call operator accepting a fixed number of arguments must be implemented, or the pre-increment operator. The call operator form `a(ts...)` may not be templated and not overloaded, except to support weights as described under optional features.
`a == b` | `bool` | Returns `true` if all state variables compare equal. Otherwise returns `false`.
`a != b` | `bool` | Must be implemented if `a == b` is implemented and must be equal to `!(a == b)`.

##### Optional features

- `A` is a type meeting the requirements of Accumulator
- `a` and `b` are values of type `A`
- `w` is a value of type `boost::histogram::weight_type`
- `ts...` is a pack of values of arbitrary types

Table 1.10. Valid expressions

Expression | Return | Semantics, Pre/Post-conditions
--- | --- | ---
`a += w` or `a(w, ts...)` |  | Does a weighted fill of the accumulator. Use this to implement weight support for an accumulator that is normally filled with `++a` or `a(ts...)`, respectively. Only the corresponding matching form may be implemented: `a += w` for `++a`, `a(w, ts...)` for `a(ts...)`. The call operator form `a(w, ts...)` may not be templated and not overloaded.
`a += b` | `A&` | Adds a second accumulator `b` of type `A`. The result must be the same as if `a` had been filled with all arguments of `b`.
`a *= x` | `A&` | Scales the accumulator state by the real value `x`. The result must be the same as if `a` had been filled with all arguments scaled by `x`.
`os << a` | `std::basic_ostream<CharT, Traits>&` | `os` is a value of type `std::basic_ostream<CharT, Traits>`. Streams a text representation of the axis. May not mutate `a`.
`a.serialize(ar, n)` |  | `ar` is a value of an archive with Boost.Serialization semantics and `n` is an unsigned integral value. Saves to the archive or loads serialized state from the archive. The version number `n` is the stored version when the object is loaded or the current version when the object is saved.

##### Models

- `boost::histogram::accumulators::sum`
- `boost::histogram::accumulators::weighted_sum`
- `boost::histogram::accumulators::mean`
- `boost::histogram::accumulators::weighted_mean`
- `boost::histogram::accumulators::collector`