MCPcopy Create free account
hub / github.com/LibreCAD/LibreCAD / AddFun

Method AddFun

libraries/muparser/src/muParserBytecode.cpp:379–445  ·  view source on GitHub ↗

\brief Add function to bytecode. \param a_iArgc Number of arguments, negative numbers indicate multiarg functions. \param a_pFun Pointer to function callback. */

Source from the content-addressed store, hash-verified

377 \param a_pFun Pointer to function callback.
378 */
379 void ParserByteCode::AddFun(generic_callable_type a_pFun, int a_iArgc, bool isFunctionOptimizable)
380 {
381 std::size_t sz = m_vRPN.size();
382 bool optimize = false;
383
384 // only optimize functions with fixed number of more than a single arguments
385 if (isFunctionOptimizable && m_bEnableOptimizer && a_iArgc > 0)
386 {
387 // <ibg 2020-06-10/> Unary Plus is a no-op
388 if (a_pFun == generic_callable_type{(erased_fun_type)&MathImpl<value_type>::UnaryPlus, nullptr})
389 return;
390
391 optimize = true;
392
393 for (int i = 0; i < std::abs(a_iArgc); ++i)
394 {
395 if (m_vRPN[sz - i - 1].Cmd != cmVAL)
396 {
397 optimize = false;
398 break;
399 }
400 }
401 }
402
403 if (optimize)
404 {
405 value_type val = 0;
406 switch (a_iArgc)
407 {
408 case 1: val = a_pFun.call_fun<1>(m_vRPN[sz - 1].Val.data2); break;
409 case 2: val = a_pFun.call_fun<2>(m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
410 case 3: val = a_pFun.call_fun<3>(m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
411 case 4: val = a_pFun.call_fun<4>(m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
412 case 5: val = a_pFun.call_fun<5>(m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
413 case 6: val = a_pFun.call_fun<6>(m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
414 case 7: val = a_pFun.call_fun<7>(m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
415 case 8: val = a_pFun.call_fun<8>(m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
416 case 9: val = a_pFun.call_fun<9>(m_vRPN[sz - 9].Val.data2, m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
417 case 10: val = a_pFun.call_fun<10>(m_vRPN[sz - 10].Val.data2, m_vRPN[sz - 9].Val.data2, m_vRPN[sz - 8].Val.data2, m_vRPN[sz - 7].Val.data2, m_vRPN[sz - 6].Val.data2, m_vRPN[sz - 5].Val.data2, m_vRPN[sz - 4].Val.data2, m_vRPN[sz - 3].Val.data2, m_vRPN[sz - 2].Val.data2, m_vRPN[sz - 1].Val.data2); break;
418 default:
419 // For now functions with unlimited number of arguments are not optimized
420 throw ParserError(ecINTERNAL_ERROR);
421 }
422
423 // remove the folded values
424 m_vRPN.erase(m_vRPN.end() - a_iArgc, m_vRPN.end());
425
426 SToken tok;
427 tok.Cmd = cmVAL;
428 tok.Val.data = 0;
429 tok.Val.data2 = val;
430 tok.Val.ptr = nullptr;
431 m_vRPN.push_back(tok);
432 }
433 else
434 {
435 SToken tok;
436 tok.Cmd = cmFUNC;

Callers 1

ApplyFuncMethod · 0.80

Calls 4

eraseMethod · 0.80
sizeMethod · 0.45
endMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected