diff options
| -rw-r--r-- | slicer/slicer/modelPartsTraits.h | 103 | ||||
| -rw-r--r-- | slicer/slicer/modelPartsTypes.h | 8 | ||||
| -rw-r--r-- | slicer/slicer/modelPartsTypes.impl.h | 118 | 
3 files changed, 124 insertions, 105 deletions
diff --git a/slicer/slicer/modelPartsTraits.h b/slicer/slicer/modelPartsTraits.h new file mode 100644 index 0000000..6213c9c --- /dev/null +++ b/slicer/slicer/modelPartsTraits.h @@ -0,0 +1,103 @@ +#ifndef SLICER_MODELPARTSTRAITS_H +#define SLICER_MODELPARTSTRAITS_H + +#include <Ice/Optional.h> +#include <functional> + +namespace Slicer { +	// Function traits helpers +	template<typename R, typename... Args> struct function_traits; + +	template<typename R, typename... Args> struct function_traits<std::function<R(Args...)>> { +		template<size_t A> struct arg { +			using type = std::tuple_element_t<A, std::tuple<Args...>>; +		}; +	}; + +	template<typename F> using callable_traits = function_traits<std::function<std::remove_pointer_t<F>>>; + +	template<typename F, size_t A> using callable_param = typename callable_traits<F>::template arg<A>::type; + +	// Converters that remove "optionalness". +	template<typename X> struct Coerce { +		using T = std::decay_t<X>; + +		[[nodiscard]] inline constexpr T & +		operator()(T & x) const noexcept +		{ +			return x; +		} + +		[[nodiscard]] inline constexpr const T & +		operator()(const T & x) const noexcept +		{ +			return x; +		} + +		template<typename Y> +		[[nodiscard]] inline constexpr T & +		operator()(Ice::optional<Y> & x) const noexcept +		{ +			if (!x) { +				x = Y(); +			} +			return *x; +		} + +		template<typename Y> +		[[nodiscard]] inline constexpr const T & +		operator()(const Ice::optional<Y> & x) const +		{ +			return *x; +		} + +		[[nodiscard]] inline constexpr static bool +		valueExists(const T &) noexcept +		{ +			return true; +		} + +		[[nodiscard]] inline constexpr static bool +		valueExists(const Ice::optional<T> & y) noexcept +		{ +			return y.has_value(); +		} +	}; + +	template<typename X> struct Coerce<Ice::optional<X>> { +		using T = std::decay_t<X>; + +		[[nodiscard]] inline constexpr Ice::optional<T> & +		operator()(Ice::optional<T> & x) const noexcept +		{ +			return x; +		} + +		[[nodiscard]] inline constexpr const Ice::optional<T> & +		operator()(const Ice::optional<T> & x) const noexcept +		{ +			return x; +		} + +		template<typename Y> +		[[nodiscard]] inline constexpr Ice::optional<T> +		operator()(Y & y) const noexcept +		{ +			return y; +		} + +		[[nodiscard]] inline constexpr static bool +		valueExists(const T &) noexcept +		{ +			return true; +		} + +		[[nodiscard]] inline constexpr static bool +		valueExists(const Ice::optional<T> &) noexcept +		{ +			return true; +		} +	}; +} + +#endif diff --git a/slicer/slicer/modelPartsTypes.h b/slicer/slicer/modelPartsTypes.h index ecc965a..e1e96d6 100644 --- a/slicer/slicer/modelPartsTypes.h +++ b/slicer/slicer/modelPartsTypes.h @@ -60,12 +60,12 @@ namespace Slicer {  	protected:  		[[noreturn]] void conversion_fail(std::string_view typeName);  		template<typename ET, typename MT, typename Conv> -		inline static bool tryConvertFrom(ValueSource & vsp, MT * model, const Conv & conv); -		template<typename ET, typename MT> inline static bool tryConvertFrom(ValueSource & vsp, MT * model); +		inline static bool tryConvertFrom(const ValueSource & vsp, MT * model, const Conv & conv); +		template<typename ET, typename MT> inline static bool tryConvertFrom(const ValueSource & vsp, MT * model);  		template<typename ET, typename MT, typename Conv> -		inline static TryConvertResult tryConvertTo(ValueTarget & vsp, const MT * model, const Conv & conv); +		inline static TryConvertResult tryConvertTo(const ValueTarget & vsp, const MT * model, const Conv & conv);  		template<typename ET, typename MT> -		inline static TryConvertResult tryConvertTo(ValueTarget & vsp, const MT * model); +		inline static TryConvertResult tryConvertTo(const ValueTarget & vsp, const MT * model);  	};  	template<typename T, typename M, T M::*MV> diff --git a/slicer/slicer/modelPartsTypes.impl.h b/slicer/slicer/modelPartsTypes.impl.h index af3f980..b332c08 100644 --- a/slicer/slicer/modelPartsTypes.impl.h +++ b/slicer/slicer/modelPartsTypes.impl.h @@ -4,6 +4,7 @@  #include "common.h"  #include "enumMap.h"  #include "hookMap.h" +#include "modelPartsTraits.h"  #include "modelPartsTypes.h"  #include <Ice/StreamHelpers.h>  #include <IceUtil/Optional.h> @@ -206,99 +207,16 @@ namespace Slicer {  		return (bool)*this->Model;  	} -	// Function traits helpers -	template<typename R, typename... Args> struct function_traits; -	template<typename R, typename... Args> struct function_traits<std::function<R(Args...)>> { -		template<int A> struct arg { -			using type = typename std::tuple_element<A, std::tuple<Args...>>::type; -		}; -	}; -	template<typename F> -	struct callable_traits : public function_traits<std::function<typename std::remove_pointer<F>::type>> { -	}; - -	// Converters that remove "optionalness". -	template<typename X> struct Coerce { -		using T = typename std::remove_const<typename std::remove_reference<X>::type>::type; - -		T & -		operator()(T & x) const -		{ -			return x; -		} -		const T & -		operator()(const T & x) const -		{ -			return x; -		} -		template<typename Y> -		T & -		operator()(Ice::optional<Y> & x) const -		{ -			if (!x) { -				x = Y(); -			} -			return *x; -		} -		template<typename Y> -		const T & -		operator()(const Ice::optional<Y> & x) const -		{ -			return *x; -		} -		static bool -		valueExists(const T &) -		{ -			return true; -		} -		static bool -		valueExists(const Ice::optional<T> & y) -		{ -			return y.has_value(); -		} -	}; -	template<typename X> struct Coerce<Ice::optional<X>> { -		using T = typename std::remove_const<typename std::remove_reference<X>::type>::type; - -		Ice::optional<T> & -		operator()(Ice::optional<T> & x) const -		{ -			return x; -		} -		const Ice::optional<T> & -		operator()(const Ice::optional<T> & x) const -		{ -			return x; -		} -		template<typename Y> -		Ice::optional<T> -		operator()(Y & y) const -		{ -			return y; -		} -		static bool -		valueExists(const T &) -		{ -			return true; -		} -		static bool -		valueExists(const Ice::optional<T> &) -		{ -			return true; -		} -	}; -  	template<typename ET, typename MT, typename Conv>  	inline bool -	ModelPartForConvertedBase::tryConvertFrom(ValueSource & vsp, MT * model, const Conv & conv) +	ModelPartForConvertedBase::tryConvertFrom(const ValueSource & vsp, MT * model, const Conv & conv)  	{ -		if (auto vspt = dynamic_cast<TValueSource<ET> *>(&vsp)) { -			using CA = typename callable_traits<Conv>::template arg<0>::type; +		if (auto vspt = dynamic_cast<const TValueSource<ET> *>(&vsp)) { +			using CA = callable_param<Conv, 0>;  			ET tmp;  			vspt->set(tmp); -			auto converted = conv(Coerce<CA>()(tmp)); -			if (Coerce<MT>::valueExists(converted)) { -				*model = Coerce<MT>()(converted); +			if (auto converted = conv(Coerce<CA>()(tmp)); Coerce<MT>::valueExists(converted)) { +				*model = Coerce<MT>()(std::move(converted));  			}  			return true;  		} @@ -307,9 +225,9 @@ namespace Slicer {  	template<typename ET, typename MT>  	inline bool -	ModelPartForConvertedBase::tryConvertFrom(ValueSource & vsp, MT * model) +	ModelPartForConvertedBase::tryConvertFrom(const ValueSource & vsp, MT * model)  	{ -		if (auto vspt = dynamic_cast<TValueSource<ET> *>(&vsp)) { +		if (auto vspt = dynamic_cast<const TValueSource<ET> *>(&vsp)) {  			if (Coerce<ET>::valueExists(*model)) {  				vspt->set(Coerce<ET>()(*model));  			} @@ -320,15 +238,13 @@ namespace Slicer {  	template<typename ET, typename MT, typename Conv>  	inline TryConvertResult -	ModelPartForConvertedBase::tryConvertTo(ValueTarget & vsp, const MT * model, const Conv & conv) -	{ -		if (auto vspt = dynamic_cast<TValueTarget<ET> *>(&vsp)) { -			using CA = typename callable_traits<Conv>::template arg<0>::type; -			using CAR = typename std::remove_const<typename std::remove_reference<CA>::type>::type; -			if (Coerce<CAR>::valueExists(*model)) { -				auto converted = conv(Coerce<CA>()(*model)); -				if (Coerce<ET>::valueExists(converted)) { -					vspt->get(Coerce<ET>()(converted)); +	ModelPartForConvertedBase::tryConvertTo(const ValueTarget & vsp, const MT * model, const Conv & conv) +	{ +		if (auto vspt = dynamic_cast<const TValueTarget<ET> *>(&vsp)) { +			using CA = callable_param<Conv, 0>; +			if (Coerce<std::decay_t<CA>>::valueExists(*model)) { +				if (auto converted = conv(Coerce<CA>()(*model)); Coerce<ET>::valueExists(converted)) { +					vspt->get(Coerce<ET>()(std::move(converted)));  					return TryConvertResult::Value;  				}  			} @@ -339,9 +255,9 @@ namespace Slicer {  	template<typename ET, typename MT>  	inline TryConvertResult -	ModelPartForConvertedBase::tryConvertTo(ValueTarget & vsp, const MT * model) +	ModelPartForConvertedBase::tryConvertTo(const ValueTarget & vsp, const MT * model)  	{ -		if (auto vspt = dynamic_cast<TValueTarget<ET> *>(&vsp)) { +		if (auto vspt = dynamic_cast<const TValueTarget<ET> *>(&vsp)) {  			if (Coerce<ET>::valueExists(*model)) {  				vspt->get(Coerce<ET>()(*model));  				return TryConvertResult::Value;  | 
