pinocchio  UNKNOWN
visitor.hpp
1 //
2 // Copyright (c) 2015 CNRS
3 // Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
4 //
5 // This file is part of Pinocchio
6 // Pinocchio is free software: you can redistribute it
7 // and/or modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation, either version
9 // 3 of the License, or (at your option) any later version.
10 //
11 // Pinocchio is distributed in the hope that it will be
12 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Lesser Public License for more details. You should have
15 // received a copy of the GNU Lesser General Public License along with
16 // Pinocchio If not, see
17 // <http://www.gnu.org/licenses/>.
18 
19 #ifndef __se3_visitor_hpp__
20 #define __se3_visitor_hpp__
21 
22 #define BOOST_FUSION_INVOKE_MAX_ARITY 10
23 #include <boost/fusion/include/invoke.hpp>
24 #include <boost/fusion/include/algorithm.hpp>
25 #include "pinocchio/multibody/joint/joint-variant.hpp"
26 
27 
28 namespace boost {
29  namespace fusion {
30 
31  // Append the element T at the front of boost fusion vector V.
32  template<typename T,typename V>
33  typename result_of::push_front<V const, T>::type
34  append(T const& t,V const& v) { return push_front(v,t); }
35 
36  // Append the elements T1 and T2 at the front of boost fusion vector V.
37  template<typename T1,typename T2,typename V>
38  typename result_of::push_front<typename result_of::push_front<V const, T2>::type const, T1>::type
39  append2(T1 const& t1,T2 const& t2,V const& v) { return push_front(push_front(v,t2),t1); }
40  }
41 }
42 
43 
44 namespace se3
45 {
46  namespace fusion
47  {
48  namespace bf = boost::fusion;
49 
50  template<typename Visitor>
51  struct JointVisitor : public boost::static_visitor<>
52  {
53  template<typename D>
54  void operator() (const JointModelBase<D> & jmodel) const
55  {
56  JointDataVariant& jdataSpec = static_cast<const Visitor*>(this)->jdata;
57 
58  bf::invoke(&Visitor::template algo<D>,
59  bf::append2(boost::ref(jmodel),
60  boost::ref(boost::get<typename D::JointDataDerived>(jdataSpec)),
61  static_cast<const Visitor*>(this)->args));
62  }
63 
64  template<typename ArgsTmp>
65  static void run(const JointModelVariant & jmodel,
66  JointDataVariant & jdata,
67  ArgsTmp args)
68  {
69  return boost::apply_visitor( Visitor(jdata,args),jmodel );
70  }
71  };
72 
73 
74  template<typename Visitor>
75  struct JointModelVisitor : public boost::static_visitor<>
76  {
77  template<typename D>
78  void operator() (const JointModelBase<D> & jmodel) const
79  {
80  bf::invoke(&Visitor::template algo<D>,
81  bf::append(boost::ref(jmodel),
82  static_cast<const Visitor*>(this)->args));
83  }
84 
85  template<typename ArgsTmp>
86  static void run(const JointModelVariant & jmodel,
87  ArgsTmp args)
88  {
89  return boost::apply_visitor( Visitor(args),jmodel );
90  }
91  };
92 
93  } // namespace fusion
94 } // namespace se3
95 
96 #define JOINT_VISITOR_INIT(VISITOR) \
97  VISITOR( JointDataVariant & jdata,ArgsType args ) : jdata(jdata),args(args) {} \
98  using se3::fusion::JointVisitor< VISITOR >::run; \
99  JointDataVariant & jdata; \
100  ArgsType args
101 
102 
103 #define JOINT_MODEL_VISITOR_INIT(VISITOR) \
104  VISITOR(ArgsType args ) : args(args) {} \
105  using se3::fusion::JointModelVisitor< VISITOR >::run; \
106  ArgsType args
107 
108 #endif // ifndef __se3_visitor_hpp__