<commit_before>#ifndef __dispatchkit_hpp__
#define __dispatchkit_hpp__

#include <typeinfo>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <vector>
#include <iostream>
#include <deque>

#include "boxed_value.hpp"
#include "type_info.hpp"
#include "proxy_functions.hpp"
#include "proxy_constructors.hpp"

namespace dispatchkit
{
  class Dispatch_Engine
  {
    public:
      typedef std::multimap<std::string, boost::shared_ptr<Proxy_Function> > Function_Map;
      typedef std::map<std::string, Type_Info> Type_Name_Map;
      typedef std::map<std::string, Boxed_Value> Scope;
      typedef std::deque<Scope> Stack;

      Dispatch_Engine()
      {
        m_scopes.push_back(Scope());
      }

      bool register_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &name)
      {
        return add_function(f, name);
      }

      template<typename Function>
        bool register_function(const Function &func, const std::string &name)
        {
          return add_function(boost::shared_ptr<Proxy_Function>(new Proxy_Function_Impl<Function>(func)), name);
        }

 
      template<typename Class>
        void set_object(const std::string &name, const Class &obj)
        {
          for (int i = m_scopes.size()-1; i >= 0; --i)
          {
            std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
            if (itr != m_scopes[i].end())
            {
              m_scopes[i][name] = Boxed_Value(obj);
              return;
            }
          }

          add_object(name, obj);
        }

      template<typename Class>
        void add_object(const std::string &name, const Class &obj)
        {
          m_scopes.back()[name] = Boxed_Value(obj);
        }

      void new_scope()
      {
        m_scopes.push_back(Scope());
      }

      void pop_scope()
      {
        if (m_scopes.size() > 1)
        {
          m_scopes.pop_back();
        } else {
          throw std::range_error("Unable to pop global stack");
        }
      }

      Stack get_stack()
      {
        return m_scopes;
      }

      Stack set_stack(Stack s)
      {
        swap(s, m_scopes);
        return s;
      }


      Boxed_Value get_object(const std::string &name) const
      {
        for (int i = m_scopes.size()-1; i >= 0; --i)
        {
          std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
          if (itr != m_scopes[i].end())
          {
            return itr->second;
          }
        }

        throw std::range_error("Object not known: " + name);
      }

      template<typename Type>
        void register_type(const std::string &name)
        {
          m_types.insert(std::make_pair(name, Get_Type_Info<Type>::get()));
        }

      std::vector<Type_Name_Map::value_type> get_types() const
      {
        return std::vector<Type_Name_Map::value_type>(m_types.begin(), m_types.end());
      }

      std::vector<std::pair<std::string, Function_Map::mapped_type> > 
        get_function(const std::string &t_name) const
      {
        std::vector<std::pair<std::string, Function_Map::mapped_type> > funcs;

        try {
          funcs.insert(funcs.end(), 
              Function_Map::value_type(
                t_name, 
                boxed_cast<Function_Map::mapped_type>(get_object(t_name)))
              );
        } catch (const std::bad_cast &) {
        } catch (const std::range_error &) {
        }

        std::pair<Function_Map::const_iterator, Function_Map::const_iterator> range
          = m_functions.equal_range(t_name);

        funcs.insert(funcs.end(), range.first, range.second);
        return funcs;
      }

      std::vector<Function_Map::value_type> get_functions() const
      {
        return std::vector<Function_Map::value_type>(m_functions.begin(), m_functions.end());
      }

    private:
      bool add_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &t_name)
      {
        std::pair<Function_Map::const_iterator, Function_Map::const_iterator> range
          = m_functions.equal_range(t_name);

        while (range.first != range.second)
        {
          if ((*f) == *(range.first->second))
          {
            return false;
          }
          ++range.first;
        }

        m_functions.insert(std::make_pair(t_name, f));
        return true;
      }
<commit_msg>Return matching named functions when a get_object query finds no matching name object<commit_after>#ifndef __dispatchkit_hpp__
#define __dispatchkit_hpp__

#include <typeinfo>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <vector>
#include <iostream>
#include <deque>

#include "boxed_value.hpp"
#include "type_info.hpp"
#include "proxy_functions.hpp"
#include "proxy_constructors.hpp"

namespace dispatchkit
{
  class Dispatch_Function : public Proxy_Function
  {
    public:
      Dispatch_Function(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &t_funcs)
        : m_funcs(t_funcs)
      {
      }

      bool operator==(const Proxy_Function &f) const
      {
        return false;
      }

      virtual ~Dispatch_Function() {}

      virtual Boxed_Value operator()(const std::vector<Boxed_Value> &params)
      {
        return dispatch(m_funcs, params);
      }

      virtual std::vector<Type_Info> get_param_types()
      {
        return std::vector<Type_Info>();
      }

    private:
      std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > m_funcs;
  };  
  
  
  class Dispatch_Engine
  {
    public:
      typedef std::multimap<std::string, boost::shared_ptr<Proxy_Function> > Function_Map;
      typedef std::map<std::string, Type_Info> Type_Name_Map;
      typedef std::map<std::string, Boxed_Value> Scope;
      typedef std::deque<Scope> Stack;

      Dispatch_Engine()
      {
        m_scopes.push_back(Scope());
      }

      bool register_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &name)
      {
        return add_function(f, name);
      }

      template<typename Function>
        bool register_function(const Function &func, const std::string &name)
        {
          return add_function(boost::shared_ptr<Proxy_Function>(new Proxy_Function_Impl<Function>(func)), name);
        }

 
      template<typename Class>
        void set_object(const std::string &name, const Class &obj)
        {
          for (int i = m_scopes.size()-1; i >= 0; --i)
          {
            std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
            if (itr != m_scopes[i].end())
            {
              m_scopes[i][name] = Boxed_Value(obj);
              return;
            }
          }

          add_object(name, obj);
        }

      template<typename Class>
        void add_object(const std::string &name, const Class &obj)
        {
          m_scopes.back()[name] = Boxed_Value(obj);
        }

      void new_scope()
      {
        m_scopes.push_back(Scope());
      }

      void pop_scope()
      {
        if (m_scopes.size() > 1)
        {
          m_scopes.pop_back();
        } else {
          throw std::range_error("Unable to pop global stack");
        }
      }

      Stack get_stack()
      {
        return m_scopes;
      }

      Stack set_stack(Stack s)
      {
        swap(s, m_scopes);
        return s;
      }


      Boxed_Value get_object(const std::string &name) const
      {
        for (int i = m_scopes.size()-1; i >= 0; --i)
        {
          std::map<std::string, Boxed_Value>::const_iterator itr = m_scopes[i].find(name);
          if (itr != m_scopes[i].end())
          {
            return itr->second;
          }
        }

        std::vector<std::pair<std::string, Function_Map::mapped_type> > funcs = get_function_impl(name, false);

        if (funcs.empty())
        {
          throw std::range_error("Object not known: " + name);
        } else {
          return Boxed_Value(boost::shared_ptr<Proxy_Function>(new Dispatch_Function(funcs)));
        }
      }

      template<typename Type>
        void register_type(const std::string &name)
        {
          m_types.insert(std::make_pair(name, Get_Type_Info<Type>::get()));
        }

      std::vector<Type_Name_Map::value_type> get_types() const
      {
        return std::vector<Type_Name_Map::value_type>(m_types.begin(), m_types.end());
      }

      std::vector<std::pair<std::string, Function_Map::mapped_type> > 
        get_function_impl(const std::string &t_name, bool include_objects) const
      {
        std::vector<std::pair<std::string, Function_Map::mapped_type> > funcs;

        if (include_objects)
        {
          try {
            funcs.insert(funcs.end(), 
                Function_Map::value_type(
                  t_name, 
                  boxed_cast<Function_Map::mapped_type>(get_object(t_name)))
                );
          } catch (const bad_boxed_cast &) {
          } catch (const std::range_error &) {
          }
        }

        std::pair<Function_Map::const_iterator, Function_Map::const_iterator> range
          = m_functions.equal_range(t_name);

        funcs.insert(funcs.end(), range.first, range.second);
        return funcs;
      }

      std::vector<std::pair<std::string, Function_Map::mapped_type> > 
        get_function(const std::string &t_name) const
      {
        return get_function_impl(t_name, true);
      }
 
      std::vector<Function_Map::value_type> get_functions() const
      {
        return std::vector<Function_Map::value_type>(m_functions.begin(), m_functions.end());
      }

    private:
      bool add_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &t_name)
      {
        std::pair<Function_Map::const_iterator, Function_Map::const_iterator> range
          = m_functions.equal_range(t_name);

        while (range.first != range.second)
        {
          if ((*f) == *(range.first->second))
          {
            return false;
          }
          ++range.first;
        }

        m_functions.insert(std::make_pair(t_name, f));
        return true;
      }

{'fraction_non_alphanumeric': 0.127084755681264, 'fraction_numerical': 0.0009753242953281966, 'mean_word_length': 2.319520880543865, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 99, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7431424', 'n_tokens_mistral': 3275, 'n_tokens_neox': 3198, 'n_words': 554}