diff --git a/src/pvxs/client.h b/src/pvxs/client.h index 9fe0120..bc0c80f 100644 --- a/src/pvxs/client.h +++ b/src/pvxs/client.h @@ -424,7 +424,7 @@ public: */ template SubBuilder& record(const std::string& name, const T& val) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); this->_record(name, &norm, impl::StoreAs::code); return _sb(); } @@ -506,7 +506,7 @@ public: template PutBuilder& set(const std::string& name, const T& val, bool required=true) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); return set(name, &norm, impl::StoreAs::code, required); } @@ -563,7 +563,7 @@ public: template RPCBuilder& arg(const std::string& name, const T& val) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); _set(name, &norm, impl::StoreAs::code, true); return *this; } diff --git a/src/pvxs/data.h b/src/pvxs/data.h index f0ca8dd..d821656 100644 --- a/src/pvxs/data.h +++ b/src/pvxs/data.h @@ -79,8 +79,8 @@ template<> struct StorageMap { typedef std::string store_t; static constexpr StoreType code{StoreType::String}; }; -template<> -struct StorageMap> +template +struct StorageMap> { typedef shared_array store_t; static constexpr StoreType code{StoreType::Array}; }; template<> @@ -90,6 +90,25 @@ struct StorageMap template using StoreAs = StorageMap::type>; +template +struct StoreTransform { + // pass through by default + static inline const T& in (const T& v) { return v; } + static inline const T& out(const T& v) { return v; } +}; +template +struct StoreTransform> { + // cast shared_array to void + static inline + shared_array in(const shared_array& v) { + return v.template castTo(); + } + static inline + shared_array out(const shared_array& v) { + return v.template castTo(); + } +}; + } // namespace impl //! Groups of related types @@ -536,7 +555,7 @@ public: inline T as() const { typename impl::StoreAs::store_t ret; copyOut(&ret, impl::StoreAs::code); - return ret; + return impl::StoreTransform::out(ret); } //! Attempt to extract value from field. @@ -546,7 +565,7 @@ public: typename impl::StoreAs::store_t temp; auto ret = tryCopyOut(&temp, impl::StoreAs::code); if(ret) { - val = temp; + val = impl::StoreTransform::out(temp); } return ret; } @@ -558,7 +577,7 @@ public: void as(FN&& fn) const { typename impl::StoreAs::store_t val; if(tryCopyOut(&val, impl::StoreAs::code)) { - fn(val); + fn(impl::StoreTransform::out(val)); } } @@ -566,7 +585,7 @@ public: //! @returns false if from() would throw NoField or NoConvert template inline bool tryFrom(const T& val) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); return copyIn(&norm, impl::StoreAs::code); } @@ -583,7 +602,7 @@ public: */ template void from(const T& val) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); copyIn(&norm, impl::StoreAs::code); } diff --git a/test/testpvreq.cpp b/test/testpvreq.cpp index 25c8bfa..a6fdeab 100644 --- a/test/testpvreq.cpp +++ b/test/testpvreq.cpp @@ -34,7 +34,7 @@ struct TestBuilder : client::detail::CommonBuilder TestBuilder& set(const std::string& name, const T& val, bool required=true) { - typename impl::StoreAs::store_t norm(val); + const typename impl::StoreAs::store_t& norm(impl::StoreTransform::in(val)); _set(name, &norm, impl::StoreAs::code, required); return *this; } diff --git a/test/testxcode.cpp b/test/testxcode.cpp index 0047a92..1c80cc1 100644 --- a/test/testxcode.cpp +++ b/test/testxcode.cpp @@ -340,7 +340,7 @@ void testDeserialize2() }); testOk1(!!val["value"].isMarked()); testOk1(!val["arbitrary.sarr"].isMarked()); - testArrEq(val["value"].as>().castTo(), + testArrEq(val["value"].as>(), shared_array({1u, 0xdeadbeef, 2u})); } @@ -528,7 +528,7 @@ void testArrayXCodeT(const char(&encoded)[N], std::initializer_list values) testToBytes(true, [&expected, &def](Buffer& buf) { auto val = def.create(); - val["value"] = expected.template castTo(); + val["value"] = expected; to_wire_valid(buf, val); }, encoded); @@ -540,7 +540,7 @@ void testArrayXCodeT(const char(&encoded)[N], std::initializer_list values) from_wire_valid(buf, ctxt, val2); }); - testArrEq(expected, val2["value"].as>().castTo()); + testArrEq(expected, val2["value"].as>()); } void testArrayXCode()