File indexing completed on 2026-08-17 08:46:52
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_HISTOGRAM_DETAIL_CHUNK_VECTOR_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_CHUNK_VECTOR_HPP
0009
0010 #include <boost/core/span.hpp>
0011 #include <boost/throw_exception.hpp>
0012 #include <stdexcept>
0013 #include <vector>
0014
0015 namespace boost {
0016 namespace histogram {
0017 namespace detail {
0018
0019
0020
0021
0022
0023 template <class ValueType>
0024 class chunk_vector {
0025 public:
0026 using base = std::vector<ValueType>;
0027 using allocator_type = typename base::allocator_type;
0028 using pointer = typename base::pointer;
0029 using const_pointer = typename base::const_pointer;
0030 using size_type = typename base::size_type;
0031 using const_reference = boost::span<const ValueType>;
0032 using reference = boost::span<ValueType>;
0033
0034
0035
0036 using value_type = const_reference;
0037
0038 template <class Pointer>
0039 struct iterator_t {
0040 iterator_t& operator++() {
0041 ptr_ += chunk_;
0042 return *this;
0043 }
0044
0045 iterator_t operator++(int) {
0046 iterator_t copy(*this);
0047 ptr_ += chunk_;
0048 return copy;
0049 }
0050
0051 value_type operator*() const { return value_type(ptr_, ptr_ + chunk_); }
0052
0053 Pointer ptr_;
0054 size_type chunk_;
0055 };
0056
0057 using iterator = iterator_t<pointer>;
0058 using const_iterator = iterator_t<const_pointer>;
0059
0060
0061 explicit chunk_vector(size_type chunk, const allocator_type& alloc = {})
0062 : chunk_(chunk), vec_(alloc) {}
0063
0064 chunk_vector(std::initializer_list<value_type> list, size_type chunk,
0065 const allocator_type& alloc = {})
0066 : chunk_(chunk), vec_(list, alloc) {}
0067
0068 allocator_type get_allocator() noexcept(noexcept(allocator_type())) {
0069 return vec_.get_allocator();
0070 }
0071
0072 void push_back(const_reference x) {
0073 if (x.size() != chunk_)
0074 BOOST_THROW_EXCEPTION(std::runtime_error("argument has wrong size"));
0075
0076 for (auto&& elem : x) vec_.push_back(elem);
0077 }
0078
0079 auto insert(const_iterator pos, const_iterator o_begin, const_iterator o_end) {
0080 if (std::distance(o_begin, o_end) % chunk_ == 0)
0081 BOOST_THROW_EXCEPTION(std::runtime_error("argument has wrong size"));
0082 return vec_.insert(pos, o_begin, o_end);
0083 }
0084
0085 const_iterator begin() const noexcept { return {vec_.data(), chunk_}; }
0086 const_iterator end() const noexcept { return {vec_.data() + vec_.size(), chunk_}; }
0087
0088 value_type operator[](size_type idx) const noexcept {
0089 return {vec_.data() + idx * chunk_, vec_.data() + (idx + 1) * chunk_};
0090 }
0091
0092 size_type size() const noexcept { return vec_.size() / chunk_; }
0093
0094 private:
0095 size_type chunk_;
0096 base vec_;
0097 };
0098
0099 }
0100 }
0101 }
0102
0103 #endif