1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2024-11-10 00:45:36 +00:00

DoubleFunction: safer variadic call with variadic template

This commit is contained in:
Antonin Portelli 2014-03-03 13:04:53 +00:00
parent dc849a9f87
commit a66a2d8c5c
3 changed files with 44 additions and 45 deletions

View File

@ -20,24 +20,6 @@
#include <latan/Function.hpp>
#include <latan/includes.hpp>
#define DEF_STD_FUNC_1ARG(name, funcName) \
name##Function::name##Function(void): DoubleFunction(1) {}\
name##Function::~name##Function(void) {}\
double name##Function::operator()(std::vector<double> &arg)\
{\
return funcName(arg[0]);\
}\
name##Function STDMATH_NAMESPACE::funcName;
#define DEF_STD_FUNC_2ARG(name, funcName) \
name##Function::name##Function(void): DoubleFunction(2) {}\
name##Function::~name##Function(void) {}\
double name##Function::operator()(std::vector<double> &arg)\
{\
return funcName(arg[0], arg[1]);\
}\
name##Function STDMATH_NAMESPACE::funcName;
using namespace std;
using namespace Latan;
@ -108,20 +90,9 @@ double DoubleFunction::operator()(std::stack<double> &arg) const
return (*this)(*buffer_);
}
double DoubleFunction::operator()(const double x0, ...) const
double DoubleFunction::operator()(void) const
{
(*buffer_)[0] = x0;
if (getNArg() > 1)
{
va_list va;
va_start(va, x0);
for (Index i = 1; i < getNArg(); ++i)
{
(*buffer_)(i) = va_arg(va, double);
}
va_end(va);
}
checkSize(0);
return (*this)(*buffer_);
return (*this)(nullptr);
}

View File

@ -48,7 +48,9 @@ public:
double operator()(const DVec &arg) const;
double operator()(const std::vector<double> &arg) const;
double operator()(std::stack<double> &arg) const;
double operator()(const double x0, ...) const;
double operator()(void) const;
template <typename... Ts>
double operator()(const double arg0, const Ts... args) const;
protected:
// function call
virtual double operator()(const double *arg) const;
@ -61,6 +63,19 @@ private:
static const vecFunc nullFunction_;
};
template <typename... Ts>
double DoubleFunction::operator()(const double arg0, const Ts... args) const
{
static_assert(static_or<std::is_trivially_assignable<double, Ts>::value...>::value,
"DoubleFunction arguments are not compatible with double");
const double arg[] = {arg0, args...};
checkSize(sizeof...(args) + 1);
return (*this)(arg);
}
END_NAMESPACE
#endif // Latan_Function_hpp_

View File

@ -24,6 +24,7 @@
#include <map>
#include <string>
#include <sstream>
#include <type_traits>
#include <cstdlib>
#define BEGIN_NAMESPACE namespace Latan {
@ -33,10 +34,8 @@
#define unique_arg(...) __VA_ARGS__
// attribute to switch off unused warnings with gcc
#ifdef __GNUC__
#define __dumb __attribute__((unused))
#else
#define __dumb
#ifndef __GNUC__
#define __unused
#endif
// max length for paths
@ -104,6 +103,27 @@ using ConstMap = Eigen::Map<const Derived>;
// Index type //////////////////////////////////////////////////////////////////
typedef DMatBase::Index Index;
// Type utilities //////////////////////////////////////////////////////////////
// pointer type test
template <typename Derived, typename Base>
inline bool isDerivedFrom(const Base *pt)
{
return (dynamic_cast<const Derived *>(pt) != nullptr);
}
// static logical or
template <bool... b>
struct static_or;
template <bool... tail>
struct static_or<true, tail...> : static_or<tail...> {};
template <bool... tail>
struct static_or<false, tail...> : std::false_type {};
template <>
struct static_or<> : std::true_type {};
// Environment /////////////////////////////////////////////////////////////////
namespace Env
{
@ -113,14 +133,7 @@ namespace Env
extern const std::string msgPrefix;
}
// pointer type test
template <typename Derived, typename Base>
inline bool isDerivedFrom(const Base *pt)
{
return (dynamic_cast<const Derived *>(pt) != nullptr);
}
// string conversions //////////////////////////////////////////////////////////
// String conversions //////////////////////////////////////////////////////////
template <typename T>
inline T strTo(const std::string &str)
{