LiteFX 0.4.1.2025
Computer Graphics Engine
Loading...
Searching...
No Matches
containers.hpp
1#pragma once
2
3// Disable warning C4251: STL class needs to have dll-interface to be used by clients.
4// See: https://stackoverflow.com/a/22054743/1254352
5#pragma warning(disable: 4251)
6
7#include <array>
8#include <cassert>
9#include <algorithm>
10#include <string>
11#include <optional>
12#include <map>
13#include <vector>
14#include <forward_list>
15#include <queue>
16#include <tuple>
17#include <memory>
18#include <functional>
19#include <variant>
20#include <ranges>
21#include <mutex>
22#include <generator>
23#include <utility>
24#include <iterator>
25#include <cstddef>
26#include <concepts>
27#include <typeindex>
28
29#ifdef __cpp_lib_mdspan
30#include <mdspan>
31#endif
32
33#include "traits.hpp"
34#include "string.hpp"
35#include "exceptions.hpp"
36
37// NOLINTBEGIN(cppcoreguidelines-macro-usage)
38
39#ifndef LITEFX_DEFINE_FLAGS
40# define LITEFX_DEFINE_FLAGS(T) \
41 constexpr T operator| (const T lhs, const T rhs) { using _base_t = std::underlying_type_t<T>; return static_cast<T>(static_cast<_base_t>(lhs) | static_cast<_base_t>(rhs)); } \
42 constexpr T& operator|= (T& lhs, const T& rhs) { lhs = lhs | rhs; return lhs; } \
43 constexpr T operator& (const T lhs, const T rhs) { using _base_t = std::underlying_type_t<T>; return static_cast<T>(static_cast<_base_t>(lhs) & static_cast<_base_t>(rhs)); } \
44 constexpr T& operator&= (T& lhs, const T& rhs) { lhs = lhs & rhs; return lhs; }
45#endif
46
47#ifndef LITEFX_FLAG_IS_SET
48# define LITEFX_FLAG_IS_SET(val, flag) static_cast<bool>((std::to_underlying(val) & std::to_underlying(flag)) == std::to_underlying(flag))
49#endif
50
51// NOLINTEND(cppcoreguidelines-macro-usage)
52
53namespace LiteFX {
54
58 using Handle = void*;
59
65 template<class TKey, class TVal>
66 using Dictionary = std::unordered_map<TKey, TVal>;
67
72 template<class T>
73 using Array = std::vector<T>;
74
79 template<class T>
80 using Queue = std::queue<T>;
81
86 template<class T>
87 using Span = std::span<T>;
88
93 template<class T>
94 using Optional = std::optional<T>;
95
101 template<class T, class TDeleter = std::default_delete<T>>
102 using UniquePtr = std::unique_ptr<T, TDeleter>;
103
108 template <class T>
109 using SharedPtr = std::shared_ptr<T>;
110
115 template <class T>
116 using WeakPtr = std::weak_ptr<T>;
117
122 template <class... T>
123 using Tuple = std::tuple<T...>;
124
129 template <class... T>
130 using Variant = std::variant<T...>;
131
135 template<class... TArgs>
136 struct type_switch : TArgs... {
137 using TArgs::operator()...;
138 };
139
144 template <class T>
145 using Ref = std::reference_wrapper<T>;
146
152 template <class T>
153 [[nodiscard]] constexpr UniquePtr<T> makeUnique() {
154 return std::make_unique<T>();
155 }
156
162 template <class T, class... TArgs>
163 [[nodiscard]] constexpr UniquePtr<T> makeUnique(TArgs&&... _args) {
164 return std::make_unique<T>(std::forward<TArgs>(_args)...);
165 }
166
172 template <class T>
173 [[nodiscard]] constexpr SharedPtr<T> makeShared() {
174 return std::make_shared<T>();
175 }
176
182 template <class T, class... TArgs>
183 [[nodiscard]] constexpr SharedPtr<T> makeShared(TArgs&&... _args) {
184 return std::make_shared<T>(std::forward<TArgs>(_args)...);
185 }
186
193 template <class T>
194 [[nodiscard]] constexpr SharedPtr<T> asShared(UniquePtr<T>&& ptr) {
195 SharedPtr<T> shared = std::move(ptr);
196 return shared;
197 }
198
205 template <typename T, typename TVal = void>
206 using Generator = std::generator<T, TVal>;
207
214 template <typename TValue, typename TCovariant>
215 concept is_covariant = std::is_assignable_v<TCovariant, TValue> || std::is_constructible_v<TCovariant, TValue>;
216
222 template <typename TIterator, typename TValue>
223 concept covariant_forward_iterator = std::forward_iterator<TIterator> && is_covariant<decltype(*std::declval<TIterator>()), TValue>;
224
235 template <typename T>
237 public:
241 using value_type = std::remove_cvref_t<T>;
242
246 using iterator_category = std::forward_iterator_tag;
247
251 using difference_type = std::ptrdiff_t;
252
256 using pointer = std::remove_reference_t<T>*;
257
258 private:
259 struct iterator_base {
260 protected:
261 iterator_base() = default;
262 iterator_base(iterator_base&&) noexcept = default;
263 iterator_base(const iterator_base&) = default;
264 iterator_base& operator=(iterator_base&&) noexcept = default;
265 iterator_base& operator=(const iterator_base&) = default;
266
267 public:
268 virtual ~iterator_base() noexcept = default;
269
270 virtual T operator*() const = 0;
271 virtual iterator_base& operator++() = 0;
272 virtual std::unique_ptr<iterator_base> operator++(int) = 0;
273 virtual bool operator==(const iterator_base& _other) const noexcept = 0;
274 virtual std::unique_ptr<iterator_base> copy() const = 0;
275 };
276
277 template <covariant_forward_iterator<T> TIterator>
278 struct wrapped_iterator final : public iterator_base {
279 private:
280 TIterator _it;
281
282 private:
283 wrapped_iterator() = delete;
284 wrapped_iterator(wrapped_iterator&&) noexcept = default;
285 wrapped_iterator(const wrapped_iterator&) = delete;
286 wrapped_iterator& operator=(wrapped_iterator&&) noexcept = default;
287 wrapped_iterator& operator=(const wrapped_iterator&) = delete;
288
289 public:
290 inline wrapped_iterator(TIterator it) :
291 _it(std::move(it))
292 { }
293
294 inline ~wrapped_iterator() noexcept override = default;
295
296 inline T operator*() const override {
297 return *_it;
298 };
299
300 inline iterator_base& operator++() override {
301 ++_it;
302 return *this;
303 }
304
305 inline std::unique_ptr<iterator_base> operator++(int) override {
306 return std::make_unique<wrapped_iterator>(_it++);
307 }
308
309 inline bool operator==(const iterator_base& _other) const noexcept override {
310 // NOTE: This is only safe if the other iterator is of the same type as the current iterator, which is enforced by the `CovariantIterator` class.
311 return this->_it == static_cast<const wrapped_iterator&>(_other)._it;
312 }
313
314 inline std::unique_ptr<iterator_base> copy() const override {
315 return std::make_unique<wrapped_iterator>(_it);
316 }
317 };
318
319 std::unique_ptr<iterator_base> _iterator{ nullptr }; // NOTE: Starting with C++26 there may be a way to express this with a value-semantic unique_ptr.
320 std::type_index _iterator_type{ typeid(iterator_base) };
321
322 private:
323 CovariantIterator(std::unique_ptr<iterator_base>&& iterator, std::type_index iterator_type) :
324 _iterator(std::move(iterator)), _iterator_type(iterator_type)
325 { }
326
327 public:
335 explicit CovariantIterator() {
336 // Calling this constructor is not supported. It is only publicly available, to make sure the iterator is `std::semiregular`, which is implicitly required by the `std::ranges::range` concept.
337 throw RuntimeException("Default-initializing `CovariantIterator` is not supported!");
338 }
339
345 template <typename TIterator>
346 inline CovariantIterator(const TIterator& it) :
347 _iterator(std::make_unique<wrapped_iterator<TIterator>>(it)), _iterator_type(typeid(TIterator))
348 { }
349
354 inline CovariantIterator(const CovariantIterator& _other) :
355 _iterator(_other._iterator->copy()), _iterator_type(_other._iterator_type)
356 { }
357
362 inline CovariantIterator(CovariantIterator&& _other) noexcept = default;
363
370 _iterator = _other._iterator->copy();
371 _iterator_type = _other._iterator_type;
372 return *this;
373 }
374
380 inline CovariantIterator& operator=(CovariantIterator&& _other) = default;
381
385 ~CovariantIterator() noexcept = default;
386
391 inline T operator*() const {
392 return _iterator->operator*();
393 }
394
402 inline pointer operator->() requires std::is_lvalue_reference_v<T> {
403 return &this->operator*();
404 }
405
411 _iterator->operator++();
412 return *this;
413 }
414
420 return { (*_iterator)++, _iterator_type };
421 }
422
428 inline bool operator==(const CovariantIterator& _other) const {
429 if (this->_iterator_type != _other._iterator_type)
430 return false;
431
432 return _iterator->operator==(*_other._iterator);
433 }
434 };
435
528 template <typename T>
529 struct Enumerable {
530 public:
534 using value_type = std::remove_cvref_t<T>;
535
539 using pointer = std::remove_reference_t<T>*;
540
544 using reference = std::remove_reference_t<T>&;
545
550
555
556 private:
557 struct range_holder_base {
558 protected:
559 range_holder_base() = default;
560 range_holder_base(range_holder_base&&) noexcept = delete;
561 range_holder_base(const range_holder_base&) = delete;
562 range_holder_base& operator=(range_holder_base&&) noexcept = delete;
563 range_holder_base& operator=(const range_holder_base&) = delete;
564
565 public:
566 virtual ~range_holder_base() noexcept = default;
567
568 virtual iterator begin() = 0;
569 virtual iterator end() = 0;
570 virtual const_iterator cbegin() = 0;
571 virtual const_iterator cend() = 0;
572 };
573
574 template <std::ranges::viewable_range TRange>
575 struct range_holder final : public range_holder_base {
576 private:
577 TRange _stored_range;
578
579 private:
580 range_holder() = default;
581 range_holder(range_holder&&) noexcept = default;
582 range_holder(const range_holder&) = delete;
583 range_holder& operator=(range_holder&&) noexcept = default;
584 range_holder& operator=(const range_holder&) = delete;
585
586 public:
587 inline range_holder(TRange&& range) :
588 _stored_range(std::move(range))
589 { }
590
591 inline ~range_holder() noexcept override = default;
592
593 inline iterator begin() override {
594 return { std::ranges::begin(_stored_range) };
595 }
596
597 inline iterator end() override {
598 return { std::ranges::end(_stored_range) };
599 }
600
601 inline const_iterator cbegin() override {
602 return { std::ranges::begin(_stored_range) };
603 }
604
605 inline const_iterator cend() override {
606 return { std::ranges::end(_stored_range) };
607 }
608 };
609
610 std::shared_ptr<range_holder_base> _range{ };
611
612 public:
616 inline Enumerable() :
617 Enumerable(std::array<T, 0> { })
618 { }
619
620 inline Enumerable(const Enumerable& range) = default;
621 inline Enumerable(Enumerable&& range) noexcept = default;
622 inline Enumerable& operator=(const Enumerable& range) = default;
623 inline Enumerable& operator=(Enumerable&& range) noexcept = default;
624 ~Enumerable() noexcept = default;
625
632 template <typename TRange, typename enabled = std::enable_if_t<!std::is_same_v<TRange, Enumerable>>>
633 inline Enumerable(TRange&& range) {
634 // NOTE: Concept evaluation may fail here, if we provide some other enumerable, in which case the evaluated type may be not complete yet, which is why have to
635 // do a static assert here instead of providing the concept in the template.
636 static_assert(std::ranges::viewable_range<TRange>, "The source range does not satisfy std::ranges::viewable_range!");
637 _range = std::make_shared<range_holder<std::ranges::views::all_t<decltype(range)>>>(std::forward<TRange>(range)); // NOLINT(cppcoreguidelines-prefer-member-initializer)
638 }
639
644 inline auto begin() const {
645 return _range->begin();
646 }
647
652 inline auto end() const {
653 return _range->end();
654 }
655
660 inline auto cbegin() const {
661 return _range->cbegin();
662 }
663
668 inline auto cend() const {
669 return _range->cend();
670 }
671
676 inline bool empty() const noexcept {
677 return this->begin() == this->end();
678 }
679 };
680
681#if (defined(BUILD_LITEFX_PIMPL) && BUILD_LITEFX_PIMPL) || (!defined(BUILD_LITEFX_PIMPL)) && !defined(LITEFX_IMPLEMENTATION)
686 template <class pImpl>
687 class PimplPtr final {
688 private:
692 SharedPtr<pImpl> m_ptr;
693
694 public:
698 constexpr PimplPtr() /*requires std::is_default_constructible_v<pImpl>*/ :
699 m_ptr(makeShared<pImpl>()) { }
700
706 template <typename... TArgs>
707 constexpr PimplPtr(TArgs&&... args) /*requires std::constructible_from<pImpl, TArgs...>*/ :
708 m_ptr(makeShared<pImpl>(std::forward<TArgs>(args)...)) { } // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
709
714 constexpr PimplPtr(const PimplPtr& src) /*requires std::copy_constructible<pImpl>*/ :
715 m_ptr(makeShared<pImpl>(*src.m_ptr)) { }
716
721 constexpr PimplPtr(PimplPtr&& src) noexcept = default;
722
732 constexpr PimplPtr& operator=(const PimplPtr& src) /*requires std::copy_constructible<pImpl>*/
733 {
734 if (&src != this)
735 m_ptr = makeShared<pImpl>(*src.m_ptr);
736
737 return *this;
738 }
739
745 constexpr PimplPtr& operator=(PimplPtr&& src) noexcept = default;
746
747 constexpr ~PimplPtr() noexcept = default;
748
749 public:
754 constexpr pImpl& operator* () const noexcept {
755 return *m_ptr;
756 }
757
762 constexpr pImpl* operator-> () const noexcept {
763 return m_ptr.get();
764 }
765 };
766
767 // NOLINTBEGIN(cppcoreguidelines-macro-usage)
768
777# define LITEFX_IMPLEMENTATION(impl) private: \
778 class impl; \
779 PimplPtr<impl> m_impl; \
780 friend class PimplPtr<impl>; \
781 friend class impl;
782
783 // NOLINTEND(cppcoreguidelines-macro-usage)
784#endif
785
791 template <class THandle>
792 class IResource {
793 protected:
794 IResource() noexcept = default;
795 IResource(const IResource&) = delete;
796 IResource(IResource&&) noexcept = default;
797 IResource& operator=(const IResource&) = delete;
798 IResource& operator=(IResource&&) noexcept = default;
799
800 public:
801 virtual ~IResource() noexcept = default;
802
803 protected:
808 virtual THandle& handle() noexcept = 0;
809
810 public:
815 virtual const THandle& handle() const noexcept = 0;
816 };
817
822 template <class THandle>
823 class Resource : public virtual IResource<THandle> {
824 public:
825 using handle_type = THandle;
826
827 private:
828 THandle m_handle;
829
830 protected:
835 explicit Resource(THandle handle) noexcept : m_handle(std::move(handle)) { }
836 Resource(const Resource&) = delete;
837 Resource(Resource&&) noexcept = default;
838 Resource& operator=(const Resource&) = delete;
839 Resource& operator=(Resource&&) noexcept = default;
840
841 public:
842 ~Resource() noexcept override = default;
843
844 protected:
846 THandle& handle() noexcept override { return m_handle; }
847
848 public:
850 const THandle& handle() const noexcept override { return m_handle; }
851 };
852
874 template <typename T, typename TParent = std::nullptr_t, typename TPointer = UniquePtr<T>>
875 class Builder;
876
883 template <typename T, typename TPointer>
884 class Builder<T, std::nullptr_t, TPointer> {
885 private:
886 TPointer m_instance;
887
888 public:
889 using instance_type = T;
890 using parent_type = std::nullptr_t;
891 using pointer_type = TPointer;
892
893 public:
898 constexpr const T* instance() const noexcept { return m_instance.get(); }
899
900 protected:
905 constexpr T* instance() noexcept { return m_instance.get(); }
906
907 public:
912 constexpr explicit Builder(TPointer&& instance) noexcept : m_instance(std::move(instance)) { }
913
918 constexpr Builder(Builder&& _other) noexcept : m_instance(std::move(_other.m_instance)) { }
919
920 Builder(const Builder&) = delete;
921 auto operator=(const Builder&) = delete;
922 auto operator=(const Builder&&) noexcept = delete;
923
924 constexpr virtual ~Builder() noexcept = default;
925
926 protected:
930 constexpr virtual void build() { };
931
932 public:
933 // TODO: Provide concept (`is_buildable<TBuilder>`)
941 template <typename TInstance>
942 void use(pointer_type&&) noexcept = delete;
943
947 [[nodiscard]] constexpr operator TPointer&& () {
948 this->build();
949 return std::move(m_instance);
950 }
951 };
952
959 template <typename T, typename TParent, typename TPointer>
960 class Builder {
961 private:
962 TPointer m_instance;
963 TParent* m_parent;
964
965 public:
966 using instance_type = T;
967 using parent_type = TParent;
968 using pointer_type = TPointer;
969
970 public:
975 constexpr const T* instance() const noexcept { return m_instance.get(); }
976
981 constexpr const TParent& parent() const noexcept { return *m_parent; }
982
983 protected:
988 constexpr T* instance() noexcept { return m_instance.get(); }
989
990 public:
996 constexpr explicit Builder(TParent& parent, TPointer&& instance) noexcept : m_instance(std::move(instance)), m_parent(&parent) { }
997
1002 constexpr Builder(Builder&& _other) noexcept : m_instance(std::move(_other.m_instance)), m_parent(_other.m_parent) { }
1003
1004 constexpr Builder(const Builder&) = delete;
1005 auto operator=(const Builder&) = delete;
1006 auto operator=(Builder&&) noexcept = delete;
1007 constexpr virtual ~Builder() noexcept = default;
1008
1009 protected:
1013 constexpr virtual void build() { };
1014
1015 public:
1016 // TODO: Provide concept (`is_buildable<TBuilder>`)
1024 template <typename TInstance>
1025 void use(pointer_type&&) noexcept = delete;
1026
1030 [[nodiscard]] constexpr TParent& add() {
1031 this->build();
1032 m_parent->use(std::move(m_instance));
1033 return *m_parent;
1034 }
1035 };
1036
1037 // NOLINTBEGIN(cppcoreguidelines-macro-usage)
1038
1039#if !defined(LITEFX_BUILDER)
1040# define LITEFX_BUILDER(BuilderType) public: \
1041 using builder_type = BuilderType; \
1042 friend class BuilderType;
1043#endif // !defined(LITEFX_BUILDER)
1044
1045 // NOLINTEND(cppcoreguidelines-macro-usage)
1046
1075 class SharedObject : public std::enable_shared_from_this<SharedObject> {
1076 protected:
1080 SharedObject() noexcept = default;
1081 SharedObject(SharedObject&&) noexcept = default;
1082 SharedObject(const SharedObject&) = default;
1083 SharedObject& operator=(SharedObject&&) noexcept = default;
1084 SharedObject& operator=(const SharedObject&) = default;
1085
1086 public:
1090 virtual ~SharedObject() noexcept = default;
1091
1092 protected:
1097 template <typename T>
1098 struct Allocator : public std::allocator<T> {
1099 template<typename TParent, typename... TArgs>
1100 void construct(TParent* parent, TArgs&&... args) {
1101 ::new(static_cast<void*>(parent)) TParent(std::forward<TArgs>(args)...);
1102 }
1103 };
1104
1113 template <typename T, typename... TArgs>
1114 static inline auto create(TArgs&&... args) -> SharedPtr<T> {
1115 return std::allocate_shared<T>(Allocator<T>{}, std::forward<TArgs>(args)...);
1116 }
1117
1118 public:
1122 template <typename TSelf>
1123 auto inline shared_from_this(this TSelf&& self) noexcept
1124 {
1125 return std::static_pointer_cast<std::remove_reference_t<TSelf>>(
1126 std::forward<TSelf>(self).std::template enable_shared_from_this<SharedObject>::shared_from_this());
1127 }
1128
1132 template <typename TSelf>
1133 auto inline weak_from_this(this TSelf&& self) noexcept -> WeakPtr<std::remove_reference_t<TSelf>>
1134 {
1135 return std::static_pointer_cast<std::remove_reference_t<TSelf>>(
1136 std::forward<TSelf>(self).std::template enable_shared_from_this<SharedObject>::weak_from_this().lock());
1137 }
1138 };
1139}
void use(pointer_type &&) noexcept=delete
Called by child builders to pass a constructed object back to the parent builder.
constexpr T * instance() noexcept
Returns a pointer to the current instance of the object that is built by the builder.
Definition containers.hpp:905
auto operator=(const Builder &&) noexcept=delete
T instance_type
Definition containers.hpp:889
constexpr Builder(TPointer &&instance) noexcept
Initializes the builder instance.
Definition containers.hpp:912
constexpr Builder(Builder &&_other) noexcept
Initializes the builder instance by taking over another instance.
Definition containers.hpp:918
std::nullptr_t parent_type
Definition containers.hpp:890
auto operator=(const Builder &)=delete
TPointer pointer_type
Definition containers.hpp:891
constexpr const T * instance() const noexcept
Returns a pointer to the current instance of the object that is built by the builder.
Definition containers.hpp:898
Describes an generic builder type.
Definition containers.hpp:960
auto operator=(const Builder &)=delete
constexpr Builder(Builder &&_other) noexcept
Initializes the builder instance by taking over another instance.
Definition containers.hpp:1002
constexpr T * instance() noexcept
Returns a pointer to the current instance of the object that is built by the builder.
Definition containers.hpp:988
void use(pointer_type &&) noexcept=delete
Called by child builders to pass a constructed object back to the parent builder.
constexpr Builder(TParent &parent, TPointer &&instance) noexcept
Initializes the builder instance.
Definition containers.hpp:996
auto operator=(Builder &&) noexcept=delete
TPointer pointer_type
Definition containers.hpp:968
constexpr const TParent & parent() const noexcept
Returns a reference of the parent builder.
Definition containers.hpp:981
constexpr Builder(const Builder &)=delete
T instance_type
Definition containers.hpp:966
constexpr const T * instance() const noexcept
Returns a pointer to the current instance of the object that is built by the builder.
Definition containers.hpp:975
TParent parent_type
Definition containers.hpp:967
Provides access to a resource managed by the class.
Definition containers.hpp:792
IResource() noexcept=default
virtual THandle & handle() noexcept=0
Returns the resource managed by the class.
A smart pointer that manages an implementation instance for a public interface class.
Definition containers.hpp:687
constexpr pImpl * operator->() const noexcept
Returns a pointer to the managed implementation instance.
Definition containers.hpp:762
constexpr PimplPtr(const PimplPtr &src)
Initializes a new pointer to a copy of the implementation instance managed by src .
Definition containers.hpp:714
constexpr PimplPtr()
Initializes a new pointer to an implementation instance.
Definition containers.hpp:698
constexpr ~PimplPtr() noexcept=default
constexpr PimplPtr(TArgs &&... args)
Initializes a new pointer of an implementation.
Definition containers.hpp:707
constexpr PimplPtr & operator=(const PimplPtr &src)
Initializes a new pointer to a copy of the implementation instance managed by src .
Definition containers.hpp:732
constexpr PimplPtr & operator=(PimplPtr &&src) noexcept=default
Initializes a new pointer by taking over the implementation instance managed by src .
constexpr PimplPtr(PimplPtr &&src) noexcept=default
Initializes a new pointer by taking over the implementation instance managed by src .
Implements the IResource interface.
Definition containers.hpp:823
Resource(Resource &&) noexcept=default
const THandle & handle() const noexcept override
Returns the resource managed by the class.The resource managed by the class.
Definition containers.hpp:850
Resource(const Resource &)=delete
Resource(THandle handle) noexcept
Initializes the managed resource.
Definition containers.hpp:835
THandle handle_type
Definition containers.hpp:825
An exception that is thrown, if a requested operation could not be executed.
Definition exceptions.hpp:235
Base class for an object that can be shared.
Definition containers.hpp:1075
auto weak_from_this(this TSelf &&self) noexcept -> WeakPtr< std::remove_reference_t< TSelf > >
Returns a weak pointer to the current object instance.
Definition containers.hpp:1133
static auto create(TArgs &&... args) -> SharedPtr< T >
Generic factory method used to create instances of the shared object.
Definition containers.hpp:1114
SharedObject() noexcept=default
Initializes a new shared object.
auto shared_from_this(this TSelf &&self) noexcept
Returns a shared pointer to the current object instance.
Definition containers.hpp:1123
Evaluates, if an iterator of type TIterator iterates values that are covariant to TValue .
Definition containers.hpp:223
Evaluates if a type TCovariant behaves covariant to a value type TValue . In this context,...
Definition containers.hpp:215
Definition app.hpp:6
std::generator< T, TVal > Generator
Describes an intermediate container for elements of type T .
Definition containers.hpp:206
std::reference_wrapper< T > Ref
Represents a copyable and assignable reference wrapper.
Definition containers.hpp:145
constexpr UniquePtr< T > makeUnique()
Creates a new unique pointer.
Definition containers.hpp:153
std::tuple< T... > Tuple
Represents a tuple of multiple objects.
Definition containers.hpp:123
std::vector< T > Array
Represents a dynamic array.
Definition containers.hpp:73
std::optional< T > Optional
Represents an optional value.
Definition containers.hpp:94
std::shared_ptr< T > SharedPtr
Represents a shared pointer, that expresses non-exclusive ownership.
Definition containers.hpp:109
std::unique_ptr< T, TDeleter > UniquePtr
Represents a unique pointer, that expresses exclusive ownership.
Definition containers.hpp:102
std::unordered_map< TKey, TVal > Dictionary
Represents a dictionary that maps a key to a certain value.
Definition containers.hpp:66
constexpr SharedPtr< T > makeShared()
Creates a new shared pointer.
Definition containers.hpp:173
std::queue< T > Queue
Represents a queue.
Definition containers.hpp:80
std::span< T > Span
Represents a view of an array.
Definition containers.hpp:87
std::variant< T... > Variant
Represents a variant of objects.
Definition containers.hpp:130
void * Handle
Represents a handle type.
Definition containers.hpp:58
std::weak_ptr< T > WeakPtr
Represents a weak pointer, that expresses a reference to a shared pointer instance.
Definition containers.hpp:116
constexpr SharedPtr< T > asShared(UniquePtr< T > &&ptr)
Transfers a unique pointer to a shared pointer. The unique pointer will be released during this proce...
Definition containers.hpp:194
Wraps an iterator and returns covariants of type T of the iterated value.
Definition containers.hpp:236
~CovariantIterator() noexcept=default
Releases the iterator.
CovariantIterator(const CovariantIterator &_other)
Copies another iterator instance.
Definition containers.hpp:354
bool operator==(const CovariantIterator &_other) const
Checks if two iterators are equal, i.e. they are pointing to the same value.
Definition containers.hpp:428
CovariantIterator & operator++()
Increments the iterator position by one.
Definition containers.hpp:410
CovariantIterator & operator=(CovariantIterator &&_other)=default
Takes ownership over another iterator instances.
CovariantIterator()
Initializes a new iterator instance. Always throws a RuntimeException.
Definition containers.hpp:335
std::remove_reference_t< T > * pointer
The type of a pointer returned by the iterator.
Definition containers.hpp:256
T operator*() const
Returns a reference of the value at the current iterator position.
Definition containers.hpp:391
CovariantIterator & operator=(const CovariantIterator &_other)
Copies another iterator instance.
Definition containers.hpp:369
CovariantIterator operator++(int)
Increments the iterator position by one and returns the previous iterator.
Definition containers.hpp:419
CovariantIterator(const TIterator &it)
Initializes a new iterator instance.
Definition containers.hpp:346
pointer operator->()
Returns a pointer to the value at the current iterator position.
Definition containers.hpp:402
std::remove_cvref_t< T > value_type
The type of the value that is iterated.
Definition containers.hpp:241
std::forward_iterator_tag iterator_category
The category of the iterator.
Definition containers.hpp:246
std::ptrdiff_t difference_type
The type that expresses the difference between two iterators.
Definition containers.hpp:251
CovariantIterator(CovariantIterator &&_other) noexcept=default
Takes ownership over another iterator instances.
An input range over another range, where the returned values of type T are covariants of the values ...
Definition containers.hpp:529
Enumerable & operator=(Enumerable &&range) noexcept=default
auto begin() const
Returns an iterator pointing to the start of the underlying range.
Definition containers.hpp:644
~Enumerable() noexcept=default
CovariantIterator< T > iterator
The type of the iterator used to iterate the elements of the Enumerable.
Definition containers.hpp:549
auto cend() const
Returns a constant iterator pointing to the end of the underlying range.
Definition containers.hpp:668
std::remove_reference_t< T > * pointer
The type of a pointer returned by the Enumerable.
Definition containers.hpp:539
Enumerable(const Enumerable &range)=default
bool empty() const noexcept
Returns true, if there are no elements inside the Enumerable and false otherwise.
Definition containers.hpp:676
Enumerable & operator=(const Enumerable &range)=default
auto end() const
Returns an iterator pointing to the end of the underlying range.
Definition containers.hpp:652
Enumerable(Enumerable &&range) noexcept=default
std::remove_reference_t< T > & reference
The type of a reference returned by the Enumerable.
Definition containers.hpp:544
std::remove_cvref_t< T > value_type
The type of the value that is contained by the Enumerable.
Definition containers.hpp:534
CovariantIterator< const std::remove_const_t< T > > const_iterator
The type of the iterator used to iterate constant elements of the Enumerable.
Definition containers.hpp:554
auto cbegin() const
Returns a constant iterator pointing to the start of the underlying range.
Definition containers.hpp:660
Enumerable()
Creates an enumerable over an empty range.
Definition containers.hpp:616
An allocator used to allocate the shared object.
Definition containers.hpp:1098
void construct(TParent *parent, TArgs &&... args)
Definition containers.hpp:1100
A switch that can be used to select a callable from a parameter type.
Definition containers.hpp:136