PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
dicom_dataset.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
17#pragma once
18
19#include "dicom_element.h"
20#include "dicom_tag.h"
21
23
24#include <initializer_list>
25#include <map>
26#include <optional>
27#include <span>
28#include <string>
29#include <string_view>
30#include <type_traits>
31
32namespace kcenon::pacs::core {
33
66public:
68 using storage_type = std::map<dicom_tag, dicom_element>;
69
71 using iterator = storage_type::iterator;
72
74 using const_iterator = storage_type::const_iterator;
75
76 // ========================================================================
77 // Construction
78 // ========================================================================
79
83 dicom_dataset() = default;
84
88 dicom_dataset(const dicom_dataset&) = default;
89
93 dicom_dataset(dicom_dataset&&) noexcept = default;
94
98 auto operator=(const dicom_dataset&) -> dicom_dataset& = default;
99
103 auto operator=(dicom_dataset&&) noexcept -> dicom_dataset& = default;
104
108 ~dicom_dataset() = default;
109
110 // ========================================================================
111 // Element Access
112 // ========================================================================
113
119 [[nodiscard]] auto contains(dicom_tag tag) const noexcept -> bool;
120
126 [[nodiscard]] auto get(dicom_tag tag) noexcept -> dicom_element*;
127
133 [[nodiscard]] auto get(dicom_tag tag) const noexcept -> const dicom_element*;
134
135 // ========================================================================
136 // Convenience Accessors
137 // ========================================================================
138
145 [[nodiscard]] auto get_string(dicom_tag tag,
146 std::string_view default_value = "") const
147 -> std::string;
148
155 template <typename T>
156 requires std::is_arithmetic_v<T>
157 [[nodiscard]] auto get_numeric(dicom_tag tag) const -> std::optional<T>;
158
159 // ========================================================================
160 // Sequence Access
161 // ========================================================================
162
168 [[nodiscard]] auto has_sequence(dicom_tag tag) const noexcept -> bool;
169
185 [[nodiscard]] auto get_sequence(dicom_tag tag) const noexcept
186 -> const std::vector<dicom_dataset>*;
187
193 [[nodiscard]] auto get_sequence(dicom_tag tag) noexcept
194 -> std::vector<dicom_dataset>*;
195
204 [[nodiscard]] auto get_or_create_sequence(dicom_tag tag)
205 -> std::vector<dicom_dataset>&;
206
207 // ========================================================================
208 // Private Tag Access
209 // ========================================================================
210
220 [[nodiscard]] auto get_private_creator(dicom_tag private_data_tag) const
221 -> std::optional<std::string>;
222
233 [[nodiscard]] auto get_private_block(std::string_view creator_id,
234 uint16_t group) const
235 -> std::vector<const dicom_element*>;
236
254 auto set_private_element(std::string_view creator_id, uint16_t group,
255 uint8_t element_offset, encoding::vr_type vr,
256 std::string_view value) -> std::optional<dicom_tag>;
257
268 auto remove_private_block(std::string_view creator_id, uint16_t group)
269 -> size_t;
270
275 auto cleanup_orphaned_creators() -> size_t;
276
285 [[nodiscard]] auto validate_private_tags() const -> std::vector<dicom_tag>;
286
287 // ========================================================================
288 // Modification
289 // ========================================================================
290
298 void insert(dicom_element element);
299
308 void set_string(dicom_tag tag, encoding::vr_type vr, std::string_view value);
309
317 template <typename T>
318 requires std::is_arithmetic_v<T>
319 void set_numeric(dicom_tag tag, encoding::vr_type vr, T value);
320
326 auto remove(dicom_tag tag) -> bool;
327
331 void clear() noexcept;
332
333 // ========================================================================
334 // Iteration
335 // ========================================================================
336
341 [[nodiscard]] auto begin() noexcept -> iterator;
342
347 [[nodiscard]] auto end() noexcept -> iterator;
348
353 [[nodiscard]] auto begin() const noexcept -> const_iterator;
354
359 [[nodiscard]] auto end() const noexcept -> const_iterator;
360
365 [[nodiscard]] auto cbegin() const noexcept -> const_iterator;
366
371 [[nodiscard]] auto cend() const noexcept -> const_iterator;
372
373 // ========================================================================
374 // Size Operations
375 // ========================================================================
376
381 [[nodiscard]] auto size() const noexcept -> size_t;
382
387 [[nodiscard]] auto empty() const noexcept -> bool;
388
389 // ========================================================================
390 // Utility Operations
391 // ========================================================================
392
398 [[nodiscard]] auto copy_with_tags(std::initializer_list<dicom_tag> tags) const
399 -> dicom_dataset;
400
406 [[nodiscard]] auto copy_with_tags(std::span<const dicom_tag> tags) const
407 -> dicom_dataset;
408
415 void merge(const dicom_dataset& other);
416
421 void merge(dicom_dataset&& other);
422
423private:
425};
426
427// ============================================================================
428// Template Implementations
429// ============================================================================
430
431template <typename T>
432 requires std::is_arithmetic_v<T>
433auto dicom_dataset::get_numeric(dicom_tag tag) const -> std::optional<T> {
434 const auto* elem = get(tag);
435 if (elem == nullptr) {
436 return std::nullopt;
437 }
438
439 auto result = elem->as_numeric<T>();
440 if (result.is_ok()) {
441 return result.value();
442 }
443 return std::nullopt;
444}
445
446template <typename T>
447 requires std::is_arithmetic_v<T>
451
452} // namespace kcenon::pacs::core
453
std::map< dicom_tag, dicom_element > storage_type
Storage type for elements (ordered by tag)
auto cleanup_orphaned_creators() -> size_t
Remove orphaned Private Creator elements that have no data elements.
void set_numeric(dicom_tag tag, encoding::vr_type vr, T value)
Set a numeric value for the given tag.
auto has_sequence(dicom_tag tag) const noexcept -> bool
Check if the dataset contains a sequence element with the given tag.
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
auto remove(dicom_tag tag) -> bool
Remove an element from the dataset.
dicom_dataset()=default
Default constructor - creates an empty dataset.
auto set_private_element(std::string_view creator_id, uint16_t group, uint8_t element_offset, encoding::vr_type vr, std::string_view value) -> std::optional< dicom_tag >
Insert a private data element with automatic creator management.
dicom_dataset(dicom_dataset &&) noexcept=default
Move constructor.
void insert(dicom_element element)
Insert or replace an element in the dataset.
dicom_dataset(const dicom_dataset &)=default
Copy constructor.
auto empty() const noexcept -> bool
Check if the dataset is empty.
storage_type::iterator iterator
Iterator type.
auto size() const noexcept -> size_t
Get the number of elements in the dataset.
auto cend() const noexcept -> const_iterator
Get const iterator past the last element.
auto validate_private_tags() const -> std::vector< dicom_tag >
Validate private tag relationships in this dataset.
auto get_numeric(dicom_tag tag) const -> std::optional< T >
Get the numeric value of an element.
auto get_sequence(dicom_tag tag) const noexcept -> const std::vector< dicom_dataset > *
auto end() noexcept -> iterator
Get iterator past the last element.
auto cbegin() const noexcept -> const_iterator
Get const iterator to the first element.
void clear() noexcept
Remove all elements from the dataset.
auto begin() noexcept -> iterator
Get iterator to the first element.
void merge(const dicom_dataset &other)
Merge elements from another dataset.
auto copy_with_tags(std::initializer_list< dicom_tag > tags) const -> dicom_dataset
Create a copy containing only the specified tags.
void set_string(dicom_tag tag, encoding::vr_type vr, std::string_view value)
Set a string value for the given tag.
auto get_private_block(std::string_view creator_id, uint16_t group) const -> std::vector< const dicom_element * >
Get all private data elements belonging to a specific creator.
auto get_or_create_sequence(dicom_tag tag) -> std::vector< dicom_dataset > &
Insert or create a sequence element with the given tag.
auto contains(dicom_tag tag) const noexcept -> bool
Check if the dataset contains an element with the given tag.
storage_type::const_iterator const_iterator
Const iterator type.
auto remove_private_block(std::string_view creator_id, uint16_t group) -> size_t
Remove all private data elements and their creator for a given creator.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
auto get_private_creator(dicom_tag private_data_tag) const -> std::optional< std::string >
Get the Private Creator identification string for a private data element.
static auto from_numeric(dicom_tag tag, encoding::vr_type vr, T value) -> dicom_element
Create an element from a numeric value.
DICOM Data Element representation (Tag, VR, Value)
DICOM Tag representation (Group, Element pairs)
vr_type
DICOM Value Representation (VR) types.
Definition vr_type.h:29
vr_encoding vr