diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-22 11:50:31 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2025-03-22 11:50:31 +0000 | 
| commit | 9fd25e8b10b1291525a18c8b3e34256ca6151dd6 (patch) | |
| tree | c483b55010f310ed60cb7381130feedd2b3980a9 /lib | |
| parent | Support resizing the main window (diff) | |
| download | ilt-9fd25e8b10b1291525a18c8b3e34256ca6151dd6.tar.bz2 ilt-9fd25e8b10b1291525a18c8b3e34256ca6151dd6.tar.xz ilt-9fd25e8b10b1291525a18c8b3e34256ca6151dd6.zip | |
Add ManyPtr which tracks specified subclasses
This removes the need to repeated dynamic_cast the pointer.
Provides interface which enforces the fastest option for the required
types.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/manyPtr.h | 86 | ||||
| -rw-r--r-- | lib/persistence.h | 3 | 
2 files changed, 88 insertions, 1 deletions
| diff --git a/lib/manyPtr.h b/lib/manyPtr.h new file mode 100644 index 0000000..9e08452 --- /dev/null +++ b/lib/manyPtr.h @@ -0,0 +1,86 @@ +#pragma once + +#include <memory> +#include <tuple> + +template<typename Primary, typename... Others> class ManyPtr : Primary { +public: +	using element_type = typename Primary::element_type; + +	template<typename... Params> ManyPtr(Params &&... params) : Primary {std::forward<Params>(params)...} +	{ +		updatePtrs(); +	} + +	using Primary::operator->; +	using Primary::operator*; +	using Primary::operator bool; +	using Primary::get; + +	template<typename... Params> +	void +	reset(Params &&... params) +	{ +		Primary::reset(std::forward<Params>(params)...); +		updatePtrs(); +	} + +	template<typename Other> +	[[nodiscard]] consteval static bool +	couldBe() +	{ +		return (std::is_convertible_v<Others *, Other *> || ...); +	} + +	template<typename Other> +		requires(couldBe<Other>()) +	[[nodiscard]] auto +	getAs() const +	{ +		return std::get<idx<Other>()>(others); +	} + +	template<typename Other> +		requires(!couldBe<Other>() && requires { std::dynamic_pointer_cast<Other>(std::declval<Primary>()); }) +	[[nodiscard]] auto +	dynamicCast() const +	{ +		return std::dynamic_pointer_cast<Other>(*this); +	} + +	template<typename Other> +		requires(!couldBe<Other>() && !requires { std::dynamic_pointer_cast<Other>(std::declval<Primary>()); }) +	[[nodiscard]] auto +	dynamicCast() const +	{ +		return dynamic_cast<Other *>(get()); +	} + +private: +	using OtherPtrs = std::tuple<Others *...>; + +	template<typename Other> +		requires(couldBe<Other>()) +	[[nodiscard]] consteval static bool +	idx() +	{ +		size_t typeIdx = 0; +		return ((typeIdx++ && std::is_convertible_v<Others *, Other *>) || ...); +	} + +	void +	updatePtrs() +	{ +		if (*this) { +			others = {dynamic_cast<Others *>(get())...}; +		} +		else { +			others = {}; +		} +	} + +	OtherPtrs others; +}; + +template<typename Primary, typename... Others> using ManySharedPtr = ManyPtr<std::shared_ptr<Primary>, Others...>; +template<typename Primary, typename... Others> using ManyUniquePtr = ManyPtr<std::unique_ptr<Primary>, Others...>; diff --git a/lib/persistence.h b/lib/persistence.h index e385b20..75bcea6 100644 --- a/lib/persistence.h +++ b/lib/persistence.h @@ -1,5 +1,6 @@  #pragma once +#include "manyPtr.h"  #include <charconv>  #include <format>  #include <functional> @@ -200,7 +201,7 @@ namespace Persistence {  		}  		[[nodiscard]] virtual NameActionSelection setName(const std::string_view key, SelectionFactory &&) = 0; -		virtual void selHandler() {}; +		virtual void selHandler() { };  		virtual void setType(const std::string_view, const Persistable *) = 0;  		SelectionPtr sel {}; | 
