@@ -60,16 +60,23 @@ static const std::array<std::string, 8> WHAT_STRINGS = { "call", "exception"
6060 " return" , " c_call" , " c_exception" ,
6161 " c_return" , " opcode" };
6262
63+ template <typename TCollection, typename TElement>
64+ int index_of (TCollection&& col, const TElement& element)
65+ {
66+ const auto it = std::find (col.cbegin (), col.cend (), element);
67+ if (it == col.end ())
68+ return -1 ;
69+ else
70+ return std::distance (col.begin (), it);
71+ }
72+
6373// Required because: `sys.getprofile()` returns the user object (2nd arg to PyEval_SetTrace)
6474// So `sys.setprofile(sys.getprofile())` will not round-trip as it will try to call the
6575// 2nd arg through pythons dispatch function. Hence make the object callable.
6676// See https://nedbatchelder.com/text/trace-function.html for details
6777PyObject* CInstrumenter::operator ()(PyFrameObject& frame, const char * what_string, PyObject* arg)
6878{
69- const auto it_what = std::find (WHAT_STRINGS.begin (), WHAT_STRINGS.end (), what_string);
70- int what = -1 ;
71- if (it_what != WHAT_STRINGS.end ())
72- what = std::distance (WHAT_STRINGS.begin (), it_what);
79+ const int what = index_of (WHAT_STRINGS, what_string);
7380 // To speed up further event processing install this class directly as the handler
7481 // But we might be inside a `sys.settrace` call where the user wanted to set another function
7582 // which would then be overwritten here. Hence use the CALL event which avoids the problem
0 commit comments