#ifndef __bootstrap_stl_hpp #define __bootstrap_stl_hpp__ #include "dispatchkit.hpp" #include "register_function.hpp" namespace dispatchkit { template struct Input_Range { Input_Range(Container &c) : m_begin(c.begin()), m_end(c.end()) { } Input_Range(typename Container::iterator itr) : m_begin(itr), m_end(itr) { } Input_Range(const std::pair &t_p) : m_begin(t_p.first), m_end(t_p.second) { } bool empty() const { return m_begin == m_end; } void pop_front() { if (empty()) { throw std::range_error("Range empty"); } ++m_begin; } typename std::iterator_traits::reference front() const { if (empty()) { throw std::range_error("Range empty"); } return *m_begin; } typename Container::iterator m_begin; typename Container::iterator m_end; }; template void bootstrap_input_range(Dispatch_Engine &system, const std::string &type) { system.register_function(build_constructor, ContainerType &>(), "range"); system.register_function(build_constructor, typename ContainerType::iterator>(), "range"); system.register_function(build_constructor, const std::pair &>(), "range"); register_function(system, &Input_Range::empty, "empty"); register_function(system, &Input_Range::pop_front, "pop_front"); register_function(system, &Input_Range::front, "front"); system.register_function(build_constructor, const Input_Range &>(), "clone"); } template void bootstrap_reversible_container(Dispatch_Engine &system, const std::string &type) { } template void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type) { bootstrap_reversible_container(system, type); typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); //In the interest of runtime safety for the system, we prefer the at() method for [] access, //to throw an exception in an out of bounds condition. system.register_function( boost::function(indexoper(&ContainerType::at)), "[]"); system.register_function( boost::function(indexoper(&ContainerType::operator[])), "at"); } template void bootstrap_assignable(Dispatch_Engine &system, const std::string &type) { system.register_function( boost::function(&Assignable::operator=), "="); system.register_function(build_constructor(), type); system.register_function(build_constructor(), "clone"); } template void bootstrap_container(Dispatch_Engine &system, const std::string &type) { bootstrap_assignable(system, type); system.register_function( boost::function(&ContainerType::size), "size"); system.register_function( boost::function(&ContainerType::size), "maxsize"); } template void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type) { bootstrap_input_range(system, type); bootstrap_container(system, type); } template void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type) { system.register_function(build_constructor(), type); } template void bootstrap_sequence(Dispatch_Engine &system, const std::string &type) { bootstrap_forward_container(system, type); bootstrap_default_constructible(system, type); } template void bootstrap_back_insertion_sequence(Dispatch_Engine &system, const std::string &type) { bootstrap_sequence(system, type); typedef typename SequenceType::reference (SequenceType::*backptr)(); system.register_function(boost::function(backptr(&SequenceType::back)), "back"); system.register_function(boost::function(&SequenceType::push_back), "push_back"); system.register_function(boost::function(&SequenceType::pop_back), "pop_back"); } template void bootstrap_vector(Dispatch_Engine &system, const std::string &type) { system.register_type(type); bootstrap_random_access_container(system, type); bootstrap_back_insertion_sequence(system, type); } template void bootstrap_associative_container(Dispatch_Engine &system, const std::string &type) { bootstrap_forward_container(system, type); bootstrap_default_constructible(system, type); } template void bootstrap_pair(Dispatch_Engine &system, const std::string &type) { register_member(system, &PairType::first, "first"); register_member(system, &PairType::second, "second"); system.register_function(build_constructor(), type); system.register_function(build_constructor(), type); system.register_function(build_constructor(), "clone"); system.register_function(build_constructor(), type); } template void bootstrap_pair_associative_container(Dispatch_Engine &system, const std::string &type) { bootstrap_associative_container(system, type); bootstrap_pair(system, type + "_Pair"); } template void bootstrap_unique_associative_container(Dispatch_Engine &system, const std::string &type) { bootstrap_associative_container(system, type); register_function(system, &ContainerType::count, "count"); } template void bootstrap_sorted_associative_container(Dispatch_Engine &system, const std::string &type) { typedef std::pair (ContainerType::*eq_range)(const typename ContainerType::key_type &); bootstrap_reversible_container(system, type); bootstrap_associative_container(system, type); register_function(system, eq_range(&ContainerType::equal_range), "equal_range"); } template void bootstrap_unique_sorted_associative_container(Dispatch_Engine &system, const std::string &type) { bootstrap_sorted_associative_container(system, type); bootstrap_unique_associative_container(system, type); } template void bootstrap_map(Dispatch_Engine &system, const std::string &type) { system.register_type(type); register_function(system, &MapType::operator[], "[]"); bootstrap_unique_sorted_associative_container(system, type); bootstrap_pair_associative_container(system, type); } } #endif