Commit 2fe50544 authored by jcarpent's avatar jcarpent
Browse files

[Checker] Authorize variadic macro

This fix a bug in 16.10 and later with compiling issues
parent d0c7d48c
//
// Copyright (c) 2016-2017 CNRS
// Copyright (c) 2016-2018 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
......@@ -19,6 +19,12 @@
#define __se3_check_hpp__
#include "pinocchio/multibody/model.hpp"
#include <boost/fusion/container/list.hpp>
#include <boost/fusion/container/generation/make_list.hpp>
#ifndef PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE
#define PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE 5
#endif
namespace se3
{
......@@ -44,6 +50,54 @@ namespace se3
/// Simple model checker, that assert that model.parents is indeed a tree.
DEFINE_ALGO_CHECKER(Parent);
#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
/// Checker having a list of Checker as input argument
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE,class D,boost::fusion::void_)>
struct AlgorithmCheckerList: AlgorithmCheckerBase< AlgorithmCheckerList<BOOST_PP_ENUM_PARAMS(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE,D)> >
{
typedef typename boost::fusion::list<BOOST_PP_ENUM_PARAMS(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE,D)> ArgType;
AlgorithmCheckerList(const ArgType & checkerList)
: checkerList(checkerList) {}
// Calls model.check for each checker in the fusion::list.
// Each list element is supposed to implement the AlgorithmCheckerBase API.
bool checkModel_impl(const Model & model) const;
const ArgType & checkerList;
};
#define MAKE_ALGO_CHECKER_LIST(z,n,_) \
/**/ \
template<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class D)> \
AlgorithmCheckerList<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),D)> makeAlgoCheckerList(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n) , D, const & arg)) \
{ return AlgorithmCheckerList<BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),D)>(boost::fusion::make_list(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),arg))); } \
BOOST_PP_REPEAT(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE, MAKE_ALGO_CHECKER_LIST, BOOST_PP_EMPTY)
#else
template <class ...D>
struct AlgorithmCheckerList: AlgorithmCheckerBase< AlgorithmCheckerList<D...> >
{
typedef typename boost::fusion::list<D...> ArgType;
AlgorithmCheckerList(const ArgType & checkerList)
: checkerList(checkerList) {}
// Calls model.check for each checker in the fusion::list.
// Each list element is supposed to implement the AlgorithmCheckerBase API.
bool checkModel_impl(const Model & model) const;
const ArgType & checkerList;
};
template <class ...T>
AlgorithmCheckerList<T...> makeAlgoCheckerList(const T&... args)
{
return AlgorithmCheckerList<T...>(boost::fusion::make_list(args...));
}
#endif
/// Check the validity of data wrt to model, in particular if model has been modified.
///
......
//
// Copyright (c) 2016-2017 CNRS
// Copyright (c) 2016-2018 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
......@@ -34,19 +34,15 @@ namespace se3
AlgoFusionChecker(const Model&model) : model(model) {}
inline bool operator()(const bool& accumul, const boost::fusion::void_ &) const
{ return accumul; }
template<typename T>
inline bool operator()(const bool& accumul, const T& t) const
inline bool operator()(const bool& accumul, const AlgorithmCheckerBase<T> & t) const
{ return accumul && t.checkModel(model); }
};
} // namespace internal
// Calls model.check for each checker in the fusion::list.
// Each list element is supposed to implement the AlgorithmCheckerBase API.
template<class T1,class T2,class T3,class T4,class T5,
class T6,class T7,class T8,class T9,class T10>
inline bool Model::check( const boost::fusion::list<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & checkerList ) const
{ return boost::fusion::accumulate(checkerList,true,internal::AlgoFusionChecker(*this)); }
// Check the validity of the kinematic tree defined by parents.
inline bool ParentChecker::checkModel_impl( const Model& model ) const
{
......@@ -56,6 +52,20 @@ namespace se3
return true;
}
#if !defined(BOOST_FUSION_HAS_VARIADIC_LIST)
template<BOOST_PP_ENUM_PARAMS(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE,class T)>
bool AlgorithmCheckerList<BOOST_PP_ENUM_PARAMS(PINOCCHIO_ALGO_CHECKER_LIST_MAX_LIST_SIZE,T)>::checkModel_impl(const Model& model) const
{
return boost::fusion::accumulate(checkerList,true,internal::AlgoFusionChecker(model));
}
#else
template<class ...T>
bool AlgorithmCheckerList<T...>::checkModel_impl(const Model& model) const
{
return boost::fusion::accumulate(checkerList,true,internal::AlgoFusionChecker(model));
}
#endif
inline bool checkData(const Model & model, const Data & data)
{
#define CHECK_DATA(a) if(!(a)) return false;
......
//
// Copyright (c) 2016-2017 CNRS
// Copyright (c) 2016-2018 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
......@@ -25,8 +25,8 @@
namespace se3
{
/// Default checker-list, used as the default argument in Model::check().
inline boost::fusion::list<ParentChecker,CRBAChecker,ABAChecker> makeDefaultCheckerList()
{ return boost::fusion::make_list(ParentChecker(),CRBAChecker(),ABAChecker()); }
inline AlgorithmCheckerList<ParentChecker,CRBAChecker,ABAChecker> makeDefaultCheckerList()
{ return makeAlgoCheckerList(ParentChecker(),CRBAChecker(),ABAChecker()); }
#define DEFAULT_CHECKERS makeDefaultCheckerList()
......
//
// Copyright (c) 2015-2017 CNRS
// Copyright (c) 2015-2018 CNRS
// Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
//
// This file is part of Pinocchio
......@@ -325,27 +325,6 @@ namespace se3
inline bool check(const AlgorithmCheckerBase<D> & checker = AlgorithmCheckerBase<D>()) const
{ return checker.checkModel(*this); }
/// Multiple checks for a fusion::vector of AlgorithmCheckerBase.
///
/// Run the check test for several conditons.
/// \param[in] v fusion::vector of algo checkers. The param is typically initialize with
/// boost::fusion::make_list( AlgoChecker1(), AlgoChecker2(), ...)
/// make_list is defined in #include <boost/fusion/include/make_list.hpp>
/// \warning no more than 10 checkers can be added (or Model API should be extended).
/// \note This method is implemented in src/algo/check.hxx.
template<class T1,class T2,class T3,class T4,class T5,
class T6,class T7,class T8,class T9,class T10>
inline bool check( const boost::fusion::list<T1,T2,T3,T4,T5,T6,T7,T8,T9,T10> & checkerList ) const;
template<class T1,class T2,class T3>
inline bool check( const boost::fusion::list<T1,T2,T3> & checkerList ) const;
template<class T1,class T2>
inline bool check( const boost::fusion::list<T1,T2> & checkerList ) const;
template<class T1>
inline bool check( const boost::fusion::list<T1> & checkerList ) const;
/// Run check(fusion::list) with DEFAULT_CHECKERS as argument.
inline bool check() const;
......
......@@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE ( test_check )
Y.mass() = Y.inertia().data()[0] = Y.inertia().data()[3] = Y.inertia().data()[5] = 1.0 ;
BOOST_CHECK(model.check (ABAChecker())); // some inertias are negative ... check fail.
BOOST_CHECK(model.check(boost::fusion::make_list(Check1(),ParentChecker(),CRBAChecker()) ));
BOOST_CHECK(model.check(makeAlgoCheckerList(Check1(),ParentChecker(),CRBAChecker()) ));
BOOST_CHECK(model.check(DEFAULT_CHECKERS));
se3::Data data(model);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment