Library: draft for a visitor-like VerbToken
this is a generalisation of what we use in the diff framework; typically you'd package the VerbToken into some kind of container, together with the concrete invocation argument. However, the specific twist here is that we want *variable arguments*, depending on the actual operation called on the interpreter interface.
This commit is contained in:
parent
500af8aa34
commit
9b5fdd39b8
2 changed files with 81 additions and 0 deletions
|
|
@ -48,12 +48,15 @@
|
||||||
#define LIB_VERB_VISITOR_H
|
#define LIB_VERB_VISITOR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "lib/meta/variadic-helper.hpp"
|
||||||
|
#include "lib/polymorphic-value.hpp"
|
||||||
#include "lib/symbol.hpp"
|
#include "lib/symbol.hpp"
|
||||||
#include "lib/util.hpp"
|
#include "lib/util.hpp"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
|
|
@ -128,6 +131,79 @@ namespace lib {
|
||||||
|
|
||||||
#define VERB(RECEIVER, FUN) VERB_##FUN (&RECEIVER::FUN, STRINGIFY(FUN))
|
#define VERB(RECEIVER, FUN) VERB_##FUN (&RECEIVER::FUN, STRINGIFY(FUN))
|
||||||
|
|
||||||
|
using JustSomeIrrelvantType = struct{};
|
||||||
|
const size_t VERB_TOKEN_SIZE = sizeof(VerbToken<JustSomeIrrelvantType, void(void)>);
|
||||||
|
|
||||||
|
template<class REC, class RET>
|
||||||
|
struct Hook
|
||||||
|
{
|
||||||
|
virtual ~Hook() { }
|
||||||
|
|
||||||
|
virtual RET applyTo (REC&) =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class REC, class SIG>
|
||||||
|
struct Holder;
|
||||||
|
|
||||||
|
template<class REC, class RET, typename... ARGS>
|
||||||
|
struct Holder<REC, RET(ARGS...)>
|
||||||
|
: polyvalue::CopySupport< // mix-in virtual copy/move support
|
||||||
|
Hook<REC,RET>> // ...the common interface to use
|
||||||
|
{
|
||||||
|
using Verb = VerbToken<REC,RET(ARGS...)>;
|
||||||
|
using Args = std::tuple<ARGS...>;
|
||||||
|
|
||||||
|
/** meta-sequence to pick argument values from the storage tuple */
|
||||||
|
using SequenceIterator = typename meta::BuildIdxIter<ARGS...>::Ascending;
|
||||||
|
|
||||||
|
Verb verb_;
|
||||||
|
Args args_;
|
||||||
|
|
||||||
|
Holder (typename Verb::Handler handlerRef, Literal verbID, ARGS... args)
|
||||||
|
: verb_{handlerRef, verbID}
|
||||||
|
, args_{std::forward<ARGS> (args)...}
|
||||||
|
{ }
|
||||||
|
|
||||||
|
RET
|
||||||
|
applyTo (REC& receiver) override
|
||||||
|
{
|
||||||
|
return invokeVerb (receiver, SequenceIterator());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t...idx>
|
||||||
|
RET
|
||||||
|
invokeVerb (REC& receiver, meta::IndexSeq<idx...>)
|
||||||
|
{
|
||||||
|
return verb_.applyTo (receiver, std::get<idx> (args_)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr size_t
|
||||||
|
storageOverhead(size_t argStorage)
|
||||||
|
{
|
||||||
|
return argStorage + VERB_TOKEN_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class REC, class RET, size_t arg_storage>
|
||||||
|
class VerbPack
|
||||||
|
: public PolymorphicValue<Hook<REC,RET>, storageOverhead(arg_storage)>
|
||||||
|
{
|
||||||
|
using PolyHolder = PolymorphicValue<Hook<REC,RET>, storageOverhead(arg_storage)>;
|
||||||
|
|
||||||
|
template<typename...ARGS>
|
||||||
|
using PayloadType = Holder<REC, RET(ARGS...)>*;
|
||||||
|
|
||||||
|
template<typename...ARGS>
|
||||||
|
using Handler = typename VerbToken<REC, RET(ARGS...)>::Handler;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename...ARGS>
|
||||||
|
VerbPack (Handler<ARGS...> handler, Literal verbID, ARGS&&... args)
|
||||||
|
: PolyHolder(PayloadType<ARGS...>(), handler, verbID, std::forward<ARGS>(args)...)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "lib/test/run.hpp"
|
#include "lib/test/run.hpp"
|
||||||
|
//#include "lib/verb-token.hpp"
|
||||||
#include "lib/verb-visitor.hpp"
|
#include "lib/verb-visitor.hpp"
|
||||||
#include "lib/format-string.hpp"
|
#include "lib/format-string.hpp"
|
||||||
#include "lib/format-cout.hpp"
|
#include "lib/format-cout.hpp"
|
||||||
|
|
@ -136,6 +137,10 @@ namespace test{
|
||||||
VerbSeq tokens = build_test_feed();
|
VerbSeq tokens = build_test_feed();
|
||||||
render_verbose (tokens);
|
render_verbose (tokens);
|
||||||
verify_dispatch (tokens);
|
verify_dispatch (tokens);
|
||||||
|
|
||||||
|
VerbPack<Receiver, string, sizeof(void*)> woof(&Receiver::woof, "woof");
|
||||||
|
|
||||||
|
// profile.append_woof(1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue