summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2020-11-01 17:14:45 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2020-11-01 17:14:45 +0000
commit1ac16c9fbde1650dcee3729638d973359af2ab38 (patch)
tree2e88b698568b620be85e40852dde44289bc4a830
parentWrap throwing NoConversionFound for cropping up too often (diff)
downloadslicer-1ac16c9fbde1650dcee3729638d973359af2ab38.tar.bz2
slicer-1ac16c9fbde1650dcee3729638d973359af2ab38.tar.xz
slicer-1ac16c9fbde1650dcee3729638d973359af2ab38.zip
Improve conversion helpers
constness, constexpr, noexcept, local vars
-rw-r--r--slicer/slicer/modelPartsTraits.h103
-rw-r--r--slicer/slicer/modelPartsTypes.h8
-rw-r--r--slicer/slicer/modelPartsTypes.impl.h118
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;