[/
            Copyright Hans Dembinski 2018 - 2019.
   Distributed under the Boost Software License, Version 1.0.
      (See accompanying file LICENSE_1_0.txt or copy at
            https://www.boost.org/LICENSE_1_0.txt)
]

[section:Axis 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 [@https://en.cppreference.com/w/cpp/named_req/CopyConstructible CopyConstructible], [@https://en.cppreference.com/w/cpp/named_req/CopyAssignable CopyAssignable], and *nothrow* [@https://en.cppreference.com/w/cpp/named_req/MoveAssignable 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 [link histogram.guide.expert.axis_multiple_value_types [*Guide]].]

[heading Associated Types]

* [link histogram.concepts.DiscreteAxis [*DiscreteAxis]]
* [link histogram.concepts.IntervalAxis [*IntervalAxis]]

[heading Required features]

* `A` is a type meeting the requirements of [*Axis]
* `a` is a value of type `A`
* `I` is an alias for [headerref boost/histogram/fwd.hpp `boost::histogram::axis::index_type`]

[table 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.
  ]
]
]

[heading 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 [headerref boost/histogram/fwd.hpp `boost::histogram::axis::index_type`]
* `n` is a value of type `unsigned`
* `M` is a metadata type that is [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible DefaultConstructible], [@https://en.cppreference.com/w/cpp/named_req/CopyConstructible CopyConstructible] and [@https://en.cppreference.com/w/cpp/named_req/CopyAssignable CopyAssignable]. It it supports moves, it must be *nothrow* [@https://en.cppreference.com/w/cpp/named_req/MoveAssignable MoveAssignable].
* `ar` is a value of an archive with Boost.Serialization semantics

[table 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, [funcref boost::histogram::algorithm::reduce] throws an exception on an attempt to reduce this axis.
  ]
]
[
  [`a.options()`]
  [`unsigned`]
  [
    Static constexpr member function which returns the [headerref boost/histogram/axis/option.hpp 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.
  ]
]
]

[heading Models]

* [classref boost::histogram::axis::boolean]
* [classref boost::histogram::axis::category]
* [classref boost::histogram::axis::integer]
* [classref boost::histogram::axis::regular]
* [classref boost::histogram::axis::variable]

[endsect]
