2399 {
2400 switch (node.operation) {
2401 case Op::Not: {
2404 } break;
2405 case Op::And: {
2407 } break;
2408 case Op::Or: {
2410 } break;
2411 case Op::In: {
2413 make_result(std::find(args[1]->begin(), args[1]->end(), *args[0]) != args[1]->end());
2414 } break;
2415 case Op::Equal: {
2418 } break;
2419 case Op::NotEqual: {
2422 } break;
2423 case Op::Greater: {
2426 } break;
2427 case Op::GreaterEqual: {
2430 } break;
2431 case Op::Less: {
2434 } break;
2435 case Op::LessEqual: {
2438 } break;
2439 case Op::Add: {
2441 if (args[0]->is_string() && args[1]->is_string()) {
2442 make_result(args[0]->get_ref<const json::string_t&>() + args[1]->get_ref<const json::string_t&>());
2443 } else if (args[0]->is_number_integer() && args[1]->is_number_integer()) {
2444 make_result(args[0]->get<const json::number_integer_t>() + args[1]->get<const json::number_integer_t>());
2445 } else {
2446 make_result(args[0]->get<const json::number_float_t>() + args[1]->get<const json::number_float_t>());
2447 }
2448 } break;
2449 case Op::Subtract: {
2451 if (args[0]->is_number_integer() && args[1]->is_number_integer()) {
2452 make_result(args[0]->get<const json::number_integer_t>() - args[1]->get<const json::number_integer_t>());
2453 } else {
2454 make_result(args[0]->get<const json::number_float_t>() - args[1]->get<const json::number_float_t>());
2455 }
2456 } break;
2457 case Op::Multiplication: {
2459 if (args[0]->is_number_integer() && args[1]->is_number_integer()) {
2460 make_result(args[0]->get<const json::number_integer_t>() * args[1]->get<const json::number_integer_t>());
2461 } else {
2462 make_result(args[0]->get<const json::number_float_t>() * args[1]->get<const json::number_float_t>());
2463 }
2464 } break;
2465 case Op::Division: {
2467 if (args[1]->get<const json::number_float_t>() == 0) {
2469 }
2470 make_result(args[0]->get<const json::number_float_t>() / args[1]->get<const json::number_float_t>());
2471 } break;
2472 case Op::Power: {
2474 if (args[0]->is_number_integer() && args[1]->get<const json::number_integer_t>() >= 0) {
2475 const auto result = static_cast<json::number_integer_t>(
2476 std::pow(args[0]->get<const json::number_integer_t>(), args[1]->get<const json::number_integer_t>()));
2478 } else {
2479 const auto result =
2480 std::pow(args[0]->get<const json::number_float_t>(), args[1]->get<const json::number_integer_t>());
2482 }
2483 } break;
2484 case Op::Modulo: {
2486 make_result(args[0]->get<const json::number_integer_t>() % args[1]->get<const json::number_integer_t>());
2487 } break;
2488 case Op::AtId: {
2490 node.arguments[1]->accept(*this);
2493 }
2498 } break;
2499 case Op::At: {
2501 if (args[0]->is_object()) {
2503 } else {
2504 data_eval_stack.push(&args[0]->at(args[1]->get<std::stack<const json*>::size_type>()));
2505 }
2506 } break;
2507 case Op::Default: {
2510 } break;
2511 case Op::DivisibleBy: {
2513 const auto divisor = args[1]->get<const json::number_integer_t>();
2514 make_result((divisor != 0) && (args[0]->get<const json::number_integer_t>() % divisor == 0));
2515 } break;
2516 case Op::Even: {
2518 } break;
2519 case Op::Exists: {
2522 } break;
2523 case Op::ExistsInObject: {
2525 auto&& name = args[1]->get_ref<const json::string_t&>();
2526 make_result(args[0]->find(name) != args[0]->end());
2527 } break;
2528 case Op::First: {
2531 } break;
2532 case Op::Float: {
2534 } break;
2535 case Op::Int: {
2537 } break;
2538 case Op::Last: {
2541 } break;
2542 case Op::Length: {
2544 if (val->is_string()) {
2545 make_result(val->get_ref<
const json::string_t&>().length());
2546 } else {
2548 }
2549 } break;
2550 case Op::Lower: {
2552 std::transform(result.begin(), result.end(), result.begin(), [](char c) {
2553 return static_cast<char>(::tolower(c));
2554 });
2556 } break;
2557 case Op::Max: {
2559 const auto result = std::max_element(args[0]->begin(), args[0]->end());
2561 } break;
2562 case Op::Min: {
2564 const auto result = std::min_element(args[0]->begin(), args[0]->end());
2566 } break;
2567 case Op::Odd: {
2569 } break;
2570 case Op::Range: {
2571 std::vector<int> result(
get_arguments<1>(node)[0]->get<std::vector<int>::size_type>());
2572 std::iota(result.begin(), result.end(), 0);
2574 } break;
2575 case Op::Round: {
2577 const int precision = args[1]->get<int>();
2578 const double result =
2579 std::round(args[0]->get<const json::number_float_t>() * std::pow(10.0, precision)) / std::pow(10.0, precision);
2580 if (precision == 0) {
2582 } else {
2584 }
2585 } break;
2586 case Op::Sort: {
2587 auto result_ptr = std::make_shared<json>(
get_arguments<1>(node)[0]->get<std::vector<json>>());
2588 std::sort(result_ptr->begin(), result_ptr->end());
2591 } break;
2592 case Op::Upper: {
2594 std::transform(result.begin(), result.end(), result.begin(), [](char c) {
2595 return static_cast<char>(::toupper(c));
2596 });
2598 } break;
2599 case Op::IsBoolean: {
2601 } break;
2602 case Op::IsNumber: {
2604 } break;
2605 case Op::IsInteger: {
2607 } break;
2608 case Op::IsFloat: {
2610 } break;
2611 case Op::IsObject: {
2613 } break;
2614 case Op::IsArray: {
2616 } break;
2617 case Op::IsString: {
2619 } break;
2620 case Op::Callback: {
2623 } break;
2624 case Op::Super: {
2627 const size_t level_diff = (args.size() == 1) ? args[0]->get<size_t>() : 1;
2629
2632 }
2633
2637 node);
2638 }
2639
2643 const auto block_it = new_template->block_storage.find(current_block_statement->name);
2644 if (block_it != new_template->block_storage.end()) {
2647 block_it->second->block.accept(*this);
2650 } else {
2651 throw_renderer_error(
"could not find block with name '" + current_block_statement->name +
"'", node);
2652 }
2654 } break;
2655 case Op::Join: {
2657 const auto separator = args[1]->get<json::string_t>();
2658 std::ostringstream os;
2659 std::string sep;
2660 for (const auto& value : *args[0]) {
2661 os << sep;
2662 if (value.is_string()) {
2663 os << value.get<std::string>();
2664 } else {
2665 os << value.dump();
2666 }
2667 sep = separator;
2668 }
2670 } break;
2671 case Op::None:
2672 break;
2673 }
2674 }
static std::string convert_dot_to_ptr(std::string_view ptr_name)
std::array< const json *, N > get_arguments(const FunctionNode &node)
Arguments get_argument_vector(const FunctionNode &node)
static bool truthy(const json *data)
void make_result(const json &&result)