CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AnyMethodArgument.h
Go to the documentation of this file.
1 #ifndef CommonTools_Utils_AnyMethodArgument_h
2 #define CommonTools_Utils_AnyMethodArgument_h
3 
4 #include "Reflex/Object.h"
5 #include "Reflex/Member.h"
7 
8 #include <algorithm>
9 #include <string>
10 #include <stdint.h>
11 
12 #include <boost/variant.hpp>
13 #include <boost/type_traits/is_same.hpp>
14 #include <boost/type_traits/is_integral.hpp>
15 #include <boost/type_traits/is_floating_point.hpp>
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/mpl/if.hpp>
18 
19 namespace reco {
20  namespace parser {
21 
22  // true if T matches one of the integral types in the default
23  // AnyMethodArgument variant
24  template <typename T>
26  static bool const value =
31  };
32 
33  // size_t on 32-bit Os X is type unsigned long, which doesn't match uint32_t,
34  // so add unsigned long if it doesn't match any of the other integral types.
35  // Use "unsigned long" rather than size_t as PtrVector has unsigned long as
36  // size_type
37  typedef boost::mpl::if_<matches_another_integral_type<unsigned long>,
38  boost::variant<int8_t, uint8_t,
39  int16_t, uint16_t,
40  int32_t, uint32_t,
41  int64_t, uint64_t,
42  double,float,
43  std::string>,
44  boost::variant<int8_t, uint8_t,
45  int16_t, uint16_t,
46  int32_t, uint32_t,
47  int64_t, uint64_t,
48  unsigned long,
49  double,float,
50  std::string> >::type AnyMethodArgument;
51 
52  class AnyMethodArgumentFixup : public boost::static_visitor<std::pair<AnyMethodArgument, int> > {
53  private:
55  const std::type_info & type_;
56  template<typename From, typename To>
57  std::pair<AnyMethodArgument, int> retOk_(const From &f, int cast) const {
58  return std::pair<AnyMethodArgument,int>(AnyMethodArgument(static_cast<To>(f)), cast);
59  }
60 
61  // correct return for each int output type
62  std::pair<AnyMethodArgument,int> doInt(int t) const {
63  if (type_ == typeid(int8_t)) { return retOk_<int,int8_t> (t,0); }
64  if (type_ == typeid(uint8_t)) { return retOk_<int,uint8_t> (t,0); }
65  if (type_ == typeid(int16_t)) { return retOk_<int,int16_t> (t,0); }
66  if (type_ == typeid(uint16_t)) { return retOk_<int,uint16_t>(t,0); }
67  if (type_ == typeid(int32_t)) { return retOk_<int,int32_t> (t,0); }
68  if (type_ == typeid(uint32_t)) { return retOk_<int,uint32_t>(t,0); }
69  if (type_ == typeid(int64_t)) { return retOk_<int,int64_t> (t,0); }
70  if (type_ == typeid(uint64_t)) { return retOk_<int,uint64_t>(t,0); }
71  if (type_ == typeid(unsigned long)) { return retOk_<int,unsigned long> (t,0); } // harmless if unsigned long matches another type
72  if (type_ == typeid(double)) { return retOk_<int,double> (t,1); }
73  if (type_ == typeid(float)) { return retOk_<int,float> (t,1); }
74  return std::pair<AnyMethodArgument,int>(t,-1);
75  }
76  public:
78  rflxType_(type),
79  type_(type.Name() == "string" ? typeid(std::string) : type.TypeInfo()) // Otherwise Reflex does this wrong :-(
80  {
81  while (rflxType_.IsTypedef()) rflxType_ = rflxType_.ToType();
82  /* // Code to print out enum table
83  if (rflxType_.IsEnum()) {
84  std::cerr << "Enum conversion: [" << rflxType_.Name() << "] => [" << type_.name() << "]" << std::endl;
85  std::cerr << "Enum has " << rflxType_.MemberSize() << ", members." << std::endl;
86  for (size_t i = 0; i < rflxType_.MemberSize(); ++i) {
87  Reflex::Member mem = rflxType_.MemberAt(i);
88  std::cerr << " member #"<<i<<", name = " << mem.Name() << ", rflxType_ = " << mem.TypeOf().Name() << std::endl;
89  }
90  } // */
91  }
92 
93  // we handle all integer types through 'int', as that's the way they are parsed by boost::spirit
94  template<typename I>
95  typename boost::enable_if<boost::is_integral<I>, std::pair<AnyMethodArgument,int> >::type
96  operator()(const I &t) const { return doInt(t); }
97 
98  template<typename F>
99  typename boost::enable_if<boost::is_floating_point<F>, std::pair<AnyMethodArgument,int> >::type
100  operator()(const F &t) const {
101  if (type_ == typeid(double)) { return retOk_<F,double>(t,0); }
102  if (type_ == typeid(float)) { return retOk_<F,float> (t,0); }
103  return std::pair<AnyMethodArgument,int>(t,-1);
104  }
105 
106  std::pair<AnyMethodArgument,int> operator()(const std::string &t) const {
107  if (type_ == typeid(std::string)) { return std::pair<AnyMethodArgument,int>(t,0); }
108  if (rflxType_.IsEnum()) {
109  if (rflxType_.MemberSize() == 0) {
110  throw parser::Exception(t.c_str()) << "Enumerator '" << rflxType_.Name() << "' has no keys.\nPerhaps the reflex dictionary is missing?\n";
111  }
112  Reflex::Member value = rflxType_.MemberByName(t);
113  //std::cerr << "Trying to convert '" << t << "' to a value for enumerator '" << rflxType_.Name() << "'" << std::endl;
114  if (!value) // check for existing value
115  return std::pair<AnyMethodArgument,int>(t,-1);
116  // throw parser::Exception(t.c_str()) << "Can't convert '" << t << "' to a value for enumerator '" << rflxType_.Name() << "'\n";
117  //std::cerr << " found member of type '" << value.TypeOf().Name() << "'" << std::endl;
118  if (value.TypeOf().TypeInfo() != typeid(int)) // check is backed by an Int
119  throw parser::Exception(t.c_str()) << "Enumerator '" << rflxType_.Name() << "' is not implemented by type 'int' !!??\n";
120  //std::cerr << " value is @ " << reinterpret_cast<const int *>(value.Get().Address()) << std::endl;
121  int ival = * reinterpret_cast<const int *>(value.Get().Address());
122  //std::cerr << " value is = " << ival << std::endl;
123  return std::pair<AnyMethodArgument,int>(ival,1);
124  }
125  return std::pair<AnyMethodArgument,int>(t,-1);
126  }
127 
128  };
129 
130  class AnyMethodArgument2VoidPtr : public boost::static_visitor<void *> {
131  public:
132  template<typename T>
133  void * operator()(const T &t) const { return const_cast<void*>(static_cast<const void *>(&t)); }
134  };
135  }
136 }
137 
138 #endif
type
Definition: HCALResponse.h:22
boost::enable_if< boost::is_integral< I >, std::pair< AnyMethodArgument, int > >::type operator()(const I &t) const
std::pair< AnyMethodArgument, int > operator()(const std::string &t) const
std::pair< AnyMethodArgument, int > retOk_(const From &f, int cast) const
const std::complex< double > I
Definition: I.h:8
std::pair< AnyMethodArgument, int > doInt(int t) const
double f[11][100]
boost::mpl::if_< matches_another_integral_type< unsigned long >, boost::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, float, std::string >, boost::variant< int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, unsigned long, double, float, std::string > >::type AnyMethodArgument
unsigned long long uint64_t
Definition: Time.h:15
boost::enable_if< boost::is_floating_point< F >, std::pair< AnyMethodArgument, int > >::type operator()(const F &t) const
long double T