| 390 | */ |
| 391 | template <typename IntType, typename Allocator> |
| 392 | class integer : public labeled_base<Allocator>, |
| 393 | public iterator_mixin<integer<IntType, Allocator>> { |
| 394 | using base_type = labeled_base<Allocator>; |
| 395 | |
| 396 | public: |
| 397 | using allocator_type = typename base_type::allocator_type; |
| 398 | using value_type = IntType; |
| 399 | using bin_type = interval_view<integer>; |
| 400 | |
| 401 | /** Construct axis over a semi-open integer interval [lower, upper). |
| 402 | * |
| 403 | * \param lower smallest integer of the covered range. |
| 404 | * \param upper largest integer of the covered range. |
| 405 | * \param label description of the axis. |
| 406 | * \param uoflow whether to add under-/overflow bins. |
| 407 | */ |
| 408 | integer(value_type lower, value_type upper, string_view label = {}, |
| 409 | uoflow_type uo = uoflow_type::on, const allocator_type& a = allocator_type()) |
| 410 | : base_type(upper - lower, uo, label, a), min_(lower) { |
| 411 | if (!(lower < upper)) { throw std::invalid_argument("lower < upper required"); } |
| 412 | } |
| 413 | |
| 414 | integer() = default; |
| 415 | integer(const integer&) = default; |
| 416 | integer& operator=(const integer&) = default; |
| 417 | integer(integer&&) = default; |
| 418 | integer& operator=(integer&&) = default; |
| 419 | |
| 420 | /// Returns the bin index for the passed argument. |
| 421 | int index(value_type x) const noexcept { |
| 422 | const int z = x - min_; |
| 423 | return z >= 0 ? (z > base_type::size() ? base_type::size() : z) : -1; |
| 424 | } |
| 425 | |
| 426 | /// Returns lower edge of the integral bin. |
| 427 | value_type lower(int i) const noexcept { |
| 428 | if (i < 0) { return -std::numeric_limits<value_type>::max(); } |
| 429 | if (i > base_type::size()) { return std::numeric_limits<value_type>::max(); } |
| 430 | return min_ + i; |
| 431 | } |
| 432 | |
| 433 | bin_type operator[](int idx) const noexcept { return bin_type(idx, *this); } |
| 434 | |
| 435 | bool operator==(const integer& o) const noexcept { |
| 436 | return base_type::operator==(o) && min_ == o.min_; |
| 437 | } |
| 438 | |
| 439 | private: |
| 440 | value_type min_ = 0; |
| 441 | |
| 442 | friend class ::boost::serialization::access; |
| 443 | template <class Archive> |
| 444 | void serialize(Archive&, unsigned); |
| 445 | }; |
| 446 | |
| 447 | /** Axis which maps unique values to bins (one on one). |
| 448 | * |
no outgoing calls