From 0723909c26b13a78c66bdd900e977ab112f90c6a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 8 Feb 2019 21:38:42 +0000 Subject: Extract the real function parameter type Includes demonstrable use of string_view in an interface and makes use of the the end-to-end string_view support --- icespider/compile/routeCompiler.cpp | 22 ++++++++------- icespider/core/irouteHandler.h | 6 +++++ icespider/unittests/Jamfile.jam | 1 + icespider/unittests/string_view_support.h | 45 +++++++++++++++++++++++++++++++ icespider/unittests/test-api.ice | 4 ++- icespider/unittests/testApp.cpp | 4 +-- 6 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 icespider/unittests/string_view_support.h diff --git a/icespider/compile/routeCompiler.cpp b/icespider/compile/routeCompiler.cpp index b7db3ca..7bb44d4 100644 --- a/icespider/compile/routeCompiler.cpp +++ b/icespider/compile/routeCompiler.cpp @@ -13,6 +13,7 @@ namespace IceSpider { + using namespace AdHoc::literals; namespace Compile { RouteCompiler::RouteCompiler() { @@ -436,36 +437,37 @@ namespace IceSpider { for (const auto & p : r.second->params) { if (p.second->hasUserSource) { auto ip = ps.find(p.first)->second; + const auto paramType = "std::remove_cvref<%?>::type"_fmt( + Slice::inputTypeToString(ip->type(), false, "", ip->getMetaData())); if (p.second->source == ParameterSource::Body) { if (p.second->key) { if (!doneBody) { if (p.second->type) { - fprintbf(4, output, "auto _pbody(request->getBody<%s>());\n", + fprintbf(4, output, "const auto _pbody(request->getBody<%s>());\n", *p.second->type); } else { - fprintbf(4, output, "auto _pbody(request->getBody());\n"); + fprintbf(4, output, "const auto _pbody(request->getBody());\n"); } doneBody = true; } if (p.second->type) { - fprintbf(4, output, "auto _p_%s(_pbody->%s", + fprintbf(4, output, "const auto _p_%s(_pbody->%s", p.first, p.first); } else { - fprintbf(4, output, "auto _p_%s(request->getBodyParam<%s>(_pbody, _pn_%s)", - p.first, Slice::typeToString(ip->type()), - p.first); + fprintbf(4, output, "const auto _p_%s(request->getBodyParam<%s>(_pbody, _pn_%s)", + p.first, paramType, p.first); } } else { - fprintbf(4, output, "auto _p_%s(request->getBody<%s>()", - p.first, Slice::typeToString(ip->type())); + fprintbf(4, output, "const auto _p_%s(request->getBody<%s>()", + p.first, paramType); } } else { - fprintbf(4, output, "auto _p_%s(request->get%sParam<%s>(_p%c_%s)", - p.first, getEnumString(p.second->source), Slice::typeToString(ip->type()), + fprintbf(4, output, "const auto _p_%s(request->get%sParam<%s>(_p%c_%s)", + p.first, getEnumString(p.second->source), paramType, p.second->source == ParameterSource::URL ? 'i' : 'n', p.first); } diff --git a/icespider/core/irouteHandler.h b/icespider/core/irouteHandler.h index f80c240..ad25ea2 100644 --- a/icespider/core/irouteHandler.h +++ b/icespider/core/irouteHandler.h @@ -49,6 +49,12 @@ namespace IceSpider { typedef AdHoc::Factory RouteHandlerFactory; } +#if __cplusplus < 201709 +namespace std { + template using remove_cvref = typename std::remove_cv::type>; +} +#endif + #endif diff --git a/icespider/unittests/Jamfile.jam b/icespider/unittests/Jamfile.jam index fc2d275..352d665 100644 --- a/icespider/unittests/Jamfile.jam +++ b/icespider/unittests/Jamfile.jam @@ -138,5 +138,6 @@ lib test-api : adhocutil ..//pthread ..//Ice + . ; diff --git a/icespider/unittests/string_view_support.h b/icespider/unittests/string_view_support.h new file mode 100644 index 0000000..ef9fb94 --- /dev/null +++ b/icespider/unittests/string_view_support.h @@ -0,0 +1,45 @@ +#ifndef ICETRAY_STRING_VIEW_SUPPORT_H +#define ICETRAY_STRING_VIEW_SUPPORT_H + +#include +#include +#include + +namespace Ice +{ + template<> + struct StreamableTraits + { + static const StreamHelperCategory helper = StreamHelperCategoryBuiltin; + static const int minWireSize = 1; + static const bool fixedLength = false; + }; + + template<> + struct StreamHelper { + template static inline void + write(S * stream, const std::string_view& v) + { + stream->write(v.data(), v.size()); + } + + template static inline void + read(S * stream, std::string_view& v) + { + const char* vdata = 0; + size_t vsize = 0; + + stream->read(vdata, vsize); + + if (vsize > 0) { + v = std::string_view(vdata, vsize); + } + else { + v = {}; + } + } + }; +} + +#endif + diff --git a/icespider/unittests/test-api.ice b/icespider/unittests/test-api.ice index c89e0fc..f92a5cd 100644 --- a/icespider/unittests/test-api.ice +++ b/icespider/unittests/test-api.ice @@ -1,3 +1,5 @@ +#define stringview ["cpp:view-type:std::string_view"] string +[["cpp:include:string_view_support.h"]] module TestIceSpider { class SomeModel { string value; @@ -24,7 +26,7 @@ module TestIceSpider { string simplei(int i); SomeModel index(); SomeModel withParams(string s, int i) throws Ex; - void returnNothing(string s) throws Ex; + void returnNothing(stringview s) throws Ex; void complexParam(optional(0) string s, SomeModel m); }; interface DummyPlugin { diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp index e76e85c..cd43674 100644 --- a/icespider/unittests/testApp.cpp +++ b/icespider/unittests/testApp.cpp @@ -150,13 +150,13 @@ class TestSerice : public TestIceSpider::TestApi { return std::make_shared("withParams"); } - void returnNothing(const std::string s, const Ice::Current &) override + void returnNothing(const std::string_view s, const Ice::Current &) override { if (s == "error") { throw TestIceSpider::Ex("test error"); } else if (s.length() == 3) { - throw TestIceSpider::Ex(s); + throw TestIceSpider::Ex(std::string(s)); } BOOST_REQUIRE_EQUAL(s, "some value"); } -- cgit v1.2.3