Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:46:53

0001 // Copyright 2019 Hans Dembinski
0002 //
0003 // Distributed under the Boost Software License, Version 1.0.
0004 // (See accompanying file LICENSE_1_0.txt
0005 // or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_HISTOGRAM_DETAIL_STATIC_VECTOR_HPP
0008 #define BOOST_HISTOGRAM_DETAIL_STATIC_VECTOR_HPP
0009 
0010 #include <algorithm>
0011 #include <boost/throw_exception.hpp>
0012 #include <stdexcept>
0013 
0014 namespace boost {
0015 namespace histogram {
0016 namespace detail {
0017 
0018 // A crude implementation of boost::container::static_vector.
0019 // Like std::vector, but with static allocation up to a maximum capacity.
0020 template <class T, std::size_t N>
0021 class static_vector {
0022   // Cannot inherit from std::array, since this confuses span.
0023   static constexpr bool swap_element_is_noexcept() noexcept {
0024     using std::swap;
0025     return noexcept(swap(std::declval<T&>(), std::declval<T&>()));
0026   }
0027 
0028 public:
0029   using element_type = T;
0030   using size_type = std::size_t;
0031   using reference = T&;
0032   using const_reference = const T&;
0033   using pointer = T*;
0034   using const_pointer = const T*;
0035   using iterator = pointer;
0036   using const_iterator = const_pointer;
0037 
0038   static_vector() = default;
0039 
0040   explicit static_vector(std::size_t s) noexcept : size_(s) { assert(size_ <= N); }
0041 
0042   static_vector(std::size_t s, const T& value) noexcept(
0043       std::is_nothrow_assignable<T, const_reference>::value)
0044       : static_vector(s) {
0045     fill(value);
0046   }
0047 
0048   static_vector(std::initializer_list<T> il) noexcept(
0049       std::is_nothrow_assignable<T, const_reference>::value)
0050       : static_vector(il.size()) {
0051     std::copy(il.begin(), il.end(), data_);
0052   }
0053 
0054   reference at(size_type pos) noexcept {
0055     if (pos >= size()) BOOST_THROW_EXCEPTION(std::out_of_range{"pos is out of range"});
0056     return data_[pos];
0057   }
0058 
0059   const_reference at(size_type pos) const noexcept {
0060     if (pos >= size()) BOOST_THROW_EXCEPTION(std::out_of_range{"pos is out of range"});
0061     return data_[pos];
0062   }
0063 
0064   reference operator[](size_type pos) noexcept { return data_[pos]; }
0065   const_reference operator[](size_type pos) const noexcept { return data_[pos]; }
0066 
0067   reference front() noexcept { return data_[0]; }
0068   const_reference front() const noexcept { return data_[0]; }
0069 
0070   reference back() noexcept { return data_[size_ - 1]; }
0071   const_reference back() const noexcept { return data_[size_ - 1]; }
0072 
0073   pointer data() noexcept { return static_cast<pointer>(data_); }
0074   const_pointer data() const noexcept { return static_cast<const_pointer>(data_); }
0075 
0076   iterator begin() noexcept { return data_; }
0077   const_iterator begin() const noexcept { return data_; }
0078 
0079   iterator end() noexcept { return begin() + size_; }
0080   const_iterator end() const noexcept { return begin() + size_; }
0081 
0082   const_iterator cbegin() const noexcept { return data_; }
0083   const_iterator cend() const noexcept { return cbegin() + size_; }
0084 
0085   constexpr size_type max_size() const noexcept { return N; }
0086   size_type size() const noexcept { return size_; }
0087   bool empty() const noexcept { return size_ == 0; }
0088 
0089   void fill(const_reference value) noexcept(
0090       std::is_nothrow_assignable<T, const_reference>::value) {
0091     std::fill(begin(), end(), value);
0092   }
0093 
0094   void swap(static_vector& other) noexcept(swap_element_is_noexcept()) {
0095     using std::swap;
0096     const size_type s = (std::max)(size(), other.size());
0097     for (auto i = begin(), j = other.begin(), end = begin() + s; i != end; ++i, ++j)
0098       swap(*i, *j);
0099     swap(size_, other.size_);
0100   }
0101 
0102 private:
0103   size_type size_ = 0;
0104   element_type data_[N];
0105 };
0106 
0107 template <class T, std::size_t N>
0108 bool operator==(const static_vector<T, N>& a, const static_vector<T, N>& b) noexcept {
0109   return std::equal(a.begin(), a.end(), b.begin(), b.end());
0110 }
0111 
0112 template <class T, std::size_t N>
0113 bool operator!=(const static_vector<T, N>& a, const static_vector<T, N>& b) noexcept {
0114   return !(a == b);
0115 }
0116 
0117 } // namespace detail
0118 } // namespace histogram
0119 } // namespace boost
0120 
0121 namespace std {
0122 template <class T, std::size_t N>
0123 void swap(
0124     ::boost::histogram::detail::static_vector<T, N>& a,
0125     ::boost::histogram::detail::static_vector<T, N>& b) noexcept(noexcept(a.swap(b))) {
0126   a.swap(b);
0127 }
0128 } // namespace std
0129 
0130 #endif