From fbe7e81c08a6b5a3f9ccdcbeb4dd4d351a5f4226 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 31 Oct 2021 22:16:55 +0200 Subject: [PATCH] Use variadic templates and forwarding references for better flexibility --- source/loader.h | 22 +++++++++++++--------- source/loaderaction.h | 19 ++++++++++--------- source/objectloader.h | 6 ++---- source/value.h | 7 ++++--- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/source/loader.h b/source/loader.h index 648c414..b9eee50 100644 --- a/source/loader.h +++ b/source/loader.h @@ -85,10 +85,10 @@ protected: /** Loads a sub-object from the statement being processed with an extra parameter for the Loader. The Loader class of the sub-object is automatically used. */ - template - void load_sub(S &s, T &p) + template + void load_sub(S &s, Args &&... args) { - typename S::Loader ldr(s, p); + typename S::Loader ldr(s, std::forward(args)...); load_sub_with(ldr); } @@ -119,6 +119,10 @@ protected: void add(const std::string &k, void (L::*func)(B0, Args...), const typename std::remove_reference::type &b0) { add(k, new LoaderFuncNBound1(func, b0)); } + template + void add(const std::string &k, void (L::*func)(B0, Args...), B0 &&b0) + { add(k, new LoaderFuncNBound1(func, std::forward(b0))); } + /** Adds a keyword that is loaded into a member of the loaded object. */ template void add(const std::string &k, T0 L::*p0) @@ -161,12 +165,12 @@ Loads an object from a file. The object must have a public Loader class. Any extra arguments are passed to the Loader constructor. */ template -void load(T &obj, const std::string &fn, Args &... args) +void load(T &obj, const std::string &fn, Args &&... args) { IO::BufferedFile in(fn); Parser parser(in, fn); - typename T::Loader loader(obj, args...); + typename T::Loader loader(obj, std::forward(args)...); loader.load(parser); } @@ -176,14 +180,14 @@ public Loader class. The collection is passed to the Loader constructor, followed by any extra arguments. */ template -void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &... args) +void load(T &obj, typename T::Loader::Collection &coll, const std::string &fn, Args &&... args) { RefPtr in = coll.open_raw(fn); if(!in) throw IO::file_not_found(fn); Parser parser(*in, fn); - typename T::Loader loader(obj, coll, args...); + typename T::Loader loader(obj, coll, std::forward(args)...); loader.load(parser); } @@ -192,14 +196,14 @@ Loads an object from a file stored in a collection. The object must havea public Loader class. Any extra arguments are passed to the Loader constructor. */ template -typename std::enable_if::value>::type load(T &obj, C &coll, const std::string &fn, Args &... args) +typename std::enable_if::value>::type load(T &obj, C &coll, const std::string &fn, Args &&... args) { RefPtr in = coll.open_raw(fn); if(!in) throw IO::file_not_found(fn); Parser parser(*in, fn); - typename T::Loader loader(obj, args...); + typename T::Loader loader(obj, std::forward(args)...); loader.load(parser); } diff --git a/source/loaderaction.h b/source/loaderaction.h index 9d5baae..2329842 100644 --- a/source/loaderaction.h +++ b/source/loaderaction.h @@ -174,15 +174,15 @@ template struct Apply { template - static void apply(L &l, F func, const Statement &, Args... args) + static void apply(L &l, F func, const Statement &, Args &&... args) { - (l.*func)(args...); + (l.*func)(std::forward(args)...); } template - static void apply(L &l, F func, const ArgumentStore &, Args... args) + static void apply(L &l, F func, const ArgumentStore &, Args &&... args) { - (l.*func)(args...); + (l.*func)(std::forward(args)...); } }; @@ -190,15 +190,15 @@ template struct Apply { template - static void apply(L &l, F func, const Statement &st, Args... args) + static void apply(L &l, F func, const Statement &st, Args &&... args) { - Apply::apply(l, func, st, args..., st.args[I].get()); + Apply::apply(l, func, st, std::forward(args)..., std::move(st.args[I].get())); } template - static void apply(L &l, F func, const ArgumentStore &as, Args... args) + static void apply(L &l, F func, const ArgumentStore &as, Args &&... args) { - Apply::apply(l, func, as, args..., as.get(I)); + Apply::apply(l, func, as, std::forward(args)..., std::move(as.get(I))); } }; @@ -240,7 +240,8 @@ protected: Bound0Type bound0; public: - LoaderFuncNBound1(FuncType f, const Bound0Type &b0): func(f), bound0(b0) { } + LoaderFuncNBound1(FuncType f, const B0 &b0): func(f), bound0(b0) { } + LoaderFuncNBound1(FuncType f, B0 &&b0): func(f), bound0(std::move(b0)) { } virtual void execute(Loader &l, const Statement &st) const { diff --git a/source/objectloader.h b/source/objectloader.h index 4c5dd02..978366f 100644 --- a/source/objectloader.h +++ b/source/objectloader.h @@ -42,10 +42,8 @@ public: protected: O &obj; - DerivedObjectLoader(O &o): B(o), obj(o) { } - - template - DerivedObjectLoader(O &o, T &a): B(o, a), obj(o) { } + template + DerivedObjectLoader(O &o, Args &&... a): B(o, std::forward(a)...), obj(o) { } public: O &get_object() const { return obj; } diff --git a/source/value.h b/source/value.h index c272bcf..bcddd6e 100644 --- a/source/value.h +++ b/source/value.h @@ -18,12 +18,13 @@ private: public: template - Value(T d): + Value(T &&d): sig(TypeInfo::signature), - data(static_cast::Store>(d)) + data(static_cast::Store>(std::forward(d))) { } - Value(Symbol d): sig(TypeInfo::signature), data(d) { } + Value(const Symbol &d): sig(TypeInfo::signature), data(d) { } + Value(Symbol &&d): sig(TypeInfo::signature), data(std::move(d)) { } template typename TypeInfo::Load get() const -- 2.43.0