NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
collection.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2024 NeoFOAM authors
3
4#pragma once
5
6#include <unordered_map>
7#include <string>
8#include <memory>
9#include <algorithm> // for std::sort
10
12
13namespace NeoFOAM
14{
15
16
17// forward declaration
18class Database;
19
29{
30public:
31
38 template<typename CollectionType>
39 Collection(CollectionType collection)
40 : impl_(std::make_unique<CollectionModel<CollectionType>>(std::move(collection)))
41 {}
42
46 Collection(const Collection& other) = delete;
47
51 Collection& operator=(const Collection& other) = delete;
52
56 Collection(Collection&& other) = default;
57
61 Collection& operator=(Collection&& other) = default;
62
69 Document& doc(const std::string& id);
70
77 const Document& doc(const std::string& id) const;
78
86 std::vector<std::string> find(const std::function<bool(const Document&)>& predicate) const;
87
93 size_t size() const;
94
100 std::string type() const;
101
107 std::string name() const;
108
115
121 const Database& db() const;
122
130 template<typename CollectionType>
131 CollectionType& as()
132 {
133 auto derived = dynamic_cast<CollectionModel<CollectionType>*>(impl_.get());
134 if (!derived)
135 {
136 throw std::bad_cast();
137 }
138 return derived->collection_;
139 }
140
141
149 template<typename CollectionType>
150 const CollectionType& as() const
151 {
152 auto derived = dynamic_cast<CollectionModel<CollectionType>*>(impl_.get());
153 if (!derived)
154 {
155 throw std::bad_cast();
156 }
157 return derived->collection_;
158 }
159
160private:
161
162 struct CollectionConcept
163 {
164 virtual ~CollectionConcept() = default;
165 virtual Document& doc(const std::string& id) = 0;
166 virtual const Document& doc(const std::string& id) const = 0;
167 virtual std::vector<std::string> find(const std::function<bool(const Document&)>& predicate
168 ) const = 0;
169 virtual size_t size() const = 0;
170 virtual std::string type() const = 0;
171 virtual std::string name() const = 0;
172 virtual Database& db() = 0;
173 virtual const Database& db() const = 0;
174 };
175
176 template<typename CollectionType>
177 struct CollectionModel : CollectionConcept
178 {
179 CollectionModel(CollectionType collection) : collection_(std::move(collection)) {}
180
181 Document& doc(const std::string& id) override { return collection_.doc(id); }
182
183 const Document& doc(const std::string& id) const override { return collection_.doc(id); }
184
185 std::vector<std::string> find(const std::function<bool(const Document&)>& predicate
186 ) const override
187 {
188 return collection_.find(predicate);
189 }
190
191 size_t size() const override { return collection_.size(); }
192
193 std::string type() const override { return collection_.type(); }
194
195 std::string name() const override { return collection_.name(); }
196
197 Database& db() override { return collection_.db(); }
198
199 const Database& db() const override { return collection_.db(); }
200
201 CollectionType collection_;
202 };
203
204 std::unique_ptr<CollectionConcept> impl_;
205};
206
213template<typename DocumentType>
215{
216
217public:
218
226
231
236
241
246
253 Document& doc(const std::string& id) { return docs_.at(id).doc(); }
254
261 const Document& doc(const std::string& id) const { return docs_.at(id).doc(); }
262
269 std::vector<std::string> find(const std::function<bool(const Document&)>& predicate) const
270 {
271 std::vector<std::string> result;
272 for (const auto& [key, doc] : docs_)
273 {
274 if (predicate(doc.doc()))
275 {
276 result.push_back(doc.id());
277 }
278 }
279 return result;
280 }
281
287 std::size_t size() const { return docs_.size(); }
288
294 const NeoFOAM::Database& db() const { return db_; }
295
301 NeoFOAM::Database& db() { return db_; }
302
308 const std::string& name() const { return name_; }
309
315 std::string type() const { return DocumentType::typeName(); }
316
322 std::vector<std::string> sortedKeys() const
323 {
324 std::vector<std::string> result;
325 for (const auto& [key, doc] : docs_)
326 {
327 result.push_back(key);
328 }
329 std::sort(result.begin(), result.end());
330 return result;
331 }
332
333protected:
334
335 std::unordered_map<std::string, DocumentType> docs_;
337 std::string name_;
338};
339
340} // namespace NeoFOAM
A mixin class for collection of documents in a database to simplify the implementation of common oper...
std::unordered_map< std::string, DocumentType > docs_
The map of document IDs to documents.
const std::string & name() const
Gets the name of the collection.
Document & doc(const std::string &id)
Retrieves a document by its ID.
CollectionMixin(CollectionMixin &&)=default
CollectionMixin & operator=(CollectionMixin &&)=delete
CollectionMixin(const CollectionMixin &)=delete
std::size_t size() const
Gets the number of documents in the collection.
std::vector< std::string > find(const std::function< bool(const Document &)> &predicate) const
Finds documents that match a given predicate.
std::string type() const
Gets the type name of the documents in the collection.
const NeoFOAM::Database & db() const
Gets a const reference to the database.
NeoFOAM::Database & db_
The reference to the database.
CollectionMixin(NeoFOAM::Database &db, std::string name)
Constructs a CollectionMixin with the given database and collection name.
std::string name_
The name of the collection.
CollectionMixin & operator=(const CollectionMixin &)=delete
std::vector< std::string > sortedKeys() const
Gets the sorted keys of the documents in the collection.
NeoFOAM::Database & db()
Gets a reference to the database.
const Document & doc(const std::string &id) const
Retrieves a document by its ID (const version).
A type-erased interface collection types.
std::vector< std::string > find(const std::function< bool(const Document &)> &predicate) const
Finds documents that match a given predicate.
const Document & doc(const std::string &id) const
Retrieves a document by its ID (const version).
Collection & operator=(const Collection &other)=delete
A Collection is not copyable, only moveable.
const Database & db() const
Returns a const reference to the database containing the collection.
Collection(const Collection &other)=delete
A Collection is not copyable, only moveable.
std::string type() const
Returns the type of the collection.
const CollectionType & as() const
Casts the collection to a specific collection type (const version).
Collection(Collection &&other)=default
A Collection is moveable, but not copyable.
Document & doc(const std::string &id)
Retrieves a document by its ID.
std::string name() const
Returns the name of the collection.
size_t size() const
Returns the number of documents in the collection.
Database & db()
Returns a reference to the database containing the collection.
Collection(CollectionType collection)
Constructs a Collection from a specific collection type.
Collection & operator=(Collection &&other)=default
A Collection is moveable, but not copyable.
CollectionType & as()
Casts the collection to a specific collection type.
A class representing a document in a database.
Definition document.hpp:51
std::string id() const
Retrieves the ID of the Document.
Definition document.hpp:82
const std::string & name(const NeoFOAM::Document &doc)
Retrieves the name of a Document.