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