factor out util function to "stringify" arbitrary arguments
this function is of use also for creating a vector of strings from a bunch of C-Strings, but it could also be used to construct other stuff initialised by strings (e.g. RegExps)
This commit is contained in:
parent
33f7fe116a
commit
941fe3a9b9
2 changed files with 79 additions and 32 deletions
|
|
@ -46,6 +46,7 @@
|
|||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
#include <typeinfo>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
|
@ -66,6 +67,7 @@ namespace util {
|
|||
using lib::Symbol;
|
||||
using util::isnil;
|
||||
using std::string;
|
||||
using std::move;
|
||||
|
||||
|
||||
namespace { // we need to guard the string conversion
|
||||
|
|
@ -184,6 +186,72 @@ namespace util {
|
|||
: tyStr(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace { // helper to convert arbitrary elements toString
|
||||
|
||||
template<class CON>
|
||||
inline void
|
||||
do_stringify(CON&)
|
||||
{ /* do nothing */ }
|
||||
|
||||
template<class CON, typename X, typename...ELMS>
|
||||
inline void
|
||||
do_stringify(CON& container, X const& elm, ELMS const& ...args)
|
||||
{
|
||||
container += util::str(elm);
|
||||
do_stringify (container, args...);
|
||||
}
|
||||
|
||||
|
||||
template<class CON, typename...ELMS>
|
||||
struct SeqContainer
|
||||
: CON
|
||||
{
|
||||
void
|
||||
operator+= (string&& s)
|
||||
{
|
||||
CON::push_back (move(s));
|
||||
}
|
||||
};
|
||||
|
||||
// most common case: use a vector container...
|
||||
using std::vector;
|
||||
|
||||
template<typename X, typename...ELMS>
|
||||
struct SeqContainer<vector<X>, ELMS...>
|
||||
:vector<X>
|
||||
{
|
||||
SeqContainer()
|
||||
{
|
||||
this->reserve(sizeof...(ELMS));
|
||||
}
|
||||
|
||||
void
|
||||
operator+= (string&& s)
|
||||
{
|
||||
this->emplace_back (move(s));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/** convert a sequence of elements to string
|
||||
* @param elms sequence of arbitrary elements
|
||||
* @return a collection of type CON, initialised by the
|
||||
* string representation of the given elements
|
||||
*/
|
||||
template<class CON, typename...ELMS>
|
||||
inline CON
|
||||
stringify(ELMS const& ...elms)
|
||||
{
|
||||
SeqContainer<CON,ELMS...> storage;
|
||||
do_stringify (storage, elms...);
|
||||
return CON {move(storage)};
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace { // helper to build range iterator on demand
|
||||
template<class CON, typename TOGGLE = void>
|
||||
struct _RangeIter
|
||||
|
|
|
|||
|
|
@ -68,29 +68,13 @@ namespace test{
|
|||
|
||||
// using lib::Literal;
|
||||
using std::string;
|
||||
using util::stringify;
|
||||
using util::contains;
|
||||
using util::isnil;
|
||||
using util::_Fmt;
|
||||
using lib::Symbol;
|
||||
// using std::rand;
|
||||
|
||||
namespace {
|
||||
|
||||
template<class CON>
|
||||
inline void
|
||||
stringify(CON&)
|
||||
{
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
template<class CON, typename X, typename...ARGS>
|
||||
inline void
|
||||
stringify(CON& container, X const& elm, ARGS const& ...args)
|
||||
{
|
||||
container.emplace_back (util::str(elm));
|
||||
stringify (container, args...);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -390,19 +374,20 @@ namespace test{
|
|||
EventMatch&
|
||||
arg (ARGS const& ...args)
|
||||
{
|
||||
ArgSeq argSeq;
|
||||
argSeq.reserve(sizeof...(ARGS));
|
||||
stringify (argSeq, args...);
|
||||
ArgSeq argSeq(stringify<ArgSeq> (args...));
|
||||
string argList(util::join(argSeq));
|
||||
|
||||
solution_.andFilter (matchArguments(std::move(argSeq)));
|
||||
evaluateQuery ("match-arguments("+util::join(argSeq)+")");
|
||||
solution_.andFilter (matchArguments(move(argSeq)));
|
||||
evaluateQuery ("match-arguments("+argList+")");
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename... MORE>
|
||||
template<typename...ARGS>
|
||||
EventMatch&
|
||||
argMatch (string regExp, MORE...args)
|
||||
argMatch (ARGS const& ...regExps)
|
||||
{
|
||||
stringify<ArgSeq> (regExps...);
|
||||
|
||||
UNIMPLEMENTED("process regular expression match on call argument list");
|
||||
}
|
||||
|
||||
|
|
@ -584,10 +569,7 @@ namespace test{
|
|||
EventLog&
|
||||
call (string target, string function, ARGS const& ...args)
|
||||
{
|
||||
ArgSeq argSeq;
|
||||
argSeq.reserve(sizeof...(ARGS));
|
||||
stringify (argSeq, args...);
|
||||
return call (target, function, std::move(argSeq));
|
||||
return call (target, function, stringify<ArgSeq>(args...));
|
||||
}
|
||||
|
||||
/** Log a function call on given object ("`this`")... */
|
||||
|
|
@ -609,10 +591,7 @@ namespace test{
|
|||
EventLog&
|
||||
note (ELMS const& ...initialiser)
|
||||
{
|
||||
ArgSeq args;
|
||||
args.reserve(sizeof...(ELMS));
|
||||
stringify (args, initialiser...);
|
||||
log_->emplace_back(args);
|
||||
log_->emplace_back(stringify<ArgSeq> (initialiser...));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue