Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible and resonable to use Boost ICL instead of for_each in case of selecting a service for request?

I have a request structure with std::vector<std::string> arguments in it. I have a std::map<std::string, std::vector<std::string> > services where key is service name and value is a vector of arguments that service responds to. arguments of different services may overlap (N services may have same or partly same arguments). I need to find all services that correspond to given request. I wonder if it would be better (from code ease or reading and request selection speed most importantly) for me to use Boost ICL instead of current for_each I use for services selection (I simply iterate over each service and look if any of its arguments are presented in request)?

like image 635
myWallJSON Avatar asked Jan 26 '26 16:01

myWallJSON


1 Answers

I would go with the most readable variant. If performance is of concern, just cache the applicable services for an argument (set) into a multimap.

If I got the idea right, the following shows some c++11/boost syntactic sugars which demonstrate what I mean with readability:

#include <boost/range/numeric.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

typedef std::vector<std::string> args_t;
typedef std::map<std::string, args_t> service_map;

struct applicable
{
    template <typename T>
        applicable(const T& args) : _args(args) { }

    bool operator()(const service_map::value_type& svc) const
    {
        for (auto& a:_args)
            if (svc.second.end() == boost::find(svc.second, a))
                return false;
        return true;
    }
  private: args_t _args;
};

int main(int argc, const char *argv[])
{
    using namespace boost::adaptors;
    static const service_map services { 
        { "A", { "1","2","3" } }, 
        { "B", { "2","3","4" } },
        { "C", { "3","4","5" } }, 
        { "D", { "4","5","6" } } 
    };

    const std::string label = "request: ";

    for (const auto& req : std::list<args_t> { {"5"}, {"4","3"}, {"1","3"} })
    {
        std::cout << boost::accumulate(req, label) << std::endl;

        for (auto& svc : services | filtered(applicable(req)))
            std::cout << "applicable: " << svc.first << std::endl;
    }
}

Of course many optimizations could be applied. But you know what they say about premature optimization :)

Output:

request: 5
applicable: C
applicable: D
request: 43
applicable: B
applicable: C
request: 13
applicable: A
like image 177
sehe Avatar answered Jan 29 '26 07:01

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!