Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:43:48

0001 // Copyright 2020 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_MULTI_INDEX_HPP
0008 #define BOOST_HISTOGRAM_MULTI_INDEX_HPP
0009 
0010 #include <algorithm>
0011 #include <boost/histogram/detail/detect.hpp>
0012 #include <boost/histogram/detail/nonmember_container_access.hpp>
0013 #include <boost/histogram/fwd.hpp>
0014 #include <boost/mp11/integer_sequence.hpp>
0015 #include <boost/throw_exception.hpp>
0016 #include <initializer_list>
0017 #include <iterator>
0018 #include <stdexcept>
0019 #include <tuple>
0020 
0021 namespace boost {
0022 namespace histogram {
0023 
0024 /** Holder for multiple axis indices.
0025 
0026   Adapts external iterable, tuple, or explicit list of indices to the same representation.
0027  */
0028 template <std::size_t Size>
0029 struct multi_index {
0030   using value_type = axis::index_type;
0031   using iterator = value_type*;
0032   using const_iterator = const value_type*;
0033 
0034   static multi_index create(std::size_t s) {
0035     if (s != size())
0036       BOOST_THROW_EXCEPTION(std::invalid_argument("size does not match static size"));
0037     return multi_index(priv_tag{});
0038   }
0039 
0040   template <class... Is>
0041   multi_index(axis::index_type i, Is... is)
0042       : multi_index(std::initializer_list<axis::index_type>{
0043             i, static_cast<axis::index_type>(is)...}) {}
0044 
0045   template <class... Is>
0046   multi_index(const std::tuple<axis::index_type, Is...>& is)
0047       : multi_index(is, mp11::make_index_sequence<(1 + sizeof...(Is))>{}) {}
0048 
0049   template <class Iterable, class = detail::requires_iterable<Iterable>>
0050   multi_index(const Iterable& is) {
0051     if (detail::size(is) != size())
0052       BOOST_THROW_EXCEPTION(std::invalid_argument("no. of axes != no. of indices"));
0053     using std::begin;
0054     using std::end;
0055     std::copy(begin(is), end(is), data_);
0056   }
0057 
0058   iterator begin() noexcept { return data_; }
0059   iterator end() noexcept { return data_ + size(); }
0060   const_iterator begin() const noexcept { return data_; }
0061   const_iterator end() const noexcept { return data_ + size(); }
0062   static constexpr std::size_t size() noexcept { return Size; }
0063 
0064 private:
0065   struct priv_tag {};
0066 
0067   multi_index(priv_tag) {}
0068 
0069   template <class T, std::size_t... Is>
0070   multi_index(const T& is, mp11::index_sequence<Is...>)
0071       : multi_index(static_cast<axis::index_type>(std::get<Is>(is))...) {}
0072 
0073   axis::index_type data_[size()];
0074 };
0075 
0076 template <>
0077 struct multi_index<static_cast<std::size_t>(-1)> {
0078   using value_type = axis::index_type;
0079   using iterator = value_type*;
0080   using const_iterator = const value_type*;
0081 
0082   static multi_index create(std::size_t s) { return multi_index(priv_tag{}, s); }
0083 
0084   template <class... Is>
0085   multi_index(axis::index_type i, Is... is)
0086       : multi_index(std::initializer_list<axis::index_type>{
0087             i, static_cast<axis::index_type>(is)...}) {}
0088 
0089   template <class... Is>
0090   multi_index(const std::tuple<axis::index_type, Is...>& is)
0091       : multi_index(is, mp11::make_index_sequence<(1 + sizeof...(Is))>{}) {}
0092 
0093   template <class Iterable, class = detail::requires_iterable<Iterable>>
0094   multi_index(const Iterable& is) : size_(detail::size(is)) {
0095     using std::begin;
0096     using std::end;
0097     std::copy(begin(is), end(is), data_);
0098   }
0099 
0100   iterator begin() noexcept { return data_; }
0101   iterator end() noexcept { return data_ + size_; }
0102   const_iterator begin() const noexcept { return data_; }
0103   const_iterator end() const noexcept { return data_ + size_; }
0104   std::size_t size() const noexcept { return size_; }
0105 
0106 private:
0107   struct priv_tag {};
0108 
0109   multi_index(priv_tag, std::size_t s) : size_(s) {}
0110 
0111   template <class T, std::size_t... Ns>
0112   multi_index(const T& is, mp11::index_sequence<Ns...>)
0113       : multi_index(static_cast<axis::index_type>(std::get<Ns>(is))...) {}
0114 
0115   std::size_t size_ = 0;
0116   static constexpr std::size_t max_size_ = BOOST_HISTOGRAM_DETAIL_AXES_LIMIT;
0117   axis::index_type data_[max_size_];
0118 };
0119 
0120 } // namespace histogram
0121 } // namespace boost
0122 
0123 #endif