Skip to content

Commit 31aa778

Browse files
olivier-stasseOlivier Stasse
authored andcommitted
[command] Add a template to return value from command.
Only up to 2 arguments. Variadic template might be implemented but I found no simple solution.
1 parent 605517c commit 31aa778

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

include/dynamic-graph/command-bind.h

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,198 @@ makeCommandVerbose(E &entity,
415415
inline std::string docCommandVerbose(const std::string &doc) {
416416
return std::string("\n") + doc + "\n\nNo input.\n Return a string.\n\n";
417417
}
418+
/*************************/
419+
/* Template return types */
420+
/*************************/
421+
422+
template <class E, class ReturnType>
423+
struct CommandReturnType0 : public Command {
424+
CommandReturnType0(E &entity, boost::function<ReturnType(void)> function,
425+
const std::string &docString)
426+
: Command(entity, EMPTY_ARG, docString), fptr(function) {}
427+
428+
protected:
429+
virtual Value doExecute() {
430+
assert(getParameterValues().size() == 0);
431+
Value res;
432+
res = fptr();
433+
return res;
434+
}
435+
436+
private:
437+
boost::function<ReturnType(void)> fptr;
438+
};
439+
440+
template <class E, class ReturnType>
441+
CommandReturnType0<E, ReturnType> *
442+
makeCommandReturnType0(E &entity, boost::function<ReturnType(void)> function,
443+
const std::string &docString) {
444+
return new CommandReturnType0<E, ReturnType>(entity, function, docString);
445+
}
446+
447+
template <class E, class ReturnType>
448+
CommandReturnType0<E, ReturnType> *
449+
makeCommandReturnType0(E &entity, boost::function<ReturnType(E *)> function,
450+
const std::string &docString) {
451+
return new CommandReturnType0<E, ReturnType>(
452+
entity, boost::bind(function, &entity), docString);
453+
}
454+
455+
template <class E, class ReturnType>
456+
CommandReturnType0<E, ReturnType> *
457+
makeCommandReturnType0(E &entity, ReturnType (E::*function)(void),
458+
const std::string &docString) {
459+
return new CommandReturnType0<E, ReturnType>(
460+
entity, boost::bind(function, &entity), docString);
461+
}
462+
463+
template <typename ReturnType>
464+
inline std::string docCommandReturnType0(const std::string &doc,
465+
const std::string &return_type) {
466+
return std::string("\n") + doc + "\n\nNo input.\n" +
467+
typeid(ReturnType).name() + " return.\n\n";
468+
}
469+
470+
} // namespace command
471+
} // namespace dynamicgraph
472+
473+
/* --- FUNCTION 1 ARGS ------------------------------------------------------ */
474+
namespace dynamicgraph {
475+
namespace command {
476+
477+
template <class E, typename ReturnType, typename T>
478+
struct CommandReturnType1 : public Command {
479+
typedef boost::function<ReturnType(const T &)> function_t;
480+
typedef boost::function<ReturnType(E *, const T &)> memberFunction_t;
481+
typedef void (E::*memberFunction_ptr_t)(const T &);
482+
483+
CommandReturnType1(E &entity, function_t function,
484+
const std::string &docString)
485+
: Command(entity, boost::assign::list_of(ValueHelper<T>::TypeID),
486+
docString),
487+
fptr(function) {}
488+
489+
protected:
490+
virtual Value doExecute() {
491+
assert(getParameterValues().size() == 1);
492+
T val = getParameterValues()[0].value();
493+
Value res(fptr(val));
494+
return res; // void
495+
}
496+
497+
private:
498+
function_t fptr;
499+
};
500+
501+
template <class E, typename ReturnType, typename T>
502+
CommandReturnType1<E, ReturnType, T> *
503+
makeCommandReturnType1(E &entity,
504+
boost::function<ReturnType(const T &)> function,
505+
const std::string &docString) {
506+
return new CommandReturnType1<E, ReturnType, T>(entity, function, docString);
507+
}
508+
509+
template <class E, typename ReturnType, typename T>
510+
CommandReturnType1<E, ReturnType, T> *makeCommandReturnType1(
511+
E &entity,
512+
// The following syntaxt don't compile when not specializing the template
513+
// arg... why ???
514+
// typename CommandReturnType1<E,T>::memberFunction_t function ,
515+
boost::function<ReturnType(E *, const T &)> function,
516+
const std::string &docString) {
517+
return new CommandReturnType1<E, ReturnType, T>(
518+
entity, boost::bind(function, &entity, _1), docString);
519+
}
520+
521+
template <class E, typename ReturnType, typename T>
522+
CommandReturnType1<E, ReturnType, T> *
523+
makeCommandReturnType1(E &entity, ReturnType (E::*function)(const T &),
524+
const std::string &docString) {
525+
return new CommandReturnType1<E, ReturnType, T>(
526+
entity, boost::bind(function, &entity, _1), docString);
527+
return NULL;
528+
}
529+
530+
template <typename ReturnType>
531+
inline std::string docCommandReturnType1(const std::string &doc,
532+
const std::string &type) {
533+
return std::string("\n") + doc + "\n\nInput:\n - A " + type + ".\n" +
534+
typeid(ReturnType).name() + "return.\n\n";
535+
}
536+
537+
} // namespace command
538+
} // namespace dynamicgraph
539+
540+
/*********** FUNCTION 2 Arguments ************************/
541+
namespace dynamicgraph {
542+
namespace command {
543+
544+
template <class E, typename ReturnType, typename T1, typename T2>
545+
struct CommandReturnType2 : public Command {
546+
typedef boost::function<ReturnType(const T1 &, const T2 &)> function_t;
547+
typedef boost::function<ReturnType(E *, const T1 &, const T2 &)>
548+
memberFunction_t;
549+
typedef void (E::*memberFunction_ptr_t)(const T1 &, const T2 &);
550+
551+
CommandReturnType2(E &entity, function_t function,
552+
const std::string &docString)
553+
: Command(entity,
554+
boost::assign::list_of(ValueHelper<T1>::TypeID)(
555+
ValueHelper<T2>::TypeID),
556+
docString),
557+
fptr(function) {}
558+
559+
protected:
560+
virtual Value doExecute() {
561+
assert(getParameterValues().size() == 2);
562+
T1 val1 = getParameterValues()[0].value();
563+
T2 val2 = getParameterValues()[1].value();
564+
fptr(val1, val2);
565+
return Value(); // void
566+
}
567+
568+
private:
569+
function_t fptr;
570+
};
571+
572+
template <class E, typename ReturnType, typename T1, typename T2>
573+
CommandReturnType2<E, ReturnType, T1, T2> *makeCommandReturnType2(
574+
E &entity, boost::function<ReturnType(const T1 &, const T2 &)> function,
575+
const std::string &docString) {
576+
return new CommandReturnType2<E, ReturnType, T1, T2>(entity, function,
577+
docString);
578+
}
579+
580+
template <class E, typename ReturnType, typename T1, typename T2>
581+
CommandReturnType2<E, ReturnType, T1, T2> *makeCommandReturnType2(
582+
E &entity,
583+
// The following syntaxt don't compile when not specializing the template
584+
// arg... why ???
585+
// typename CommandReturnType2<E,T1,T2>::memberFunction_t function ,
586+
boost::function<ReturnType(E *, const T1 &, const T2 &)> function,
587+
const std::string &docString) {
588+
return new CommandReturnType2<E, ReturnType, T1, T2>(
589+
entity, boost::bind(function, &entity, _1, _2), docString);
590+
}
591+
592+
template <class E, typename ReturnType, typename T1, typename T2>
593+
CommandReturnType2<E, ReturnType, T1, T2> *
594+
makeCommandReturnType2(E &entity,
595+
ReturnType (E::*function)(const T1 &, const T2 &),
596+
const std::string &docString) {
597+
return new CommandReturnType2<E, ReturnType, T1, T2>(
598+
entity, boost::bind(function, &entity, _1, _2), docString);
599+
return NULL;
600+
}
601+
602+
template <typename ReturnType>
603+
inline std::string docCommandReturnType2(const std::string &doc,
604+
const std::string &type1,
605+
const std::string &type2) {
606+
return (std::string("\n") + doc + "\n\n" + "Input:\n - A " + type1 + ".\n" +
607+
"Input:\n - A " + type2 + ".\n" +
608+
"ReturnType:\n - Returns:" + typeid(ReturnType).name() + +".\n\n");
609+
}
418610

419611
} // namespace command
420612
} // namespace dynamicgraph

0 commit comments

Comments
 (0)