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 963032 : 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 963146 : {"z", Dim::Z}};
38 963021 : return ids;
39 : }
40 :
41 1107116 : auto &custom_ids() {
42 1107116 : static std::unordered_map<std::string, Dim::Id> ids;
43 1106394 : return ids;
44 : }
45 :
46 : std::shared_mutex mutex;
47 : } // namespace
48 :
49 434248 : Dim::Dim(const std::string &label) {
50 434248 : if (const auto it = builtin_ids().find(label); it != builtin_ids().end()) {
51 42491 : m_id = it->second;
52 42491 : return;
53 : }
54 388942 : std::shared_lock read_lock(mutex);
55 389679 : if (const auto it = custom_ids().find(label); it != custom_ids().end()) {
56 386832 : m_id = it->second;
57 386442 : return;
58 : }
59 2146 : read_lock.unlock();
60 2146 : const std::unique_lock write_lock(mutex);
61 2146 : const auto id = scipp::size(custom_ids()) + 1000;
62 2146 : 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 2146 : m_id = static_cast<Id>(id);
66 2146 : custom_ids()[label] = m_id;
67 388588 : }
68 :
69 435327 : std::string Dim::name() const {
70 435327 : if (static_cast<int64_t>(m_id) < 1000)
71 811080 : for (const auto &item : builtin_ids())
72 811080 : if (item.second == m_id)
73 99812 : return item.first;
74 335515 : const std::shared_lock read_lock(mutex);
75 30014465 : for (const auto &item : custom_ids())
76 30013298 : if (item.second == m_id)
77 334047 : return item.first;
78 0 : return "unreachable"; // throw or terminate?
79 335270 : }
80 :
81 22401 : std::string to_string(const Dim dim) { return dim.name(); }
82 :
83 : } // namespace scipp::units
|