Search code examples
c++stringalgorithmswitch-statementstring-view

How to name algorithm in c++ for process items in collection which can add or remove items?


I search for some std:: algorithm but failed. I want to process items from input iterator til last iterator and write output into out iterator. Note output can be less or more then input stream. So I write example to show what exactly I need:

#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <string_view>

void some_algorithm_name(auto it_beg, auto it_end, auto it_out, auto func)
{
    for (; it_beg != it_end; it_beg++)
    {
        func(*it_beg, it_out);
    }
}

int main(int argc, char** argv)
{
    using namespace std;
    string_view in = "abcdefaa";
    string      out;
    some_algorithm_name(begin(in),
                        end(in),
                        back_inserter(out),
                        [](char ch, auto& out_it)
                        {
                            switch (ch)
                            {
                                case 'a': // duplicate
                                {
                                    *out_it++ = 'a';
                                    *out_it++ = 'a';
                                    break;
                                }
                                case 'b': // skip
                                {
                                    break;
                                }
                                case 'c': // change/transform
                                {
                                    *out_it++ = 'd';
                                    break;
                                }
                                case 'd': // change/transform
                                {
                                    *out_it++ = 'c';
                                    break;
                                }
                                default: // copy
                                {
                                    *out_it++ = ch;
                                }
                            }
                        });

    string expected = "aadcefaaaa";
    cout << "input: " << quoted(in) << endl;
    cout << "output: " << quoted(expected) << (expected == out ? "==" : "!=")
         << quoted(out) << endl;
    return 0;
}

Is any library or framework where I can find such algorithm? Or maybe you can offer some name for it?


Solution

  • One of approaches is to use standard algorithm std::accumulate declared in header <numeric>. For example

    #include <iostream>
    #include <string>
    #include <string_view>
    #include <iterator>
    #include <numeric>
    
    int main()
    {
        std::string_view in = "abcdefaa";
        std::string out;
    
        auto lambda = []( auto result, auto ch )
        {
            switch (ch)
            {
            case 'a': // duplicate
                result.append( 2, 'a' );
                break;
            case 'b': // skip
                break;
            case 'c': // change/transform
                result += 'd';
                break;
            case 'd': // change/transform
                result += 'c';
                break;
            default: // copy
                result += ch;
                break;
            }
    
            return  result;
        };
    
        out = std::accumulate( std::begin( in ), std::end( in ), std::string(), lambda );
    
        std::cout << "in = " << in << '\n';
        std::cout << "out = " << out << '\n';
    }
    

    The program output is

    in = abcdefaa
    out = aadcefaaaa
    

    I quickly showed one of approaches based on standard algorithms. However it seems there is better to use the old range-based for loop.