liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2019 Hans Dembinski
//
// Distributed under the Boost Software License, version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
 
#ifndef BOOST_HISTOGRAM_ACCUMULATORS_NUMBER_HPP
#define BOOST_HISTOGRAM_ACCUMULATORS_NUMBER_HPP
 
#include <boost/core/nvp.hpp>
#include <boost/histogram/fwd.hpp> // for count<>
#include <type_traits>             // for std::common_type
 
namespace boost {
namespace histogram {
namespace accumulators {
 
/**
  Uses a C++ builtin arithmetic type to accumulate a count.
 
  This wrapper class may be used as a base class by users who want to add custom metadata
  to each bin of a histogram. Otherwise, arithmetic types should be used directly as
  accumulators in storages for simplicity. In other words, prefer `dense_storage<double>`
  over `dense_storage<count<double>>`, both are functionally equivalent.
 
  When weighted data is accumulated and high precision is required, use
  `accumulators::sum` instead. If a local variance estimate for the weight distribution
  should be computed as well (generally needed for a detailed statistical analysis), use
  `accumulators::weighted_sum`.
*/
template <class ValueType>
class count {
public:
  using value_type = ValueType;
  using const_reference = const value_type&;
 
  count() = default;
 
  /// Initialize count to value and allow implicit conversion
  count(const_reference value) noexcept : value_(value) {}
 
  /// Allow implicit conversion from other count
  template <class T>
  count(const count<T>& c) noexcept : count(c.value()) {}
 
  /// Increment count by one
  count& operator++() noexcept {
    ++value_;
    return *this;
  }
 
  /// Increment count by value
  count& operator+=(const_reference value) noexcept {
    value_ += value;
    return *this;
  }
 
  /// Add another count
  count& operator+=(const count& s) noexcept {
    value_ += s.value_;
    return *this;
  }
 
  /// Scale by value
  count& operator*=(const_reference value) noexcept {
    value_ *= value;
    return *this;
  }
 
  bool operator==(const count& rhs) const noexcept { return value_ == rhs.value_; }
 
  bool operator!=(const count& rhs) const noexcept { return !operator==(rhs); }
 
  /// Return count
  const_reference value() const noexcept { return value_; }
 
  // conversion to value_type must be explicit
  explicit operator value_type() const noexcept { return value_; }
 
  template <class Archive>
  void serialize(Archive& ar, unsigned /* version */) {
    ar& make_nvp("value", value_);
  }
 
  // begin: extra operators to make count behave like a regular number
 
  count& operator*=(const count& rhs) noexcept {
    value_ *= rhs.value_;
    return *this;
  }
 
  count operator*(const count& rhs) const noexcept {
    count x = *this;
    x *= rhs;
    return x;
  }
 
  count& operator/=(const count& rhs) noexcept {
    value_ /= rhs.value_;
    return *this;
  }
 
  count operator/(const count& rhs) const noexcept {
    count x = *this;
    x /= rhs;
    return x;
  }
 
  bool operator<(const count& rhs) const noexcept { return value_ < rhs.value_; }
 
  bool operator>(const count& rhs) const noexcept { return value_ > rhs.value_; }
 
  bool operator<=(const count& rhs) const noexcept { return value_ <= rhs.value_; }
 
  bool operator>=(const count& rhs) const noexcept { return value_ >= rhs.value_; }
 
  // end: extra operators
 
private:
  value_type value_{};
};
 
} // namespace accumulators
} // namespace histogram
} // namespace boost
 
#ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED
namespace std {
template <class T, class U>
struct common_type<boost::histogram::accumulators::count<T>,
                   boost::histogram::accumulators::count<U>> {
  using type = boost::histogram::accumulators::count<common_type_t<T, U>>;
};
} // namespace std
#endif
 
#endif