diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index 4044f65..a1b7b1d 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -9,61 +9,63 @@ namespace chaiscript { - namespace threading + namespace detail { + namespace threading + { #ifndef CHAISCRIPT_NO_THREADS - template - class Thread_Storage - { - public: - ~Thread_Storage() - { - m_thread_storage.reset(); - } - - inline T *operator->() const - { - if (!m_thread_storage.get()) + template + class Thread_Storage + { + public: + ~Thread_Storage() { - m_thread_storage.reset(new T()); + m_thread_storage.reset(); } - return m_thread_storage.get(); - } + inline T *operator->() const + { + if (!m_thread_storage.get()) + { + m_thread_storage.reset(new T()); + } - inline T &operator*() const - { - return *(this->operator->()); - } + return m_thread_storage.get(); + } - private: - mutable boost::thread_specific_ptr m_thread_storage; - }; + inline T &operator*() const + { + return *(this->operator->()); + } + + private: + mutable boost::thread_specific_ptr m_thread_storage; + }; #else - template - class Thread_Storage - { - public: - inline T *operator->() const - { - return &obj; - } + template + class Thread_Storage + { + public: + inline T *operator->() const + { + return &obj; + } - inline T &operator*() const - { - return obj; - } + inline T &operator*() const + { + return obj; + } - private: - mutable T obj; - }; + private: + mutable T obj; + }; #endif - + } } } diff --git a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp index c18aa64..46c70ec 100644 --- a/include/chaiscript/dispatchkit/bad_boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/bad_boxed_cast.hpp @@ -11,43 +11,45 @@ namespace chaiscript { - - /** - * class that is thrown in the event of a bad_boxed_cast. That is, - * in the case that a Boxed_Value cannot be cast to the desired type - */ - class bad_boxed_cast : public std::bad_cast + namespace exception { - public: - bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &what) - : from(t_from), to(&t_to), m_what(what) - { - } + /** + * class that is thrown in the event of a bad_boxed_cast. That is, + * in the case that a Boxed_Value cannot be cast to the desired type + */ + class bad_boxed_cast : public std::bad_cast + { + public: + bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to, + const std::string &what) + : from(t_from), to(&t_to), m_what(what) + { + } - bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) throw() - : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast") - { - } + bad_boxed_cast(const Type_Info &t_from, const std::type_info &t_to) throw() + : from(t_from), to(&t_to), m_what("Cannot perform boxed_cast") + { + } - bad_boxed_cast(const std::string &w) throw() - : m_what(w) - { - } + bad_boxed_cast(const std::string &w) throw() + : m_what(w) + { + } - virtual ~bad_boxed_cast() throw() {} + virtual ~bad_boxed_cast() throw() {} - virtual const char * what() const throw() - { - return m_what.c_str(); - } + virtual const char * what() const throw() + { + return m_what.c_str(); + } - Type_Info from; - const std::type_info *to; + Type_Info from; + const std::type_info *to; - private: - std::string m_what; - }; + private: + std::string m_what; + }; + } } diff --git a/include/chaiscript/dispatchkit/bind_first.hpp b/include/chaiscript/dispatchkit/bind_first.hpp index 830639e..4fe800b 100644 --- a/include/chaiscript/dispatchkit/bind_first.hpp +++ b/include/chaiscript/dispatchkit/bind_first.hpp @@ -30,34 +30,38 @@ namespace chaiscript { - - template - boost::function + + namespace detail + { + template + boost::function bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const O &o) { return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); } - template - boost::function + template + boost::function bind_first(Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, const O &o) { return boost::bind(boost::mem_fn(f), o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); } - template - boost::function + template + boost::function bind_first(Ret (*f)(BOOST_PP_ENUM_PARAMS(m, Param)), const O &o) { return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); } - template - boost::function + template + boost::function bind_first(const boost::function &f, const O &o) { return boost::bind(f, o BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM(n, param, _)); } + + } } #undef n diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index 622bf7a..06e5fdc 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -58,7 +58,7 @@ namespace chaiscript return p1 &= P1(r.i); } - throw bad_boxed_cast("&= only valid for integer types"); + throw exception::bad_boxed_cast("&= only valid for integer types"); } template @@ -69,7 +69,7 @@ namespace chaiscript return p1 ^= P1(r.i); } - throw bad_boxed_cast("^= only valid for integer types"); + throw exception::bad_boxed_cast("^= only valid for integer types"); } template @@ -80,7 +80,7 @@ namespace chaiscript return p1 |= P1(r.i); } - throw bad_boxed_cast("&= only valid for integer types"); + throw exception::bad_boxed_cast("&= only valid for integer types"); } template @@ -102,7 +102,7 @@ namespace chaiscript return p1 <<= P1(r.i); } - throw bad_boxed_cast("<<= only valid for integer types"); + throw exception::bad_boxed_cast("<<= only valid for integer types"); } @@ -136,7 +136,7 @@ namespace chaiscript return p1 %= P1(r.i); } - throw bad_boxed_cast("%= only valid for integer types"); + throw exception::bad_boxed_cast("%= only valid for integer types"); } @@ -148,7 +148,7 @@ namespace chaiscript return p1 >>= P1(r.i); } - throw bad_boxed_cast(">>= only valid for integer types"); + throw exception::bad_boxed_cast(">>= only valid for integer types"); } @@ -393,7 +393,7 @@ namespace chaiscript lhs.assign(Boxed_Value(rhs)); return lhs; } else { - throw bad_boxed_cast("type mismatch in pointer assignment"); + throw exception::bad_boxed_cast("type mismatch in pointer assignment"); } } @@ -413,7 +413,7 @@ namespace chaiscript { return (lhs.assign(rhs)); } else { - throw bad_boxed_cast("boxed_value has a set type already"); + throw exception::bad_boxed_cast("boxed_value has a set type already"); } } @@ -453,7 +453,7 @@ namespace chaiscript { if (params.size() < 2) { - throw arity_error(static_cast(params.size()), 2); + throw exception::arity_error(static_cast(params.size()), 2); } Const_Proxy_Function f = boxed_cast(params[0]); @@ -470,7 +470,7 @@ namespace chaiscript { if (params.size() < 1) { - throw arity_error(static_cast(params.size()), 1); + throw exception::arity_error(static_cast(params.size()), 1); } Const_Proxy_Function f = boxed_cast(params[0]); diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index c1182ae..ef8abee 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -20,503 +20,511 @@ namespace chaiscript { namespace bootstrap { - /** - * Bidir_Range, based on the D concept of ranges. - * \todo Update the Range code to base its capabilities on - * the user_typetraits of the iterator passed in - */ - template - struct Bidir_Range + namespace standard_library { - typedef Container container_type; - typedef typename std::iterator_traits::reference reference_type; - - Bidir_Range(Container &c) - : m_begin(c.begin()), m_end(c.end()) - { - } - - bool empty() const - { - return m_begin == m_end; - } - - void pop_front() - { - if (empty()) + /** + * Bidir_Range, based on the D concept of ranges. + * \todo Update the Range code to base its capabilities on + * the user_typetraits of the iterator passed in + */ + template + struct Bidir_Range { - throw std::range_error("Range empty"); - } - ++m_begin; - } + typedef Container container_type; + typedef typename std::iterator_traits::reference reference_type; - void pop_back() - { - if (empty()) + Bidir_Range(Container &c) + : m_begin(c.begin()), m_end(c.end()) + { + } + + bool empty() const + { + return m_begin == m_end; + } + + void pop_front() + { + if (empty()) + { + throw std::range_error("Range empty"); + } + ++m_begin; + } + + void pop_back() + { + if (empty()) + { + throw std::range_error("Range empty"); + } + --m_end; + } + + reference_type front() const + { + if (empty()) + { + throw std::range_error("Range empty"); + } + return *m_begin; + } + + reference_type back() const + { + if (empty()) + { + throw std::range_error("Range empty"); + } + typename Container::iterator pos = m_end; + --pos; + return *(pos); + } + + typename Container::iterator m_begin; + typename Container::iterator m_end; + }; + + template + struct Const_Bidir_Range { - throw std::range_error("Range empty"); - } - --m_end; + typedef const Container container_type; + typedef typename std::iterator_traits::reference const_reference_type; + + Const_Bidir_Range(const Container &c) + : m_begin(c.begin()), m_end(c.end()) + { + } + + bool empty() const + { + return m_begin == m_end; + } + + void pop_front() + { + if (empty()) + { + throw std::range_error("Range empty"); + } + ++m_begin; + } + + void pop_back() + { + if (empty()) + { + throw std::range_error("Range empty"); + } + --m_end; + } + + const_reference_type front() const + { + if (empty()) + { + throw std::range_error("Range empty"); + } + return *m_begin; + } + + const_reference_type back() const + { + if (empty()) + { + throw std::range_error("Range empty"); + } + typename Container::const_iterator pos = m_end; + --pos; + return *(pos); + } + + typename Container::const_iterator m_begin; + typename Container::const_iterator m_end; + }; + + namespace detail { + /** + * Add Bidir_Range support for the given ContainerType + */ + template + ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type + "_Range"); + + copy_constructor(type + "_Range", m); + + m->add(constructor(), "range"); + + m->add(fun(&Bidir_Type::empty), "empty"); + m->add(fun(&Bidir_Type::pop_front), "pop_front"); + m->add(fun(&Bidir_Type::front), "front"); + m->add(fun(&Bidir_Type::pop_back), "pop_back"); + m->add(fun(&Bidir_Type::back), "back"); + + return m; + } + + /** + * Algorithm for inserting at a specific position into a container + */ + template + void insert_at(Type &container, int pos, const typename Type::value_type &v) + { + typename Type::iterator itr = container.begin(); + typename Type::iterator end = container.end(); + + if (pos < 0 || std::distance(itr, end) < pos) + { + throw std::range_error("Cannot insert past end of range"); + } + + std::advance(itr, pos); + container.insert(itr, v); + } + + /** + * Algorithm for erasing a specific position from a container + */ + template + void erase_at(Type &container, int pos) + { + typename Type::iterator itr = container.begin(); + typename Type::iterator end = container.end(); + + if (pos < 0 || std::distance(itr, end) < (pos-1)) + { + throw std::range_error("Cannot erase past end of range"); + } + + std::advance(itr, pos); + container.erase(itr); + } + } - reference_type front() const - { - if (empty()) + template + ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); + detail::input_range_type_impl >(type,m); + detail::input_range_type_impl >("Const_" + type, m); + return m; } - return *m_begin; - } - reference_type back() const - { - if (empty()) + /** + * Add random_access_container concept to the given ContainerType + * http://www.sgi.com/tech/stl/RandomAccessContainer.html + */ + template + ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); + typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); + typedef typename ContainerType::const_reference(ContainerType::*constindexoper)(size_t) const; + + //In the interest of runtime safety for the m, we prefer the at() method for [] access, + //to throw an exception in an out of bounds condition. + m->add( + fun(boost::function + (boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); + m->add( + fun(boost::function + (boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); + + return m; } - typename Container::iterator pos = m_end; - --pos; - return *(pos); - } - typename Container::iterator m_begin; - typename Container::iterator m_end; - }; - - template - struct Const_Bidir_Range - { - typedef const Container container_type; - typedef typename std::iterator_traits::reference const_reference_type; - - Const_Bidir_Range(const Container &c) - : m_begin(c.begin()), m_end(c.end()) - { - } - - bool empty() const - { - return m_begin == m_end; - } - - void pop_front() - { - if (empty()) + /** + * Add assignable concept to the given ContainerType + * http://www.sgi.com/tech/stl/Assignable.html + */ + template + ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); + basic_constructors(type, m); + operators::assign(m); + return m; } - ++m_begin; - } - void pop_back() - { - if (empty()) + /** + * Add container concept to the given ContainerType + * http://www.sgi.com/tech/stl/Container.html + */ + template + ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); - } - --m_end; - } + m->add(fun(boost::function(boost::mem_fn(&ContainerType::size))), "size"); + m->add(fun(&ContainerType::empty), "empty"); + m->add(fun(&ContainerType::clear), "clear"); - const_reference_type front() const - { - if (empty()) + return m; + } + + /** + * Add default constructable concept to the given Type + * http://www.sgi.com/tech/stl/DefaultConstructible.html + */ + template + ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); + m->add(constructor(), type); + return m; } - return *m_begin; - } - const_reference_type back() const - { - if (empty()) + + + /** + * Add sequence concept to the given ContainerType + * http://www.sgi.com/tech/stl/Sequence.html + */ + template + ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) { - throw std::range_error("Range empty"); + std::string insert_name; + if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + { + insert_name = "insert_ref_at"; + } else { + insert_name = "insert_at"; + } + + m->add(fun(&detail::insert_at), insert_name); + m->add(fun(&detail::erase_at), "erase_at"); + + return m; } - typename Container::const_iterator pos = m_end; - --pos; - return *(pos); - } - typename Container::const_iterator m_begin; - typename Container::const_iterator m_end; - }; + /** + * Add back insertion sequence concept to the given ContainerType + * http://www.sgi.com/tech/stl/BackInsertionSequence.html + */ + template + ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) + { + typedef typename ContainerType::reference (ContainerType::*backptr)(); -namespace detail { - /** - * Add Bidir_Range support for the given ContainerType - */ - template - ModulePtr input_range_type_impl(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type + "_Range"); + m->add(fun(static_cast(&ContainerType::back)), "back"); - copy_constructor(type + "_Range", m); + std::string push_back_name; + if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + { + push_back_name = "push_back_ref"; + } else { + push_back_name = "push_back"; + } - m->add(constructor(), "range"); - - m->add(fun(&Bidir_Type::empty), "empty"); - m->add(fun(&Bidir_Type::pop_front), "pop_front"); - m->add(fun(&Bidir_Type::front), "front"); - m->add(fun(&Bidir_Type::pop_back), "pop_back"); - m->add(fun(&Bidir_Type::back), "back"); - - return m; - } -} - - template - ModulePtr input_range_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - detail::input_range_type_impl >(type,m); - detail::input_range_type_impl >("Const_" + type, m); - return m; - } - - /** - * Add random_access_container concept to the given ContainerType - * http://www.sgi.com/tech/stl/RandomAccessContainer.html - */ - template - ModulePtr random_access_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) - { - typedef typename ContainerType::reference(ContainerType::*indexoper)(size_t); - typedef typename ContainerType::const_reference(ContainerType::*constindexoper)(size_t) const; - - //In the interest of runtime safety for the m, we prefer the at() method for [] access, - //to throw an exception in an out of bounds condition. - m->add( - fun(boost::function(boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); - m->add( - fun(boost::function(boost::mem_fn(static_cast(&ContainerType::at)))), "[]"); - - return m; - } - - /** - * Add assignable concept to the given ContainerType - * http://www.sgi.com/tech/stl/Assignable.html - */ - template - ModulePtr assignable_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - basic_constructors(type, m); - operators::assign(m); - return m; - } - - /** - * Add container concept to the given ContainerType - * http://www.sgi.com/tech/stl/Container.html - */ - template - ModulePtr container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(boost::function(boost::mem_fn(&ContainerType::size))), "size"); - m->add(fun(&ContainerType::empty), "empty"); - m->add(fun(&ContainerType::clear), "clear"); - - return m; - } - - /** - * Add default constructable concept to the given Type - * http://www.sgi.com/tech/stl/DefaultConstructible.html - */ - template - ModulePtr default_constructible_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(constructor(), type); - return m; - } - - /** - * Algorithm for inserting at a specific position into a container - */ - template - void insert_at(Type &container, int pos, const typename Type::value_type &v) - { - typename Type::iterator itr = container.begin(); - typename Type::iterator end = container.end(); - - if (pos < 0 || std::distance(itr, end) < pos) - { - throw std::range_error("Cannot insert past end of range"); - } - - std::advance(itr, pos); - container.insert(itr, v); - } - - /** - * Algorithm for erasing a specific position from a container - */ - template - void erase_at(Type &container, int pos) - { - typename Type::iterator itr = container.begin(); - typename Type::iterator end = container.end(); - - if (pos < 0 || std::distance(itr, end) < (pos-1)) - { - throw std::range_error("Cannot erase past end of range"); - } - - std::advance(itr, pos); - container.erase(itr); - } - - /** - * Add sequence concept to the given ContainerType - * http://www.sgi.com/tech/stl/Sequence.html - */ - template - ModulePtr sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) - { - std::string insert_name; - if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) - { - insert_name = "insert_ref_at"; - } else { - insert_name = "insert_at"; - } - - m->add(fun(&insert_at), insert_name); - m->add(fun(&erase_at), "erase_at"); - - return m; - } - - /** - * Add back insertion sequence concept to the given ContainerType - * http://www.sgi.com/tech/stl/BackInsertionSequence.html - */ - template - ModulePtr back_insertion_sequence_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) - { - typedef typename ContainerType::reference (ContainerType::*backptr)(); - - m->add(fun(static_cast(&ContainerType::back)), "back"); - - std::string push_back_name; - if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) - { - push_back_name = "push_back_ref"; - } else { - push_back_name = "push_back"; - } - - typedef void (ContainerType::*pushback)(const typename ContainerType::value_type &); - m->add(fun(static_cast(&ContainerType::push_back)), push_back_name); - m->add(fun(&ContainerType::pop_back), "pop_back"); - return m; - } + typedef void (ContainerType::*pushback)(const typename ContainerType::value_type &); + m->add(fun(static_cast(&ContainerType::push_back)), push_back_name); + m->add(fun(&ContainerType::pop_back), "pop_back"); + return m; + } - /** - *Front insertion sequence - *http://www.sgi.com/tech/stl/FrontInsertionSequence.html - */ - template - ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module())) - { - typedef typename ContainerType::reference (ContainerType::*frontptr)(); - typedef void (ContainerType::*pushptr)(typename ContainerType::const_reference); - typedef void (ContainerType::*popptr)(); + /** + *Front insertion sequence + *http://www.sgi.com/tech/stl/FrontInsertionSequence.html + */ + template + ModulePtr front_insertion_sequence_type(const std::string &, ModulePtr m = ModulePtr(new Module())) + { + typedef typename ContainerType::reference (ContainerType::*frontptr)(); + typedef void (ContainerType::*pushptr)(typename ContainerType::const_reference); + typedef void (ContainerType::*popptr)(); - m->add(fun(static_cast(&ContainerType::front)), "front"); + m->add(fun(static_cast(&ContainerType::front)), "front"); - std::string push_front_name; - if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) - { - push_front_name = "push_front_ref"; - } else { - push_front_name = "push_front"; - } - - m->add(fun(static_cast(&ContainerType::push_front)), push_front_name); - m->add(fun(static_cast(&ContainerType::pop_front)), "pop_front"); - return m; - } + std::string push_front_name; + if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value)) + { + push_front_name = "push_front_ref"; + } else { + push_front_name = "push_front"; + } - /** - * bootstrap a given PairType - * http://www.sgi.com/tech/stl/pair.html - */ - template - ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); + m->add(fun(static_cast(&ContainerType::push_front)), push_front_name); + m->add(fun(static_cast(&ContainerType::pop_front)), "pop_front"); + return m; + } - - typename PairType::first_type PairType::* f = &PairType::first; - typename PairType::second_type PairType::* s = &PairType::second; - - m->add(fun(f), "first"); - m->add(fun(s), "second"); - - basic_constructors(type, m); - m->add(constructor(), type); - - return m; - } + /** + * bootstrap a given PairType + * http://www.sgi.com/tech/stl/pair.html + */ + template + ModulePtr pair_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); - /** - * Add pair associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/PairAssociativeContainer.html - */ - template - ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - pair_type(type + "_Pair", m); + typename PairType::first_type PairType::* f = &PairType::first; + typename PairType::second_type PairType::* s = &PairType::second; - return m; - } + m->add(fun(f), "first"); + m->add(fun(s), "second"); - /** - * Add unique associative container concept to the given ContainerType - * http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html - */ - template - ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(boost::function(boost::mem_fn(&ContainerType::count))), "count"); + basic_constructors(type, m); + m->add(constructor(), type); - return m; - } - - /** - * Add a MapType container - * http://www.sgi.com/tech/stl/Map.html - */ - template - ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); - - typedef typename MapType::mapped_type &(MapType::*elemaccess)(const typename MapType::key_type &); - - m->add(fun(static_cast(&MapType::operator[])), "[]"); - - container_type(type, m); - assignable_type(type, m); - unique_associative_container_type(type, m); - pair_associative_container_type(type, m); - input_range_type(type, m); - - return m; - } - - /** - * hopefully working List type - * http://www.sgi.com/tech/stl/List.html - */ - template - ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); - - front_insertion_sequence_type(type, m); - back_insertion_sequence_type(type, m); - sequence_type(type, m); - container_type(type, m); - default_constructible_type(type, m); - assignable_type(type, m); - input_range_type(type, m); - - return m; - } - - /** - * Create a vector type with associated concepts - * http://www.sgi.com/tech/stl/Vector.html - */ - template - ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); - - typedef typename VectorType::reference (VectorType::*frontptr)(); - m->add(fun(static_cast(&VectorType::front)), "front"); + return m; + } - back_insertion_sequence_type(type, m); - sequence_type(type, m); - random_access_container_type(type, m); - container_type(type, m); - default_constructible_type(type, m); - assignable_type(type, m); - input_range_type(type, m); + /** + * Add pair associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/PairAssociativeContainer.html + */ + template + ModulePtr pair_associative_container_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + pair_type(type + "_Pair", m); - if (typeid(VectorType) == typeid(std::vector)) - { - m->eval("def Vector::`==`(rhs) : type_match(rhs, this) { \ - if ( rhs.size() != this.size() ) { \ - return false; \ - } else { \ - var r1 = range(this); \ - var r2 = range(rhs); \ - while (!r1.empty()) \ - { \ - if (!eq(r1.front(), r2.front())) \ - { \ - return false; \ + return m; + } + + /** + * Add unique associative container concept to the given ContainerType + * http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html + */ + template + ModulePtr unique_associative_container_type(const std::string &/*type*/, ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(boost::function(boost::mem_fn(&ContainerType::count))), "count"); + + return m; + } + + /** + * Add a MapType container + * http://www.sgi.com/tech/stl/Map.html + */ + template + ModulePtr map_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + + typedef typename MapType::mapped_type &(MapType::*elemaccess)(const typename MapType::key_type &); + + m->add(fun(static_cast(&MapType::operator[])), "[]"); + + container_type(type, m); + assignable_type(type, m); + unique_associative_container_type(type, m); + pair_associative_container_type(type, m); + input_range_type(type, m); + + return m; + } + + /** + * hopefully working List type + * http://www.sgi.com/tech/stl/List.html + */ + template + ModulePtr list_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + + front_insertion_sequence_type(type, m); + back_insertion_sequence_type(type, m); + sequence_type(type, m); + container_type(type, m); + default_constructible_type(type, m); + assignable_type(type, m); + input_range_type(type, m); + + return m; + } + + /** + * Create a vector type with associated concepts + * http://www.sgi.com/tech/stl/Vector.html + */ + template + ModulePtr vector_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + + typedef typename VectorType::reference (VectorType::*frontptr)(); + m->add(fun(static_cast(&VectorType::front)), "front"); + + + back_insertion_sequence_type(type, m); + sequence_type(type, m); + random_access_container_type(type, m); + container_type(type, m); + default_constructible_type(type, m); + assignable_type(type, m); + input_range_type(type, m); + + if (typeid(VectorType) == typeid(std::vector)) + { + m->eval("def Vector::`==`(rhs) : type_match(rhs, this) { \ + if ( rhs.size() != this.size() ) { \ + return false; \ + } else { \ + var r1 = range(this); \ + var r2 = range(rhs); \ + while (!r1.empty()) \ + { \ + if (!eq(r1.front(), r2.front())) \ + { \ + return false; \ + } \ + r1.pop_front(); \ + r2.pop_front(); \ + } \ + return true; \ } \ - r1.pop_front(); \ - r2.pop_front(); \ - } \ - return true; \ - } \ - }"); - } + }"); + } - return m; - } + return m; + } - /** - * Add a String container - * http://www.sgi.com/tech/stl/basic_string.html - */ - template - ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) - { - m->add(user_type(), type); - operators::addition(m); - operators::assign_sum(m); - opers_comparison(m); - random_access_container_type(type, m); - sequence_type(type, m); - default_constructible_type(type, m); - container_type(type, m); - assignable_type(type, m); - input_range_type(type, m); + /** + * Add a String container + * http://www.sgi.com/tech/stl/basic_string.html + */ + template + ModulePtr string_type(const std::string &type, ModulePtr m = ModulePtr(new Module())) + { + m->add(user_type(), type); + operators::addition(m); + operators::assign_sum(m); + opers_comparison(m); + random_access_container_type(type, m); + sequence_type(type, m); + default_constructible_type(type, m); + container_type(type, m); + assignable_type(type, m); + input_range_type(type, m); - //Special case: add push_back to string (which doesn't support other back_insertion operations - std::string push_back_name; - if (typeid(typename String::value_type) == typeid(Boxed_Value)) - { - push_back_name = "push_back_ref"; - } else { - push_back_name = "push_back"; - } - m->add(fun(&String::push_back), push_back_name); + //Special case: add push_back to string (which doesn't support other back_insertion operations + std::string push_back_name; + if (typeid(typename String::value_type) == typeid(Boxed_Value)) + { + push_back_name = "push_back_ref"; + } else { + push_back_name = "push_back"; + } + m->add(fun(&String::push_back), push_back_name); - typedef typename String::size_type (String::*find_func_ptr)(const String &, typename String::size_type) const; + typedef typename String::size_type (String::*find_func_ptr)(const String &, typename String::size_type) const; - typedef boost::function find_func; + typedef boost::function find_func; - m->add(fun(find_func(boost::mem_fn(static_cast(&String::find)))), "find"); - m->add(fun(find_func(boost::mem_fn(static_cast(&String::rfind)))), "rfind"); - m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_first_of)))), "find_first_of"); - m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_last_of)))), "find_last_of"); - m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_first_not_of)))), "find_first_not_of"); - m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_last_not_of)))), "find_last_not_of"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::find)))), "find"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::rfind)))), "rfind"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_first_of)))), "find_first_of"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_last_of)))), "find_last_of"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_first_not_of)))), "find_first_not_of"); + m->add(fun(find_func(boost::mem_fn(static_cast(&String::find_last_not_of)))), "find_last_not_of"); - m->add(fun(&String::c_str), "c_str"); - m->add(fun(&String::data), "data"); + m->add(fun(&String::c_str), "c_str"); + m->add(fun(&String::data), "data"); - return m; + return m; + } } } } diff --git a/include/chaiscript/dispatchkit/boxed_cast.hpp b/include/chaiscript/dispatchkit/boxed_cast.hpp index b410a31..6cd137c 100644 --- a/include/chaiscript/dispatchkit/boxed_cast.hpp +++ b/include/chaiscript/dispatchkit/boxed_cast.hpp @@ -44,19 +44,19 @@ namespace chaiscript #pragma warning(disable : 4127) #endif - if (boost::is_polymorphic::type>::value) + if (boost::is_polymorphic::type>::value) { try { // We will not catch any bad_boxed_dynamic_cast that is thrown, let the user get it // either way, we are not responsible if it doesn't work return detail::Cast_Helper::cast(boxed_dynamic_cast(bv)); } catch (const boost::bad_any_cast &) { - throw bad_boxed_cast(bv.get_type_info(), typeid(Type)); + throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } } else { // If it's not polymorphic, just throw the error, don't waste the time on the // attempted dynamic_cast - throw bad_boxed_cast(bv.get_type_info(), typeid(Type)); + throw exception::bad_boxed_cast(bv.get_type_info(), typeid(Type)); } #ifdef BOOST_MSVC diff --git a/include/chaiscript/dispatchkit/boxed_pod_value.hpp b/include/chaiscript/dispatchkit/boxed_pod_value.hpp index 55552c7..ab51c58 100644 --- a/include/chaiscript/dispatchkit/boxed_pod_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_pod_value.hpp @@ -128,7 +128,7 @@ namespace chaiscript return Boxed_Value(i & r.i); } - throw bad_boxed_cast("& only valid for integer types"); + throw exception::bad_boxed_cast("& only valid for integer types"); } Boxed_Value operator^(const Boxed_POD_Value &r) const @@ -138,7 +138,7 @@ namespace chaiscript return Boxed_Value(i ^ r.i); } - throw bad_boxed_cast("^ only valid for integer types"); + throw exception::bad_boxed_cast("^ only valid for integer types"); } Boxed_Value operator|(const Boxed_POD_Value &r) const @@ -148,7 +148,7 @@ namespace chaiscript return Boxed_Value(i | r.i); } - throw bad_boxed_cast("| only valid for integer types"); + throw exception::bad_boxed_cast("| only valid for integer types"); } Boxed_Value operator/(const Boxed_POD_Value &r) const @@ -168,7 +168,7 @@ namespace chaiscript return smart_size(i << r.i); } - throw bad_boxed_cast("<< only valid for integer types"); + throw exception::bad_boxed_cast("<< only valid for integer types"); } @@ -190,7 +190,7 @@ namespace chaiscript return smart_size(i % r.i); } - throw bad_boxed_cast("% only valid for integer types"); + throw exception::bad_boxed_cast("% only valid for integer types"); } Boxed_Value operator>>(const Boxed_POD_Value &r) const @@ -200,7 +200,7 @@ namespace chaiscript return smart_size(i >> r.i); } - throw bad_boxed_cast(">> only valid for integer types"); + throw exception::bad_boxed_cast(">> only valid for integer types"); } Boxed_Value smart_size(boost::int64_t i) const diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 2356ee1..cb74965 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -10,6 +10,7 @@ #include "type_info.hpp" #include "../chaiscript_threading.hpp" + #include #include #include @@ -273,30 +274,40 @@ namespace chaiscript boost::shared_ptr m_data; }; + /// Clean wrapper for providing the user with a Boxed_Value + /// Suggested use: chai.add(var(myvariable), "myvariable"); + /// \param t The value to box template Boxed_Value var(T t) { return Boxed_Value(t); } + /// Wrapper for providing the user with a Boxed_Value that is const inside + /// of the ChaiScript engine. + /// Suggested use: chai.add(const_var(myvariable), "myvariable"); + /// \param t The value to box template Boxed_Value const_var(T *t) { return Boxed_Value( const_cast::type *>(t) ); } + /// boost::shared_ptr overload for const_var template Boxed_Value const_var(const boost::shared_ptr &t) { return Boxed_Value( boost::const_pointer_cast::type>(t) ); } + /// boost::reference_wrapper overload for const_var template Boxed_Value const_var(const boost::reference_wrapper &t) { return Boxed_Value( boost::cref(t.get()) ); } + /// Generic overload for const_var template Boxed_Value const_var(const T &t) { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 053a721..8466c10 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -970,7 +970,7 @@ namespace chaiscript }; std::vector m_conversions; - chaiscript::threading::Thread_Storage m_stack_holder; + chaiscript::detail::threading::Thread_Storage m_stack_holder; State m_state; diff --git a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp index 579935d..af3edca 100644 --- a/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp +++ b/include/chaiscript/dispatchkit/dynamic_cast_conversion.hpp @@ -15,26 +15,28 @@ namespace chaiscript { - class bad_boxed_dynamic_cast : public bad_boxed_cast + namespace exception { - public: - bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to, - const std::string &t_what) - : bad_boxed_cast(t_from, t_to, t_what) - { - } + class bad_boxed_dynamic_cast : public bad_boxed_cast + { + public: + bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to, + const std::string &t_what) + : bad_boxed_cast(t_from, t_to, t_what) + { + } - bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw() - : bad_boxed_cast(t_from, t_to) - { - } - - bad_boxed_dynamic_cast(const std::string &w) throw() - : bad_boxed_cast(w) - { - } - }; + bad_boxed_dynamic_cast(const Type_Info &t_from, const std::type_info &t_to) throw() + : bad_boxed_cast(t_from, t_to) + { + } + bad_boxed_dynamic_cast(const std::string &w) throw() + : bad_boxed_cast(w) + { + } + }; + } namespace detail { @@ -114,9 +116,8 @@ namespace chaiscript } } } else { - throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion"); + throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unknown dynamic_cast_conversion"); } - } }; @@ -262,9 +263,9 @@ namespace chaiscript try { return detail::Dynamic_Conversions::get().get_conversion(user_type(), derived.get_type_info())->convert(derived); } catch (const std::out_of_range &) { - throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); + throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "No known conversion"); } catch (const std::bad_cast &) { - throw bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation"); + throw exception::bad_boxed_dynamic_cast(derived.get_type_info(), typeid(Base), "Unable to perform dynamic_cast operation"); } } diff --git a/include/chaiscript/dispatchkit/dynamic_object.hpp b/include/chaiscript/dispatchkit/dynamic_object.hpp index 96f7a81..68a0d04 100644 --- a/include/chaiscript/dispatchkit/dynamic_object.hpp +++ b/include/chaiscript/dispatchkit/dynamic_object.hpp @@ -34,239 +34,242 @@ namespace chaiscript std::map m_attrs; }; - struct Dynamic_Object_Attribute + namespace detail { - static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name, - Dynamic_Object &t_do) + struct Dynamic_Object_Attribute { - if (t_do.get_type_name() != t_type_name) + static Boxed_Value func(const std::string &t_type_name, const std::string &t_attr_name, + Dynamic_Object &t_do) { - throw bad_boxed_cast("Dynamic object type mismatch"); + if (t_do.get_type_name() != t_type_name) + { + throw exception::bad_boxed_cast("Dynamic object type mismatch"); + } + + return t_do.get_attr(t_attr_name); } + }; - return t_do.get_attr(t_attr_name); - } - }; - - /** - * A Proxy_Function implementation designed for calling a function - * that is automatically guarded based on the first param based on the - * param's type name - */ - class Dynamic_Object_Function : public Proxy_Function_Base - { - public: - Dynamic_Object_Function( - const std::string &t_type_name, - const Proxy_Function &t_func, - const boost::optional &t_ti = boost::optional()) - : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), + /** + * A Proxy_Function implementation designed for calling a function + * that is automatically guarded based on the first param based on the + * param's type name + */ + class Dynamic_Object_Function : public Proxy_Function_Base + { + public: + Dynamic_Object_Function( + const std::string &t_type_name, + const Proxy_Function &t_func, + const boost::optional &t_ti = boost::optional()) + : Proxy_Function_Base(build_param_types(t_func->get_param_types(), t_ti)), m_type_name(t_type_name), m_func(t_func), m_ti(t_ti) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } - - virtual ~Dynamic_Object_Function() {} - - virtual bool operator==(const Proxy_Function_Base &f) const - { - const Dynamic_Object_Function *df = dynamic_cast(&f); - if (df) { - return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); - } else { - return false; + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } - } - virtual bool call_match(const std::vector &vals) const - { - if (dynamic_object_typename_match(vals, m_type_name, m_ti)) + virtual ~Dynamic_Object_Function() {} + + virtual bool operator==(const Proxy_Function_Base &f) const { - return m_func->call_match(vals); - } else { - return false; - } - } - - virtual std::vector get_contained_functions() const - { - std::vector fs; - fs.push_back(m_func); - return fs; - } - - - virtual int get_arity() const - { - return m_func->get_arity(); - } - - virtual std::string annotation() const - { - return m_func->annotation(); - } - - - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - if (dynamic_object_typename_match(params, m_type_name, m_ti)) - { - return (*m_func)(params); - } else { - throw guard_error(); - } - } - - virtual bool compare_first_type(const Boxed_Value &bv) const - { - return dynamic_object_typename_match(bv, m_type_name, m_ti); - } - - private: - static std::vector build_param_types( - const std::vector &t_inner_types, boost::optional t_objectti) - { - if (t_objectti) - { - std::vector types(t_inner_types); - - assert(types.size() > 1); - assert(types[1].bare_equal(user_type())); - types[1] = *t_objectti; - return types; - } else { - return t_inner_types; - } - } - - static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, - const boost::optional &ti) - { - static Type_Info doti = user_type(); - if (bv.get_type_info().bare_equal(doti)) - { - try { - const Dynamic_Object &d = boxed_cast(bv); - return name == "Dynamic_Object" || d.get_type_name() == name; - } catch (const std::bad_cast &) { - return false; - } - } else { - if (ti) + const Dynamic_Object_Function *df = dynamic_cast(&f); + if (df) { - return bv.get_type_info().bare_equal(*ti); + return df->m_type_name == m_type_name && (*df->m_func) == (*m_func); } else { return false; } } - } - - static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, - const boost::optional &ti) - { - if (bvs.size() > 0) + virtual bool call_match(const std::vector &vals) const { - return dynamic_object_typename_match(bvs[0], name, ti); - } else { - return false; + if (dynamic_object_typename_match(vals, m_type_name, m_ti)) + { + return m_func->call_match(vals); + } else { + return false; + } + } + + virtual std::vector get_contained_functions() const + { + std::vector fs; + fs.push_back(m_func); + return fs; } - } - - std::string m_type_name; - Proxy_Function m_func; - boost::optional m_ti; - - }; - /** - * A Proxy_Function implementation designed for creating a new - * Dynamic_Object - * that is automatically guarded based on the first param based on the - * param's type name - */ - class Dynamic_Object_Constructor : public Proxy_Function_Base - { - public: - Dynamic_Object_Constructor( - const std::string &t_type_name, - const Proxy_Function &t_func) - : Proxy_Function_Base(build_type_list(t_func->get_param_types())), + virtual int get_arity() const + { + return m_func->get_arity(); + } + + virtual std::string annotation() const + { + return m_func->annotation(); + } + + + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + if (dynamic_object_typename_match(params, m_type_name, m_ti)) + { + return (*m_func)(params); + } else { + throw exception::guard_error(); + } + } + + virtual bool compare_first_type(const Boxed_Value &bv) const + { + return dynamic_object_typename_match(bv, m_type_name, m_ti); + } + + private: + static std::vector build_param_types( + const std::vector &t_inner_types, boost::optional t_objectti) + { + if (t_objectti) + { + std::vector types(t_inner_types); + + assert(types.size() > 1); + assert(types[1].bare_equal(user_type())); + types[1] = *t_objectti; + return types; + } else { + return t_inner_types; + } + } + + static bool dynamic_object_typename_match(const Boxed_Value &bv, const std::string &name, + const boost::optional &ti) + { + static Type_Info doti = user_type(); + if (bv.get_type_info().bare_equal(doti)) + { + try { + const Dynamic_Object &d = boxed_cast(bv); + return name == "Dynamic_Object" || d.get_type_name() == name; + } catch (const std::bad_cast &) { + return false; + } + } else { + if (ti) + { + return bv.get_type_info().bare_equal(*ti); + } else { + return false; + } + } + + } + + static bool dynamic_object_typename_match(const std::vector &bvs, const std::string &name, + const boost::optional &ti) + { + if (bvs.size() > 0) + { + return dynamic_object_typename_match(bvs[0], name, ti); + } else { + return false; + } + } + + std::string m_type_name; + Proxy_Function m_func; + boost::optional m_ti; + + }; + + + /** + * A Proxy_Function implementation designed for creating a new + * Dynamic_Object + * that is automatically guarded based on the first param based on the + * param's type name + */ + class Dynamic_Object_Constructor : public Proxy_Function_Base + { + public: + Dynamic_Object_Constructor( + const std::string &t_type_name, + const Proxy_Function &t_func) + : Proxy_Function_Base(build_type_list(t_func->get_param_types())), m_type_name(t_type_name), m_func(t_func) - { - assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) - && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); - } - - static std::vector build_type_list(const std::vector &tl) - { - std::vector::const_iterator begin = tl.begin(); - std::vector::const_iterator end = tl.end(); - - if (begin != end) { - ++begin; + assert( (t_func->get_arity() > 0 || t_func->get_arity() < 0) + && "Programming error, Dynamic_Object_Function must have at least one parameter (this)"); } - return std::vector(begin, end); - } - - virtual ~Dynamic_Object_Constructor() {} - - virtual bool operator==(const Proxy_Function_Base &f) const - { - const Dynamic_Object_Constructor *dc = dynamic_cast(&f); - if (dc) + static std::vector build_type_list(const std::vector &tl) { - return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); - } else { - return false; + std::vector::const_iterator begin = tl.begin(); + std::vector::const_iterator end = tl.end(); + + if (begin != end) + { + ++begin; + } + + return std::vector(begin, end); } - } - virtual bool call_match(const std::vector &vals) const - { - std::vector new_vals; - new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name))); - new_vals.insert(new_vals.end(), vals.begin(), vals.end()); + virtual ~Dynamic_Object_Constructor() {} - return m_func->call_match(new_vals); - } + virtual bool operator==(const Proxy_Function_Base &f) const + { + const Dynamic_Object_Constructor *dc = dynamic_cast(&f); + if (dc) + { + return dc->m_type_name == m_type_name && (*dc->m_func) == (*m_func); + } else { + return false; + } + } + + virtual bool call_match(const std::vector &vals) const + { + std::vector new_vals; + new_vals.push_back(Boxed_Value(Dynamic_Object(m_type_name))); + new_vals.insert(new_vals.end(), vals.begin(), vals.end()); + + return m_func->call_match(new_vals); + } - virtual int get_arity() const - { - // "this" is not considered part of the arity - return m_func->get_arity() - 1; - } + virtual int get_arity() const + { + // "this" is not considered part of the arity + return m_func->get_arity() - 1; + } - virtual std::string annotation() const - { - return m_func->annotation(); - } + virtual std::string annotation() const + { + return m_func->annotation(); + } - protected: - virtual Boxed_Value do_call(const std::vector ¶ms) const - { - std::vector new_params; - chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); - new_params.push_back(bv); - new_params.insert(new_params.end(), params.begin(), params.end()); + protected: + virtual Boxed_Value do_call(const std::vector ¶ms) const + { + std::vector new_params; + chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name)); + new_params.push_back(bv); + new_params.insert(new_params.end(), params.begin(), params.end()); - (*m_func)(new_params); + (*m_func)(new_params); - return bv; - } + return bv; + } - private: - std::string m_type_name; - Proxy_Function m_func; + private: + std::string m_type_name; + Proxy_Function m_func; - }; + }; + } } #endif diff --git a/include/chaiscript/dispatchkit/handle_return.hpp b/include/chaiscript/dispatchkit/handle_return.hpp index 1805646..20ada84 100644 --- a/include/chaiscript/dispatchkit/handle_return.hpp +++ b/include/chaiscript/dispatchkit/handle_return.hpp @@ -17,111 +17,115 @@ namespace chaiscript { - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template - struct Handle_Return - { - static Boxed_Value handle(const Ret &r) + namespace detail + { + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template + struct Handle_Return { - return Boxed_Value(r); - } - }; + static Boxed_Value handle(const Ret &r) + { + return Boxed_Value(r); + } + }; - template - struct Handle_Return &> - { - static Boxed_Value handle(const boost::shared_ptr &r) + template + struct Handle_Return &> { - return Boxed_Value(r); - } - }; + static Boxed_Value handle(const boost::shared_ptr &r) + { + return Boxed_Value(r); + } + }; - template - struct Handle_Return &> - { - static Boxed_Value handle(const boost::shared_ptr &r) + template + struct Handle_Return &> { - return Boxed_Value(r); - } - }; - - template - struct Handle_Return - { - static Boxed_Value handle(const Ret &r) + static Boxed_Value handle(const boost::shared_ptr &r) + { + return Boxed_Value(r); + } + }; + + template + struct Handle_Return { - return Boxed_Value(boost::cref(r)); - } - }; + static Boxed_Value handle(const Ret &r) + { + return Boxed_Value(boost::cref(r)); + } + }; - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template - struct Handle_Return - { - static Boxed_Value handle(Ret &r) + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template + struct Handle_Return { - return Boxed_Value(boost::ref(r)); - } + static Boxed_Value handle(Ret &r) + { + return Boxed_Value(boost::ref(r)); + } - static Boxed_Value handle(const Ret &r) - { - return Boxed_Value(boost::cref(r)); - } - }; + static Boxed_Value handle(const Ret &r) + { + return Boxed_Value(boost::cref(r)); + } + }; - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - static Boxed_Value handle(const Boxed_Value &r) + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template<> + struct Handle_Return { - return r; - } - }; + static Boxed_Value handle(const Boxed_Value &r) + { + return r; + } + }; - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - static Boxed_Value handle(const Boxed_Value &r) + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template<> + struct Handle_Return { - return r; - } - }; + static Boxed_Value handle(const Boxed_Value &r) + { + return r; + } + }; - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - static Boxed_Value handle(const Boxed_Value &r) + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template<> + struct Handle_Return { - return r; - } - }; + static Boxed_Value handle(const Boxed_Value &r) + { + return r; + } + }; - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - static Boxed_Value handle() + /** + * Used internally for handling a return value from a Proxy_Function call + */ + template<> + struct Handle_Return { - return Boxed_Value(Boxed_Value::Void_Type()); - } - }; + static Boxed_Value handle() + { + return Boxed_Value(Boxed_Value::Void_Type()); + } + }; + + } } #endif diff --git a/include/chaiscript/dispatchkit/operators.hpp b/include/chaiscript/dispatchkit/operators.hpp index af18c59..d401a2d 100644 --- a/include/chaiscript/dispatchkit/operators.hpp +++ b/include/chaiscript/dispatchkit/operators.hpp @@ -3,446 +3,449 @@ namespace chaiscript { - namespace operators + namespace bootstrap { - template - Ret assign(L l, R r) - { - return (l = r); - } + namespace operators + { + template + Ret assign(L l, R r) + { + return (l = r); + } - template - Ret assign_bitwise_and(L l, R r) - { - return (l &= r); - } + template + Ret assign_bitwise_and(L l, R r) + { + return (l &= r); + } - template - Ret assign_xor(L l, R r) - { - return (l ^= r); - } + template + Ret assign_xor(L l, R r) + { + return (l ^= r); + } - template - Ret assign_bitwise_or(L l, R r) - { - return (l |= r); - } + template + Ret assign_bitwise_or(L l, R r) + { + return (l |= r); + } - template - Ret assign_difference(L l, R r) - { - return (l -= r); - } + template + Ret assign_difference(L l, R r) + { + return (l -= r); + } - template - Ret assign_left_shift(L l, R r) - { - return (l <<= r); - } + template + Ret assign_left_shift(L l, R r) + { + return (l <<= r); + } - template - Ret assign_product(L l, R r) - { - return (l *= r); - } + template + Ret assign_product(L l, R r) + { + return (l *= r); + } - template - Ret assign_quotient(L l, R r) - { - return (l /= r); - } + template + Ret assign_quotient(L l, R r) + { + return (l /= r); + } - template - Ret assign_remainder(L l, R r) - { - return (l %= r); - } + template + Ret assign_remainder(L l, R r) + { + return (l %= r); + } - template - Ret assign_right_shift(L l, R r) - { - return (l >>= r); - } + template + Ret assign_right_shift(L l, R r) + { + return (l >>= r); + } - template - Ret assign_sum(L l, R r) - { - return (l += r); - } + template + Ret assign_sum(L l, R r) + { + return (l += r); + } - template - Ret prefix_decrement(L l) - { - return (--l); - } + template + Ret prefix_decrement(L l) + { + return (--l); + } - template - Ret prefix_increment(L l) - { - return (++l); - } + template + Ret prefix_increment(L l) + { + return (++l); + } - template - Ret equal(L l, R r) - { - return (l == r); - } + template + Ret equal(L l, R r) + { + return (l == r); + } - template - Ret greater_than(L l, R r) - { - return (l > r); - } + template + Ret greater_than(L l, R r) + { + return (l > r); + } - template - Ret greater_than_equal(L l, R r) - { - return (l >= r); - } + template + Ret greater_than_equal(L l, R r) + { + return (l >= r); + } - template - Ret less_than(L l, R r) - { - return (l < r); - } + template + Ret less_than(L l, R r) + { + return (l < r); + } - template - Ret less_than_equal(L l, R r) - { - return (l <= r); - } + template + Ret less_than_equal(L l, R r) + { + return (l <= r); + } - template - Ret logical_compliment(L l) - { - return (!l); - } + template + Ret logical_compliment(L l) + { + return (!l); + } - template - Ret not_equal(L l, R r) - { - return (l != r); - } + template + Ret not_equal(L l, R r) + { + return (l != r); + } - template - Ret addition(L l, R r) - { - return (l + r); - } + template + Ret addition(L l, R r) + { + return (l + r); + } - template - Ret unary_plus(L l) - { - return (+l); - } + template + Ret unary_plus(L l) + { + return (+l); + } - template - Ret subtraction(L l, R r) - { - return (l - r); - } + template + Ret subtraction(L l, R r) + { + return (l - r); + } - template - Ret unary_minus(L l) - { + template + Ret unary_minus(L l) + { #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable : 4146) - return (-l); + return (-l); #pragma warning(pop) #else - return (-l); + return (-l); #endif - } + } - template - Ret bitwise_and(L l, R r) - { - return (l & r); - } + template + Ret bitwise_and(L l, R r) + { + return (l & r); + } - template - Ret bitwise_compliment(L l) - { - return (~l); - } + template + Ret bitwise_compliment(L l) + { + return (~l); + } - template - Ret bitwise_xor(L l, R r) - { - return (l ^ r); - } + template + Ret bitwise_xor(L l, R r) + { + return (l ^ r); + } - template - Ret bitwise_or(L l, R r) - { - return (l | r); - } + template + Ret bitwise_or(L l, R r) + { + return (l | r); + } - template - Ret division(L l, R r) - { - return (l / r); - } + template + Ret division(L l, R r) + { + return (l / r); + } - template - Ret left_shift(L l, R r) - { - return l << r; - } + template + Ret left_shift(L l, R r) + { + return l << r; + } - template - Ret multiplication(L l, R r) - { - return l * r; - } + template + Ret multiplication(L l, R r) + { + return l * r; + } - template - Ret remainder(L l, R r) - { - return (l % r); - } + template + Ret remainder(L l, R r) + { + return (l % r); + } - template - Ret right_shift(L l, R r) - { - return (l >> r); - } + template + Ret right_shift(L l, R r) + { + return (l >> r); + } - template - ModulePtr assign(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign), "="); - return m; - } + template + ModulePtr assign(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign), "="); + return m; + } - template - ModulePtr assign_bitwise_and(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_bitwise_and), "&="); - return m; - } + template + ModulePtr assign_bitwise_and(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_bitwise_and), "&="); + return m; + } - template - ModulePtr assign_xor(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_xor), "^="); - return m; - } + template + ModulePtr assign_xor(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_xor), "^="); + return m; + } - template - ModulePtr assign_bitwise_or(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_bitwise_or), "|="); - return m; - } + template + ModulePtr assign_bitwise_or(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_bitwise_or), "|="); + return m; + } - template - ModulePtr assign_difference(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_difference), "-="); - return m; - } + template + ModulePtr assign_difference(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_difference), "-="); + return m; + } - template - ModulePtr assign_left_shift(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_left_shift), "<<="); - return m; - } + template + ModulePtr assign_left_shift(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_left_shift), "<<="); + return m; + } - template - ModulePtr assign_product(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_product), "*="); - return m; - } + template + ModulePtr assign_product(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_product), "*="); + return m; + } - template - ModulePtr assign_quotient(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_quotient), "/="); - return m; - } + template + ModulePtr assign_quotient(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_quotient), "/="); + return m; + } - template - ModulePtr assign_remainder(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_remainder), "%="); - return m; - } + template + ModulePtr assign_remainder(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_remainder), "%="); + return m; + } - template - ModulePtr assign_right_shift(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_right_shift), ">>="); - return m; - } + template + ModulePtr assign_right_shift(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_right_shift), ">>="); + return m; + } - template - ModulePtr assign_sum(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&assign_sum), "+="); - return m; - } + template + ModulePtr assign_sum(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&assign_sum), "+="); + return m; + } - template - ModulePtr prefix_decrement(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&prefix_decrement), "--"); - return m; - } + template + ModulePtr prefix_decrement(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&prefix_decrement), "--"); + return m; + } - template - ModulePtr prefix_increment(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&prefix_increment), "++"); - return m; - } + template + ModulePtr prefix_increment(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&prefix_increment), "++"); + return m; + } - template - ModulePtr equal(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&equal), "=="); - return m; - } + template + ModulePtr equal(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&equal), "=="); + return m; + } - template - ModulePtr greater_than(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&greater_than), ">"); - return m; - } + template + ModulePtr greater_than(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&greater_than), ">"); + return m; + } - template - ModulePtr greater_than_equal(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&greater_than_equal), ">="); - return m; - } + template + ModulePtr greater_than_equal(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&greater_than_equal), ">="); + return m; + } - template - ModulePtr less_than(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&less_than), "<"); - return m; - } + template + ModulePtr less_than(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&less_than), "<"); + return m; + } - template - ModulePtr less_than_equal(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&less_than_equal), "<="); - return m; - } + template + ModulePtr less_than_equal(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&less_than_equal), "<="); + return m; + } - template - ModulePtr logical_compliment(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&logical_compliment), "!"); - return m; - } + template + ModulePtr logical_compliment(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&logical_compliment), "!"); + return m; + } - template - ModulePtr not_equal(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(¬_equal), "!="); - return m; - } + template + ModulePtr not_equal(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(¬_equal), "!="); + return m; + } - template - ModulePtr addition(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&addition), "+"); - return m; - } + template + ModulePtr addition(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&addition), "+"); + return m; + } - template - ModulePtr unary_plus(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&unary_plus), "+"); - return m; - } + template + ModulePtr unary_plus(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&unary_plus), "+"); + return m; + } - template - ModulePtr subtraction(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&subtraction), "-"); - return m; - } + template + ModulePtr subtraction(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&subtraction), "-"); + return m; + } - template - ModulePtr unary_minus(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&unary_minus), "-"); - return m; - } + template + ModulePtr unary_minus(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&unary_minus), "-"); + return m; + } - template - ModulePtr bitwise_and(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&bitwise_and), "&"); - return m; - } + template + ModulePtr bitwise_and(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&bitwise_and), "&"); + return m; + } - template - ModulePtr bitwise_compliment(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&bitwise_compliment), "~"); - return m; - } + template + ModulePtr bitwise_compliment(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&bitwise_compliment), "~"); + return m; + } - template - ModulePtr bitwise_xor(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&bitwise_xor), "^"); - return m; - } + template + ModulePtr bitwise_xor(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&bitwise_xor), "^"); + return m; + } - template - ModulePtr bitwise_or(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&bitwise_or), "|"); - return m; - } + template + ModulePtr bitwise_or(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&bitwise_or), "|"); + return m; + } - template - ModulePtr division(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&division), "/"); - return m; - } + template + ModulePtr division(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&division), "/"); + return m; + } - template - ModulePtr left_shift(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&left_shift), "<<"); - return m; - } + template + ModulePtr left_shift(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&left_shift), "<<"); + return m; + } - template - ModulePtr multiplication(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&multiplication), "*"); - return m; - } + template + ModulePtr multiplication(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&multiplication), "*"); + return m; + } - template - ModulePtr remainder(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&remainder), "%"); - return m; - } + template + ModulePtr remainder(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&remainder), "%"); + return m; + } - template - ModulePtr right_shift(ModulePtr m = ModulePtr(new Module())) - { - m->add(fun(&right_shift), ">>"); - return m; - } + template + ModulePtr right_shift(ModulePtr m = ModulePtr(new Module())) + { + m->add(fun(&right_shift), ">>"); + return m; + } + } } } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 728428a..e7cd654 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -175,19 +175,22 @@ namespace chaiscript typedef boost::shared_ptr Proxy_Function; typedef boost::shared_ptr Const_Proxy_Function; - /** - * Exception thrown if a function's guard fails to execute - */ - class guard_error : public std::runtime_error + namespace exception { - public: - guard_error() throw() - : std::runtime_error("Guard evaluation failed") - { } + /** + * Exception thrown if a function's guard fails to execute + */ + class guard_error : public std::runtime_error + { + public: + guard_error() throw() + : std::runtime_error("Guard evaluation failed") + { } - virtual ~guard_error() throw() - { } - }; + virtual ~guard_error() throw() + { } + }; + } /** * A Proxy_Function implementation that is not type safe, the called function @@ -251,11 +254,11 @@ namespace chaiscript { return m_f(params); } else { - throw guard_error(); + throw exception::guard_error(); } } else { - throw arity_error(static_cast(params.size()), m_arity); + throw exception::arity_error(static_cast(params.size()), m_arity); } } @@ -266,9 +269,9 @@ namespace chaiscript { try { return boxed_cast((*m_guard)(params)); - } catch (const arity_error &) { + } catch (const exception::arity_error &) { return false; - } catch (const bad_boxed_cast &) { + } catch (const exception::bad_boxed_cast &) { return false; } } else { @@ -438,7 +441,7 @@ namespace chaiscript { public: Proxy_Function_Impl(const boost::function &f) - : Proxy_Function_Base(build_param_type_list(static_cast(0))), + : Proxy_Function_Base(detail::build_param_type_list(static_cast(0))), m_f(f), m_dummy_func(0) { } @@ -465,7 +468,7 @@ namespace chaiscript return false; } - return compare_types(m_types, vals) || compare_types_cast(m_dummy_func, vals); + return compare_types(m_types, vals) || detail::compare_types_cast(m_dummy_func, vals); } virtual std::string annotation() const @@ -481,7 +484,7 @@ namespace chaiscript protected: virtual Boxed_Value do_call(const std::vector ¶ms) const { - return Do_Call::result_type>::go(m_f, params); + return detail::Do_Call::result_type>::go(m_f, params); } private: @@ -545,13 +548,13 @@ namespace chaiscript if (bv.is_const()) { const Class *o = boxed_cast(bv); - return Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::handle(o->*m_attr); } else { Class *o = boxed_cast(bv); - return Handle_Return::type>::handle(o->*m_attr); + return detail::Handle_Return::type>::handle(o->*m_attr); } } else { - throw arity_error(static_cast(params.size()), 1); + throw exception::arity_error(static_cast(params.size()), 1); } } @@ -603,11 +606,11 @@ namespace chaiscript { return (*(*begin))(plist); } - } catch (const bad_boxed_cast &) { + } catch (const exception::bad_boxed_cast &) { //parameter failed to cast, try again - } catch (const arity_error &) { + } catch (const exception::arity_error &) { //invalid num params, try again - } catch (const guard_error &) { + } catch (const exception::guard_error &) { //guard failed to allow the function to execute, //try again } diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 9f4c807..30a51cb 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -28,43 +28,50 @@ namespace chaiscript { - /** - * Exception thrown when there is a mismatch in number of - * parameters during Proxy_Function execution - */ - struct arity_error : std::range_error + namespace exception { - arity_error(int t_got, int t_expected) - : std::range_error("Function dispatch arity mismatch"), - got(t_got), expected(t_expected) + /** + * Exception thrown when there is a mismatch in number of + * parameters during Proxy_Function execution + */ + struct arity_error : std::range_error { - } - - virtual ~arity_error() throw() {} - int got; - int expected; - }; - - template - struct Do_Call - { - template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + arity_error(int t_got, int t_expected) + : std::range_error("Function dispatch arity mismatch"), + got(t_got), expected(t_expected) { - return Handle_Return::handle(call_func(fun, params)); } - }; - template<> - struct Do_Call - { - template - static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) - { - call_func(fun, params); - return Handle_Return::handle(); - }; + virtual ~arity_error() throw() {} + + int got; + int expected; }; + } + + namespace detail + { + template + struct Do_Call + { + template + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + { + return Handle_Return::handle(call_func(fun, params)); + } + }; + + template<> + struct Do_Call + { + template + static Boxed_Value go(const boost::function &fun, const std::vector ¶ms) + { + call_func(fun, params); + return Handle_Return::handle(); + }; + }; + } } #define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) @@ -78,57 +85,59 @@ namespace chaiscript namespace chaiscript { - /** - * Used by Proxy_Function_Impl to return a list of all param types - * it contains. - */ - template - std::vector build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param))) - { - std::vector ti; - ti.push_back(detail::Get_Type_Info::get()); - - BOOST_PP_REPEAT(n, gettypeinfo, ~) - - return ti; - } - - /** - * Used by Proxy_Function_Impl to perform typesafe execution of a function. - * The function attempts to unbox each paramter to the expected type. - * if any unboxing fails the execution of the function fails and - * the bad_boxed_cast is passed up to the caller. - */ - template - Ret call_func(const boost::function &f, - const std::vector ¶ms) - { - if (params.size() != n) + namespace detail + { + /** + * Used by Proxy_Function_Impl to return a list of all param types + * it contains. + */ + template + std::vector build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param))) { - throw arity_error(static_cast(params.size()), n); - } else { - return f(BOOST_PP_REPEAT(n, casthelper, ~)); - } - } + std::vector ti; + ti.push_back(detail::Get_Type_Info::get()); - /** - * Used by Proxy_Function_Impl to determine if it is equivalent to another - * Proxy_Function_Impl object. This function is primarly used to prevent - * registration of two functions with the exact same signatures - */ - template - bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), - const std::vector & BOOST_PP_IF(n, params, )) - { - try { - BOOST_PP_REPEAT(n, trycast, ~); - } catch (const bad_boxed_cast &) { - return false; + BOOST_PP_REPEAT(n, gettypeinfo, ~) + + return ti; } - return true; - } + /** + * Used by Proxy_Function_Impl to perform typesafe execution of a function. + * The function attempts to unbox each paramter to the expected type. + * if any unboxing fails the execution of the function fails and + * the bad_boxed_cast is passed up to the caller. + */ + template + Ret call_func(const boost::function &f, + const std::vector ¶ms) + { + if (params.size() != n) + { + throw exception::arity_error(static_cast(params.size()), n); + } else { + return f(BOOST_PP_REPEAT(n, casthelper, ~)); + } + } + /** + * Used by Proxy_Function_Impl to determine if it is equivalent to another + * Proxy_Function_Impl object. This function is primarly used to prevent + * registration of two functions with the exact same signatures + */ + template + bool compare_types_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), + const std::vector & BOOST_PP_IF(n, params, )) + { + try { + BOOST_PP_REPEAT(n, trycast, ~); + } catch (const exception::bad_boxed_cast &) { + return false; + } + + return true; + } + } } #undef n diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index c85b035..0423b22 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -78,13 +78,13 @@ namespace chaiscript template Proxy_Function fun(T t, const Q &q) { - return fun(bind_first(t, q)); + return fun(detail::bind_first(t, q)); } template Proxy_Function fun(T t, const Q &q, const R &r) { - return fun(bind_first(bind_first(t, q), r)); + return fun(detail::bind_first(detail::bind_first(t, q), r)); } } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 1f3bf32..7945812 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -204,14 +204,14 @@ namespace chaiscript &typeid(typename Bare_Type::type)); } }; + + template + struct Stripped_Type + { + typedef typename Bare_Type::type>::type type; + }; } - template - struct Stripped_Type - { - typedef typename Bare_Type::type>::type type; - }; - template Type_Info user_type(T) { diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index f21754f..554ef39 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -552,10 +552,10 @@ namespace chaiscript m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); m_engine.add(fun(static_cast(&ChaiScript::load_module), this), "load_module"); - add(vector_type >("Vector")); - add(string_type("string")); - add(map_type >("Map")); - add(pair_type >("Pair")); + add(standard_library::vector_type >("Vector")); + add(standard_library::string_type("string")); + add(standard_library::map_type >("Map")); + add(standard_library::pair_type >("Pair")); m_engine.add(fun(&ChaiScript::use, this), "use"); m_engine.add(fun(&ChaiScript::internal_eval, this), "eval"); diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 8467c9d..f2c7ee7 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -662,7 +662,7 @@ namespace chaiscript try { cond = boxed_cast(this->children[0]->eval(t_ss)); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { t_ss.pop_scope(); throw Eval_Error("While condition not boolean"); } @@ -684,7 +684,7 @@ namespace chaiscript try { cond = boxed_cast(this->children[0]->eval(t_ss)); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { t_ss.pop_scope(); throw Eval_Error("While condition not boolean"); } @@ -714,7 +714,7 @@ namespace chaiscript try { cond = boxed_cast(this->children[0]->eval(t_ss)); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { throw Eval_Error("If condition not boolean"); } catch (Eval_Error &ee) { @@ -748,7 +748,7 @@ namespace chaiscript try { cond = boxed_cast(this->children[i+1]->eval(t_ss)); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { throw Eval_Error("'else if' condition not boolean"); } catch (Eval_Error &ee) { @@ -814,7 +814,7 @@ namespace chaiscript } } } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { t_ss.pop_scope(); throw Eval_Error("For condition not boolean"); } @@ -872,7 +872,7 @@ namespace chaiscript } } } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { t_ss.pop_scope(); throw Eval_Error("For condition not boolean"); } @@ -1120,7 +1120,7 @@ namespace chaiscript bool guard; try { guard = boxed_cast(catch_block->children[1]->eval(t_ss)); - } catch (const bad_boxed_cast &) { + } catch (const exception::bad_boxed_cast &) { if (this->children.back()->identifier == AST_Node_Type::Finally) { try { this->children.back()->children[0]->eval(t_ss); @@ -1200,7 +1200,7 @@ namespace chaiscript try { guard = boxed_cast(catch_block->children[1]->eval(t_ss)); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { if (this->children.back()->identifier == AST_Node_Type::Finally) { try { this->children.back()->children[0]->eval(t_ss); @@ -1339,7 +1339,7 @@ namespace chaiscript const std::string & function_name = this->children[1]->text; if (function_name == class_name) { t_ss.add(Proxy_Function - (new Dynamic_Object_Constructor(class_name, Proxy_Function + (new detail::Dynamic_Object_Constructor(class_name, Proxy_Function (new Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back(), @@ -1354,7 +1354,7 @@ namespace chaiscript // No biggie, the type name is just not known } t_ss.add(Proxy_Function - (new Dynamic_Object_Function(class_name, Proxy_Function + (new detail::Dynamic_Object_Function(class_name, Proxy_Function (new Dynamic_Proxy_Function(boost::bind(&eval_function, boost::ref(t_ss), this->children.back(), t_param_names, _1), static_cast(numparams), this->children.back(), @@ -1377,7 +1377,7 @@ namespace chaiscript virtual ~Attr_Decl_AST_Node() {} virtual Boxed_Value eval(Dispatch_Engine &t_ss){ try { - t_ss.add(fun(boost::function(boost::bind(&Dynamic_Object_Attribute::func, this->children[0]->text, + t_ss.add(fun(boost::function(boost::bind(&detail::Dynamic_Object_Attribute::func, this->children[0]->text, this->children[1]->text, _1))), this->children[1]->text); } @@ -1445,7 +1445,7 @@ namespace chaiscript try { lhs = boxed_cast(retval); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { throw Eval_Error("Condition not boolean"); } if (lhs) { @@ -1488,7 +1488,7 @@ namespace chaiscript try { lhs = boxed_cast(retval); } - catch (const bad_boxed_cast &) { + catch (const exception::bad_boxed_cast &) { throw Eval_Error("Condition not boolean"); } if (lhs) { diff --git a/samples/example.cpp b/samples/example.cpp index fdf1c14..e802982 100644 --- a/samples/example.cpp +++ b/samples/example.cpp @@ -154,7 +154,7 @@ int main(int /*argc*/, char * /*argv*/[]) { //Ability to create our own container types when needed. std::vector and std::map are //mostly supported currently - chai.add(bootstrap::vector_type >("IntVector")); + chai.add(bootstrap::standard_library::vector_type >("IntVector")); // Test ability to register a function that excepts a shared_ptr version of a type @@ -163,9 +163,9 @@ int main(int /*argc*/, char * /*argv*/[]) { chai.add(fun(&bound_log, std::string("Msg")), "BoundFun"); //Dynamic objects test - chai.add(chaiscript::Proxy_Function(new Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world"); - chai.add(chaiscript::Proxy_Function(new Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType"); - chai.add(fun(boost::function(boost::bind(&Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); + chai.add(chaiscript::Proxy_Function(new detail::Dynamic_Object_Function("TestType", fun(&hello_world))), "hello_world"); + chai.add(chaiscript::Proxy_Function(new detail::Dynamic_Object_Constructor("TestType", fun(&hello_constructor))), "TestType"); + chai.add(fun(boost::function(boost::bind(&detail::Dynamic_Object_Attribute::func, "TestType", "attr", _1))), "attr"); chai.eval("var x = TestType()"); // chai.eval("x.attr = \"hi\""); diff --git a/src/reflection.cpp b/src/reflection.cpp index 2a64348..d5fc6cb 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -48,7 +48,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_reflect m->add(chaiscript::fun(&get_parse_tree), "get_parse_tree"); - chaiscript::bootstrap::vector_type > >("AST_NodeVector", m); + chaiscript::bootstrap::standard_library::vector_type > >("AST_NodeVector", m); CHAISCRIPT_CLASS( m, chaiscript::File_Position, diff --git a/src/stl_extra.cpp b/src/stl_extra.cpp index 3a6dd80..59a542a 100644 --- a/src/stl_extra.cpp +++ b/src/stl_extra.cpp @@ -12,7 +12,7 @@ CHAISCRIPT_MODULE_EXPORT chaiscript::ModulePtr create_chaiscript_module_stl_extra() { - return chaiscript::bootstrap::list_type >("List"); + return chaiscript::bootstrap::standard_library::list_type >("List"); } diff --git a/unittests/boxed_cast_test.cpp b/unittests/boxed_cast_test.cpp index 7436577..ab9b882 100644 --- a/unittests/boxed_cast_test.cpp +++ b/unittests/boxed_cast_test.cpp @@ -13,7 +13,7 @@ bool run_test_type_conversion(const Boxed_Value &bv, bool expectedpass) try { To ret = chaiscript::boxed_cast(bv); use(ret); - } catch (const chaiscript::bad_boxed_cast &/*e*/) { + } catch (const chaiscript::exception::bad_boxed_cast &/*e*/) { if (expectedpass) { // std::cerr << "Failure in run_test_type_conversion: " << e.what() << std::endl; return false; @@ -274,7 +274,7 @@ bool pointer_test(const T& default_value, const T& new_value) } return true; - } catch (const bad_boxed_cast &) { + } catch (const exception::bad_boxed_cast &) { std::cerr << "Bad boxed cast performing ** to ** test" << std::endl; return false; } catch (...) {