MUSX Document Model
Loading...
Searching...
No Matches
MusxInstance.h
1/*
2 * Copyright (C) 2025, Robert Patterson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22#pragma once
23
24#include <vector>
25#include <memory>
26#include <functional>
27#include <optional>
28#include <type_traits>
29#include <utility>
30
31#include "Fundamentals.h"
32#include "DocumentElement.h"
33
34namespace musx {
35namespace dom {
36
39template <typename T>
40using MusxInstance = std::shared_ptr<const T>;
41
44template <typename T>
45using MusxInstanceWeak = std::weak_ptr<const T>;
46
47class Document;
48class MusicRange;
49class EntryInfoPtr;
50
51namespace others {
52class StaffUsed;
53class Staff;
54class StaffComposite;
55}
56
65template <typename T>
66// Private inheritance keeps the vector implementation detail out of the public API and avoids any
67// accidental polymorphic use of a standard container with a non-virtual destructor.
68class MusxInstanceListBase : public DocumentElement, private std::vector<MusxInstance<T>>
69{
70 Cmper getPartId() const = delete;
71
72public:
73 using typename std::vector<MusxInstance<T>>::value_type;
74 using typename std::vector<MusxInstance<T>>::allocator_type;
75 using typename std::vector<MusxInstance<T>>::size_type;
76 using typename std::vector<MusxInstance<T>>::difference_type;
77 using typename std::vector<MusxInstance<T>>::reference;
78 using typename std::vector<MusxInstance<T>>::const_reference;
79 using typename std::vector<MusxInstance<T>>::pointer;
80 using typename std::vector<MusxInstance<T>>::const_pointer;
81 using typename std::vector<MusxInstance<T>>::iterator;
82 using typename std::vector<MusxInstance<T>>::const_iterator;
83 using typename std::vector<MusxInstance<T>>::reverse_iterator;
84 using typename std::vector<MusxInstance<T>>::const_reverse_iterator;
85
87 explicit MusxInstanceListBase(const std::weak_ptr<Document>& document, Cmper partId)
88 : DocumentElement(document, partId) {}
89
92
93 using std::vector<MusxInstance<T>>::begin;
94 using std::vector<MusxInstance<T>>::end;
95 using std::vector<MusxInstance<T>>::empty;
96 using std::vector<MusxInstance<T>>::size;
97 using std::vector<MusxInstance<T>>::reserve;
98 using std::vector<MusxInstance<T>>::clear;
99 using std::vector<MusxInstance<T>>::emplace_back;
100 using std::vector<MusxInstance<T>>::push_back;
101 using std::vector<MusxInstance<T>>::operator[];
102 using std::vector<MusxInstance<T>>::at;
103 using std::vector<MusxInstance<T>>::front;
104 using std::vector<MusxInstance<T>>::back;
105};
106
116template <typename T>
118{
119public:
120 using MusxInstanceListBase<T>::MusxInstanceListBase;
121
122 // No helpers by default
123};
124
129template<>
130class MusxInstanceList<others::StaffUsed> : public MusxInstanceListBase<others::StaffUsed>
131{
132public:
133 using MusxInstanceListBase<others::StaffUsed>::MusxInstanceListBase;
134
137 MusxInstance<others::Staff> getStaffInstanceAtIndex(size_t index) const;
138
143 MusxInstance<others::StaffComposite> getStaffInstanceAtIndex(size_t index, MeasCmper measureId, Edu eduPosition = 0) const;
144
147 std::optional<size_t> getIndexForStaff(StaffCmper staffId) const;
148
150 StaffCmper getTopStaffId() const;
151
153 StaffCmper getBottomStaffId() const;
154
164 bool iterateEntries(size_t startIndex, size_t endIndex, const MusicRange& range, std::function<bool(const EntryInfoPtr&)> iterator) const;
165};
166
193template<class T>
195 static_assert(!std::is_reference_v<T>, "T must not be a reference");
196 using OwnedT = std::remove_const_t<T>;
197
198public:
200 DeferredReference() noexcept = default;
201
204 DeferredReference(const T& ref) noexcept : m_ref(&ref) {}
205
208 explicit DeferredReference(const T* ptr) noexcept : m_ref(ptr) {}
209
219 const T& bind(const T& ref) noexcept
220 {
221 m_owned.reset();
222 m_ref = std::addressof(ref);
223 return *m_ref;
224 }
225
233 const T& emplace(OwnedT&& value) noexcept(std::is_nothrow_move_constructible_v<OwnedT>) {
234 m_owned.emplace(std::move(value));
235 m_ref = std::addressof(*m_owned);
236 return *m_ref;
237 }
238
240 explicit operator bool() const noexcept { return m_ref != nullptr; }
241
244 const T& get() const noexcept { return *m_ref; }
245
247 const T* operator->() const noexcept { return m_ref; }
248
250 const T& operator*() const noexcept { return *m_ref; }
251
252private:
253 std::optional<OwnedT> m_owned = std::nullopt;
254 const T* m_ref = nullptr;
255};
256
257#ifndef DOXYGEN_SHOULD_IGNORE_THIS
266template<class T> DeferredReference(const T&) -> DeferredReference<T>;
267template<class T> DeferredReference(const T*) -> DeferredReference<T>;
269#endif // DOXYGEN_SHOULD_IGNORE_THIS
270
271} // namespace dom
272} // namespace musx
Wraps a reference to an existing object or owns a temporary value if needed.
Definition MusxInstance.h:194
DeferredReference(const T *ptr) noexcept
Constructs a non-owning DeferredReference bound to a pointer.
Definition MusxInstance.h:208
const T & bind(const T &ref) noexcept
Binds this DeferredReference to an existing object without taking ownership.
Definition MusxInstance.h:219
DeferredReference() noexcept=default
Constructs an empty DeferredReference with no bound reference.
const T & emplace(OwnedT &&value) noexcept(std::is_nothrow_move_constructible_v< OwnedT >)
Moves a value into owned storage and binds to it.
Definition MusxInstance.h:233
const T * operator->() const noexcept
Provides pointer-like access to the referenced or owned object.
Definition MusxInstance.h:247
const T & operator*() const noexcept
Dereferences to the referenced or owned object.
Definition MusxInstance.h:250
const T & get() const noexcept
Gets a const reference to the referenced or owned object.
Definition MusxInstance.h:244
Base for DOM classes that belong to a Document.
Definition DocumentElement.h:46
Cmper getPartId() const
Gets the part id associated with this instance.
Definition DocumentElement.h:70
Represents a document object that encapsulates the entire EnigmaXML structure.
Definition Document.h:88
Wraps a frame of shared_ptr<const EntryInfo> and an index for per entry access. This class manages ow...
Definition Entries.h:513
Utility class that represents of a range of musical time.
Definition CommonClasses.h:492
A container of pooled shared object instances from an ObjectPool.
Definition MusxInstance.h:69
MusxInstanceListBase(const std::weak_ptr< Document > &document, Cmper partId)
Default constructor.
Definition MusxInstance.h:87
Cmper getRequestedPartId() const
Gets the part id that was used to create this list.
Definition MusxInstance.h:91
Provides optional per-type extension methods for MusxInstanceList.
Definition MusxInstance.h:118
An array of StaffUsed defines a set of staves in a staff system or in Scroll View.
Definition Others.h:2816
int16_t MeasCmper
Enigma meas Cmper (may be negative when not applicable)
Definition Fundamentals.h:64
std::shared_ptr< const T > MusxInstance
Defines the type of a musx instance stored in a pool.
Definition MusxInstance.h:40
uint16_t Cmper
Enigma "comperator" key type.
Definition Fundamentals.h:55
int32_t Edu
"Enigma Durational Units" value (1024 per quarter note)
Definition Fundamentals.h:61
int16_t StaffCmper
Enigma staff (staffId) Cmper (may be negative when not applicable)
Definition Fundamentals.h:65
std::weak_ptr< const T > MusxInstanceWeak
Defines a weak ptr to the type of a musx instance stored in a pool.
Definition MusxInstance.h:45
object model for musx file (enigmaxml)
Definition BaseClasses.h:38