diff options
author | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-11-01 17:14:45 +0000 |
---|---|---|
committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-11-01 17:14:45 +0000 |
commit | 1ac16c9fbde1650dcee3729638d973359af2ab38 (patch) | |
tree | 2e88b698568b620be85e40852dde44289bc4a830 | |
parent | Wrap throwing NoConversionFound for cropping up too often (diff) | |
download | slicer-1ac16c9fbde1650dcee3729638d973359af2ab38.tar.bz2 slicer-1ac16c9fbde1650dcee3729638d973359af2ab38.tar.xz slicer-1ac16c9fbde1650dcee3729638d973359af2ab38.zip |
Improve conversion helpers
constness, constexpr, noexcept, local vars
-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; |