Line data Source code
1 : // SPDX-License-Identifier: BSD-3-Clause 2 : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp) 3 : /// @file 4 : /// @author Simon Heybrock 5 : #pragma once 6 : 7 : #include <array> 8 : 9 : // Warnings are raised by boost small_vector with gcc12 10 : #pragma GCC diagnostic push 11 : #pragma GCC diagnostic ignored "-Wstringop-overread" 12 : #include <boost/container/small_vector.hpp> 13 : #pragma GCC diagnostic pop 14 : 15 : #include "scipp-core_export.h" 16 : #include "scipp/common/index.h" 17 : #include "scipp/common/span.h" 18 : #include "scipp/core/slice.h" 19 : #include "scipp/units/dim.h" 20 : 21 : namespace scipp::core { 22 : 23 : /// Maximum number of dimensions supported by transform-based operations 24 : constexpr int32_t NDIM_OP_MAX = 6; 25 : /// Number of dimension labels/sizes/strides storable without heap allocation 26 : constexpr int32_t NDIM_STACK = 4; 27 : 28 : class Dimensions; 29 : 30 : /// Small (fixed maximum size) and stable (preserving key order) map 31 : template <class Key, class Value, int16_t Capacity> 32 : class SCIPP_CORE_EXPORT small_stable_map { 33 : public: 34 : static constexpr auto capacity = Capacity; 35 : 36 26032178 : small_stable_map() = default; 37 : 38 : bool operator==(const small_stable_map &other) const noexcept; 39 : bool operator!=(const small_stable_map &other) const noexcept; 40 : 41 37354809 : [[nodiscard]] auto begin() const noexcept { return m_keys.begin(); } 42 93961174 : [[nodiscard]] auto end() const noexcept { return m_keys.begin() + size(); } 43 0 : [[nodiscard]] auto rbegin() const noexcept { 44 0 : return std::reverse_iterator(end()); 45 : } 46 0 : [[nodiscard]] auto rend() const noexcept { 47 0 : return std::reverse_iterator(begin()); 48 : } 49 : [[nodiscard]] 50 : typename boost::container::small_vector<Key, Capacity>::const_iterator 51 : find(const Key &key) const; 52 433555 : [[nodiscard]] bool empty() const noexcept { return size() == 0; } 53 268843452 : [[nodiscard]] scipp::index size() const noexcept { return m_keys.size(); } 54 : [[nodiscard]] bool contains(const Key &key) const; 55 : [[nodiscard]] scipp::index index(const Key &key) const; 56 : [[nodiscard]] const Value &operator[](const Key &key) const; 57 : [[nodiscard]] const Value &at(const Key &key) const; 58 : void assign(const Key &key, const Value &value); 59 : void insert_left(const Key &key, const Value &value); 60 : void insert_right(const Key &key, const Value &value); 61 : void erase(const Key &key); 62 : void clear() noexcept; 63 : void replace_key(const Key &from, const Key &to); 64 15454267 : [[nodiscard]] scipp::span<const Key> keys() const &noexcept { 65 30908534 : return {m_keys.data(), static_cast<size_t>(size())}; 66 : } 67 35387513 : [[nodiscard]] scipp::span<const Value> values() const &noexcept { 68 70775026 : return {m_values.data(), static_cast<size_t>(size())}; 69 : } 70 : 71 : private: 72 : boost::container::small_vector<Key, Capacity> m_keys{}; 73 : boost::container::small_vector<Value, Capacity> m_values{}; 74 : }; 75 : 76 : /// Similar to class Dimensions but without implied ordering 77 : class SCIPP_CORE_EXPORT Sizes 78 : : public small_stable_map<Dim, scipp::index, NDIM_STACK> { 79 : private: 80 : using base = small_stable_map<Dim, scipp::index, NDIM_STACK>; 81 : 82 : protected: 83 : using base::assign; 84 : using base::insert_left; 85 : using base::insert_right; 86 : 87 : public: 88 13016089 : Sizes() noexcept = default; 89 : 90 : void set(const Dim dim, const scipp::index size); 91 : void resize(const Dim dim, const scipp::index size); 92 : [[nodiscard]] bool includes(const Sizes &sizes) const; 93 : [[nodiscard]] Sizes slice(const Slice ¶ms) const; 94 : 95 : /// Return the labels of the space defined by *this. 96 15454267 : [[nodiscard]] auto labels() const &noexcept { return keys(); } 97 : /// Return the shape of the space defined by *this. 98 35387513 : [[nodiscard]] auto sizes() const &noexcept { return values(); } 99 : 100 : [[nodiscard]] Sizes rename_dims(const std::vector<std::pair<Dim, Dim>> &names, 101 : const bool fail_on_unknown = true) const; 102 : }; 103 : 104 : [[nodiscard]] SCIPP_CORE_EXPORT Sizes 105 : concat(const scipp::span<const Sizes> sizes, const Dim dim); 106 : 107 : [[nodiscard]] SCIPP_CORE_EXPORT Sizes merge(const Sizes &a, const Sizes &b); 108 : 109 : SCIPP_CORE_EXPORT bool is_edges(const Sizes &sizes, const Sizes &dataSizes, 110 : const Dim dim); 111 : 112 : } // namespace scipp::core 113 : 114 : namespace scipp { 115 : using core::Sizes; 116 : }