5#pragma warning(disable: 4251)
14#include <forward_list>
29#ifdef __cpp_lib_mdspan
35#include "exceptions.hpp"
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; }
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))
65 template<
class TKey,
class TVal>
101 template<
class T,
class TDeleter = std::default_delete<T>>
122 template <
class... T>
129 template <
class... T>
135 template<
class... TArgs>
137 using TArgs::operator()...;
145 using Ref = std::reference_wrapper<T>;
154 return std::make_unique<T>();
162 template <
class T,
class... TArgs>
164 return std::make_unique<T>(std::forward<TArgs>(_args)...);
174 return std::make_shared<T>();
182 template <
class T,
class... TArgs>
184 return std::make_shared<T>(std::forward<TArgs>(_args)...);
205 template <
typename T,
typename TVal =
void>
214 template <
typename TValue,
typename TCovariant>
215 concept is_covariant = std::is_assignable_v<TCovariant, TValue> || std::is_constructible_v<TCovariant, TValue>;
222 template <
typename TIterator,
typename TValue>
235 template <
typename T>
259 struct iterator_base {
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;
268 virtual ~iterator_base()
noexcept =
default;
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;
277 template <covariant_forward_iterator<T> TIterator>
278 struct wrapped_iterator final :
public iterator_base {
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;
290 inline wrapped_iterator(TIterator it) :
294 inline ~wrapped_iterator() noexcept override = default;
296 inline T operator*()
const override {
300 inline iterator_base& operator++()
override {
305 inline std::unique_ptr<iterator_base> operator++(
int)
override {
306 return std::make_unique<wrapped_iterator>(_it++);
309 inline bool operator==(
const iterator_base& _other)
const noexcept override {
311 return this->_it ==
static_cast<const wrapped_iterator&
>(_other)._it;
314 inline std::unique_ptr<iterator_base> copy()
const override {
315 return std::make_unique<wrapped_iterator>(_it);
319 std::unique_ptr<iterator_base> _iterator{
nullptr };
320 std::type_index _iterator_type{
typeid(iterator_base) };
323 CovariantIterator(std::unique_ptr<iterator_base>&& iterator, std::type_index iterator_type) :
324 _iterator(std::move(iterator)), _iterator_type(iterator_type)
337 throw RuntimeException(
"Default-initializing `CovariantIterator` is not supported!");
345 template <
typename TIterator>
347 _iterator(std::make_unique<wrapped_iterator<TIterator>>(it)), _iterator_type(typeid(TIterator))
355 _iterator(_other._iterator->copy()), _iterator_type(_other._iterator_type)
370 _iterator = _other._iterator->copy();
371 _iterator_type = _other._iterator_type;
391 inline T operator*()
const {
392 return _iterator->operator*();
411 _iterator->operator++();
420 return { (*_iterator)++, _iterator_type };
429 if (this->_iterator_type != _other._iterator_type)
432 return _iterator->operator==(*_other._iterator);
528 template <
typename T>
557 struct range_holder_base {
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;
566 virtual ~range_holder_base()
noexcept =
default;
574 template <std::ranges::viewable_range TRange>
575 struct range_holder final :
public range_holder_base {
577 TRange _stored_range;
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;
587 inline range_holder(TRange&& range) :
588 _stored_range(std::move(range))
591 inline ~range_holder() noexcept override = default;
594 return { std::ranges::begin(_stored_range) };
598 return { std::ranges::end(_stored_range) };
602 return { std::ranges::begin(_stored_range) };
606 return { std::ranges::end(_stored_range) };
610 std::shared_ptr<range_holder_base> _range{ };
632 template <typename TRange, typename enabled = std::enable_if_t<!std::is_same_v<TRange,
Enumerable>>>
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));
645 return _range->begin();
653 return _range->end();
661 return _range->cbegin();
669 return _range->cend();
676 inline bool empty() const noexcept {
677 return this->
begin() == this->
end();
681#if (defined(BUILD_LITEFX_PIMPL) && BUILD_LITEFX_PIMPL) || (!defined(BUILD_LITEFX_PIMPL)) && !defined(LITEFX_IMPLEMENTATION)
686 template <
class pImpl>
706 template <
typename... TArgs>
708 m_ptr(
makeShared<pImpl>(std::forward<TArgs>(args)...)) { }
754 constexpr pImpl& operator* () const noexcept {
777# define LITEFX_IMPLEMENTATION(impl) private: \
779 PimplPtr<impl> m_impl; \
780 friend class PimplPtr<impl>; \
791 template <
class THandle>
815 virtual const THandle&
handle() const noexcept = 0;
822 template <class THandle>
846 THandle&
handle() noexcept
override {
return m_handle; }
850 const THandle&
handle() const noexcept
override {
return m_handle; }
874 template <
typename T,
typename TParent = std::
nullptr_t,
typename TPo
inter = UniquePtr<T>>
883 template <
typename T,
typename TPo
inter>
898 constexpr const T*
instance() const noexcept {
return m_instance.get(); }
905 constexpr T*
instance() noexcept {
return m_instance.get(); }
912 constexpr explicit Builder(TPointer&& instance) noexcept : m_instance(std::move(instance)) { }
918 constexpr Builder(
Builder&& _other) noexcept : m_instance(std::move(_other.m_instance)) { }
924 constexpr virtual ~
Builder() noexcept = default;
930 constexpr virtual
void build() { };
941 template <
typename TInstance>
947 [[nodiscard]] constexpr operator TPointer&& () {
949 return std::move(m_instance);
959 template <
typename T,
typename TParent,
typename TPo
inter>
975 constexpr const T*
instance() const noexcept {
return m_instance.get(); }
981 constexpr const TParent&
parent() const noexcept {
return *m_parent; }
988 constexpr T*
instance() noexcept {
return m_instance.get(); }
996 constexpr explicit Builder(TParent& parent, TPointer&& instance) noexcept : m_instance(std::move(instance)), m_parent(&parent) { }
1002 constexpr Builder(
Builder&& _other) noexcept : m_instance(std::move(_other.m_instance)), m_parent(_other.m_parent) { }
1013 constexpr virtual
void build() { };
1024 template <
typename TInstance>
1030 [[nodiscard]] constexpr TParent& add() {
1032 m_parent->use(std::move(m_instance));
1039#if !defined(LITEFX_BUILDER)
1040# define LITEFX_BUILDER(BuilderType) public: \
1041 using builder_type = BuilderType; \
1042 friend class BuilderType;
1097 template <typename T>
1099 template<
typename TParent,
typename... TArgs>
1101 ::new(
static_cast<void*
>(parent)) TParent(std::forward<TArgs>(args)...);
1113 template <
typename T,
typename... TArgs>
1115 return std::allocate_shared<T>(
Allocator<T>{}, std::forward<TArgs>(args)...);
1122 template <
typename TSelf>
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());
1132 template <
typename TSelf>
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());
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
Builder(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
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