Modernes C++ programmieren

Okt 20, 2024

lst-0082-book.cpp

// https://godbolt.org/z/jxvhded75
#include <string>
#include <vector>
#include <iostream>
#include <map>
#include <functional>
std::map<char,std::function<int(int,int)>> binOps { // binary operators
    {'+', std::plus<int>{} },
    {'-', std::minus<int>{} },
    {'*', std::multiplies<int>{} },
    {'/', std::divides<int>{} },
    {'%', std::modulus<int>{} },
    };
std::map<char,std::function<int(int)>> unOps { };    // unary operators
auto val = [](auto n) { return [n](){ return n; };}; // returns a lambda
std::map<char,std::function<int()>> zeroOps {        // nullary operators
  {'0', val(0)}, {'1', val(1)}, {'2', val(2)}, {'3', val(3)}, {'4', val(4)},
  {'5', val(5)}, {'6', val(6)}, {'7', val(7)}, {'8', val(8)}, {'9', val(9)},
  };
std::map<char,std::function<void(std::vector<int>&)>> stackOps { 
  { ' ', [](auto &stack) { } },           // no operation
  { 'c', [](auto &stack) { stack.clear(); } }, // Clear the entire stack
  { ':', [](auto &stack) {                // swap the top two elements
            auto top = stack.back(); stack.pop_back();
            auto second = stack.back(); stack.pop_back();
            stack.push_back(top);
            stack.push_back(second);
  } },
  { '=', [](auto &stack) {                // print the entire stack
            for(int elem : stack) { std::cout << elem; }
            std::cout << "\n";
  } },
};
void calculator(std::string input) {
  std::vector<int> stack {};
  for(char c : input) {
    int top, second;
    if(auto it = unOps.find(c); it != unOps.end()) {
      // if unary operator 
      auto func = it->second;
      top = stack.back(); stack.pop_back(); //  get top element
      stack.push_back(func(top));           //  apply func, push result onto stack
    } else if(auto it = binOps.find(c); it != binOps.end()) {
      // if binary operator 
      auto func = it->second;
      top = stack.back(); stack.pop_back(); //  get the top 2 elements
      second = stack.back(); stack.pop_back();
      stack.push_back(func(second, top));//  apply func, push result onto stack
    } else if(auto it = zeroOps.find(c); it !=zeroOps.end()) {
      // if nullary operator 
      auto func = it->second;
      stack.push_back(func());               // ... result of func on stack
    } else if(auto it = stackOps.find(c); it != stackOps.end()) {
      // if stack operator
      auto func = it->second;
      func(stack);                           // ... apply func to stack
    } else {
      std::cout << "\n'" << c << "' I don't understand.\n";
    }
  } /* for c */
}
int main(int argc, const char* argv[]) {
    if(argc > 1) {
        calculator(argv[1]);
    } else {
        // 3+4*5+6 with multiplication before addition results in 29
        calculator("345*+6+=");
    }
    calculator("93-=");                      // 9 - 3 = Output: 6
    calculator("82/=");                      // 8 / 2 = Output: 4
    calculator("92%=");                      // 9 % 2 = Output: 1
}