#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()) { } bool empty() const { return m_begin == m_end; } void popFront() { 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"); register_function(system, &Input_Range::empty, "empty"); register_function(system, &Input_Range::popFront, "popFront"); register_function(system, &Input_Range::front, "front"); } 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=), "="); } 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); } } #endif