CMS 3D CMS Logo

FWExpressionValidator.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWExpressionValidator
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Fri Aug 22 20:42:51 EDT 2008
11 //
12 
13 // system include files
14 #include <cctype>
15 #include <algorithm>
16 
19 #include <cstring>
20 
21 // user include files
24 
25 //
26 // constants, enums and typedefs
27 //
28 typedef std::vector<std::shared_ptr<fireworks::OptionNode> > Options;
29 
30 namespace fireworks {
31  template <class T>
33  bool operator()(const T& iLHS, const T& iRHS) const { return *iLHS < *iRHS; }
34  };
35 
36  template <class T>
38  bool operator()(const T& iLHS, const T& iRHS) const { return iLHS->description() == iRHS->description(); }
39  };
40 
41  class OptionNode {
42  public:
44  OptionNode(const std::string& iDescription, unsigned long iSubstitutionEnd, const edm::TypeWithDict& iType);
45 
46  const std::string& description() const { return m_description; }
47  unsigned long substitutionEnd() const { return m_endOfName; }
48  const std::vector<std::shared_ptr<OptionNode> >& options() const {
49  if (m_hasSubOptions && m_subOptions.empty()) {
51  std::sort(
53  std::vector<std::shared_ptr<OptionNode> >::iterator it = std::unique(
55  m_subOptions.erase(it, m_subOptions.end());
56 
57  m_hasSubOptions = !m_subOptions.empty();
58  }
59  return m_subOptions;
60  }
61 
62  bool operator<(const OptionNode& iRHS) const {
63  return m_description.substr(0, m_endOfName) < iRHS.m_description.substr(0, iRHS.m_endOfName);
64  }
65 
66  static void fillOptionForType(const edm::TypeWithDict&, std::vector<std::shared_ptr<OptionNode> >&);
67 
68  private:
72  mutable std::vector<std::shared_ptr<OptionNode> > m_subOptions;
73  mutable bool m_hasSubOptions;
74  static bool typeHasOptions(const edm::TypeWithDict& iType);
75  };
76 
77  OptionNode::OptionNode(const std::string& iDescription,
78  unsigned long iSubstitutionEnd,
79  const edm::TypeWithDict& iType)
80  : m_type(iType),
81  m_description(iDescription),
82  m_endOfName(iSubstitutionEnd),
83  m_hasSubOptions(typeHasOptions(iType)) {}
84 
85  namespace {
86  std::string descriptionFromMember(const edm::FunctionWithDict& iMember) {
87  std::string typeString = iMember.typeName();
88  std::string::size_type index = typeString.find_first_of('(');
89  if (index == std::string::npos) {
90  return iMember.name() + ":" + typeString;
91  } else {
92  return iMember.name() + typeString.substr(index, std::string::npos) + ":" + typeString.substr(0, index);
93  }
94  }
95  } // namespace
96 
98  : m_type(reco::returnType(iMember)),
99  m_description(descriptionFromMember(iMember)),
100  m_endOfName(iMember.name().size()),
101  m_hasSubOptions(typeHasOptions(m_type)) {}
102 
104  std::vector<std::shared_ptr<OptionNode> >& oOptions) {
105  edm::TypeWithDict type = iType;
106  if (type.isPointer()) {
107  type = type.toType(); // for Pointers, I get the real type this way
108  }
109  // first look in base scope
111  oOptions.reserve(oOptions.size() + functions.size());
112  for (auto const& function : functions) {
113  edm::FunctionWithDict m(function);
114  if (!m.isConst() || m.isConstructor() || m.isDestructor() || m.isOperator() || !m.isPublic() ||
115  m.name().substr(0, 2) == "__") {
116  continue;
117  }
118  oOptions.push_back(std::make_shared<OptionNode>(m));
119  }
120 
121  edm::TypeBases bases(type);
122  for (auto const& base : bases) {
123  fillOptionForType(edm::BaseWithDict(base).typeOf(), oOptions);
124  }
125  }
126 
127  bool OptionNode::typeHasOptions(const edm::TypeWithDict& iType) { return iType.isClass(); }
128 
129 } // namespace fireworks
130 
131 //
132 // static data member definitions
133 //
134 
135 //
136 // constructors and destructor
137 //
138 #define FUN1(_fun_) \
139  m_builtins.push_back(std::make_shared<OptionNode>(#_fun_ "(float):float", strlen(#_fun_) + 1, s_float))
140 
141 #define FUN2(_fun_) \
142  m_builtins.push_back(std::make_shared<OptionNode>(#_fun_ "(float,float):float", strlen(#_fun_) + 1, s_float))
143 
145  using fireworks::OptionNode;
146  static const edm::TypeWithDict s_float(typeid(float));
147  FUN1(abs);
148  FUN1(acos);
149  FUN1(asin);
150  FUN1(atan);
151  FUN1(cos);
152  FUN1(cosh);
153  FUN1(exp);
154  FUN1(log);
155  FUN1(log10);
156  FUN1(sin);
157  FUN1(sinh);
158  FUN1(sqrt);
159  FUN1(tan);
160  FUN1(tanh);
161  FUN2(atan2);
162  FUN2(chi2prob);
163  FUN2(pow);
164  FUN2(min);
165  FUN2(max);
167 }
168 
169 // FWExpressionValidator::FWExpressionValidator(const FWExpressionValidator& rhs)
170 // {
171 // // do actual copying here;
172 // }
173 
175 
176 //
177 // assignment operators
178 //
179 // const FWExpressionValidator& FWExpressionValidator::operator=(const FWExpressionValidator& rhs)
180 // {
181 // //An exception safe implementation is
182 // FWExpressionValidator temp(rhs);
183 // swap(rhs);
184 //
185 // return *this;
186 // }
187 
188 //
189 // member functions
190 //
192  using fireworks::OptionNode;
193  m_type = iType;
194  m_options.clear();
196  OptionNode::fillOptionForType(iType, m_options);
198  std::vector<std::shared_ptr<OptionNode> >::iterator it =
200  m_options.erase(it, m_options.end());
201 }
202 
203 //
204 // const member functions
205 //
206 namespace {
207  void dummyDelete(void*) {}
208 
209  void findTypeDelimiters(const char*& ioBegin, const char* iEnd, std::vector<const char*>& oDelimeters) {
210  oDelimeters.clear();
211  if (ioBegin == iEnd) {
212  return;
213  }
214  const char* it = iEnd - 1;
215  const char* itEnd = ioBegin - 1;
216  for (; it != itEnd; --it) {
217  if (isalnum(*it)) {
218  continue;
219  }
220  bool shouldStop = false;
221  switch (*it) {
222  case '_':
223  break;
224  case '.':
225  oDelimeters.push_back(it);
226  break;
227  default:
228  shouldStop = true;
229  }
230  if (shouldStop) {
231  break;
232  }
233  }
234  ioBegin = it + 1;
235  std::reverse(oDelimeters.begin(), oDelimeters.end());
236  }
237 } // namespace
238 
240  const char* iBegin,
241  const char* iEnd,
242  std::vector<std::pair<std::shared_ptr<std::string>, std::string> >& oOptions) const {
243  using fireworks::OptionNode;
244  oOptions.clear();
245  std::vector<const char*> delimeters;
246  findTypeDelimiters(iBegin, iEnd, delimeters);
247  //must find correct OptionNode
248  const Options* nodes = &m_options;
249  const char* begin = iBegin;
250  for (std::vector<const char*>::iterator it = delimeters.begin(), itEnd = delimeters.end(); it != itEnd; ++it) {
251  OptionNode temp(std::string(begin, *it), *it - begin, edm::TypeWithDict());
252 
253  std::shared_ptr<OptionNode> comp(&temp, dummyDelete);
254  Options::const_iterator itFind = std::lower_bound(
256 
257  if (itFind == nodes->end() || *comp < *(*itFind)) {
258  //no match so we have an error
259  return;
260  }
261  nodes = &((*itFind)->options());
262  begin = (*it) + 1;
263  }
264 
265  //only use add items which begin with the part of the member we are trying to match
266  std::string part(begin, iEnd);
267  unsigned int part_size = part.size();
268  for (Options::const_iterator it = nodes->begin(), itEnd = nodes->end(); it != itEnd; ++it) {
269  if (part == (*it)->description().substr(0, part_size)) {
270  oOptions.push_back(
271  std::make_pair(std::shared_ptr<std::string>(const_cast<std::string*>(&((*it)->description())), dummyDelete),
272  (*it)->description().substr(part_size, (*it)->substitutionEnd() - part_size)));
273  }
274  }
275 }
276 
277 //
278 // static member functions
279 //
OptionNode(const edm::FunctionWithDict &)
bool operator()(const T &iLHS, const T &iRHS) const
void setType(const edm::TypeWithDict &)
void tanh(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in])
#define FUN1(_fun_)
std::string::size_type m_endOfName
unsigned long substitutionEnd() const
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
bool operator()(const T &iLHS, const T &iRHS) const
std::vector< std::shared_ptr< fireworks::OptionNode > > m_options
uint16_t size_type
bool operator<(const OptionNode &iRHS) const
#define FUN2(_fun_)
void fillOptions(const char *iBegin, const char *iEnd, std::vector< std::pair< std::shared_ptr< std::string >, std::string > > &oOptions) const override
edm::TypeWithDict returnType(const edm::FunctionWithDict &)
Definition: returnType.cc:16
T sqrt(T t)
Definition: SSEVec.h:23
def unique(seq, keepstr=True)
Definition: tier0.py:24
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::shared_ptr< fireworks::OptionNode > > Options
const std::vector< std::shared_ptr< OptionNode > > & options() const
std::string typeName() const
std::string name() const
static bool typeHasOptions(const edm::TypeWithDict &iType)
static void fillOptionForType(const edm::TypeWithDict &, std::vector< std::shared_ptr< OptionNode > > &)
part
Definition: HCALResponse.h:20
bool isClass() const
std::vector< std::shared_ptr< fireworks::OptionNode > > m_builtins
fixed size matrix
std::vector< std::shared_ptr< OptionNode > > m_subOptions
TypeWithDict toType() const
long double T
const std::string & description() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
MPlex< T, D1, D2, N > atan2(const MPlex< T, D1, D2, N > &y, const MPlex< T, D1, D2, N > &x)
Definition: Matriplex.h:648