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 : #include <limits>
6 : #include <mutex>
7 : #include <shared_mutex>
8 : #include <stdexcept>
9 : #include <unordered_map>
10 :
11 : #include "scipp/common/index.h"
12 : #include "scipp/units/dim.h"
13 :
14 : namespace scipp::units {
15 :
16 : namespace {
17 956173 : const auto &builtin_ids() {
18 : static std::unordered_map<std::string, Dim::Id> ids{
19 : {"<invalid>", Dim::Invalid},
20 : {"<none>", Dim::None},
21 : {"<internal_structure_component>", Dim::InternalStructureComponent},
22 : {"<internal_structure_row>", Dim::InternalStructureRow},
23 : {"<internal_structure_column>", Dim::InternalStructureColumn},
24 : {"<internal_histogram>", Dim::InternalHistogram},
25 : {"<internal_sort>", Dim::InternalSort},
26 : {"<internal_accumulate>", Dim::InternalAccumulate},
27 : {"energy", Dim::Energy},
28 : {"event", Dim::Event},
29 : {"group", Dim::Group},
30 : {"position", Dim::Position},
31 : {"row", Dim::Row},
32 : {"temperature", Dim::Temperature},
33 : {"time", Dim::Time},
34 : {"wavelength", Dim::Wavelength},
35 : {"x", Dim::X},
36 : {"y", Dim::Y},
37 956287 : {"z", Dim::Z}};
38 956111 : return ids;
39 : }
40 :
41 1094928 : auto &custom_ids() {
42 1094928 : static std::unordered_map<std::string, Dim::Id> ids;
43 1093859 : return ids;
44 : }
45 :
46 : std::shared_mutex mutex;
47 : } // namespace
48 :
49 430993 : Dim::Dim(const std::string &label) {
50 430993 : if (const auto it = builtin_ids().find(label); it != builtin_ids().end()) {
51 42043 : m_id = it->second;
52 42043 : return;
53 : }
54 386133 : std::shared_lock read_lock(mutex);
55 386888 : if (const auto it = custom_ids().find(label); it != custom_ids().end()) {
56 383885 : m_id = it->second;
57 383553 : return;
58 : }
59 2221 : read_lock.unlock();
60 2221 : const std::unique_lock write_lock(mutex);
61 2221 : const auto id = scipp::size(custom_ids()) + 1000;
62 2221 : if (id > std::numeric_limits<std::underlying_type<Id>::type>::max())
63 0 : throw std::runtime_error(
64 0 : "Exceeded maximum number of different dimension labels.");
65 2221 : m_id = static_cast<Id>(id);
66 2221 : custom_ids()[label] = m_id;
67 385774 : }
68 :
69 427428 : std::string Dim::name() const {
70 427428 : if (static_cast<int64_t>(m_id) < 1000)
71 799529 : for (const auto &item : builtin_ids())
72 799529 : if (item.second == m_id)
73 99115 : return item.first;
74 328313 : const std::shared_lock read_lock(mutex);
75 31856966 : for (const auto &item : custom_ids())
76 31856052 : if (item.second == m_id)
77 327202 : return item.first;
78 0 : return "unreachable"; // throw or terminate?
79 328386 : }
80 :
81 22431 : std::string to_string(const Dim dim) { return dim.name(); }
82 :
83 : } // namespace scipp::units
|