8#include <reflection-cpp/reflection.hpp>
22template <
typename ReferencedRecordT,
typename ThroughRecordT>
36 using iterator =
typename ReferencedRecordList::iterator;
37 using const_iterator =
typename ReferencedRecordList::const_iterator;
49 [[nodiscard]] std::
size_t Count() const;
52 [[nodiscard]] std::
size_t IsEmpty() const;
82 [[nodiscard]] iterator begin() noexcept;
83 [[nodiscard]] iterator end() noexcept;
84 [[nodiscard]] const_iterator begin() const noexcept;
85 [[nodiscard]] const_iterator end() const noexcept;
87 std::weak_ordering operator<=>(
HasManyThrough const& other) const noexcept = default;
91 std::function<size_t()> count;
92 std::function<void()> all;
99 _loader = std::move(loader);
105 _count = std::nullopt;
106 _records = std::nullopt;
115 template <
typename Callable>
116 void Each(Callable
const& callable)
118 if (!_records && _loader.each)
120 _loader.each(callable);
124 for (
auto const& record:
All())
143 std::optional<size_t> _count;
144 std::optional<ReferencedRecordList> _records;
148constexpr bool IsHasManyThrough = IsSpecializationOf<HasManyThrough, T>;
150template <
typename ReferencedRecordT,
typename ThroughRecordT>
152 ThroughRecordT>::All()
157 return _records.value();
160template <
typename ReferencedRecordT,
typename ThroughRecordT>
162 ThroughRecordT>::All() noexcept
166 return _records.value();
169template <
typename ReferencedRecordT,
typename ThroughRecordT>
173 _records = { std::move(records) };
174 _count = _records->size();
178template <
typename ReferencedRecordT,
typename ThroughRecordT>
182 return _records->size();
187 return _count.value_or(0);
190template <
typename ReferencedRecordT,
typename ThroughRecordT>
196template <
typename ReferencedRecordT,
typename ThroughRecordT>
199 ThroughRecordT>::At(std::size_t index)
const
201 return *All().at(index);
204template <
typename ReferencedRecordT,
typename ThroughRecordT>
208 return *All().at(index);
211template <
typename ReferencedRecordT,
typename ThroughRecordT>
214 ThroughRecordT>::operator[](std::size_t index)
const
216 return *All()[index];
219template <
typename ReferencedRecordT,
typename ThroughRecordT>
223 return *All()[index];
226template <
typename ReferencedRecordT,
typename ThroughRecordT>
227HasManyThrough<ReferencedRecordT, ThroughRecordT>::iterator
HasManyThrough<ReferencedRecordT,
228 ThroughRecordT>::begin() noexcept
230 return All().begin();
233template <
typename ReferencedRecordT,
typename ThroughRecordT>
234HasManyThrough<ReferencedRecordT, ThroughRecordT>::iterator HasManyThrough<ReferencedRecordT, ThroughRecordT>::end() noexcept
239template <
typename ReferencedRecordT,
typename ThroughRecordT>
240HasManyThrough<ReferencedRecordT, ThroughRecordT>::const_iterator HasManyThrough<ReferencedRecordT, ThroughRecordT>::begin()
243 return All().begin();
246template <
typename ReferencedRecordT,
typename ThroughRecordT>
247HasManyThrough<ReferencedRecordT, ThroughRecordT>::const_iterator HasManyThrough<ReferencedRecordT, ThroughRecordT>::end()
This API represents a many-to-many relationship between two records through a third record.
void Each(Callable const &callable)
Iterates over all records in this relationship.
std::size_t Count() const
Retrieves the number of records in this relationship.
ReferencedRecord const & operator[](std::size_t index) const
Retrieves the record at the given index.
std::vector< std::shared_ptr< ReferencedRecord > > ReferencedRecordList
The list of records on the "many" side of the relationship.
ReferencedRecordList const & All() const noexcept
Retrieves the list of loaded records.
void Reload()
Reloads the records from the database.
void SetAutoLoader(Loader loader) noexcept
Used internally to configure on-demand loading of the records.
ReferencedRecord const & At(std::size_t index) const
Retrieves the record at the given index.
ThroughRecordT ThroughRecord
The record type of the "through" side of the relationship.
std::size_t IsEmpty() const
Checks if this relationship is empty.
ReferencedRecordList & Emplace(ReferencedRecordList &&records) noexcept
Emplaces the given list of records into this relationship.
ReferencedRecordT ReferencedRecord
The record type of the "many" side of the relationship.
Represents an error when a record is required to be loaded but is not.